Click here to Skip to main content
15,884,099 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
#include<iostream.h>
#include<conio.h>


class Matrix
{
public:    // constructors
    Matrix()
    {    //printf("Executing constructor Matrix() ...\n");
        // create a Matrix object without content
        p = NULL;
        rows = 0;
        cols = 0;
    }
    Matrix(const int row_count, const int column_count)
    {    // create a Matrix object with given number of rows and columns
        //printf("Executing constructor Matrix(const int column_count, const int row_count) ...\n");
        p = NULL;
        if (row_count > 0 && column_count > 0)
        {
            rows = row_count;
            cols = column_count;
            p = new double*[rows];
            for (int r = 0; r < rows; r++)
            {
                p[r] = new double[rows];
                // initially fill in zeros for all values in the matrix;
                for (int c = 0; c < cols; c++)
                {
                    p[r][c] = 0;
                }
            }
        }
    }
    // assignment operator
    Matrix(const Matrix& a)
    {
        //printf("Executing constructor Matrix(const Matrix& a) ...\n");
        rows = a.rows;
        cols = a.cols;
        p = new double*[a.rows];
        for (int r = 0; r < a.rows; r++)
        {
            p[r] = new double[a.cols];
            // copy the values from the matrix a
            for (int c = 0; c < a.cols; c++)
            {
                p[r][c] = a.p[r][c];
            }
        }
    }
    // index operator. You can use this class like myMatrix(col, row)
    // the indexes are one-based, not zero based.
 double& operator()(const int r, const int c)
 {
        //printf("Executing Matrix operator() ...\n");
       if (p != NULL && r > 0 && r <= rows && c > 0 && c <= cols)
       {
           return p[r-1][c-1];
        }
       else
       {
            throw Exception("Subscript out of range");
        }
    }
    // assignment operator
    Matrix& operator= (const Matrix& a)
    {
        //printf("Executing Matrix operator= ...\n");
        rows = a.rows;
        cols = a.cols;
        p = new double*[a.rows];
        for (int r = 0; r < a.rows; r++)
        {
            p[r] = new double[a.cols];
            // copy the values from the matrix a
            for (int c = 0; c < a.cols; c++)
            {
                p[r][c] = a.p[r][c];
            }
        }
        return *this;
    }
    // operator addition 1
    friend Matrix operator+(const Matrix& a, const Matrix& B)
    {
        // check if the dimensions match
       /* if (a.rows == b.rows && a.cols == b.cols)*/
        {
          Matrix res(a.rows, a.cols);
            for (int r = 0; r < a.rows; r++)
            {
                for (int c = 0; c < a.cols; c++)
                {
                 //   res.p[r][c] = a.p[r][c] + b.p[r][c];
                }
            }
          return res;
        }
 else
        {
            // give an error
            throw Exception("Dimensions does not match");
        }
        // return an empty matrix (this never happens but just for safety)
        return Matrix();
    }
    // add a double value (elements wise)
    Matrix& add(double v)
    {
        for (int r = 0; r < rows; r++)
        {
            for (int c = 0; c < cols; c++)
            {
                p[r][c] += v;
            }
        }
      return *this;
    }
    // subtract a double value (elements wise)
    Matrix& subtract(double v)
    {
        return add(-v);
    }
    // multiply a double value (elements wise)
    Matrix& multiply(double v)
    {
        for (int r = 0; r < rows; r++)
        {
            for (int c = 0; c < cols; c++)
            {
                p[r][c] *= v;
            }
        }
      return *this;
    }
    // operator subtraction 2
    friend Matrix operator- (const Matrix& a, const Matrix& b)
    {
        // check if the dimensions match
        if (a.rows == b.rows && a.cols == b.cols)
        {
          Matrix res(a.rows, a.cols);
            for (int r = 0; r < a.rows; r++)
            {
                for (int c = 0; c < a.cols; c++)
                {
                    res.p[r][c] = a.p[r][c] - b.p[r][c];
                }
            }
          return res;
        }
        else
        {
            // give an error
            throw Exception("Dimensions does not match");
        }
        // return an empty matrix (this never happens but just for safety)
        return Matrix();
    }
    // operator unary minus
    friend Matrix operator- (const Matrix& a)
    {
      Matrix res(a.rows, a.cols);
        for (int r = 0; r < a.rows; r++)
        {
            for (int c = 0; c < a.cols; c++)
            {
                res.p[r][c] = -a.p[r][c];
            }
        }
   
        return res;
    }
   
