解线性方程组的直接方法(c语言实现)

在自然科学和工程技术中很多问题的解决常常归结为解线性代数方程组,例如采用差分法或者有限元方法解常微分方程,偏微分方程编制问题等都会导致求解线性代数方程组。

关于线性方程组的数值解法一般分为两类:直接法和迭代法。

本博客主要来介绍直接法

直接法来求解线性方程组的方法主要有以下几种:

1. 高斯消去法。  高斯消去法说白了就是线性代数中所讲过的对于矩阵的初等行变换,但是高斯消去法的局限性很高。

这里将《数值分析》第五版, 清华大学出版社这一书中所举的例子写出来,

对于这一个系数矩阵\begin{bmatrix} 0& 1\\ 1 & 0 \end{bmatrix}, 高斯消去法将无法实现。

2. 列主元高斯消去法。由高斯消去法知道,在消元过程中可能出现akk \neq0但很小时,用其作为除数,会导致其他元素数量级的严重增长和舍入误差的扩散,最后会使得计算解不可靠。于是便有了列主元高斯消去法。

初等行变换的目的是将矩阵化为行阶梯型矩阵,

列主元高斯消去法,说的简单一点便是:假定当前遍历到的行是i, 矩阵的阶数是n, 那么我们需要从i -> n的所有行,找到当前的i行的第一个不为0所在的列索引j, 判断在行数 i -> n ,列数为j上的所有的元素,找到其最大的值,并将最大值所在的行交换到i行。

然后继续进行行阶梯型的变换。

==》 这里我们来说明一点C语言中本身没有矩阵的操作,但是提供了二维数组的存储数据的形式。而在实际内存中,二维数组也是按照1D数组来保存的,且是i行的所有元素写完之后,才会去写i+1行上的元素。且是连续存放的。这里说一句题外话,在Python的numpy模块中,其在创建二维数组或者矩阵的时候,行与行之间在内存中是有间隔的,可以在numpy documentation中查到。所以有时候,我们会去主动地把二维数组写成1维数组。

==》这里我们关于列主元高斯消去法实现了两种方式,分别是把系数矩阵写为2D,和系数矩阵写为1D。

本次程序所计算的实例是:

\begin{bmatrix} 1 & 2 &3 \\ 2 & 5& 2\\ 3 & 1 & 5 \end{bmatrix}\begin{bmatrix} x_{1}\\ x_{2}\\ x_{3} \end{bmatrix}=\begin{bmatrix} 14\\ 18\\ 20 \end{bmatrix}

C语言代码如下所示:

这里要说明两点,1. 关于下面函数的参数Arr,在C语言中规定,二维数组的Arr[][]中,必须至少确定出它的列数是多少。所以之力按照我们所举的例子是3x3阶的矩阵,所以这里确定出了列数。

2. 对应的系数矩阵为什么写成double (*Arr)[3]这种形式,正常情况下,我门写数组的指针,应该是 double *b, 或者 double *b[],

但是因为在c语言中,"[]" 的优先级比"*"要高,所以要加上括号来先取指针。

#include 
/*这里是来创建高斯消去法的函数, 分别采用两种形式,分别是2维矩阵和1维矩阵*/
void Gauss_eliminate(double (*Arr)[3], double *b, int N){
    /* 这里的参数说明:
        1. Arr 是方程组的系数矩阵, 是一个二维方阵
        2. b 是方程组的右端项, 是一个一维数组
        3. N 是矩阵的阶数*/

    // 列主元高斯消去法,需要我们去首先找到列主元
    int max_val_index = 0;
    double effecd = 0.0;
    for(int i=0; i abs(Arr[max_val_index][i])){
                max_val_index = row_i;
            }
        }
        // 待循环结束,便是找到了主元所在列上的最大值所对应的索引
        // 将max_val_index所指示的行交换到主行上去
        double temp = 0.0;
        for(int d=0; d

3. 我们这里还进行了将系数矩阵写成1D数组的编程

C语言代码如下:

void Gauss_elimate1D(double *Arr, double *b, int N){
    // 首先进行主元上的寻找和交换
    int max_val_index = 0;
    double effectd = 0.0;
    for(int i=0; i abs(Arr[max_val_index*N+i])){
                max_val_index = row_i;
            }
        }
        // 循环结束后,便得到了最大主元所在的行,下面进行交换
        double temp = 0.0;
        for(int col_i=i; col_i

运行结果见图:

解线性方程组的直接方法(c语言实现)_第1张图片

程序有什么问题,请留言,大家互相学习。

赞助一点钱给龙猪。

解线性方程组的直接方法(c语言实现)_第2张图片

你可能感兴趣的:(c)