三角分解法解线性方程组

合集下载

Guass列选主元消去法和三角分解法

Guass列选主元消去法和三角分解法

Guass列选主元消去法和三⾓分解法 最近数值计算学了Guass列主消元法和三⾓分解法解线性⽅程组,具体原理如下:1、Guass列选主元消去法对于AX =B1)、消元过程:将(A|B)进⾏变换为,其中是上三⾓矩阵。

即:k从1到n-1a、列选主元选取第k列中绝对值最⼤元素作为主元。

b、换⾏c、归⼀化d、消元2)、回代过程:由解出。

2、三⾓分解法(Doolittle分解)将A分解为如下形式由矩阵乘法原理a、计算U的第⼀⾏,再计算L的第⼀列b、设已求出U的1⾄r-1⾏,L的1⾄r-1列。

先计算U的第r⾏,再计算L的第r列。

a)计算U的r⾏b)计算L的r列C#代码: 代码说明:Guass列主消元法部分将计算出来的根仍然储存在增⼴矩阵的最后⼀列,⽽Doolittle分解,将分解后的结果也储存⾄原来的数组中,这样可以节约空间。

using System;using System.Windows.Forms;namespace Test{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Cannel_Button_Click(object sender, EventArgs e){this.textBox1.Clear();this.textBox2.Clear();this.textBox3.Clear();boBox1.SelectedIndex = -1;}public double[,] GetNum(string str, int n){string[] strnum = str.Split(' ');double[,] a = new double[n, n + 1];int k = 0;for (int i = 0; i < n; i++){for (int j = 0; j < strnum.Length / n; j++){a[i, j] = double.Parse((strnum[k]).ToString());k++;}}return a;}public void Gauss(double[,] a, int n){int i, j;SelectColE(a, n);for (i = n - 1; i >= 0; i--){for (j = i + 1; j < n; j++)a[i, n] -= a[i, j] * a[j, n];a[i, n] /= a[i, i];}}//选择列主元并进⾏消元public void SelectColE(double[,] a, int n){int i, j, k, maxRowE;double temp; //⽤于记录消元时的因数for (j = 0; j < n; j++){maxRowE = j;for (i = j; i < n; i++)if (System.Math.Abs(a[i, j]) > System.Math.Abs(a[maxRowE, j]))maxRowE = i;if (maxRowE != j)swapRow(a, j, maxRowE, n); //与最⼤主元所在⾏交换//消元for (i = j + 1; i < n; i++){temp = a[i, j] / a[j, j];for (k = j; k < n + 1; k++)a[i, k] -= a[j, k] * temp;}}return;}public void swapRow(double[,] a, int m, int maxRowE, int n){int k;double temp;for (k = m; k < n + 1; k++){temp = a[m, k];a[m, k] = a[maxRowE, k];a[maxRowE, k] = temp;}}public void Doolittle(double[,] a, int n){for (int i = 0; i < n; i++){if (i == 0){for (int j = i + 1; j < n; j++)a[j, 0] = a[j, 0] / a[0, 0];}else{double temp = 0, s = 0;for (int j = i; j < n; j++){for (int k = 0; k < i; k++){temp = temp + a[i, k] * a[k, j];}a[i, j] = a[i, j] - temp;}for (int j = i + 1; j < n; j++){for (int k = 0; k < i; k++){s = s + a[j, k] * a[k, i];}a[j, i] = (a[j, i] - s) / a[i, i];}}}}private void Exit_Button_Click(object sender, EventArgs e){this.Close();}private void Confirm_Button_Click(object sender, EventArgs e){if (this.textBox2.Text.Trim().ToString().Length == 0){this.textBox2.Text = this.textBox1.Text.Trim();}else{this.textBox2.Text = this.textBox2.Text + "\r\n" + this.textBox1.Text.Trim();}this.textBox1.Clear();}private void Calculate_Button_Click(object sender, EventArgs e){string str = this.textBox2.Text.Trim().ToString();string myString = str.Replace("\n", " ").Replace("\r", string.Empty);double[,] a = new double[this.textBox2.Lines.GetUpperBound(0) + 1, this.textBox2.Lines.GetUpperBound(0) + 2];a = GetNum(myString, this.textBox2.Lines.GetUpperBound(0) + 1);if (boBox1.Text == "Guass列主消元法"){Gauss(a, this.textBox2.Lines.GetUpperBound(0) + 1);for (int i = 0; i < this.textBox2.Lines.GetUpperBound(0) + 1; i++){this.textBox3.Text = this.textBox3.Text + "\r\nX" + (i + 1) + "=" + a[i, this.textBox2.Lines.GetUpperBound(0) + 1]; }}else if (boBox1.Text == "Doolittle三⾓分解法"){this.textBox3.Enabled = true;Doolittle(a, this.textBox2.Lines.GetUpperBound(0) + 1);bel3.Text = "分解后的结果:";this.textBox3.Clear();this.textBox3.Text += "L矩阵:\r\n";for (int i = 0; i < this.textBox2.Lines.GetUpperBound(0) + 1; i++) {for (int j = 0; j < this.textBox2.Lines.GetUpperBound(0) + 1; j++) {if (j < i){this.textBox3.Text += a[i, j].ToString() + "\t";}else if (i == j){this.textBox3.Text += "1\t";}else{this.textBox3.Text += "0\t";}}this.textBox3.Text += "\r\n";}this.textBox3.Text += "\r\nU矩阵:\r\n";for (int i = 0; i < this.textBox2.Lines.GetUpperBound(0) + 1; i++) {for (int j = 0; j < this.textBox2.Lines.GetUpperBound(0) + 1; j++) {if (j >= i){this.textBox3.Text += a[i, j].ToString() + "\t";}else{this.textBox3.Text += "0\t";}}this.textBox3.Text += "\r\n";}}}private void textBox1_KeyDown(object sender, KeyEventArgs e){if (e.KeyCode == Keys.Enter){if (this.textBox1.Text.Trim().ToString().Length == 0){Calculate_Button_Click(sender, e);}else{Confirm_Button_Click(sender, e);}}}private void button1_Click(object sender, EventArgs e){this.textBox2.Enabled = true;}}} 运⾏截图: ⾄此完毕。

范数-摆脱课本繁琐的公式,比较好懂

范数-摆脱课本繁琐的公式,比较好懂
p p
p
范数的特殊情况。 注:前三种范数都是p—范数的特殊情况。其中 前三种范数都是 范数的特殊情况
|| X ||∞ = lim || X || p
p →∞
计算方法三 计算方法三⑤
向量范数的连续性: 向量范数的连续性
5/35
定理3.3 设f(X)=||X||为Rn上的任一向量范数 则f(X) 定理 为 上的任一向量范数,则 的分量x 的连续函数. 为X的分量 1,x2,…,xn的连续函数 的分量
lim x i = xi (i = 1,2,..., n)
(k ) k →∞
则称向量X= (x1,x2,...,xn)T为向量序列 则称向量 , {X(k)}的极限,或者说向量序列 (k)}收敛 的极限, 的极限 或者说向量序列{X 收敛 于向量X, 于向量 ,记为
lim X
k →∞
(k )
=X 或 X
(k )
→ X (k → ∞)
计算方法三 计算方法三⑤
计算方法三 计算方法三⑤
x1 (k ) ( k ) x2 X = ………… M x (k ) n (k ) x1 x1 (k ) x2 ( k ) x2 X = → = M M x (k ) x n n
几种常用的矩阵范数: 几种常用的矩阵范数:
n
13/35
a11 a21 设 A= ⋅⋅⋅ a n1
a12 ⋅⋅⋅ a1n A 1 = max∑aij 列范数 1≤j≤n i=1 n a22 ⋅⋅⋅ a2n A ∞ = max∑aij 行范数 ⋅⋅⋅ ⋅⋅⋅ ⋅⋅⋅ 1≤i≤n j=1 T an2 ⋅⋅⋅ ann A 2 = λ (A A) max AF =

用直接三角分解法解线性方程组

用直接三角分解法解线性方程组

三角阵。等式左边是单位下三角阵,右边是上三角阵,要使等式
成则立L , L只1 ,能U等于U单1,位即矩此阵三I。角于分是解L唯1一L1。
UU
1 1
I,
1 2 1
1 2 1
例7 解:
设 A 3 7
1
,试将A进行三角分解。
1 1 3
由高斯消去法得到
m21
3 1
3,m31
1 1
1
m 32
L1
1 1
0 0 1 2
例:

0 1 2
0 1 0
3 0 1
103的PLU分 解 。
解:用1,2, ,n的排列表示n阶置换阵P,其中排列的第i个元素
j,表示P的i行非零元素位于j列。则分解过程如下:
1 0 0 1 2
3 1 1 0 1
3 1 1 0
2 0
43
1 2
0 1 0
3 0 1
0 1 3
Ux j y j
Ly
j
bj
n1
k
n(n 1)
n2
n 次乘法
k 1
2
22
Ux j y j n k n(n 1) n2 n 次乘除法
k 1
2
22
即共需n 2 次乘除法运算。
n 2 次 乘 除 法
三角分解法的存放元素的方法:
以A (a ij )33 为例,
a11 A a21
1 mk1,k 1
k,
Lk1
1 mk1,k 1
k
mnk
1
mn,k
1
A ( L11 L21
L1 n1
)U
LU,1
a (1) 11

线性方程组的数值算法C语言实现(附代码)

线性方程组的数值算法C语言实现(附代码)

线性方程组AX=B 的数值计算方法实验一、 实验描述:随着科学技术的发展,线性代数作为高等数学的一个重要组成部分,在科学实践中得到广泛的应用。

本实验的通过C 语言的算法设计以及编程,来实现高斯消元法、三角分解法和解线性方程组的迭代法(雅可比迭代法和高斯-赛德尔迭代法),对指定方程组进行求解。

二、 实验原理:1、高斯消去法:运用高斯消去法解方程组,通常会用到初等变换,以此来得到与原系数矩阵等价的系数矩阵,达到消元的目的。

初等变换有三种:(a)、(交换变换)对调方程组两行;(b)、用非零常数乘以方程组的某一行;(c)、将方程组的某一行乘以一个非零常数,再加到另一行。

通常利用(c),即用一个方程乘以一个常数,再减去另一个方程来置换另一个方程。

在方程组的增广矩阵中用类似的变换,可以化简系数矩阵,求出其中一个解,然后利用回代法,就可以解出所有的解。

2、选主元:若在解方程组过程中,系数矩阵上的对角元素为零的话,会导致解出的结果不正确。

所以在解方程组过程中要避免此种情况的出现,这就需要选择行的判定条件。

经过行变换,使矩阵对角元素均不为零。

这个过程称为选主元。

选主元分平凡选主元和偏序选主元两种。

平凡选主元:如果()0p pp a ≠,不交换行;如果()0p pp a =,寻找第p 行下满足()0p pp a ≠的第一行,设行数为k ,然后交换第k 行和第p 行。

这样新主元就是非零主元。

偏序选主元:为了减小误差的传播,偏序选主元策略首先检查位于主对角线或主对角线下方第p 列的所有元素,确定行k ,它的元素绝对值最大。

然后如果k p >,则交换第k 行和第p 行。

通常用偏序选主元,可以减小计算误差。

3、三角分解法:由于求解上三角或下三角线性方程组很容易所以在解线性方程组时,可将系数矩阵分解为下三角矩阵和上三角矩阵。

其中下三角矩阵的主对角线为1,上三角矩阵的对角线元素非零。

有如下定理:如果非奇异矩阵A 可表示为下三角矩阵L 和上三角矩阵U 的乘积: A LU = (1) 则A 存在一个三角分解。

三角线性方程组的数值计算

三角线性方程组的数值计算

三角线性方程组的数值计算1. 实验描述有回代的高斯消元法:如果A 是N ×N 非奇异矩阵,则存在线性方程组UX=Y 与线性方程组AX=B 等价,这里U 是上三角矩阵,并且u kk ≠0。

当构造出U 和Y 后,可以用回代法求解UX=Y ,并且得到方程组的解X 。

三角分解法:设线性方程组AX=B 的系数矩阵A 存在三角分解(如果非奇异矩阵A 可以表示为下三角矩阵L 和上三角矩阵U 的乘积:A=LU 则A 存在一个三角分解),则线性方程组可以表示为 LUX=B 而方程组的解可以通过定义Y=UX 并求解下面的俩个方程组得到。

首先对方程组LY=B 求解Y ,然后对方程组UX=Y 求解X 。

雅可比迭代:设矩阵A 具有严格对角优势,则AX=B 有唯一解X=P 利用迭代式(x j(k+1)=b j −a j 1x k −⋯−a jj −1x j −1 k −a jj +1x jj +1 k−⋯a jN x N(k )a jj(其中j=1,2,…,N))可产生一个向量序列﹛P k ﹜,而且对于任意初始向量P 0,向量序列都将收敛到P 0。

高斯-赛德尔迭代:x j(k+1)=b j −a j 1x k +1 −⋯−a jj −1x j −1 k +1 −a jj +1x jj +1 k−⋯−a jN x N(k )a jj2. 实验内容设有如下三角线性方程组,而且系数矩阵具有严格对角优势:d 1x 1+c 1x 1 =b 1a 1+d 2x 2+c 2x 2=b 2a 2x 2+d 3x 3+c 3x 4 =b 3 . . . . . . . . . . . . a N-2x N-2+d N-1x N-1+c N-1x N =b N-1a N-1x N-1+d N x N =b N假设d1=d2=…=dn=12,b1=b2=…=bn=5;c1=c2=..=cn=a1=a2=…=an=-2; 1.用高斯消元法计算;2.采用LU 分解来计算;3.采用雅可比迭代法计算;4.采用高斯-赛德尔迭代法计算。

解线性方程组的三角分解法

解线性方程组的三角分解法

⎛1 0 ⎛1 3 2 1 ⎞ ⎜3 1 ⎜ ⎟ ⎜ 3 13 12 9 ⎜ ⎟ = ⎜2 3 ⎜ 2 12 29 15 ⎟ ⎜ 2 ⎜ ⎟ ⎜ 1 9 15 34 3 ⎝ ⎠ ⎜1 ⎜ 2 ⎝ ⎛1 ⎜ ⎜3 =⎜ ⎜2 ⎜ ⎜ ⎜1 ⎝ 0 1 3 2 3 2 0⎞ ⎟ 0⎟⎛1 ⎜ ⎟⎜0 1 0⎟⎜ 0 ⎟⎜ 1 ⎟ 0 1⎟⎝ 4 ⎠ 0 0
⎛1⎞ 0 0 0 ⎞ ⎛ y1 ⎞ ⎛ 1 ⎞ ⎛ y1 ⎞ ⎜ 5 ⎟ ⎜ ⎟ ⎜ ⎟ ⎟⎜ ⎟ ⎜ ⎟ y 4 0 0 ⎟ ⎜ y2 ⎟ ⎜ 10 ⎟ 2 ⎟。 = ,得到 ⎜ 2 ⎟ = ⎜ ⎜ ⎜ ⎟ ⎜ ⎟ ⎟ ⎜ ⎟ y3 0 16 0 y3 24 3⎟ ⎜ ⎟ ⎜ ⎟ ⎟⎜ ⎟ ⎜ ⎟ 0 0 25 ⎠ ⎝ y4 ⎠ ⎝ 50 ⎠ ⎝ y4 ⎠ ⎜ 2 ⎟ ⎜2⎟ ⎝ ⎠
⎛ 1 0 0 0⎞ ⎜ ⎟ 6 ⎞ ⎜ 2 1 0 0⎟⎛3 ⎟ห้องสมุดไป่ตู้⎟⎜0 6 ⎟ ⎜3 ⎜ ⎟⎜ = 1 8⎟ ⎜ 0 1 0⎟⎜0 ⎟ ⎜3 ⎟⎜ 12 ⎠ ⎜ ⎟⎝0 4 1 0 1 ⎜ ⎟ ⎝3 ⎠
6 3 6⎞ ⎟ 1 0 2⎟ 0 2 6⎟ ⎟ 0 0 2⎠
解方程组
⎛ 1 0 0 0⎞ ⎜ ⎟ ⎜ 2 1 0 0 ⎟ ⎛ y1 ⎞ ⎛ 9 ⎞ ⎜3 ⎟⎜ y ⎟ ⎜ 7 ⎟ ⎜1 ⎟⎜ 2 ⎟ = ⎜ ⎟ 0 1 0 ⎟ ⎜ y3 ⎟ ⎜ 1 ⎟ ⎜ ⎜3 ⎟⎜ ⎟ ⎜ ⎟ ⎜4 ⎟ ⎝ y4 ⎠ ⎝13 ⎠ 1 0 1⎟ ⎜ ⎝3 ⎠
⎛3 ⎜ ⎜2 ⎜1 ⎜ ⎝4
6 3 5 2 2 3
6 6 8
1 0 0 0 1 0 0 0 1
9 4 12 0 0 0
2 3 1 0 2 6 − 3 4 1 0 4 − 3 1 0 2 −

三角分解法解线性方程组

三角分解法解线性方程组

三角分解法解线性方程组#include<iostream.h>#include<iomanip.h>#include<stdlib.h>//----------------------------------------------全局变量定义区 const int Number=15; //方程最大个数doublea[Number][Number],b[Number],copy_a[Number][Number],copy_b[Number]; // 系数行列式int A_y[Number]; //a[][]中随着横坐标增加列坐标的排列顺序,如a[0][0],a[1][2],a[2][1]...则A_y[]={0,2,1...}; int lenth,copy_lenth;//方程的个数char * x; //未知量a,b,c的载体int i,j;//----------------------------------------------函数声明区 voidinput(); //输入方程组void print_menu(); //打印主菜单int Doolittle_check(double a[][Number],double b[Number]); //判断是否行列式>0,若是,调整为顺序主子式全>0void xiaoqu_u_l(); //将行列式Doolittle分解 void calculate_u_l(); //计算Doolittle结果 void exchange(int m,int i); //交换A_y[m],A_y[i] void exchange_lie(int j); //交换a[][j]与b[]; void exchange_hang(int m,int n);//分别交换a[][]和b[]中的m与n两行 void exchange_a_lie(int m,int n); //交换a[][]中的m和n列 void exchange_x(int m,int n); //交换x[]中的x[m]和x[n] //函数定义区void print_menu(){system("cls");cout<<"------------方程系数和常数矩阵表示如下:\n"; for(intj=0;j<lenth;j++)cout<<"系数"<<j+1<<" ";cout<<"\t常数";cout<<endl;for(int i=0;i<lenth;i++){for(j=0;j<lenth;j++)cout<<setw(8)<<setiosflags(ios::left)<<a[i][j];cout<<"\t"<<b[i]<<endl; }}void input(){int i,j;cout<<"方程的个数:";cin>>lenth;if(lenth>Number){cout<<"It is too big.\n";return;}x=new char[lenth];for(i=0;i<lenth;i++)x[i]='a'+i;//输入方程矩阵//提示如何输入cout<<"====================================================\n";cout<<"请在每个方程里输入"<<lenth<<"系数和一个常数:\n"; //输入每个方程for(i=0;i<lenth;i++){cout<<"输入方程"<<i+1<<":";for(j=0;j<lenth;j++)cin>>a[i][j];cin>>b[i];}}void Doolittle() //Doolittle消去法计算方程组 {double temp_a[Number][Number],temp_b[Number];int i,j,flag;for(i=0;i<lenth;i++)for(j=0;j<lenth;j++)temp_a[i][j]=a[i][j]; flag=Doolittle_check(temp_a,temp_b);if(flag==0) cout<<"\n行列式为零.无法用Doolittle求解."; xiaoqu_u_l();calculate_u_l();cout<<"用Doolittle方法求得结果如下:\n";for(i=0;i<lenth;i++) //输出结果{for(j=0;x[j]!='a'+i&&j<lenth;j++);cout<<x[j]<<"="<<b[j]<<endl;}}void calculate_u_l() //计算Doolittle结果{ int i,j;double sum_ax=0; for(i=0;i<lenth;i++){for(j=0,sum_ax=0;j<i;j++)sum_ax+=a[i][j]*b[j];b[i]=b[i]-sum_ax;}for(i=lenth-1;i>=0;i--){for(j=i+1,sum_ax=0;j<lenth;j++)sum_ax+=a[i][j]*b[j];b[i]=(b[i]-sum_ax)/a[i][i]; }}void xiaoqu_u_l() //将行列式按Doolittle分解{ int i,j,n,k;double temp; for(i=1,j=0;i<lenth;i++)a[i][j]=a[i][j]/a[0][0]; for(n=1;n<lenth;n++){ //求第n+1层的上三角矩阵部分即Ufor(j=n;j<lenth;j++){ for(k=0,temp=0;k<n;k++)temp+=a[n][k]*a[k][j];a[n][j]-=temp;}for(i=n+1;i<lenth;i++) //求第n+1层的下三角矩阵部分即L{ for(k=0,temp=0;k<n;k++)temp+=a[i][k]*a[k][n];a[i][n]=(a[i][n]-temp)/a[n][n];}}}int Doolittle_check(double temp_a[][Number],double temp_b[Number]) //若行列式不为零,将系数矩阵调整为顺序主子式大于零{int i,j,k,maxi;double lik,temp;for(k=0;k<lenth-1;k++){j=k;for(maxi=i=k;i<lenth;i++)if(temp_a[i][j]>temp_a[maxi][j]) maxi=i;if(maxi!=k){ exchange_hang(k,maxi);for(j=0;j<lenth;j++){ temp=temp_a[k][j];temp_a[k][j]=temp_a[maxi][j];temp_a[maxi][j]=temp;}}for(i=k+1;i<lenth;i++){lik=temp_a[i][k]/temp_a[k][k];for(j=k;j<lenth;j++)temp_a[i][j]=temp_a[i][j]-temp_a[k][j]*lik;temp_b[i]=temp_b[i]-temp_b[k]*lik;}}if(temp_a[lenth-1][lenth-1]==0) return 0;return 1;}void exchange_hang(int m,int n) //交换a[][]中和b[]两行 { int j; double temp;for(j=0;j<lenth;j++){ temp=a[m][j];a[m][j]=a[n][j];a[n][j]=temp;}temp=b[m];b[m]=b[n];b[n]=temp;}void exchange(int m,int i) //交换A_y[m],A_y[i] { int temp;temp=A_y[m];A_y[m]=A_y[i];A_y[i]=temp;}void exchange_lie(int j) //交换未知量b[]和第i列 { double temp;int i; for(i=0;i<lenth;i++){ temp=a[i][j];a[i][j]=b[i];b[i]=temp;}}void exchange_a_lie(int m,int n) //交换a[]中的两列{ double temp;int i; for(i=0;i<lenth;i++) { temp=a[i][m];a[i][m]=a[i][n];a[i][n]=temp;}}void exchange_x(int m,int n) //交换未知量x[m]与x[n] { char temp;temp=x[m];x[m]=x[n];x[n]=temp;}//主函数void main(){int flag=1;input(); //输入方程while(flag){print_menu(); //打印主菜单cout<<"用Doolittle方法求得结果如下:\n";for(i=0;i<lenth;i++) //输出结果{for(j=0;x[j]!='a'+i&&j<lenth;j++);cout<<x[j]<<"="<<b[j]<<endl;}}}。

列主元高斯消去法和列主元三角分解法解线性方程

列主元高斯消去法和列主元三角分解法解线性方程

计算方法实验报告1课题名称用列主元高斯消去法和列主元三角分解法解线性方程目的和意义高斯消去法是一个古老的求解线性方程组的方法,但由它改进得到的选主元的高斯消去法则是目前计算机上常用的解低阶稠密矩阵方程组的有效方法;用高斯消去法解线性方程组的基本思想时用矩阵行的初等变换将系数矩阵A 约化为具有简单形式的矩阵上三角矩阵、单位矩阵等,而三角形方程组则可以直接回带求解 用高斯消去法解线性方程组b Ax =其中A ∈Rn ×n 的计算量为:乘除法运算步骤为32(1)(1)(21)(1)(1)262233n n n n n n n n n n nMD n ----+=+++=+-,加减运算步骤为(1)(21)(1)(1)(1)(25)6226n n n n n n n n n n AS -----+=++=;相比之下,传统的克莱姆法则则较为繁琐,如求解20阶线性方程组,克莱姆法则大约要19510⨯次乘法,而用高斯消去法只需要3060次乘除法;在高斯消去法运算的过程中,如果出现absAi,i 等于零或过小的情况,则会导致矩阵元素数量级严重增长和舍入误差的扩散,使得最后的计算结果不可靠,所以目前计算机上常用的解低阶稠密矩阵方程的快速有效的方法时列主元高斯消去法,从而使计算结果更加精确; 2、列主元三角分解法高斯消去法的消去过程,实质上是将A 分解为两个三角矩阵的乘积A=LU,并求解Ly=b 的过程;回带过程就是求解上三角方程组Ux=y;所以在实际的运算中,矩阵L 和U 可以直接计算出,而不需要任何中间步骤,从而在计算过程中将高斯消去法的步骤进行了进一步的简略,大大提高了运算速度,这就是三角分解法采用选主元的方式与列主元高斯消去法一样,也是为了避免除数过小,从而保证了计算的精确度计算公式1、 列主元高斯消去法设有线性方程组Ax=b,其中设A 为非奇异矩阵;方程组的增广矩阵为第1步k=1:首先在A 的第一列中选取绝对值最大的元素1l a ,作为第一步的主元素:111211212222112[,]n n n l n nn n a a a a b a a a b a a a b ⎡⎤⎢⎥⎢⎥⎢⎥=⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦a b然后交换A,b 的第1行与第l 行元素,再进行消元计算;设列主元素消去法已经完成第1步到第k -1步的按列选主元,交换两行,消元计算得到与原方程组等价的方程组 Akx=bk第k 步计算如下:对于k=1,2,…,n -11按列选主元:即确定t 使 2如果t ≠k,则交换A,b 第t 行与第k 行元素; 3消元计算消元乘数mik 满足:4回代求解2、 列主元三角分解法 对方程组的增广矩阵 经过k -1步分解后,可变成如下形式:111max 0l i i n a a ≤≤=≠(1)(1)(1)(1)(1)1112111(2)(2)(2)(2)22222()(()1)()()()()()1,1()(,)()[,][,] k k k k nk k nk n k k k k k kk kn k k k k n k k k n nn a a a a b a a a b a a b a b b a a a +++⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥→=⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦A b A b ()()max 0k k tk ik k i na a ≤≤=≠,(1,,)ik ik ik kka a m i k n a ←=-=+, (,1,,), (1,,)ij ij ik kji i ik k a a m a i j k n b b m b i k n ←+=+⎧⎨←+=+⎩⎪⎪⎩⎪⎪⎨⎧--=-←←∑+=)1,,2,1(,)(1n n i a x a b x a b x ii n i j j ij i i nnn n [,]A A b =11121,11111222,122221,11,1,1,211,11,2121,112,112,1k k k k k k k j n k k j n k k k i i i k n n kk kj kn k ik ij in i nknjk k k j k n n nnk k n a a a b A a u u u u u u y l l l l l l ll l l l u u u u u y u u u u y a a b a a b l a -------------⎡→⎣⎤⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎦第k 步分解,为了避免用绝对值很小的数kku 作除数,引进量1111 (,1,,;1,2,,) ()/ (1,2,,;1,2,,)k kj kj km mj m k ik ik im mk kkm u a l u j k k n k n l a l u u i k k n k n -=-=⎧=-=+=⎪⎪⎨⎪=-=++=⎪⎩∑∑11(,1,,)k i ik im mk m s a l u i k k n -==-=+∑,于是有kk u =ks ;如果 ,则将矩阵的第t 行与第k 行元素互换,将i,j 位置的新元素仍记为jjl 或jja ,然后再做第k 步分解,这时列主元高斯消去法程序流程图max t ik i n s s ≤≤= ()/ 1,2,,)1 (1,2,,),kk k k t iki k ik u s s s l s s i k k n l i k k n ===++≤=++即交换前的,(且列主元高斯消去法Matlab主程序function x=gauss1A,b,c %列主元法高斯消去法解线性方程Ax=bif lengthA~=lengthb %判断输入的方程组是否有误disp'输入方程有误'return;enddisp'原方程为AX=b:' %显示方程组Abdisp'------------------------'n=lengthA;for k=1:n-1 %找列主元p,q=maxabsAk:n,k; %找出第k列中的最大值,其下标为p,qq=q+k-1; %q在Ak:n,k中的行号转换为在A中的行号if absp<cdisp'列元素太小,detA≈0';break;elseif q>ktemp1=Ak,:; %列主元所在行不是当前行,将当前行与列主Ak,:=Aq,:; 元所在行交换包括bAq,:=temp1;temp2=bk,:;bk,:=bq,:;bq,:=temp2;end%消元for i=k+1:nmi,k=Ai,k/Ak,k; %Ak,k将Ai,k消为0所乘系数Ai,k:n=Ai,k:n-mi,kAk,k:n; %第i行消元处理bi=bi-mi,kbk; %b消元处理endenddisp'消元后所得到的上三角阵是'A %显示消元后的系数矩阵bn=bn/An,n; %回代求解for i=n-1:-1:1bi=bi-sumAi,i+1:nbi+1:n/Ai,i;endclear x;disp'AX=b的解x是' x=b;调用函数解题列主元三角分解法程序流程图列主元三角分解法Matlab主程序①自己编的程序:function x=PLUA,b,eps %定义函数列主元三角分解法函数if lengthA~=lengthb %判断输入的方程组是否有误disp'输入方程有误'return;enddisp'原方程为AX=b:' %显示方程组Abdisp'------------------------'n=lengthA;A=A b; %将A与b合并,得到增广矩阵for r=1:nif r==1for i=1:nc d=maxabsA:,1; %选取最大列向量,并做行交换if c<=eps %最大值小于e,主元太小,程序结束break;elseendd=d+1-1;p=A1,:;A1,:=Ad,:;Ad,:=p;A1,i=A1,i;endA1,2:n=A1,2:n;A2:n,1=A2:n,1/A1,1; %求u1,ielseur,r=Ar,r-Ar,1:r-1A1:r-1,r; %按照方程求取ur,iif absur,r<=eps %如果ur,r小于e,则交换行p=Ar,:;Ar,:=Ar+1,:;Ar+1,:=p;elseendfor i=r:nAr,i=Ar,i-Ar,1:r-1A1:r-1,i; %根据公式求解,并把结果存在矩阵A中endfor i=r+1:nAi,r=Ai,r-Ai,1:r-1A1:r-1,r/Ar,r; %根据公式求解,并把结果存在矩阵A中endendendy1=A1,n+1;for i=2:nh=0;for k=1:i-1h=h+Ai,kyk;endyi=Ai,n+1-h; %根据公式求解yiendxn=yn/An,n;for i=n-1:-1:1h=0;for k=i+1:nh=h+Ai,kxk;endxi=yi-h/Ai,i; %根据公式求解xiendAdisp'AX=b的解x是'x=x'; %输出方程的解②可直接得到P,L,U并解出方程解的的程序查阅资料得子函数PLU1,其作用是将矩阵A分解成L乘以U的形式;PLU2为调用PLU1解题的程序,是自己编的Ⅰ.function l,u,p=PLU1A %定义子函数,其功能为列主元三角分解系数矩阵A m,n=sizeA; %判断系数矩阵是否为方阵if m~=nerror'矩阵不是方阵'returnendif detA==0 %判断系数矩阵能否被三角分解error'矩阵不能被三角分解'endu=A;p=eyem;l=eyem; %将系数矩阵三角分解,分别求出P,L,Ufor i=1:mfor j=i:mtj=uj,i;for k=1:i-1tj=tj-uj,kuk,i;endenda=i;b=absti;for j=i+1:mif b<abstjb=abstj;a=j;endendif a~=ifor j=1:mc=ui,j;ui,j=ua,j;ua,j=c;endfor j=1:mc=pi,j;pi,j=pa,j;pa,j=c;endc=ta;ta=ti;ti=c;endui,i=ti;for j=i+1:muj,i=tj/ti;endfor j=i+1:mfor k=1:i-1ui,j=ui,j-ui,kuk,j;endendendl=trilu,-1+eyem;u=triuu,0Ⅱ.function x=PLU2A,b %定义列主元三角分解法的函数l,u,p=PLU1A %调用PLU分解系数矩阵A m=lengthA; %由于A左乘p,故b也要左乘p v=b;for q=1:mbq=sumpq,1:mv1:m,1;endb1=b1 %求解方程Ly=b for i=2:1:mbi=bi-sumli,1:i-1b1:i-1;endbm=bm/um,m; %求解方程Ux=y for i=m-1:-1:1bi=bi-sumui,i+1:mbi+1:m/ui,i;endclear x;disp'AX=b的解x是' x=b;调用函数解题①②编程疑难这是第一次用matlab编程,对matlab的语句还不是非常熟悉,因此在编程过程中,出现了许多错误提示;并且此次编程的两种方法对矩阵的运算也比较复杂;问题主要集中在循环控制中,循环次数多了一次或者缺少了一次,导致数据错误,一些基本的编程语句在语法上也会由于生疏而产生许多问题,但是语句的错误由于系统会提示,比较容易进行修改,数据计算过程中的一些逻辑错误,比如循环变量的控制,这些系统不会提示错误,需要我们细心去发现错误,不断修正,调试;。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

三角分解法解线性方程组#include<iostream.h>#include<iomanip.h>#include<stdlib.h>//----------------------------------------------全局变量定义区 const int Number=15; //方程最大个数doublea[Number][Number],b[Number],copy_a[Number][Number],copy_b[Number]; // 系数行列式int A_y[Number]; //a[][]中随着横坐标增加列坐标的排列顺序,如a[0][0],a[1][2],a[2][1]...则A_y[]={0,2,1...}; int lenth,copy_lenth;//方程的个数char * x; //未知量a,b,c的载体int i,j;//----------------------------------------------函数声明区 voidinput(); //输入方程组void print_menu(); //打印主菜单int Doolittle_check(double a[][Number],double b[Number]); //判断是否行列式>0,若是,调整为顺序主子式全>0void xiaoqu_u_l(); //将行列式Doolittle分解 void calculate_u_l(); //计算Doolittle结果 void exchange(int m,int i); //交换A_y[m],A_y[i] void exchange_lie(int j); //交换a[][j]与b[]; void exchange_hang(int m,int n);//分别交换a[][]和b[]中的m与n两行 void exchange_a_lie(int m,int n); //交换a[][]中的m和n列 void exchange_x(int m,int n); //交换x[]中的x[m]和x[n] //函数定义区void print_menu(){system("cls");cout<<"------------方程系数和常数矩阵表示如下:\n"; for(intj=0;j<lenth;j++)cout<<"系数"<<j+1<<" ";cout<<"\t常数";cout<<endl;for(int i=0;i<lenth;i++){for(j=0;j<lenth;j++)cout<<setw(8)<<setiosflags(ios::left)<<a[i][j];cout<<"\t"<<b[i]<<endl; }}void input(){int i,j;cout<<"方程的个数:";cin>>lenth;if(lenth>Number){cout<<"It is too big.\n";return;}x=new char[lenth];for(i=0;i<lenth;i++)x[i]='a'+i;//输入方程矩阵//提示如何输入cout<<"====================================================\n";cout<<"请在每个方程里输入"<<lenth<<"系数和一个常数:\n"; //输入每个方程for(i=0;i<lenth;i++){cout<<"输入方程"<<i+1<<":";for(j=0;j<lenth;j++)cin>>a[i][j];cin>>b[i];}}void Doolittle() //Doolittle消去法计算方程组 {double temp_a[Number][Number],temp_b[Number];int i,j,flag;for(i=0;i<lenth;i++)for(j=0;j<lenth;j++)temp_a[i][j]=a[i][j]; flag=Doolittle_check(temp_a,temp_b);if(flag==0) cout<<"\n行列式为零.无法用Doolittle求解."; xiaoqu_u_l();calculate_u_l();cout<<"用Doolittle方法求得结果如下:\n";for(i=0;i<lenth;i++) //输出结果{for(j=0;x[j]!='a'+i&&j<lenth;j++);cout<<x[j]<<"="<<b[j]<<endl;}}void calculate_u_l() //计算Doolittle结果{ int i,j;double sum_ax=0; for(i=0;i<lenth;i++){for(j=0,sum_ax=0;j<i;j++)sum_ax+=a[i][j]*b[j];b[i]=b[i]-sum_ax;}for(i=lenth-1;i>=0;i--){for(j=i+1,sum_ax=0;j<lenth;j++)sum_ax+=a[i][j]*b[j];b[i]=(b[i]-sum_ax)/a[i][i]; }}void xiaoqu_u_l() //将行列式按Doolittle分解{ int i,j,n,k;double temp; for(i=1,j=0;i<lenth;i++)a[i][j]=a[i][j]/a[0][0]; for(n=1;n<lenth;n++){ //求第n+1层的上三角矩阵部分即Ufor(j=n;j<lenth;j++){ for(k=0,temp=0;k<n;k++)temp+=a[n][k]*a[k][j];a[n][j]-=temp;}for(i=n+1;i<lenth;i++) //求第n+1层的下三角矩阵部分即L{ for(k=0,temp=0;k<n;k++)temp+=a[i][k]*a[k][n];a[i][n]=(a[i][n]-temp)/a[n][n];}}}int Doolittle_check(double temp_a[][Number],double temp_b[Number]) //若行列式不为零,将系数矩阵调整为顺序主子式大于零{int i,j,k,maxi;double lik,temp;for(k=0;k<lenth-1;k++){j=k;for(maxi=i=k;i<lenth;i++)if(temp_a[i][j]>temp_a[maxi][j]) maxi=i;if(maxi!=k){ exchange_hang(k,maxi);for(j=0;j<lenth;j++){ temp=temp_a[k][j];temp_a[k][j]=temp_a[maxi][j];temp_a[maxi][j]=temp;}}for(i=k+1;i<lenth;i++){lik=temp_a[i][k]/temp_a[k][k];for(j=k;j<lenth;j++)temp_a[i][j]=temp_a[i][j]-temp_a[k][j]*lik;temp_b[i]=temp_b[i]-temp_b[k]*lik;}}if(temp_a[lenth-1][lenth-1]==0) return 0;return 1;}void exchange_hang(int m,int n) //交换a[][]中和b[]两行 { int j; double temp;for(j=0;j<lenth;j++){ temp=a[m][j];a[m][j]=a[n][j];a[n][j]=temp;}temp=b[m];b[m]=b[n];b[n]=temp;}void exchange(int m,int i) //交换A_y[m],A_y[i] { int temp;temp=A_y[m];A_y[m]=A_y[i];A_y[i]=temp;}void exchange_lie(int j) //交换未知量b[]和第i列 { double temp;int i; for(i=0;i<lenth;i++){ temp=a[i][j];a[i][j]=b[i];b[i]=temp;}}void exchange_a_lie(int m,int n) //交换a[]中的两列{ double temp;int i; for(i=0;i<lenth;i++) { temp=a[i][m];a[i][m]=a[i][n];a[i][n]=temp;}}void exchange_x(int m,int n) //交换未知量x[m]与x[n] { char temp;temp=x[m];x[m]=x[n];x[n]=temp;}//主函数void main(){int flag=1;input(); //输入方程while(flag){print_menu(); //打印主菜单cout<<"用Doolittle方法求得结果如下:\n";for(i=0;i<lenth;i++) //输出结果{for(j=0;x[j]!='a'+i&&j<lenth;j++);cout<<x[j]<<"="<<b[j]<<endl;}}}。

相关文档
最新文档