《计算方法》 李晓红等 第三章 解线性方程组的直接法 例题 代码

#include "stdafx.h"

#include

// 解线性方程组的直接法

 

void PS(double A[], int n, char *name);

void GaussXiaoQu()

{

    printf("高斯直接消元法:\n");

    double a[3][3] = {{2,4,-2},{1,-1,5},{4,1,-2}};

    double b[3] = {6,0,2};

    double x[3];

 

    int n = 3;

    int k,i,j;

    double l;

 

    // 消元

    for (k = 0; k < n-1; k++)

    {

        for (i = k+1; i < n; i++)

        {

            l = a[i][k]/a[k][k];

            b[i] = b[i] - l*b[k];

            for (j = k; j < n; j++)

            {

                a[i][j] = a[i][j] - l*a[k][j];

            }

        }          

    }

    // 消元结果

    for (i = 0; i < n; i++)

    {

        for (j = 0; j < n; j++)

            printf("%f\t",a[i][j]);

        printf("%f",b[i]);

        printf("\n");

    }

    // 回代

    for (i = n-1; i >= 0; i--)

    {

        x[i] = b[i];

        for (j = n-1; j > i; j--)

            x[i] = x[i] - a[i][j]*x[j];

        x[i] = x[i] / a[i][i];

    }

    printf("x= ");

    for(i = 0; i < n; i++)

        printf("%f\t",x[i]);

    printf("\n");

}

 

void GaussLieZhuYuan()

{

    printf("高斯列主元法:\n");

    double a[3][3] = {{1,2,3},{5,4,10},{3,-0.1,1}};

    double b[3] = {1,0,2};

    double x[3];

 

    int n = 3;  // 系数矩阵维数

    int k,i,j;

    double l;

    double tmp;

    int r;

 

    // 消元

    for (k = 0; k < n-1; k++)

    {

        // 找到该列最大元

        for (r=k,j=k+1; j < n; j++) {

            if (abs(a[j][k]) > abs(a[r][k]))

            {

                r = j;

            }

        }

        // 行交换

        if (r != k)

        {

            for (j = k; j < n; j++) {

                tmp = a[k][j];

                a[k][j] = a[r][j];

                a[r][j] = tmp;

            }

            tmp = b[k];

            b[k] = b[r];

            b[r] = tmp;

        }

        // 消元

        for (i = k+1; i < n; i++)

        {

            l = a[i][k]/a[k][k];

            b[i] = b[i] - l*b[k];

            for (j = k; j < n; j++)

            {

                a[i][j] = a[i][j] - l*a[k][j];

            }

        }          

    }

    // 消元结果

    for (i = 0; i < n; i++)

    {

        for (j = 0; j < n; j++)

            printf("%f\t",a[i][j]);

        printf("%f",b[i]);

        printf("\n");

    }

    // 回代

    for (i = n-1; i >= 0; i--)

    {

        x[i] = b[i];

        for (j = n-1; j > i; j--)

            x[i] = x[i] - a[i][j]*x[j];

        x[i] = x[i] / a[i][i];

    }

    printf("x= ");

    for (i = 0; i < n; i++) {

        printf("%f\t",x[i]);

    }

    printf("\n");

}

 

void GaussQuanZhuYuan()

