2-2, linear algebra equations

Content from teacher Wang Xiaohua

This was sort of hard core, do first to understand, learn how to use the main iterative steps to solve the problem

 

Two common iterative method for solving the equations, respectively Jacobi iterative method (Jacobi) and Gauss - Seidel iterative method (Gauss-Seidel)

 

Complete Jacobi iteration algorithm

const double PRECISION = 0.000000001;
const int VEC_N = 16;  //实际方程组的个数 n 必须小于VEC_N

void jacobi_eqn(double a[][VEC_N], double b[], int n, double x[])
{
    double xt[VEC_N];
    double max_diff = 0.0;

    do
    {
        for (int i = 0; i < n; i++)
        {
            double sum = 0.0;
            for (int k = 0; k < n; k++)
            {
                if (i != k)  //对角线元素不计算
                {
                    sum += a[i][k] * x[k];
                }
            }
            xt[i] = (b[i] - sum) / a[i][i];   //根据关系计算 xi 的新值
        }

        max_diff = calc_max_diff(xt, x, n);

        for (int j = 0; j < n; j++)
        {
            x[j] = xt[j]; //更新 x,准备下一次迭代
        }
    } while (max_diff > PRECISION);
}

 

高斯-赛德尔迭代法
雅可比迭代法每次迭代计算时,将上一次的迭代变量整体带入到迭代关系式中,计算新的迭代变量值,也就是所谓的整体迭代。在迭代收敛的前提下,如果迭代变量中的每个分量 x 在计算出新的迭代值后,直接带入迭代,参与其他迭代分量的计算,则能显著地提高迭代效果,这种改进的方法就是高斯-赛德尔迭代法。
从算法实现的角度理解,这种改进思想就是每计算出一个迭代分量的新迭代值,就立即让它参与到其他迭代分量的计算中,其迭代关系可以理解为:

const double PRECISION = 0.000000001;
const int VEC_N = 16;  //实际方程组的个数 n 必须小于 VEC_N

void gauss_seidel_eqn(double a[][VEC_N], double b[], int n, double x[])
{
    double max_diff = 0.0;

    do
    {
        max_diff = 0.0;
        for (int i = 0; i < n; i++)
        {
            double sum = 0.0;
            for (int k = 0; k < n; k++)
            {
                if (i != k)  //对角线元素不计算
                {
                    sum += a[i][k] * x[k];
                }
            }
            double xt = (b[i] - sum) / a[i][i];   //根据关系计算 xi 的新值
            if (std::fabs(xt - x[i]) > max_diff) //max_diff 只保留差值最大的
            {
                max_diff = std::fabs(xt - x[i]);
            }
            x[i] = xt;
        }
    } while (max_diff > PRECISION);
}

 

Guess you like

Origin www.cnblogs.com/orxx/p/10956858.html