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;

 

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 不联网,ubuntu下安装gcc

    不联网,ubuntu下安装gcc1.下载 在GCC网站上(http://gcc.gnu.org/)或者通过网上搜索可以查找到下载资源。目前GCC的最新版本为3.4.0。可供下载的文件一般有两种形式:gcc-3.4.0.tar.gz和gcc-3.4.0.tar.bz2,只是压缩格式不一样,内容完全一致,下载其中一种即可。 2.解压缩 根据压缩格式,选择下面相应的一种方式解包(以下的“%”表示命令行提示符

    2022年7月24日
    23
  • mybatismysql批量insert数据_mysql数据库简介

    mybatismysql批量insert数据_mysql数据库简介MySQL批量插入

    2022年10月5日
    0
  • 建立任务,OSTaskCreate()源码解析

    建立任务,OSTaskCreate()源码解析想让uC/OS-Ⅱ管理用户的任务,用户必须要先建立任务。用户可以通过传递任务地址和其它参数到以下两个函数之一来建立任务:OSTaskCreate()或OSTaskCreateExt()。OSTas

    2022年7月3日
    22
  • java中jersey什么意思_java jersey介绍

    java中jersey什么意思_java jersey介绍简介Jersey是JAX-RS(JSR311)开源参考实现用于构建RESTfulWebservice,它包含三个部分:核心服务器(CoreServer):通过提供JSR311中标准化的注释和API标准化,可以用直观的方式开发RESTfulWeb服务。核心客户端(CoreClient):Jersey客户端API能够帮助开发者与RESTful服务轻松通信;集成(Integration):J…

    2022年7月12日
    43
  • Java中的三种注释类型「建议收藏」

    Java中的三种注释类型「建议收藏」注释:用于说明解释程序的文字就是注释。Java中的注释有三种:单行注释多行注释文档注释(Java特有)注释的作用有什么?主要就是提高了代码的阅读性,是调试程序的重要方法。当然,写注释也是一种良好编程习惯。可以将自己的思想通过注释先整理出来,再用代码去体现。来看看具体的使用吧!单行注释格式://注释文字多行注释格式:/*注释文字*/下面给出单行注释和多行注释的示例://单行注释publicclassHelloWorld{/* 程序入口

    2022年7月7日
    25
  • 循环移动数组元素

    循环移动数组元素//循环移动数组元素//一种大部分数据只移动一次的算法//方法://  将数据循环移动,可以直接计算出每个数据的最终位置,直接移动即可//分析://  这种算法基本可看做每个数据只需要移动一次//  但是每个数据移动的位置需要计算,算法

    2022年7月25日
    29

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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