Software & Finance





C++ - Matrix Inverse





Inverse of matix is also widely used in many application. There is a slight difference between adjoint and inverse of a matrix. That is you have to divide each element in adjoint of the matrix by the determinant of the matrix.

 

At the end, you can see if you can find cofactor of a matrix, then it is easy to solve both adjoint and inverse of the matrix.

 

For matrix calculations, finding the determinant and cofactor are the important task. Once you have them, then it is easy to calculate adjoint or inverse of a matrix.

 

Inverse of a matrix is widely used in solving linear equations also. Here is the code for inverse of a matrix and sample output data.

 


Source Code


#if !defined(MATRIX_H)

#define MATRIX_H

 

#include <stdio.h>

#include <iostream>

#include <tchar.h>

#include <math.h>

 

class CMatrix

{

private:

    int m_rows;

    int m_cols;

    char m_name[128];

 

    CMatrix();

public:

    double **m_pData;

 

    CMatrix(const char *name, int rows, int cols) : m_rows(rows), m_cols(cols)

    {

        strcpy(m_name, name);

        m_pData = new double*[m_rows];

        for(int i = 0; i < m_rows; i++)

            m_pData[i] = new double[m_cols];

 

        for(int i = 0; i < m_rows; i++)

        {

            for(int j = 0; j < m_cols; j++)

            {

                m_pData[i][j] = 0.0;

            }

        }

    }

 

    CMatrix(const CMatrix &other)

    {

        strcpy(m_name, other.m_name);

        m_rows = other.m_rows;

        m_cols = other.m_cols;

 

        m_pData = new double*[m_rows];

        for(int i = 0; i < m_rows; i++)

            m_pData[i] = new double[m_cols];

 

        for(int i = 0; i < m_rows; i++)

        {

            for(int j = 0; j < m_cols; j++)

            {

                m_pData[i][j] = other.m_pData[i][j];

            }

        }

    }

 

    ~CMatrix()

    {

        for(int i = 0; i < m_rows; i++)

            delete [] m_pData[i];

        delete [] m_pData;

        m_rows = m_cols = 0;

    }

 

    void SetName(const char *name) { strcpy(m_name, name); }

    const char* GetName() const { return m_name; }

 

    void GetInput()

    {

        std::cin >> *this;

    }

 

    void FillSimulatedInput()

    {

        static int factor1 = 1, factor2 = 2;

        std::cout << "\n\nEnter Input For Matrix : " << m_name << " Rows: " << m_rows << " Cols: " << m_cols << "\n";

        for(int i = 0; i < m_rows; i++)

        {

            for(int j = 0; j < m_cols; j++)

            {

                std::cout << "Input For Row: " << i + 1 << " Col: " << j + 1 << " = ";

                int data = ((i + 1) * factor1) + (j + 1) * factor2;

                m_pData[i][j] = data / 10.2;

                std::cout << m_pData[i][j] << "\n";

 

                factor1 += (rand() % 4);

                factor2 += (rand() % 3);

            }

            std::cout << "\n";

        }

 

        std::cout << "\n";

    }   

 

    double Determinant()

