数值分析III--求方程组的根
1. 雅克比(Jacobi)迭代法求方程组的根
雅克比迭代法非常简单,对于一个给定的n×n方程组\(\displaystyle A\mathbf {x} =\mathbf {b}\)
\[\displaystyle A={\begin{bmatrix}a_{11}a_{12}\cdots a_{1n}\\a_{21}a_{22}\cdots a_{2n}\\\vdots \vdots \ddots \vdots \\a_{n1}a_{n2}\cdots a_{nn}\end{bmatrix}},\qquad \mathbf {x} ={\begin{bmatrix}x_{1}\\x_{2}\\\vdots \\x_{n}\end{bmatrix}},\qquad \mathbf {b} ={\begin{bmatrix}b_{1}\\b_{2}\\\vdots \\b_{n}\end{bmatrix}}.\]可以把 A分解成两个矩阵
\[\displaystyle A=D+R\qquad \qquad D={\begin{bmatrix}a_{11}0\cdots 0\\0a_{22}\cdots 0\\\vdots \vdots \ddots \vdots \\00\cdots a_{nn}\end{bmatrix}},\qquad R={\begin{bmatrix}0a_{12}\cdots a_{1n}\\a_{21}0\cdots a_{2n}\\\vdots \vdots \ddots \vdots \\a_{n1}a_{n2}\cdots 0\end{bmatrix}}\]方程组可以改写为 \(\displaystyle D\mathbf {x} =\mathbf {b} -R\mathbf {x}\),该公式即为迭代公式。
又可写成 \(\displaystyle \mathbf {x} ^{(k+1)}=D^{-1}(\mathbf {b} -R\mathbf {x} ^{(k)})\)。
注意这种解方程组的问题,矩阵都要满一定的收敛条件,在这里是迭代矩阵的谱半径小于1,\(\rho (D^{-1}R)<1\)。
#include"math.h"
#include"stdio.h"
#include"stdlib.h"
void main()
{
double x1,x2,x3,x11,x22,x33;
int i=0;
printf("No.0008雅克比迭代法求方程组的根\n\n输入初值:");
scanf("%lf %lf %lf",&x1,&x2,&x3);
while(fabs(x11-(1-x2-x3)/(-8.0))>0.001 && fabs(x22-(16-x1-x3)/(-5.0))>0.001 && fabs(x33-(7-x1-x2)/(-4.0))>0.001)
{
x11=(1-x2-x3)/(-8.0);//写迭代式
x22=(16-x1-x3)/(-5.0);//写迭代式
x33=(7-x1-x2)/(-4.0);//写迭代式
x1=x11;
x2=x22;
x3=x33;
i++;
}
printf("解为:\nx1=%lf\nx2=%lf \nx3=%lf\n迭代次数:%d\n",x1,x2,x3,i);
system("pause");
}
2. 高斯-赛德尔(Gauss-Seidel)迭代法求方程组的根
高斯-赛德尔迭代法和雅克比迭代法的区别在于,将A分解为一个上三角矩阵和下三角矩阵的形式。
\[\displaystyle A=L_{*}+U\qquad {\text{其中}}\qquad L_{*}={\begin{bmatrix}a_{11}0\cdots 0\\a_{21}a_{22}\cdots 0\\\vdots \vdots \ddots \vdots \\a_{n1}a_{n2}\cdots a_{nn}\end{bmatrix}},\quad U={\begin{bmatrix}0a_{12}\cdots a_{1n}\\00\cdots a_{2n}\\\vdots \vdots \ddots \vdots \\00\cdots 0\end{bmatrix}}\]这样,代入迭代式后为:
\[\displaystyle L_{*}\mathbf {x} =\mathbf {b} -U\mathbf {x}\] \[\displaystyle \mathbf {x} ^{(k+1)}=L_{*}^{-1}(\mathbf {b} -U\mathbf {x} ^{(k)})\]系数矩阵 A 严格对角占优或对称正定时,高斯-赛德尔迭代法必收敛。
#include"math.h"
#include"stdio.h"
#include"stdlib.h"
main()
{
double x1,x2,x3,x11,x22,x33;
int i=0;
printf("No.0009高斯赛德尔(Gauss-Seidel)迭代法求方程组的根\n\n输入初值:");
scanf("%lf %lf %lf",&x1,&x2,&x3);
while(fabs(x11-(1-x2-x3)/(-8.0))>0.01 && fabs(x22-(16-x1-x3)/(-5.0))>0.01 && fabs(x33-(7-x1-x2)/(-4.0))>0.01)
{
x11=x1;x22=x2;x33=x3;
x1=(1-x2-x3)/(-8.0);//写迭代式
x2=(16-x1-x3)/(-5.0);//写迭代式
x3=(7-x1-x2)/(-4.0);//写迭代式
i++;
}
printf("解为:\nx1=%lf\nx2=%lf \nx3=%lf\n迭代次数:%d\n",x1,x2,x3,i);
system("pause");
}
3. 牛顿迭代法求方程组的根
这个根牛顿迭代法求解方程的根一样。。。
\[\displaystyle x_{n+1}=x_{n}-J_{F}(x_{n})^{-1}F(x_{n})\]其中 \(J_{F}(x)\)是雅克比矩阵。
#include"math.h"
#include"stdio.h"
#include"stdlib.h"
main()
{
double x1,x2,x11,x22;
int i=0;
printf("No.0010牛顿迭代法求方程组的根\n\n输入初值:");
scanf("%lf %lf",&x1,&x2);
x11=x1-(2*x2/(2*x2-8*x1)*(x1+2*x2-3)-2/(2*x2-8*x1)*(2*x1*x1+x2*x2-5));//写迭代式
x22=x2-(-4*x1/(2*x2-8*x1)*(x1+2*x2-3)+1/(2*x2-8*x1)*(2*x1*x1+x2*x2-5));
i++;//写迭代式
while(fabs(x11-x1)>0.001 && fabs(x22-x2)>0.001)
{ x1=x11;
x2=x22;
x11=x1-(2*x2/(2*x2-8*x1)*(x1+2*x2-3)-2/(2*x2-8*x1)*(2*x1*x1+x2*x2-5));//写迭代式
x22=x2-(-4*x1/(2*x2-8*x1)*(x1+2*x2-3)+1/(2*x2-8*x1)*(2*x1*x1+x2*x2-5));//写迭代式
i++;
}
printf("解为:\nx1=%lf\nx2=%lf \n迭代次数:%d\n",x11,x22,i);
system("pause");
}