C++矩阵运算

C++矩阵运算

矩阵的定义可以使用STL提供的Vector,

譬如,定义A[4][4]

1 vector<vector<double>> A = 
2 { { 1.0, T, 0, 0 },
3  { 0, 1, 0, 0 },
4  { 0, 0, 1, T },
5  { 0, 0, 0, 1 } };

一、运算符重载实现矩阵加法

 

 1 vector<vector<double>> operator + (vector<vector<double>> arrA, vector<vector<double>> arrB)
 2 {//矩阵加法
 3     // 矩阵arrA的行数
 4         int rowA = arrA.size();
 5     //矩阵arrA的列数  
 6     int colA = arrA[0].size();
 7     //矩阵arrB的行数  
 8     int rowB = arrB.size();
 9     //矩阵arrB的列数  
10     int colB = arrB[0].size();
11     //相乘后的结果矩阵  
12     vector<vector<double>>  res;
13     if ((colA != colB) || (rowA != rowB))//判断矩阵行列是否一致。则返回空  
14     {
15         return res;
16     }
17     else
18     {
19         //设置结果矩阵的大小,初始化为为0  
20         res.resize(rowA);
21         for (int i = 0; i < rowA; ++i)
22         {
23             res[i].resize(colB);
24         }
25 
26         //矩阵相加  
27         for (int i = 0; i < rowA; ++i)
28         {
29             for (int j = 0; j < colB; ++j)
30             {
31 
32                 res[i][j] = arrA[i][j] + arrB[i][j];
33                 
34             }
35         }
36     }
37     return res;
38 }

 二、矩阵乘法

 1 vector<vector<double>> operator * (vector<vector<double>> arrA, vector<vector<double>> arrB)  2 {//矩阵乘法  3 //矩阵arrA的行数   4 int rowA = arrA.size();  5 //矩阵arrA的列数   6 int colA = arrA[0].size();  7 //矩阵arrB的行数   8 int rowB = arrB.size();  9 //矩阵arrB的列数  10 int colB = arrB[0].size(); 11 //相乘后的结果矩阵  12 vector<vector<double>> res; 13 if (colA != rowB)//如果矩阵arrA的列数不等于矩阵arrB的行数。则返回空  14  { 15 return res; 16  } 17 else 18  { 19 //设置结果矩阵的大小,初始化为为0  20  res.resize(rowA); 21 for (int i = 0; i < rowA; ++i) 22  { 23  res[i].resize(colB); 24  } 25 26 //矩阵相乘  27 for (int i = 0; i < rowA; ++i) 28  { 29 for (int j = 0; j < colB; ++j) 30  { 31 for (int k = 0; k < colA; ++k) 32  { 33 res[i][j] += arrA[i][k] * arrB[k][j]; 34  } 35  } 36  } 37  } 38 return res; 39 40 } 41 vector<vector<double>> operator * (double n, vector<vector<double>> arr) 42 {//矩阵乘法 43 //矩阵arrA的行数  44 int row = arr.size(); 45 //矩阵arrA的列数  46 int col = arr[0].size(); 47 48 vector<vector<double>> res; 49 50 51 //设置结果矩阵的大小,初始化为为0  52  res.resize(row); 53 for (int i = 0; i < row; ++i) 54  { 55  res[i].resize(col); 56  } 57 58 //矩阵相乘  59 for (int i = 0; i < row; ++i) 60  { 61 for (int j = 0; j < col; ++j) 62  { 63 64 res[i][j] = arr[i][j] * n; 65  } 66  } 67 68 return res; 69 70 }

 

 

 

三、求行列式的值

 1 double det(vector<vector<double>> arr)  2 {  3 //矩阵arrA的行数   4 int row = arr.size();  5 //矩阵arrA的列数   6 int col = arr[0].size();  7 if (row != col)  8  {  9 return 0; 10  } 11 if (1 == row) 12  { 13 return arr[0][0]; 14  } 15 //创建结果矩阵 16 vector<vector<double>> res; 17 res.resize(row-1); 18 int p = 0; 19 int q = 0; 20 double sum = 0; 21 for (int i = 0; i < row-1; ++i) 22  { 23 res[i].resize(col-1); 24  } 25 for (int i = 0; i < row; i++) 26  { 27 for (int res_i = 0; res_i < row - 1; res_i++) 28  { 29 if (res_i < i) 30  { 31 p = 0; 32  } 33 else 34  { 35 p = 1; 36  } 37 38 for (int j = 0; j < col - 1; j++) 39  { 40 res[res_i][j] = arr[res_i + p][j+1]; 41  } 42  } 43 if (i % 2 == 0) 44  { 45 q = 1; 46  } 47 else 48  { 49 q = -1; 50  } 51 sum += arr[i][0] * q*det(res); 52 53  } 54 return sum; 55 }

 四、求逆矩阵

 1 vector<vector<double>> inv(vector<vector<double>> arr)  2 {//求逆矩阵  3 //矩阵arrA的行数   4 int row = arr.size();  5 //矩阵arrA的列数   6 int col = arr[0].size();  7 if (row != col)  8  {  9 vector<vector<double>> err= { {0} }; 10 return err; 11  } 12 //创建结果矩阵 13 vector<vector<double>> res; 14  res.resize(row); 15 for (int i = 0; i < row; ++i) 16  { 17  res[i].resize(col); 18 res[i][i] = 1;//初始化单位阵 19  } 20 int temp_row = 0; 21 double max = 0; 22 double ratio = 0; 23 for (int i = 0; i < row; i++) 24  { 25 //列选主元素 26 max = arr[i][i]; 27 temp_row = i; 28 for (int i_change = i; i_change < row; i_change++) 29  { 30 if (i_change == i) 31 continue; 32 if (max < arr[i][i_change]) 33  { 34 max = arr[i][i_change]; 35 temp_row = i_change; 36  } 37  } 38 if (temp_row != i) 39  { 40  swap(arr[i], arr[temp_row]); 41  swap(res[i], res[temp_row]); 42  } 43 44 //消元 45 for (int i_change = 0; i_change < row; i_change++) 46  { 47 if (i_change == i) 48 continue; 49 ratio = arr[i][i] / arr[i_change][i]; 50 51 for (int j = 0; j < col; j++) 52  { 53 if (j >= i) 54  { 55 arr[i_change][j] = (arr[i_change][j] - arr[i][j] / ratio); 56  } 57 res[i_change][j] = (res[i_change][j] - res[i][j] / ratio); 58  } 59 60  } 61 62 63  } 64 //归一 65 for (int i = 0; i < row; i++) 66  { 67 for (int j = 0; j < col; j++) 68  { 69 res[i][j] = res[i][j] / arr[i][i]; 70  } 71  } 72 73 return res; 74 }

 ————

补充:

对于上面矩阵加减乘除,如果输入的数据类型存在double、int等不同的数据类型,则需要不断重载运算符,带来不必要的麻烦。而C++的模板机制可以很好的解决这个问题。

模板定义:模板就是实现代码重用机制的一种工具,它可以实现类型参数化,即把类型定义为参数, 从而实现了真正的代码可重用性。模版可以分为两类,一个是函数模版,另外一个是类模版。

(1)函数模板

template <class T>
void SwapFunction(T &first, T &second){
}//函数模版

函数模板可以用来创建一个通用的函数,以支持多种不同的形参,避免重载函数的函数体重复设计!

函数模板解决”+”运算符重载

 1 template <class T>  2 T operator + (T arrA, T arrB)  3 {//矩阵加法  4 // 矩阵arrA的行数  5 int rowA = arrA.size();  6 //矩阵arrA的列数   7 int colA = arrA[0].size();  8 //矩阵arrB的行数   9 int rowB = arrB.size(); 10 //矩阵arrB的列数  11 int colB = arrB[0].size(); 12 //相乘后的结果矩阵  13  T res; 14 if ((colA != colB) || (rowA != rowB))//判断矩阵行列是否一致。则返回空  15  { 16 return res; 17  } 18 else 19  { 20 //设置结果矩阵的大小,初始化为为0  21  res.resize(rowA); 22 for (int i = 0; i < rowA; ++i) 23  { 24  res[i].resize(colB); 25  } 26 27 //矩阵相加  28 for (int i = 0; i < rowA; ++i) 29  { 30 for (int j = 0; j < colB; ++j) 31  { 32 33 res[i][j] = arrA[i][j] + arrB[i][j]; 34 35  } 36  } 37  } 38 return res; 39 }

这样使用就很灵活了

1 vector<vector<int >>A = { { 1, 2 }, { 3, 2 } }; 2 vector<vector<int >>B = { { 1, 2 }, { 3, 2 } }; 3 vector<vector<int >> C = A + B; 4 5 vector<vector<double >>A2 = { { 1, 2 }, { 3, 2 } }; 6 vector<vector<double >>B2 = { { 1, 2 }, { 3, 2 } }; 7 vector<vector<double >> C2 = A2 + B2;

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/119498.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • HDU-3068-最长回文 (Manacher算法)[通俗易懂]

    HDU-3068-最长回文 (Manacher算法)

  • 安卓方向传感器_自制悬挂式指南针

    安卓方向传感器_自制悬挂式指南针调用方向传感器开发简易指南针的原理其实很简单的:先准备一张指南针的图片,该图片上的方向指针指向北方。接下来开发一个检测方向的传感器,程序检测到设备顶部绕Z轴转过多少度,让指南针图片反向转过多少度即可。由此可见,指南针应用只要在界面中添加一张图片,并让图片总是反向转过方向传感器返回的第一个角度值即可。

  • settime和setinterval_setinterval是异步还是同步

    settime和setinterval_setinterval是异步还是同步setTimeout和setInterval的语法相同。它们都有两个参数,一个是将要执行的代码字符串,还有一个是以毫秒为单位的时间间隔,当过了那个时间段之后就将执行那段代码。这两个函数的区别是:setInterval在执行完一次代码之后,经过了那个固定的时间间隔,它还会自动重复执行代码,而setTimeout只执行一次那段代码。有一次我没有分清,使用了setInterval,导致电脑崩溃了。setTimeout表面上是只执行一次,只是起到延迟作用。但是也可以通过创建一个函数循环重复调用…

  • MongoDB(二)—-数据库操作

    MongoDB(二)—-数据库操作

    2020年11月12日
  • Postman 使用教程 – 手把手教你 API 接口测试[通俗易懂]

    Postman 使用教程 – 手把手教你 API 接口测试[通俗易懂]Postman是一套API接口测试工具,它的强大在于灵活趁手的接口测试功能,极大的提高了API测试效率。本教程将由浅入深,带领大家一起学习如何使用Postman进行接口测试。API是什么?API的英文即ApplicationProgrammingInterface首字母的缩写。不要被这么长的单词吓到,直译过来的意思就是:程序之间的接口。我更倾向于把API理解为,程序之间的合约。有关API是什么及.

  • 金蝶显示服务器异常,金蝶迷你版登录提示云服务器异常

    金蝶迷你版登录提示云服务器异常内容精选换一换如果您购买了ECS,而没有对ECS进行主机安全防护,那么您主机将面临账户爆破、异常登录、恶意攻击等安全威胁。购买ECS,勾选开通主机安全,HSS基础版(按需计费)免费赠送。HSS可以帮助您全面识别并管理主机中的信息资产,实时监测主机中的风险并阻止非法入侵行为,帮助企业构建服务器安全体系,降低当前服务器面临的主要安全风险。基础版(按需计费)区块链管理页面…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号