【线性代数|C++】矩阵乘法

1 数与矩阵相乘

1.1 定义

  • λ \lambda λ与矩阵 A A A的乘积记作 λ A \lambda A λA A λ A\lambda Aλ,规定 λ A = A λ = [ λ a 11 λ a 12 ⋯ λ a 1 n λ a 21 λ a 22 ⋯ λ a 2 n ⋮ ⋮ ⋮ λ a m 1 λ a m 2 ⋯ λ a m n ] . \lambda A = A\lambda =\begin{bmatrix}\lambda a_{11} & \lambda a_{12} & \cdots & \lambda a_{1n} \\ \lambda a_{21} & \lambda a_{22} & \cdots & \lambda a_{2n} \\ \vdots & \vdots && \vdots \\ \lambda a_{m1} & \lambda a_{m2} & \cdots & \lambda a_{mn} \end{bmatrix}. λA=Aλ= λa11λa21λam1λa12λa22λam2λa1nλa2nλamn .

1.2 C++代码

1.2.1 增加成员函数MatMulti()
  • 在CMatrix.h中声明函数
  //成员函数(静态)名:MatMulti
  //功能:求数与矩阵相乘的乘积
  //形参fNum:数
  //形参vvMatInput:参与计算的矩阵
  //形参vvMatOutput:结果矩阵
  static bool MatMulti
  (
    double fNum,
    const vector<vector<double>> &vvMatInput,
    vector<vector<double>> &vvMatOuput 
  );
  • 在CMatrix.cpp中定义函数
bool CMatrix::MatMulti
(
  double fNum,
  const vector<vector<double>> &vvMatInput,
  vector<vector<double>> &vvMatOuput 
)
{
  vvMatOuput.clear();
  vvMatOuput = vvMatInput;
  for (unsigned int i = 0; i < vvMatOuput.size(); i++)
  {
    for (unsigned int j = 0; j < vvMatOuput[i].size(); j++)
    {
      vvMatOuput[i][j] *= fNum; 
    }
  }  
  return true;
}
  • 在test.cpp中测试函数
#include <iostream>
#include <iomanip>
#include <vector>

#include "CMatrix.h"

using namespace std;

int main()
{
  vector<vector<double>> vvMat1{{ 2, 4},
                                {-3,-6}};

  vector<vector<double>> vvMatRet;

  CMatrix::MatMulti(5.0, vvMat1, vvMatRet);

  for (unsigned int i = 0; i < vvMatRet.size(); i++)
  {
    for (unsigned int j = 0; j < vvMatRet[i].size(); j++)
    {
        cout << setw(5) << vvMatRet[i][j];
    }
    cout << endl;
  }

  cout << "DONE" << endl; 

  return 0;
}

2 矩阵与矩阵相乘

2.1 定义

  • A = ( a i j ) A=(a_{ij}) A=(aij)是一个 m × s m\times s m×s矩阵, B = ( b i j ) B=(b_{ij}) B=(bij)是一个 s × n s\times n s×n矩阵,那么规定矩阵 A A A与矩阵 B B B的乘积是一个 m × n m\times n m×n矩阵 C = ( c i j ) C=(c_{ij}) C=(cij),其中 c i j = a i 1 b 1 j + a i 2 b 2 j + ⋯ + a i s b s j = ∑ k = 1 s a i k b k j c_{ij}=a_{i1}b_{1j}+a_{i2}b_{2j}+\cdots +a_{is}b_{sj}=\sum_{k=1}^sa_{ik}b_{kj} cij=ai1b1j+ai2b2j++aisbsj=k=1saikbkj ( i = 1 , 2 , ⋯   , m ; j = 1 , 2 , ⋯   , n ) (i=1,2,\cdots ,m;j=1,2,\cdots ,n) (i=1,2,,m;j=1,2,,n)并把此乘积记作 C = A B . C=AB. C=AB.
  • 注意:只有当第一个矩阵(左矩阵)的列数等于第二个矩阵(右矩阵)的行数时,两个矩阵才能相乘.

2.2 C++代码

2.2.1 增加成员函数GetMatRowsCols()

矩阵与矩阵相乘前,需首先判断左矩阵的列数是否等于右矩阵的行数,为此在类CMatrix中增加一个读取矩阵行数和列数的成员函数GetMatRowsCols().

  • 在CMatrix.h中声明函数
