00001
00008 #include "Morpheus_Matrix.h"
00009 #include <cassert>
00010 #include <cmath>
00011 #include <iostream>
00012
00013 namespace Morpheus {
00014
00015 Matrix::Matrix(const int nrows, const int ncols)
00016 {
00017 nrows_ = nrows;
00018 ncols_ = ncols;
00019
00020
00021 assert(nrows_ > 0);
00022 assert(ncols_ > 0);
00023
00024
00025 data_ = new double*[nrows_];
00026 for(int r=0; r<nrows_; r++)
00027 data_[r] = new double[ncols_];
00028 }
00029
00030
00031 Matrix::~Matrix()
00032 {
00033
00034 for(int r=0; r<nrows_; r++)
00035 delete[] data_[r];
00036
00037 delete[] data_;
00038 }
00039
00040
00041 double& Matrix::operator()(const int row, const int col)
00042 {
00043 return data_[row][col];
00044 }
00045
00046
00047 void Matrix::multiply(const Vector& X, Vector& Y) const
00048 {
00049
00050 assert(X.getNumElements() == ncols_);
00051 assert(Y.getNumElements() == nrows_);
00052
00053 for(int r=0; r<nrows_; r++)
00054 {
00055 Y[r] = 0;
00056 for(int c=0; c<ncols_; c++)
00057 {
00058 Y[r] = Y[r] + data_[r][c]*X[c];
00059 }
00060 }
00061 }
00062
00063
00064 void Matrix::multiply(const Matrix& X, Matrix& Y) const
00065 {
00066
00067 assert(nrows_ == Y.nrows_);
00068 assert(ncols_ == X.nrows_);
00069 assert(X.ncols_ == Y.ncols_);
00070
00071 for(int r=0; r<Y.nrows_; r++)
00072 {
00073 for(int c=0; c<Y.ncols_; c++)
00074 {
00075 Y(r,c) = 0;
00076 for(int k=0; k<ncols_; k++)
00077 {
00078 Y(r,c) = Y(r,c) + data_[r][k] * X.data_[k][c];
00079 }
00080 }
00081 }
00082 }
00083
00084
00085 bool Matrix::isSymmetric() const
00086 {
00087 if(nrows_ != ncols_)
00088 return false;
00089
00090 for(int r=0; r<nrows_; r++)
00091 {
00092 for(int c=0; c<ncols_; c++)
00093 {
00094 if(data_[r][c] != data_[c][r])
00095 return false;
00096 }
00097 }
00098
00099 return true;
00100 }
00101
00102
00103 bool Matrix::isUpperTriangular() const
00104 {
00105 if(nrows_ != ncols_)
00106 return false;
00107
00108 for(int r=0; r<nrows_; r++)
00109 {
00110 for(int c=r+1; c<ncols_; c++)
00111 {
00112 if(data_[r][c] != 0)
00113 return false;
00114 }
00115 }
00116
00117 return true;
00118 }
00119
00120
00121
00122 double Matrix::norm1() const
00123 {
00124 double curColSum;
00125 double maxColSum = 0;
00126 for(int c=0; c<ncols_; c++)
00127 {
00128 curColSum = 0;
00129 for(int r=0; r<nrows_; r++)
00130 {
00131 curColSum = curColSum + data_[r][c];
00132 }
00133 if(curColSum > maxColSum)
00134 maxColSum = curColSum;
00135 }
00136 return maxColSum;
00137 }
00138
00139
00140
00141 double Matrix::normInf() const
00142 {
00143 double curRowSum;
00144 double maxRowSum = 0;
00145 for(int r=0; r<nrows_; r++)
00146 {
00147 curRowSum = 0;
00148 for(int c=0; c<ncols_; c++)
00149 {
00150 curRowSum = curRowSum + data_[r][c];
00151 }
00152 if(curRowSum > maxRowSum)
00153 maxRowSum = curRowSum;
00154 }
00155 return maxRowSum;
00156 }
00157
00158
00159 int Matrix::getNumRows() const
00160 {
00161 return nrows_;
00162 }
00163
00164
00165 int Matrix::getNumCols() const
00166 {
00167 return ncols_;
00168 }
00169
00170
00171 int Matrix::getNumEntries() const
00172 {
00173 return (nrows_*ncols_);
00174 }
00175
00176
00177 bool Matrix::approxEqual(const Matrix& m, const double tol) const
00178 {
00179 if(nrows_ != m.nrows_ || ncols_ != m.ncols_)
00180 return false;
00181
00182 for(int r=0; r<nrows_; r++)
00183 {
00184 for(int c=0; c<ncols_; c++)
00185 {
00186 if(std::abs(data_[r][c] - m.data_[r][c]) > tol)
00187 return false;
00188 }
00189 }
00190 return true;
00191 }
00192
00193
00194 void Matrix::print() const
00195 {
00196 std::cout << nrows_ << "x" << ncols_ << " Matrix\n";
00197 for(int r=0; r<nrows_; r++)
00198 {
00199 for(int c=0; c<ncols_; c++)
00200 {
00201 std::cout << data_[r][c] << " ";
00202 }
00203 std::cout << std::endl;
00204 }
00205 }
00206
00207 }