bool same_order(const SMatrix& m1, const SMatrix& m2) { if(m1.getRows() == m2.getRows() && m1.getCols() == m2.getCols()) return true; else return false; }
/** * Divide the matrix by the given matrix. The matrixes must be the same size * this is checked via assertions. We perform the division by multiplication * of the inverse so this is a costly operation. * * @param im The matrix to divide by */ SMatrix SMatrix::operator /( const SMatrix &im ) const { assert( this->getCols() == im.getCols() && "Amount of Columns Differ"); assert( this->getRows() == im.getRows() && "Amount of Rows Differ" ); return (*this) * inv ( im ); }
/** * Multiply one matrix by the other - the matrixes are the same size * Multiplication is done: this * im * * @param im The matrix to multiply by */ SMatrix SMatrix::operator *( const SMatrix &im ) const { SMatrix m ( im.getRows()); m.storeProduct( *this, im ); return m; }
bool SMatrix::equal(const SMatrix& otherMat) const { if(cols == otherMat.getCols() && rows == otherMat.getRows()) return true; else return false; }
bool multiplicable(const SMatrix& m1, const SMatrix& m2) { if( m1.getRows() == m2.getCols()) return true; else return false; }
/** * Inverse the given matrix * * @param im The matrix to invert */ SMatrix inv ( const SMatrix &im ) { SMatrix m ( im.getRows() ); m.storeInverse ( im ); return m; }
/** * Transpose the Given matrix into the new Matrix * * @param im The matrix to transpose */ SMatrix transpose ( const SMatrix &im ) { SMatrix m( im.getRows()); m.storeTranspose( im ); return m; }
void output(std::ostream& outs, const SMatrix& src) { // NOTE: r and c are row # and coloum #, NOT indices for(int r = 1; r <= src.getRows(); ++r) { for(int c = 1; c <= src.getCols(); ++c) outs << setw(SMatrix::FIELD_WIDTH) << src.valAt(r, c); outs << endl; } }
SMatrix add(const SMatrix& m1, const SMatrix& m2) { SMatrix newMat; newMat.setRows(m1.getRows()); newMat.setCols(m1.getCols()); int result; for( int i = 0; i < m1.getRows(); i++ ) { for( int j = 0; j < m1.getCols(); j++ ) { result = m1.valAt(i+1, j+1) + m2.valAt(i+1, j+1); newMat.setVal(i, j, result); } } return newMat; }
SMatrix SMatrix::times(const SMatrix& otherMat) const { SMatrix newMat; newMat.setRows(rows); newMat.setCols(otherMat.getCols()); int result; for( int i = 0; i < rows; i++ ) { for( int k = 0; k < otherMat.getCols(); k++ ) { result = 0; for(int j = 0; j < otherMat.getRows(); j++ ) { result+=(data[i][j] * otherMat.valAt(j+1, k+1)); } newMat.setVal(i, k, result); } } return newMat; }
/** * Calculate the determinate of matrix. Theres a number of * ways to do this. Using coofactors of a matrix uses recursion so * we avoid this. Instead we use Gauss-Jordan Elimination and use * an iterative approach. * * This elimination comes into play due to the fact * that if the elements in lower triangle of the * matrix are all zeroes, the determinant is simply * the product of the diagonals. This also applies * in the upper triangle zeroes. It means the determinate * ends up being the product of the main diagonal after elmination * * * @param im The matrix to calculate the determinate of */ T det ( const SMatrix &im ) { unsigned i, j, k; T temp, factor, detvalue = 1.0; // Determinate of a 1x1 matrix if ( im.getRows() == 1 ){ return im[0][0]; } // Determinate of a 2x2 matrix else if ( im.getRows() == 2 ){ return im[0][0]*im[1][1] - im[1][0]*im[0][1]; } // Determinate of a 3x3 matrix else if ( im.getRows() == 3 ){ detvalue = -im[0][2]*im[1][1]*im[2][0];//-a02 a11 a20 detvalue += im[0][1]*im[1][2]*im[2][0];//+ a01 a12 a20 detvalue += im[0][2]*im[1][0]*im[2][1];//+ a02 a10 a21 detvalue -= im[0][0]*im[1][2]*im[2][1];//- a00 a12 a21 detvalue -= im[0][1]*im[1][0]*im[2][2];//- a01 a10 a22 detvalue += im[0][0]*im[1][1]*im[2][2];//+ a00 a11 a22 return detvalue; } // The determinate for any other size matrix SMatrix m ( im ); for ( i = 0; i < m.getRows(); i++ ){ // If the main diagonal is zero, resort the matrix if ( m[i][i] == 0.0 ){ for ( j = i+1; j < m.getRows(); j++ ){ if ( m[j][i] != 0.0 ){ // Add one row to other for ( k = 0; k < m.getCols(); k++ ){ temp = m[i][k]; m[i][k] = m[j][k]; m[j][k] = temp; } // For Gauss-Jordan Elimination if we do a switch, //the determinant switches sign. detvalue = -detvalue; break; } } } // If after resort the diagonal is still zero then the determinate // is definately zero // Pointless contining if det is already zero if ( m[i][i] == 0.0 ){ return 0.0; } // We now elimiate the lower rows to obtain a triangle of zeros for ( j = i+1; j < m.getRows(); j++ ){ if ( j != i ){ factor = ( m[j][i] * 1.0 ) / m[i][i]; // Add one row to the other for ( k = i; k < m.getCols(); k++ ){ m[j][k]-=factor * m[i][k]; } } } } // Calculate the main diagonal for ( i = 0; i < m.getRows(); i++ ){ detvalue *= m[i][i]; } return detvalue; }