C++实现简单的矩阵运算

C++实现简单的矩阵运算

说明

在写C++的程序时有时候需要使用到矩阵运算,而大部分时候又不至于使用加载matlab库的方式实现军阵矩阵运算的功能,下面提供一些矩阵运算的基本的API,其中很大一部分程序是参照别人别人的程序写的,本人只是做了一些整合的工作。

程序

vector<vector<double> > Testlib::creatmatrix(uint h, uint l) //创建一个值全部为0的矩阵
{
        return creatmatrix(h,l,0);
}

vector<vector<double> > Testlib::creatmatrix(uint h, uint l, double a)//创建一个值全部为自定义值得矩阵
{
        vector<vector<double>> v;
        for (uint i = 0; i < h; i++)
        {
            vector<double>v1(l,a);
            v.push_back(v1);
        }
        return v;
}


//矩阵A+矩阵B=矩阵C,并返回
vector<vector<double>> Testlib::plus(const vector<vector<double>>&A,const vector<vector<double>>&B)//两矩阵相加
{
    if(A.empty()||B.empty())
    {
        qDebug()<<"矩阵不能为空"<<endl;
        return {};
    }
    uint h=A.size();
    uint l=A[0].size();
    if(B.size()!=h||B[0].size()!=l)
    {
        qDebug()<<"两矩阵无法相加"<<endl;
        return {};
    }
    vector<vector<double>> C;
    C=creatmatrix( h, l);

    for(uint i=0;i<h;i++)
    {
        for (uint j = 0; j < l; j++)
        {
            C[i][j]=A[i][j]+B[i][j];
            if (abs(C[i][j])<1e-6)
            {
                C[i][j]=0.0;
            }
        }
    }
    return C;
}

//矩阵A-矩阵B=矩阵C,并返回
vector<vector<double>> Testlib::minus(const vector<vector<double>>&A,const vector<vector<double>>&B) //两矩阵相减
{
    uint h=A.size();
    uint l=A[0].size();
    vector<vector<double>> C;
    C=creatmatrix( h, l);

    for(uint i=0;i<h;i++)
    {
        for (uint j = 0; j < l; j++)
        {
            C[i][j]=A[i][j]-B[i][j];
            if (abs(C[i][j])<1e-6)
            {
                C[i][j]=0.0;
            }
        }
    }
    return C;
}

//矩阵A*矩阵B=矩阵C,并返回
vector<vector<double>> Testlib::multiply(const vector<vector<double>>&A,const vector<vector<double>>&B)
{
    if(A.empty()||B.empty())
    {
        cout<<"矩阵不能为空"<<endl;
        return {};
    }
    uint A_h=A.size();
    uint A_l=A[0].size();
    uint B_h=B.size();
    uint B_l=B[0].size();
    if(A_l !=B_h)
    {
        cout<<"两矩阵维数无法相乘"<<endl;
        return {};
    }
    vector<vector<double>> C=creatmatrix(A_h,B_l);
    for (uint i = 0; i < A_h; i++)
    {
        for (uint j = 0; j < B_l; j++)
        {
            C[i][j]=0;
            for (uint k = 0; k < A_l; k++)
            {
                C[i][j] +=A[i][k]*B[k][j];
            }
            if (abs(C[i][j])<1e-6)
            {
                C[i][j]=0.0;
            }
        }
    }
    return C;
}

//矩阵A*num=矩阵B,并返回
vector<vector<double>> Testlib::multiply_num(const vector<vector<double>>&A,double num)
{
    if(A.empty()){
        cout<<"矩阵不能为空"<<endl;
        return {};
    }
    uint A_h=A.size();
    uint A_l=A[0].size();
    vector<vector<double>> B=creatmatrix(A_h,A_l);
    for (uint i = 0; i < A_h; i++)
    {
        for (uint j = 0; j < A_l; j++)
        {
            B[i][j]=num*A[i][j];
        }
    }
    return B;
}
//矩阵A与矩阵B上下叠加获得新的矩阵C,并返回
vector<vector<double>> Testlib::matrix_overlaying_below(const vector<vector<double>>&A,const vector<vector<double>>&B)
{
    //判断矩阵的列是否相等
    uint A_h=A.size();
    uint A_l=A[0].size();
    uint B_h=B.size();
    uint B_l=B[0].size();
    if (A_l != B_l)
    {
        cout<<"叠加的矩阵列数不相等"<<endl;
        return {};
    }
    //创建
    vector<vector<double>> C=creatmatrix(A_h+B_h,A_l);
    //将A传入
    for (uint i = 0; i < A_h; i++)
    {
        for (uint j = 0; j < A_l; j++)
        {
            C[i][j]=A[i][j];
        }
    }
    //将B传入
    for (uint i = 0; i < B_h; i++)
    {
        for (uint j = 0; j < B_l; j++)
        {
            C[i+A_h][j]=B[i][j];
        }
    }
    return C;
}

