我正在制作雅各比方法的功能。我的问题是我的迭代应该让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;
}
答案 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提出的解决方案非常接近。