服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++利用伴随阵法实现矩阵求逆

C++利用伴随阵法实现矩阵求逆

2023-03-01 15:41convective rain C/C++

这篇文章主要为大家详细介绍了C++如何利用伴随阵法实现矩阵求逆,文中的示例代码讲解详细,具有一定的学习和借鉴价值,需要的可以参考一下

先来一段百度百科上的搜索结果:

伴随阵法

定理:n阶矩阵为可逆的充分必要条件是A非奇异,且:

C++利用伴随阵法实现矩阵求逆

其中,是|A|中元素的代数余子式;矩阵

C++利用伴随阵法实现矩阵求逆

称为矩阵A的伴随矩阵,记作A*,于是有

C++利用伴随阵法实现矩阵求逆

用此方法求逆矩阵,对于小型矩阵,特别是二阶方阵求逆既方便、快阵,又有规律可循。因为二阶可逆矩阵的伴随矩阵,只需要将主对角线元素的位置互换,次对角线的元素变号即可。

若可逆矩阵是二阶或二阶以上矩阵,在求逆矩阵的过程中,需要求9个或9个以上代数余子式,还要计算一个三阶或三阶以上行列式,工作量大且中途难免出现符号及计算的差错。对于求出的逆炬阵是否正确,一般要通过来检验。一旦发现错误,必须对每一计算逐一排查。

下面我们来设计一下伴随阵法矩阵求逆的C++代码。

首先,需要自定义一个矩阵类型

?
1
2
3
#include<vector>
typedef vector<double> vec;
typedef vector<vec> mat;

然后,设计矩阵数乘的代码

?
1
2
3
4
5
6
7
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;
}

再写一段计算伴随矩阵的代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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;
}

最后,把我原创的代码分享给大家

?
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
#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;
}

以上就是C++利用伴随阵法实现矩阵求逆的详细内容,更多关于C++矩阵求逆的资料请关注服务器之家其它相关文章!

原文链接:https://blog.csdn.net/qq_54180412/article/details/122943327

延伸 · 阅读

精彩推荐