急球c语言!矩阵直接分解法(lu分解法)

Python014

急球c语言!矩阵直接分解法(lu分解法),第1张

以四维为例。系数在M中,常数项在N中

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

void main()

{

int i,j,m,n

double TM=0,TMm=0,TN=0,TNn=0

int NN = 4

double L[4][4]= {{1,0,0,0}, {0,1,0,0}, {0,0,1,0},{0,0,0,1}, }

// M coef 4x4, N const 4x1

double M[4][4]={4,-1,0,2,-1,4,-1,0,0,-1,4,-1,2,0,-1,4}

double N[4][1]={-1,-7,9,0}

for(i=1i<NNi++) {

for(j=0j<ij++) {

for(m=0m<jm++) {

TM=M[i][m] * L[j][m] + TMm

TMm=TM

TM=0

}

M[i][j]=M[i][j]-TMm

TMm=0

L[i][j]=M[i][j]/M[j][j]

}

for(n=0n<in++) {

TN=M[i][n]*L[i][n]+TNn

TNn=TN

TN=0

}

M[i][i]=M[i][i]-TNn

TNn=0

}

// solve

for(i=0i<NNi++) {

for(m=0m<im++) {

TM=L[i][m]*N[m][0]+TMm

TMm=TM

TM=0

}

N[i][0]=N[i][0]-TMm

TMm=0

}

for(i=0i<NNi++) {

N[i][0]=N[i][0]/M[i][i]

}

for(i=NN-1i>=0i--) {

for(m=i+1m<NNm++) {

TM=L[m][i]*N[m][0]+TMm

TMm=TM

TM=0

}

N[i][0]=N[i][0]-TMm

TMm=0

}

for(i=0i<NNi++) printf("%0.2f\n",N[i][0])

}

这里向你推荐一下克鲁特算法(其实就是对高斯列主元消元法进行优化,使之更适合于计算机编程),首先将矩阵A进行LU分解(将系数矩阵分解成一个上三角矩阵和一个下三角矩阵),分解的过程中用到了隐式的主元寻找法,同时利用克鲁特算法可以将两个n*n矩阵压缩到一个n*n矩阵中,大大节省了存储空间提高了计算速度。

方程可化为L*U*x=B,令U*x=y --->L*y=B

然后利用回代先求y,再利用y求x

因为该方法在求解过程中不涉及增广矩阵所以矩阵B几乎不参与什么运算,所以它的计算速度应该能够达到高斯列主元消元法的三倍,但原理与其基本一致。

而且我在程序中使用了动态数组方便你今后进行扩展。

以下程序按照《矩阵论第二版》和《C语言数值计算法方法大全》编写,LU分解部分程序主要参考了《C语言数值计算法方法大全》第二章的程序

如果你需要详细的理论讲解我可以将这两本书和源程序发给你,上面的论述相当详细足够你答辩用的了,我的邮箱[email protected]

计算结果:

A矩阵:

2 2 5

3 4 7

1 3 3

B矩阵:

5

6

5

解矩阵:

x 1=-7

x 2=0.333333

x 3=3.66667

Press any key to continue

#include <cmath>

#include <iostream>

#include <iomanip>

#include <cstdlib>

#include <functional>

#include <vector>

#include <algorithm>

using namespace std

#define TINY 1.0e-20 //A small number.

#define N 3

void ludcmp(vector<vector<float>>&a, int n, vector<int>&indx, float &d)//对矩阵进行LU分解

void lubksb(vector<vector<float>>&a, int n, vector<int>&indx, vector<float>&b)//对矩阵进行前向和后向回代

void root(vector<vector<float>>&x,vector<float>&col)//解方程结果保存在y中

void iniv(vector<vector<float>>&x,vector<float>line,int n)//对二维动态数组进行初始化

void main()

