00001 #ifndef fl_matrix_h
00002 #define fl_matrix_h
00003
00004
00005 #include "fl/pointer.h"
00006
00007 #include <math.h>
00008 #include <iostream>
00009 #include <sstream>
00010 #include <vector>
00011 #include <map>
00012 #include <complex>
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 namespace fl
00037 {
00038
00039 template<class T> class Matrix;
00040 template<class T> class MatrixTranspose;
00041 template<class T> class MatrixRegion;
00042
00043
00044
00045
00051 template<class T>
00052 class MatrixAbstract
00053 {
00054 public:
00055 virtual ~MatrixAbstract ();
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 virtual T & operator () (const int row, const int column) const = 0;
00071 virtual T & operator [] (const int row) const;
00072 virtual int rows () const;
00073 virtual int columns () const;
00074 virtual MatrixAbstract * duplicate () const = 0;
00075 virtual void clear (const T scalar = (T) 0);
00076 virtual void resize (const int rows, const int columns = 1) = 0;
00077
00078
00079 virtual T frob (T n) const;
00080 virtual T sumSquares () const;
00081 virtual void normalize (const T scalar = 1.0);
00082 virtual T dot (const MatrixAbstract & B) const;
00083 virtual Matrix<T> cross (const MatrixAbstract & B) const;
00084 virtual void identity (const T scalar = 1.0);
00085 virtual MatrixRegion<T> row (const int r) const;
00086 virtual MatrixRegion<T> column (const int c) const;
00087 virtual MatrixRegion<T> region (const int firstRow = 0, const int firstColumn = 0, int lastRow = -1, int lastColumn = -1) const;
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 virtual bool operator == (const MatrixAbstract & B) const;
00119 bool operator != (const MatrixAbstract & B) const
00120 {
00121 return ! ((*this) == B);
00122 }
00123
00124
00125
00126
00127 virtual Matrix<T> operator * (const MatrixAbstract & B) const;
00128
00129 virtual Matrix<T> elementMultiply (const MatrixAbstract & B) const;
00130
00131
00132 virtual Matrix<T> operator + (const MatrixAbstract & B) const;
00133
00134 virtual Matrix<T> operator - (const MatrixAbstract & B) const;
00135
00136
00137 virtual MatrixAbstract & operator *= (const MatrixAbstract & B);
00138 virtual MatrixAbstract & operator *= (const T scalar);
00139
00140 virtual MatrixAbstract & operator /= (const T scalar);
00141 virtual MatrixAbstract & operator += (const MatrixAbstract & B);
00142
00143 virtual MatrixAbstract & operator -= (const MatrixAbstract & B);
00144 virtual MatrixAbstract & operator -= (const T scalar);
00145
00146
00147 virtual void read (std::istream & stream);
00148 virtual void write (std::ostream & stream, bool withName = false) const;
00149
00150
00151 static int displayWidth;
00152 static int displayPrecision;
00153 };
00154
00155
00156
00157
00158 template<class T>
00159 class Matrix : public MatrixAbstract<T>
00160 {
00161 public:
00162 Matrix ();
00163 Matrix (const int rows, const int columns = 1);
00164 Matrix (const MatrixAbstract<T> & that);
00165 template<class T2>
00166 Matrix (const MatrixAbstract<T2> & that)
00167 {
00168 int h = that.rows ();
00169 int w = that.columns ();
00170 resize (h, w);
00171 T * i = (T *) data;
00172 for (int c = 0; c < w; c++)
00173 {
00174 for (int r = 0; r < h; r++)
00175 {
00176 *i++ = (T) that (r, c);
00177 }
00178 }
00179 }
00180 Matrix (std::istream & stream);
00181 Matrix (T * that, const int rows, const int columns = 1);
00182 Matrix (Pointer & that, const int rows = -1, const int columns = 1);
00183 virtual ~Matrix ();
00184 void detach ();
00185
00186 virtual T & operator () (const int row, const int column) const
00187 {
00188 return ((T *) data)[column * rows_ + row];
00189 }
00190 virtual T & operator [] (const int row) const
00191 {
00192 return ((T *) data)[row];
00193 }
00194 virtual int rows () const;
00195 virtual int columns () const;
00196 virtual MatrixAbstract<T> * duplicate () const;
00197 virtual void clear (const T scalar = (T) 0);
00198 virtual void resize (const int rows, const int columns = 1);
00199 virtual void copyFrom (const Matrix<T> & that);
00200
00201 virtual Matrix reshape (const int rows, const int columns = 1) const;
00202
00203 virtual T frob (T n) const;
00204 virtual T sumSquares () const;
00205 virtual T dot (const Matrix & B) const;
00206 virtual Matrix transposeSquare () const;
00207
00208 virtual MatrixTranspose<T> operator ~ () const;
00209 virtual Matrix operator * (const MatrixAbstract<T> & B) const;
00210 virtual Matrix operator * (const Matrix & B) const;
00211 virtual Matrix operator * (const T scalar) const;
00212 virtual Matrix operator / (const T scalar) const;
00213 virtual Matrix operator + (const Matrix & B) const;
00214 virtual Matrix operator - (const Matrix & B) const;
00215
00216 virtual Matrix & operator *= (const Matrix & B);
00217 virtual MatrixAbstract<T> & operator *= (const T scalar);
00218 virtual MatrixAbstract<T> & operator /= (const T scalar);
00219 virtual Matrix & operator += (const Matrix & B);
00220 virtual Matrix & operator -= (const Matrix & B);
00221 virtual MatrixAbstract<T> & operator -= (const T scalar);
00222
00223 virtual void read (std::istream & stream);
00224 virtual void write (std::ostream & stream, bool withName = false) const;
00225
00226
00227 Pointer data;
00228 int rows_;
00229 int columns_;
00230 };
00231
00238 template<class T>
00239 class Vector : public Matrix<T>
00240 {
00241 public:
00242 Vector ();
00243 Vector (const int rows);
00244 Vector (const MatrixAbstract<T> & that);
00245 template<class T2>
00246 Vector (const MatrixAbstract<T2> & that)
00247 {
00248 int h = that.rows ();
00249 int w = that.columns ();
00250 resize (h, w);
00251 T * i = (T *) data;
00252 for (int c = 0; c < w; c++)
00253 {
00254 for (int r = 0; r < h; r++)
00255 {
00256 *i++ = (T) that (r, c);
00257 }
00258 }
00259 }
00260 Vector (const Matrix<T> & that);
00261 Vector (std::istream & stream);
00262 Vector (T * that, const int rows);
00263 Vector (Pointer & that, const int rows = -1);
00264
00265 Vector & operator = (const MatrixAbstract<T> & that);
00266 Vector & operator = (const Matrix<T> & that);
00267
00268 virtual MatrixAbstract<T> * duplicate () const;
00269 virtual void resize (const int rows, const int columns = 1);
00270 };
00271
00281 template<class T>
00282 class MatrixPacked : public MatrixAbstract<T>
00283 {
00284 public:
00285 MatrixPacked ();
00286 MatrixPacked (const int rows);
00287 MatrixPacked (const MatrixAbstract<T> & that);
00288 MatrixPacked (std::istream & stream);
00289
00290 virtual T & operator () (const int row, const int column) const;
00291 virtual T & operator [] (const int row) const;
00292 virtual int rows () const;
00293 virtual int columns () const;
00294 virtual MatrixAbstract<T> * duplicate () const;
00295 virtual void clear (const T scalar = (T) 0);
00296 virtual void resize (const int rows, const int columns = -1);
00297 virtual void copyFrom (const MatrixAbstract<T> & that);
00298 virtual void copyFrom (const MatrixPacked & that);
00299
00300 virtual MatrixPacked operator ~ () const;
00301
00302 virtual void read (std::istream & stream);
00303 virtual void write (std::ostream & stream, bool withName = false) const;
00304
00305
00306 Pointer data;
00307 int rows_;
00308 };
00309
00317 template<class T>
00318 class MatrixSparse : public MatrixAbstract<T>
00319 {
00320 public:
00321 MatrixSparse ();
00322 MatrixSparse (const int rows, const int columns);
00323 MatrixSparse (const MatrixAbstract<T> & that);
00324 MatrixSparse (std::istream & stream);
00325 ~MatrixSparse ();
00326
00327 void set (const int row, const int column, const T value);
00328 virtual T & operator () (const int row, const int column) const;
00329 virtual int rows () const;
00330 virtual int columns () const;
00331 virtual MatrixAbstract<T> * duplicate () const;
00332 virtual void clear (const T scalar = (T) 0);
00333 virtual void resize (const int rows, const int columns = 1);
00334 virtual void copyFrom (const MatrixSparse & that);
00335
00336 virtual T frob (T n) const;
00337
00338 virtual MatrixSparse operator - (const MatrixSparse & B) const;
00339
00340 virtual void read (std::istream & stream);
00341 virtual void write (std::ostream & stream, bool withName = false) const;
00342
00343 int rows_;
00344 fl::SmartPointer< std::vector< std::map<int, T> > > data;
00345 };
00346
00351 template<class T>
00352 class MatrixIdentity : public MatrixAbstract<T>
00353 {
00354 public:
00355 MatrixIdentity ();
00356 MatrixIdentity (int size, T value = 1);
00357
00358 virtual T & operator () (const int row, const int column) const;
00359 virtual int rows () const;
00360 virtual int columns () const;
00361 virtual MatrixAbstract<T> * duplicate () const;
00362 virtual void clear (const T scalar = (T) 0);
00363 virtual void resize (const int rows, const int columns = -1);
00364
00365 int size;
00366 T value;
00367 };
00368
00373 template<class T>
00374 class MatrixDiagonal : public MatrixAbstract<T>
00375 {
00376 public:
00377 MatrixDiagonal ();
00378 MatrixDiagonal (const int rows, const int columns = -1);
00379 MatrixDiagonal (const Vector<T> & that, const int rows = -1, const int columns = -1);
00380
00381 virtual T & operator () (const int row, const int column) const;
00382 virtual T & operator [] (const int row) const;
00383 virtual int rows () const;
00384 virtual int columns () const;
00385 virtual MatrixAbstract<T> * duplicate () const;
00386 virtual void clear (const T scalar = (T) 0);
00387 virtual void resize (const int rows, const int columns = -1);
00388
00389 int rows_;
00390 int columns_;
00391 Pointer data;
00392 };
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00412 template<class T>
00413 class MatrixTranspose : public MatrixAbstract<T>
00414 {
00415 public:
00416 MatrixTranspose (const MatrixAbstract<T> & that);
00417 virtual ~MatrixTranspose ();
00418
00419 virtual T & operator () (const int row, const int column) const
00420 {
00421 return (*wrapped) (column, row);
00422 }
00423 virtual T & operator [] (const int row) const
00424 {
00425 return (*wrapped)[row];
00426 }
00427 virtual int rows () const;
00428 virtual int columns () const;
00429 virtual MatrixAbstract<T> * duplicate () const;
00430 virtual void clear (const T scalar = (T) 0);
00431 virtual void resize (const int rows, const int columns);
00432
00433
00434
00435
00436 MatrixAbstract<T> * wrapped;
00437 };
00438
00439 template<class T>
00440 class MatrixRegion : public MatrixAbstract<T>
00441 {
00442 public:
00443 MatrixRegion (const MatrixRegion & that);
00444 MatrixRegion (const MatrixAbstract<T> & that, const int firstRow = 0, const int firstColumn = 0, int lastRow = -1, int lastColumn = -1);
00445 virtual ~MatrixRegion ();
00446
00447 template<class T2>
00448 MatrixRegion & operator = (const MatrixAbstract<T2> & that)
00449 {
00450 int h = that.rows ();
00451 int w = that.columns ();
00452 resize (h, w);
00453 for (int c = 0; c < w; c++)
00454 {
00455 for (int r = 0; r < h; r++)
00456 {
00457 (*this)(r,c) = (T) that(r,c);
00458 }
00459 }
00460 return *this;
00461 }
00462 MatrixRegion & operator = (const MatrixRegion & that);
00463
00464 virtual T & operator () (const int row, const int column) const
00465 {
00466 return (*wrapped)(row + firstRow, column + firstColumn);
00467 }
00468 virtual T & operator [] (const int row) const
00469 {
00470 return (*wrapped)(row % rows_ + firstRow, row / rows_ + firstColumn);
00471 }
00472 virtual int rows () const;
00473 virtual int columns () const;
00474 virtual MatrixAbstract<T> * duplicate () const;
00475 virtual void clear (const T scalar = (T) 0);
00476 virtual void resize (const int rows, const int columns = 1);
00477
00478 virtual MatrixTranspose<T> operator ~ () const;
00479 virtual Matrix<T> operator * (const MatrixAbstract<T> & B) const;
00480 virtual Matrix<T> operator * (const T scalar) const;
00481
00482 MatrixAbstract<T> * wrapped;
00483 int firstRow;
00484 int firstColumn;
00485 int rows_;
00486 int columns_;
00487 };
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 template<class T>
00498 class Matrix2x2 : public MatrixAbstract<T>
00499 {
00500 public:
00501 Matrix2x2 ();
00502 template<class T2>
00503 Matrix2x2 (const MatrixAbstract<T2> & that)
00504 {
00505
00506
00507 data[0][0] = (T) that(0,0);
00508 data[0][1] = (T) that(1,0);
00509 data[1][0] = (T) that(0,1);
00510 data[1][1] = (T) that(1,1);
00511 }
00512 Matrix2x2 (std::istream & stream);
00513
00514 virtual T & operator () (const int row, const int column) const
00515 {
00516 return (T &) data[column][row];
00517 }
00518 virtual T & operator [] (const int row) const
00519 {
00520 return ((T *) data)[row];
00521 }
00522 virtual int rows () const;
00523 virtual int columns () const;
00524 virtual MatrixAbstract<T> * duplicate () const;
00525 virtual void resize (const int rows = 2, const int columns = 2);
00526
00527
00528
00529 virtual Matrix2x2<T> operator ! () const;
00530 virtual Matrix2x2<T> operator ~ () const;
00531 virtual Matrix<T> operator * (const MatrixAbstract<T> & B) const;
00532 virtual Matrix2x2<T> operator * (const Matrix2x2<T> & B) const;
00533 virtual Matrix2x2<T> operator * (const T scalar) const;
00534 virtual Matrix2x2<T> operator / (const T scalar) const;
00535 virtual Matrix2x2<T> & operator *= (const Matrix2x2<T> & B);
00536 virtual MatrixAbstract<T> & operator *= (const T scalar);
00537
00538 virtual void read (std::istream & stream);
00539 virtual void write (std::ostream & stream, bool withName = false) const;
00540
00541
00542 T data[2][2];
00543 };
00544
00545 template<class T>
00546 class Matrix3x3 : public MatrixAbstract<T>
00547 {
00548 public:
00549 Matrix3x3 ();
00550 template<class T2>
00551 Matrix3x3 (const MatrixAbstract<T2> & that)
00552 {
00553 data[0][0] = (T) that(0,0);
00554 data[0][1] = (T) that(1,0);
00555 data[0][2] = (T) that(2,0);
00556 data[1][0] = (T) that(0,1);
00557 data[1][1] = (T) that(1,1);
00558 data[1][2] = (T) that(2,1);
00559 data[2][0] = (T) that(0,2);
00560 data[2][1] = (T) that(1,2);
00561 data[2][2] = (T) that(2,2);
00562 }
00563 Matrix3x3 (std::istream & stream);
00564
00565 virtual T & operator () (const int row, const int column) const
00566 {
00567 return (T &) data[column][row];
00568 }
00569 virtual T & operator [] (const int row) const
00570 {
00571 return ((T *) data)[row];
00572 }
00573 virtual int rows () const;
00574 virtual int columns () const;
00575 virtual MatrixAbstract<T> * duplicate () const;
00576 virtual void resize (const int rows = 3, const int columns = 3);
00577
00578 virtual Matrix<T> operator * (const MatrixAbstract<T> & B) const;
00579
00580 virtual void read (std::istream & stream);
00581 virtual void write (std::ostream & stream, bool withName = false) const;
00582
00583
00584 T data[3][3];
00585 };
00586
00587
00588
00589
00591 template<class T>
00592 inline std::ostream &
00593 operator << (std::ostream & stream, const MatrixAbstract<T> & A)
00594 {
00595 for (int r = 0; r < A.rows (); r++)
00596 {
00597 if (r > 0)
00598 {
00599 if (A.columns () > 1)
00600 {
00601 stream << std::endl;
00602 }
00603 else
00604 {
00605 stream << " ";
00606 }
00607 }
00608 std::string line;
00609 for (int c = 0; c < A.columns (); c++)
00610 {
00611
00612
00613
00614 std::ostringstream formatted;
00615 formatted.precision (A.displayPrecision);
00616 formatted << A (r, c);
00617 if (c > 0)
00618 {
00619 line += ' ';
00620 }
00621 while (line.size () < c * A.displayWidth)
00622 {
00623 line += ' ';
00624 }
00625 line += formatted.str ();
00626 }
00627 stream << line;
00628 }
00629 return stream;
00630 }
00631
00632
00639 template<class T>
00640 inline std::istream &
00641 operator >> (std::istream & stream, MatrixAbstract<T> & A)
00642 {
00643 int rows;
00644 int columns;
00645 stream >> rows >> columns;
00646 A.resize (rows, columns);
00647
00648 for (int r = 0; r < rows; r++)
00649 {
00650 for (int c = 0; c < columns; c++)
00651 {
00652 stream >> A(r, c);
00653 }
00654 }
00655 return stream;
00656 }
00657
00662 template<class T>
00663 inline MatrixAbstract<T> &
00664 operator << (MatrixAbstract<T> & A, const std::string & source)
00665 {
00666 std::istringstream stream (source);
00667 int rows = A.rows ();
00668 int columns = A.columns ();
00669 for (int r = 0; r < rows; r++)
00670 {
00671 for (int c = 0; c < columns; c++)
00672 {
00673 stream >> A(r,c);
00674 }
00675 }
00676 return A;
00677 }
00678
00679 template<class T>
00680 inline void
00681 geev (const Matrix2x2<T> & A, Matrix<T> & eigenvalues)
00682 {
00683
00684 T b = A.data[0][0] + A.data[1][1];
00685 T c = A.data[0][0] * A.data[1][1] - A.data[0][1] * A.data[1][0];
00686 T b4c = b * b - 4 * c;
00687 if (b4c < 0)
00688 {
00689 throw "eigen: no real eigenvalues!";
00690 }
00691 if (b4c > 0)
00692 {
00693 b4c = sqrt (b4c);
00694 }
00695 eigenvalues.resize (2, 1);
00696 eigenvalues (0, 0) = (b - b4c) / 2.0;
00697 eigenvalues (1, 0) = (b + b4c) / 2.0;
00698 }
00699
00700 inline void
00701 geev (const Matrix2x2<double> & A, Matrix<std::complex<double> > & eigenvalues)
00702 {
00703 eigenvalues.resize (2, 1);
00704
00705
00706 double b = -(A.data[0][0] + A.data[1][1]);
00707 double c = A.data[0][0] * A.data[1][1] - A.data[0][1] * A.data[1][0];
00708 double b4c = b * b - 4 * c;
00709 bool imaginary = b4c < 0;
00710 if (b4c != 0)
00711 {
00712 b4c = sqrt (fabs (b4c));
00713 }
00714 if (imaginary)
00715 {
00716 b /= -2.0;
00717 b4c /= 2.0;
00718 eigenvalues(0,0) = std::complex<double> (b, b4c);
00719 eigenvalues(1,0) = std::complex<double> (b, -b4c);
00720 }
00721 else
00722 {
00723 eigenvalues(0,0) = (-b - b4c) / 2.0;
00724 eigenvalues(1,0) = (-b + b4c) / 2.0;
00725 }
00726 }
00727 }
00728
00729
00730 #endif