//成员函数(静态)名:GetMatRowsCols
//功能:读取矩阵的行数和列数,如果非矩阵结构(如:各行元素数量不等)则返回false
//形参vvMatInput:待读取行数和列数的矩阵
//形参iRowsNum:矩阵的行数
//形参iColsNum:矩阵的列数
static bool GetMatRowsCols
(
  const vector<vector<double>> &vvMatInput,
  int &iRowsNum,
  int &iColsNum
);
  • 在CMatrix.cpp中定义函数
bool CMatrix::GetMatRowsCols
(
  const vector<vector<double>> &vvMatInput,
  int &iRowsCount,
  int &iColsCount
)
{
  iRowsCount = vvMatInput.size();
  if (0 == iRowsCount)
  {
    iColsCount = 0;
    return false;
  }    

  iColsCount = vvMatInput[0].size();
  if (0 == iColsCount)
  {
    iRowsCount = 0;
    return false;
  }    
  
  for (unsigned int i = 1; i < vvMatInput.size(); i++)
  {
    if (iColsCount != vvMatInput[i].size())
    {
      iRowsCount = 0;
      iColsCount = 0;
      return false;
    }
  } 
  
  return true;
}
2.2.2 增加成员函数MatrixMulti()

矩阵乘矩阵函数与数乘矩阵函数为重载函数,通过形参进行区分。

  • 在CMatrix.h中声明函数
//成员函数(静态)名:MatMulti
//功能:求矩阵与矩阵相乘的乘积
//形参vvLMat:左矩阵
//形参vvRMat:右矩阵
//形参vvMatRet:计算结果
static bool MatrixMulti
(
  const vector<vector<double>> &vvLMat,
  const vector<vector<double>> &vvRMat,
  vector<vector<double>> &vvMatRet
); 
  • 在CMatrix.cpp中定义函数
bool CMatrix::MatrixMulti
(
  const vector<vector<double>> &vvLMat,
  const vector<vector<double>> &vvRMat,
  vector<vector<double>> &vvMatRet
)
{
  //首先判断左矩阵的列数是否与右矩阵的行数相等
  int iLMatRowsCount, iLMatColsCount; 
  int iRMatRowsCount, iRMatColsCount;
  if (!GetMatRowsCols(vvLMat, iLMatRowsCount, iLMatColsCount))
    return false;
  
  if (!GetMatRowsCols(vvRMat, iRMatRowsCount, iRMatColsCount))
    return false;

  if (iLMatColsCount != iRMatRowsCount)
    return false;
  
  vvMatRet.clear();
  vector<double> v0;  //用于临时存储矩阵行元素
  double f0;//用于临时存储矩阵元素值
  for (int i = 0; i < iLMatRowsCount; i++)
  {
    v0.clear();
    for (int j = 0; j < iRMatColsCount; j++)
    {
      f0 = 0;
      for (int n = 0; n < iLMatColsCount; n++)
      {
        f0 += (vvLMat[i][n] * vvRMat[n][j]);
      }
      v0.push_back(f0);
    } 
    vvMatRet.push_back(v0) ; 
  }  
  
  return true;
}
  • 在text.cpp中测试函数
#include <iostream>
#include <iomanip>
#include <vector>

#include "CMatrix.h"

using namespace std;

int main()
{
  vector<vector<double>> vvMat1{{ 2, 4},
                                {-3,-6}};

  vector<vector<double>> vvMat2{{-2, 4},
                                { 1,-2}};
  vector<vector<double>> vvMatRet;

  if(!CMatrix::MatrixMulti(vvMat1, vvMat2, vvMatRet))
  {
    cout << "输入矩阵不具备相乘的条件" << endl;
  }
  else
  {
    for (unsigned int i = 0; i < vvMatRet.size(); i++)
    {
      for (unsigned int j = 0; j < vvMatRet[i].size(); j++)
      {
         cout << setw(3) << vvMatRet[i][j];
      }
      cout << endl;
    }    
  }

  cout << "DONE" << endl; 

  return 0;
}

  1. 应用文献:《工程数学 线性代数(第五版)》同济大学数学系编,高等教育出版社
  2. 以上内容为个人学习、练习的记录,如有错误,欢迎指正。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SurveyingEngineer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值