Friday 17 November 2017

C++ Program to Find Inverse of a Matrix


Code:

#if !defined(MATRIX_H)
#define MATRIX_H
#include   stdio.h
#include   iostream
#include   tchar.h
#include   math.h
#include   stdlib.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: 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 |




More Java Programs:

















100+ Best Home Decoration Ideas For Christmas Day 2019 To Make Home Beautiful

Best gifts for Christmas Day | Greeting cards for Christmas Day | Gift your children a new gift on Christmas day This Christmas d...