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;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM