Advertisement
balsa0

Mathematical matrix function library

Mar 18th, 2013
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.12 KB | None | 0 0
  1. /* * * * * * * * * * * * * * * * * * * * * **
  2.  * Mathematical matrix function library     *
  3.  * by Shuffle                   *
  4.  * version 0.7 (2013-03-18)                 *
  5.  * * * * * * * * * * * * * * * * * * * * * */
  6.  
  7. #include <iostream>
  8. #include <cstdlib>
  9. #include <cmath>
  10.  
  11. using namespace std;
  12.  
  13. ///Class definition
  14. class Matrix{
  15.     public:
  16.         Matrix(int,int,bool,bool,int);
  17.         ~Matrix();
  18.         //Basic and diagnostical
  19.         int getHeight() const;
  20.         int getWidth() const;
  21.         float getItem(int,int) const;
  22.         void setItem(float,int,int);
  23.         void setMathematical(bool);
  24.         bool getMathematical() const;
  25.         void applyProcessOnAll(float (*)(float));
  26.         void applyProcessOnItem(float (*)(float), int, int);
  27.         //Mathematical
  28.         float getDeterminant() const;
  29.         Matrix getSubDeterminants() const;
  30.         bool isSquareMatrix() const;
  31.         Matrix getTransposed() const;
  32.         Matrix getInverse() const;
  33.         Matrix flipHorizontal() const;
  34.         Matrix flipVertical() const;
  35.         Matrix flipDiagonal() const;
  36.         //Debug
  37.         void setDebug(bool);
  38.         void fillWithRandomData(int);   //by Gergő
  39.         void fillTestData();
  40.         void drawMatrix() const;
  41.         void debugSpacing() const;
  42.     private:
  43.         int rows;               //number of matrix rows
  44.         int cols;               //number of matrix columns
  45.         float **MatrixData;     //contains matrix data
  46.         int isMathematical;     //if indexing begins with 0 or 1 (only in get/setItem methods)
  47.         bool debug;             //level 1 debug
  48.         bool debugRecurse;      //level 2 debug > set in constructor!
  49.         int debugLevel;
  50. };
  51.  
  52. ///Constructor & destructor
  53.  
  54.     Matrix::Matrix(int height, int width, bool isMath = true, bool dbg = false, int debugLvl = 0){
  55.         if (height < 1 || width < 1 ){
  56.             std::cout << "#(!!!)Zero or 1x1 size matrix! Exiting..." << "\r\n";
  57.             throw 2;
  58.         }
  59.         #define MATRIX_DEBUG if(debug)
  60.         setDebug(dbg);
  61.         debugLevel = debugLvl;
  62.         MATRIX_DEBUG debugSpacing();
  63.         MATRIX_DEBUG std::cout << "#Creating matrix..." << "\r\n";
  64.         rows = height;
  65.         cols = width;
  66.         setMathematical(isMath);
  67.         MatrixData = new float*[rows];
  68.         for (int i = 0;i <= rows-1; i++){
  69.             MatrixData[i] = new float[cols];
  70.         }
  71.         debugRecurse = false;
  72.     }
  73.  
  74.     Matrix::~Matrix(){
  75.  
  76.     }
  77.  
  78. ///Debugging methotds
  79.  
  80.     void Matrix::setDebug(bool dbg){
  81.         debug = dbg;
  82.     }
  83.  
  84.     void Matrix::debugSpacing() const{
  85.         for(int i=0; i < debugLevel;i++)
  86.             cout << "\t";
  87.     }
  88.  
  89.     void Matrix::drawMatrix() const{
  90.         MATRIX_DEBUG debugSpacing();
  91.         cout << "***\t";
  92.         for(int z = 1; z <= cols;z++)
  93.             cout << "[" << z << "]\t";
  94.         cout << "\r\n";
  95.         for(int i = 0; i <= rows-1;i++){
  96.             MATRIX_DEBUG debugSpacing();
  97.             cout << "[" << i+1 << "]\t";
  98.             for(int j = 0; j <= cols-1;j++){
  99.                 cout << MatrixData[i][j] << "\t";
  100.             }
  101.             cout << "\r\n";
  102.         }  
  103.     }
  104.  
  105.     void Matrix::fillWithRandomData(int interval){
  106.         srand(time(NULL));
  107.         for(int i = 0; i <= rows-1;i++)
  108.             for(int j = 0; j <= cols-1;j++)
  109.                 MatrixData[i][j]=floor(((float)rand()/(float)RAND_MAX)*interval);
  110.     }
  111.  
  112.     void Matrix::fillTestData(){
  113.         #define M MatrixData
  114.         M[0][0] = 1;M[0][1] = 4;M[0][2] = -0;
  115.         M[1][0] = 2;M[1][1] = 5;M[1][2] = 1;
  116.         M[2][0] = 3;M[2][1] = 6;M[2][2] = 0;
  117.         #undef M
  118.     }
  119.  
  120. ///Basic and diagnostical methods
  121.  
  122.     int Matrix::getWidth() const{
  123.         return rows;
  124.     }
  125.  
  126.     int Matrix::getHeight() const{
  127.         return cols;
  128.     }
  129.  
  130.     float Matrix::getItem(int row, int col) const{
  131.         return MatrixData[row-isMathematical][col-isMathematical];
  132.     }
  133.  
  134.     void Matrix::setItem(float ertek, int row, int col){
  135.         MatrixData[row-isMathematical][col-isMathematical] = ertek;
  136.     }
  137.  
  138.     void Matrix::setMathematical(bool isMath){
  139.         if (isMath){
  140.             MATRIX_DEBUG debugSpacing();
  141.             MATRIX_DEBUG std::cout << "#Indexing matrix set to mathematical!" << "\r\n";
  142.             isMathematical = 1;
  143.         }else{
  144.             MATRIX_DEBUG debugSpacing();
  145.             MATRIX_DEBUG std::cout << "#Indexing matrix set to C style!" << "\r\n";
  146.             isMathematical = 0;
  147.         }
  148.     }
  149.  
  150.     bool Matrix::getMathematical() const{
  151.         return isMathematical ? true : false;
  152.     }
  153.  
  154.     void Matrix::applyProcessOnAll(float (*proc)(float)){
  155.     //use: object.applyProcessOnAll(*function);
  156.         MATRIX_DEBUG debugSpacing();
  157.         MATRIX_DEBUG std::cout << " #Processing matrix...";
  158.         for(int i = 0; i <= rows-1;i++)
  159.             for(int j = 0; j <= cols-1;j++)
  160.                 MatrixData[i][j]=proc(MatrixData[i][j]);
  161.         MATRIX_DEBUG std::cout << "done!" << "\r\n";
  162.     }
  163.  
  164.     void Matrix::applyProcessOnItem(float (*proc)(float), int row, int col){
  165.     //use: object.applyProcessOnAll(*function,row,column);
  166.         MATRIX_DEBUG debugSpacing();
  167.         MATRIX_DEBUG std::cout << "#Processing item [" << row << "][" << col << "]";
  168.         MatrixData[row-1][col-1]=proc(MatrixData[row-1][col-1]);
  169.         MATRIX_DEBUG std::cout << "done!" << "\r\n";
  170.     }
  171.  
  172. ///Mathematical methods
  173.  
  174.     bool Matrix::isSquareMatrix() const{
  175.         if (rows == cols)
  176.             return true;
  177.         else
  178.             return false;
  179.     }
  180.  
  181.     Matrix Matrix::getTransposed() const {
  182.         Matrix I = Matrix(cols,rows,false,debug,debugLevel+1);
  183.         for(int i = 0; i <= rows-1;i++)
  184.             for(int j = 0; j <= cols-1;j++)
  185.                 I.setItem(MatrixData[i][j],j,i);
  186.         return I;
  187.     }
  188.  
  189.     Matrix Matrix::flipHorizontal() const{ //!ezt használjuk determináns számításhoz
  190.         Matrix I = Matrix(rows,cols,false,debug,debugLevel+1);
  191.         for(int i = 0; i <= rows-1;i++)
  192.             for(int j = 0; j <= cols-1;j++)
  193.                 I.setItem(MatrixData[i][j],rows-1-i,j);
  194.         return I;
  195.     }
  196.  
  197.     Matrix Matrix::flipVertical() const{
  198.         Matrix I = Matrix(rows,cols,false,debug,debugLevel+1);
  199.         for(int i = 0; i <= rows-1;i++)
  200.             for(int j = 0; j <= cols-1;j++)
  201.                 I.setItem(MatrixData[i][j],i,cols-1-j);
  202.         return I;
  203.     }
  204.  
  205.     Matrix Matrix::flipDiagonal() const{
  206.         Matrix I = Matrix(rows,cols,false,debug,debugLevel+1);
  207.         for(int i = 0; i <= rows-1;i++)
  208.             for(int j = 0; j <= cols-1;j++)
  209.                 I.setItem(MatrixData[i][j],rows-1-i,cols-1-j);
  210.         return I;
  211.     }
  212.  
  213.     float Matrix::getDeterminant() const{
  214.  
  215.         if (isSquareMatrix()){
  216.             MATRIX_DEBUG debugSpacing();
  217.             MATRIX_DEBUG cout << "#Counting determinant...\r\n";
  218.             //!csúnya, át kell írni - önmagáról másolat
  219.             Matrix tempMatrix = Matrix(rows,cols,false,debugRecurse,debugLevel+1);
  220.             for(int v = 0; v <= rows-1;v++)
  221.                 for(int z = 0; z <= cols-1;z++)
  222.                     tempMatrix.setItem(MatrixData[v][z],v,z);
  223.             //!
  224.             float tDeterminant = 0,subResult;
  225.             int overHead, item, phaseFlip = 1;
  226.             if (cols > 2){
  227.                 for(int phase=0;phase<=1;phase++){      //!átlók megfordítása (2X fut le)
  228.                     for(int i=0;i<=cols-1;i++){
  229.                         subResult = 1;                  //!szorzat 0-zása
  230.                         for(int j=0;j<=cols-1;j++){
  231.                             item = i + j;               //!oldalra léptetést valósítja meg
  232.                             if (item > cols -1)
  233.                                 overHead = cols;        //!overhead: ha esetleg túlfolynánk a mátrixon, akkor visszaugrasztja a mutatót bal oldalra (mintha maga mellé lenne másolva)
  234.                             else
  235.                                 overHead = 0;
  236.                             subResult *= tempMatrix.getItem(j,item-overHead); //!részedmény szorzása az átlóban lévő elemek részeredményével
  237.                         }
  238.                         tDeterminant += phaseFlip * subResult;
  239.                     }
  240.                     //!fázis megfordítása
  241.                     phaseFlip = -1;
  242.                     tempMatrix = tempMatrix.flipHorizontal();
  243.                 }
  244.                 MATRIX_DEBUG debugSpacing();
  245.                 MATRIX_DEBUG cout << "#Done! Determinant: " << tDeterminant << "\r\n";
  246.                 return tDeterminant;
  247.             }else if(cols == 2){
  248.                 //!2x2-es mátrix számítása fixen
  249.                 subResult = tempMatrix.getItem(0,0);
  250.                 subResult *= tempMatrix.getItem(1,1);
  251.                 tDeterminant = subResult;
  252.                 subResult = tempMatrix.getItem(0,1);
  253.                 subResult *= tempMatrix.getItem(1,0);
  254.                 tDeterminant -= subResult;
  255.                 MATRIX_DEBUG debugSpacing();
  256.                 MATRIX_DEBUG cout << "#Done! Determinant: " << tDeterminant << "\r\n";
  257.                 return tDeterminant;
  258.             }else if(cols == 1){
  259.                 tDeterminant  = tempMatrix.getItem(0,0);
  260.                 MATRIX_DEBUG debugSpacing();
  261.                 MATRIX_DEBUG cout << "#Done! Determinant: " << tDeterminant << "\r\n";
  262.                 return tDeterminant;
  263.             }
  264.         }else{
  265.             MATRIX_DEBUG debugSpacing();
  266.             MATRIX_DEBUG cout << "#(!!!)Not a SquareMatrix! ";
  267.             return 0;
  268.         }
  269.     }
  270.  
  271.     Matrix Matrix::getSubDeterminants() const{
  272.         MATRIX_DEBUG debugSpacing();
  273.         MATRIX_DEBUG cout << "#Counting subdeterminants...\r\n";
  274.         Matrix sDeterminants(rows, cols, false, debugRecurse,debugLevel+1);
  275.         for(int i = 0; i <= rows-1;i++){
  276.             for(int j = 0; j <= cols-1;j++){ //!minden egyes elemre al-determináns számolása
  277.                 //!új mátrix létrehozása egyel kevesebb oszloppal és sorral
  278.                 Matrix subMatrix(rows-1, cols-1, false, debugRecurse,debugLevel+1);
  279.                 //!részmátrix elemeinek bemásolása
  280.                 MATRIX_DEBUG cout << "\r\n#Number: " << MatrixData[i][j] <<"\r\n";
  281.                 int backStep1 = 0;
  282.                 int backStep2 = 0;
  283.                 for(int k = 0; k <= rows-1;k++){
  284.                     if (i==k){
  285.                         backStep1 = 1;
  286.                         MATRIX_DEBUG cout << "#>>Skipping k: " << k << "\r\n";
  287.                         continue;
  288.                     }
  289.                     for(int l = 0; l <= cols-1;l++){
  290.                         if (j==l){
  291.                             backStep2 = 1;
  292.                             MATRIX_DEBUG cout << "#>>Skipping l: " << k << "\r\n";
  293.                             continue;
  294.                         }
  295.                         MATRIX_DEBUG cout << "#>>Reading item index: (" << k << "," << l << ") value: " << MatrixData[k][l] <<"\r\n";
  296.                         subMatrix.setItem(MatrixData[k][l],k-backStep1,l-backStep2);
  297.                         MATRIX_DEBUG cout << "# >>Setting to position: (" << k-backStep1 << "," << l-backStep2 << ")\r\n";
  298.                     }
  299.                     backStep2 = 0;
  300.                 }
  301.                 MATRIX_DEBUG subMatrix.drawMatrix();
  302.                 MATRIX_DEBUG cout << "#Subdeterminant: " << subMatrix.getDeterminant() <<"\r\n";
  303.                 sDeterminants.setItem(subMatrix.getDeterminant(),i,j);
  304.             }
  305.             MATRIX_DEBUG debugSpacing();
  306.             MATRIX_DEBUG cout << "#Done!\r\n";
  307.         }
  308.         sDeterminants.drawMatrix();
  309.         return sDeterminants;
  310.     }
  311.  
  312.     Matrix Matrix::getInverse() const{
  313.         MATRIX_DEBUG debugSpacing();
  314.         MATRIX_DEBUG cout << "#Counting inverse...\r\n";
  315.         //!csúnya, át kell írni - önmagáról másolat
  316.         Matrix tempMatrix = Matrix(rows,cols,false,debugRecurse,debugLevel+1);
  317.         for(int v = 0; v <= rows-1;v++)
  318.             for(int z = 0; z <= cols-1;z++)
  319.                 tempMatrix.setItem(MatrixData[v][z],v,z);
  320.         //!
  321.         float mDeterm = tempMatrix.getDeterminant();            //!1.lépés: determinánsok számítása
  322.         if (mDeterm != 0){                                      //!(nem 0 a determináns?)
  323.             Matrix sDeterm = tempMatrix.getSubDeterminants();   //!2.lépés: al-determinánsok számítása
  324.             sDeterm = sDeterm.getTransposed();                  //!3.lépés: al-determinánsok transzponálása
  325.             int sign = 1;                                       //!4.lépés: előjelek fordítása sakktábla szerűen és leosztás a determinánssal
  326.             for(int i = 0; i <= rows-1;i++){
  327.                 for(int j = 0; j <= cols-1;j++){               
  328.                     sDeterm.setItem((sDeterm.getItem(i,j)*sign)/mDeterm,i,j);
  329.                     sign = sign * (-1);
  330.                 }
  331.             }
  332.             MATRIX_DEBUG debugSpacing();
  333.             MATRIX_DEBUG cout << "#Done!\r\n";
  334.             return sDeterm;
  335.         }else{
  336.             MATRIX_DEBUG debugSpacing();
  337.             MATRIX_DEBUG cout << "#ERROR! Determinant is zero (0)! \r\n";
  338.             throw 1;
  339.         }
  340.     }
  341.  
  342. ///Processor sample
  343.     float addOne(float num){    //test
  344.         return num+1;
  345.     }
  346.  
  347. ///Debug function
  348.     void boolCout(bool x){
  349.         if (x)
  350.             std::cout << "true";
  351.         else
  352.             std::cout << "false";
  353.     }
  354.  
  355. ///Entrance
  356.     int main(void){
  357.         Matrix A = Matrix(3,3,true,true);  
  358.         A.fillWithRandomData(4);
  359.         A.fillTestData();
  360.         //A.drawMatrix();
  361.         A.getDeterminant();
  362.         //Matrix B = A.getSubDeterminants();
  363.         //A.applyProcessOnAll(*addOne);
  364.         A = A.getInverse();
  365.         cout << "\r\n";
  366.         A.drawMatrix();
  367.         return 0;
  368.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement