zoukankan      html  css  js  c++  java
  • 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/

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

  • 相关阅读:
    Odoo模块开发教程3-模块继承之修改视图和数据第四讲
    Odoo模块开发教程3-模块继承之修改视图和数据第三讲
    Odoo模块开发教程2-模块继承之原模型继承
    Odoo模块开发教程1-模块继承第一讲
    Odoo安装教程14-创建新的插件模块之网页和控制器
    Odoo安装教程13-创建新的插件模块之业务逻辑层
    Odoo安装教程12-创建新的插件模块之设置视图层第三讲
    HackBar收费版绕过
    记一次linux服务器入侵应急响应
    软件开发之安全设计
  • 原文地址:https://www.cnblogs.com/pinking/p/6722705.html
Copyright © 2011-2022 走看看