2016-02-26 3 views
0

Почему-то мой метод Якоби переписывает переменную x_old.метод jacobi переписывает старый x

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.00722826 0869565225 -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 позже, я получаю перезаписанную версию. Есть ли способ изменить это, не делая копию матрицы в функции?

+0

Вы повторно объявляете 'old_x' каждый раз через цикл while. Это то, что вы намерены? – bradimus

+0

haha ​​no, мне сказали сделать это в более раннем вопросе, который я опубликовал. Я полагал, что это не повредит, по крайней мере, с точки зрения устранения этой проблемы. –

ответ

0

если кто-нибудь любопытно, этот код работает:

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_old. IIRC, используя знак равенства с java, фактически ссылается на старую переменную (что я делал дважды с b тоже). Используется для Matlab. С помощью функции cholesky, по моему мнению, я считаю, что единственным реальным решением является вызов новой переменной внутри области действия функции, я бы хотел, чтобы этого можно было избежать для проблем с памятью, но опять же, если я хочу сохранить исходный A и создать новая матрица такого же размера, я считаю, что общее потребление памяти не будет сильно изменено. Единственный вопрос, который у меня есть, это то, могу ли я установить double[][] MatrixInsideFunction = A; или мне нужно снова сделать массив копий.