我是编码新手(对编码/格式/效率错误等感到抱歉)。 我编写了此程序,该程序可以对测量数据进行插值,并为您提供一些结果(如线路参数,兼容性等)。 我还编写了一个简单的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)));
}
}
答案 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
字段,因为双精度数组长度应保留此值。