    {

        double det = 0;

        double **pd = m_pData;

        switch(m_rows)

        {

       

        case 2:

        {

            det = pd[0][0] * pd[1][1] - pd[0][1] * pd[1][0];

            return det;

        }

        break;

 

        case 3:

        {

            /***

            a b c

            d e f

            g h i

 

            a b c a b c

            d e f d e f

            g h i g h i

 

            // det (A) = aei + bfg + cdh - afh - bdi - ceg.

            ***/

 

            double a = pd[0][0];

            double b = pd[0][1];

            double c = pd[0][2];

 

            double d = pd[1][0];

            double e = pd[1][1];

            double f = pd[1][2];

 

            double g = pd[2][0];

            double h = pd[2][1];

            double i = pd[2][2];

 

            double det = (a*e*i + b*f*g + c*d*h);

            det = det - a*f*h;

            det = det - b*d*i;

            det = det - c*e*g;

 

            return det;

        }

        break;

 

        case 4:

        {

            CMatrix *temp[4];

            for(int i = 0; i < 4; i++)

                temp[i] = new CMatrix("", 3,3);

 

            for(int k = 0; k < 4; k++)

            {

               

                for(int i = 1; i < 4; i++)

                {

                    int j1 = 0;

                    for(int j = 0; j < 4; j++)

                    {

                        if(k == j)

                            continue;

                        temp[k]->m_pData[i-1][j1++] = this->m_pData[i][j];

                    }

                }

            }

            double det = this->m_pData[0][0] * temp[0]->Determinant() -

            this->m_pData[0][1] * temp[1]->Determinant() +

            this->m_pData[0][2] * temp[2]->Determinant() -

            this->m_pData[0][3] * temp[3]->Determinant();

            return det;

        }

        break;

 

        case 5:

        {

            CMatrix *temp[5];

            for(int i = 0; i < 5; i++)

                temp[i] = new CMatrix("", 4,4);

 

            for(int k = 0; k < 5; k++)

            {

               

                for(int i = 1; i < 5; i++)

                {

                    int j1 = 0;

                    for(int j = 0; j < 5; j++)

                    {

                        if(k == j)

                            continue;

                        temp[k]->m_pData[i-1][j1++] = this->m_pData[i][j];

                    }

                }

            }

            double det = this->m_pData[0][0] * temp[0]->Determinant() -

            this->m_pData[0][1] * temp[1]->Determinant() +

            this->m_pData[0][2] * temp[2]->Determinant() -

            this->m_pData[0][3] * temp[3]->Determinant() +

            this->m_pData[0][4] * temp[4]->Determinant();

            return det;

        }

        case 6:

        case 7:

        case 8:

        case 9:

        case 10:

        case 11:

        case 12:

        default:

        {

            int DIM = m_rows;

            CMatrix **temp = new CMatrix*[DIM];

            for(int i = 0; i < DIM; i++)

                temp[i] = new CMatrix("", DIM - 1,DIM - 1);

 

            for(int k = 0; k < DIM; k++)

            {

               

                for(int i = 1; i < DIM; i++)

                {

                    int j1 = 0;

                    for(int j = 0; j < DIM; j++)

                    {

                        if(k == j)

                            continue;

                        temp[k]->m_pData[i-1][j1++] = this->m_pData[i][j];

                    }

                }

            }

 

            double det = 0;

            for(int k = 0; k < DIM; k++)

            {

                if( (k %2) == 0)

                    det = det + (this->m_pData[0][k] * temp[k]->Determinant());

                else

                    det = det - (this->m_pData[0][k] * temp[k]->Determinant());

            }

 

            for(int i = 0; i < DIM; i++)

                delete temp[i];

            delete [] temp;

 

            return det;

        }

        break;

        }

    }

 

    CMatrix& operator = (const CMatrix &other)

    {

        if( this->m_rows != other.m_rows ||

            this->m_cols != other.m_cols)

        {

            std::cout << "WARNING: Assignment is taking place with by changing the number of rows and columns of the matrix";

        }

        for(int i = 0; i < m_rows; i++)

            delete [] m_pData[i];

        delete [] m_pData;

        m_rows = m_cols = 0;

 

        strcpy(m_name, other.m_name);

        m_rows = other.m_rows;

        m_cols = other.m_cols;

 

        m_pData = new double*[m_rows];

        for(int i = 0; i < m_rows; i++)

            m_pData[i] = new double[m_cols];

 

        for(int i = 0; i < m_rows; i++)

        {

            for(int j = 0; j < m_cols; j++)

            {

                m_pData[i][j] = other.m_pData[i][j];

            }

        }

 

        return *this;

    }

 

    CMatrix CoFactor()