    // operator multiplication 3
    friend Matrix operator* (const Matrix& a, const Matrix& B)
    {
        // check if the dimensions match
        if (a.cols == b.rows)
        {
          Matrix res(a.rows, b.cols);
            for (int r = 0; r < a.rows; r++)
            {
                for (int c_res = 0; c_res < b.cols; c_res++)
                {
                    for (int c = 0; c < a.cols; c++)
                    {
                        res.p[r][c_res] += a.p[r][c] * b.p[c][c_res];
                    }
                }
            }
          return res;
        }
        else
        {
            // give an error
            throw Exception("Dimensions does not match");
        }
        // return an empty matrix (this never happens but just for safety)
        return Matrix();
    }
    /*
     * returns the minor from the given matrix where
     * the selected row and column are removed
     */
    Matrix minor(const int row, const int col)
    {
        //printf("minor(row=%i, col=%i), rows=%i, cols=%i\n", row, col, rows, cols);
        Matrix res;
       if (row > 0 && row <= rows && col > 0 && col <= cols)
       {
            res = Matrix(rows - 1, cols - 1);
           
            // copy the content of the matrix to the minor, except the selected
            for (int r = 1; r <= (rows - (row >= rows)); r++)
            {
                for (int c = 1; c <= (cols - (col >= cols)); c++)
                {
                    //printf("r=%i, c=%i, value=%f, rr=%i, cc=%i \n", r, c, p[r-1][c-1], r - (r > row), c - (c > col));
                    res(r - (r > row), c - (c > col)) = p[r-1][c-1];
                }
            }       
        }
        else
        {
            throw Exception("Index for minor out of range");
        }
       
        return res;
    }
   
    /*
     * returns the size of the i-th dimension of the matrix.
     * i.e. for i=1 the function returns the number of rows,
     * and for i=2 the function returns the number of columns
     * else the function returns 0
     */
    int size(const int i)
    {
        if (i == 1)
        {
            return rows;
        }
        else if (i == 2)
        {
            return cols;
        }
        return 0;
    }
    // returns the number of rows
    int get_rows()
    {
        return rows;
    }
   
    // returns the number of columns
    int get_cols()
    {
        return cols;
    }
    // print the contents of the matrix
    void print()
    {
        if (p != NULL)
        {
            printf("[");
            for (int r = 0; r < rows; r++)
            {
                if (r > 0)
                {
                    printf(" ");
                }
                for (int c = 0; c < cols-1; c++)
                {
                    printf("%.2f, ", p[r][c]);
                }
                if (r < rows-1)
                {
                    printf("%.2f;\n", p[r][cols-1]);
                }
                else
                {
                    printf("%.2f]\n", p[r][cols-1]);
                }
            }
        }
        else
        {
            // matrix is empty
            printf("[ ]\n");
        }
    }
public:
    // destructor
    ~Matrix()
    {
        // clean up allocated memory
        for (int r = 0; r < rows; r++)
        {
            delete p[r];
        }
        delete p;
        p = NULL;
    }
private:
    int rows;
    int cols;
    double** p;         // pointer to a matrix with doubles
};
/*
 * i.e. for i=1 the function returns the number of rows,
 * and for i=2 the function returns the number of columns
 * else the function returns 0
 */
int size(Matrix& a, const int i)
{
    return a.size(i);
}

// addition of Matrix with double
Matrix operator+ (const Matrix& a, const double B)
{
    Matrix res = a;
    res.add(B);
    return res;
}
// addition of double with Matrix
Matrix operator+ (const double b, const Matrix& a)
{
    Matrix res = a;
    res.add(b);
    return res;
}
// subtraction of Matrix with double
Matrix operator- (const Matrix& a, const double B)
{
    Matrix res = a;
    res.subtract(B);
    return res;
}
// subtraction of double with Matrix
Matrix operator- (const double b, const Matrix& a)
{
    Matrix res = -a;
    res.add(b);
    return res;
}
// multiplication of Matrix with double
Matrix operator* (const Matrix& a, const double B)
{
    Matrix res = a;
    res.multiply(B);
    return res;
}
// multiplication of double with Matrix
Matrix operator* (const double b, const Matrix& a)
{
    Matrix res = a;
    res.multiply(b);
    return res;
}

/**
 * returns a matrix with size cols x rows with ones as values
 */
Matrix ones(const int rows, const int cols)
{
    Matrix res = Matrix(rows, cols);
    for (int r = 1; r < rows; r++)
    {
        for (int c = 1; c <= cols; c++)
        {
            res(r, c) = 1;
        }
    }
    return res;
}
/**
 * returns a matrix with size cols x rows with zeros as values
 */
Matrix zeros(const int rows, const int cols)
{
    return Matrix(rows, cols);
}

/**
 * returns a diagonal matrix with size n x n with ones at the diagonal
 * @param   v a vector
 * @return  a diagonal matrix with ones on the diagonal
 */
