C++利用伴隨陣法實(shí)現(xiàn)矩陣求逆
先來(lái)一段百度百科上的搜索結(jié)果:
伴隨陣法
定理:n階矩陣為可逆的充分必要條件是A非奇異,且:
其中,是|A|中元素的代數(shù)余子式;矩陣
稱為矩陣A的伴隨矩陣,記作A*,于是有
用此方法求逆矩陣,對(duì)于小型矩陣,特別是二階方陣求逆既方便、快陣,又有規(guī)律可循。因?yàn)槎A可逆矩陣的伴隨矩陣,只需要將主對(duì)角線元素的位置互換,次對(duì)角線的元素變號(hào)即可。
若可逆矩陣是二階或二階以上矩陣,在求逆矩陣的過(guò)程中,需要求9個(gè)或9個(gè)以上代數(shù)余子式,還要計(jì)算一個(gè)三階或三階以上行列式,工作量大且中途難免出現(xiàn)符號(hào)及計(jì)算的差錯(cuò)。對(duì)于求出的逆炬陣是否正確,一般要通過(guò)來(lái)檢驗(yàn)。一旦發(fā)現(xiàn)錯(cuò)誤,必須對(duì)每一計(jì)算逐一排查。
下面我們來(lái)設(shè)計(jì)一下伴隨陣法矩陣求逆的C++代碼。
首先,需要自定義一個(gè)矩陣類型
#include<vector> typedef vector<double> vec; typedef vector<vec> mat;
然后,設(shè)計(jì)矩陣數(shù)乘的代碼
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; }
再寫(xiě)一段計(jì)算伴隨矩陣的代碼
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]; //當(dāng)A為一階矩陣時(shí),直接返回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); //伴隨矩陣與原矩陣存在轉(zhuǎn)置關(guān)系 return B; }
最后,把我原創(chuàng)的代碼分享給大家
#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]; //當(dāng)A為一階矩陣時(shí),直接返回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); //輸入階數(shù) 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; }
以上就是C++利用伴隨陣法實(shí)現(xiàn)矩陣求逆的詳細(xì)內(nèi)容,更多關(guān)于C++矩陣求逆的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)單元測(cè)試的示例詳解
單元測(cè)試(unit testing),是指對(duì)軟件中的最小可測(cè)試單元進(jìn)行檢查和驗(yàn)證。這篇文章主要為大家介紹了C語(yǔ)言實(shí)現(xiàn)單元測(cè)試的方法,需要的可以參考一下2022-09-09解析設(shè)計(jì)模式中的Prototype原型模式及在C++中的使用
這篇文章主要介紹了設(shè)計(jì)模式中的Prototype原型模式及在C++中的使用,需要的朋友可以參考下2016-03-03手動(dòng)添加bits/stdc++.h到vs2017的詳細(xì)步驟
這篇文章主要介紹了手動(dòng)添加bits/stdc++.h到vs2017的詳細(xì)步驟,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02