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