多次运行后程序给出错误结果

时间:2018-08-25 14:19:23

标签: java swing jframe jpanel

我是编码新手(对编码/格式/效率错误等感到抱歉)。 我编写了此程序,该程序可以对测量数据进行插值,并为您提供一些结果(如线路参数,兼容性等)。 我还编写了一个简单的GUI(对不起,如果是一团糟),以使其易于使用。 当我第一次输入数据并开始计算过程时,它会给出预期的结果。一旦我尝试输入其他数据(甚至再次输入相同的数据),它就会返回完全错误和奇怪的结果。我试图在程序的每个“迭代”之后清除所有字段,数组,变量,但是我无法解决此问题。 有什么建议吗?

package com.company;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


// main class
public class Main {

public static void main(String[] args) {
    Gui q= new Gui();

  }
}
// simple GUI class w/ all global variables
class Gui {

private JTextField txts;
private JTextField items1, items3;
private JTextField items2;
private int n = 0;
private double x1[], x3[];
private double y1[], y3[];
private double sigma = 0, j = 0, k = 0, m = 0;
private double w[];
private double x2[];
private double y2[];
private double wsumx = 0, werrA = 0, werrB = 0, wsumy = 0, sumv32=0, sumv32y=0, sumv3v2=0;
private double wsumxy = 0, wsumx2 = 0, sumw = 0, sumv1 = 0, sumv2 = 0, sumv34=0;
private double sumx = 0, sumy = 0, sumxy = 0, sumx2 = 0;
private double delta = 0, A = 0, B = 0, a = 0, b = 0, c = 0;
private double errA = 0;
private double errB = 0;
private double chi = 0;
private double redchi = 0;
private double v3[];

//constructor
public Gui() {

    //creates a window with a basic layout
    JFrame frame = new JFrame("Lab Assistant V1.0");
    frame.setLayout(new BorderLayout());
    frame.setSize(600, 250);

    // creates buttons
    JButton calcola1 = new JButton("Calculate");
    JButton calcola2 = new JButton("Calculate");
    JButton calcola3 = new JButton("Calculate");

    JButton canc1 = new JButton("Clear");
    JButton canc2 = new JButton("Clear");
    JButton canc3 = new JButton("Clear");


    JButton enter1 = new JButton("Enter");
    JButton enter2 = new JButton("Enter");
    JButton enter3 = new JButton("Enter");

    JButton comp1 = new JButton("Compatibility");
    JButton comp2 = new JButton("Compatibility");

    // creates labels
    JLabel sval = new JLabel("Type in y error");
    JLabel num1 = new JLabel("N° of values");
    JLabel num2 = new JLabel("N° of values");
    JLabel num3 = new JLabel("N° of values");

    // creates tabs and text fields
    JTabbedPane tabs = new JTabbedPane();

    txts = new JTextField(20);
    items1 = new JTextField(3);
    items2 = new JTextField(3);
    items3 = new JTextField(3);

    // adds elements to each tab
    JPanel stnd = new JPanel();
    tabs.addTab("Standard", stnd);

    stnd.add(sval, BorderLayout.NORTH);
    stnd.add(txts);
    stnd.add(num1);
    stnd.add(items1);
    stnd.add(enter1, BorderLayout.SOUTH);
    stnd.add(calcola1);
    stnd.add(comp1);
    stnd.add(canc1);


    JPanel weight = new JPanel();
    tabs.addTab("Weighted", weight);

    weight.add(num2);
    weight.add(items2);
    weight.add(enter2, BorderLayout.SOUTH);
    weight.add(calcola2, BorderLayout.SOUTH);
    weight.add(comp2);
    weight.add(canc2);

    JPanel nonlin = new JPanel();
    tabs.addTab("Non-linear", nonlin);

    nonlin.add(num3);
    nonlin.add(items3);
    nonlin.add(enter3);
    nonlin.add(calcola3);
    nonlin.add(canc3);

    // adds all tabs to the main window
    frame.add(tabs);

    // events fot the enter button (tab 1)
    enter1.addActionListener(
            new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    n = Integer.parseInt(items1.getText());
                    x1 = new double[n];
                    y1 = new double[n];

                    sigma = Double.parseDouble(txts.getText());
                    JOptionPane.showMessageDialog(null, " Y error: " + sigma);
                    for (int i = 0; i < n; i++) {
                        String C = JOptionPane.showInputDialog(null, "Enter x values");
                        String d = JOptionPane.showInputDialog(null, "Enter y values");
                        if (!C.isEmpty() || !d.isEmpty()) {
                            j = Double.parseDouble(C);
                            x1[i] = j;
                            //JOptionPane.showMessageDialog(null, "X value: " + x1[i] + "");

                            k = Double.parseDouble(d);
                            y1[i] = k;
                            //JOptionPane.showMessageDialog(null, "Y value: " + y1[i]);
                        } else {
                            JOptionPane.showMessageDialog(null, "Warning! Enter a valid number.");
                        }

                    }


                }
            }

    );

    // events fot the enter button (tab 2)
    enter2.addActionListener(
            new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    n = Integer.parseInt(items2.getText());
                    x2 = new double[n];
                    y2 = new double[n];
                    w = new double[n];

                    for (int i = 0; i < n; i++) {
                        String C = JOptionPane.showInputDialog(null, "Enter x values");
                        String d = JOptionPane.showInputDialog(null, "Enter y values");

                        if (!C.isEmpty() || !d.isEmpty()) {
                            j = Double.parseDouble(C);
                            x2[i] = j;
                            //JOptionPane.showMessageDialog(null, "X value: " + x2[i] + "");

                            k = Double.parseDouble(d);
                            y2[i] = k;
                            //JOptionPane.showMessageDialog(null, "Y value: " + y2[i]);
                            String f = JOptionPane.showInputDialog(null, "Enter weights");
                            m = Double.parseDouble(f);
                            w[i] = m;
                            //JOptionPane.showMessageDialog(null, "Weight: " + w[i]);
                        } else {
                            JOptionPane.showMessageDialog(null, "Warning! Enter a valid number.");
                        }


                    }
                }
            }
    );
    // events fot the enter button (tab 3)
    enter3.addActionListener(
            new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    n = Integer.parseInt(items3.getText());
                    x3 = new double[n];
                    y3 = new double[n];
                    v3 = new double[n];

                    for (int i = 0; i < n; i++) {
                        String C = JOptionPane.showInputDialog(null, "Enter x values");
                        String d = JOptionPane.showInputDialog(null, "Enter y values");

                        if (!C.isEmpty() || !d.isEmpty()) {
                            j = Double.parseDouble(C);
                            x3[i] = j;
                            //JOptionPane.showMessageDialog(null, "X value: " + x2[i] + "");

                            k = Double.parseDouble(d);
                            y3[i] = k;
                            //JOptionPane.showMessageDialog(null, "Y value: " + y2[i]);

                        } else {
                            JOptionPane.showMessageDialog(null, "Warning! Enter a valid number.");
                        }


                    }

                }
            }

    );
    // events for tha calculate button (tab 1)
    calcola1.addActionListener(
            new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    calculateols(x1, y1);
                    JOptionPane.showMessageDialog(null, "Delta: " + delta);

                    if(delta <= 0){
                        JOptionPane.showMessageDialog(null, "An error occurred. Delta is an invalid value.");
                    }
                    else {
                        JOptionPane.showMessageDialog(null, "A: " + A);
                        JOptionPane.showMessageDialog(null, "B: " + B);
                        JOptionPane.showMessageDialog(null, "The line parameters are: " + String.format("%04f", A) + "(+)" + String.format("%04f", B) + "x");
                        JOptionPane.showMessageDialog(null, "A error: " + errA);
                        JOptionPane.showMessageDialog(null, "B error: " + errB);

                    }
                }
            }


    );
    // events for the compatibility button (tab 1)
    comp1.addActionListener(
            new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Chi(x1, y1);
                    JOptionPane.showMessageDialog(null, "Chi: " + chi);
                    JOptionPane.showMessageDialog(null, "Chi/dof: " + redchi);
                }
            }
    );
    // events for tha calculate button (tab 2)
    calcola2.addActionListener(
            new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    calculatewols(x2, y2, w);
                    JOptionPane.showMessageDialog(null, "Delta :" + delta);
                    if(delta <= 0){
                        JOptionPane.showMessageDialog(null, "An error occurred. Delta is an invalid value.");
                    }
                    else {
                        JOptionPane.showMessageDialog(null, "A: " + A);
                        JOptionPane.showMessageDialog(null, "B: " + B);
                        JOptionPane.showMessageDialog(null, "The line parameters are: " + String.format("%04f", A) + "(+)" + String.format("%04f", B) + "x");
                        JOptionPane.showMessageDialog(null, "A error: " + werrA);
                        JOptionPane.showMessageDialog(null, "B error: " + werrB);
                    }
                }
            }
    );
    // events for the compatibility button (tab 2)
    comp2.addActionListener(
            new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Chiw(x2, y2);
                    JOptionPane.showMessageDialog(null, "Chi: " + chi);
                    JOptionPane.showMessageDialog(null, "Chi/dof: " + redchi);
                }
            }
    );
    // events for tha calculate button (tab 3)
    calcola3.addActionListener(
            new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    calculatepar(x3, y3);
                    JOptionPane.showMessageDialog(null, "a: " + a);
                    JOptionPane.showMessageDialog(null, "b: " +b);
                    JOptionPane.showMessageDialog(null, "c:" + c);
                    JOptionPane.showMessageDialog(null, "The curve parameters are: " + String.format("%04f", a) + "(+)" + String.format("%04f", b) + "x"+"(+)"+String.format("%04f", c)+"x^2");

                }
            }
    );

    // events for cancel button (first tab)
    canc1.addActionListener(
            new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    txts.setText("");
                    items1.setText("");
                    n = 0;
                     x1 = null;
                    y1 = null;
                }

            }

    );
    // events for cancel button (second tab)
    canc2.addActionListener(
            new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    items2.setText("");
                    n = 0;
                    x2 = null;
                    y2 = null;
                    w = null;
                }
            }
    );
    // events for cancel button (third tab)
    canc3.addActionListener(
            new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    items3.setText("");
                    n = 0;
                    x3 = null;
                    y3 = null;
                }
            }
    );


    frame.setVisible(true);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


}

