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