    {

        CMatrix cofactor("COF", m_rows, m_cols);

        if(m_rows != m_cols)

            return cofactor;

 

        if(m_rows < 2)

            return cofactor;

        else if(m_rows == 2)

        {

            cofactor.m_pData[0][0] = m_pData[1][1];

            cofactor.m_pData[0][1] = -m_pData[1][0];

            cofactor.m_pData[1][0] = -m_pData[0][1];

            cofactor.m_pData[1][1] = m_pData[0][0];

            return cofactor;

        }

        else if(m_rows >= 3)

        {

            int DIM = m_rows;

            CMatrix ***temp = new CMatrix**[DIM];

            for(int i = 0; i < DIM; i++)

                temp[i] = new CMatrix*[DIM];

            for(int i = 0; i < DIM; i++)

                for(int j = 0; j < DIM; j++)

                    temp[i][j] = new CMatrix("", DIM - 1,DIM - 1);

 

            for(int k1 = 0; k1 < DIM; k1++)

            {  

                for(int k2 = 0; k2 < DIM; k2++)

                {

                    int i1 = 0;

                    for(int i = 0; i < DIM; i++)

                    {

                        int j1 = 0;

                        for(int j = 0; j < DIM; j++)

                        {

                            if(k1 == i || k2 == j)

                                continue;

                            temp[k1][k2]->m_pData[i1][j1++] = this->m_pData[i][j];

                        }

                        if(k1 != i)

                            i1++;

                    }

                }

            }

 

            bool flagPositive = true;

            for(int k1 = 0; k1 < DIM; k1++)

            {  

                flagPositive = ( (k1 % 2) == 0);

 

                for(int k2 = 0; k2 < DIM; k2++)

                {

                    if(flagPositive == true)

                    {

                        cofactor.m_pData[k1][k2] = temp[k1][k2]->Determinant();

                        flagPositive = false;

                    }

                    else

                    {

                        cofactor.m_pData[k1][k2] = -temp[k1][k2]->Determinant();

                        flagPositive = true;

                    }

                }

               

            }

 

            for(int i = 0; i < DIM; i++)

                for(int j = 0; j < DIM; j++)

                    delete temp[i][j];

 

            for(int i = 0; i < DIM; i++)

                delete [] temp[i];

 

            delete [] temp;

        }

        return cofactor;

    }

 

    CMatrix Adjoint()

    {

        CMatrix cofactor("COF", m_rows, m_cols);

        CMatrix adj("ADJ", m_rows, m_cols);

        if(m_rows != m_cols)

            return adj;

 

        cofactor = this->CoFactor();

           

        // adjoint is transpose of a cofactor of a matrix

        for(int i = 0; i < m_rows; i++)

        {

            for(int j = 0; j < m_cols; j++)

            {

                adj.m_pData[j][i] = cofactor.m_pData[i][j];

            }

        }

        return adj;

    }

 

    CMatrix Transpose()

    {

        CMatrix trans("TR", m_cols, m_rows);

 

        for(int i = 0; i < m_rows; i++)

        {

            for(int j = 0; j < m_cols; j++)

            {

                trans.m_pData[j][i] = m_pData[i][j];

            }

        }

        return trans;

    }

 

    CMatrix Inverse()

    {

        CMatrix cofactor("COF", m_rows, m_cols);

        CMatrix inv("INV", m_rows, m_cols);

        if(m_rows != m_cols)

            return inv;

 

        // to find out Determinant

        double det = Determinant();

 

        cofactor = this->CoFactor();

           

        // inv = transpose of cofactor / Determinant

        for(int i = 0; i < m_rows; i++)

        {

            for(int j = 0; j < m_cols; j++)

            {

                inv.m_pData[j][i] = cofactor.m_pData[i][j] / det;

            }

        }

        return inv;

    }

 

    CMatrix operator + (const CMatrix &other)

    {

        if( this->m_rows != other.m_rows ||

            this->m_cols != other.m_cols)

        {

            std::cout << "Addition could not take place because number of rows and columns are different between the two matrices";

            return *this;

        }

 

        CMatrix result("", m_rows, m_cols);

 

        for(int i = 0; i < m_rows; i++)

        {

            for(int j = 0; j < m_cols; j++)

            {

                result.m_pData[i][j] = this->m_pData[i][j] + other.m_pData[i][j];

            }

        }

        return result;

    }

 

    CMatrix operator - (const CMatrix &other)

    {

        if( this->m_rows != other.m_rows ||

            this->m_cols != other.m_cols)

        {

            std::cout << "Subtraction could not take place because number of rows and columns are different between the two matrices";

            return *this;

        }

 

        CMatrix result("", m_rows, m_cols);

 

        for(int i = 0; i < m_rows; i++)

        {

            for(int j = 0; j < m_cols; j++)

            {

                result.m_pData[i][j] = this->m_pData[i][j] - other.m_pData[i][j];

            }

        }

        return result;

    }

 

 

 

    CMatrix operator * (const CMatrix &other)

