00001 /* 00002 File: Mat.h 00003 00004 Function: Defines a generic resizeable matrix. 00005 00006 Author(s): Andrew Willmott 00007 00008 Copyright: (c) 1995-2000, Andrew Willmott 00009 */ 00010 00011 #ifndef __Mat__ 00012 #define __Mat__ 00013 00014 #include "vl/VL.h" 00015 // Defines the actual type for TMat etc. 00016 00017 #include "vl/Vec.h" 00018 #include "vl/Mat2.h" 00019 #include "vl/Mat3.h" 00020 #include "vl/Mat4.h" 00021 #ifndef __SVL__ 00022 #include "vl/SubMat.h" 00023 #endif 00024 00025 #include <iostream.h> 00026 00027 00028 // --- Mat Class -------------------------------------------------------------- 00029 00030 00031 class TMat 00032 { 00033 public: 00034 00035 // Constructors 00036 00037 inline TMat(); // Null matrix: no space allocated 00038 inline TMat(Int rows, Int cols); // Ordinary uninitialised matrix 00039 TMat(Int rows, Int cols, Double elt0 ...);// Mat(2, 2, 1.0, 2.0, 3.0, 4.0) 00040 inline TMat(Int nrows, Int ncols, TMReal *ndata);// Create reference matrix 00041 TMat(const TMat &m); // Copy constructor 00042 #ifndef __SVL__ 00043 TMat(const TSubMat &m); // Conversion constructors... 00044 #endif 00045 TMat(const TMat2 &m); 00046 TMat(const TMat3 &m); 00047 TMat(const TMat4 &m); 00048 TMat(Int rows, Int cols, ZeroOrOne k); // I * k 00049 TMat(Int rows, Int cols, Block k); // block matrix (m[i][j] = k) 00050 00051 inline ~TMat(); 00052 00053 // Accessor methods 00054 00055 inline Int Rows() const { return(rows & VL_REF_MASK); }; 00056 inline Int Cols() const { return(cols); }; 00057 00058 inline TMVec operator [] (Int i); // Indexing by row 00059 inline TMVec operator [] (Int i) const; // Indexing by row 00060 00061 inline TMReal &Elt(Int i, Int j); // Indexing by Elt; no checking 00062 inline TMReal Elt(Int i, Int j) const; 00063 00064 inline TMReal *Ref() const; // Return pointer to data 00065 00066 // Assignment operators 00067 00068 TMat &operator = (const TMat &m); // Assignment of a matrix 00069 #ifndef __SVL__ 00070 TMat &operator = (const TSubMat &m);// Assignment of submatrix 00071 #endif 00072 inline TMat &operator = (ZeroOrOne k); // Set to k * I... 00073 inline TMat &operator = (Block k); // Set to a block matrix... 00074 TMat &operator = (const TMat2 &m); 00075 TMat &operator = (const TMat3 &m); 00076 TMat &operator = (const TMat4 &m); 00077 00078 Void SetSize(Int nrows, Int ncols); 00079 Void SetSize(const TMat &m); 00080 Bool IsSquare() const { return((rows & VL_REF_MASK) == cols); }; 00081 00082 // Matrix initialisers 00083 00084 Void MakeZero(); 00085 Void MakeDiag(TMReal k); 00086 Void MakeDiag(); 00087 Void MakeBlock(TMReal k); 00088 Void MakeBlock(); 00089 00090 TMat &Clamp(Real fuzz); 00091 TMat &Clamp(); 00092 00093 protected: 00094 // Private... 00095 TMReal *data; 00096 UInt rows; 00097 UInt cols; 00098 00099 Bool IsRef() { return(rows & VL_REF_FLAG); }; 00100 }; 00101 00102 00103 // --- Mat In-Place Operators ------------------------------------------------- 00104 00105 TMat &operator += (TMat &m, const TMat &n); 00106 TMat &operator -= (TMat &m, const TMat &n); 00107 TMat &operator *= (TMat &m, const TMat &n); 00108 TMat &operator *= (TMat &m, TMReal s); 00109 TMat &operator /= (TMat &m, TMReal s); 00110 00111 // --- Mat Comparison Operators ----------------------------------------------- 00112 00113 Bool operator == (const TMat &m, const TMat &n); 00114 Bool operator != (const TMat &m, const TMat &n); 00115 00116 // --- Mat Arithmetic Operators ----------------------------------------------- 00117 00118 TMat operator + (const TMat &m, const TMat &n); 00119 TMat operator - (const TMat &m, const TMat &n); 00120 TMat operator - (const TMat &m); 00121 TMat operator * (const TMat &m, const TMat &n); 00122 TMat operator * (const TMat &m, TMReal s); 00123 inline TMat operator * (TMReal s, const TMat &m); 00124 TMat operator / (const TMat &m, TMReal s); 00125 00126 TMVec operator * (const TMat &m, const TMVec &v); 00127 TMVec operator * (const TMVec &v, const TMat &m); 00128 TMVec &operator *= (TMVec &v, const TMat &m); 00129 00130 TMat trans(const TMat &m); // Transpose 00131 TMReal trace(const TMat &m); // Trace 00132 TMat inv(const TMat &m, TMReal *determinant = 0, TMReal pEps = 1e-20); 00133 // Inverse 00134 TMat oprod(const TMVec &a, const TMVec &b); // Outer product 00135 00136 TMat clamped(const TMat &m, Real fuzz); 00137 TMat clamped(const TMat &m); 00138 00139 // --- Mat Input & Output ----------------------------------------------------- 00140 00141 ostream &operator << (ostream &s, const TMat &m); 00142 istream &operator >> (istream &s, TMat &m); 00143 00144 00145 // --- Mat Inlines ------------------------------------------------------------ 00146 00147 00148 inline TMat::TMat() : data(0), rows(0), cols(0) 00149 { 00150 } 00151 00152 inline TMat::TMat(Int rows, Int cols) : rows(rows), cols(cols) 00153 { 00154 Assert(rows > 0 && cols > 0, "(Mat) illegal matrix size"); 00155 00156 data = new TMReal[rows * cols]; 00157 Assert(data != 0, "(Mat) Out of memory"); 00158 } 00159 00160 inline TMat::TMat(Int nrows, Int ncols, TMReal *ndata) : 00161 data(ndata), rows(nrows | VL_REF_FLAG), cols(ncols) 00162 { 00163 } 00164 00165 inline TMVec TMat::operator [] (Int i) 00166 { 00167 CheckRange(i, 0, Rows(), "(Mat::[i]) i index out of range"); 00168 00169 return(TMVec(cols, data + i * cols)); 00170 } 00171 00172 inline TMVec TMat::operator [] (Int i) const 00173 { 00174 CheckRange(i, 0, Rows(), "(Mat::[i]) i index out of range"); 00175 00176 return(TMVec(cols, data + i * cols)); 00177 } 00178 00179 inline TMReal &TMat::Elt(Int i, Int j) 00180 { 00181 CheckRange(i, 0, Rows(), "(Mat::e(i,j)) i index out of range"); 00182 CheckRange(j, 0, Cols(), "(Mat::e(i,j)) j index out of range"); 00183 00184 return(data[i * cols + j]); 00185 } 00186 00187 inline TMReal TMat::Elt(Int i, Int j) const 00188 { 00189 CheckRange(i, 0, Rows(), "(Mat::e(i,j)) i index out of range"); 00190 CheckRange(j, 0, Cols(), "(Mat::e(i,j)) j index out of range"); 00191 00192 return(data[i * cols + j]); 00193 } 00194 00195 inline TMReal *TMat::Ref() const 00196 { 00197 return(data); 00198 } 00199 00200 inline TMat operator * (TMReal s, const TMat &m) 00201 { 00202 return(m * s); 00203 } 00204 00205 inline TMat &TMat::operator = (ZeroOrOne k) 00206 { 00207 MakeDiag(k); 00208 00209 return(SELF); 00210 } 00211 00212 inline TMat &TMat::operator = (Block k) 00213 { 00214 MakeBlock((ZeroOrOne) k); 00215 00216 return(SELF); 00217 } 00218 00219 inline TMat::~TMat() 00220 { 00221 if (!IsRef()) 00222 delete[] data; 00223 } 00224 00225 #endif