// interpolates data through the ordinary least squares method
private void calculateols(double x[], double y[]) {


    for (double w : x)
        sumx += w;

    for (double w : y)
        sumy += w;

    for (int i = 0; i < x.length; i++) {
        sumxy += x[i] * y[i];
    }

    for (int i = 0; i < x.length; i++) {
        sumx2 += Math.pow(x[i], 2);
    }


    delta = (n * sumx2) - (Math.pow(sumx, 2));
    A = ((sumx2 * sumy) - (sumx * sumxy)) / delta;
    B = ((n * sumxy) - (sumx * sumy)) / delta;


    errA = sigma * (Math.pow(sumx2 / delta, 0.5));
    errB = sigma * (Math.pow(n / delta, 0.5));



}

// calculates the compatibility between interpolated data and measured (input) data
private void Chi(double X[], double Y[]) {

    for (int i = 0; i < X.length; i++) {
        chi += (Math.pow((Y[i] - A - (B * X[i])), 2)) / (Math.pow(sigma, 2));
    }

    redchi = chi / (X.length - 2);
}

// interpolates data through the weighted ordinary least squares method
private void calculatewols(double wx[], double wy[], double W[]) {


    for (int i = 0; i < W.length; i++) {
        sumw += W[i];
    }

    for (int i = 0; i < wx.length; i++) {
        wsumx += w[i] * wx[i];
    }

    for (int i = 0; i < wx.length; i++) {
        wsumy += w[i] * wy[i];
    }

    for (int i = 0; i < wx.length; i++) {
        wsumxy += w[i] * wx[i] * wy[i];
    }


    for (int i = 0; i < wx.length; i++) {
        wsumx2 += w[i] * (Math.pow(wx[i], 2));
    }


    delta = (sumw * wsumx2) - (Math.pow(wsumx, 2));
    A = ((wsumx2 * wsumy) - (wsumx * wsumxy)) / delta;
    B = ((sumw * wsumxy) - (wsumx * wsumy)) / delta;


    werrA = (Math.pow(wsumx2 / delta, 0.5));
    werrB = (Math.pow(sumw / delta, 0.5));


}
//  checks compatibility (as before)
private void Chiw(double X[], double Y[]) {

    for (int i = 0; i < X.length; i++) {
        chi += (Math.pow((Y[i] - A - (B * X[i])), 2)) * w[i];
    }

    redchi = chi / (X.length - 2);
}

