【问题标题】:jacobi method overwriting old xjacobi 方法覆盖旧 x
【发布时间】:2016-06-09 03:05:10
【问题描述】:

由于某种原因,我的 Jacobi 方法正在覆盖 x_old 变量。

public static double[] Jacobi(double[][] A, double[] b, double tol) {
    int m = b.length;
    double[] x = b;
    double err = tol*100;
    while(err > tol) {
        double[] x_old = x;
        for(int i = 0; i < m; i++) {
            double sum = 0.0;
            for(int j = 0; j < m; j++) {
                if(i != j){
                    sum += A[i][j]*x_old[j];
                }
            }
            System.out.println(sum);
            x[i] = (b[i]-sum)/A[i][i];
        }
        printVector(x);
        printVector(x_old);
        err = norm(subtract(x,x_old));

    }
    return x;
}

测试代码

    double[][] A = {{1.48 , 5.244, 0, -2},{4, 2, 4, 7}, {9, 2, 11, -3}, {-1, 0.2, 3, 12}};
    double[][] B = {{92 , 1.3, 0.5, 0.5},{2, 23.3, 1, 0.3}, {0, -2, 28, 3.3}, {-1, 0.2, 3, 12}};
    double[][] v = {{2 , 1, 1, 0},{4, 3, 3, 1}, {8, 7, 9, 5}, {6, 7, 9, 8}};
    double[] x = {-2, 4, 13.2, 0.22};
    double[] y = {1.5, -3, 8.87, 0.6};

    double[] c = MyMath.Jacobi(B,y,1e-10);

结果

0.8349999999999993 9.06445652173913 3.015575667102071 0.516473922373577

[0.007228260869565225 -0.5177878335510356 0.20908658331778313 0.0069605064688685785] [0.007228260869565225 -0.5177878335510356 0.20908658331778313 0.0069605064688685785]

显然程序退出是因为错误变为零。我不明白这是如何工作的。有任何想法吗?

另外,我还有一个覆盖 A 的函数。

public static double[][] cholesky(double[][] A) {
    int m = A.length; // rows
    double akk, akjkk;
    for(int k = 0 ; k < m ; k++){
        akk = A[k][k];
        for(int j = k+1 ; j < m ; j++){
            akjkk = A[k][j]/akk;
            for(int i = j ; i < m ; i++){
                A[j][i] -= A[k][i]*akjkk;
            }
        }
        for(int i = k ; i < m ; i++){
            A[k][i] /= Math.sqrt(akk);
        }
    }
    return A;
}

我确信有一个明显的解决方案,但是当我将矩阵 U 传递给函数时,然后尝试访问 U,我收到了覆盖的版本。有没有办法在不复制函数中的矩阵的情况下改变它?

【问题讨论】:

  • 您每次都通过while 循环重新声明old_x。这是你想要的吗?
  • 哈哈不,我在之前发布的一个问题中被告知要这样做。我认为至少在解决此问题方面不会受到伤害。

标签: java scope numerical-methods


【解决方案1】:

如果有人好奇这段代码是否有效:

    public static double[] Jacobi(double[][] A, double[] b, double tol) {
    int m = b.length;
    double[] x_old = new double[m];
    double[] x = new double[m];
    double err = tol*10;
    while(err > tol) {
        System.arraycopy(x,0,x_old,0,m);
        for(int i = 0; i < m; i++) {
            double sum = 0.0;
            for(int j = 0; j < m; j++) {
                if(i != j){
                    sum += A[i][j]*x_old[j];
                }
            }
            x[i] = (b[i]-sum)/A[i][i];
        }
        err = norm(subtract(x,x_old));
    }
    return x;
}

设置 x = x_old 时可能是内存分配问题。 IIRC 在 java 中使用等号实际上引用了旧变量(我也用 b 做了两次)。用过matlab。使用 cholesky 函数,根据我的理解,我相信唯一真正的解决方案是在函数范围内调用一个新变量,我希望可以避免内存问题,但话又说回来,如果我想存储原始 A 并创建一个相同大小的新矩阵,我相信整体内存消耗不会有太大变化。我唯一的问题是我是否可以设置double[][] MatrixInsideFunction = A;,或者我是否必须再次复制数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    • 2018-06-21
    • 1970-01-01
    • 2012-05-30
    • 1970-01-01
    相关资源
    最近更新 更多