矩阵的逆矩阵,伴随矩阵

简介:

#include<iostream> 
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<sstream>
#include<cmath>
#include<regex>
#define N 100
using namespace std;

template<typename out_type, typename in_value>

out_type convert(const in_value & t){
    stringstream stream;
    stream<<t;//向流中传值
    out_type result;//这里存储转换结果
    stream>>result;//向result中写入值
    return result;
}

struct Number{
    int x, y;
    static int gcd(int a, int b){
        return b==0 ? a : gcd(b, a%b);
    }
    Number(){}
    Number(int xx, int yy=1):x(xx), y(yy){}
    Number operator /(Number tmp){
        return Number(x*tmp.y/(gcd(x*tmp.y, y*tmp.x)), y*tmp.x/gcd(x*tmp.y, y*tmp.x));
    } 
    
    Number operator *(Number tmp){
        return Number(x*tmp.x/gcd(x*tmp.x, y*tmp.y), y*tmp.y/gcd(x*tmp.x, y*tmp.y));
    }
    
    Number operator -(Number tmp){
        int lcm = y*tmp.y/gcd(y, tmp.y);//最小公倍数 
        int xx = lcm/y*x - lcm/tmp.y*tmp.x;
        if(xx==0)
            return Number(0, 1);
        return Number(xx/gcd(xx, lcm), lcm/gcd(xx, lcm));
    }
    
    bool operator ==(Number tmp){
        return x==tmp.x && y==tmp.y;
    }
};


ostream& operator<<(ostream& output, const Number &p){
    output<<setw(10)<<convert<string>(p.x)+"/"+convert<string>(p.y)<<" ";
}

struct Determinant{
    Number d[N][N];
    int n, m;
    Determinant(int nn, int mm): n(nn), m(mm){}
    
    void out_matrix(){
        for(int i=1; i<=n; ++i){
            for(int j=1; j<=m; ++j)
                cout<<d[i][j];
            cout<<endl;
        }
    }
    
    void inverse_matrix_company(Number k){
        for(int i=1; i<=n; ++i)
            for(int j=1; j<=m; ++j)
                d[i][j] = d[i][j]/k;
    } 
    
    bool exchangeRow(int mm, Number x[][N], int r){
        int row = r;
        for(int j=r+1; j<=n; ++j)
            if(!(x[j][r]==Number(0,1))){
                row = j;
                break;
            }
        if(row != r){//交换两行 
            for(int j=1; j<=mm; ++j){
                Number tmp = x[r][j];
                x[r][j] = x[row][j];
                x[row][j] = tmp;
            }
            return true;
        }
        return false;
    }
     
    Number determinantValue(){
        if(n != m)
            return Number(0, 1);
        Number ans(1, 1);
        Number dd[N][N];
        for(int i=1; i<=n; ++i)
            for(int j=1; j<=m; ++j)
                dd[i][j] = d[i][j];
        bool sign = true;
        for(int i=1; i<=n; ++i){
            for(int j=i+1; j<=n; ++j){
                if(dd[i][i]==Number(0, 1)){
                    if(!exchangeRow(n, dd, i)) return Number(0, 1);
                    sign = !sign;
                }
                Number mul = dd[j][i]/dd[i][i];
                for(int k=i; k<=n; ++k)
                    dd[j][k] = dd[j][k]-mul*dd[i][k];
            }
        }
        
        for(int i=1; i<=n; ++i)
            ans = ans*dd[i][i];
        if(!sign) ans.x = -ans.x;
        return ans;
    }
    Determinant inverse_matrix(){
        Determinant inverse(n, m);
        for(int i=1; i<=n; ++i){
            for(int j=1; j<=n; ++j)
                inverse.d[i][j] = d[i][j];
            for(int j=n+1; j<=2*n; ++j)
                inverse.d[i][j] =  j-i == n ? Number(1, 1) : Number(0, 1);
        }
         
        for(int i=1; i<=n; ++i){
            if(inverse.d[i][i]==Number(0,1))
                exchangeRow(2*n, inverse.d, i);
            if(!(inverse.d[i][i]==Number(1,1))){
                Number mul = Number(1,1)/inverse.d[i][i];
                for(int j=i; j<=2*n; ++j)
                    inverse.d[i][j] = inverse.d[i][j]*mul;
            }
            for(int j=i-1; j>=1; --j){
                if(inverse.d[j][i]==Number(0,1)) continue;
                Number mul = inverse.d[j][i]/inverse.d[i][i];
                for(int k=i; k<=2*n; ++k)
                    inverse.d[j][k] = inverse.d[j][k]-inverse.d[i][k]*mul;
            }
            for(int j=i+1; j<=n; ++j){
                if(inverse.d[j][i]==Number(0,1)) continue;
                Number mul = inverse.d[j][i]/inverse.d[i][i];
                for(int k=i; k<=2*n; ++k)
                    inverse.d[j][k] = inverse.d[j][k]-inverse.d[i][k]*mul;
            }
        }
        
        for(int i=1; i<=n; ++i)
            for(int j=1; j<=m; ++j)
                inverse.d[i][j] = inverse.d[i][j+n];
        return inverse;
    }
    