Matrix diag(const int n)
{
    Matrix res = Matrix(n, n);
    for (int i = 1; i <= n; i++)
    {
        res(i, i) = 1;
    }
    return res;
}
/**
 * returns a diagonal matrix
 * @param   v a vector
 * @return  a diagonal matrix with the given vector v on the diagonal
 */
Matrix diag(Matrix& v)
{
    Matrix res;
    if (v.get_cols() == 1)
    {
        // the given matrix is a vector n x 1
        int rows = v.get_rows();
        res = Matrix(rows, rows);
       
        // copy the values of the vector to the matrix
        for (int r=1; r <= rows; r++)
        {
            res(r, r) = v(r, 1);
        }
    }
    else if (v.get_rows() == 1)
    {
        // the given matrix is a vector 1 x n
        int cols = v.get_cols();
        res = Matrix(cols, cols);
        // copy the values of the vector to the matrix
        for (int c=1; c <= cols; c++)
        {
            res(c, c) = v(1, c);
        }       
    }
    else
    {
        throw Exception("Parameter for diag must be a vector");
    }
    return res;
}
/*
 * returns the determinant of Matrix a
 */
double det(Matrix& a)
{
    double d = 0;       // value of the determinant
    int rows = a.get_rows();
    int cols = a.get_cols();
   
    if (rows == cols)
    {
        // this is a square matrix
        if (rows == 1)
        {
            // this is a 1 x 1 matrix
            d = a(1, 1);
        }
        else if (rows == 2)
        {
            // this is a 2 x 2 matrix
            // the determinant of [a11,a12;a21,a22] is det = a11*a22-a21*a12
            d = a(1, 1) * a(2, 2) - a(2, 1) * a(1, 2);
        }
        else
        {
            // this is a matrix of 3 x 3 or larger
            for (int c = 1; c <= cols; c++)
            {
                Matrix M = a.minor(1, c);
                //d += pow(-1, 1+c)  * a(1, c) * det(M);
                d += (c%2 + c%2 - 1) * a(1, c) * det(M);  // faster than with pow()
            }
        }
    }
    else
    {
        throw Exception("Matrix must be square");
    }
    return d;
}
// swap two values
void swap(double& a, double& b)
{
    double temp = a;
    a = b;
    b = temp;
}
/*
 * returns the inverse of Matrix a
 */
Matrix inv(Matrix& a)
{
    Matrix res;
    double d = 0;       // value of the determinant
    int rows = a.get_rows();
    int cols = a.get_cols();
   
    d = det(a);
    if (rows == cols && d != 0)
    {
        // this is a square matrix
        if (rows == 1)
        {
            // this is a 1 x 1 matrix
            res = Matrix(rows, cols);
            res(1, 1) = 1 / a(1, 1);
        }
        else if (rows == 2)
        {
            // this is a 2 x 2 matrix
            res = Matrix(rows, cols);
            res(1, 1) = a(2, 2);
            res(1, 2) = -a(1, 2);
            res(2, 1) = -a(2, 1);
            res(2, 2) = a(1, 1);
            res = (1/d) * res;
        }
        else
        {
            // this is a matrix of 3 x 3 or larger
            // calculate inverse using gauss-jordan elimination
            //      [url="http://mathworld.wolfram.com/MatrixInverse.html"]http://mathworld.wolfram.com/MatrixInverse.html[/url]
            //      [url="http://math.uww.edu/~mcfarlat/inverse.htm"]http://math.uww.edu/~mcfarlat/inverse.htm[/url]
            res = diag(rows);     // a diagonal matrix with ones at the diagonal
            Matrix ai = a;        // make a copy of Matrix a
            for (int c = 1; c <= cols; c++)
            {
                // element (c, c) should be non zero. if not, swap content
                // of lower rows
                int r;
                for (r = c; r <= rows && ai(r, c) == 0; r++)
                {
                }               
                if (r != c)
                {
                    // swap rows
                    for (int s = 1; s <= cols; s++)
                    {
                        swap(ai(c, s), ai(r, s));
                        swap(res(c, s), res(r, s));
                    }
                }
                // eliminate non-zero values on the other rows at column c
                for (int r = 1; r <= rows; r++)
                {
                    if(r != c)
                    {
                        // eleminate value at column c and row r
                        if (ai(r, c) != 0)
                        {
                            double f = - ai(r, c) / ai(c, c);
                           
                            // add (f * row c) to row r to eleminate the value
                            // at column c
                            for (int s = 1; s <= cols; s++)
                            {
                                ai(r, s) += f * ai(c, s);
                                res(r, s) += f * res(c, s);
                            }
                        }                   
                    }
                    else
                    {
                        // make value at (c, c) one,
                        // divide each value on row r with the value at ai(c,c)
                        double f = ai(c, c);
                        for (int s = 1; s <= cols; s++)
                        {
                            ai(r, s) /= f;
                            res(r, s) /= f;
                        }                       
                    }
                }               
            }
        }
    }
    else
    {
        if (rows == cols)
        {
            throw Exception("Matrix must be square");
        }
        else
        {
            throw Exception("Determinant of matrix is zero");
        }
    }
    return res;
}