{

    printf("高斯全主元法:\n");

    double a[3][3] = {{1,2,3},{5,4,10},{3,-0.1,1}};

    double b[3] = {1,0,2};

    double x[3];

    double y[3];

 

    int n = 3;  // 系数矩阵维数

    int k,i,j;

    double l;

    double tmp;

    int r,c;

    int p[3] = {0,1,2},q;

    // 消元

    for (k = 0; k < n-1; k++)

    {

        // 找到子矩阵内最大元

        r = c = k;

        for (i = k; i < n; i++) {

            for (j = k; j < n; j++) {

                if (abs(a[i][j]) > abs(a[r][c]))

                {

                    r = i;

                    c = j;

                }

            }

        }

 

        // 行交换 k~r

        if (r != k)

        {

            for (j = k; j < n; j++) {

                tmp = a[k][j];

                a[k][j] = a[r][j];

                a[r][j] = tmp;

            }

            tmp = b[k];

            b[k] = b[r];

            b[r] = tmp;

        }

        // 交换列 k~c

        if (c != k)

        {

            for (i = 0; i < n; i++) {

                tmp = a[i][k];

                a[i][k] = a[i][c];

                a[i][c] = tmp;

            }

            q = p[k];

            p[k] = p[c];

            p[c] = q;

        }

        // 消元

        for (i = k+1; i < n; i++)

        {

            l = a[i][k]/a[k][k];

            b[i] = b[i] - l*b[k];

            for (j = k; j < n; j++)

            {

                a[i][j] = a[i][j] - l*a[k][j];

            }

        }          

    }

    // 消元结果

    for (i = 0; i < n; i++)

    {

        for (j = 0; j < n; j++)

            printf("%f\t",a[i][j]);

        printf("%f",b[i]);

        printf("\n");

    }

    // 回代

    for (i = n-1; i >= 0; i--)

    {

        x[i] = b[i];

        for (j = n-1; j > i; j--)

            x[i] = x[i] - a[i][j]*x[j];

        x[i] = x[i] / a[i][i];

    }

     

    printf("x= ");

    for (i = 0; i < n; i++) {

        for (j = 0; j < n; j++)

        {

            if (i == p[j])

            {

                y[i] = x[j];

            }

        }

        printf("%f\t",y[i]);

    }

    printf("\n");

}

 

void GaussYueDangMethod()

{

    printf("高斯约当消去法(列主元):\n");

    double a[3][3] = {{1,-1,0},{2,2,3},{-1,2,1}};

    double b[3] = {1,0,0};

    double x[3];

 

    int n = 3;  // 系数矩阵维数

    int k,i,j;

    double l;

    double tmp;

    int r;

 

    // 消元

    for (k = 0; k < n; k++)

    {

        // 找到该列最大元

        for (r=k,j=k+1; j < n; j++) {

            if (abs(a[j][k]) > abs(a[r][k]))

            {

                r = j;

            }

        }

        // 行交换

        if (r != k)

        {

            for (j = k; j < n; j++) {

                tmp = a[k][j];

                a[k][j] = a[r][j];

                a[r][j] = tmp;

            }

            tmp = b[k];

            b[k] = b[r];

            b[r] = tmp;

        }

        // 消元

        for (i = 0; i < n; i++) {

            if (i == k)

                continue;

            else

            {

                l = a[i][k]/a[k][k];

                b[i] = b[i] - l*b[k];

                for (j = k; j < n; j++)

                {

                    a[i][j] = a[i][j] - l*a[k][j];

                }

            }

        }

        // 消去本行

        l = a[k][k];

        for (j = k; j < n; j++)

            a[k][j] = a[k][j] / l;

        b[k] = b[k] / l;

        // 消元结果

        for (i = 0; i < n; i++)

        {

            for (j = 0; j < n; j++)

                printf("%f\t",a[i][j]);

            printf("%f",b[i]);

            printf("\n");

        }

        printf("\n");

    }

/*  // 消元结果

    for (i = 0; i < n; i++)

    {

        for (j = 0; j < n; j++)

            printf("%f\t",a[i][j]);

        printf("%f",b[i]);

        printf("\n");

    }

*/  // 回代

    for (i = n-1; i >= 0; i--)

    {

        x[i] = b[i];

    }

    printf("x= ");

    for (i = 0; i < n; i++) {

        printf("%f\t",x[i]);

    }

    printf("\n");

}

 

void ZhuiGanMethod_I()