{

int i,j,n=N//输入矩阵的维数

float A[N][N]={{2,2,5},{3,4,7},{1,3,3}}//左边A矩阵

float B[N]={5,6,5}//右边B矩阵

vector<vector<float>>x//建立动态二维数组存放A,保证你的程序进行扩展时只改A,B,N

vector<float>line

vector<float>y(n)//建立动态数组存放B

iniv(x,line,n)

y.clear()

for(i=0i<ni++)//将A赋给x,B赋给y

{

y.push_back(B[i])

for(j=0j<nj++)

{

x[i].push_back(A[i][j])

}

}

cout<<"A矩阵:"<<endl

for(i=0i<ni++)

{

for(j=0j<nj++)

{

cout<<setw(2)<<setiosflags(ios::left)<<setw(2)<<x[i][j]<<" "

}

cout<<endl

}

cout<<"B矩阵:"<<endl

for(i=0i<ni++)

{

cout<<setw(2)<<setiosflags(ios::left)<<setw(2)<<y[i]<<endl

}

root(x,y)//求根

cout<<"解矩阵:"<<endl

for(i=0i<ni++)

{

cout<<setw(2)<<setiosflags(ios::left)<<"x"<<i+1<<"="<<y[i]<<endl

}

cout<<endl

}

void root(vector<vector<float>>&x,vector<float>&col)

{

int n=x.size(),i=0,j=0

vector<int>index(n)//用于记录寻找主元素过程中对矩阵的初等变换

index.clear()

float m=1.0//记录变换方式,此程序中无用

ludcmp(x,n,index,m)//进行LU分解

lubksb(x,n,index,col)//根据分解结果进行回带

}

//以下程序按照《矩阵论第二版》和《C语言数值计算法方法大全》编写,LU分解部分程序主要参考了《C语言数值计算法方法大全》第二章的程序

//如果你需要详细的理论讲解我可以将这两本书和源程序发给你,我的邮箱[email protected]

void ludcmp(vector<vector<float>>&a, int n, vector<int>&indx, float &d)

{

int i,imax,j,k

float big=0,dum=0,sum=0,temp=0

vector<float>vv(n)

vv.clear()

d=1.0

for (i=0i<ni++)

{

big=0.0

for (j=0j<nj++)

if ((temp=fabs(a[i][j])) >big)

big=temp

vv[i]=1.0/big

}

for (j=0j<nj++)

{

for (i=0i<ji++)

{

sum=a[i][j]

for (k=0k<ik++)

sum -= a[i][k]*a[k][j]

a[i][j]=sum

}

big=0.0

for (i=ji<ni++)

{

sum=a[i][j]

for (k=0k<jk++)

sum -= a[i][k]*a[k][j]

a[i][j]=sum

if ( (dum=vv[i]*fabs(sum)) >= big)

{

big=dum

imax=i

}

}

if (j != imax)

{

for (k=0k<nk++)

{

dum=a[imax][k]

a[imax][k]=a[j][k]

a[j][k]=dum

}

d = -(d)

vv[imax]=vv[j]

}

indx[j]=imax

if (a[j][j] == 0.0)

a[j][j]=TINY

if (j != n)

{

dum=1.0/(a[j][j])

for (i=j+1i<ni++)

a[i][j] *= dum

}

}

}

void lubksb(vector<vector<float>>&a, int n, vector<int>&indx, vector<float>&b)

{

int i,ii=0,ip,j

float sum

for(i=0i<ni++)//按LU分解时寻找主元所进行的初等变换进行反边变换。

{

ip=indx[i]

sum=b[ip]

b[ip]=b[i]

b[i]=sum

}

sum=0

for (i=1i<ni++)

{

sum=0

for(j=0j<ij++)

{

sum+=a[i][j]*b[j]

}

b[i]=b[i]-sum

}

b[n-1]=b[n-1]/a[n-1][n-1]

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

{

sum=0

for(j=i+1j<nj++)

{

sum+=a[i][j]*b[j]

}

b[i]=(b[i]-sum)/a[i][i]

}

}

void iniv(vector<vector<float>>&x,vector<float>line,int n)

{

int i,j

for(i=0i<ni++)

{

x.push_back(line)

for(j=0j<nj++)

{

x[i].clear()

}

}

}