Matrix Library. v1.6.4

Dependents:   Matrix_class Wizardsneverdie TwoTank mbed_multiplex_matrix ... more

Matrix.cpp

Committer:
Yo_Robot
Date:
2011-09-26
Revision:
1:48f417da268e
Parent:
0:3abd8c2d7c34
Child:
2:493402568a5e

File content as of revision 1:48f417da268e:

#include "mbed.h"
#include "Matrix.h"


/// Rows by Cols Matrix Constructor
Matrix::Matrix(int Rows, int Cols): _nCols(Cols), _nRows(Rows)
{
    _matrix.resize(_nRows);
    for( int i = 0; i < _nRows; i++ )
        _matrix[i].resize(_nCols);
}


/// Defines the same parameters as 'base' Matrix
Matrix::Matrix(const Matrix &base): _nCols(base._nCols), _nRows(base._nRows)
{
    _matrix.resize(_nRows);
    for( int i = 0; i < _nRows; i++ )
        _matrix[i].resize(_nCols);
}


/// Square Matrix Constructor
Matrix::Matrix(int square): _nCols(square), _nRows(square)
{
    _matrix.resize(_nRows);
    for( int i = 0; i < _nRows; i++ )
        _matrix[i].resize(_nCols);
}


/// Default Constructor
Matrix::Matrix(){/*Intentionally left Blank*/}


/************************************************************************/


/// Overloaded Asign Operator. Resizes Matrix
Matrix& Matrix::operator = ( const Matrix &rightM )
{
    if( *this != rightM )
    {
        this->_nRows = rightM._nRows;
        this->_nCols = rightM._nCols;

        this->_matrix.resize( rightM._nRows );
        for( int i = 0; i < rightM._nRows; i++ )
            this->_matrix [i].resize(rightM._nCols);

        for( int i = 0; i < _nRows; i++ )
            for( int j = 0; j < _nCols; j++ )
                this->_matrix[i][j] = rightM._matrix[i][j];

        return *this;

    }else{

        Matrix ret (*this);
        return ret;
    }
}

/// Comapre element by element
bool Matrix::operator == ( const Matrix& rightM )
{
    if( _nRows == rightM._nRows  &&  _nCols == rightM._nCols )
    {
        bool equal = false;

        for( int i = 0; i < _nRows; i++ )
            for( int j = 0; j < _nCols; j++ )
                if( _matrix[i][j] != rightM._matrix[i][j] )
                    equal = equal || true;

        return !equal;

    }else{  return false;  }
}


/// Calls for '==' operator
bool Matrix::operator != ( const Matrix &rightM )
{
    return !( *this == rightM );
}


/// Matrices must be same size.
/// Element by element adition.
Matrix& Matrix::operator +=(const Matrix& rightM)
{
    if( _nRows == rightM._nRows  &&  _nCols == rightM._nCols )
    {
        for( int i = 0; i < _nRows; i++ )
            for( int j = 0; j < _nCols; j++ )
                _matrix[i][j] += rightM._matrix[i][j];

        return *this;

    }else{
        printf( "\n\nERROR\nDiferent Dimensions @ += \n" );
       // Matrix error(4);
       // error.Clear();
       // return error;
    }
}


/// Matrices must be same size.
/// Element by element Substraction
Matrix& Matrix::operator -=(const Matrix& rightM)
{
    if( _nRows == rightM._nRows  &&  _nCols == rightM._nCols )
    {
        for( int i = 0; i < _nRows; i++ )
            for( int j = 0; j < _nCols; j++ )
                _matrix[i][j] -= rightM._matrix[i][j];

        return *this;

    }else{
        printf( "\n\nERROR\nDiferent Dimensions @ -= \n" );
        //Matrix error(4);
        //error.Clear();
        //return error;
    }
}


/// Element by element Adition. Must be same sizes
const Matrix Matrix::operator +(const Matrix& rightM)
{
    Matrix result = *this;
    result += rightM;
    return result;
}


/// Element by element Substraction. Must be same sizes
const Matrix Matrix::operator -(const Matrix& rightM)
{
    Matrix result = *this;
    result -= rightM;
    return result;
}

/************************************************************************/


/// Returns true if matrix is full of zeros
bool Matrix::isZero()
{
    bool zero = false;
    for( int i = 0; i < this->_nRows; i++ )
        for( int j = 0; j < this->_nCols; j++ )
            if( this->_matrix[i][j] != 0 )
                zero = zero || true;
    return !zero;
}


