00001 #ifndef SimTK_SIMMATRIX_SMALLMATRIX_MAT_H_
00002 #define SimTK_SIMMATRIX_SMALLMATRIX_MAT_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00039 #include "SimTKcommon/internal/common.h"
00040
00041 namespace SimTK {
00042
00045 template <int M, int N, class ELT, int CS, int RS> class Mat {
00046 typedef ELT E;
00047 typedef typename CNT<E>::TNeg ENeg;
00048 typedef typename CNT<E>::TWithoutNegator EWithoutNegator;
00049 typedef typename CNT<E>::TReal EReal;
00050 typedef typename CNT<E>::TImag EImag;
00051 typedef typename CNT<E>::TComplex EComplex;
00052 typedef typename CNT<E>::THerm EHerm;
00053 typedef typename CNT<E>::TPosTrans EPosTrans;
00054
00055 typedef typename CNT<E>::TAbs EAbs;
00056 typedef typename CNT<E>::TStandard EStandard;
00057 typedef typename CNT<E>::TInvert EInvert;
00058 typedef typename CNT<E>::TNormalize ENormalize;
00059 typedef typename CNT<E>::TSqHermT ESqHermT;
00060 typedef typename CNT<E>::TSqTHerm ESqTHerm;
00061
00062 typedef typename CNT<E>::Scalar EScalar;
00063 typedef typename CNT<E>::Number ENumber;
00064 typedef typename CNT<E>::StdNumber EStdNumber;
00065 typedef typename CNT<E>::Precision EPrecision;
00066 typedef typename CNT<E>::ScalarSq EScalarSq;
00067
00068 public:
00069
00070 enum {
00071 NRows = M,
00072 NCols = N,
00073 MinDim = N < M ? N : M,
00074 MaxDim = N > M ? N : M,
00075 RowSpacing = RS,
00076 ColSpacing = CS,
00077 NPackedElements = M * N,
00078 NActualElements = (N-1)*CS + (M-1)*RS + 1,
00079 NActualScalars = CNT<E>::NActualScalars * NActualElements,
00080 ImagOffset = NTraits<ENumber>::ImagOffset,
00081 RealStrideFactor = 1,
00082
00083 ArgDepth = ((int)CNT<E>::ArgDepth < (int)MAX_RESOLVED_DEPTH
00084 ? CNT<E>::ArgDepth + 1
00085 : MAX_RESOLVED_DEPTH),
00086 IsScalar = 0,
00087 IsNumber = 0,
00088 IsStdNumber = 0,
00089 IsPrecision = 0,
00090 SignInterpretation = CNT<E>::SignInterpretation
00091 };
00092
00093 typedef Mat<M,N,E,CS,RS> T;
00094 typedef Mat<M,N,ENeg,CS,RS> TNeg;
00095 typedef Mat<M,N,EWithoutNegator,CS,RS> TWithoutNegator;
00096
00097 typedef Mat<M,N,EReal,CS*CNT<E>::RealStrideFactor,RS*CNT<E>::RealStrideFactor>
00098 TReal;
00099 typedef Mat<M,N,EImag,CS*CNT<E>::RealStrideFactor,RS*CNT<E>::RealStrideFactor>
00100 TImag;
00101 typedef Mat<M,N,EComplex,CS,RS> TComplex;
00102 typedef Mat<N,M,EHerm,RS,CS> THerm;
00103 typedef Mat<N,M,E,RS,CS> TPosTrans;
00104 typedef E TElement;
00105 typedef Row<N,E,CS> TRow;
00106 typedef Vec<M,E,RS> TCol;
00107 typedef Vec<MinDim,E,RS+CS> TDiag;
00108
00109
00110
00111 typedef Mat<M,N,EAbs,M,1> TAbs;
00112 typedef Mat<M,N,EStandard,M,1> TStandard;
00113 typedef Mat<N,M,EInvert,N,1> TInvert;
00114 typedef Mat<M,N,ENormalize,M,1> TNormalize;
00115 typedef SymMat<N,ESqHermT> TSqHermT;
00116 typedef SymMat<M,ESqTHerm> TSqTHerm;
00117
00118 typedef EScalar Scalar;
00119 typedef ENumber Number;
00120 typedef EStdNumber StdNumber;
00121 typedef EPrecision Precision;
00122 typedef EScalarSq ScalarSq;
00123
00124 typedef THerm TransposeType;
00125
00126 int size() const { return M*N; }
00127 int nrow() const { return M; }
00128 int ncol() const { return N; }
00129
00130
00131 ScalarSq scalarNormSqr() const {
00132 ScalarSq sum(0);
00133 for(int j=0;j<N;++j) sum += CNT<TCol>::scalarNormSqr((*this)(j));
00134 return sum;
00135 }
00136
00137
00138
00139
00140 TAbs abs() const {
00141 TAbs mabs;
00142 for(int j=0;j<N;++j) mabs(j) = (*this)(j).abs();
00143 return mabs;
00144 }
00145
00146 TStandard standardize() const {
00147 TStandard mstd;
00148 for(int j=0;j<N;++j) mstd(j) = (*this)(j).standardize();
00149 return mstd;
00150 }
00151
00152
00153
00154
00155
00156 template <class P> struct EltResult {
00157 typedef Mat<M,N, typename CNT<E>::template Result<P>::Mul, M, 1> Mul;
00158 typedef Mat<M,N, typename CNT<E>::template Result<P>::Dvd, M, 1> Dvd;
00159 typedef Mat<M,N, typename CNT<E>::template Result<P>::Add, M, 1> Add;
00160 typedef Mat<M,N, typename CNT<E>::template Result<P>::Sub, M, 1> Sub;
00161 };
00162
00163
00164
00165 template <class P> struct Result {
00166 typedef MulCNTs<M,N,ArgDepth,Mat,ColSpacing,RowSpacing,
00167 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00168 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> MulOp;
00169 typedef typename MulOp::Type Mul;
00170
00171 typedef MulCNTsNonConforming<M,N,ArgDepth,Mat,ColSpacing,RowSpacing,
00172 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00173 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> MulOpNonConforming;
00174 typedef typename MulOpNonConforming::Type MulNon;
00175
00176 typedef DvdCNTs<M,N,ArgDepth,Mat,ColSpacing,RowSpacing,
00177 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00178 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> DvdOp;
00179 typedef typename DvdOp::Type Dvd;
00180
00181 typedef AddCNTs<M,N,ArgDepth,Mat,ColSpacing,RowSpacing,
00182 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00183 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> AddOp;
00184 typedef typename AddOp::Type Add;
00185
00186 typedef SubCNTs<M,N,ArgDepth,Mat,ColSpacing,RowSpacing,
00187 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00188 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> SubOp;
00189 typedef typename SubOp::Type Sub;
00190 };
00191
00192
00193 template <class P> struct Substitute {
00194 typedef Mat<M,N,P> Type;
00195 };
00196
00197
00198
00199 Mat(){
00200 #ifndef NDEBUG
00201 setToNaN();
00202 #endif
00203 }
00204
00205
00206
00207
00208 Mat(const Mat& src) {
00209 for (int j=0; j<N; ++j)
00210 (*this)(j) = src(j);
00211 }
00212 Mat& operator=(const Mat& src) {
00213 for (int j=0; j<N; ++j)
00214 (*this)(j) = src(j);
00215 return *this;
00216 }
00217
00218 explicit Mat(const SymMat<M, ELT>& src) {
00219 for (int i = 0; i < M; ++i)
00220 for (int j = 0; j <= i; ++j) {
00221 (*this)(i, j) = src(i, j);
00222 (*this)(j, i) = src(i, j);
00223 }
00224 }
00225
00226
00227
00228 template <int CSS, int RSS> Mat(const Mat<M,N,E,CSS,RSS>& src) {
00229 for (int j=0; j<N; ++j)
00230 (*this)(j) = src(j);
00231 }
00232
00233
00234
00235 template <int CSS, int RSS> Mat(const Mat<M,N,ENeg,CSS,RSS>& src) {
00236 for (int j=0; j<N; ++j)
00237 (*this)(j) = src(j);
00238 }
00239
00240
00241
00242 template <class EE, int CSS, int RSS> explicit Mat(const Mat<M,N,EE,CSS,RSS>& mm)
00243 { for (int j=0;j<N;++j) (*this)(j) = mm(j);}
00244
00245
00246
00247 explicit Mat(const E& e)
00248 { for (int j=0;j<N;++j) (*this)(j) = E(0); diag()=e; }
00249
00250
00251 Mat(const E& e0,const E& e1)
00252 {assert(M*N==2);d[rIx(0)]=e0;d[rIx(1)]=e1;}
00253 Mat(const E& e0,const E& e1,const E& e2)
00254 {assert(M*N==3);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;}
00255 Mat(const E& e0,const E& e1,const E& e2,const E& e3)
00256 {assert(M*N==4);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;}
00257 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4)
00258 {assert(M*N==5);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;}
00259 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00260 const E& e5)
00261 {assert(M*N==6);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00262 d[rIx(5)]=e5;}
00263 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00264 const E& e5,const E& e6)
00265 {assert(M*N==7);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00266 d[rIx(5)]=e5;d[rIx(6)]=e6;}
00267 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00268 const E& e5,const E& e6,const E& e7)
00269 {assert(M*N==8);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00270 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;}
00271 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00272 const E& e5,const E& e6,const E& e7,const E& e8)
00273 {assert(M*N==9);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00274 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;}
00275 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00276 const E& e5,const E& e6,const E& e7,const E& e8,const E& e9)
00277 {assert(M*N==10);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00278 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;}
00279 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00280 const E& e5,const E& e6,const E& e7,const E& e8,const E& e9,
00281 const E& e10)
00282 {assert(M*N==11);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00283 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;}
00284 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00285 const E& e5,const E& e6,const E& e7,const E& e8,const E& e9,
00286 const E& e10, const E& e11)
00287 {assert(M*N==12);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00288 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;
00289 d[rIx(11)]=e11;}
00290 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00291 const E& e5,const E& e6,const E& e7,const E& e8,const E& e9,
00292 const E& e10, const E& e11, const E& e12)
00293 {assert(M*N==13);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00294 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;
00295 d[rIx(11)]=e11;d[rIx(12)]=e12;}
00296 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00297 const E& e5,const E& e6,const E& e7,const E& e8,const E& e9,
00298 const E& e10, const E& e11, const E& e12, const E& e13)
00299 {assert(M*N==14);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00300 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;
00301 d[rIx(11)]=e11;d[rIx(12)]=e12;d[rIx(13)]=e13;}
00302 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00303 const E& e5,const E& e6,const E& e7,const E& e8,const E& e9,
00304 const E& e10, const E& e11, const E& e12, const E& e13, const E& e14)
00305 {assert(M*N==15);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00306 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;
00307 d[rIx(11)]=e11;d[rIx(12)]=e12;d[rIx(13)]=e13;d[rIx(14)]=e14;}
00308 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00309 const E& e5,const E& e6,const E& e7,const E& e8,const E& e9,
00310 const E& e10, const E& e11, const E& e12, const E& e13, const E& e14,
00311 const E& e15)
00312 {assert(M*N==16);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00313 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;
00314 d[rIx(11)]=e11;d[rIx(12)]=e12;d[rIx(13)]=e13;d[rIx(14)]=e14;d[rIx(15)]=e15;}
00315
00316
00317 explicit Mat(const TRow& r0)
00318 { assert(M==1); (*this)[0]=r0; }
00319 Mat(const TRow& r0,const TRow& r1)
00320 { assert(M==2);(*this)[0]=r0;(*this)[1]=r1; }
00321 Mat(const TRow& r0,const TRow& r1,const TRow& r2)
00322 { assert(M==3);(*this)[0]=r0;(*this)[1]=r1;(*this)[2]=r2; }
00323 Mat(const TRow& r0,const TRow& r1,const TRow& r2,
00324 const TRow& r3)
00325 { assert(M==4);(*this)[0]=r0;(*this)[1]=r1;(*this)[2]=r2;(*this)[3]=r3; }
00326 Mat(const TRow& r0,const TRow& r1,const TRow& r2,
00327 const TRow& r3,const TRow& r4)
00328 { assert(M==5);(*this)[0]=r0;(*this)[1]=r1;(*this)[2]=r2;
00329 (*this)[3]=r3;(*this)[4]=r4; }
00330 Mat(const TRow& r0,const TRow& r1,const TRow& r2,
00331 const TRow& r3,const TRow& r4,const TRow& r5)
00332 { assert(M==6);(*this)[0]=r0;(*this)[1]=r1;(*this)[2]=r2;
00333 (*this)[3]=r3;(*this)[4]=r4;(*this)[5]=r5; }
00334
00335
00336 template <class EE, int SS> explicit Mat(const Row<N,EE,SS>& r0)
00337 { assert(M==1); (*this)[0]=r0; }
00338 template <class EE, int SS> Mat(const Row<N,EE,SS>& r0,const Row<N,EE,SS>& r1)
00339 { assert(M==2);(*this)[0]=r0;(*this)[1]=r1; }
00340 template <class EE, int SS>
00341 Mat(const Row<N,EE,SS>& r0,const Row<N,EE,SS>& r1,const Row<N,EE,SS>& r2)
00342 { assert(M==3);(*this)[0]=r0;(*this)[1]=r1;(*this)[2]=r2; }
00343 template <class EE, int SS>
00344 Mat(const Row<N,EE,SS>& r0,const Row<N,EE,SS>& r1,const Row<N,EE,SS>& r2,
00345 const Row<N,EE,SS>& r3)
00346 { assert(M==4);(*this)[0]=r0;(*this)[1]=r1;(*this)[2]=r2;(*this)[3]=r3; }
00347 template <class EE, int SS>
00348 Mat(const Row<N,EE,SS>& r0,const Row<N,EE,SS>& r1,const Row<N,EE,SS>& r2,
00349 const Row<N,EE,SS>& r3,const Row<N,EE,SS>& r4)
00350 { assert(M==5);(*this)[0]=r0;(*this)[1]=r1;(*this)[2]=r2;
00351 (*this)[3]=r3;(*this)[4]=r4; }
00352 template <class EE, int SS>
00353 Mat(const Row<N,EE,SS>& r0,const Row<N,EE,SS>& r1,const Row<N,EE,SS>& r2,
00354 const Row<N,EE,SS>& r3,const Row<N,EE,SS>& r4,const Row<N,EE,SS>& r5)
00355 { assert(M==6);(*this)[0]=r0;(*this)[1]=r1;(*this)[2]=r2;
00356 (*this)[3]=r3;(*this)[4]=r4;(*this)[5]=r5; }
00357
00358
00359
00360 explicit Mat(const TCol& r0)
00361 { assert(N==1); (*this)(0)=r0; }
00362 Mat(const TCol& r0,const TCol& r1)
00363 { assert(N==2);(*this)(0)=r0;(*this)(1)=r1; }
00364 Mat(const TCol& r0,const TCol& r1,const TCol& r2)
00365 { assert(N==3);(*this)(0)=r0;(*this)(1)=r1;(*this)(2)=r2; }
00366 Mat(const TCol& r0,const TCol& r1,const TCol& r2,
00367 const TCol& r3)
00368 { assert(N==4);(*this)(0)=r0;(*this)(1)=r1;(*this)(2)=r2;(*this)(3)=r3; }
00369 Mat(const TCol& r0,const TCol& r1,const TCol& r2,
00370 const TCol& r3,const TCol& r4)
00371 { assert(N==5);(*this)(0)=r0;(*this)(1)=r1;(*this)(2)=r2;
00372 (*this)(3)=r3;(*this)(4)=r4; }
00373 Mat(const TCol& r0,const TCol& r1,const TCol& r2,
00374 const TCol& r3,const TCol& r4,const TCol& r5)
00375 { assert(N==6);(*this)(0)=r0;(*this)(1)=r1;(*this)(2)=r2;
00376 (*this)(3)=r3;(*this)(4)=r4;(*this)(5)=r5; }
00377
00378
00379 template <class EE, int SS> explicit Mat(const Vec<M,EE,SS>& r0)
00380 { assert(N==1); (*this)(0)=r0; }
00381 template <class EE, int SS> Mat(const Vec<M,EE,SS>& r0,const Vec<M,EE,SS>& r1)
00382 { assert(N==2);(*this)(0)=r0;(*this)(1)=r1; }
00383 template <class EE, int SS>
00384 Mat(const Vec<M,EE,SS>& r0,const Vec<M,EE,SS>& r1,const Vec<M,EE,SS>& r2)
00385 { assert(N==3);(*this)(0)=r0;(*this)(1)=r1;(*this)(2)=r2; }
00386 template <class EE, int SS>
00387 Mat(const Vec<M,EE,SS>& r0,const Vec<M,EE,SS>& r1,const Vec<M,EE,SS>& r2,
00388 const Vec<M,EE,SS>& r3)
00389 { assert(N==4);(*this)(0)=r0;(*this)(1)=r1;(*this)(2)=r2;(*this)(3)=r3; }
00390 template <class EE, int SS>
00391 Mat(const Vec<M,EE,SS>& r0,const Vec<M,EE,SS>& r1,const Vec<M,EE,SS>& r2,
00392 const Vec<M,EE,SS>& r3,const Vec<M,EE,SS>& r4)
00393 { assert(N==5);(*this)(0)=r0;(*this)(1)=r1;(*this)(2)=r2;
00394 (*this)(3)=r3;(*this)(4)=r4; }
00395 template <class EE, int SS>
00396 Mat(const Vec<M,EE,SS>& r0,const Vec<M,EE,SS>& r1,const Vec<M,EE,SS>& r2,
00397 const Vec<M,EE,SS>& r3,const Vec<M,EE,SS>& r4,const Vec<M,EE,SS>& r5)
00398 { assert(N==6);(*this)(0)=r0;(*this)(1)=r1;(*this)(2)=r2;
00399 (*this)(3)=r3;(*this)(4)=r4;(*this)(5)=r5; }
00400
00401
00402
00403 template <class EE> explicit Mat(const EE* p)
00404 { assert(p); for(int i=0;i<M;++i) (*this)[i]=&p[i*N]; }
00405
00406
00407
00408
00409 template <class EE, int CSS, int RSS> Mat& operator=(const Mat<M,N,EE,CSS,RSS>& mm) {
00410 for (int j=0; j<N; ++j) (*this)(j) = mm(j);
00411 return *this;
00412 }
00413
00414 template <class EE> Mat& operator=(const EE* p) {
00415 assert(p); for(int i=0;i<M;++i) (*this)[i]=&p[i*N];
00416 return *this;
00417 }
00418
00419
00420 template <class EE, int CSS, int RSS> Mat&
00421 operator+=(const Mat<M,N,EE,CSS,RSS>& mm) {
00422 for (int j=0; j<N; ++j) (*this)(j) += mm(j);
00423 return *this;
00424 }
00425 template <class EE, int CSS, int RSS> Mat&
00426 operator+=(const Mat<M,N,negator<EE>,CSS,RSS>& mm) {
00427 for (int j=0; j<N; ++j) (*this)(j) -= -(mm(j));
00428 return *this;
00429 }
00430
00431 template <class EE, int CSS, int RSS> Mat&
00432 operator-=(const Mat<M,N,EE,CSS,RSS>& mm) {
00433 for (int j=0; j<N; ++j) (*this)(j) -= mm(j);
00434 return *this;
00435 }
00436 template <class EE, int CSS, int RSS> Mat&
00437 operator-=(const Mat<M,N,negator<EE>,CSS,RSS>& mm) {
00438 for (int j=0; j<N; ++j) (*this)(j) += -(mm(j));
00439 return *this;
00440 }
00441
00442
00443
00444 template <class EE, int CSS, int RSS> Mat&
00445 operator*=(const Mat<N,N,EE,CSS,RSS>& mm) {
00446 const Mat t(*this);
00447 for (int j=0; j<N; ++j)
00448 for (int i=0; i<M; ++i)
00449 (*this)(i,j) = t[i] * mm(j);
00450 return *this;
00451 }
00452
00453
00454
00455
00456
00457 template <class E2, int CS2, int RS2>
00458 typename Result<Mat<M,N,E2,CS2,RS2> >::Add
00459 conformingAdd(const Mat<M,N,E2,CS2,RS2>& r) const {
00460 typename Result<Mat<M,N,E2,CS2,RS2> >::Add result;
00461 for (int j=0;j<N;++j) result(j) = (*this)(j) + r(j);
00462 return result;
00463 }
00464
00465 template <class E2, int CS2, int RS2>
00466 typename Result<Mat<M,N,E2,CS2,RS2> >::Sub
00467 conformingSubtract(const Mat<M,N,E2,CS2,RS2>& r) const {
00468 typename Result<Mat<M,N,E2,CS2,RS2> >::Sub result;
00469 for (int j=0;j<N;++j) result(j) = (*this)(j) - r(j);
00470 return result;
00471 }
00472
00473 template <class E2, int CS2, int RS2>
00474 typename Mat<M,N,E2,CS2,RS2>::template Result<Mat>::Sub
00475 conformingSubtractFromLeft(const Mat<M,N,E2,CS2,RS2>& l) const {
00476 return l.conformingSubtract(*this);
00477 }
00478
00479
00480
00481 template <class E2, int RS2>
00482 typename Result<SymMat<M,E2,RS2> >::Add
00483 conformingAdd(const SymMat<M,E2,RS2>& sy) const {
00484 assert(M==N);
00485 return sy.conformingAdd(*this);
00486 }
00487
00488 template <class E2, int RS2>
00489 typename Result<SymMat<M,E2,RS2> >::Sub
00490 conformingSubtract(const SymMat<M,E2,RS2>& sy) const {
00491 assert(M==N);
00492 return sy.conformingSubtractFromLeft(*this);
00493 }
00494
00495 template <class E2, int RS2>
00496 typename SymMat<M,E2,RS2>::template Result<Mat>::Sub
00497 conformingSubtractFromLeft(const SymMat<M,E2,RS2>& sy) const {
00498 assert(M==N);
00499 return sy.conformingSubtract(*this);
00500 }
00501
00502
00503 template <int N2, class E2, int CS2, int RS2>
00504 typename Result<Mat<N,N2,E2,CS2,RS2> >::Mul
00505 conformingMultiply(const Mat<N,N2,E2,CS2,RS2>& m) const {
00506 typename Result<Mat<N,N2,E2,CS2,RS2> >::Mul result;
00507 for (int j=0;j<N2;++j)
00508 for (int i=0;i<M;++i)
00509 result(i,j) = (*this)[i].conformingMultiply(m(j));
00510 return result;
00511 }
00512
00513 template <int M2, class E2, int CS2, int RS2>
00514 typename Mat<M2,M,E2,CS2,RS2>::template Result<Mat>::Mul
00515 conformingMultiplyFromLeft(const Mat<M2,M,E2,CS2,RS2>& m) const {
00516 return m.conformingMultiply(*this);
00517 }
00518
00519
00520 template <int M2, class E2, int CS2, int RS2>
00521 typename Result<Mat<M2,N,E2,CS2,RS2> >::Dvd
00522 conformingDivide(const Mat<M2,N,E2,CS2,RS2>& m) const {
00523 return conformingMultiply(m.invert());
00524 }
00525
00526 template <int M2, class E2, int CS2, int RS2>
00527 typename Mat<M2,N,E2,CS2,RS2>::template Result<Mat>::Dvd
00528 conformingDivideFromLeft(const Mat<M2,N,E2,CS2,RS2>& m) const {
00529 return m.conformingMultiply((*this).invert());
00530 }
00531
00532 const TRow& operator[](int i) const { return row(i); }
00533 TRow& operator[](int i) { return row(i); }
00534 const TCol& operator()(int j) const { return col(j); }
00535 TCol& operator()(int j) { return col(j); }
00536
00537 const E& operator()(int i,int j) const { return d[i*RS+j*CS]; }
00538 E& operator()(int i,int j) { return d[i*RS+j*CS]; }
00539
00540
00541 ScalarSq normSqr() const { return scalarNormSqr(); }
00542 ScalarSq norm() const { return std::sqrt(scalarNormSqr()); }
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 TNormalize normalize() const {
00558 if (CNT<E>::IsScalar) {
00559 return castAwayNegatorIfAny() / (SignInterpretation*norm());
00560 } else {
00561 TNormalize elementwiseNormalized;
00562
00563 for (int j=0; j<N; ++j)
00564 elementwiseNormalized(j) = (*this)(j).normalize();
00565 return elementwiseNormalized;
00566 }
00567 }
00568
00569
00570
00571 TInvert invert() const;
00572
00573 const Mat& operator+() const { return *this; }
00574 const TNeg& operator-() const { return negate(); }
00575 TNeg& operator-() { return updNegate(); }
00576 const THerm& operator~() const { return transpose(); }
00577 THerm& operator~() { return updTranspose(); }
00578
00579 const TNeg& negate() const { return *reinterpret_cast<const TNeg*>(this); }
00580 TNeg& updNegate() { return *reinterpret_cast<TNeg*>(this); }
00581
00582 const THerm& transpose() const { return *reinterpret_cast<const THerm*>(this); }
00583 THerm& updTranspose() { return *reinterpret_cast<THerm*>(this); }
00584
00585 const TPosTrans& positionalTranspose() const
00586 { return *reinterpret_cast<const TPosTrans*>(this); }
00587 TPosTrans& updPositionalTranspose()
00588 { return *reinterpret_cast<TPosTrans*>(this); }
00589
00590
00591
00592
00593
00594 const TReal& real() const { return *reinterpret_cast<const TReal*>(this); }
00595 TReal& real() { return *reinterpret_cast< TReal*>(this); }
00596
00597
00598
00599
00600
00601
00602
00603
00604 const TImag& imag() const {
00605 const int offs = ImagOffset;
00606 const Precision* p = reinterpret_cast<const Precision*>(this);
00607 return *reinterpret_cast<const TImag*>(p+offs);
00608 }
00609 TImag& imag() {
00610 const int offs = ImagOffset;
00611 Precision* p = reinterpret_cast<Precision*>(this);
00612 return *reinterpret_cast<TImag*>(p+offs);
00613 }
00614
00615 const TWithoutNegator& castAwayNegatorIfAny() const {return *reinterpret_cast<const TWithoutNegator*>(this);}
00616 TWithoutNegator& updCastAwayNegatorIfAny() {return *reinterpret_cast<TWithoutNegator*>(this);}
00617
00618 const TRow& row(int i) const
00619 { assert(0<=i&&i<M); return *reinterpret_cast<const TRow*>(&d[i*RS]); }
00620 TRow& row(int i)
00621 { assert(0<=i&&i<M); return *reinterpret_cast< TRow*>(&d[i*RS]); }
00622
00623 const TCol& col(int j) const
00624 { assert(0<=j&&j<N); return *reinterpret_cast<const TCol*>(&d[j*CS]); }
00625 TCol& col(int j)
00626 { assert(0<=j&&j<N); return *reinterpret_cast< TCol*>(&d[j*CS]); }
00627
00628
00629 const TDiag& diag() const { return *reinterpret_cast<const TDiag*>(d); }
00630 TDiag& diag() { return *reinterpret_cast<TDiag*>(d); }
00631
00632 StdNumber trace() const {return diag().sum();}
00633
00634
00635
00636
00637
00638
00639
00640
00641 template <class EE> Mat<M,N, typename CNT<E>::template Result<EE>::Mul>
00642 scalarMultiply(const EE& e) const {
00643 Mat<M,N, typename CNT<E>::template Result<EE>::Mul> result;
00644 for (int j=0; j<N; ++j) result(j) = (*this)(j).scalarMultiply(e);
00645 return result;
00646 }
00647 template <class EE> Mat<M,N, typename CNT<EE>::template Result<E>::Mul>
00648 scalarMultiplyFromLeft(const EE& e) const {
00649 Mat<M,N, typename CNT<EE>::template Result<E>::Mul> result;
00650 for (int j=0; j<N; ++j) result(j) = (*this)(j).scalarMultiplyFromLeft(e);
00651 return result;
00652 }
00653
00654
00655
00656 template <class EE> Mat<M,N, typename CNT<E>::template Result<EE>::Dvd>
00657 scalarDivide(const EE& e) const {
00658 Mat<M,N, typename CNT<E>::template Result<EE>::Dvd> result;
00659 for (int j=0; j<N; ++j) result(j) = (*this)(j).scalarDivide(e);
00660 return result;
00661 }
00662 template <class EE> Mat<M,N, typename CNT<EE>::template Result<E>::Dvd>
00663 scalarDivideFromLeft(const EE& e) const {
00664 Mat<M,N, typename CNT<EE>::template Result<E>::Dvd> result;
00665 for (int j=0; j<N; ++j) result(j) = (*this)(j).scalarDivideFromLeft(e);
00666 return result;
00667 }
00668
00669
00670 template <class EE> Mat<M,N, typename CNT<E>::template Result<EE>::Add>
00671 scalarAdd(const EE& e) const {
00672 Mat<M,N, typename CNT<E>::template Result<EE>::Add> result(*this);
00673 result.diag() += e;
00674 return result;
00675 }
00676
00677
00678 template <class EE> Mat<M,N, typename CNT<E>::template Result<EE>::Sub>
00679 scalarSubtract(const EE& e) const {
00680 Mat<M,N, typename CNT<E>::template Result<EE>::Sub> result(*this);
00681 result.diag() -= e;
00682 return result;
00683 }
00684
00685 template <class EE> Mat<M,N, typename CNT<EE>::template Result<E>::Sub>
00686 scalarSubtractFromLeft(const EE& e) const {
00687 Mat<M,N, typename CNT<EE>::template Result<E>::Sub> result(-(*this));
00688 result.diag() += e;
00689 return result;
00690 }
00691
00692
00693
00694
00695 template <class EE> Mat& operator =(const EE& e) {return scalarEq(e);}
00696 template <class EE> Mat& operator+=(const EE& e) {return scalarPlusEq(e);}
00697 template <class EE> Mat& operator-=(const EE& e) {return scalarMinusEq(e);}
00698 template <class EE> Mat& operator*=(const EE& e) {return scalarTimesEq(e);}
00699 template <class EE> Mat& operator/=(const EE& e) {return scalarDivideEq(e);}
00700
00701
00702
00703 template <class EE> Mat& scalarEq(const EE& ee)
00704 { for(int j=0; j<N; ++j) (*this)(j).scalarEq(EE(0));
00705 diag().scalarEq(ee);
00706 return *this; }
00707
00708 template <class EE> Mat& scalarPlusEq(const EE& ee)
00709 { diag().scalarPlusEq(ee); return *this; }
00710
00711 template <class EE> Mat& scalarMinusEq(const EE& ee)
00712 { diag().scalarMinusEq(ee); return *this; }
00713
00714 template <class EE> Mat& scalarMinusEqFromLeft(const EE& ee)
00715 { scalarTimesEq(E(-1)); diag().scalarAdd(ee); return *this; }
00716
00717 template <class EE> Mat& scalarTimesEq(const EE& ee)
00718 { for(int j=0; j<N; ++j) (*this)(j).scalarTimesEq(ee); return *this; }
00719 template <class EE> Mat& scalarTimesEqFromLeft(const EE& ee)
00720 { for(int j=0; j<N; ++j) (*this)(j).scalarTimesEqFromLeft(ee); return *this; }
00721
00722 template <class EE> Mat& scalarDivideEq(const EE& ee)
00723 { for(int j=0; j<N; ++j) (*this)(j).scalarDivideEq(ee); return *this; }
00724 template <class EE> Mat& scalarDivideEqFromLeft(const EE& ee)
00725 { for(int j=0; j<N; ++j) (*this)(j).scalarDivideEqFromLeft(ee); return *this; }
00726
00727 void setToNaN() {
00728 for (int j=0; j<N; ++j)
00729 (*this)(j).setToNaN();
00730 }
00731
00732
00733
00734
00735 template <int MM, int NN> struct SubMat {
00736 typedef Mat<MM,NN,ELT,CS,RS> Type;
00737 };
00738
00739 template <int MM, int NN>
00740 const typename SubMat<MM,NN>::Type& getSubMat(int i, int j) const {
00741 assert(0 <= i && i + MM <= M);
00742 assert(0 <= j && j + NN <= N);
00743 return SubMat<MM,NN>::Type::getAs(&(*this)(i,j));
00744 }
00745 template <int MM, int NN>
00746 typename SubMat<MM,NN>::Type& updSubMat(int i, int j) {
00747 assert(0 <= i && i + MM <= M);
00748 assert(0 <= j && j + NN <= N);
00749 return SubMat<MM,NN>::Type::updAs(&(*this)(i,j));
00750 }
00751
00752
00753 static const Mat& getAs(const ELT* p) {return *reinterpret_cast<const Mat*>(p);}
00754 static Mat& updAs(ELT* p) {return *reinterpret_cast<Mat*>(p);}
00755
00756
00757 static Mat<M,N,ELT,M,1> getNaN() {
00758 Mat<M,N,ELT,M,1> m;
00759 m.setToNaN();
00760 return m;
00761 }
00762
00763 TRow sum() const {
00764 TRow temp;
00765 for (int i = 0; i < N; ++i)
00766 temp[i] = col(i).sum();
00767 return temp;
00768 }
00769
00770 private:
00771 E d[NActualElements];
00772
00773
00774
00775
00776
00777 int rIx(int k) const {
00778 const int row = k / N;
00779 const int col = k % N;
00780 return row*RS + col*CS;
00781 }
00782 };
00783
00785
00786
00788
00789 template <int M, int N, class EL, int CSL, int RSL, class ER, int CSR, int RSR> inline
00790 typename Mat<M,N,EL,CSL,RSL>::template Result<Mat<M,N,ER,CSR,RSR> >::Add
00791 operator+(const Mat<M,N,EL,CSL,RSL>& l, const Mat<M,N,ER,CSR,RSR>& r) {
00792 return Mat<M,N,EL,CSL,RSL>::template Result<Mat<M,N,ER,CSR,RSR> >
00793 ::AddOp::perform(l,r);
00794 }
00795
00796 template <int M, int N, class EL, int CSL, int RSL, class ER, int CSR, int RSR> inline
00797 typename Mat<M,N,EL,CSL,RSL>::template Result<Mat<M,N,ER,CSR,RSR> >::Sub
00798 operator-(const Mat<M,N,EL,CSL,RSL>& l, const Mat<M,N,ER,CSR,RSR>& r) {
00799 return Mat<M,N,EL,CSL,RSL>::template Result<Mat<M,N,ER,CSR,RSR> >
00800 ::SubOp::perform(l,r);
00801 }
00802
00803
00804 template <int M, int N, class EL, int CSL, int RSL, int P, class ER, int CSR, int RSR> inline
00805 typename Mat<M,N,EL,CSL,RSL>::template Result<Mat<N,P,ER,CSR,RSR> >::Mul
00806 operator*(const Mat<M,N,EL,CSL,RSL>& l, const Mat<N,P,ER,CSR,RSR>& r) {
00807 return Mat<M,N,EL,CSL,RSL>::template Result<Mat<N,P,ER,CSR,RSR> >
00808 ::MulOp::perform(l,r);
00809 }
00810
00811
00812
00813 template <int M, int N, class EL, int CSL, int RSL, int MM, int NN, class ER, int CSR, int RSR> inline
00814 typename Mat<M,N,EL,CSL,RSL>::template Result<Mat<MM,NN,ER,CSR,RSR> >::MulNon
00815 operator*(const Mat<M,N,EL,CSL,RSL>& l, const Mat<MM,NN,ER,CSR,RSR>& r) {
00816 return Mat<M,N,EL,CSL,RSL>::template Result<Mat<MM,NN,ER,CSR,RSR> >
00817 ::MulOpNonConforming::perform(l,r);
00818 }
00819
00820 template <int M, int N, class EL, int CSL, int RSL, class ER, int CSR, int RSR> inline
00821 bool operator==(const Mat<M,N,EL,CSL,RSL>& l, const Mat<M,N,ER,CSR,RSR>& r) {
00822 for (int j=0; j<N; ++j)
00823 if (l(j) != r(j)) return false;
00824 return true;
00825 }
00826 template <int M, int N, class EL, int CSL, int RSL, class ER, int CSR, int RSR> inline
00827 bool operator!=(const Mat<M,N,EL,CSL,RSL>& l, const Mat<M,N,ER,CSR,RSR>& r) {
00828 return !(l==r);
00829 }
00830
00831
00833
00835
00836
00837
00838
00839 template <int M, int N, class E, int CS, int RS> inline
00840 typename Mat<M,N,E,CS,RS>::template Result<float>::Mul
00841 operator*(const Mat<M,N,E,CS,RS>& l, const float& r)
00842 { return Mat<M,N,E,CS,RS>::template Result<float>::MulOp::perform(l,r); }
00843 template <int M, int N, class E, int CS, int RS> inline
00844 typename Mat<M,N,E,CS,RS>::template Result<float>::Mul
00845 operator*(const float& l, const Mat<M,N,E,CS,RS>& r) {return r*l;}
00846
00847 template <int M, int N, class E, int CS, int RS> inline
00848 typename Mat<M,N,E,CS,RS>::template Result<double>::Mul
00849 operator*(const Mat<M,N,E,CS,RS>& l, const double& r)
00850 { return Mat<M,N,E,CS,RS>::template Result<double>::MulOp::perform(l,r); }
00851 template <int M, int N, class E, int CS, int RS> inline
00852 typename Mat<M,N,E,CS,RS>::template Result<double>::Mul
00853 operator*(const double& l, const Mat<M,N,E,CS,RS>& r) {return r*l;}
00854
00855 template <int M, int N, class E, int CS, int RS> inline
00856 typename Mat<M,N,E,CS,RS>::template Result<long double>::Mul
00857 operator*(const Mat<M,N,E,CS,RS>& l, const long double& r)
00858 { return Mat<M,N,E,CS,RS>::template Result<long double>::MulOp::perform(l,r); }
00859 template <int M, int N, class E, int CS, int RS> inline
00860 typename Mat<M,N,E,CS,RS>::template Result<long double>::Mul
00861 operator*(const long double& l, const Mat<M,N,E,CS,RS>& r) {return r*l;}
00862
00863
00864 template <int M, int N, class E, int CS, int RS> inline
00865 typename Mat<M,N,E,CS,RS>::template Result<typename CNT<E>::Precision>::Mul
00866 operator*(const Mat<M,N,E,CS,RS>& l, int r) {return l * (typename CNT<E>::Precision)r;}
00867 template <int M, int N, class E, int CS, int RS> inline
00868 typename Mat<M,N,E,CS,RS>::template Result<typename CNT<E>::Precision>::Mul
00869 operator*(int l, const Mat<M,N,E,CS,RS>& r) {return r * (typename CNT<E>::Precision)l;}
00870
00871
00872
00873
00874 template <int M, int N, class E, int CS, int RS, class R> inline
00875 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Mul
00876 operator*(const Mat<M,N,E,CS,RS>& l, const std::complex<R>& r)
00877 { return Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::MulOp::perform(l,r); }
00878 template <int M, int N, class E, int CS, int RS, class R> inline
00879 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Mul
00880 operator*(const std::complex<R>& l, const Mat<M,N,E,CS,RS>& r) {return r*l;}
00881
00882
00883 template <int M, int N, class E, int CS, int RS, class R> inline
00884 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Mul
00885 operator*(const Mat<M,N,E,CS,RS>& l, const conjugate<R>& r) {return l*(std::complex<R>)r;}
00886 template <int M, int N, class E, int CS, int RS, class R> inline
00887 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Mul
00888 operator*(const conjugate<R>& l, const Mat<M,N,E,CS,RS>& r) {return r*(std::complex<R>)l;}
00889
00890
00891 template <int M, int N, class E, int CS, int RS, class R> inline
00892 typename Mat<M,N,E,CS,RS>::template Result<typename negator<R>::StdNumber>::Mul
00893 operator*(const Mat<M,N,E,CS,RS>& l, const negator<R>& r) {return l * (typename negator<R>::StdNumber)(R)r;}
00894 template <int M, int N, class E, int CS, int RS, class R> inline
00895 typename Mat<M,N,E,CS,RS>::template Result<typename negator<R>::StdNumber>::Mul
00896 operator*(const negator<R>& l, const Mat<M,N,E,CS,RS>& r) {return r * (typename negator<R>::StdNumber)(R)l;}
00897
00898
00899
00900
00901
00902
00903
00904 template <int M, int N, class E, int CS, int RS> inline
00905 typename Mat<M,N,E,CS,RS>::template Result<float>::Dvd
00906 operator/(const Mat<M,N,E,CS,RS>& l, const float& r)
00907 { return Mat<M,N,E,CS,RS>::template Result<float>::DvdOp::perform(l,r); }
00908 template <int M, int N, class E, int CS, int RS> inline
00909 typename CNT<float>::template Result<Mat<M,N,E,CS,RS> >::Dvd
00910 operator/(const float& l, const Mat<M,N,E,CS,RS>& r)
00911 { return CNT<float>::template Result<Mat<M,N,E,CS,RS> >::DvdOp::perform(l,r); }
00912
00913 template <int M, int N, class E, int CS, int RS> inline
00914 typename Mat<M,N,E,CS,RS>::template Result<double>::Dvd
00915 operator/(const Mat<M,N,E,CS,RS>& l, const double& r)
00916 { return Mat<M,N,E,CS,RS>::template Result<double>::DvdOp::perform(l,r); }
00917 template <int M, int N, class E, int CS, int RS> inline
00918 typename CNT<double>::template Result<Mat<M,N,E,CS,RS> >::Dvd
00919 operator/(const double& l, const Mat<M,N,E,CS,RS>& r)
00920 { return CNT<double>::template Result<Mat<M,N,E,CS,RS> >::DvdOp::perform(l,r); }
00921
00922 template <int M, int N, class E, int CS, int RS> inline
00923 typename Mat<M,N,E,CS,RS>::template Result<long double>::Dvd
00924 operator/(const Mat<M,N,E,CS,RS>& l, const long double& r)
00925 { return Mat<M,N,E,CS,RS>::template Result<long double>::DvdOp::perform(l,r); }
00926 template <int M, int N, class E, int CS, int RS> inline
00927 typename CNT<long double>::template Result<Mat<M,N,E,CS,RS> >::Dvd
00928 operator/(const long double& l, const Mat<M,N,E,CS,RS>& r)
00929 { return CNT<long double>::template Result<Mat<M,N,E,CS,RS> >::DvdOp::perform(l,r); }
00930
00931
00932 template <int M, int N, class E, int CS, int RS> inline
00933 typename Mat<M,N,E,CS,RS>::template Result<typename CNT<E>::Precision>::Dvd
00934 operator/(const Mat<M,N,E,CS,RS>& l, int r) {return l / (typename CNT<E>::Precision)r;}
00935 template <int M, int N, class E, int CS, int RS> inline
00936 typename CNT<typename CNT<E>::Precision>::template Result<Mat<M,N,E,CS,RS> >::Dvd
00937 operator/(int l, const Mat<M,N,E,CS,RS>& r) {return (typename CNT<E>::Precision)l / r;}
00938
00939
00940
00941
00942
00943 template <int M, int N, class E, int CS, int RS, class R> inline
00944 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Dvd
00945 operator/(const Mat<M,N,E,CS,RS>& l, const std::complex<R>& r)
00946 { return Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::DvdOp::perform(l,r); }
00947 template <int M, int N, class E, int CS, int RS, class R> inline
00948 typename CNT<std::complex<R> >::template Result<Mat<M,N,E,CS,RS> >::Dvd
00949 operator/(const std::complex<R>& l, const Mat<M,N,E,CS,RS>& r)
00950 { return CNT<std::complex<R> >::template Result<Mat<M,N,E,CS,RS> >::DvdOp::perform(l,r); }
00951
00952
00953 template <int M, int N, class E, int CS, int RS, class R> inline
00954 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Dvd
00955 operator/(const Mat<M,N,E,CS,RS>& l, const conjugate<R>& r) {return l/(std::complex<R>)r;}
00956 template <int M, int N, class E, int CS, int RS, class R> inline
00957 typename CNT<std::complex<R> >::template Result<Mat<M,N,E,CS,RS> >::Dvd
00958 operator/(const conjugate<R>& l, const Mat<M,N,E,CS,RS>& r) {return (std::complex<R>)l/r;}
00959
00960
00961 template <int M, int N, class E, int CS, int RS, class R> inline
00962 typename Mat<M,N,E,CS,RS>::template Result<typename negator<R>::StdNumber>::Dvd
00963 operator/(const Mat<M,N,E,CS,RS>& l, const negator<R>& r) {return l/(typename negator<R>::StdNumber)(R)r;}
00964 template <int M, int N, class E, int CS, int RS, class R> inline
00965 typename CNT<R>::template Result<Mat<M,N,E,CS,RS> >::Dvd
00966 operator/(const negator<R>& l, const Mat<M,N,E,CS,RS>& r) {return (typename negator<R>::StdNumber)(R)l/r;}
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976 template <int M, int N, class E, int CS, int RS> inline
00977 typename Mat<M,N,E,CS,RS>::template Result<float>::Add
00978 operator+(const Mat<M,N,E,CS,RS>& l, const float& r)
00979 { return Mat<M,N,E,CS,RS>::template Result<float>::AddOp::perform(l,r); }
00980 template <int M, int N, class E, int CS, int RS> inline
00981 typename Mat<M,N,E,CS,RS>::template Result<float>::Add
00982 operator+(const float& l, const Mat<M,N,E,CS,RS>& r) {return r+l;}
00983
00984 template <int M, int N, class E, int CS, int RS> inline
00985 typename Mat<M,N,E,CS,RS>::template Result<double>::Add
00986 operator+(const Mat<M,N,E,CS,RS>& l, const double& r)
00987 { return Mat<M,N,E,CS,RS>::template Result<double>::AddOp::perform(l,r); }
00988 template <int M, int N, class E, int CS, int RS> inline
00989 typename Mat<M,N,E,CS,RS>::template Result<double>::Add
00990 operator+(const double& l, const Mat<M,N,E,CS,RS>& r) {return r+l;}
00991
00992 template <int M, int N, class E, int CS, int RS> inline
00993 typename Mat<M,N,E,CS,RS>::template Result<long double>::Add
00994 operator+(const Mat<M,N,E,CS,RS>& l, const long double& r)
00995 { return Mat<M,N,E,CS,RS>::template Result<long double>::AddOp::perform(l,r); }
00996 template <int M, int N, class E, int CS, int RS> inline
00997 typename Mat<M,N,E,CS,RS>::template Result<long double>::Add
00998 operator+(const long double& l, const Mat<M,N,E,CS,RS>& r) {return r+l;}
00999
01000
01001 template <int M, int N, class E, int CS, int RS> inline
01002 typename Mat<M,N,E,CS,RS>::template Result<typename CNT<E>::Precision>::Add
01003 operator+(const Mat<M,N,E,CS,RS>& l, int r) {return l + (typename CNT<E>::Precision)r;}
01004 template <int M, int N, class E, int CS, int RS> inline
01005 typename Mat<M,N,E,CS,RS>::template Result<typename CNT<E>::Precision>::Add
01006 operator+(int l, const Mat<M,N,E,CS,RS>& r) {return r + (typename CNT<E>::Precision)l;}
01007
01008
01009
01010
01011 template <int M, int N, class E, int CS, int RS, class R> inline
01012 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Add
01013 operator+(const Mat<M,N,E,CS,RS>& l, const std::complex<R>& r)
01014 { return Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::AddOp::perform(l,r); }
01015 template <int M, int N, class E, int CS, int RS, class R> inline
01016 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Add
01017 operator+(const std::complex<R>& l, const Mat<M,N,E,CS,RS>& r) {return r+l;}
01018
01019
01020 template <int M, int N, class E, int CS, int RS, class R> inline
01021 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Add
01022 operator+(const Mat<M,N,E,CS,RS>& l, const conjugate<R>& r) {return l+(std::complex<R>)r;}
01023 template <int M, int N, class E, int CS, int RS, class R> inline
01024 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Add
01025 operator+(const conjugate<R>& l, const Mat<M,N,E,CS,RS>& r) {return r+(std::complex<R>)l;}
01026
01027
01028 template <int M, int N, class E, int CS, int RS, class R> inline
01029 typename Mat<M,N,E,CS,RS>::template Result<typename negator<R>::StdNumber>::Add
01030 operator+(const Mat<M,N,E,CS,RS>& l, const negator<R>& r) {return l + (typename negator<R>::StdNumber)(R)r;}
01031 template <int M, int N, class E, int CS, int RS, class R> inline
01032 typename Mat<M,N,E,CS,RS>::template Result<typename negator<R>::StdNumber>::Add
01033 operator+(const negator<R>& l, const Mat<M,N,E,CS,RS>& r) {return r + (typename negator<R>::StdNumber)(R)l;}
01034
01035
01036
01037
01038 template <int M, int N, class E, int CS, int RS> inline
01039 typename Mat<M,N,E,CS,RS>::template Result<float>::Sub
01040 operator-(const Mat<M,N,E,CS,RS>& l, const float& r)
01041 { return Mat<M,N,E,CS,RS>::template Result<float>::SubOp::perform(l,r); }
01042 template <int M, int N, class E, int CS, int RS> inline
01043 typename CNT<float>::template Result<Mat<M,N,E,CS,RS> >::Sub
01044 operator-(const float& l, const Mat<M,N,E,CS,RS>& r)
01045 { return CNT<float>::template Result<Mat<M,N,E,CS,RS> >::SubOp::perform(l,r); }
01046
01047 template <int M, int N, class E, int CS, int RS> inline
01048 typename Mat<M,N,E,CS,RS>::template Result<double>::Sub
01049 operator-(const Mat<M,N,E,CS,RS>& l, const double& r)
01050 { return Mat<M,N,E,CS,RS>::template Result<double>::SubOp::perform(l,r); }
01051 template <int M, int N, class E, int CS, int RS> inline
01052 typename CNT<double>::template Result<Mat<M,N,E,CS,RS> >::Sub
01053 operator-(const double& l, const Mat<M,N,E,CS,RS>& r)
01054 { return CNT<double>::template Result<Mat<M,N,E,CS,RS> >::SubOp::perform(l,r); }
01055
01056 template <int M, int N, class E, int CS, int RS> inline
01057 typename Mat<M,N,E,CS,RS>::template Result<long double>::Sub
01058 operator-(const Mat<M,N,E,CS,RS>& l, const long double& r)
01059 { return Mat<M,N,E,CS,RS>::template Result<long double>::SubOp::perform(l,r); }
01060 template <int M, int N, class E, int CS, int RS> inline
01061 typename CNT<long double>::template Result<Mat<M,N,E,CS,RS> >::Sub
01062 operator-(const long double& l, const Mat<M,N,E,CS,RS>& r)
01063 { return CNT<long double>::template Result<Mat<M,N,E,CS,RS> >::SubOp::perform(l,r); }
01064
01065
01066 template <int M, int N, class E, int CS, int RS> inline
01067 typename Mat<M,N,E,CS,RS>::template Result<typename CNT<E>::Precision>::Sub
01068 operator-(const Mat<M,N,E,CS,RS>& l, int r) {return l - (typename CNT<E>::Precision)r;}
01069 template <int M, int N, class E, int CS, int RS> inline
01070 typename CNT<typename CNT<E>::Precision>::template Result<Mat<M,N,E,CS,RS> >::Sub
01071 operator-(int l, const Mat<M,N,E,CS,RS>& r) {return (typename CNT<E>::Precision)l - r;}
01072
01073
01074
01075
01076
01077 template <int M, int N, class E, int CS, int RS, class R> inline
01078 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Sub
01079 operator-(const Mat<M,N,E,CS,RS>& l, const std::complex<R>& r)
01080 { return Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::SubOp::perform(l,r); }
01081 template <int M, int N, class E, int CS, int RS, class R> inline
01082 typename CNT<std::complex<R> >::template Result<Mat<M,N,E,CS,RS> >::Sub
01083 operator-(const std::complex<R>& l, const Mat<M,N,E,CS,RS>& r)
01084 { return CNT<std::complex<R> >::template Result<Mat<M,N,E,CS,RS> >::SubOp::perform(l,r); }
01085
01086
01087 template <int M, int N, class E, int CS, int RS, class R> inline
01088 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Sub
01089 operator-(const Mat<M,N,E,CS,RS>& l, const conjugate<R>& r) {return l-(std::complex<R>)r;}
01090 template <int M, int N, class E, int CS, int RS, class R> inline
01091 typename CNT<std::complex<R> >::template Result<Mat<M,N,E,CS,RS> >::Sub
01092 operator-(const conjugate<R>& l, const Mat<M,N,E,CS,RS>& r) {return (std::complex<R>)l-r;}
01093
01094
01095 template <int M, int N, class E, int CS, int RS, class R> inline
01096 typename Mat<M,N,E,CS,RS>::template Result<typename negator<R>::StdNumber>::Sub
01097 operator-(const Mat<M,N,E,CS,RS>& l, const negator<R>& r) {return l-(typename negator<R>::StdNumber)(R)r;}
01098 template <int M, int N, class E, int CS, int RS, class R> inline
01099 typename CNT<R>::template Result<Mat<M,N,E,CS,RS> >::Sub
01100 operator-(const negator<R>& l, const Mat<M,N,E,CS,RS>& r) {return (typename negator<R>::StdNumber)(R)l-r;}
01101
01102
01103
01104 template <int M, int N, class E, int CS, int RS, class CHAR, class TRAITS> inline
01105 std::basic_ostream<CHAR,TRAITS>&
01106 operator<<(std::basic_ostream<CHAR,TRAITS>& o, const Mat<M,N,E,CS,RS>& m) {
01107 for (int i=0;i<M;++i) {
01108 o << std::endl << "[";
01109 for (int j=0;j<N;++j)
01110 o << (j>0?",":"") << m(i,j);
01111 o << "]";
01112 }
01113 if (M) o << std::endl;
01114 return o;
01115 }
01116
01117 template <int M, int N, class E, int CS, int RS, class CHAR, class TRAITS> inline
01118 std::basic_istream<CHAR,TRAITS>&
01119 operator>>(std::basic_istream<CHAR,TRAITS>& is, Mat<M,N,E,CS,RS>& m) {
01120
01121 assert(false);
01122 return is;
01123 }
01124
01125 }
01126
01127
01128 #endif //SimTK_SIMMATRIX_SMALLMATRIX_MAT_H_