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