/// Returns true if Matrix is Single Row ot Single Column.
bool Matrix::isVector()
{
    if( this->_nRows == 1 || this->_nCols == 1 )
        return true;
    else
        return false;
}

/*************************************************************************/

/// Returns all elements in Matrix as a single Row vector.
Matrix Matrix::ToPackedVector()
{
    Matrix Shattered( ( this->_nRows * this->_nCols ) , 1 );

    int cont = 0;
    for( int i = 0; i < this->_nRows; i++ )
    {
        for( int j = 0; j < this->_nCols; j++ )
        {
            Shattered._matrix[0][cont] = this->_matrix[i][j];
            cont++;
        }
    }

    return Shattered;
}

/***************************************************************************/

/// Test elment-by-element. Prints detailed error.
bool Matrix::Equals( const Matrix mat1, const Matrix mat2 )
{
    if( mat1._nCols == mat2._nCols  &&  mat1._nRows == mat2._nRows )
    {
        bool equal = false;

        for( int i = 0; i < mat1._nRows; i++ )
            for( int j = 0; j < mat1._nCols; j++ )
                if( mat1._matrix[i][j] != mat2._matrix[i][j] )
                    equal = equal || true;

        return !equal;

    }else{
        printf( "\n\nERROR:\nDiferent Size Matrices!\n" );
        printf( "mat1._nRows = %u\nmat1._nCols = %u\n",mat1._nRows, mat1._nCols );
        printf( "mat2._nRows = %u\nmat2._nCols = %u\n",mat2._nRows, mat2._nCols );
        return false;
    }
}


/// To Implicitly create a Single Column Matrix.
Matrix Matrix::CreateColumnMatrix(int Cols)
{
    Matrix ColMatrix(1,Cols);
    return ColMatrix;
}


/// To Implicitly create a Single Row Matrix.
Matrix Matrix::CreateRowMatrix(int Rows)
{
    Matrix RowMatrix( Rows, 1);
    return RowMatrix;
}


/// To implicitly Clone a Matrix. Although '=' works the same.
void Matrix::Clone( const Matrix &Source, Matrix &Receip )
{
    Receip._nCols = Source._nCols;
    Receip._nRows = Source._nRows;

    Receip._matrix.resize(Receip._nRows);
    for( int i = 0; i < Receip._nRows; i++ )
        Receip._matrix[i].resize(Receip._nCols);

    for( int i = 0; i < Receip._nRows; i++ )
       for( int j = 0; j < Receip._nCols; j++ )
           Receip._matrix[i][j] = Source._matrix[i][j];
}


/// To add (Insert) a Single Row to a Matrix. 
void Matrix::AddRow(Matrix& Mat, int Row)
{
    --Row;

    if( Row > Mat._nRows + 1)
    {
        printf("\n\nERROR:\nRow out of Limits @ AddRow()\n");
       
    }else{

       Mat._nRows++;
       Mat._matrix.resize( Mat._nRows );

       Mat._matrix[ Mat._nRows - 1 ].resize( Mat._nCols );

       for( int i = Mat._nRows - 1; i > Row; i-- )
           for( int j = 0; j < Mat._nCols; j++ )
               Mat._matrix[i][j] = Mat._matrix[i - 1][j];

       for( int j = 0; j < Mat._nCols; j++ )
           Mat._matrix[Row][j] = 0.0;
    }
}


/// To add (Insert) a single Column to a Matrix
void Matrix::AddColumn( Matrix &Mat, int Col )
{
    --Col;

    if( Col > Mat._nCols + 1 )
    {
        printf("\n\nERROR:\nRow out of Limits on AddCol()\n");
        
    }else{


            Mat._nCols++;
            for( int i = 0; i < Mat._nRows; i++ )
                Mat._matrix[i].resize( Mat._nCols );

            for( int i = 0; i < Mat._nRows; i++ )
                for( int j = Mat._nCols; j > Col; j-- )
                    Mat._matrix[i][j] = Mat._matrix[i][j - 1];

            for( int i = 0; i < Mat._nRows; i++ )
                Mat._matrix[i][Col] = 0.0;

    }
}


