2-2、線形代数方程式

先生王Xiaohuaからのコンテンツ

これは、ハードコアの一種だった、理解することが最初の操作を行い、問題を解決するために、メインの反復手順を使用する方法を学びます

 

方程式を解くための二つの一般的な反復法、それぞれヤコビ反復法(ヤコビ)とガウス - ザイデル反復法(ガウス・ザイデル)

 

完全なヤコビ反復アルゴリズム

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);
}

 

おすすめ

転載: www.cnblogs.com/orxx/p/10956858.html