{

    printf("三对角方程追赶法I:\n");

    double p[3];

    double q[2];

    double a[3][3] = {{6,1,0},{1,4,1},{6,1,14}};

    double d[3] = {6,24,322};

    double x[3];

    int k;

    int n = 3;

    double l;

 

    p[0] = d[0]/a[0][0];

    q[0] = a[0][1]/a[0][0];

    for (k = 1; k < n; k++) {

        l = a[k][k] - a[k][k-1]*q[k-1];

        p[k] = (d[k]-a[k][k-1]*p[k-1])/l;

        if(k

    }

    // p,q结果

    for (k = 0; k < n; k++)

        printf("p[%d]=%f\t",k,p[k]);

    printf("\n");

    for (k = 0; k < n-1; k++)

        printf("q[%d]=%f\t",k,q[k]);

    printf("\n");

    // 回代

    x[n-1] = p[n-1];

    for (k = n-2; k >= 0; k--) {

        x[k] = p[k]-q[k]*x[k+1];

    }

    for (k = 0; k < n; k++) {

        printf("%f\t",x[k]);

    }

    printf("\n");

}

 

void ZhiJieSanJiaoXing()

{

    printf("直接三角形分解法:\n");

    double a[3][3] = {{2,2,3},{4,7,7},{-2,4,5}};

    double b[3] = {3,1,-7};

     

    double l[3][3],u[3][3];

    int n = 3;

    int i,j;

 

    // LU分解

    int k = 0;;

    int r;

 

    for (k = 0; k < n; k++) {

        // 先计算u

        for (j = 0; j < n; j++) {

            if(j

            else

            {

                u[k][j] = a[k][j];

                for (r = 0; r < k && k > 0; r++) {

                    u[k][j] -= l[k][r]*u[r][j];

                }

            }

        }

        // 后计算l

 

        for (i = 0; i < n; i++) {

 

            if (i

            else if(i==k) l[i][k]=1.;

            else

            {

                l[i][k] = a[i][k];

                for (r = 0; r < k && k > 0; r++) {

                    l[i][k] -= l[i][r]*u[r][k];

                }

                l[i][k] /= u[k][k];

            }

        }

    }

    printf("l=\n");

    for (i = 0; i < n; i++)

    {

        for (j = 0; j < n; j++)

            printf("%f\t",l[i][j]);

        printf("\n");

    }

    printf("u=\n");

    for (i = 0; i < n; i++)

    {

        for (j = 0; j < n; j++)

            printf("%f\t",u[i][j]);

        printf("\n");

    }

 

    // 回代 求y

    // Ly = b

    double y[3];

    y[0] = b[0];

    for (i = 1; i < n; i++) {

        y[i] = b[i];

        for (j = 0; j < i; j++) {

            y[i] = y[i] - l[i][j]*y[j];

        }

    }

    // 求x

    //Ux=y

    double x[3];

    x[n-1] = y[n-1]/u[n-1][n-1];

    for (i = n-2; i >=0; i--) {

        x[i] = y[i];

        for (j = i+1; j < n; j++) {

            x[i] = x[i] - u[i][j]*x[j];

        }

        x[i] /= u[i][i];

    }

 

    printf("x= ");

    for (i = 0; i < n; i++) {

        printf("%f\t",x[i]);

    }

    printf("\n");

}

 

 

 

 

void ZhuiGanMethod_II()

{

    printf("三对角方程追赶法II:\n");

    double p[3];

    double q[2];

    double a[3][3] = {{6,1,0},{1,4,1},{0,1,14}};

    double d[3] = {6,24,322};

    double x[3],y[3];

    int i;

    int n = 3;

     

    // 追

    p[0] = a[0][0];

    q[0] = a[0][1]/p[0];

    for (i = 1; i < n; i++)

    {

        p[i] = a[i][i] - a[i][i-1]*q[i-1];

        if (i

    }

    PS(p,n,"p");PS(q,n-1,"q");

    // 赶

    for (i=0;i

    {

        y[i] = d[i];

        if(i>0) y[i] -= a[i][i-1]*y[i-1];

        y[i] /= p[i];

    }

    for (i=n-1;i>=0;i--) {

        x[i] = y[i];

        if(i

    }

    PS(y,n,"y");PS(x,n,"x");

}

 

 

void PingFangGenMethod()

{

    printf("平方根法: A=LL'\n");

    double a[3][3] = {{6,1,0},{1,4,1},{0,1,14}};

    double b[3] = {6,24,322};

    int n = 3;

    int i,j,k;

    double l[3][3];

    double x[3],y[3];

 

    for (i=0;i

        for (j=0;j

            l[i][j] = 0.;

        }

    }

    // 分解

    for (i=0;i

        // 对角元

        l[i][i] = a[i][i];

        for (k=0;k

            l[i][i] -= l[i][k]*l[i][k];

        }

        l[i][i] = sqrt(l[i][i]);

        // 列元

        for (j=i+1;j

            l[j][i] = a[j][i];

            for (k=0;k

                l[j][i] -= l[j][k]*l[i][k];  // 转置!

            }

            l[j][i] /= l[i][i];

        }

    }

    printf("l=\n");

    for (i = 0; i < n; i++)

    {

        for (j = 0; j < n; j++)

            printf("%f\t",l[i][j]);

        printf("\n");

    }

    // 回代 ,L'y = b

    for (i=0;i

    {

        y[i] = b[i];

        for (j=0;j

            y[i] -= l[i][j]*y[j];  

        }

        y[i] /= l[i][i];

    }

    for (i=n-1;i>=0;i--) {

        x[i] = y[i];

        for(j=n-1;j>i;j--)

            x[i]-=l[j][i]*x[j]; // 主意L 转置, L' x = y

        x[i] /= l[i][i];

    }

    PS(y,n,"y");PS(x,n,"x");

}

 

void GaiJinPingFangMethod() //

{

    printf("改进的平方根法: A=LDL'\n");

     

    double a[3][3] = {{6,1,0},{1,4,1},{0,1,14}};

    double b[3] = {6,24,322};

    int n = 3;

    int i,j,k;

    double l[3][3],u[3][3];

 

    for (i=0;i

        for (j=0;j

            u[i][j] = l[i][j] = 0.;

        }

    }

 

    // LU分解

    int r;

 

    for (k = 0; k < n; k++) {

        // 先计算u

        for (j = k; j < n; j++) {

            u[k][j] = a[k][j];

            for (r = 0; r < k && k > 0; r++) {

                u[k][j] -= l[k][r]*u[r][j];

            }

        }

        // 后计算l, 主意与紧凑格式法差异,运算量减少

        l[k][k] = 1.;

        for (i = k+1; i < n; i++) {

            l[i][k] = u[k][i]/u[k][k];

        }

    }

    printf("l=\n");

    for (i = 0; i < n; i++)

    {

        for (j = 0; j < n; j++)

            printf("%f\t",l[i][j]);

        printf("\n");

    }

    printf("u=\n");

    for (i = 0; i < n; i++)

    {

        for (j = 0; j < n; j++)

            printf("%f\t",u[i][j]);

        printf("\n");

    }

    // 回代 求y

    // Ly = b

    double y[3];

    y[0] = b[0];

    for (i = 1; i < n; i++) {

        y[i] = b[i];

        for (j = 0; j < i; j++) {

            y[i] = y[i] - l[i][j]*y[j];

        }

    }

    // 求x

    //Ux=y

    double x[3];

    x[n-1] = y[n-1]/u[n-1][n-1];

    for (i = n-2; i >=0; i--) {

        x[i] = y[i];

        for (j = i+1; j < n; j++) {

            x[i] = x[i] - u[i][j]*x[j];

        }

        x[i] /= u[i][i];

    }

    PS(x,n,"x");

}

你可能感兴趣的:(计算机)