/// Delete a Single Column From Matrix.
void Matrix::DeleteCol( Matrix &Mat, int Col)
{
    --Col; // Because of Column zero.

    if( Col > Mat._nCols )
    {
        printf("\n\nERROR:\nColumn out of Limits @ DeleteCol()\n");
            
    }else{

        for( int i = 0; i < Mat._nRows; i++ )
            for( int j = Col; j < Mat._nCols; j++ )
                Mat._matrix[i][j] = Mat._matrix[i][j+1];

        // Decrease one column
        Mat._nCols--;

        //Erase last Column
        for( int i = 0; i < Mat._nRows; i++ )
            Mat._matrix[i].reserve(Mat._nCols);

    }
}


/// Delete a Single Row form Matrix
void Matrix::DeleteRow(Matrix& Mat, int Row)
{
    --Row;

    if( Row > Mat._nRows )
    {
        printf("\n\nERROR:\nColumn out of Limits @ DeleteCol()\n");
        
    }else{

        for( int i = Row; i < Mat._nRows - 1; i++ )
        
            for( int j = 0; j < Mat._nCols; j++ )
                Mat._matrix[i][j] = Mat._matrix[i+1][j];
        Mat._nRows--;
        Mat._matrix.resize(Mat._nRows);
    }
}

/*****************************************************************************************/

/// Extracts a single row form calling matrix and saves it to another matrix.
void Matrix::ExportRow( int Row, Matrix &Mat )
{
    --Row;

    if( Row > this->_nRows )
    {
        printf( "\n\nWARNING: Row out of dimmensions @ GetRow\n"
                "Nothing Done.\n\n" );

    }else{

        Matrix SingleRow( 1 , this->_nCols );
        SingleRow.Clear();
        
        for( int j = 0; j < this->_nCols; j++ )
        SingleRow._matrix[0][j] = this->_matrix[Row][j];
        
        Mat = SingleRow;
    }
}


/// Extracts a single column form calling matrix and saves it to another matrix.
void Matrix::ExportCol( int Col, Matrix &Mat )
{
    if( Col > this->_nCols )
    {
        printf( "\n\nWARNING:\nCol out of dimmensions.\n"
                "Nothing Done.\n\n" );
    }else{

        Matrix SingleCol( this->_nRows, 1 );
        for(int i = 0; i < this->_nRows; i++ )
            SingleCol._matrix[i][0] = this->_matrix[i][Col];
        Mat = SingleCol;
    }
}


/// Makes matrix Bigger!
void Matrix::Resize( int Rows, int Cols )
{
    this->_nRows = Rows;
    this->_nCols = Cols;
    this->_matrix.resize( _nRows );
    
    for( int i = 0; i< _nRows ; i++ )
        _matrix[i].resize(_nCols);
}


/// Ask user for elemnts in Matrix
void Matrix::FillMatrix()
{
    for(int i = 0; i < _nRows; i++)
    {
        for(int j = 0; j < _nCols; j++)
        {
            printf( "Position [%u][%u]: ", i, j );
            float numero;
            scanf( "%f", &numero );
            printf("%.3f ", numero);
            this->_matrix[i][j] = numero;
        }
        printf("\n");
    }
    printf("\n");
}


/// Prints out Matrix.
void Matrix::print()
{
    for( int i = 0; i < _nRows; i++ )
    {
        for( int j = 0; j < _nCols; j++ )
        {
            printf( "%.3f, ",_matrix[i][j] );

        }
        printf( "\n" );
    }
}


/// Fills matrix with zeros.
void Matrix::Clear()
{
    for( int i = 0; i < _nRows; i++ )
       for( int j = 0; j < _nCols; j++ )
           _matrix[i][j] = 0;
}

/********************************************************************************/

/// Inserts a Single element in a desired Position( Index starts at [1][1] );
void Matrix::add(int Row, int Col, float number)
{
    --Col; --Row;
    
    if( Row > _nRows || Col > _nCols )
    {
        printf("\n\nERROR:\nOut of limits of Matrix @ mat.Add()");
        
    }else{
        _matrix[Row][Col] = number;
    }
}


/// Adds all elements in matrix and returns the answer.
float Matrix::sum()
{
    float total;

    for( int i = 0; i < this->_nRows; i++ )
        for( int j = 0; j < this->_nCols; j++ )
            total += this->_matrix[i][j];
    return total;
}


/// Returns the specified element. Index Starts at [1][1].
float Matrix::getNumber( int Row, int Col )
{ return this->_matrix[Row -1][Col - 1]; }

/// Returns the number of Rows in Matrix.
int Matrix::getRows(){ return this->_nRows; }


/// Returns the number of Columns in Matrix.
int Matrix::getCols(){ return this->_nCols; }