NA-PTA-NA Lab4 Jacobi迭代 与 Gauss-Seidel迭代

本文介绍了使用雅可比和高斯-塞德尔迭代方法来求解给定的n×n线性系统Ax=b的程序实现。在雅可比方法中,通过检查每行最大绝对值来交换非零元素到对角线位置。高斯-塞德尔方法则在迭代过程中考虑当前行的更新。函数返回值包括找到解的迭代次数、超过最大迭代次数、零列矩阵和未收敛情况。提供的样例程序展示了这两种方法的输出,并给出了不同的测试用例,包括无唯一解、未达到收敛和超出最大迭代次数的情况。
摘要由CSDN通过智能技术生成

Compare Methods of Jacobi with Gauss-Seidel
Use Jacobi and Gauss-Seidel methods to solve a given n×n linear system Ax=b​ with an initial approximation x​(0)​​ .

Note: When checking each a​ii​​ , first scan downward for the entry with maximum absolute value (a​ii​​ included). If that entry is non-zero, swap it to the diagonal. Otherwise if that entry is zero, scan upward for the entry with maximum absolute value. If that entry is non-zero, then add that row to the i-th row.

Format of functions:

int Jacobi( int n, double a[][MAX_SIZE], double b[], double x[], double TOL, int MAXN );

int Gauss_Seidel( int n, double a[][MAX_SIZE], double b[], double x[], double TOL, int MAXN );

在这里插入图片描述

The function must return:

  • k if there is a solution found after k iterations;
  • 0 if maximum number of iterations exceeded;
  • -1 if the matrix has a zero column and hence no unique solution exists;
  • -2 if there is no convergence, that is, there is an entry of x​(K) that is out of the range [-bound, bound] where bound is a constant defined by the judge.

Sample program of judge:

#include <stdio.h>
#include <math.h>

#define MAX_SIZE 10
#define bound pow(2, 127)
#define ZERO 1e-9 /* X is considered to be 0 if |X|<ZERO */

enum bool { false = 0, true = 1 };
#define bool enum bool

int Jacobi( int n, double a[][MAX_SIZE], double b[], double x[], double TOL, int MAXN );

int Gauss_Seidel( int n, double a[][MAX_SIZE], double b[], double x[], double TOL, int MAXN );

int main()
{
    int n, MAXN, i, j, k;
    double a[MAX_SIZE][MAX_SIZE], b[MAX_SIZE], x[MAX_SIZE];
    double TOL;

    scanf("%d", &n);
    for (i=0; i<n; i++) {
        for (j=0; j<n; j++)
            scanf("%lf", &a[i][j]);
        scanf("%lf", &b[i]);
    }
    scanf("%lf %d", &TOL, &MAXN);

    printf("Result of Jacobi method:\n");
    for ( i=0; i<n; i++ )
        x[i] = 0.0;
    k = Jacobi( n, a, b, x, TOL, MAXN );
    switch ( k ) {
        case -2:
            printf("No convergence.\n");
            break;
        case -1: 
            printf("Matrix has a zero column.  No unique solution exists.\n");
            break;
        case 0:
            printf("Maximum number of iterations exceeded.\n");
            break;
        default:
            printf("no_iteration = %d\n", k);
            for ( j=0; j<n; j++ )
                printf("%.8f\n", x[j]);
            break;
    }
    printf("Result of Gauss-Seidel method:\n");
    for ( i=0; i<n; i++ )
        x[i] = 0.0;
    k = Gauss_Seidel( n, a, b, x, TOL, MAXN );
    switch ( k ) {
        case -2:
            printf("No convergence.\n");
            break;
        case -1: 
            printf("Matrix has a zero column.  No unique solution exists.\n");
            break;
        case 0:
            printf("Maximum number of iterations exceeded.\n");
            break;
        default:
            printf("no_iteration = %d\n", k);
            for ( j=0; j<n; j++ )
                printf("%.8f\n", x[j]);
            break;
    }

    return 0;
}

/* Your function will be put here */

Sample Input 1:

3
2    -1    1    -1
2    2    2    4
-1    -1    2    -5
0.000000001 1000

Sample Output 1:

Result of Jacobi method:
No convergence.
Result of Gauss-Seidel method:
no_iteration = 37
1.00000000
2.00000000
-1.00000000

