C++利用伴随阵法实现矩阵求逆
convective rain 人气:0先来一段百度百科上的搜索结果:
伴随阵法
定理:n阶矩阵为可逆的充分必要条件是A非奇异,且:
其中,是|A|中元素的代数余子式;矩阵
称为矩阵A的伴随矩阵,记作A*,于是有
用此方法求逆矩阵,对于小型矩阵,特别是二阶方阵求逆既方便、快阵,又有规律可循。因为二阶可逆矩阵的伴随矩阵,只需要将主对角线元素的位置互换,次对角线的元素变号即可。
若可逆矩阵是二阶或二阶以上矩阵,在求逆矩阵的过程中,需要求9个或9个以上代数余子式,还要计算一个三阶或三阶以上行列式,工作量大且中途难免出现符号及计算的差错。对于求出的逆炬阵是否正确,一般要通过来检验。一旦发现错误,必须对每一计算逐一排查。
下面我们来设计一下伴随阵法矩阵求逆的C++代码。
首先,需要自定义一个矩阵类型
#include<vector> typedef vector<double> vec; typedef vector<vec> mat;
然后,设计矩阵数乘的代码
mat num_mul(mat A, double num) { mat B(A.size(), vec(A[0].size())); for(int i = 0; i < B.size(); i++) for(int j = 0; j < B[0].size(); j++) B[i][j] = A[i][j] * num; return B; }
再写一段计算伴随矩阵的代码
mat cutoff(mat A, int i, int j) { //切割,划去第1行第i列 mat B(A.size() - 1, vec(A.size() - 1)); for(int c = 0; c < B.size(); c++) for(int r = 0; r < B.size(); r++) B[c][r] = A[c + (c >= i)][r + (r >= j)]; return B; } double det(mat A) { if(A.size() == 1) return A[0][0]; //当A为一阶矩阵时,直接返回A中唯一的元素 double ans = 0; for(int j = 0; j < A.size(); j++) ans += A[0][j] * det(cutoff(A, 0, j)) * (j % 2 ? -1 : 1); return ans; } mat company_mat(mat A) { mat B(A.size(), vec(A.size())); for(int i = 0; i < B.size(); i++) for(int j = 0; j < B.size(); j++) B[j][i] = det(cutoff(A, i, j)) * ((i + j) % 2 ? -1 : 1); //伴随矩阵与原矩阵存在转置关系 return B; }
最后,把我原创的代码分享给大家
#include<iostream> #include<vector> using namespace std; typedef vector<double> vec; typedef vector<vec> mat; mat cutoff(mat A, int i, int j) { //切割,划去第1行第i列 mat B(A.size() - 1, vec(A.size() - 1)); for(int c = 0; c < B.size(); c++) for(int r = 0; r < B.size(); r++) B[c][r] = A[c + (c >= i)][r + (r >= j)]; return B; } double det(mat A) { if(A.size() == 1) return A[0][0]; //当A为一阶矩阵时,直接返回A中唯一的元素 double ans = 0; for(int j = 0; j < A.size(); j++) ans += A[0][j] * det(cutoff(A, 0, j)) * (j % 2 ? -1 : 1); return ans; } mat company_mat(mat A) { mat B(A.size(), vec(A.size())); for(int i = 0; i < B.size(); i++) for(int j = 0; j < B.size(); j++) B[j][i] = det(cutoff(A, i, j)) * ((i + j) % 2 ? -1 : 1); return B; } void output(mat A) { cout << "......\n"; for(int i = 0; i < A.size(); i++) { for(int j = 0; j < A[0].size(); j++) printf("%.2lf ", A[i][j]); cout << '\n'; } cout << "......\n"; } mat num_mul(mat A, double num) { mat B(A.size(), vec(A[0].size())); for(int i = 0; i < B.size(); i++) for(int j = 0; j < B[0].size(); j++) B[i][j] = A[i][j] * num; return B; } int main() { int n; scanf("%d", &n); //输入阶数 if(n == 0) return 0; mat A(n, vec(n)); for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) scanf("%lf", &A[i][j]); //输入A各行各列的元素 mat B = num_mul(company_mat(A), 1 / det(A)); output(B); return 0; }
加载全部内容