-
Notifications
You must be signed in to change notification settings - Fork 0
/
2.cpp
143 lines (134 loc) · 3.08 KB
/
2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include<iostream>
#include <cmath>
#define N 10
using namespace std;
class Mat
{
public:
int m = 1, n = 1; //行数和列数
double mat[N][N] = { 0 }; //矩阵开始的元素
Mat() {}
Mat(int mm, int nn)
{
m = mm; n = nn;
}
void create();//创建矩阵
void Print();//打印矩阵
void eye();//令矩阵行列下标相同时值为 1,不同时为 0
bool inv(Mat a);//求矩阵的逆
};
void Mat::create()
{
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> mat[i][j];
}
}
}
void Mat::Print()
{
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
cout << mat[i][j] << "\t";
}
cout << endl;
}
}
void Mat::eye()
{
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
if (i == j)
mat[i][j] = 1;
else
mat[i][j] = 0;
}
}
}
bool Mat::inv(Mat a)
{
if (a.n != a.m)
{
cout << "矩阵不可逆" << endl;
return false;
}
m = a.m; n = a.n;
eye(); //创建单位矩阵
//下来进行自上而下的初等行变换,使得矩阵 a.mat 变成单位上三角矩阵
for (int i = 1; i <= m; i++) //注意这里要 i<=m,和之前的上三角矩阵有不同
{ //因为要判断最后一行化为上三角矩阵的最后一行最后一列元素是否为 0
//寻找第 i 列不为零的元素
int k;
for (k = i; k <= m; k++)
{
if (fabs(a.mat[k][i]) > 1e-10) //满足这个条件时,认为这个元素不为0
break;
}
if (k <= m)//说明第 i 列有不为0的元素
{
if (k != i)//说明第 i 行 第 i 列元素为零,需要和其他行交换
{
//交换第 i 行和第 k 行所有元素
for (int j = 1; j <= n; j++)//需从第一个元素交换,注意与之前化上三角矩阵不同
{//使用mat[0][j]作为中间变量交换元素,两个矩阵都要交换
a.mat[0][j] = a.mat[i][j]; a.mat[i][j] = a.mat[k][j]; a.mat[k][j] = a.mat[0][j];
mat[0][j] = mat[i][j]; mat[i][j] = mat[k][j]; mat[k][j] = mat[0][j];
}
}
double b = a.mat[i][i];//倍数
//将矩阵 a.mat 的主对角线元素化为 1
for (int j = 1; j <= n; j++)//从第一个元素开始
{
a.mat[i][j] /= b;
mat[i][j] /= b;
}
for (int j = i + 1; j <= m; j++)
{
//注意本来为 -a.mat[j][i]/a.mat[i][i],因为a.mat[i][i]等于 1,则不需要除它
b = -a.mat[j][i];
for (k = 1; k <= n; k++)
{
a.mat[j][k] += b * a.mat[i][k];//第 i 行 b 倍加到第 j 行
mat[j][k] += b * mat[i][k];
}
}
}
else
{
cout << "不可逆!" << endl;
return false;
}
}
//下面进行自下而上的行变换,将 a.mat 矩阵化为单位矩阵
for (int i = m; i > 1; i--)
{
for (int j = i - 1; j >= 1; j--)
{
double b = -a.mat[j][i];
a.mat[j][i] = 0; //实际上是通过初等行变换将这个元素化为 0,
for (int k = 1; k <= n; k++)
{//通过相同的初等行变换来变换右边矩阵
mat[j][k] += b * mat[i][k];
}
}
}
return true;
}
int main()
{
int n;
cout << "请输入矩阵:" << endl;
cin >> n;
Mat a(n, n);
a.create();
Mat b;
if (b.inv(a))
b.Print();
return 0;
}