Sample Input 2:

3
1    2    -2    7
1    1    1    2
2    2    1    5
0.000000001 1000

Sample Output 2:

Result of Jacobi method:
no_iteration = 232
1.00000000
2.00000000
-1.00000000
Result of Gauss-Seidel method:
No convergence.

Sample Input 3:

5
2 1 0 0 0 1
1 2 1 0 0 1
0 1 2 1 0 1
0 0 1 2 1 1
0 0 0 1 2 1
0.000000001 100

Sample Output 3:

Result of Jacobi method:
Maximum number of iterations exceeded.
Result of Gauss-Seidel method:
no_iteration = 65
0.50000000
0.00000000
0.50000000
0.00000000
0.50000000

基本的Jacobi和Gauss-Seidel迭代的应用,分别如下:
在这里插入图片描述
注意在实际代码中不宜选择矩阵形式,因为计算很复杂。

My Answer:

/* Your function will be put here */
#define max(a,b) ((a)>(b)?(a):(b))
#include <stdlib.h>

bool ZeroConlumn(double a[][MAX_SIZE], int n)
{
	for (int j = 0; j < n; j++) {
		bool allzero = true;
		for (int i = 0; i < n; i++) {
			if (a[i][j] != 0) {
				allzero = false;
				break;
			}
		}
		if (allzero)return true;
	}
	return false;
}

bool NoConverge(double x[], int n)
{
	for (int i = 0; i < n; i++)
		if (x[i] > bound || x[i] < -bound) return true;
	return false;
}

void Swap(double a[], double b[], int n)
{
	double* t = (double*)malloc(n * sizeof(double));
	for (int i = 0; i < n; i++) {
		t[i] = a[i]; a[i] = b[i]; b[i] = t[i];
	}

}

double DiffNorm(double a[], double b[], int n)
{
	double m = 0.0;
	for (int i = 0; i < n; i++)
		m = max(m, fabs(a[i] - b[i]));
	return m;
}

int Jacobi(int n, double a[][MAX_SIZE], double b[], double x[], double TOL, int MAXN)
{
	if (ZeroConlumn(a, n))return -1;

	double* x1 = (double*)malloc(n * sizeof(double));
	double* x2 = (double*)malloc(n * sizeof(double));

	for (int i = 0; i < n; i++) x1[i] = x[i];

	int k;
	double sum;
	for (k = 0; k < MAXN; k++) {
		for (int i = 0; i < n; i++) {
			sum = 0;
			for (int j = 0; j < n; j++) {
				if (j == i)continue;
				sum += a[i][j] * x1[j];
			}
			x2[i] = (b[i] - sum) / a[i][i];
		}
		if (DiffNorm(x2, x1, n) < TOL) {						// find the solution
			for (int cnt = 0; cnt < n; cnt++) x[cnt] = x2[cnt];
			return k + 1;
		}
		if (NoConverge(x2, n))return -2;
		Swap(x1, x2, n);
	}
	if (NoConverge(x1, n))return -2;
	if (k == MAXN)return 0;
}

int Gauss_Seidel(int n, double a[][MAX_SIZE], double b[], double x[], double TOL, int MAXN)
{
	if (ZeroConlumn(a, n))return -1;

	double* x1 = (double*)malloc(n * sizeof(double));
	double* x2 = (double*)malloc(n * sizeof(double));

	for (int i = 0; i < n; i++) x1[i] = x[i];

	int k;
	double sum;
	for (k = 0; k < MAXN; k++) {
		for (int i = 0; i < n; i++) {
			sum = 0;
			for (int j = 0; j < n; j++)
			{
				if (j < i) sum += a[i][j] * x2[j];
				if (j > i) sum += a[i][j] * x1[j];
			}
			x2[i] = (b[i] - sum) / a[i][i];
		}
		if (DiffNorm(x2, x1, n) < TOL) {						// find the solution
			for (int cnt = 0; cnt < n; cnt++) x[cnt] = x2[cnt];
			return k + 1;
		}
		if (NoConverge(x2, n))return -2;
		Swap(x1, x2, n);
	}
	if (NoConverge(x1, n))return -2;
	if (k == MAXN)return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值