    {

        if( this->m_cols != other.m_rows)

        {

            std::cout << "Multiplication could not take place because number of columns of 1st Matrix and number of rows in 2nd Matrix are different";

            return *this;

        }

 

        CMatrix result("", this->m_rows, other.m_cols);

 

        for(int i = 0; i < this->m_rows; i++)

        {

            for(int j = 0; j < other.m_cols; j++)

            {

                for(int k = 0; k < this->m_cols; k++)

                {

                    result.m_pData[i][j] += this->m_pData[i][k] * other.m_pData[k][j];

                }

            }

        }

        return result;

    }

 

    bool operator == (const CMatrix &other)

    {

        if( this->m_rows != other.m_rows ||

            this->m_cols != other.m_cols)

        {

            std::cout << "Comparision could not take place because number of rows and columns are different between the two matrices";

            return false;

        }

 

        CMatrix result("", m_rows, m_cols);

 

        bool bEqual = true;

        for(int i = 0; i < m_rows; i++)

        {

            for(int j = 0; j < m_cols; j++)

            {

                if(this->m_pData[i][j] != other.m_pData[i][j])

                    bEqual = false;

            }

        }

        return bEqual;

    }

 

 

    friend std::istream& operator >> (std::istream &is, CMatrix &m);

    friend std::ostream& operator << (std::ostream &os, const CMatrix &m);   

};

 

std::istream& operator >> (std::istream &is, CMatrix &m)

{

    std::cout << "\n\nEnter Input For Matrix : " << m.m_name << " Rows: " << m.m_rows << " Cols: " << m.m_cols << "\n";

    for(int i = 0; i < m.m_rows; i++)

    {

        for(int j = 0; j < m.m_cols; j++)

        {

            std::cout << "Input For Row: " << i + 1 << " Col: " << j + 1 << " = ";

            is >> m.m_pData[i][j];

        }

        std::cout << "\n";

    }

    std::cout << "\n";

    return is;

}

 

std::ostream& operator << (std::ostream &os,const CMatrix &m)

{

    os << "\n\nMatrix : " << m.m_name << " Rows: " << m.m_rows << " Cols: " << m.m_cols << "\n\n";

    for(int i = 0; i < m.m_rows; i++)

    {

        os << " | ";

        for(int j = 0; j < m.m_cols; j++)

        {

            char buf[32];

            double data = m.m_pData[i][j];

            if( m.m_pData[i][j] > -0.00001 &&

                m.m_pData[i][j] < 0.00001)

                data = 0;

            sprintf(buf, "%10.2lf ", data);

            os <<  buf;

        }

        os << "|\n";

    }

    os << "\n\n";

    return os;

}

 

 

#endif

 

 

int main()

{  

 

    CMatrix a("A", 5,5);

    //std::cin >> a;

    a.FillSimulatedInput();

 

    CMatrix aadj = a.Inverse();

 

    std::cout << a;

    std::cout << aadj;

 

    CMatrix unit = (a * aadj);

    unit.SetName("A * A-Inv");

    std::cout << unit;

}

 

Output


 

Enter Input For Matrix : A Rows: 3 Cols: 3

Input For Row: 1 Col: 1 = 1

Input For Row: 1 Col: 2 = 3

Input For Row: 1 Col: 3 = 5

 

Input For Row: 2 Col: 1 = 3

Input For Row: 2 Col: 2 = -2

Input For Row: 2 Col: 3 = 1

 

Input For Row: 3 Col: 1 = 4

Input For Row: 3 Col: 2 = -3

Input For Row: 3 Col: 3 = 5

 

 

 

 

Matrix : A Rows: 3 Cols: 3

 

 |       1.00       3.00       5.00 |

 |       3.00      -2.00       1.00 |

 |       4.00      -3.00       5.00 |

 

 

 

 

Matrix : INV Rows: 3 Cols: 3

 

 |       0.16       0.67      -0.29 |

 |       0.24       0.33      -0.31 |

 |       0.02      -0.33       0.24 |

 

 

 

 

Matrix : A * A-Inv Rows: 3 Cols: 3

 

 |       1.00       0.00       0.00 |

 |       0.00       1.00       0.00 |

 |       0.00       0.00       1.00 |

 

 

Press any key to continue . . .

 

 

 

