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