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