// interplates non linear date through the ordinary least squares method
private void calculatepar(double v1[], double v2[]) {
    for (double z : v1)
        sumv1 += z;
    for (double z : v2)
        sumv2 += z;

    double avrx = sumv1 / n;
    double avry = sumv2 / n;

    for (int i = 0; i < n; i++)
        v3[i] = (v1[i] - avrx);
    for (int i = 0; i < n; i++) {
        sumv32 += Math.pow(v3[i], 2);
    }
    for (int i = 0; i < n; i++) {
        sumv34 += Math.pow(v3[i], 4);
    }
    for (int i = 0; i < n; i++) {
        sumv3v2 += v3[i] * v2[i];
    }
    for (int i = 0; i < n; i++) {
        sumv32y += (Math.pow(v3[i], 2))*v2[i];
    }

    c = ((n*sumv32y)- (sumv2*sumv32))/((n*sumv34)-(Math.pow(sumv32, 2)));
    b = sumv3v2/sumv32;
    a = ((sumv2*sumv34)-(sumv32*sumv32y))/((n*sumv34)-(Math.pow(sumv32, 2)));
}

}

1 个答案:

答案 0 :(得分:1)

按下清除按钮时,不会清除所有键变量。例如:

private void calculatepar(double v1[], double v2[]) {
    for (double z : v1)
        sumv1 += z;
    for (double z : v2)
        sumv2 += z;

    double avrx = sumv1 / n;
    double avry = sumv2 / n;

    for (int i = 0; i < n; i++)
        v3[i] = (v1[i] - avrx);
    for (int i = 0; i < n; i++) {
        sumv32 += Math.pow(v3[i], 2);
    }
    for (int i = 0; i < n; i++) {
        sumv34 += Math.pow(v3[i], 4);
    }
    for (int i = 0; i < n; i++) {
        sumv3v2 += v3[i] * v2[i];
    }
    for (int i = 0; i < n; i++) {
        sumv32y += (Math.pow(v3[i], 2)) * v2[i];
    }

    c = ((n * sumv32y) - (sumv2 * sumv32)) / ((n * sumv34) - (Math.pow(sumv32, 2)));
    b = sumv3v2 / sumv32;
    a = ((sumv2 * sumv34) - (sumv32 * sumv32y)) / ((n * sumv34) - (Math.pow(sumv32, 2)));
}

