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