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;

作者:禅在心中

出处:http://www.cnblogs.com/pinking/

本文版权归作者和博客园共有,欢迎批评指正及转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文地址:https://www.cnblogs.com/pinking/p/6722705.html