//矩阵A与矩阵B左右叠加,获得新的矩阵C,并返回
vector<vector<double>> Testlib::matrix_overlaying_beside(const vector<vector<double>>&A,const vector<vector<double>>&B)
{
    //判断矩阵的列是否相等
    uint A_h=A.size();
    uint A_l=A[0].size();
    uint B_h=B.size();
    uint B_l=B[0].size();
    if (A_h != B_h)
    {
        cout<<"叠加的矩阵行数不相等"<<endl;
        return {};
    }
    //创建
    vector<vector<double>> C=creatmatrix(A_h,A_l+B_l);
    //将A传入
    for (uint i = 0; i < A_h; i++)
    {
        for (uint j = 0; j < A_l; j++)
        {
            C[i][j]=A[i][j];
        }
    }
    //将B传入
    for (uint i = 0; i < B_h; i++)
    {
        for (uint j = 0; j < B_l; j++)
        {
            C[i][j+A_l]=B[i][j];
        }
    }
    return C;
}

//输入矩阵A,输出矩阵A的转置矩阵AT
vector<vector<double>> Testlib::trans(const vector<vector<double>> &A)
{
    vector<vector<double>> AT=creatmatrix(A[0].size(),A.size());
    uint h=AT.size();
    uint l=AT[0].size();
    for (uint i = 0; i <h ; i++)
    {
        for (uint j = 0; j < l; j++)
        {
            AT[i][j]=A[j][i];
        }
    }
    return AT;
}
//输入矩阵A,输出矩阵A的逆矩阵inv_A
vector<vector<double>> Testlib::inverse(const vector<vector<double>> &A)
{
    if (A.size() != A[0].size())
    {
        cout<<"输入矩阵维数不合法"<<endl;
        return {};
    }
    uint n=A.size();
    vector<vector<double>> inv_A=creatmatrix(n,n);
    vector<vector<double>> L=creatmatrix(n,n);
    vector<vector<double>> U=creatmatrix(n,n);
    vector<vector<double>> inv_L=creatmatrix(n,n);
    vector<vector<double>> inv_U=creatmatrix(n,n);
//LU分解
    //L矩阵对角元素为1
    for (uint i = 0; i < n; i++)
    {
        L[i][i] = 1;
    }
    //U矩阵第一行
    for (uint i = 0; i < n; i++)
    {
        U[0][i]=A[0][i];
    }
    //L矩阵第一列
    for (uint i = 1; i < n; i++)
    {
        L[i][0]=1.0*A[i][0]/A[0][0];
    }

    //计算LU上下三角
    for (uint i = 1; i < n; i++)
    {
        //计算U(i行j列)
        for (uint j = i; j < n; j++)
        {
            double tem = 0;
            for (uint k = 0; k < i; k++)
            {
                tem += L[i][k] * U[k][j];
            }
            U[i][j] = A[i][j] - tem;
            if (abs(U[i][j])<1e-6)
            {
                U[i][j]=0.0;
            }
        }
        //计算L(j行i列)
        for (uint j = i ; j < n; j++)
        {
            double tem = 0;
            for (uint k = 0; k < i; k++)
            {
                tem += L[j][k] * U[k][i];
            }
            L[j][i] = 1.0*(A[j][i] - tem) / U[i][i];
            if (abs(L[i][j])<1e-6)
            {
                L[i][j]=0.0;
            }
        }

    }
    //L U剩余位置设为0
    for(uint i=0;i<n;i++)
    {
        for(uint j=0;j<n;j++)
        {
            if(i>j)
            {
                U[i][j]=0.0;
            }
            else if(i<j)
            {
                L[i][j]=0.0;
            }
        }
    }
    //LU求逆
    //求矩阵U的逆
    for (int i=0;i<n;i++)
    {
        inv_U[i][i]=1/U[i][i];// U对角元素的值,直接取倒数
        for (int k=i-1;k>=0;k--)
        {
            double s=0;
            for (uint j=k+1;j<=i;j++)
            {
                s=s+U[k][j]*inv_U[j][i];
            }
            inv_U[k][i]=-s/U[k][k];//迭代计算,按列倒序依次得到每一个值,
            if (abs(inv_U[k][i])<1e-6)
            {
                inv_U[k][i]=0.0;
            }
        }
    }
    //求矩阵L的逆
    for (uint i=0;i<n;i++)
    {
        inv_L[i][i]=1; //L对角元素的值,直接取倒数,这里为1
        for (uint k=i+1;k<n;k++)
        {
            for (uint j=i;j<=k-1;j++)
            {
                inv_L[k][i]=inv_L[k][i]-L[k][j]*inv_L[j][i];
                if (abs(inv_L[k][i])<1e-6)
                {
                    inv_L[k][i]=0.0;
                }
            }
        }
    }
    inv_A=multiply(inv_U,inv_L);
    return inv_A;
}

//打印矩阵
void Testlib::show_matrix(const vector<vector<double>> &A)
{
    uint h=A.size();
    uint l=A[0].size();
    for (uint i = 0; i < h; i++)
    {
        for (uint j = 0; j < l; j++)
        {
            cout<<A[i][j]<<"\t";
        }
        cout<<endl;
    }
}

最后

目前只实现了加单的矩阵运算的功能,至于一些复杂的功能暂时没有添加的想法。

  • 1
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值