Enter Input For Matrix : A Rows: 5 Cols: 5

Input For Row: 1 Col: 1 = 0.294118

Input For Row: 1 Col: 2 = 0.980392

Input For Row: 1 Col: 3 = 1.86275

Input For Row: 1 Col: 4 = 2.84314

Input For Row: 1 Col: 5 = 3.62745

 

Input For Row: 2 Col: 1 = 2.54902

Input For Row: 2 Col: 2 = 3.92157

Input For Row: 2 Col: 3 = 5.09804

Input For Row: 2 Col: 4 = 7.05882

Input For Row: 2 Col: 5 = 9.80392

 

Input For Row: 3 Col: 1 = 6.66667

Input For Row: 3 Col: 2 = 8.92157

Input For Row: 3 Col: 3 = 10.8824

Input For Row: 3 Col: 4 = 12.6471

Input For Row: 3 Col: 5 = 15.3922

 

Input For Row: 4 Col: 1 = 12.0588

Input For Row: 4 Col: 2 = 15.098

Input For Row: 4 Col: 3 = 18.1373

Input For Row: 4 Col: 4 = 20.7843

Input For Row: 4 Col: 5 = 24.4118

 

Input For Row: 5 Col: 1 = 21.1765

Input For Row: 5 Col: 2 = 24.7059

Input For Row: 5 Col: 3 = 27.7451

Input For Row: 5 Col: 4 = 31.0784

Input For Row: 5 Col: 5 = 34.3137

 

 

 

 

Matrix : A Rows: 5 Cols: 5

 

 |       0.29       0.98       1.86       2.84       3.63 |

 |       2.55       3.92       5.10       7.06       9.80 |

 |       6.67       8.92      10.88      12.65      15.39 |

 |      12.06      15.10      18.14      20.78      24.41 |

 |      21.18      24.71      27.75      31.08      34.31 |

 

 

 

 

Matrix : INV Rows: 5 Cols: 5

 

 |      -0.93       0.80      -3.74       2.86      -0.49 |

 |       0.37      -0.32       5.35      -4.91       1.14 |

 |      -0.78      -0.93      -1.46       2.96      -1.10 |

 |       2.37      -0.10       0.25      -1.65       0.84 |

 |      -1.21       0.57      -0.58       0.87      -0.36 |

 

 

 

 

Matrix : A * A-Inv Rows: 5 Cols: 5

 

 |       1.00       0.00       0.00       0.00       0.00 |

 |       0.00       1.00       0.00       0.00       0.00 |

 |       0.00       0.00       1.00       0.00       0.00 |

 |       0.00       0.00       0.00       1.00       0.00 |

 |       0.00       0.00       0.00       0.00       1.00 |

 

 

Press any key to continue . . .

 

 

 

 

 

 

Enter Input For Matrix : A Rows: 2 Cols: 2

Input For Row: 1 Col: 1 = 0.294118

Input For Row: 1 Col: 2 = 0.980392

 

Input For Row: 2 Col: 1 = 1.27451

Input For Row: 2 Col: 2 = 2.15686

 

 

 

 

Matrix : A Rows: 2 Cols: 2

 

 |       0.29       0.98 |

 |       1.27       2.16 |

 

 

 

 

Matrix : INV Rows: 2 Cols: 2

 

 |      -3.51       1.59 |

 |       2.07      -0.48 |

 

 

 

 

Matrix : A * A-Inv Rows: 2 Cols: 2

 

 |       1.00       0.00 |

 |       0.00       1.00 |

 

 

Press any key to continue . . .

 

 

 

 

Inter Input For Matrix : A Rows: 2 Cols: 2

Input For Row: 1 Col: 1 = 3

Input For Row: 1 Col: 2 = -2

 

Input For Row: 2 Col: 1 = 3

Input For Row: 2 Col: 2 = -4

 

 

 

 

Matrix : A Rows: 2 Cols: 2

 

|       3.00      -2.00 |

|       3.00      -4.00 |

 

 

 

 

Matrix : INV Rows: 2 Cols: 2

 

|       0.67      -0.33 |

|       0.50      -0.50 |

 

 

 

 

Matrix : A * A-Inv Rows: 2 Cols: 2

 

|       1.00       0.00 |

|       0.00       1.00 |

 

 

Press any key to continue . . .