int main(int argc, char *argv[])
{
    try
    {
        // create an empty matrix of 3x3 (will initially contain zeros)
        int cols = 3;
        int rows = 3;
        Matrix A = Matrix(cols, rows);
        // fill in some values in matrix a
        int count = 0;
        for (int r = 1; r <= rows; r++)
        {
            for (int c = 1; c <= cols; c++)
            {
                count ++;
                A(r, c) = count;
            }
        }
        // adjust a value in the matrix  (indexes are one-based)
        A(2,1) = 1.23;
        // read a value from the matrix  (indexes are one-based)
        double centervalue = A(2,2);
        printf("centervalue = %f \n", centervalue);
        printf("\n");
        // print the whole matrix
        printf("A = \n");
        A.print();
        printf("\n");
        Matrix B = ones(rows, cols) + diag(rows);
        printf("B = \n");
        B.print();
        printf("\n");
        Matrix B2 = Matrix(rows, 1);        // a vector
        count = 1;
        for (int r = 1; r <= rows; r++)
        {
            count ++;
            B2(r, 1) = count * 2;
        }
        printf("B2 = \n");
        B2.print();
        printf("\n");
       
        Matrix C;
        C = A + B;
        printf("A + B = \n");
        C.print();
        printf("\n");
        C = A - B;
        printf("A - B = \n");
        C.print();
        printf("\n");
        C = A * B2;
        printf("A * B2 = \n");
        C.print();
        printf("\n");
        // create a diagonal matrix
        Matrix E = diag(B2);
        printf("E = \n");
        E.print();
        printf("\n");
        // calculate determinant
        Matrix D = Matrix(2, 2);
        D(1,1) = 2;
        D(1,2) = 4;
        D(2,1) = 1;
        D(2,2) = -2;
        printf("D = \n");
        D.print();
        printf("det(D) = %f\n\n", det(D));
        printf("A = \n");
        A.print();
        printf("\n");
        printf("det(A) = %f\n\n", det(A));
       
        Matrix F;
        F = 3 - A ;
        printf("3 - A = \n");
        F.print();
        printf("\n");
       
        // test inverse
        Matrix G = Matrix(2, 2);
        G(1, 1) = 1;
        G(1, 2) = 2;
        G(2, 1) = 3;
        G(2, 2) = 4;
        printf("G = \n");
        G.print();
        printf("\n");
        Matrix G_inv = inv(G);
        printf("inv(G) = \n");
        G_inv.print();
        printf("\n");
       
        Matrix A_inv = inv(A);
        printf("inv(A) = \n");
        A_inv.print();
        printf("\n");
    }
    catch (Exception err)
    {
        printf("Error: %s\n", "err.msg");
    }
    catch (...)
    {
        printf("An error occured...\n");
    }
    printf("\n");
    system("PAUSE");
    return EXIT_SUCCESS;
}
Posted
Updated 1-Dec-11 8:00am
v2
Comments
Sergey Alexandrovich Kryukov 1-Dec-11 13:14pm    
This is just a code dump. Who would volunteer to read it if you don't even explain the problem?
--SA
RaviRanjanKr 1-Dec-11 13:15pm    
Not clear. please be more specific while asking question.
carlmack 1-Dec-11 13:29pm    
Thanks for your kind response, i know my code is long, i am doing it for a course assignment, but more than just getting the help i need to understand because i enjoy working at it so far. I want to write a program to compute Matrices, find the determinant, the co factor do addition and subtraction etc, I want to use a base class call Matrix then some derived classes to assist with displaying and executing the correct sequence of my code, but i am lost, tell the truth, i am not giving up but i would like some help in the direction i should go, oh! my code is in C++ my compiler is Dev C++ and Boreland C++, Thanks for the assistance
#realJSOP 1-Dec-11 13:59pm    
WTF makes you think we want to wade through all that code?
Albert Holguin 1-Dec-11 16:19pm    
Where do I vote this comment up? ...lol

1 solution

C++
class COtherMatix : public Matrix
{
public:
    virtual bool SomeFunction(void)
    {
       // Do derived class stuff....
    }
};
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900