C语言求矩阵的逆矩阵

  • 格式:doc
  • 大小:33.50 KB
  • 文档页数:13

C语言求矩阵的逆矩阵

班级: 自动化1604

小组成员: 潘孝枫 金豆

2017年4月

作业要求:

1. 用C语言编程;

2. 查阅相关资料,至少了解三种以上的求矩阵的逆的方法;

3. 俩人一组,提交大作业报告,含源代码。

方法一:用伴随矩阵求矩阵的逆矩阵(潘孝枫)

最主要的问题就是求解矩阵的逆矩阵,而且是一个动态矩阵

1. 求解矩阵的伴随矩阵,套用求行列式的函数 输入矩阵

功能模块

求矩阵的行列式 求伴随矩阵 求矩阵的逆

解决问题的关键是如何运用一个循环递归将求行列式的函数反复嵌

函数的分块

1. 求矩阵的行列式的函数

2. 求余子式的函数

3. 求逆的函数

#include

#include

#define N 9 //默认行列式最大输入阶数为9

float Fun(int n, float a[N][N] ); //定义行列式计算程序,n为行列式阶数,a为矩阵a

/*主程序*/

int main(void)

{

int n ; //定义阶数n

int i, j, i1, j1,i2 ,j2 ; //定义循环变量

float a[N][N] , b[N][N] , c[N][N]; //定义数组,a为原始录入数组,b为中间变量数组,用于提取与计算余子式,c为输出结果数组

float d; //定义a的行列式值

printf("Input the order of matrix a:"); //输入a的阶数

scanf("%d",&n);

printf("Input matrix a:\n"); //输入矩阵a

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

{

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

{

scanf("%f", &a[i][j]);

}

}

d=Fun( n, a ); //计算a的行列式

if(fabs(d)<1e-6) //判断a的行列式值是否为0

{

printf("The determinant is not invertible!"); //输出“行列式值为0,不可逆 ”

}

else

{

printf("The determinant of a is %f",d); //非0继续运算

if(n==1) //阶数为1的情况

{

c[0][0]=1/d;

}

else //阶数大于1的情况

{

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

{

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

{

for(i1=0, i2=0; i2

{

for(j1=0, j2=0; j2

{

if(i1 == i)

{

i1++;

}

if(j1 == j)

{

j1++;

}

b[i2][j2]=a[i1][j1]; //提取a[i][j]所对应的余子式到矩阵b中

}

}

c[j][i]=pow( -1 , i + j ) * Fun( n - 1 , b)/d; //计算a[i][j]对应的代数余子式,存入矩阵c中并完成转置

}

}

}

printf("\n"); //输出结果

for(i=0;i

{

for(j=0;j

{

printf("%10f",c[i][j]);

}

printf("\n");

}

}

}

/*求行列式*/

float Fun( int n, float a[N][N] ) //定义求矩阵行列式的程序,采用逐步降阶求值

{

float b[N][N]; //定义矩阵b

int i = 0, j = 0; //定义循环变量i,j

float sum = 0; //定义行列式运算结果sum

int c = 0,p = 0; //定义辅助变量c,p

if(n == 1) //行列式阶数为1函数直接返回a[0][0]值

{

return a[0][0];

}

for(i = 0;i < n; i++) //针对行列式第一列展开

{

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

{

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

{

if (c < i) //判断录入数组b时行数值,如果c大于i,则在执行录入数组a时行数下移一行,否则不执行数+1的操作

{

p = 0;

}

else

{

p = 1;

}

b[c][j] = a[c+p][j+1]; //取出a[i][j]第一列每个元素对应的余子式存入数组b中

}

}

sum += a[i][0] * Fun(n - 1, b ) * pow(- 1 , i ); //求出a第一列每个元素代数余子式之和,其中嵌套Fun进行逐步降阶完成高阶行列式计算

}

return sum;

}

方法二:用行初等变换来求矩阵的逆

//应用矩阵初等变换的方法求逆矩阵

//参数说明:

// naturalmat 原矩阵

// num 矩阵的阶数

// InvMat 求解结果,逆矩阵

bool Matrix_Inv(double **naturalmat,int num,double **InvMat)

{

int i,j,k;

double **MatEnhanced;//增广矩阵(A|E)

MatEnhanced = (double**)malloc(num*sizeof(double*));

for(i=0;i

MatEnhanced[i] = (double*)malloc(2*num*sizeof(double));

double *temp;

temp = (double*)malloc(2*num*sizeof(double));

double xishu=1;//初等变换时系数,设初值为1

for(i=0;i

{

for(j=0;j

MatEnhanced[i][j] = naturalmat[i][j];

}

for(i=0;i

{

for(j=num;j<2*num;j++)

MatEnhanced[i][j] = 0;//先将后半部分全部赋值为0

MatEnhanced[i][i+num] = 1;//再将其对角线部分赋值为1

}

//接下来进行初等行变换

for(i=0;i

{

if(MatEnhanced[i][i] == 0)//如果前半部分的对角线上的元素为0,此时进行行变换

{

if(i == num-1)//如果是最后一行,那么说明该矩阵不可

return false;

//对第i行以后的各行进行判断,找到第i个元素不为零的行,并与第i行进行交换

for(j=i;j

{

if(MatEnhanced[j][i] != 0)

{

k = j;//记住该行的行号

break;//退出循环

}

}

//接下来对第i行和第k行进行交换

temp = MatEnhanced[k];//第k行

MatEnhanced[k] = MatEnhanced[i];

MatEnhanced[i] = temp;

//初等变换

for(j=0;j

{

if(j != i)//本行不参与计算