您在哪里清除sumv32,smv34 ...?

如果不清除这些值,则在调用此方法时,求和将继续。我建议您努力将 local 之类的变量保留在方法中,并避免仅在方法中使用的变量的类字段,因为这样,变量将在每次调用时重新初始化。方法被调用。

这与您其他计算方法中的问题相同。因此,所有计算方法中的sumw和类似字段都应为 local 变量,并在方法中声明和初始化

例如:

import java.util.Arrays;

public class MathUtils {
    // interpolates non linear date through the ordinary least squares method
    public static TripleValue calculatepar(double v1[], double v2[]) {
        int n = v1.length;
        if (n == 0 || n != v2.length) {
            // invalid values passed in; throw an exception here
            String message = String.format("For values v1: %s and v2: %s",
                    Arrays.toString(v1),
                    Arrays.toString(v2));
            throw new IllegalArgumentException(message);
        }
        double sumv1 = 0;
        double sumv2 = 0;
        double avrx = sumv1 / n;
        double avry = sumv2 / n;
        double[] v3 = new double[n];
        double sumv32 = 0;
        double sumv34 = 0;
        double sumv3v2 = 0;
        double sumv32y = 0;

        for (double z : v1)
            sumv1 += z;
        for (double z : v2)
            sumv2 += z;

        for (int i = 0; i < n; i++)
            v3[i] = (v1[i] - avrx);
        for (int i = 0; i < n; i++) {
            sumv32 += Math.pow(v3[i], 2);
        }
        for (int i = 0; i < n; i++) {
            sumv34 += Math.pow(v3[i], 4);
        }
        for (int i = 0; i < n; i++) {
            sumv3v2 += v3[i] * v2[i];
        }
        for (int i = 0; i < n; i++) {
            sumv32y += (Math.pow(v3[i], 2)) * v2[i];
        }

        double c = ((n * sumv32y) - (sumv2 * sumv32)) / ((n * sumv34) - (Math.pow(sumv32, 2)));
        double b = sumv3v2 / sumv32;
        double a = ((sumv2 * sumv34) - (sumv32 * sumv32y)) / ((n * sumv34) - (Math.pow(sumv32, 2)));

        return new TripleValue(a, b, c);
    }

    // other calculation methods go here
}

// class to hold one set of values returned in the method above
public class TripleValue {
    private double a;
    private double b;
    private double c;

    public TripleValue(double a, double b, double c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    public double getA() {
        return a;
    }

    public double getB() {
        return b;
    }

    public double getC() {
        return c;
    }

}

注释

  • 应更改上面的变量名称,以使它们有意义并使代码具有自注释性。
  • 我不确定您想对avry变量做什么,因为它似乎没有在计算中使用。
  • 无需使用n字段,因为双精度数组长度应保留此值。
  • 我只显示了一种提取的方法,但是您将对所有提取的方法进行类似的操作。
  • 使用安全的计算方法返回结果,而不是将字段设置为副作用。然后,调用代码将根据需要使用返回的值。