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 typedef typename CNT<E>::TSqHermT ESqHermT;
00055 typedef typename CNT<E>::TSqTHerm ESqTHerm;
00056
00057 typedef typename CNT<E>::TSqrt ESqrt;
00058 typedef typename CNT<E>::TAbs EAbs;
00059 typedef typename CNT<E>::TStandard EStandard;
00060 typedef typename CNT<E>::TInvert EInvert;
00061 typedef typename CNT<E>::TNormalize ENormalize;
00062
00063 typedef typename CNT<E>::Scalar EScalar;
00064 typedef typename CNT<E>::ULessScalar EULessScalar;
00065 typedef typename CNT<E>::Number ENumber;
00066 typedef typename CNT<E>::StdNumber EStdNumber;
00067 typedef typename CNT<E>::Precision EPrecision;
00068 typedef typename CNT<E>::ScalarNormSq EScalarNormSq;
00069
00070 public:
00071
00072 enum {
00073 NRows = M,
00074 NCols = N,
00075 MinDim = N < M ? N : M,
00076 MaxDim = N > M ? N : M,
00077 RowSpacing = RS,
00078 ColSpacing = CS,
00079 NPackedElements = M * N,
00080 NActualElements = (N-1)*CS + (M-1)*RS + 1,
00081 NActualScalars = CNT<E>::NActualScalars * NActualElements,
00082 ImagOffset = NTraits<ENumber>::ImagOffset,
00083 RealStrideFactor = 1,
00084
00085 ArgDepth = ((int)CNT<E>::ArgDepth < (int)MAX_RESOLVED_DEPTH
00086 ? CNT<E>::ArgDepth + 1
00087 : MAX_RESOLVED_DEPTH),
00088 IsScalar = 0,
00089 IsULessScalar = 0,
00090 IsNumber = 0,
00091 IsStdNumber = 0,
00092 IsPrecision = 0,
00093 SignInterpretation = CNT<E>::SignInterpretation
00094 };
00095
00096 typedef Mat<M,N,E,CS,RS> T;
00097 typedef Mat<M,N,ENeg,CS,RS> TNeg;
00098 typedef Mat<M,N,EWithoutNegator,CS,RS> TWithoutNegator;
00099
00100 typedef Mat<M,N,EReal,CS*CNT<E>::RealStrideFactor,RS*CNT<E>::RealStrideFactor>
00101 TReal;
00102 typedef Mat<M,N,EImag,CS*CNT<E>::RealStrideFactor,RS*CNT<E>::RealStrideFactor>
00103 TImag;
00104 typedef Mat<M,N,EComplex,CS,RS> TComplex;
00105 typedef Mat<N,M,EHerm,RS,CS> THerm;
00106 typedef Mat<N,M,E,RS,CS> TPosTrans;
00107 typedef E TElement;
00108 typedef Row<N,E,CS> TRow;
00109 typedef Vec<M,E,RS> TCol;
00110 typedef Vec<MinDim,E,RS+CS> TDiag;
00111
00112
00113
00114 typedef Mat<M,N,ESqrt,M,1> TSqrt;
00115 typedef Mat<M,N,EAbs,M,1> TAbs;
00116 typedef Mat<M,N,EStandard,M,1> TStandard;
00117 typedef Mat<N,M,EInvert,N,1> TInvert;
00118 typedef Mat<M,N,ENormalize,M,1> TNormalize;
00119
00120 typedef SymMat<N,ESqHermT> TSqHermT;
00121 typedef SymMat<M,ESqTHerm> TSqTHerm;
00122
00123
00124
00125 typedef Mat<M,N,E,M,1> TPacked;
00126 typedef Mat<M-1,N,E,M,1> TDropRow;
00127 typedef Mat<M,N-1,E,M,1> TDropCol;
00128 typedef Mat<M-1,N-1,E,M,1> TDropRowCol;
00129 typedef Mat<M+1,N,E,M,1> TAppendRow;
00130 typedef Mat<M,N+1,E,M,1> TAppendCol;
00131 typedef Mat<M+1,N+1,E,M,1> TAppendRowCol;
00132
00133 typedef EScalar Scalar;
00134 typedef EULessScalar ULessScalar;
00135 typedef ENumber Number;
00136 typedef EStdNumber StdNumber;
00137 typedef EPrecision Precision;
00138 typedef EScalarNormSq ScalarNormSq;
00139
00140 typedef THerm TransposeType;
00141
00142 int size() const { return M*N; }
00143 int nrow() const { return M; }
00144 int ncol() const { return N; }
00145
00146
00147 ScalarNormSq scalarNormSqr() const {
00148 ScalarNormSq sum(0);
00149 for(int j=0;j<N;++j) sum += CNT<TCol>::scalarNormSqr((*this)(j));
00150 return sum;
00151 }
00152
00153
00154
00155
00156 TSqrt sqrt() const {
00157 TSqrt msqrt;
00158 for(int j=0;j<N;++j) msqrt(j) = (*this)(j).sqrt();
00159 return msqrt;
00160 }
00161
00162
00163
00164
00165 TAbs abs() const {
00166 TAbs mabs;
00167 for(int j=0;j<N;++j) mabs(j) = (*this)(j).abs();
00168 return mabs;
00169 }
00170
00171 TStandard standardize() const {
00172 TStandard mstd;
00173 for(int j=0;j<N;++j) mstd(j) = (*this)(j).standardize();
00174 return mstd;
00175 }
00176
00177
00178
00179
00180
00181 template <class P> struct EltResult {
00182 typedef Mat<M,N, typename CNT<E>::template Result<P>::Mul, M, 1> Mul;
00183 typedef Mat<M,N, typename CNT<E>::template Result<P>::Dvd, M, 1> Dvd;
00184 typedef Mat<M,N, typename CNT<E>::template Result<P>::Add, M, 1> Add;
00185 typedef Mat<M,N, typename CNT<E>::template Result<P>::Sub, M, 1> Sub;
00186 };
00187
00188
00189
00190 template <class P> struct Result {
00191 typedef MulCNTs<M,N,ArgDepth,Mat,ColSpacing,RowSpacing,
00192 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00193 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> MulOp;
00194 typedef typename MulOp::Type Mul;
00195
00196 typedef MulCNTsNonConforming<M,N,ArgDepth,Mat,ColSpacing,RowSpacing,
00197 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00198 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> MulOpNonConforming;
00199 typedef typename MulOpNonConforming::Type MulNon;
00200
00201 typedef DvdCNTs<M,N,ArgDepth,Mat,ColSpacing,RowSpacing,
00202 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00203 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> DvdOp;
00204 typedef typename DvdOp::Type Dvd;
00205
00206 typedef AddCNTs<M,N,ArgDepth,Mat,ColSpacing,RowSpacing,
00207 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00208 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> AddOp;
00209 typedef typename AddOp::Type Add;
00210
00211 typedef SubCNTs<M,N,ArgDepth,Mat,ColSpacing,RowSpacing,
00212 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00213 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> SubOp;
00214 typedef typename SubOp::Type Sub;
00215 };
00216
00217
00218 template <class P> struct Substitute {
00219 typedef Mat<M,N,P> Type;
00220 };
00221
00222
00223
00224 Mat(){
00225 #ifndef NDEBUG
00226 setToNaN();
00227 #endif
00228 }
00229
00230
00231
00232
00233 Mat(const Mat& src) {
00234 for (int j=0; j<N; ++j)
00235 (*this)(j) = src(j);
00236 }
00237 Mat& operator=(const Mat& src) {
00238 for (int j=0; j<N; ++j)
00239 (*this)(j) = src(j);
00240 return *this;
00241 }
00242
00243
00244
00245 explicit Mat(const SymMat<M, ELT>& src) {
00246 diag() = src.diag();
00247 for (int j = 0; j < M; ++j)
00248 for (int i = j+1; i < M; ++i) {
00249 (*this)(i, j) = src.getEltLower(i, j);
00250 (*this)(j, i) = src.getEltUpper(j, i);
00251 }
00252 }
00253
00254
00255
00256 template <int CSS, int RSS> Mat(const Mat<M,N,E,CSS,RSS>& src) {
00257 for (int j=0; j<N; ++j)
00258 (*this)(j) = src(j);
00259 }
00260
00261
00262
00263 template <int CSS, int RSS> Mat(const Mat<M,N,ENeg,CSS,RSS>& src) {
00264 for (int j=0; j<N; ++j)
00265 (*this)(j) = src(j);
00266 }
00267
00268
00269
00270 template <class EE, int CSS, int RSS> explicit Mat(const Mat<M,N,EE,CSS,RSS>& mm)
00271 { for (int j=0;j<N;++j) (*this)(j) = mm(j);}
00272
00273
00274
00275 explicit Mat(const E& e)
00276 { for (int j=0;j<N;++j) (*this)(j) = E(0); diag()=e; }
00277
00278
00279
00280 explicit Mat(const ENeg& e)
00281 { for (int j=0;j<N;++j) (*this)(j) = E(0); diag()=e; }
00282
00283
00284
00285 explicit Mat(int i)
00286 { new (this) Mat(E(Precision(i))); }
00287
00288
00289 Mat(const E& e0,const E& e1)
00290 {assert(M*N==2);d[rIx(0)]=e0;d[rIx(1)]=e1;}
00291 Mat(const E& e0,const E& e1,const E& e2)
00292 {assert(M*N==3);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;}
00293 Mat(const E& e0,const E& e1,const E& e2,const E& e3)
00294 {assert(M*N==4);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;}
00295 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4)
00296 {assert(M*N==5);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;}
00297 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00298 const E& e5)
00299 {assert(M*N==6);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;}
00301 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00302 const E& e5,const E& e6)
00303 {assert(M*N==7);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00304 d[rIx(5)]=e5;d[rIx(6)]=e6;}
00305 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00306 const E& e5,const E& e6,const E& e7)
00307 {assert(M*N==8);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00308 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;}
00309 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00310 const E& e5,const E& e6,const E& e7,const E& e8)
00311 {assert(M*N==9);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00312 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;}
00313 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00314 const E& e5,const E& e6,const E& e7,const E& e8,const E& e9)
00315 {assert(M*N==10);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00316 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;}
00317 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00318 const E& e5,const E& e6,const E& e7,const E& e8,const E& e9,
00319 const E& e10)
00320 {assert(M*N==11);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00321 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;}
00322 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00323 const E& e5,const E& e6,const E& e7,const E& e8,const E& e9,
00324 const E& e10, const E& e11)
00325 {assert(M*N==12);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00326 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;
00327 d[rIx(11)]=e11;}
00328 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00329 const E& e5,const E& e6,const E& e7,const E& e8,const E& e9,
00330 const E& e10, const E& e11, const E& e12)
00331 {assert(M*N==13);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00332 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;
00333 d[rIx(11)]=e11;d[rIx(12)]=e12;}
00334 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00335 const E& e5,const E& e6,const E& e7,const E& e8,const E& e9,
00336 const E& e10, const E& e11, const E& e12, const E& e13)
00337 {assert(M*N==14);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00338 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;
00339 d[rIx(11)]=e11;d[rIx(12)]=e12;d[rIx(13)]=e13;}
00340 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00341 const E& e5,const E& e6,const E& e7,const E& e8,const E& e9,
00342 const E& e10, const E& e11, const E& e12, const E& e13, const E& e14)
00343 {assert(M*N==15);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00344 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;
00345 d[rIx(11)]=e11;d[rIx(12)]=e12;d[rIx(13)]=e13;d[rIx(14)]=e14;}
00346 Mat(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,
00347 const E& e5,const E& e6,const E& e7,const E& e8,const E& e9,
00348 const E& e10, const E& e11, const E& e12, const E& e13, const E& e14,
00349 const E& e15)
00350 {assert(M*N==16);d[rIx(0)]=e0;d[rIx(1)]=e1;d[rIx(2)]=e2;d[rIx(3)]=e3;d[rIx(4)]=e4;
00351 d[rIx(5)]=e5;d[rIx(6)]=e6;d[rIx(7)]=e7;d[rIx(8)]=e8;d[rIx(9)]=e9;d[rIx(10)]=e10;
00352 d[rIx(11)]=e11;d[rIx(12)]=e12;d[rIx(13)]=e13;d[rIx(14)]=e14;d[rIx(15)]=e15;}
00353
00354
00355 explicit Mat(const TRow& r0)
00356 { assert(M==1); (*this)[0]=r0; }
00357 Mat(const TRow& r0,const TRow& r1)
00358 { assert(M==2);(*this)[0]=r0;(*this)[1]=r1; }
00359 Mat(const TRow& r0,const TRow& r1,const TRow& r2)
00360 { assert(M==3);(*this)[0]=r0;(*this)[1]=r1;(*this)[2]=r2; }
00361 Mat(const TRow& r0,const TRow& r1,const TRow& r2,
00362 const TRow& r3)
00363 { assert(M==4);(*this)[0]=r0;(*this)[1]=r1;(*this)[2]=r2;(*this)[3]=r3; }
00364 Mat(const TRow& r0,const TRow& r1,const TRow& r2,
00365 const TRow& r3,const TRow& r4)
00366 { assert(M==5);(*this)[0]=r0;(*this)[1]=r1;(*this)[2]=r2;
00367 (*this)[3]=r3;(*this)[4]=r4; }
00368 Mat(const TRow& r0,const TRow& r1,const TRow& r2,
00369 const TRow& r3,const TRow& r4,const TRow& r5)
00370 { assert(M==6);(*this)[0]=r0;(*this)[1]=r1;(*this)[2]=r2;
00371 (*this)[3]=r3;(*this)[4]=r4;(*this)[5]=r5; }
00372
00373
00374 template <class EE, int SS> explicit Mat(const Row<N,EE,SS>& r0)
00375 { assert(M==1); (*this)[0]=r0; }
00376 template <class EE, int SS> Mat(const Row<N,EE,SS>& r0,const Row<N,EE,SS>& r1)
00377 { assert(M==2);(*this)[0]=r0;(*this)[1]=r1; }
00378 template <class EE, int SS>
00379 Mat(const Row<N,EE,SS>& r0,const Row<N,EE,SS>& r1,const Row<N,EE,SS>& r2)
00380 { assert(M==3);(*this)[0]=r0;(*this)[1]=r1;(*this)[2]=r2; }
00381 template <class EE, int SS>
00382 Mat(const Row<N,EE,SS>& r0,const Row<N,EE,SS>& r1,const Row<N,EE,SS>& r2,
00383 const Row<N,EE,SS>& r3)
00384 { assert(M==4);(*this)[0]=r0;(*this)[1]=r1;(*this)[2]=r2;(*this)[3]=r3; }
00385 template <class EE, int SS>
00386 Mat(const Row<N,EE,SS>& r0,const Row<N,EE,SS>& r1,const Row<N,EE,SS>& r2,
00387 const Row<N,EE,SS>& r3,const Row<N,EE,SS>& r4)
00388 { assert(M==5);(*this)[0]=r0;(*this)[1]=r1;(*this)[2]=r2;
00389 (*this)[3]=r3;(*this)[4]=r4; }
00390 template <class EE, int SS>
00391 Mat(const Row<N,EE,SS>& r0,const Row<N,EE,SS>& r1,const Row<N,EE,SS>& r2,
00392 const Row<N,EE,SS>& r3,const Row<N,EE,SS>& r4,const Row<N,EE,SS>& r5)
00393 { assert(M==6);(*this)[0]=r0;(*this)[1]=r1;(*this)[2]=r2;
00394 (*this)[3]=r3;(*this)[4]=r4;(*this)[5]=r5; }
00395
00396
00397
00398 explicit Mat(const TCol& r0)
00399 { assert(N==1); (*this)(0)=r0; }
00400 Mat(const TCol& r0,const TCol& r1)
00401 { assert(N==2);(*this)(0)=r0;(*this)(1)=r1; }
00402 Mat(const TCol& r0,const TCol& r1,const TCol& r2)
00403 { assert(N==3);(*this)(0)=r0;(*this)(1)=r1;(*this)(2)=r2; }
00404 Mat(const TCol& r0,const TCol& r1,const TCol& r2,
00405 const TCol& r3)
00406 { assert(N==4);(*this)(0)=r0;(*this)(1)=r1;(*this)(2)=r2;(*this)(3)=r3; }
00407 Mat(const TCol& r0,const TCol& r1,const TCol& r2,
00408 const TCol& r3,const TCol& r4)
00409 { assert(N==5);(*this)(0)=r0;(*this)(1)=r1;(*this)(2)=r2;
00410 (*this)(3)=r3;(*this)(4)=r4; }
00411 Mat(const TCol& r0,const TCol& r1,const TCol& r2,
00412 const TCol& r3,const TCol& r4,const TCol& r5)
00413 { assert(N==6);(*this)(0)=r0;(*this)(1)=r1;(*this)(2)=r2;
00414 (*this)(3)=r3;(*this)(4)=r4;(*this)(5)=r5; }
00415
00416
00417 template <class EE, int SS> explicit Mat(const Vec<M,EE,SS>& r0)
00418 { assert(N==1); (*this)(0)=r0; }
00419 template <class EE, int SS> Mat(const Vec<M,EE,SS>& r0,const Vec<M,EE,SS>& r1)
00420 { assert(N==2);(*this)(0)=r0;(*this)(1)=r1; }
00421 template <class EE, int SS>
00422 Mat(const Vec<M,EE,SS>& r0,const Vec<M,EE,SS>& r1,const Vec<M,EE,SS>& r2)
00423 { assert(N==3);(*this)(0)=r0;(*this)(1)=r1;(*this)(2)=r2; }
00424 template <class EE, int SS>
00425 Mat(const Vec<M,EE,SS>& r0,const Vec<M,EE,SS>& r1,const Vec<M,EE,SS>& r2,
00426 const Vec<M,EE,SS>& r3)
00427 { assert(N==4);(*this)(0)=r0;(*this)(1)=r1;(*this)(2)=r2;(*this)(3)=r3; }
00428 template <class EE, int SS>
00429 Mat(const Vec<M,EE,SS>& r0,const Vec<M,EE,SS>& r1,const Vec<M,EE,SS>& r2,
00430 const Vec<M,EE,SS>& r3,const Vec<M,EE,SS>& r4)
00431 { assert(N==5);(*this)(0)=r0;(*this)(1)=r1;(*this)(2)=r2;
00432 (*this)(3)=r3;(*this)(4)=r4; }
00433 template <class EE, int SS>
00434 Mat(const Vec<M,EE,SS>& r0,const Vec<M,EE,SS>& r1,const Vec<M,EE,SS>& r2,
00435 const Vec<M,EE,SS>& r3,const Vec<M,EE,SS>& r4,const Vec<M,EE,SS>& r5)
00436 { assert(N==6);(*this)(0)=r0;(*this)(1)=r1;(*this)(2)=r2;
00437 (*this)(3)=r3;(*this)(4)=r4;(*this)(5)=r5; }
00438
00439
00440
00441 template <class EE> explicit Mat(const EE* p)
00442 { assert(p); for(int i=0;i<M;++i) (*this)[i]=&p[i*N]; }
00443
00444
00445
00446
00447 template <class EE, int CSS, int RSS> Mat& operator=(const Mat<M,N,EE,CSS,RSS>& mm) {
00448 for (int j=0; j<N; ++j) (*this)(j) = mm(j);
00449 return *this;
00450 }
00451
00452 template <class EE> Mat& operator=(const EE* p) {
00453 assert(p); for(int i=0;i<M;++i) (*this)[i]=&p[i*N];
00454 return *this;
00455 }
00456
00457
00458 template <class EE, int CSS, int RSS> Mat&
00459 operator+=(const Mat<M,N,EE,CSS,RSS>& mm) {
00460 for (int j=0; j<N; ++j) (*this)(j) += mm(j);
00461 return *this;
00462 }
00463 template <class EE, int CSS, int RSS> Mat&
00464 operator+=(const Mat<M,N,negator<EE>,CSS,RSS>& mm) {
00465 for (int j=0; j<N; ++j) (*this)(j) -= -(mm(j));
00466 return *this;
00467 }
00468
00469 template <class EE, int CSS, int RSS> Mat&
00470 operator-=(const Mat<M,N,EE,CSS,RSS>& mm) {
00471 for (int j=0; j<N; ++j) (*this)(j) -= mm(j);
00472 return *this;
00473 }
00474 template <class EE, int CSS, int RSS> Mat&
00475 operator-=(const Mat<M,N,negator<EE>,CSS,RSS>& mm) {
00476 for (int j=0; j<N; ++j) (*this)(j) += -(mm(j));
00477 return *this;
00478 }
00479
00480
00481
00482 template <class EE, int CSS, int RSS> Mat&
00483 operator*=(const Mat<N,N,EE,CSS,RSS>& mm) {
00484 const Mat t(*this);
00485 for (int j=0; j<N; ++j)
00486 for (int i=0; i<M; ++i)
00487 (*this)(i,j) = t[i] * mm(j);
00488 return *this;
00489 }
00490
00491
00492
00493
00494
00495 template <class E2, int CS2, int RS2>
00496 typename Result<Mat<M,N,E2,CS2,RS2> >::Add
00497 conformingAdd(const Mat<M,N,E2,CS2,RS2>& r) const {
00498 typename Result<Mat<M,N,E2,CS2,RS2> >::Add result;
00499 for (int j=0;j<N;++j) result(j) = (*this)(j) + r(j);
00500 return result;
00501 }
00502
00503 template <class E2, int CS2, int RS2>
00504 typename Result<Mat<M,N,E2,CS2,RS2> >::Sub
00505 conformingSubtract(const Mat<M,N,E2,CS2,RS2>& r) const {
00506 typename Result<Mat<M,N,E2,CS2,RS2> >::Sub result;
00507 for (int j=0;j<N;++j) result(j) = (*this)(j) - r(j);
00508 return result;
00509 }
00510
00511 template <class E2, int CS2, int RS2>
00512 typename Mat<M,N,E2,CS2,RS2>::template Result<Mat>::Sub
00513 conformingSubtractFromLeft(const Mat<M,N,E2,CS2,RS2>& l) const {
00514 return l.conformingSubtract(*this);
00515 }
00516
00517
00518
00519 template <class E2, int RS2>
00520 typename Result<SymMat<M,E2,RS2> >::Add
00521 conformingAdd(const SymMat<M,E2,RS2>& sy) const {
00522 assert(M==N);
00523 return sy.conformingAdd(*this);
00524 }
00525
00526 template <class E2, int RS2>
00527 typename Result<SymMat<M,E2,RS2> >::Sub
00528 conformingSubtract(const SymMat<M,E2,RS2>& sy) const {
00529 assert(M==N);
00530 return sy.conformingSubtractFromLeft(*this);
00531 }
00532
00533 template <class E2, int RS2>
00534 typename SymMat<M,E2,RS2>::template Result<Mat>::Sub
00535 conformingSubtractFromLeft(const SymMat<M,E2,RS2>& sy) const {
00536 assert(M==N);
00537 return sy.conformingSubtract(*this);
00538 }
00539
00540
00541 template <int N2, class E2, int CS2, int RS2>
00542 typename Result<Mat<N,N2,E2,CS2,RS2> >::Mul
00543 conformingMultiply(const Mat<N,N2,E2,CS2,RS2>& m) const {
00544 typename Result<Mat<N,N2,E2,CS2,RS2> >::Mul result;
00545 for (int j=0;j<N2;++j)
00546 for (int i=0;i<M;++i)
00547 result(i,j) = (*this)[i].conformingMultiply(m(j));
00548 return result;
00549 }
00550
00551 template <int M2, class E2, int CS2, int RS2>
00552 typename Mat<M2,M,E2,CS2,RS2>::template Result<Mat>::Mul
00553 conformingMultiplyFromLeft(const Mat<M2,M,E2,CS2,RS2>& m) const {
00554 return m.conformingMultiply(*this);
00555 }
00556
00557
00558 template <int M2, class E2, int CS2, int RS2>
00559 typename Result<Mat<M2,N,E2,CS2,RS2> >::Dvd
00560 conformingDivide(const Mat<M2,N,E2,CS2,RS2>& m) const {
00561 return conformingMultiply(m.invert());
00562 }
00563
00564 template <int M2, class E2, int CS2, int RS2>
00565 typename Mat<M2,N,E2,CS2,RS2>::template Result<Mat>::Dvd
00566 conformingDivideFromLeft(const Mat<M2,N,E2,CS2,RS2>& m) const {
00567 return m.conformingMultiply((*this).invert());
00568 }
00569
00570 const TRow& operator[](int i) const { return row(i); }
00571 TRow& operator[](int i) { return row(i); }
00572 const TCol& operator()(int j) const { return col(j); }
00573 TCol& operator()(int j) { return col(j); }
00574
00575 const E& operator()(int i,int j) const { return elt(i,j); }
00576 E& operator()(int i,int j) { return elt(i,j); }
00577
00578
00579 ScalarNormSq normSqr() const { return scalarNormSqr(); }
00580 typename CNT<ScalarNormSq>::TSqrt
00581 norm() const { return CNT<ScalarNormSq>::sqrt(scalarNormSqr()); }
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596 TNormalize normalize() const {
00597 if (CNT<E>::IsScalar) {
00598 return castAwayNegatorIfAny() / (SignInterpretation*norm());
00599 } else {
00600 TNormalize elementwiseNormalized;
00601
00602 for (int j=0; j<N; ++j)
00603 elementwiseNormalized(j) = (*this)(j).normalize();
00604 return elementwiseNormalized;
00605 }
00606 }
00607
00608
00609
00610 TInvert invert() const;
00611
00612 const Mat& operator+() const { return *this; }
00613 const TNeg& operator-() const { return negate(); }
00614 TNeg& operator-() { return updNegate(); }
00615 const THerm& operator~() const { return transpose(); }
00616 THerm& operator~() { return updTranspose(); }
00617
00618 const TNeg& negate() const { return *reinterpret_cast<const TNeg*>(this); }
00619 TNeg& updNegate() { return *reinterpret_cast<TNeg*>(this); }
00620
00621 const THerm& transpose() const { return *reinterpret_cast<const THerm*>(this); }
00622 THerm& updTranspose() { return *reinterpret_cast<THerm*>(this); }
00623
00624 const TPosTrans& positionalTranspose() const
00625 { return *reinterpret_cast<const TPosTrans*>(this); }
00626 TPosTrans& updPositionalTranspose()
00627 { return *reinterpret_cast<TPosTrans*>(this); }
00628
00629
00630
00631
00632
00633 const TReal& real() const { return *reinterpret_cast<const TReal*>(this); }
00634 TReal& real() { return *reinterpret_cast< TReal*>(this); }
00635
00636
00637
00638
00639
00640
00641
00642
00643 const TImag& imag() const {
00644 const int offs = ImagOffset;
00645 const Precision* p = reinterpret_cast<const Precision*>(this);
00646 return *reinterpret_cast<const TImag*>(p+offs);
00647 }
00648 TImag& imag() {
00649 const int offs = ImagOffset;
00650 Precision* p = reinterpret_cast<Precision*>(this);
00651 return *reinterpret_cast<TImag*>(p+offs);
00652 }
00653
00654 const TWithoutNegator& castAwayNegatorIfAny() const {return *reinterpret_cast<const TWithoutNegator*>(this);}
00655 TWithoutNegator& updCastAwayNegatorIfAny() {return *reinterpret_cast<TWithoutNegator*>(this);}
00656
00657 const TRow& row(int i) const {
00658 SimTK_INDEXCHECK(i,M, "Mat::row[i]");
00659 return *reinterpret_cast<const TRow*>(&d[i*RS]);
00660 }
00661 TRow& row(int i) {
00662 SimTK_INDEXCHECK(i,M, "Mat::row[i]");
00663 return *reinterpret_cast<TRow*>(&d[i*RS]);
00664 }
00665
00666 const TCol& col(int j) const {
00667 SimTK_INDEXCHECK(j,N, "Mat::col(j)");
00668 return *reinterpret_cast<const TCol*>(&d[j*CS]);
00669 }
00670 TCol& col(int j) {
00671 SimTK_INDEXCHECK(j,N, "Mat::col(j)");
00672 return *reinterpret_cast<TCol*>(&d[j*CS]);
00673 }
00674
00675 const E& elt(int i, int j) const {
00676 SimTK_INDEXCHECK(i,M, "Mat::elt(i,j)");
00677 SimTK_INDEXCHECK(j,N, "Mat::elt(i,j)");
00678 return d[i*RS+j*CS];
00679 }
00680 E& elt(int i, int j) {
00681 SimTK_INDEXCHECK(i,M, "Mat::elt(i,j)");
00682 SimTK_INDEXCHECK(j,N, "Mat::elt(i,j)");
00683 return d[i*RS+j*CS];
00684 }
00685
00686 const TDiag& diag() const { return *reinterpret_cast<const TDiag*>(d); }
00687 TDiag& diag() { return *reinterpret_cast<TDiag*>(d); }
00688
00689 EStandard trace() const {return diag().sum();}
00690
00691
00692
00693
00694
00695
00696
00697
00698 template <class EE> Mat<M,N, typename CNT<E>::template Result<EE>::Mul>
00699 scalarMultiply(const EE& e) const {
00700 Mat<M,N, typename CNT<E>::template Result<EE>::Mul> result;
00701 for (int j=0; j<N; ++j) result(j) = (*this)(j).scalarMultiply(e);
00702 return result;
00703 }
00704 template <class EE> Mat<M,N, typename CNT<EE>::template Result<E>::Mul>
00705 scalarMultiplyFromLeft(const EE& e) const {
00706 Mat<M,N, typename CNT<EE>::template Result<E>::Mul> result;
00707 for (int j=0; j<N; ++j) result(j) = (*this)(j).scalarMultiplyFromLeft(e);
00708 return result;
00709 }
00710
00711
00712
00713 template <class EE> Mat<M,N, typename CNT<E>::template Result<EE>::Dvd>
00714 scalarDivide(const EE& e) const {
00715 Mat<M,N, typename CNT<E>::template Result<EE>::Dvd> result;
00716 for (int j=0; j<N; ++j) result(j) = (*this)(j).scalarDivide(e);
00717 return result;
00718 }
00719 template <class EE> Mat<M,N, typename CNT<EE>::template Result<E>::Dvd>
00720 scalarDivideFromLeft(const EE& e) const {
00721 Mat<M,N, typename CNT<EE>::template Result<E>::Dvd> result;
00722 for (int j=0; j<N; ++j) result(j) = (*this)(j).scalarDivideFromLeft(e);
00723 return result;
00724 }
00725
00726
00727 template <class EE> Mat<M,N, typename CNT<E>::template Result<EE>::Add>
00728 scalarAdd(const EE& e) const {
00729 Mat<M,N, typename CNT<E>::template Result<EE>::Add> result(*this);
00730 result.diag() += e;
00731 return result;
00732 }
00733
00734
00735 template <class EE> Mat<M,N, typename CNT<E>::template Result<EE>::Sub>
00736 scalarSubtract(const EE& e) const {
00737 Mat<M,N, typename CNT<E>::template Result<EE>::Sub> result(*this);
00738 result.diag() -= e;
00739 return result;
00740 }
00741
00742 template <class EE> Mat<M,N, typename CNT<EE>::template Result<E>::Sub>
00743 scalarSubtractFromLeft(const EE& e) const {
00744 Mat<M,N, typename CNT<EE>::template Result<E>::Sub> result(-(*this));
00745 result.diag() += e;
00746 return result;
00747 }
00748
00749
00750
00751
00752 template <class EE> Mat& operator =(const EE& e) {return scalarEq(e);}
00753 template <class EE> Mat& operator+=(const EE& e) {return scalarPlusEq(e);}
00754 template <class EE> Mat& operator-=(const EE& e) {return scalarMinusEq(e);}
00755 template <class EE> Mat& operator*=(const EE& e) {return scalarTimesEq(e);}
00756 template <class EE> Mat& operator/=(const EE& e) {return scalarDivideEq(e);}
00757
00758
00759
00760 template <class EE> Mat& scalarEq(const EE& ee)
00761 { for(int j=0; j<N; ++j) (*this)(j).scalarEq(EE(0));
00762 diag().scalarEq(ee);
00763 return *this; }
00764
00765 template <class EE> Mat& scalarPlusEq(const EE& ee)
00766 { diag().scalarPlusEq(ee); return *this; }
00767
00768 template <class EE> Mat& scalarMinusEq(const EE& ee)
00769 { diag().scalarMinusEq(ee); return *this; }
00770
00771 template <class EE> Mat& scalarMinusEqFromLeft(const EE& ee)
00772 { scalarTimesEq(E(-1)); diag().scalarAdd(ee); return *this; }
00773
00774 template <class EE> Mat& scalarTimesEq(const EE& ee)
00775 { for(int j=0; j<N; ++j) (*this)(j).scalarTimesEq(ee); return *this; }
00776 template <class EE> Mat& scalarTimesEqFromLeft(const EE& ee)
00777 { for(int j=0; j<N; ++j) (*this)(j).scalarTimesEqFromLeft(ee); return *this; }
00778
00779 template <class EE> Mat& scalarDivideEq(const EE& ee)
00780 { for(int j=0; j<N; ++j) (*this)(j).scalarDivideEq(ee); return *this; }
00781 template <class EE> Mat& scalarDivideEqFromLeft(const EE& ee)
00782 { for(int j=0; j<N; ++j) (*this)(j).scalarDivideEqFromLeft(ee); return *this; }
00783
00784 void setToNaN() {
00785 for (int j=0; j<N; ++j)
00786 (*this)(j).setToNaN();
00787 }
00788
00789 void setToZero() {
00790 for (int j=0; j<N; ++j)
00791 (*this)(j).setToZero();
00792 }
00793
00794
00795
00796
00797 template <int MM, int NN> struct SubMat {
00798 typedef Mat<MM,NN,ELT,CS,RS> Type;
00799 };
00800
00801 template <int MM, int NN>
00802 const typename SubMat<MM,NN>::Type& getSubMat(int i, int j) const {
00803 assert(0 <= i && i + MM <= M);
00804 assert(0 <= j && j + NN <= N);
00805 return SubMat<MM,NN>::Type::getAs(&(*this)(i,j));
00806 }
00807 template <int MM, int NN>
00808 typename SubMat<MM,NN>::Type& updSubMat(int i, int j) {
00809 assert(0 <= i && i + MM <= M);
00810 assert(0 <= j && j + NN <= N);
00811 return SubMat<MM,NN>::Type::updAs(&(*this)(i,j));
00812 }
00813
00814
00817 TDropRow dropRow(int i) const {
00818 assert(0 <= i && i < M);
00819 TDropRow out;
00820 for (int r=0, nxt=0; r<M-1; ++r, ++nxt) {
00821 if (nxt==i) ++nxt;
00822 out[r] = (*this)[nxt];
00823 }
00824 return out;
00825 }
00826
00829 TDropCol dropCol(int j) const {
00830 assert(0 <= j && j < N);
00831 TDropCol out;
00832 for (int c=0, nxt=0; c<N-1; ++c, ++nxt) {
00833 if (nxt==j) ++nxt;
00834 out(c) = (*this)(nxt);
00835 }
00836 return out;
00837 }
00838
00842 TDropRowCol dropRowCol(int i, int j) const {
00843 assert(0 <= i && i < M);
00844 assert(0 <= j && j < N);
00845 TDropRowCol out;
00846 for (int c=0, nxtc=0; c<N-1; ++c, ++nxtc) {
00847 if (nxtc==j) ++nxtc;
00848 for (int r=0, nxtr=0; r<M-1; ++r, ++nxtr) {
00849 if (nxtr==i) ++nxtr;
00850 out(r,c) = (*this)(nxtr,nxtc);
00851 }
00852 }
00853 return out;
00854 }
00855
00859 template <class EE, int SS>
00860 TAppendRow appendRow(const Row<N,EE,SS>& row) const {
00861 TAppendRow out;
00862 out.updSubMat<M,N>(0,0) = (*this);
00863 out[M] = row;
00864 return out;
00865 }
00866
00870 template <class EE, int SS>
00871 TAppendCol appendCol(const Vec<M,EE,SS>& col) const {
00872 TAppendCol out;
00873 out.updSubMat<M,N>(0,0) = (*this);
00874 out(N) = col;
00875 return out;
00876 }
00877
00884 template <class ER, int SR, class EC, int SC>
00885 TAppendRowCol appendRowCol(const Row<N+1,ER,SR>& row,
00886 const Vec<M+1,EC,SC>& col) const
00887 {
00888 TAppendRowCol out;
00889 out.updSubMat<M,N>(0,0) = (*this);
00890 out[M].updSubRow<N>(0) = row.updSubRow<N>(0);
00891 out(N) = col;
00892 return out;
00893 }
00894
00900 template <class EE, int SS>
00901 TAppendRow insertRow(int i, const Row<N,EE,SS>& row) const {
00902 assert(0 <= i && i <= M);
00903 if (i==M) return appendRow(row);
00904 TAppendRow out;
00905 for (int r=0, nxt=0; r<M; ++r, ++nxt) {
00906 if (nxt==i) out[nxt++] = row;
00907 out[nxt] = (*this)[r];
00908 }
00909 return out;
00910 }
00911
00917 template <class EE, int SS>
00918 TAppendCol insertCol(int j, const Vec<M,EE,SS>& col) const {
00919 assert(0 <= j && j <= N);
00920 if (j==N) return appendCol(col);
00921 TAppendCol out;
00922 for (int c=0, nxt=0; c<N; ++c, ++nxt) {
00923 if (nxt==j) out(nxt++) = col;
00924 out(nxt) = (*this)(c);
00925 }
00926 return out;
00927 }
00928
00936 template <class ER, int SR, class EC, int SC>
00937 TAppendRowCol insertRowCol(int i, int j, const Row<N+1,ER,SR>& row,
00938 const Vec<M+1,EC,SC>& col) const {
00939 assert(0 <= i && i <= M);
00940 assert(0 <= j && j <= N);
00941 TAppendRowCol out;
00942 for (int c=0, nxtc=0; c<N; ++c, ++nxtc) {
00943 if (nxtc==i) ++nxtc;
00944 for (int r=0, nxtr=0; r<M; ++r, ++nxtr) {
00945 if (nxtr==i) ++nxtr;
00946 out(nxtr,nxtc) = (*this)(r,c);
00947 }
00948 }
00949 out[i] = row;
00950 out(j) = col;
00951 return out;
00952 }
00953
00954
00955 static const Mat& getAs(const ELT* p) {return *reinterpret_cast<const Mat*>(p);}
00956 static Mat& updAs(ELT* p) {return *reinterpret_cast<Mat*>(p);}
00957
00958
00959 static Mat<M,N,ELT,M,1> getNaN() {
00960 Mat<M,N,ELT,M,1> m;
00961 m.setToNaN();
00962 return m;
00963 }
00964
00966 bool isNaN() const {
00967 for (int j=0; j<N; ++j)
00968 if (this->col(j).isNaN())
00969 return true;
00970 return false;
00971 }
00972
00975 bool isInf() const {
00976 bool seenInf = false;
00977 for (int j=0; j<N; ++j) {
00978 if (!this->col(j).isFinite()) {
00979 if (!this->col(j).isInf())
00980 return false;
00981 seenInf = true;
00982 }
00983 }
00984 return seenInf;
00985 }
00986
00988 bool isFinite() const {
00989 for (int j=0; j<N; ++j)
00990 if (!this->col(j).isFinite())
00991 return false;
00992 return true;
00993 }
00994
00997 static double getDefaultTolerance() {return MinDim*CNT<ELT>::getDefaultTolerance();}
00998
01001 template <class E2, int CS2, int RS2>
01002 bool isNumericallyEqual(const Mat<M,N,E2,CS2,RS2>& m, double tol) const {
01003 for (int j=0; j < N; ++j)
01004 if (!(*this)(j).isNumericallyEqual(m(j), tol))
01005 return false;
01006 return true;
01007 }
01008
01012 template <class E2, int CS2, int RS2>
01013 bool isNumericallyEqual(const Mat<M,N,E2,CS2,RS2>& m) const {
01014 const double tol = std::max(getDefaultTolerance(),m.getDefaultTolerance());
01015 return isNumericallyEqual(m, tol);
01016 }
01017
01023 bool isNumericallyEqual
01024 (const ELT& e,
01025 double tol = getDefaultTolerance()) const
01026 {
01027 for (int i=0; i<M; ++i)
01028 for (int j=0; j<N; ++j) {
01029 if (i==j) {
01030 if (!CNT<ELT>::isNumericallyEqual((*this)(i,i), e, tol))
01031 return false;
01032 } else {
01033
01034 if (!CNT<ELT>::isNumericallyEqual((*this)(i,j), ELT(0), tol))
01035 return false;
01036 }
01037 }
01038 return true;
01039 }
01040
01048 bool isNumericallySymmetric(double tol = getDefaultTolerance()) const {
01049 if (M != N) return false;
01050 for (int j=0; j<M; ++j)
01051 for (int i=j; i<M; ++i)
01052 if (!CNT<ELT>::isNumericallyEqual(elt(j,i), CNT<ELT>::transpose(elt(i,j)), tol))
01053 return false;
01054 return true;
01055 }
01056
01063 bool isExactlySymmetric() const {
01064 if (M != N) return false;
01065 for (int j=0; j<M; ++j)
01066 for (int i=j; i<M; ++i)
01067 if (elt(j,i) != CNT<ELT>::transpose(elt(i,j)))
01068 return false;
01069 return true;
01070 }
01071
01072 TRow sum() const {
01073 TRow temp;
01074 for (int j = 0; j < N; ++j)
01075 temp[j] = col(j).sum();
01076 return temp;
01077 }
01078
01079 private:
01080 E d[NActualElements];
01081
01082
01083
01084
01085
01086 int rIx(int k) const {
01087 const int row = k / N;
01088 const int col = k % N;
01089 return row*RS + col*CS;
01090 }
01091 };
01092
01094
01095
01097
01098 template <int M, int N, class EL, int CSL, int RSL, class ER, int CSR, int RSR> inline
01099 typename Mat<M,N,EL,CSL,RSL>::template Result<Mat<M,N,ER,CSR,RSR> >::Add
01100 operator+(const Mat<M,N,EL,CSL,RSL>& l, const Mat<M,N,ER,CSR,RSR>& r) {
01101 return Mat<M,N,EL,CSL,RSL>::template Result<Mat<M,N,ER,CSR,RSR> >
01102 ::AddOp::perform(l,r);
01103 }
01104
01105 template <int M, int N, class EL, int CSL, int RSL, class ER, int CSR, int RSR> inline
01106 typename Mat<M,N,EL,CSL,RSL>::template Result<Mat<M,N,ER,CSR,RSR> >::Sub
01107 operator-(const Mat<M,N,EL,CSL,RSL>& l, const Mat<M,N,ER,CSR,RSR>& r) {
01108 return Mat<M,N,EL,CSL,RSL>::template Result<Mat<M,N,ER,CSR,RSR> >
01109 ::SubOp::perform(l,r);
01110 }
01111
01112
01113 template <int M, int N, class EL, int CSL, int RSL, int P, class ER, int CSR, int RSR> inline
01114 typename Mat<M,N,EL,CSL,RSL>::template Result<Mat<N,P,ER,CSR,RSR> >::Mul
01115 operator*(const Mat<M,N,EL,CSL,RSL>& l, const Mat<N,P,ER,CSR,RSR>& r) {
01116 return Mat<M,N,EL,CSL,RSL>::template Result<Mat<N,P,ER,CSR,RSR> >
01117 ::MulOp::perform(l,r);
01118 }
01119
01120
01121
01122 template <int M, int N, class EL, int CSL, int RSL, int MM, int NN, class ER, int CSR, int RSR> inline
01123 typename Mat<M,N,EL,CSL,RSL>::template Result<Mat<MM,NN,ER,CSR,RSR> >::MulNon
01124 operator*(const Mat<M,N,EL,CSL,RSL>& l, const Mat<MM,NN,ER,CSR,RSR>& r) {
01125 return Mat<M,N,EL,CSL,RSL>::template Result<Mat<MM,NN,ER,CSR,RSR> >
01126 ::MulOpNonConforming::perform(l,r);
01127 }
01128
01129 template <int M, int N, class EL, int CSL, int RSL, class ER, int CSR, int RSR> inline
01130 bool operator==(const Mat<M,N,EL,CSL,RSL>& l, const Mat<M,N,ER,CSR,RSR>& r) {
01131 for (int j=0; j<N; ++j)
01132 if (l(j) != r(j)) return false;
01133 return true;
01134 }
01135 template <int M, int N, class EL, int CSL, int RSL, class ER, int CSR, int RSR> inline
01136 bool operator!=(const Mat<M,N,EL,CSL,RSL>& l, const Mat<M,N,ER,CSR,RSR>& r) {
01137 return !(l==r);
01138 }
01139
01140
01142
01144
01145
01146
01147
01148 template <int M, int N, class E, int CS, int RS> inline
01149 typename Mat<M,N,E,CS,RS>::template Result<float>::Mul
01150 operator*(const Mat<M,N,E,CS,RS>& l, const float& r)
01151 { return Mat<M,N,E,CS,RS>::template Result<float>::MulOp::perform(l,r); }
01152 template <int M, int N, class E, int CS, int RS> inline
01153 typename Mat<M,N,E,CS,RS>::template Result<float>::Mul
01154 operator*(const float& l, const Mat<M,N,E,CS,RS>& r) {return r*l;}
01155
01156 template <int M, int N, class E, int CS, int RS> inline
01157 typename Mat<M,N,E,CS,RS>::template Result<double>::Mul
01158 operator*(const Mat<M,N,E,CS,RS>& l, const double& r)
01159 { return Mat<M,N,E,CS,RS>::template Result<double>::MulOp::perform(l,r); }
01160 template <int M, int N, class E, int CS, int RS> inline
01161 typename Mat<M,N,E,CS,RS>::template Result<double>::Mul
01162 operator*(const double& l, const Mat<M,N,E,CS,RS>& r) {return r*l;}
01163
01164 template <int M, int N, class E, int CS, int RS> inline
01165 typename Mat<M,N,E,CS,RS>::template Result<long double>::Mul
01166 operator*(const Mat<M,N,E,CS,RS>& l, const long double& r)
01167 { return Mat<M,N,E,CS,RS>::template Result<long double>::MulOp::perform(l,r); }
01168 template <int M, int N, class E, int CS, int RS> inline
01169 typename Mat<M,N,E,CS,RS>::template Result<long double>::Mul
01170 operator*(const long double& l, const Mat<M,N,E,CS,RS>& r) {return r*l;}
01171
01172
01173 template <int M, int N, class E, int CS, int RS> inline
01174 typename Mat<M,N,E,CS,RS>::template Result<typename CNT<E>::Precision>::Mul
01175 operator*(const Mat<M,N,E,CS,RS>& l, int r) {return l * (typename CNT<E>::Precision)r;}
01176 template <int M, int N, class E, int CS, int RS> inline
01177 typename Mat<M,N,E,CS,RS>::template Result<typename CNT<E>::Precision>::Mul
01178 operator*(int l, const Mat<M,N,E,CS,RS>& r) {return r * (typename CNT<E>::Precision)l;}
01179
01180
01181
01182
01183 template <int M, int N, class E, int CS, int RS, class R> inline
01184 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Mul
01185 operator*(const Mat<M,N,E,CS,RS>& l, const std::complex<R>& r)
01186 { return Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::MulOp::perform(l,r); }
01187 template <int M, int N, class E, int CS, int RS, class R> inline
01188 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Mul
01189 operator*(const std::complex<R>& l, const Mat<M,N,E,CS,RS>& r) {return r*l;}
01190
01191
01192 template <int M, int N, class E, int CS, int RS, class R> inline
01193 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Mul
01194 operator*(const Mat<M,N,E,CS,RS>& l, const conjugate<R>& r) {return l*(std::complex<R>)r;}
01195 template <int M, int N, class E, int CS, int RS, class R> inline
01196 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Mul
01197 operator*(const conjugate<R>& l, const Mat<M,N,E,CS,RS>& r) {return r*(std::complex<R>)l;}
01198
01199
01200 template <int M, int N, class E, int CS, int RS, class R> inline
01201 typename Mat<M,N,E,CS,RS>::template Result<typename negator<R>::StdNumber>::Mul
01202 operator*(const Mat<M,N,E,CS,RS>& l, const negator<R>& r) {return l * (typename negator<R>::StdNumber)(R)r;}
01203 template <int M, int N, class E, int CS, int RS, class R> inline
01204 typename Mat<M,N,E,CS,RS>::template Result<typename negator<R>::StdNumber>::Mul
01205 operator*(const negator<R>& l, const Mat<M,N,E,CS,RS>& r) {return r * (typename negator<R>::StdNumber)(R)l;}
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215 template <int M, int N, class E, int CS, int RS> inline
01216 typename Mat<M,N,E,CS,RS>::template Result<float>::Dvd
01217 operator/(const Mat<M,N,E,CS,RS>& l, const float& r)
01218 { return Mat<M,N,E,CS,RS>::template Result<float>::DvdOp::perform(l,r); }
01219
01220 template <int M, int N, class E, int CS, int RS> inline
01221 typename CNT<float>::template Result<Mat<M,N,E,CS,RS> >::Dvd
01222 operator/(const float& l, const Mat<M,N,E,CS,RS>& r)
01223 { return l * r.invert(); }
01224
01225 template <int M, int N, class E, int CS, int RS> inline
01226 typename Mat<M,N,E,CS,RS>::template Result<double>::Dvd
01227 operator/(const Mat<M,N,E,CS,RS>& l, const double& r)
01228 { return Mat<M,N,E,CS,RS>::template Result<double>::DvdOp::perform(l,r); }
01229
01230 template <int M, int N, class E, int CS, int RS> inline
01231 typename CNT<double>::template Result<Mat<M,N,E,CS,RS> >::Dvd
01232 operator/(const double& l, const Mat<M,N,E,CS,RS>& r)
01233 { return l * r.invert(); }
01234
01235 template <int M, int N, class E, int CS, int RS> inline
01236 typename Mat<M,N,E,CS,RS>::template Result<long double>::Dvd
01237 operator/(const Mat<M,N,E,CS,RS>& l, const long double& r)
01238 { return Mat<M,N,E,CS,RS>::template Result<long double>::DvdOp::perform(l,r); }
01239
01240 template <int M, int N, class E, int CS, int RS> inline
01241 typename CNT<long double>::template Result<Mat<M,N,E,CS,RS> >::Dvd
01242 operator/(const long double& l, const Mat<M,N,E,CS,RS>& r)
01243 { return l * r.invert(); }
01244
01245
01246 template <int M, int N, class E, int CS, int RS> inline
01247 typename Mat<M,N,E,CS,RS>::template Result<typename CNT<E>::Precision>::Dvd
01248 operator/(const Mat<M,N,E,CS,RS>& l, int r)
01249 { return l / (typename CNT<E>::Precision)r; }
01250
01251 template <int M, int N, class E, int CS, int RS> inline
01252 typename CNT<typename CNT<E>::Precision>::template Result<Mat<M,N,E,CS,RS> >::Dvd
01253 operator/(int l, const Mat<M,N,E,CS,RS>& r)
01254 { return (typename CNT<E>::Precision)l / r; }
01255
01256
01257
01258
01259
01260 template <int M, int N, class E, int CS, int RS, class R> inline
01261 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Dvd
01262 operator/(const Mat<M,N,E,CS,RS>& l, const std::complex<R>& r)
01263 { return Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::DvdOp::perform(l,r); }
01264 template <int M, int N, class E, int CS, int RS, class R> inline
01265 typename CNT<std::complex<R> >::template Result<Mat<M,N,E,CS,RS> >::Dvd
01266 operator/(const std::complex<R>& l, const Mat<M,N,E,CS,RS>& r)
01267 { return CNT<std::complex<R> >::template Result<Mat<M,N,E,CS,RS> >::DvdOp::perform(l,r); }
01268
01269
01270 template <int M, int N, class E, int CS, int RS, class R> inline
01271 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Dvd
01272 operator/(const Mat<M,N,E,CS,RS>& l, const conjugate<R>& r) {return l/(std::complex<R>)r;}
01273 template <int M, int N, class E, int CS, int RS, class R> inline
01274 typename CNT<std::complex<R> >::template Result<Mat<M,N,E,CS,RS> >::Dvd
01275 operator/(const conjugate<R>& l, const Mat<M,N,E,CS,RS>& r) {return (std::complex<R>)l/r;}
01276
01277
01278 template <int M, int N, class E, int CS, int RS, class R> inline
01279 typename Mat<M,N,E,CS,RS>::template Result<typename negator<R>::StdNumber>::Dvd
01280 operator/(const Mat<M,N,E,CS,RS>& l, const negator<R>& r) {return l/(typename negator<R>::StdNumber)(R)r;}
01281 template <int M, int N, class E, int CS, int RS, class R> inline
01282 typename CNT<R>::template Result<Mat<M,N,E,CS,RS> >::Dvd
01283 operator/(const negator<R>& l, const Mat<M,N,E,CS,RS>& r) {return (typename negator<R>::StdNumber)(R)l/r;}
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293 template <int M, int N, class E, int CS, int RS> inline
01294 typename Mat<M,N,E,CS,RS>::template Result<float>::Add
01295 operator+(const Mat<M,N,E,CS,RS>& l, const float& r)
01296 { return Mat<M,N,E,CS,RS>::template Result<float>::AddOp::perform(l,r); }
01297 template <int M, int N, class E, int CS, int RS> inline
01298 typename Mat<M,N,E,CS,RS>::template Result<float>::Add
01299 operator+(const float& l, const Mat<M,N,E,CS,RS>& r) {return r+l;}
01300
01301 template <int M, int N, class E, int CS, int RS> inline
01302 typename Mat<M,N,E,CS,RS>::template Result<double>::Add
01303 operator+(const Mat<M,N,E,CS,RS>& l, const double& r)
01304 { return Mat<M,N,E,CS,RS>::template Result<double>::AddOp::perform(l,r); }
01305 template <int M, int N, class E, int CS, int RS> inline
01306 typename Mat<M,N,E,CS,RS>::template Result<double>::Add
01307 operator+(const double& l, const Mat<M,N,E,CS,RS>& r) {return r+l;}
01308
01309 template <int M, int N, class E, int CS, int RS> inline
01310 typename Mat<M,N,E,CS,RS>::template Result<long double>::Add
01311 operator+(const Mat<M,N,E,CS,RS>& l, const long double& r)
01312 { return Mat<M,N,E,CS,RS>::template Result<long double>::AddOp::perform(l,r); }
01313 template <int M, int N, class E, int CS, int RS> inline
01314 typename Mat<M,N,E,CS,RS>::template Result<long double>::Add
01315 operator+(const long double& l, const Mat<M,N,E,CS,RS>& r) {return r+l;}
01316
01317
01318 template <int M, int N, class E, int CS, int RS> inline
01319 typename Mat<M,N,E,CS,RS>::template Result<typename CNT<E>::Precision>::Add
01320 operator+(const Mat<M,N,E,CS,RS>& l, int r) {return l + (typename CNT<E>::Precision)r;}
01321 template <int M, int N, class E, int CS, int RS> inline
01322 typename Mat<M,N,E,CS,RS>::template Result<typename CNT<E>::Precision>::Add
01323 operator+(int l, const Mat<M,N,E,CS,RS>& r) {return r + (typename CNT<E>::Precision)l;}
01324
01325
01326
01327
01328 template <int M, int N, class E, int CS, int RS, class R> inline
01329 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Add
01330 operator+(const Mat<M,N,E,CS,RS>& l, const std::complex<R>& r)
01331 { return Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::AddOp::perform(l,r); }
01332 template <int M, int N, class E, int CS, int RS, class R> inline
01333 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Add
01334 operator+(const std::complex<R>& l, const Mat<M,N,E,CS,RS>& r) {return r+l;}
01335
01336
01337 template <int M, int N, class E, int CS, int RS, class R> inline
01338 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Add
01339 operator+(const Mat<M,N,E,CS,RS>& l, const conjugate<R>& r) {return l+(std::complex<R>)r;}
01340 template <int M, int N, class E, int CS, int RS, class R> inline
01341 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Add
01342 operator+(const conjugate<R>& l, const Mat<M,N,E,CS,RS>& r) {return r+(std::complex<R>)l;}
01343
01344
01345 template <int M, int N, class E, int CS, int RS, class R> inline
01346 typename Mat<M,N,E,CS,RS>::template Result<typename negator<R>::StdNumber>::Add
01347 operator+(const Mat<M,N,E,CS,RS>& l, const negator<R>& r) {return l + (typename negator<R>::StdNumber)(R)r;}
01348 template <int M, int N, class E, int CS, int RS, class R> inline
01349 typename Mat<M,N,E,CS,RS>::template Result<typename negator<R>::StdNumber>::Add
01350 operator+(const negator<R>& l, const Mat<M,N,E,CS,RS>& r) {return r + (typename negator<R>::StdNumber)(R)l;}
01351
01352
01353
01354
01355 template <int M, int N, class E, int CS, int RS> inline
01356 typename Mat<M,N,E,CS,RS>::template Result<float>::Sub
01357 operator-(const Mat<M,N,E,CS,RS>& l, const float& r)
01358 { return Mat<M,N,E,CS,RS>::template Result<float>::SubOp::perform(l,r); }
01359 template <int M, int N, class E, int CS, int RS> inline
01360 typename CNT<float>::template Result<Mat<M,N,E,CS,RS> >::Sub
01361 operator-(const float& l, const Mat<M,N,E,CS,RS>& r)
01362 { return CNT<float>::template Result<Mat<M,N,E,CS,RS> >::SubOp::perform(l,r); }
01363
01364 template <int M, int N, class E, int CS, int RS> inline
01365 typename Mat<M,N,E,CS,RS>::template Result<double>::Sub
01366 operator-(const Mat<M,N,E,CS,RS>& l, const double& r)
01367 { return Mat<M,N,E,CS,RS>::template Result<double>::SubOp::perform(l,r); }
01368 template <int M, int N, class E, int CS, int RS> inline
01369 typename CNT<double>::template Result<Mat<M,N,E,CS,RS> >::Sub
01370 operator-(const double& l, const Mat<M,N,E,CS,RS>& r)
01371 { return CNT<double>::template Result<Mat<M,N,E,CS,RS> >::SubOp::perform(l,r); }
01372
01373 template <int M, int N, class E, int CS, int RS> inline
01374 typename Mat<M,N,E,CS,RS>::template Result<long double>::Sub
01375 operator-(const Mat<M,N,E,CS,RS>& l, const long double& r)
01376 { return Mat<M,N,E,CS,RS>::template Result<long double>::SubOp::perform(l,r); }
01377 template <int M, int N, class E, int CS, int RS> inline
01378 typename CNT<long double>::template Result<Mat<M,N,E,CS,RS> >::Sub
01379 operator-(const long double& l, const Mat<M,N,E,CS,RS>& r)
01380 { return CNT<long double>::template Result<Mat<M,N,E,CS,RS> >::SubOp::perform(l,r); }
01381
01382
01383 template <int M, int N, class E, int CS, int RS> inline
01384 typename Mat<M,N,E,CS,RS>::template Result<typename CNT<E>::Precision>::Sub
01385 operator-(const Mat<M,N,E,CS,RS>& l, int r) {return l - (typename CNT<E>::Precision)r;}
01386 template <int M, int N, class E, int CS, int RS> inline
01387 typename CNT<typename CNT<E>::Precision>::template Result<Mat<M,N,E,CS,RS> >::Sub
01388 operator-(int l, const Mat<M,N,E,CS,RS>& r) {return (typename CNT<E>::Precision)l - r;}
01389
01390
01391
01392
01393
01394 template <int M, int N, class E, int CS, int RS, class R> inline
01395 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Sub
01396 operator-(const Mat<M,N,E,CS,RS>& l, const std::complex<R>& r)
01397 { return Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::SubOp::perform(l,r); }
01398 template <int M, int N, class E, int CS, int RS, class R> inline
01399 typename CNT<std::complex<R> >::template Result<Mat<M,N,E,CS,RS> >::Sub
01400 operator-(const std::complex<R>& l, const Mat<M,N,E,CS,RS>& r)
01401 { return CNT<std::complex<R> >::template Result<Mat<M,N,E,CS,RS> >::SubOp::perform(l,r); }
01402
01403
01404 template <int M, int N, class E, int CS, int RS, class R> inline
01405 typename Mat<M,N,E,CS,RS>::template Result<std::complex<R> >::Sub
01406 operator-(const Mat<M,N,E,CS,RS>& l, const conjugate<R>& r) {return l-(std::complex<R>)r;}
01407 template <int M, int N, class E, int CS, int RS, class R> inline
01408 typename CNT<std::complex<R> >::template Result<Mat<M,N,E,CS,RS> >::Sub
01409 operator-(const conjugate<R>& l, const Mat<M,N,E,CS,RS>& r) {return (std::complex<R>)l-r;}
01410
01411
01412 template <int M, int N, class E, int CS, int RS, class R> inline
01413 typename Mat<M,N,E,CS,RS>::template Result<typename negator<R>::StdNumber>::Sub
01414 operator-(const Mat<M,N,E,CS,RS>& l, const negator<R>& r) {return l-(typename negator<R>::StdNumber)(R)r;}
01415 template <int M, int N, class E, int CS, int RS, class R> inline
01416 typename CNT<R>::template Result<Mat<M,N,E,CS,RS> >::Sub
01417 operator-(const negator<R>& l, const Mat<M,N,E,CS,RS>& r) {return (typename negator<R>::StdNumber)(R)l-r;}
01418
01419
01420
01421 template <int M, int N, class E, int CS, int RS, class CHAR, class TRAITS> inline
01422 std::basic_ostream<CHAR,TRAITS>&
01423 operator<<(std::basic_ostream<CHAR,TRAITS>& o, const Mat<M,N,E,CS,RS>& m) {
01424 for (int i=0;i<M;++i) {
01425 o << std::endl << "[";
01426 for (int j=0;j<N;++j)
01427 o << (j>0?",":"") << m(i,j);
01428 o << "]";
01429 }
01430 if (M) o << std::endl;
01431 return o;
01432 }
01433
01434 template <int M, int N, class E, int CS, int RS, class CHAR, class TRAITS> inline
01435 std::basic_istream<CHAR,TRAITS>&
01436 operator>>(std::basic_istream<CHAR,TRAITS>& is, Mat<M,N,E,CS,RS>& m) {
01437
01438 assert(false);
01439 return is;
01440 }
01441
01442 }
01443
01444
01445 #endif //SimTK_SIMMATRIX_SMALLMATRIX_MAT_H_