Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Tools/Math/LA_Matrix.cpp

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 #include <vector>
00003 #include <iomanip>
00004 #include <sstream>
00005 #include <assert.h>
00006 #include <float.h>
00007 #include <math.h>
00008 #include "LA_Matrix.h"
00009 #include "LA_Lu_decomp.h"
00010 //------------------------------------------------------------------------------
00011 namespace LA
00012 {
00013 //------------------------------------------------------------------------------
00014 Matrix::Matrix() : r(0), c(0), content(NULL)
00015 {
00016 }
00017 //------------------------------------------------------------------------------
00018 Matrix::Matrix(int rows, int columns) : r(0), c(0), content(NULL)
00019 {
00020   create(rows, columns);
00021 }
00022 //------------------------------------------------------------------------------
00023 Matrix::Matrix(int rows, int columns, const double* M)
00024 : r(0), c(0), content(NULL)
00025 {
00026   create(rows, columns, M);
00027 }
00028 //------------------------------------------------------------------------------
00029 Matrix::Matrix(const Matrix& M)
00030 : r(0), c(0), content(NULL)
00031 {
00032   *this = M;
00033 }
00034 //------------------------------------------------------------------------------
00035 Matrix::Matrix(const Matrix3x3<double>& M)
00036 : r(0), c(0), content(NULL)
00037 {
00038   *this = M;
00039 }
00040 //------------------------------------------------------------------------------
00041 Matrix Matrix::identity(int dim)
00042 {
00043   Matrix M(dim, dim);
00044   for (int i = 1; i <= dim; ++i)
00045     M(i, i) = 1.0;
00046   return M;
00047 }
00048 //------------------------------------------------------------------------------
00049 Matrix::~Matrix()
00050 {
00051   destroy();
00052 }
00053 //------------------------------------------------------------------------------
00054 Matrix& Matrix::operator=(const Matrix& M)
00055 {
00056   create(M.r, M.c);
00057   for (int i = 0; i < M.r; ++i)
00058     content[i] = M.content[i];
00059   return *this;
00060 }
00061 //------------------------------------------------------------------------------
00062 Matrix& Matrix::operator=(const Matrix3x3<double>& M)
00063 {
00064   create(3, 3);
00065   for (int i = 0; i < 3; ++i)
00066   {
00067     content[0][i] = M.c[i].x;
00068     content[1][i] = M.c[i].y;
00069     content[2][i] = M.c[i].z;
00070   }
00071   return *this;
00072 }
00073 //------------------------------------------------------------------------------
00074 void Matrix::create(int rows, int columns)
00075 {
00076   destroy();
00077   r = rows;
00078   c = columns;
00079   if (r != 0)
00080   {
00081     content = new Vector[r];
00082     for (int i = 0; i < r; ++i)
00083       content[i] = Vector(c);
00084   }
00085 }
00086 //------------------------------------------------------------------------------
00087 void Matrix::create(int rows, int columns, const double* M)
00088 {
00089   destroy();
00090   r = rows;
00091   c = columns;
00092   if (r != 0)
00093   {
00094     content = new Vector[r];
00095     const double* pos = M;
00096     for (int i = 0; i < r; ++i)
00097     {
00098       content[i] = Vector(c, pos);
00099       pos += c;
00100     }
00101   }
00102 }
00103 //------------------------------------------------------------------------------
00104 const Vector& Matrix::operator[](int row) const
00105 {
00106   assert((row >= 0) && (row < r));
00107   return content[row];
00108 }
00109 //------------------------------------------------------------------------------
00110 Vector& Matrix::operator[](int row)
00111 {
00112   assert((row >= 0) && (row < r));
00113   return content[row];
00114 }
00115 //------------------------------------------------------------------------------
00116 const Vector& Matrix::operator()(int row) const
00117 {
00118   assert((row >= 1) && (row <= r));
00119   return content[row-1];  
00120 }
00121 //------------------------------------------------------------------------------
00122 Vector& Matrix::operator()(int row)
00123 {
00124   assert((row >= 1) && (row <= r));
00125   return content[row-1];  
00126 }
00127 //------------------------------------------------------------------------------
00128 const double& Matrix::operator()(int row, int column) const
00129 {
00130   assert((row >= 1) && (row <= r));
00131   assert((column >= 1) && (column <= c));
00132   return content[row-1].content[column-1];
00133 }
00134 //------------------------------------------------------------------------------
00135 double& Matrix::operator()(int row, int column)
00136 {
00137   assert((row >= 1) && (row <= r));
00138   assert((column >= 1) && (column <= c));
00139   return content[row-1].content[column-1];
00140 }
00141 //------------------------------------------------------------------------------
00142 int Matrix::rows() const
00143 {
00144   return r;
00145 }
00146 //------------------------------------------------------------------------------
00147 int Matrix::columns() const
00148 {
00149   return c;
00150 }
00151 //------------------------------------------------------------------------------
00152 Vector Matrix::get_row(int index) const
00153 {
00154   assert((index >= 1) && (index <= r));
00155   return content[index-1];
00156 }
00157 //------------------------------------------------------------------------------
00158 void Matrix::set_row(int index, const Vector& v)
00159 {
00160   assert((index >= 1) && (index <= r));
00161   assert(v.n == c);
00162   content[index-1] = v;
00163 }
00164 //------------------------------------------------------------------------------
00165 Vector Matrix::get_column(int index) const
00166 {
00167   assert((index >= 1) && (index <= c));
00168   Vector v(c);
00169   index--;
00170   for (int i = 0; i < c; ++i)
00171     v[i] = content[i][index];    
00172   return v;
00173 }
00174 //------------------------------------------------------------------------------
00175 void Matrix::set_column(int index, const Vector& v)
00176 {
00177   assert((index >= 1) && (index <= c));
00178   assert(v.n == r);
00179   index--;
00180   for (int i = 0; i < r; ++i)
00181     content[i].content[index] = v.content[i];
00182 }
00183 //------------------------------------------------------------------------------
00184 Matrix Matrix::get_sub(int rowstart, int rowlength,
00185                        int columnstart, int columnlength) const
00186 {
00187   assert((rowstart >= 1) && ((rowstart+rowlength-1) <= r));
00188   assert((columnstart >= 1) && ((columnstart+columnlength-1) <= c));
00189 
00190   Matrix M(rowlength, columnlength);
00191   for (int i = 0; i < rowlength; ++i)
00192     M.content[i] = content[rowstart + i - 1].sub(columnstart, columnlength);
00193 
00194   return M;
00195 }
00196 //------------------------------------------------------------------------------
00197 void Matrix::set_sub(int rowstart, int columnstart, const Matrix& M)
00198 {
00199   assert((rowstart >= 1) && ((rowstart+M.r-1) <= r));
00200   assert((columnstart >= 1) && ((columnstart+M.c-1) <= c));
00201 
00202   for (int i = 0; i < M.r; ++i)
00203     content[rowstart + i - 1].set_sub(columnstart, M.content[i]);
00204 }
00205 //------------------------------------------------------------------------------
00206 Matrix& Matrix::operator+=(const Matrix& M)
00207 {
00208   assert((r == M.r) && (c == M.c));
00209   for (int i = 0; i < r; ++i)
00210     content[i] += M.content[i];
00211   return *this;
00212 }
00213 //------------------------------------------------------------------------------
00214 Matrix& Matrix::operator-=(const Matrix& M)
00215 {
00216   assert((r == M.r) && (c == M.c));
00217   for (int i = 0; i < r; ++i)
00218     content[i] -= M.content[i];
00219   return *this;
00220 }
00221 //------------------------------------------------------------------------------
00222 Matrix& Matrix::operator*=(const Matrix& M)
00223 {
00224   *this = *this * M;
00225   return *this;
00226 }
00227 //------------------------------------------------------------------------------
00228 Matrix& Matrix::operator*=(const double& s)
00229 {
00230   for (int i = 0; i < r; ++i)
00231     content[i] *= s;
00232   return *this;
00233 }
00234 //------------------------------------------------------------------------------
00235 Matrix& Matrix::operator/=(const Matrix& M)
00236 {
00237   *this *= LA::invert(M);
00238   return *this;
00239 }
00240 //------------------------------------------------------------------------------
00241 Matrix& Matrix::operator/=(const double& s)
00242 {
00243   for (int i = 0; i < r; ++i)
00244     content[i] /= s;
00245   return *this;
00246 }
00247 //------------------------------------------------------------------------------
00248 void Matrix::transpose()
00249 {
00250   Matrix MT(c, r);
00251   for (int i = 0; i < r; ++i)
00252   {
00253     for (int j = 0; j < c; ++j)
00254     {
00255       MT.content[j].content[i] = content[i].content[j];
00256     }
00257   }
00258   *this = MT;
00259 }
00260 //------------------------------------------------------------------------------
00261 Matrix Matrix::transposition() const
00262 {
00263   Matrix M(*this);
00264   M.transpose();
00265   return M;
00266 }
00267 //------------------------------------------------------------------------------
00268 Matrix Matrix::T() const
00269 {
00270   return transposition();
00271 }
00272 //------------------------------------------------------------------------------
00273 void Matrix::invert()
00274 {
00275   assert(r == c);
00276 
00277   LU lu(*this);
00278   *this = lu.inverse();
00279 }
00280 //------------------------------------------------------------------------------
00281 Matrix Matrix::inverse() const
00282 {
00283   return LA::invert(*this);
00284 }
00285 //------------------------------------------------------------------------------
00286 Vector Matrix::solve(const Vector& b)
00287 {
00288   assert(r == c);
00289   assert(b.n == r);
00290 
00291   LU lu(*this);
00292   return lu.solve(b);
00293 }
00294 //------------------------------------------------------------------------------
00295 double Matrix::det() const
00296 {
00297   assert(r == c);
00298 
00299   LU lu(*this);
00300   return lu.det();
00301 }
00302 //------------------------------------------------------------------------------
00303 std::string Matrix::asString() const
00304 {
00305   std::ostringstream os;
00306   os << *this;
00307   return os.str();
00308 }
00309 //------------------------------------------------------------------------------
00310 void Matrix::destroy()
00311 {
00312   if (content != NULL)
00313   {
00314     delete [] content;
00315     content = NULL;
00316   }
00317 }
00318 //------------------------------------------------------------------------------
00319 Matrix operator+(const Matrix& M1, const Matrix& M2)
00320 {
00321   Matrix M(M1);
00322   M += M2;
00323   return M;
00324 }
00325 //------------------------------------------------------------------------------
00326 Matrix operator-(const Matrix& M1, const Matrix& M2)
00327 {
00328   Matrix M(M1);
00329   M -= M2;
00330   return M;
00331 }
00332 //------------------------------------------------------------------------------
00333 Matrix operator*(const Matrix& M1, const Matrix& M2)
00334 {
00335   assert(M1.c == M2.r);
00336   Matrix M(M1.r, M2.c);
00337 
00338   for (int i = 0; i < M1.r; ++i)
00339   {
00340     for (int j = 0; j < M2.c; ++j)
00341     {
00342       for (int k = 0; k < M1.c; ++k)
00343       {
00344         M.content[i].content[j] +=
00345           M1.content[i].content[k]*M2.content[k].content[j];
00346       }
00347     }
00348   }
00349 
00350   return M;
00351 }
00352 //------------------------------------------------------------------------------
00353 Vector operator*(const Matrix& M, const Vector& v)
00354 {
00355   assert(M.c == v.n);
00356   Vector res(M.r);
00357 
00358   for (int i = 0; i < M.r; ++i)
00359   {
00360     for (int j = 0; j < M.c; ++j)
00361     {
00362       res.content[i] += M.content[i].content[j] * v.content[j];
00363     }
00364   }
00365 
00366   return res;
00367 }
00368 //------------------------------------------------------------------------------
00369 Matrix operator*(const Matrix& M, const double& s)
00370 {
00371   Matrix Mres(M);
00372   Mres *= s;
00373   return Mres;
00374 }
00375 //------------------------------------------------------------------------------
00376 Matrix operator*(const double& s, const Matrix& M)
00377 {
00378   Matrix Mres(M);
00379   Mres *= s;
00380   return Mres;
00381 }
00382 //------------------------------------------------------------------------------
00383 Matrix operator/(const Matrix& M, const double& s)
00384 {
00385   Matrix Mres(M);
00386   Mres /= s;
00387   return Mres;
00388 }
00389 //------------------------------------------------------------------------------
00390 Matrix operator/(const Matrix& M1, const Matrix& M2)
00391 {
00392   return M1 * invert(M2);
00393 }
00394 //------------------------------------------------------------------------------
00395 Matrix transpose(const Matrix& M)
00396 {
00397   Matrix MT(M);
00398   MT.transpose();
00399   return MT;
00400 }
00401 //------------------------------------------------------------------------------
00402 Matrix invert(const Matrix& M)
00403 {
00404   Matrix Minv(M);
00405   Minv.invert();
00406   return Minv;
00407 }
00408 //------------------------------------------------------------------------------
00409 Matrix inv(const Matrix& M)
00410 {
00411   Matrix Minv(M);
00412   Minv.invert();
00413   return Minv;
00414 }
00415 //------------------------------------------------------------------------------
00416 double det(const Matrix& M)
00417 {
00418   return M.det();
00419 }
00420 //------------------------------------------------------------------------------
00421 std::ostream& operator<<(std::ostream& out, const Matrix& M)
00422 {
00423   for (int i = 1; i <= M.rows(); ++i)
00424   {
00425     out << "| ";
00426     for (int j = 1; j <= M.columns(); ++j)
00427     {
00428       out << std::setw(10) << std::setfill(' ') << M(i, j) << ' ';      
00429     }
00430     out << "|" << std::endl;
00431   }
00432   return out;  
00433 }
00434 //------------------------------------------------------------------------------
00435 Out& operator<<(Out& stream, const Matrix& M)
00436 {
00437   stream << M.r;
00438   stream << M.c;
00439   for (int i = 0; i < M.r; ++i)
00440     for (int j = 0; j < M.c; ++j)
00441       stream << M.content[i].content[j];
00442   return stream;
00443 }
00444 //------------------------------------------------------------------------------
00445 In& operator>>(In& stream, Matrix& M)
00446 {
00447   int r, c;
00448   stream >> r;
00449   stream >> c;
00450   M.create(r, c);
00451   for (int i = 0; i < r; ++i)
00452     for (int j = 0; j < c; ++j)
00453       stream >> M.content[i].content[j];
00454   return stream;
00455 }
00456 //------------------------------------------------------------------------------
00457 }
00458 //------------------------------------------------------------------------------

Generated on Mon Mar 20 22:00:06 2006 for GT2005 by doxygen 1.3.6