00001 #ifndef SimTK_SIMMATRIX_SMALLMATRIX_SYMMAT_H_
00002 #define SimTK_SIMMATRIX_SMALLMATRIX_SYMMAT_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
00074 #include "SimTKcommon/internal/common.h"
00075
00076 namespace SimTK {
00077
00079 template <int M, class ELT, int RS> class SymMat {
00080 typedef ELT E;
00081 typedef typename CNT<E>::TNeg ENeg;
00082 typedef typename CNT<E>::TWithoutNegator EWithoutNegator;
00083 typedef typename CNT<E>::TReal EReal;
00084 typedef typename CNT<E>::TImag EImag;
00085 typedef typename CNT<E>::TComplex EComplex;
00086 typedef typename CNT<E>::THerm EHerm;
00087 typedef typename CNT<E>::TPosTrans EPosTrans;
00088 typedef typename CNT<E>::TSqHermT ESqHermT;
00089 typedef typename CNT<E>::TSqTHerm ESqTHerm;
00090
00091 typedef typename CNT<E>::TAbs EAbs;
00092 typedef typename CNT<E>::TStandard EStandard;
00093 typedef typename CNT<E>::TInvert EInvert;
00094 typedef typename CNT<E>::TNormalize ENormalize;
00095
00096 typedef typename CNT<E>::Scalar EScalar;
00097 typedef typename CNT<E>::Number ENumber;
00098 typedef typename CNT<E>::StdNumber EStdNumber;
00099 typedef typename CNT<E>::Precision EPrecision;
00100 typedef typename CNT<E>::ScalarSq EScalarSq;
00101
00102 public:
00103
00104 enum {
00105 NRows = M,
00106 NCols = M,
00107 NPackedElements = (M*(M+1))/2,
00108 NActualElements = RS * NPackedElements,
00109 NActualScalars = CNT<E>::NActualScalars * NActualElements,
00110 RowSpacing = RS,
00111 ColSpacing = NActualElements,
00112 ImagOffset = NTraits<ENumber>::ImagOffset,
00113 RealStrideFactor = 1,
00114
00115 ArgDepth = ((int)CNT<E>::ArgDepth < (int)MAX_RESOLVED_DEPTH
00116 ? CNT<E>::ArgDepth + 1
00117 : MAX_RESOLVED_DEPTH),
00118 IsScalar = 0,
00119 IsNumber = 0,
00120 IsStdNumber = 0,
00121 IsPrecision = 0,
00122 SignInterpretation = CNT<E>::SignInterpretation
00123 };
00124
00125 typedef SymMat<M,E,RS> T;
00126 typedef SymMat<M,ENeg,RS> TNeg;
00127 typedef SymMat<M,EWithoutNegator,RS> TWithoutNegator;
00128
00129 typedef SymMat<M,EReal,RS*CNT<E>::RealStrideFactor>
00130 TReal;
00131 typedef SymMat<M,EImag,RS*CNT<E>::RealStrideFactor>
00132 TImag;
00133 typedef SymMat<M,EComplex,RS> TComplex;
00134 typedef T THerm;
00135 typedef SymMat<M,EHerm,RS> TPosTrans;
00136 typedef E TElement;
00137 typedef Vec<M,E,RS> TDiag;
00138 typedef Vec<(M*(M-1))/2,E,RS> TLower;
00139 typedef Vec<(M*(M-1))/2,EHerm,RS> TUpper;
00140 typedef Vec<(M*(M+1))/2,E,RS> TAsVec;
00141
00142
00143
00144 typedef Row<M,E,1> TRow;
00145 typedef Vec<M,E,1> TCol;
00146 typedef SymMat<M,EAbs,1> TAbs;
00147 typedef SymMat<M,EStandard,1> TStandard;
00148 typedef SymMat<M,EInvert,1> TInvert;
00149 typedef SymMat<M,ENormalize,1> TNormalize;
00150 typedef SymMat<M,ESqHermT,1> TSqHermT;
00151 typedef SymMat<M,ESqTHerm,1> TSqTHerm;
00152 typedef SymMat<M,E,1> TPacked;
00153
00154 typedef EScalar Scalar;
00155 typedef ENumber Number;
00156 typedef EStdNumber StdNumber;
00157 typedef EPrecision Precision;
00158 typedef EScalarSq ScalarSq;
00159
00160 int size() const { return (M*(M+1))/2; }
00161 int nrow() const { return M; }
00162 int ncol() const { return M; }
00163
00164
00165
00166 ScalarSq scalarNormSqr() const {
00167 return getDiag().scalarNormSqr() + 2.*getLower().scalarNormSqr();
00168 }
00169
00170
00171
00172
00173 TAbs abs() const {
00174 return TAbs(getAsVec().abs());
00175 }
00176
00177 TStandard standardize() const {
00178 return TStandard(getAsVec().standardize());
00179 }
00180
00181 StdNumber trace() const {return getDiag().sum();}
00182
00183
00184
00185
00186 template <class P> struct EltResult {
00187 typedef SymMat<M, typename CNT<E>::template Result<P>::Mul, 1> Mul;
00188 typedef SymMat<M, typename CNT<E>::template Result<P>::Dvd, 1> Dvd;
00189 typedef SymMat<M, typename CNT<E>::template Result<P>::Add, 1> Add;
00190 typedef SymMat<M, typename CNT<E>::template Result<P>::Sub, 1> Sub;
00191 };
00192
00193
00194
00195 template <class P> struct Result {
00196 typedef MulCNTs<M,M,ArgDepth,SymMat,ColSpacing,RowSpacing,
00197 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00198 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> MulOp;
00199 typedef typename MulOp::Type Mul;
00200
00201 typedef MulCNTsNonConforming<M,M,ArgDepth,SymMat,ColSpacing,RowSpacing,
00202 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00203 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> MulOpNonConforming;
00204 typedef typename MulOpNonConforming::Type MulNon;
00205
00206
00207 typedef DvdCNTs<M,M,ArgDepth,SymMat,ColSpacing,RowSpacing,
00208 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00209 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> DvdOp;
00210 typedef typename DvdOp::Type Dvd;
00211
00212 typedef AddCNTs<M,M,ArgDepth,SymMat,ColSpacing,RowSpacing,
00213 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00214 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> AddOp;
00215 typedef typename AddOp::Type Add;
00216
00217 typedef SubCNTs<M,M,ArgDepth,SymMat,ColSpacing,RowSpacing,
00218 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00219 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> SubOp;
00220 typedef typename SubOp::Type Sub;
00221 };
00222
00223
00224 template <class P> struct Substitute {
00225 typedef SymMat<M,P> Type;
00226 };
00227
00228
00229
00230 SymMat(){
00231 #ifndef NDEBUG
00232 setToNaN();
00233 #endif
00234 }
00235
00236 SymMat(const SymMat& src) {
00237 updAsVec() = src.getAsVec();
00238 }
00239
00240 SymMat& operator=(const SymMat& src) {
00241 updAsVec() = src.getAsVec();
00242 return *this;
00243 }
00244
00245
00246
00247 template <class EE, int CSS, int RSS>
00248 explicit SymMat(const Mat<M,M,EE,CSS,RSS>& m) {
00249 updDiag() = m.diag().real();
00250 for (int j=0; j<M; ++j)
00251 for (int i=j+1; i<M; ++i)
00252 updEltLower(i,j) = m(i,j);
00253 }
00254
00255
00256
00257 template <int RSS> SymMat(const SymMat<M,E,RSS>& src)
00258 { updAsVec() = src.getAsVec(); }
00259
00260
00261
00262 template <int RSS> SymMat(const SymMat<M,ENeg,RSS>& src)
00263 { updAsVec() = src.getAsVec(); }
00264
00265
00266
00267 template <class EE, int RSS> explicit SymMat(const SymMat<M,EE,RSS>& src)
00268 { updAsVec() = src.getAsVec(); }
00269
00270
00271
00272
00273 explicit SymMat(const E& e)
00274 { updDiag() = e; updLower() = E(0); }
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 template <class EE> explicit SymMat(const EE* p) {
00292 assert(p);
00293 for (int i=0; i<M; ++i) {
00294 const int rowStart = (i*(i+1))/2;
00295 updDiag()[i] = p[rowStart + i];
00296 for (int j=0; j<i; ++j)
00297 updEltLower(i,j) = p[rowStart + j];
00298 }
00299 }
00300
00301
00302
00303 template <class EE> SymMat& operator=(const EE* p) {
00304 assert(p);
00305 for (int i=0; i<M; ++i) {
00306 const int rowStart = (i*(i+1))/2;
00307 updDiag()[i] = p[rowStart + i];
00308 for (int j=0; j<i; ++j)
00309 updEltLower(i,j) = p[rowStart + j];
00310 }
00311 return *this;
00312 }
00313
00314
00315
00316
00317 template <class EE, int RSS> SymMat& operator=(const SymMat<M,EE,RSS>& mm) {
00318 updAsVec() = mm.getAsVec();
00319 return *this;
00320 }
00321
00322
00323
00324 template <class EE, int RSS> SymMat&
00325 operator+=(const SymMat<M,EE,RSS>& mm) {
00326 updAsVec() += mm.getAsVec();
00327 return *this;
00328 }
00329 template <class EE, int RSS> SymMat&
00330 operator+=(const SymMat<M,negator<EE>,RSS>& mm) {
00331 updAsVec() -= -mm.getAsVec();
00332 return *this;
00333 }
00334
00335 template <class EE, int RSS> SymMat&
00336 operator-=(const SymMat<M,EE,RSS>& mm) {
00337 updAsVec() -= mm.getAsVec();
00338 return *this;
00339 }
00340 template <class EE, int RSS> SymMat&
00341 operator-=(const SymMat<M,negator<EE>,RSS>& mm) {
00342 updAsVec() += -mm.getAsVec();
00343 return *this;
00344 }
00345
00346
00347
00348 template <class EE, int RSS> SymMat&
00349 operator*=(const SymMat<M,EE,RSS>& mm) {
00350 assert(false);
00351 return *this;
00352 }
00353
00354
00355
00356
00357
00358 template <class E2, int RS2>
00359 typename Result<SymMat<M,E2,RS2> >::Add
00360 conformingAdd(const SymMat<M,E2,RS2>& r) const {
00361 return typename Result<SymMat<M,E2,RS2> >::Add
00362 (getAsVec().conformingAdd(r.getAsVec()));
00363 }
00364
00365 template <class E2, int RS2>
00366 typename Result<SymMat<M,E2,RS2> >::Sub
00367 conformingSubtract(const SymMat<M,E2,RS2>& r) const {
00368 return typename Result<SymMat<M,E2,RS2> >::Sub
00369 (getAsVec().conformingSubtract(r.getAsVec()));
00370 }
00371
00372
00373
00374
00375 const E& operator()(int i,int j) const
00376 { return i==j ? getDiag()[i] : getEltLower(i,j); }
00377 E& operator()(int i,int j)
00378 { return i==j ? updDiag()[i] : updEltLower(i,j); }
00379
00380
00381 ScalarSq normSqr() const { return scalarNormSqr(); }
00382 ScalarSq norm() const { return std::sqrt(scalarNormSqr()); }
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 TNormalize normalize() const {
00396 if (CNT<E>::IsScalar) {
00397 return castAwayNegatorIfAny() / (SignInterpretation*norm());
00398 } else {
00399 TNormalize elementwiseNormalized;
00400
00401 elementwiseNormalized.updAsVec() = getAsVec().normalize();
00402 return elementwiseNormalized;
00403 }
00404 }
00405
00406 TInvert invert() const {assert(false); return TInvert();}
00407
00408 const SymMat& operator+() const { return *this; }
00409 const TNeg& operator-() const { return negate(); }
00410 TNeg& operator-() { return updNegate(); }
00411 const THerm& operator~() const { return transpose(); }
00412 THerm& operator~() { return updTranspose(); }
00413
00414 const TNeg& negate() const { return *reinterpret_cast<const TNeg*>(this); }
00415 TNeg& updNegate() { return *reinterpret_cast<TNeg*>(this); }
00416
00417 const THerm& transpose() const { return *reinterpret_cast<const THerm*>(this); }
00418 THerm& updTranspose() { return *reinterpret_cast<THerm*>(this); }
00419
00420 const TPosTrans& positionalTranspose() const
00421 { return *reinterpret_cast<const TPosTrans*>(this); }
00422 TPosTrans& updPositionalTranspose()
00423 { return *reinterpret_cast<TPosTrans*>(this); }
00424
00425 const TReal& real() const { return *reinterpret_cast<const TReal*>(this); }
00426 TReal& real() { return *reinterpret_cast< TReal*>(this); }
00427
00428
00429 const TImag& imag() const {
00430 const int offs = ImagOffset;
00431 const EImag* p = reinterpret_cast<const EImag*>(this);
00432 return *reinterpret_cast<const TImag*>(p+offs);
00433 }
00434 TImag& imag() {
00435 const int offs = ImagOffset;
00436 EImag* p = reinterpret_cast<EImag*>(this);
00437 return *reinterpret_cast<TImag*>(p+offs);
00438 }
00439
00440 const TWithoutNegator& castAwayNegatorIfAny() const {return *reinterpret_cast<const TWithoutNegator*>(this);}
00441 TWithoutNegator& updCastAwayNegatorIfAny() {return *reinterpret_cast<TWithoutNegator*>(this);}
00442
00443
00444
00445
00446
00447
00448
00449
00450 template <class EE> SymMat<M, typename CNT<E>::template Result<EE>::Mul>
00451 scalarMultiply(const EE& e) const {
00452 SymMat<M, typename CNT<E>::template Result<EE>::Mul> result;
00453 result.updAsVec() = getAsVec().scalarMultiply(e);
00454 return result;
00455 }
00456 template <class EE> SymMat<M, typename CNT<EE>::template Result<E>::Mul>
00457 scalarMultiplyFromLeft(const EE& e) const {
00458 SymMat<M, typename CNT<EE>::template Result<E>::Mul> result;
00459 result.updAsVec() = getAsVec().scalarMultiplyFromLeft(e);
00460 return result;
00461 }
00462
00463
00464
00465 template <class EE> SymMat<M, typename CNT<E>::template Result<EE>::Dvd>
00466 scalarDivide(const EE& e) const {
00467 SymMat<M, typename CNT<E>::template Result<EE>::Dvd> result;
00468 result.updAsVec() = getAsVec().scalarDivide(e);
00469 return result;
00470 }
00471 template <class EE> SymMat<M, typename CNT<EE>::template Result<E>::Dvd>
00472 scalarDivideFromLeft(const EE& e) const {
00473 SymMat<M, typename CNT<EE>::template Result<E>::Dvd> result;
00474 result.updAsVec() = getAsVec().scalarDivideFromLeft(e);
00475 return result;
00476 }
00477
00478
00479 template <class EE> SymMat<M, typename CNT<E>::template Result<EE>::Add>
00480 scalarAdd(const EE& e) const {
00481 SymMat<M, typename CNT<E>::template Result<EE>::Add> result(*this);
00482 result.updDiag() += e;
00483 return result;
00484 }
00485
00486
00487 template <class EE> SymMat<M, typename CNT<E>::template Result<EE>::Sub>
00488 scalarSubtract(const EE& e) const {
00489 SymMat<M, typename CNT<E>::template Result<EE>::Sub> result(*this);
00490 result.diag() -= e;
00491 return result;
00492 }
00493
00494
00495 template <class EE> SymMat<M, typename CNT<EE>::template Result<E>::Sub>
00496 scalarSubtractFromLeft(const EE& e) const {
00497 SymMat<M, typename CNT<EE>::template Result<E>::Sub> result(-(*this));
00498 result.diag() += e;
00499 return result;
00500 }
00501
00502
00503
00504
00505 template <class EE> SymMat& operator =(const EE& e) {return scalarEq(e);}
00506 template <class EE> SymMat& operator+=(const EE& e) {return scalarPlusEq(e);}
00507 template <class EE> SymMat& operator-=(const EE& e) {return scalarMinusEq(e);}
00508 template <class EE> SymMat& operator*=(const EE& e) {return scalarTimesEq(e);}
00509 template <class EE> SymMat& operator/=(const EE& e) {return scalarDivideEq(e);}
00510
00511
00512
00513 template <class EE> SymMat& scalarEq(const EE& ee)
00514 { updDiag() = ee; updLower() = E(0); return *this; }
00515 template <class EE> SymMat& scalarPlusEq(const EE& ee)
00516 { updDiag() += ee; return *this; }
00517 template <class EE> SymMat& scalarMinusEq(const EE& ee)
00518 { updDiag() -= ee; return *this; }
00519
00520
00521 template <class EE> SymMat& scalarMinusEqFromLeft(const EE& ee)
00522 { updLower() *= E(-1); updDiag().scalarMinusEqFromLeft(ee); return *this; }
00523
00524 template <class EE> SymMat& scalarTimesEq(const EE& ee)
00525 { updAsVec() *= ee; return *this; }
00526 template <class EE> SymMat& scalarTimesEqFromLeft(const EE& ee)
00527 { updAsVec().scalarTimesEqFromLeft(ee); return *this; }
00528 template <class EE> SymMat& scalarDivideEq(const EE& ee)
00529 { updAsVec() /= ee; return *this; }
00530 template <class EE> SymMat& scalarDivideEqFromLeft(const EE& ee)
00531 { updAsVec().scalarDivideEqFromLeft(ee); return *this; }
00532
00533 void setToNaN() { updAsVec().setToNaN(); }
00534
00535
00536 static const SymMat& getAs(const ELT* p) {return *reinterpret_cast<const SymMat*>(p);}
00537 static SymMat& updAs(ELT* p) {return *reinterpret_cast<SymMat*>(p);}
00538
00539
00540 static TPacked getNaN() {
00541 return TPacked(CNT<typename TPacked::TDiag>::getNaN(),
00542 CNT<typename TPacked::TLower>::getNaN());
00543 }
00544
00545 const TDiag& getDiag() const {return TDiag::getAs(d);}
00546 TDiag& updDiag() {return TDiag::updAs(d);}
00547
00548
00549 const TDiag& diag() const {return getDiag();}
00550 TDiag& diag() {return updDiag();}
00551
00552 const TLower& getLower() const {return TLower::getAs(&d[M*RS]);}
00553 TLower& updLower() {return TLower::updAs(&d[M*RS]);}
00554
00555 const TUpper& getUpper() const {return reinterpret_cast<const TUpper&>(getLower());}
00556 TUpper& updUpper() {return reinterpret_cast< TUpper&>(updLower());}
00557
00558 const TAsVec& getAsVec() const {return TAsVec::getAs(d);}
00559 TAsVec& updAsVec() {return TAsVec::updAs(d);}
00560
00561
00562 const E& getEltLower(int i, int j) const {return getLower()[lowerIx(i,j)];}
00563 E& updEltLower(int i, int j) {return updLower()[lowerIx(i,j)];}
00564
00565
00566 const EHerm& getEltUpper(int i, int j) const {return getUpper()[lowerIx(j,i)];}
00567 EHerm& updEltUpper(int i, int j) {return updUpper()[lowerIx(j,i)];}
00568
00569 TRow sum() const {
00570 TRow temp(~getDiag());
00571 for (int i = 1; i < M; ++i)
00572 for (int j = 0; j < i; ++j) {
00573 E value = getEltLower(i, j);;
00574 temp[i] += value;
00575 temp[j] += value;
00576 }
00577 return temp;
00578 }
00579
00580 private:
00581 E d[NActualElements];
00582
00583 SymMat(const TDiag& di, const TLower& low) {
00584 updDiag() = di; updLower() = low;
00585 }
00586
00587 explicit SymMat(const TAsVec& v) {
00588 TAsVec::updAs(d) = v;
00589 }
00590
00591
00592
00593 static int lowerIx(int i, int j) {
00594 assert(0 <= j && j < i && i < M);
00595 return (i-j-1) + j*(M-1) - (j*(j-1))/2;
00596 }
00597
00598 template <int MM, class EE, int RSS> friend class SymMat;
00599 };
00600
00602
00603
00605
00606
00607 template <int M, class E1, int S1, class E2, int S2> inline
00608 typename SymMat<M,E1,S1>::template Result< SymMat<M,E2,S2> >::Add
00609 operator+(const SymMat<M,E1,S1>& l, const SymMat<M,E2,S2>& r) {
00610 return SymMat<M,E1,S1>::template Result< SymMat<M,E2,S2> >
00611 ::AddOp::perform(l,r);
00612 }
00613
00614
00615 template <int M, class E1, int S1, class E2, int S2> inline
00616 typename SymMat<M,E1,S1>::template Result< SymMat<M,E2,S2> >::Sub
00617 operator-(const SymMat<M,E1,S1>& l, const SymMat<M,E2,S2>& r) {
00618 return SymMat<M,E1,S1>::template Result< SymMat<M,E2,S2> >
00619 ::SubOp::perform(l,r);
00620 }
00621
00622
00623
00624 template <int M, class E1, int S1, class E2, int S2> inline
00625 typename SymMat<M,E1,S1>::template Result< SymMat<M,E2,S2> >::Mul
00626 operator-(const SymMat<M,E1,S1>& l, const SymMat<M,E2,S2>& r) {
00627 return SymMat<M,E1,S1>::template Result< SymMat<M,E2,S2> >
00628 ::MulOp::perform(l,r);
00629 }
00630
00631
00632 template <int M, class E1, int S1, class E2, int S2> inline bool
00633 operator==(const SymMat<M,E1,S1>& l, const SymMat<M,E2,S2>& r) {
00634 return l.getAsVec() == r.getAsVec();
00635 }
00636
00637
00638 template <int M, class E1, int S1, class E2, int S2> inline bool
00639 operator!=(const SymMat<M,E1,S1>& l, const SymMat<M,E2,S2>& r) {return !(l==r);}
00640
00642
00644
00645
00646
00647
00648 template <int M, class E, int S> inline
00649 typename SymMat<M,E,S>::template Result<float>::Mul
00650 operator*(const SymMat<M,E,S>& l, const float& r)
00651 { return SymMat<M,E,S>::template Result<float>::MulOp::perform(l,r); }
00652 template <int M, class E, int S> inline
00653 typename SymMat<M,E,S>::template Result<float>::Mul
00654 operator*(const float& l, const SymMat<M,E,S>& r) {return r*l;}
00655
00656 template <int M, class E, int S> inline
00657 typename SymMat<M,E,S>::template Result<double>::Mul
00658 operator*(const SymMat<M,E,S>& l, const double& r)
00659 { return SymMat<M,E,S>::template Result<double>::MulOp::perform(l,r); }
00660 template <int M, class E, int S> inline
00661 typename SymMat<M,E,S>::template Result<double>::Mul
00662 operator*(const double& l, const SymMat<M,E,S>& r) {return r*l;}
00663
00664 template <int M, class E, int S> inline
00665 typename SymMat<M,E,S>::template Result<long double>::Mul
00666 operator*(const SymMat<M,E,S>& l, const long double& r)
00667 { return SymMat<M,E,S>::template Result<long double>::MulOp::perform(l,r); }
00668 template <int M, class E, int S> inline
00669 typename SymMat<M,E,S>::template Result<long double>::Mul
00670 operator*(const long double& l, const SymMat<M,E,S>& r) {return r*l;}
00671
00672
00673 template <int M, class E, int S> inline
00674 typename SymMat<M,E,S>::template Result<typename CNT<E>::Precision>::Mul
00675 operator*(const SymMat<M,E,S>& l, int r) {return l * (typename CNT<E>::Precision)r;}
00676 template <int M, class E, int S> inline
00677 typename SymMat<M,E,S>::template Result<typename CNT<E>::Precision>::Mul
00678 operator*(int l, const SymMat<M,E,S>& r) {return r * (typename CNT<E>::Precision)l;}
00679
00680
00681
00682
00683 template <int M, class E, int S, class R> inline
00684 typename SymMat<M,E,S>::template Result<std::complex<R> >::Mul
00685 operator*(const SymMat<M,E,S>& l, const std::complex<R>& r)
00686 { return SymMat<M,E,S>::template Result<std::complex<R> >::MulOp::perform(l,r); }
00687 template <int M, class E, int S, class R> inline
00688 typename SymMat<M,E,S>::template Result<std::complex<R> >::Mul
00689 operator*(const std::complex<R>& l, const SymMat<M,E,S>& r) {return r*l;}
00690
00691
00692 template <int M, class E, int S, class R> inline
00693 typename SymMat<M,E,S>::template Result<std::complex<R> >::Mul
00694 operator*(const SymMat<M,E,S>& l, const conjugate<R>& r) {return l*(std::complex<R>)r;}
00695 template <int M, class E, int S, class R> inline
00696 typename SymMat<M,E,S>::template Result<std::complex<R> >::Mul
00697 operator*(const conjugate<R>& l, const SymMat<M,E,S>& r) {return r*(std::complex<R>)l;}
00698
00699
00700 template <int M, class E, int S, class R> inline
00701 typename SymMat<M,E,S>::template Result<typename negator<R>::StdNumber>::Mul
00702 operator*(const SymMat<M,E,S>& l, const negator<R>& r) {return l * (typename negator<R>::StdNumber)(R)r;}
00703 template <int M, class E, int S, class R> inline
00704 typename SymMat<M,E,S>::template Result<typename negator<R>::StdNumber>::Mul
00705 operator*(const negator<R>& l, const SymMat<M,E,S>& r) {return r * (typename negator<R>::StdNumber)(R)l;}
00706
00707
00708
00709
00710
00711
00712
00713 template <int M, class E, int S> inline
00714 typename SymMat<M,E,S>::template Result<float>::Dvd
00715 operator/(const SymMat<M,E,S>& l, const float& r)
00716 { return SymMat<M,E,S>::template Result<float>::DvdOp::perform(l,r); }
00717 template <int M, class E, int S> inline
00718 typename CNT<float>::template Result<SymMat<M,E,S> >::Dvd
00719 operator/(const float& l, const SymMat<M,E,S>& r)
00720 { return CNT<float>::template Result<SymMat<M,E,S> >::DvdOp::perform(l,r); }
00721
00722 template <int M, class E, int S> inline
00723 typename SymMat<M,E,S>::template Result<double>::Dvd
00724 operator/(const SymMat<M,E,S>& l, const double& r)
00725 { return SymMat<M,E,S>::template Result<double>::DvdOp::perform(l,r); }
00726 template <int M, class E, int S> inline
00727 typename CNT<double>::template Result<SymMat<M,E,S> >::Dvd
00728 operator/(const double& l, const SymMat<M,E,S>& r)
00729 { return CNT<double>::template Result<SymMat<M,E,S> >::DvdOp::perform(l,r); }
00730
00731 template <int M, class E, int S> inline
00732 typename SymMat<M,E,S>::template Result<long double>::Dvd
00733 operator/(const SymMat<M,E,S>& l, const long double& r)
00734 { return SymMat<M,E,S>::template Result<long double>::DvdOp::perform(l,r); }
00735 template <int M, class E, int S> inline
00736 typename CNT<long double>::template Result<SymMat<M,E,S> >::Dvd
00737 operator/(const long double& l, const SymMat<M,E,S>& r)
00738 { return CNT<long double>::template Result<SymMat<M,E,S> >::DvdOp::perform(l,r); }
00739
00740
00741 template <int M, class E, int S> inline
00742 typename SymMat<M,E,S>::template Result<typename CNT<E>::Precision>::Dvd
00743 operator/(const SymMat<M,E,S>& l, int r) {return l / (typename CNT<E>::Precision)r;}
00744 template <int M, class E, int S> inline
00745 typename CNT<typename CNT<E>::Precision>::template Result<SymMat<M,E,S> >::Dvd
00746 operator/(int l, const SymMat<M,E,S>& r) {return (typename CNT<E>::Precision)l / r;}
00747
00748
00749
00750
00751
00752 template <int M, class E, int S, class R> inline
00753 typename SymMat<M,E,S>::template Result<std::complex<R> >::Dvd
00754 operator/(const SymMat<M,E,S>& l, const std::complex<R>& r)
00755 { return SymMat<M,E,S>::template Result<std::complex<R> >::DvdOp::perform(l,r); }
00756 template <int M, class E, int S, class R> inline
00757 typename CNT<std::complex<R> >::template Result<SymMat<M,E,S> >::Dvd
00758 operator/(const std::complex<R>& l, const SymMat<M,E,S>& r)
00759 { return CNT<std::complex<R> >::template Result<SymMat<M,E,S> >::DvdOp::perform(l,r); }
00760
00761
00762 template <int M, class E, int S, class R> inline
00763 typename SymMat<M,E,S>::template Result<std::complex<R> >::Dvd
00764 operator/(const SymMat<M,E,S>& l, const conjugate<R>& r) {return l/(std::complex<R>)r;}
00765 template <int M, class E, int S, class R> inline
00766 typename CNT<std::complex<R> >::template Result<SymMat<M,E,S> >::Dvd
00767 operator/(const conjugate<R>& l, const SymMat<M,E,S>& r) {return (std::complex<R>)l/r;}
00768
00769
00770 template <int M, class E, int S, class R> inline
00771 typename SymMat<M,E,S>::template Result<typename negator<R>::StdNumber>::Dvd
00772 operator/(const SymMat<M,E,S>& l, const negator<R>& r) {return l/(typename negator<R>::StdNumber)(R)r;}
00773 template <int M, class E, int S, class R> inline
00774 typename CNT<R>::template Result<SymMat<M,E,S> >::Dvd
00775 operator/(const negator<R>& l, const SymMat<M,E,S>& r) {return (typename negator<R>::StdNumber)(R)l/r;}
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785 template <int M, class E, int S> inline
00786 typename SymMat<M,E,S>::template Result<float>::Add
00787 operator+(const SymMat<M,E,S>& l, const float& r)
00788 { return SymMat<M,E,S>::template Result<float>::AddOp::perform(l,r); }
00789 template <int M, class E, int S> inline
00790 typename SymMat<M,E,S>::template Result<float>::Add
00791 operator+(const float& l, const SymMat<M,E,S>& r) {return r+l;}
00792
00793 template <int M, class E, int S> inline
00794 typename SymMat<M,E,S>::template Result<double>::Add
00795 operator+(const SymMat<M,E,S>& l, const double& r)
00796 { return SymMat<M,E,S>::template Result<double>::AddOp::perform(l,r); }
00797 template <int M, class E, int S> inline
00798 typename SymMat<M,E,S>::template Result<double>::Add
00799 operator+(const double& l, const SymMat<M,E,S>& r) {return r+l;}
00800
00801 template <int M, class E, int S> inline
00802 typename SymMat<M,E,S>::template Result<long double>::Add
00803 operator+(const SymMat<M,E,S>& l, const long double& r)
00804 { return SymMat<M,E,S>::template Result<long double>::AddOp::perform(l,r); }
00805 template <int M, class E, int S> inline
00806 typename SymMat<M,E,S>::template Result<long double>::Add
00807 operator+(const long double& l, const SymMat<M,E,S>& r) {return r+l;}
00808
00809
00810 template <int M, class E, int S> inline
00811 typename SymMat<M,E,S>::template Result<typename CNT<E>::Precision>::Add
00812 operator+(const SymMat<M,E,S>& l, int r) {return l + (typename CNT<E>::Precision)r;}
00813 template <int M, class E, int S> inline
00814 typename SymMat<M,E,S>::template Result<typename CNT<E>::Precision>::Add
00815 operator+(int l, const SymMat<M,E,S>& r) {return r + (typename CNT<E>::Precision)l;}
00816
00817
00818
00819
00820 template <int M, class E, int S, class R> inline
00821 typename SymMat<M,E,S>::template Result<std::complex<R> >::Add
00822 operator+(const SymMat<M,E,S>& l, const std::complex<R>& r)
00823 { return SymMat<M,E,S>::template Result<std::complex<R> >::AddOp::perform(l,r); }
00824 template <int M, class E, int S, class R> inline
00825 typename SymMat<M,E,S>::template Result<std::complex<R> >::Add
00826 operator+(const std::complex<R>& l, const SymMat<M,E,S>& r) {return r+l;}
00827
00828
00829 template <int M, class E, int S, class R> inline
00830 typename SymMat<M,E,S>::template Result<std::complex<R> >::Add
00831 operator+(const SymMat<M,E,S>& l, const conjugate<R>& r) {return l+(std::complex<R>)r;}
00832 template <int M, class E, int S, class R> inline
00833 typename SymMat<M,E,S>::template Result<std::complex<R> >::Add
00834 operator+(const conjugate<R>& l, const SymMat<M,E,S>& r) {return r+(std::complex<R>)l;}
00835
00836
00837 template <int M, class E, int S, class R> inline
00838 typename SymMat<M,E,S>::template Result<typename negator<R>::StdNumber>::Add
00839 operator+(const SymMat<M,E,S>& l, const negator<R>& r) {return l + (typename negator<R>::StdNumber)(R)r;}
00840 template <int M, class E, int S, class R> inline
00841 typename SymMat<M,E,S>::template Result<typename negator<R>::StdNumber>::Add
00842 operator+(const negator<R>& l, const SymMat<M,E,S>& r) {return r + (typename negator<R>::StdNumber)(R)l;}
00843
00844
00845
00846
00847 template <int M, class E, int S> inline
00848 typename SymMat<M,E,S>::template Result<float>::Sub
00849 operator-(const SymMat<M,E,S>& l, const float& r)
00850 { return SymMat<M,E,S>::template Result<float>::SubOp::perform(l,r); }
00851 template <int M, class E, int S> inline
00852 typename CNT<float>::template Result<SymMat<M,E,S> >::Sub
00853 operator-(const float& l, const SymMat<M,E,S>& r)
00854 { return CNT<float>::template Result<SymMat<M,E,S> >::SubOp::perform(l,r); }
00855
00856 template <int M, class E, int S> inline
00857 typename SymMat<M,E,S>::template Result<double>::Sub
00858 operator-(const SymMat<M,E,S>& l, const double& r)
00859 { return SymMat<M,E,S>::template Result<double>::SubOp::perform(l,r); }
00860 template <int M, class E, int S> inline
00861 typename CNT<double>::template Result<SymMat<M,E,S> >::Sub
00862 operator-(const double& l, const SymMat<M,E,S>& r)
00863 { return CNT<double>::template Result<SymMat<M,E,S> >::SubOp::perform(l,r); }
00864
00865 template <int M, class E, int S> inline
00866 typename SymMat<M,E,S>::template Result<long double>::Sub
00867 operator-(const SymMat<M,E,S>& l, const long double& r)
00868 { return SymMat<M,E,S>::template Result<long double>::SubOp::perform(l,r); }
00869 template <int M, class E, int S> inline
00870 typename CNT<long double>::template Result<SymMat<M,E,S> >::Sub
00871 operator-(const long double& l, const SymMat<M,E,S>& r)
00872 { return CNT<long double>::template Result<SymMat<M,E,S> >::SubOp::perform(l,r); }
00873
00874
00875 template <int M, class E, int S> inline
00876 typename SymMat<M,E,S>::template Result<typename CNT<E>::Precision>::Sub
00877 operator-(const SymMat<M,E,S>& l, int r) {return l - (typename CNT<E>::Precision)r;}
00878 template <int M, class E, int S> inline
00879 typename CNT<typename CNT<E>::Precision>::template Result<SymMat<M,E,S> >::Sub
00880 operator-(int l, const SymMat<M,E,S>& r) {return (typename CNT<E>::Precision)l - r;}
00881
00882
00883
00884
00885
00886 template <int M, class E, int S, class R> inline
00887 typename SymMat<M,E,S>::template Result<std::complex<R> >::Sub
00888 operator-(const SymMat<M,E,S>& l, const std::complex<R>& r)
00889 { return SymMat<M,E,S>::template Result<std::complex<R> >::SubOp::perform(l,r); }
00890 template <int M, class E, int S, class R> inline
00891 typename CNT<std::complex<R> >::template Result<SymMat<M,E,S> >::Sub
00892 operator-(const std::complex<R>& l, const SymMat<M,E,S>& r)
00893 { return CNT<std::complex<R> >::template Result<SymMat<M,E,S> >::SubOp::perform(l,r); }
00894
00895
00896 template <int M, class E, int S, class R> inline
00897 typename SymMat<M,E,S>::template Result<std::complex<R> >::Sub
00898 operator-(const SymMat<M,E,S>& l, const conjugate<R>& r) {return l-(std::complex<R>)r;}
00899 template <int M, class E, int S, class R> inline
00900 typename CNT<std::complex<R> >::template Result<SymMat<M,E,S> >::Sub
00901 operator-(const conjugate<R>& l, const SymMat<M,E,S>& r) {return (std::complex<R>)l-r;}
00902
00903
00904 template <int M, class E, int S, class R> inline
00905 typename SymMat<M,E,S>::template Result<typename negator<R>::StdNumber>::Sub
00906 operator-(const SymMat<M,E,S>& l, const negator<R>& r) {return l-(typename negator<R>::StdNumber)(R)r;}
00907 template <int M, class E, int S, class R> inline
00908 typename CNT<R>::template Result<SymMat<M,E,S> >::Sub
00909 operator-(const negator<R>& l, const SymMat<M,E,S>& r) {return (typename negator<R>::StdNumber)(R)l-r;}
00910
00911
00912
00913 template <int M, class E, int RS, class CHAR, class TRAITS> inline
00914 std::basic_ostream<CHAR,TRAITS>&
00915 operator<<(std::basic_ostream<CHAR,TRAITS>& o, const SymMat<M,E,RS>& m) {
00916 for (int i=0;i<M;++i) {
00917 o << std::endl << "[";
00918 for (int j=0; j<=i; ++j)
00919 o << (j>0?" ":"") << m(i,j);
00920 for (int j=i+1; j<M; ++j)
00921 o << " *";
00922 o << "]";
00923 }
00924 if (M) o << std::endl;
00925 return o;
00926 }
00927
00928 template <int M, class E, int RS, class CHAR, class TRAITS> inline
00929 std::basic_istream<CHAR,TRAITS>&
00930 operator>>(std::basic_istream<CHAR,TRAITS>& is, SymMat<M,E,RS>& m) {
00931
00932 assert(false);
00933 return is;
00934 }
00935
00936 }
00937
00938
00939 #endif //SimTK_SIMMATRIX_SMALLMATRIX_SYMMAT_H_