C++利用伴隨陣法實(shí)現(xiàn)矩陣求逆
先來一段百度百科上的搜索結(jié)果:
伴隨陣法
定理:n階矩陣為可逆的充分必要條件是A非奇異,且:

其中,是|A|中元素的代數(shù)余子式;矩陣

稱為矩陣A的伴隨矩陣,記作A*,于是有

用此方法求逆矩陣,對(duì)于小型矩陣,特別是二階方陣求逆既方便、快陣,又有規(guī)律可循。因?yàn)槎A可逆矩陣的伴隨矩陣,只需要將主對(duì)角線元素的位置互換,次對(duì)角線的元素變號(hào)即可。
若可逆矩陣是二階或二階以上矩陣,在求逆矩陣的過程中,需要求9個(gè)或9個(gè)以上代數(shù)余子式,還要計(jì)算一個(gè)三階或三階以上行列式,工作量大且中途難免出現(xiàn)符號(hào)及計(jì)算的差錯(cuò)。對(duì)于求出的逆炬陣是否正確,一般要通過來檢驗(yàn)。一旦發(fā)現(xiàn)錯(cuò)誤,必須對(duì)每一計(jì)算逐一排查。
下面我們來設(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;
}
再寫一段計(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)文章
QT5交叉編譯入門級(jí)教程(arm64、mips64)
交叉編譯就是在當(dāng)前系統(tǒng)平臺(tái)上,開發(fā)編譯運(yùn)行于其它平臺(tái)的程序,比如本文硬件環(huán)境是x86平臺(tái),但是編譯出來的程序是在arm64架構(gòu)、mips64等架構(gòu)上運(yùn)行,本文給大家分享QT5交叉編譯入門級(jí)教程(arm64、mips64),感興趣的朋友一起看看吧2023-11-11
如何用C++制作LeetCode刷題小技巧-錯(cuò)題記錄本
這篇文章主要介紹了如何用C++制作LeetCode刷題小技巧-錯(cuò)題記錄本的方法,需要的朋友可以參考下2021-04-04
C語(yǔ)言實(shí)現(xiàn)魔方陣算法(幻方陣 奇魔方 單偶魔方實(shí)現(xiàn))
魔方陣是指由1,2,3……n2填充的,每一行、每一列、對(duì)角線之和均相等的方陣,階數(shù)n = 3,4,5…。魔方陣也稱為幻方陣,看下面的實(shí)現(xiàn)方法吧2013-11-11
C語(yǔ)言實(shí)現(xiàn)雙人貪吃蛇游戲?qū)嵗a
大家好,本篇文章主要講的是C語(yǔ)言實(shí)現(xiàn)雙人貪吃蛇游戲?qū)嵗a,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12
C++ 詳細(xì)講解stack與queue的模擬實(shí)現(xiàn)
C++ Stack(堆棧) 是一個(gè)容器類的改編,為程序員提供了堆棧的全部功能,也就是說實(shí)現(xiàn)了一個(gè)先進(jìn)后出(FILO)的數(shù)據(jù)結(jié)構(gòu),許多程序都使用了 queue 容器。queue 容器可以用來表示超市的結(jié)賬隊(duì)列或服務(wù)器上等待執(zhí)行的數(shù)據(jù)庫(kù)事務(wù)隊(duì)列2022-04-04

