雅可比方法函数的迭代

时间:2016-09-26 23:57:18

标签: c++

我正在制作雅各比方法的功能。我的问题是我的迭代应该让x向量元素收敛到1s,但是我的函数中的x向量元素只是变成'nan'而不是1s?

void Jacobi(int n, double (* A)[20], double * b, double * x) 
{
   double sum[20];
   double xnext[20];

   cout << "sum" << endl;
   for (int i = 0 ; i < 20 ; i++)
   {
       sum[i]=0;
       cout << sum[i]<<endl;
   }

   cout << endl;
   cout << endl;

   cout << "xnext" << endl;
   for (int i = 0 ; i < 20 ; i++)
   {
       xnext[i]=0;
       cout << xnext[i]<< endl; 
   }

   //iterations loop
   for (int iter = 0 ; iter < n ; iter++)
   {       
       for (int i = 0; i < 20 ; i++)
       {
           sum[i] = 0;

           for (int j = 0 ; j < 20 ; j++)
           {
           if (i != j)
               sum[i] = sum[i] + (A[i][j] * x[j]) ;
           }

           xnext[i] = (1/A[i][i])*(b[i]-sum[i]);

       }

       cout << endl;

       cout << "xnext "<< iter <<endl;
       for(int i= 0; i < 20 ; i++)
       {
           x[i]=xnext[i];
           cout << x[i]<< endl;
       }

   } 

   cout << endl;

   cout << "New x vector" << endl;
   for (int i = 0 ; i < 20 ; i++)
   {
      cout << x[i] << endl;
   }

   return;
}

int main() 
{
  //defining matrix A
  double A[20][20];    
  //defining vectors x and b
  double x[20];        
  double b[20];
  double sol[20];

  //for Matrix A
  //initialize everything to zero
  memset(A[0], 0, 20*20*sizeof(double));
  // set elements for main three diagonals
  for (int i = 0 ; i< 19; ++i)
  {
      A[i][i] = 2.0; 
      A[i][i+1] = -1.0; 
      A[i+1][i] = -1.0; 
   }
   // set last element
   A[19][19] = 2.0;

   //for vector x
   for (int i = 0 ; i < 20 ; ++i)
   {
       x[i]=0;
   }

   //for vector b
   for (int i = 0 ; i < 20 ; i++)
   {
       if (i=0)
          b[i]=1;
       else if (i=19)
          b[i]=1;
       else
          b[i]=0;
   }           


   //for vector solution
   for (int i = 0 ; i < 20 ; i++)
   {
       sol[i] = 1 ;
   }           

   double * ptr[20];
   for (int i= 0; i < 20 ; i++)
       ptr[i] = A[i];

   cout << "x vector" << endl;
   cout << endl;
   for (int i = 0 ; i < 20 ; ++i)
   {
       cout << x[i] << endl;
   }

   cout << endl;

   //using Gauss-Seidel Function
   Jacobi(40, A , b , x); 




   return 0;
}

1 个答案:

答案 0 :(得分:0)

这几乎是正确的,但存在一些问题。

矩阵A未正确初始化。主对角线填充2.0。但是,当i为19时,用-1.0填充下一个最接近的对角线的代码超出范围。此外,A的其他元素都没有被初始化。这会导致以下变化:

// initialize everything to zero
memset(A[0], 0, 20*20*sizeof(double));
// set elements for main three diagonals
for (int i = 0 ; i< 19; ++i)
{
    A[i][i] = 2.0; 
    A[i][i+1] = -1.0; 
    A[i+1][i] = -1.0; 
}
// set last element
A[19][19] = 2.0;

下一个变化是Jacobi方法本身。 xnext[i] = (1.0/A[i][i])*(b[i] - sum[i]);是下一个x的正确公式。但是,下一行将xnext替换为迭代之间的增量。在将迭代次数增加到600之后,得到的向量最终与Octave提出的解决方案非常接近。