    Determinant company_matrix(){//伴随矩阵 
         Determinant company(n, m);
         for(int i=1; i<=n; ++i)
             for(int j=1; j<=m; ++j){
                 Determinant tmp(n-1, m-1);//余子式 
                 int r=1, c=1;
                 for(int ii=1; ii<=n; ++ii){
                     c=1;
                     if(i!=ii){
                         for(int jj=1; jj<=m; ++jj)
                             if(j!=jj){
                                 tmp.d[r][c] = d[ii][jj];
                                 ++c;
                             }
                         ++r;
                     }
                }
                company.d[j][i] = tmp.determinantValue();//赋给伴随矩阵相应的位置
                if((i+j)&1) company.d[j][i].x = -company.d[j][i].x;
             }
        return company;
    }
};

int main(){
    int n, m;
    int x, y;
    cin>>n>>m; 
    Determinant determinant(n, m);
//    regex patternOne("([a-z]+)\\.([a-z]+)");
//    smatch pieces_match;
    
    for(int i=1; i<=n; ++i){
        string str;
        for(int j=1; j<=n; ++j){
            scanf("%d/%d", &x, &y);
            determinant.d[i][j] = Number(x, y);
        }
    }
    //伴随矩阵 
    cout<<"伴随矩阵 "<<endl;
    Determinant company = determinant.company_matrix();    
    company.out_matrix();
    
    //行列式的值 
//    cout<<determinant.determinantValue();
//    cout<<endl;
    
    //逆置矩阵(通过伴随矩阵)
    cout<<"逆置矩阵(通过伴随矩阵)"<<endl;
    company.inverse_matrix_company(determinant.determinantValue());
    company.out_matrix();
    
    //逆置矩阵(初等行变换) 
    cout<<"逆置矩阵(初等行变换) "<<endl;
    Determinant inverse = determinant.inverse_matrix(); 
    inverse.out_matrix();
    cout<<endl;
    
    return 0;
}
/*
3
2/1 1/1 1/1
1/1 2/1 1/1
1/1 1/1 2/1
3
0/1 2/1 -1/1
1/1 1/1 2/1
-1/1 -1/1 -1/1
5
0/1 0/1 0/1 1/1 3/1
0/1 0/1 0/1 -1/1 2/1
1/1 1/1 1/1 0/1 0/1
0/1 1/1 1/1 0/1 0/1
0/1 0/1 1/1 0/1 0/1
*/

目录
相关文章
|
3月前
|
机器学习/深度学习 存储 缓存
窥探向量乘矩阵的存内计算原理—基于向量乘矩阵的存内计算
窥探向量乘矩阵的存内计算原理—基于向量乘矩阵的存内计算
23 0
|
3月前
【数值分析】用幂法计算矩阵的主特征值和对应的特征向量(附matlab代码)
【数值分析】用幂法计算矩阵的主特征值和对应的特征向量(附matlab代码)
|
7月前
|
人工智能
从浅到深研究矩阵的特征值、特征向量
从浅到深研究矩阵的特征值、特征向量
76 0
|
8月前
|
机器学习/深度学习 决策智能
矩阵分析 (六) 矩阵的函数
矩阵分析 (六) 矩阵的函数
|
8月前
|
机器学习/深度学习 决策智能
矩阵分析 (八) 矩阵的直积
矩阵分析 (八) 矩阵的直积
218 0
|
8月前
|
机器学习/深度学习 决策智能
矩阵分析 (七) 矩阵特征值的估计
矩阵分析 (七) 矩阵特征值的估计
116 0
|
8月前
|
机器学习/深度学习 决策智能
矩阵分析 (五) 矩阵的分解
矩阵分析 (五) 矩阵的分解
|
机器学习/深度学习 传感器 算法
基于有限差分法和追赶法解对角矩阵解二维热传导问题附matlab代码
基于有限差分法和追赶法解对角矩阵解二维热传导问题附matlab代码
深度之眼(十)——矩阵特征值与特征向量
深度之眼(十)——矩阵特征值与特征向量
212 0
深度之眼(十)——矩阵特征值与特征向量
|
机器学习/深度学习
深度之眼(三)——矩阵的行列式
深度之眼(三)——矩阵的行列式
158 0
深度之眼(三)——矩阵的行列式