高斯赛德尔法
Gauss Seidel Method
我写了一个Gauss-Seidel方法来计算矩阵A的未知x值。网上的另一种方法似乎首先检查行列式是否包含非零,但其他算法,包括我教授的笔记,不进行验证检查。
所以我暂时按照我教授在class中给出的算法,我认为第一个xNew是正确的,因为我在我的计算器上验证了它,但我的其他x值没有更新, 谁能看出为什么?
public static void gaussSeidel(double[][] A, double[] b){
int count = 0;
boolean stop = false;
do{
double[] xNew = new double[b.length]; // x2 = 0, x3 = 0,
double[] xOld = new double[b.length];
for(int i = 0; i < A.length; i++){
double sum = 0.0;
double sum1 = 0.0;
for(int j = 0; j < A.length; j++){
if( j != i)
sum += (A[i][j]*xOld[j]);
sum1 += (A[i][j]*xNew[j]);
}
xNew[i] = (b[i] - sum - sum1)*(1/A[i][i]);
System.out.println("X_" + (i+1) + ": " + xNew[i]);
System.out.println("Error is: " + Math.abs((xNew[i] - xOld[i])));
System.out.println("");
count++;
if(Math.abs(xNew[i] - xOld[i]) > EPSILON){
xNew[i] = xOld[i];
}
else{
stop = true;}
}
}while( !stop && count <= MAX_ITERATIONS);
}
我的矩阵:
double[][] a = {{12,-2,1,0,0,0,0,0,0,0,0},
{-2,12,2,1,0,0,0,0,0,0,0}, {1,-2,12,-2,1,0,0,0,0,0,0}, {0,1,-2,12,-2,1,0,0,0,0,0},
{0,0,1,-2,12,2,1,0,0,0,0}, {0,0,0,1,-2,12,-2,1,0,0,0},
{0,0,0,0,1,-2,12,-2,1,0,0},{0,0,0,0,0,1,-2,12,-2,1,0},
{0,0,0,0,0,0,1,-2,12,-2,0},{0,0,0,0,0,0,0,1,-2,12,0}};
我的 b 值:
double[] b = {13.97, 5.93, -6.02, 8.32, -23.75, 28.45, -8.9, -10.5, 10.34, -38.74};
每次循环时,您都会一次又一次地创建以下数组:
double[] xNew = new double[b.length]; // x2 = 0, x3 = 0,
double[] xOld = new double[b.length];
当然,您丢失了在上一个循环中计算的值。我认为你只需要创建一次,所以在你的循环之外如下:
public static void gaussSeidel(double[][] A, double[] b){
int count = 0;
boolean stop = false;
double[] xNew = new double[b.length]; // x2 = 0, x3 = 0,
double[] xOld = new double[b.length];
do{
for(int i = 0; i < A.length; i++){
double sum = 0.0;
double sum1 = 0.0;
for(int j = 0; j < A.length; j++){
if( j != i)
sum += (A[i][j]*xOld[j]);
sum1 += (A[i][j]*xNew[j]);
}
xNew[i] = (b[i] - sum - sum1)*(1/A[i][i]);
System.out.println("X_" + (i+1) + ": " + xNew[i]);
System.out.println("Error is: " + Math.abs((xNew[i] - xOld[i])));
System.out.println("");
count++;
if(Math.abs(xNew[i] - xOld[i]) > EPSILON){
xNew[i] = xOld[i];
}
else{
stop = true;}
}
}while( !stop && count <= MAX_ITERATIONS);
}
我写了一个Gauss-Seidel方法来计算矩阵A的未知x值。网上的另一种方法似乎首先检查行列式是否包含非零,但其他算法,包括我教授的笔记,不进行验证检查。
所以我暂时按照我教授在class中给出的算法,我认为第一个xNew是正确的,因为我在我的计算器上验证了它,但我的其他x值没有更新, 谁能看出为什么?
public static void gaussSeidel(double[][] A, double[] b){
int count = 0;
boolean stop = false;
do{
double[] xNew = new double[b.length]; // x2 = 0, x3 = 0,
double[] xOld = new double[b.length];
for(int i = 0; i < A.length; i++){
double sum = 0.0;
double sum1 = 0.0;
for(int j = 0; j < A.length; j++){
if( j != i)
sum += (A[i][j]*xOld[j]);
sum1 += (A[i][j]*xNew[j]);
}
xNew[i] = (b[i] - sum - sum1)*(1/A[i][i]);
System.out.println("X_" + (i+1) + ": " + xNew[i]);
System.out.println("Error is: " + Math.abs((xNew[i] - xOld[i])));
System.out.println("");
count++;
if(Math.abs(xNew[i] - xOld[i]) > EPSILON){
xNew[i] = xOld[i];
}
else{
stop = true;}
}
}while( !stop && count <= MAX_ITERATIONS);
}
我的矩阵:
double[][] a = {{12,-2,1,0,0,0,0,0,0,0,0},
{-2,12,2,1,0,0,0,0,0,0,0}, {1,-2,12,-2,1,0,0,0,0,0,0}, {0,1,-2,12,-2,1,0,0,0,0,0},
{0,0,1,-2,12,2,1,0,0,0,0}, {0,0,0,1,-2,12,-2,1,0,0,0},
{0,0,0,0,1,-2,12,-2,1,0,0},{0,0,0,0,0,1,-2,12,-2,1,0},
{0,0,0,0,0,0,1,-2,12,-2,0},{0,0,0,0,0,0,0,1,-2,12,0}};
我的 b 值:
double[] b = {13.97, 5.93, -6.02, 8.32, -23.75, 28.45, -8.9, -10.5, 10.34, -38.74};
每次循环时,您都会一次又一次地创建以下数组:
double[] xNew = new double[b.length]; // x2 = 0, x3 = 0,
double[] xOld = new double[b.length];
当然,您丢失了在上一个循环中计算的值。我认为你只需要创建一次,所以在你的循环之外如下:
public static void gaussSeidel(double[][] A, double[] b){
int count = 0;
boolean stop = false;
double[] xNew = new double[b.length]; // x2 = 0, x3 = 0,
double[] xOld = new double[b.length];
do{
for(int i = 0; i < A.length; i++){
double sum = 0.0;
double sum1 = 0.0;
for(int j = 0; j < A.length; j++){
if( j != i)
sum += (A[i][j]*xOld[j]);
sum1 += (A[i][j]*xNew[j]);
}
xNew[i] = (b[i] - sum - sum1)*(1/A[i][i]);
System.out.println("X_" + (i+1) + ": " + xNew[i]);
System.out.println("Error is: " + Math.abs((xNew[i] - xOld[i])));
System.out.println("");
count++;
if(Math.abs(xNew[i] - xOld[i]) > EPSILON){
xNew[i] = xOld[i];
}
else{
stop = true;}
}
}while( !stop && count <= MAX_ITERATIONS);
}