- 矩阵求逆c++实现
高斯消元法可以用来找出一个可逆矩阵的逆矩阵。设A 为一个N * N的矩阵,其逆矩阵可被两个分块矩阵表示出来。将一个N * N单位矩阵 放在A 的右手边,形成一个N * 2N的分块矩阵B = [A,I] 。经过高斯消元法的计算程序后,矩阵B 的左手边会变成一个单位矩阵I ,而逆矩阵A ^(-1) 会出现在B 的右手边。假如高斯消元法不能将A 化为三角形的格式,那就代表A 是一个不可逆的矩阵。应用上,高斯消元法极少被用来求出逆矩阵。高斯消元法通常只为线性方程组求解。
实验结果:123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263//********************************
//*** 求任何一个实矩阵的逆***
//********************************
#include
"stdafx.h"
#include <math.h>
#include <malloc.h>
#include <iostream>
#include <iomanip>
using namespace std;
#define N
10
//定义方阵的最大阶数为10
//函数的声明部分
float
MatDet(
float
*p,
int
n);
//求矩阵的行列式
float
Creat_M(
float
*p,
int
m,
int
n,
int
k);
//求矩阵元素A(m, n)的代数余之式
void
print(
float
*p,
int
n);
//输出矩阵n*n
bool Gauss(
float
A[][N],
float
B[][N],
int
n);
//采用部分主元的高斯消去法求方阵A的逆矩阵B
int
main()
{
float
*buffer, *p;
//定义数组首地址指针变量
int
row, num;
//定义矩阵的行数和矩阵元素个数
int
i, j;
float
determ;
//定义矩阵的行列式
float
a[N][N], b[N][N];
int
n;
cout <<
"采用逆矩阵的定义法求矩阵的逆矩阵! "
;
cout <<
"请输入矩阵的行数: "
;
cin >> row;
num =
2
* row * row;
buffer = (
float
*)calloc(num, sizeof(
float
));
//分配内存单元
p = buffer;
if
(NULL != p)
{
for
(i =
0
; i < row; i++)
{
cout <<
"Please input the number of "
<< i+
1
<<
" row: "
;
for
(j =
0
; j < row; j++)
{
cin >> *p++;
}
}
}
else
{
cout <<
"Can't distribute memory "
;
}
cout <<
"The original matrix : "
;
print(buffer, row);
//打印该矩阵
determ = MatDet(buffer, row);
//求整个矩阵的行列式
p = buffer + row * row;
if
(determ !=
0
)
{
cout <<
"The determinant of the matrix is "
<< determ << endl;
for
(i =
0
; i < row; i++)
//求逆矩阵
{
for
(j =
0
; j < row; j++)
{
*(p+j*row+i) = Creat_M(buffer, i, j, row)/determ;
}
}
cout <<
"The inverse matrix is: "
<< endl;
print(p, row);
//打印该矩阵
}
else
{
cout <<
"The determinant is 0, and there is no inverse matrix! "
;
}
free(buffer);
//释放内存空间
cout <<
"采用部分主元的高斯消去法求方阵的逆矩阵! "
;
cout <<
"请输入方阵的阶数: "
;
cin >> n;
cout <<
"请输入"
<< n <<
"阶方阵: "
;
//输入一个n阶方阵
for
(i =
0
; i < n; i++)
{
for
(j =
0
; j < n; j++)
{
cin >> a[i][j];
}
}
//运用高斯消去法求该矩阵的逆矩阵并输出
if
(Gauss(a, b, n))
{
cout <<
"该方阵的逆矩阵为: "
;
for
(i =
0
; i < n; i++)
{
cout << setw(
4
);
for
(j =
0
; j < n; j++)
{
cout << b[i][j] << setw(
10
);
}
cout << endl;
}
}
getchar();
return
0
;
}
//-----------------------------------------------
//功能: 求矩阵(n*n)的行列式
//入口参数: 矩阵的首地址,矩阵的行数
//返回值: 矩阵的行列式值
//----------------------------------------------
float
MatDet(
float
*p,
int
n)
{
int
r, c, m;
int
lop =
0
;
float
result =
0
;
float
mid =
1
;
if
(n !=
1
)
{
lop = (n ==
2
) ?
1
: n;
//控制求和循环次数,若为2阶,则循环1次,否则为n次
for
(m =
0
; m < lop; m++)
{
mid =
1
;
//顺序求和, 主对角线元素相乘之和
for
(r =
0
, c = m; r < n; r++, c++)
{
mid = mid * (*(p+r*n+c%n));
}
result += mid;
}
for
(m =
0
; m < lop; m++)
{
mid =
1
;
//逆序相减, 减去次对角线元素乘积
for
(r =
0
, c = n-
1
-m+n; r < n; r++, c--)
{
mid = mid * (*(p+r*n+c%n));
}
result -= mid;
}
}
else
result = *p;
return
result;
}
//----------------------------------------------------------------------------
//功能: 求k*k矩阵中元素A(m, n)的代数余之式
//入口参数: k*k矩阵的首地址,矩阵元素A的下标m,n,矩阵行数k
//返回值: k*k矩阵中元素A(m, n)的代数余之式
//----------------------------------------------------------------------------
float
Creat_M(
float
*p,
int
m,
int
n,
int
k)
{
int
len;
int
i, j;
float
mid_result =
0
;
int
sign =
1
;
float
*p_creat, *p_mid;
len = (k-
1
)*(k-
1
);
//k阶矩阵的代数余之式为k-1阶矩阵
p_creat = (
float
*)calloc(len, sizeof(
float
));
//分配内存单元
p_mid = p_creat;
for
(i =
0
; i < k; i++)
{
for
(j =
0
; j < k; j++)
{
if
(i != m && j != n)
//将除第i行和第j列外的所有元素存储到以p_mid为首地址的内存单元
{
*p_mid++ = *(p+i*k+j);
}
}
}
sign = (m+n)%
2
==
0
?
1
: -
1
;
//代数余之式前面的正、负号
mid_result = (
float
)sign*MatDet(p_creat, k-
1
);
free(p_creat);
return
mid_result;
}
//-----------------------------------------------------
//功能: 打印n*n矩阵
//入口参数: n*n矩阵的首地址,矩阵的行数n
//返回值: 无返回值
//-----------------------------------------------------
void
print(
float
*p,
int
n)
{
int
i, j;
for
(i =
0
; i < n; i++)
{
cout << setw(
4
);
for
(j =
0
; j < n; j++)
{
cout << setiosflags(ios::right) << *p++ << setw(
10
);
}
cout << endl;
}
}
//------------------------------------------------------------------
//功能: 采用部分主元的高斯消去法求方阵A的逆矩阵B
//入口参数: 输入方阵,输出方阵,方阵阶数
//返回值: true or false
//-------------------------------------------------------------------
bool Gauss(
float
A[][N],
float
B[][N],
int
n)
{
int
i, j, k;
float
max, temp;
float
t[N][N];
//临时矩阵
//将A矩阵存放在临时矩阵t[n][n]中
for
(i =
0
; i < n; i++)
{
for
(j =
0
; j < n; j++)
{
t[i][j] = A[i][j];
}
}
//初始化B矩阵为单位阵
for
(i =
0
; i < n; i++)
{
for
(j =
0
; j < n; j++)
{
B[i][j] = (i == j) ? (
float
)
1
:
0
;
}
}
for
(i =
0
; i < n; i++)
{
//寻找主元
max = t[i][i];
k = i;
for
(j = i+
1
; j < n; j++)
{
if
(fabs(t[j][i]) > fabs(max))
{
max = t[j][i];
k = j;
}
}
//如果主元所在行不是第i行,进行行交换
if
(k != i)
{
for
(j =
0
; j < n; j++)
{
temp = t[i][j];
t[i][j] = t[k][j];
t[k][j] = temp;
//B伴随交换
temp = B[i][j];
B[i][j] = B[k][j];
B[k][j] = temp;
}
}
//判断主元是否为0, 若是, 则矩阵A不是满秩矩阵,不存在逆矩阵
if
(t[i][i] ==
0
)
{
cout <<
"There is no inverse matrix!"
;
return
false
;
}
//消去A的第i列除去i行以外的各行元素
temp = t[i][i];
for
(j =
0
; j < n; j++)
{
t[i][j] = t[i][j] / temp;
//主对角线上的元素变为1
B[i][j] = B[i][j] / temp;
//伴随计算
}
for
(j =
0
; j < n; j++)
//第0行->第n行
{
if
(j != i)
//不是第i行
{
temp = t[j][i];
for
(k =
0
; k < n; k++)
//第j行元素 - i行元素*j列i行元素
{
t[j][k] = t[j][k] - t[i][k]*temp;
B[j][k] = B[j][k] - B[i][k]*temp;
}
}
}
}
getchar();
return
true
;
}</iomanip></iostream></malloc.h></math.h>