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>::Sub>& 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>::Sub>& 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>::Sub>&>(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>::TSqrt ESqrt;
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>::ULessScalar EULessScalar;
00102 typedef typename CNT<E>::Number ENumber;
00103 typedef typename CNT<E>::StdNumber EStdNumber;
00104 typedef typename CNT<E>::Precision EPrecision;
00105 typedef typename CNT<E>::ScalarNormSq EScalarNormSq;
00106
00107 public:
00108
00109 enum {
00110 NRows = 1,
00111 NCols = N,
00112 NPackedElements = N,
00113 NActualElements = N * STRIDE,
00114 NActualScalars = CNT<E>::NActualScalars * NActualElements,
00115 RowSpacing = NActualElements,
00116 ColSpacing = STRIDE,
00117 ImagOffset = NTraits<ENumber>::ImagOffset,
00118 RealStrideFactor = 1,
00119
00120 ArgDepth = ((int)CNT<E>::ArgDepth < (int)MAX_RESOLVED_DEPTH
00121 ? CNT<E>::ArgDepth + 1
00122 : MAX_RESOLVED_DEPTH),
00123 IsScalar = 0,
00124 IsULessScalar = 0,
00125 IsNumber = 0,
00126 IsStdNumber = 0,
00127 IsPrecision = 0,
00128 SignInterpretation = CNT<E>::SignInterpretation
00129 };
00130
00131 typedef Row<N,E,STRIDE> T;
00132 typedef Row<N,ENeg,STRIDE> TNeg;
00133 typedef Row<N,EWithoutNegator,STRIDE> TWithoutNegator;
00134
00135 typedef Row<N,EReal,STRIDE*CNT<E>::RealStrideFactor>
00136 TReal;
00137 typedef Row<N,EImag,STRIDE*CNT<E>::RealStrideFactor>
00138 TImag;
00139 typedef Row<N,EComplex,STRIDE> TComplex;
00140 typedef Vec<N,EHerm,STRIDE> THerm;
00141 typedef Vec<N,E,STRIDE> TPosTrans;
00142 typedef E TElement;
00143 typedef Row TRow;
00144 typedef E TCol;
00145
00146
00147
00148 typedef Vec<N,ESqrt,1> TSqrt;
00149 typedef Row<N,EAbs,1> TAbs;
00150 typedef Row<N,EStandard,1> TStandard;
00151 typedef Vec<N,EInvert,1> TInvert;
00152 typedef Row<N,ENormalize,1> TNormalize;
00153
00154 typedef SymMat<N,ESqHermT> TSqHermT;
00155 typedef EScalarNormSq TSqTHerm;
00156
00157
00158
00159 typedef EScalar Scalar;
00160 typedef EULessScalar ULessScalar;
00161 typedef ENumber Number;
00162 typedef EStdNumber StdNumber;
00163 typedef EPrecision Precision;
00164 typedef EScalarNormSq ScalarNormSq;
00165
00166 int size() const { return N; }
00167 int nrow() const { return 1; }
00168 int ncol() const { return N; }
00169
00170
00171
00172 ScalarNormSq scalarNormSqr() const {
00173 ScalarNormSq sum(0);
00174 for(int i=0;i<N;++i) sum += CNT<E>::scalarNormSqr(d[i*STRIDE]);
00175 return sum;
00176 }
00177
00178
00179
00180
00181 TSqrt sqrt() const {
00182 TSqrt rsqrt;
00183 for(int i=0;i<N;++i) rsqrt[i] = CNT<E>::sqrt(d[i*STRIDE]);
00184 return rsqrt;
00185 }
00186
00187
00188
00189
00190 TAbs abs() const {
00191 TAbs rabs;
00192 for(int i=0;i<N;++i) rabs[i] = CNT<E>::abs(d[i*STRIDE]);
00193 return rabs;
00194 }
00195
00196 TStandard standardize() const {
00197 TStandard rstd;
00198 for(int i=0;i<N;++i) rstd[i] = CNT<E>::standardize(d[i*STRIDE]);
00199 return rstd;
00200 }
00201
00202
00203
00204 EStandard sum() const {
00205 E sum(0);
00206 for (int i=0;i<N;++i) sum += d[i*STRIDE];
00207 return CNT<E>::standardize(sum);
00208 }
00209
00210
00211
00212
00213 template <class P> struct EltResult {
00214 typedef Row<N, typename CNT<E>::template Result<P>::Mul, 1> Mul;
00215 typedef Row<N, typename CNT<E>::template Result<P>::Dvd, 1> Dvd;
00216 typedef Row<N, typename CNT<E>::template Result<P>::Add, 1> Add;
00217 typedef Row<N, typename CNT<E>::template Result<P>::Sub, 1> Sub;
00218 };
00219
00220
00221
00222 template <class P> struct Result {
00223 typedef MulCNTs<1,N,ArgDepth,Row,ColSpacing,RowSpacing,
00224 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00225 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> MulOp;
00226 typedef typename MulOp::Type Mul;
00227
00228 typedef MulCNTsNonConforming<1,N,ArgDepth,Row,ColSpacing,RowSpacing,
00229 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00230 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> MulOpNonConforming;
00231 typedef typename MulOpNonConforming::Type MulNon;
00232
00233
00234 typedef DvdCNTs<1,N,ArgDepth,Row,ColSpacing,RowSpacing,
00235 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00236 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> DvdOp;
00237 typedef typename DvdOp::Type Dvd;
00238
00239 typedef AddCNTs<1,N,ArgDepth,Row,ColSpacing,RowSpacing,
00240 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00241 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> AddOp;
00242 typedef typename AddOp::Type Add;
00243
00244 typedef SubCNTs<1,N,ArgDepth,Row,ColSpacing,RowSpacing,
00245 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00246 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> SubOp;
00247 typedef typename SubOp::Type Sub;
00248 };
00249
00250
00251 template <class P> struct Substitute {
00252 typedef Row<N,P> Type;
00253 };
00254
00255
00256
00257 Row(){
00258 #ifndef NDEBUG
00259 setToNaN();
00260 #endif
00261 }
00262
00263
00264
00265
00266 Row(const Row& src) {
00267 Impl::copy(*this, src);
00268 }
00269 Row& operator=(const Row& src) {
00270 Impl::copy(*this, src);
00271 return *this;
00272 }
00273
00274
00275
00276 template <int SS> Row(const Row<N,E,SS>& src) {
00277 Impl::copy(*this, src);
00278 }
00279
00280
00281
00282 template <int SS> Row(const Row<N,ENeg,SS>& src) {
00283 Impl::copy(*this, src);
00284 }
00285
00286
00287
00288 template <class EE, int SS> explicit Row(const Row<N,EE,SS>& vv) {
00289 Impl::copy(*this, vv);
00290 }
00291
00292
00293 explicit Row(const E& e)
00294 { for (int i=0;i<N;++i) d[i*STRIDE]=e; }
00295
00296
00297 explicit Row(const ENeg& ne)
00298 { for (int i=0;i<N;++i) d[i*STRIDE]=ne; }
00299
00300
00301
00302 explicit Row(int i)
00303 { new (this) Row(E(Precision(i))); }
00304
00305
00306 Row(const E& e0,const E& e1)
00307 { assert(N==2);(*this)[0]=e0;(*this)[1]=e1; }
00308 Row(const E& e0,const E& e1,const E& e2)
00309 { assert(N==3);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2; }
00310 Row(const E& e0,const E& e1,const E& e2,const E& e3)
00311 { assert(N==4);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;(*this)[3]=e3; }
00312 Row(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4)
00313 { assert(N==5);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
00314 (*this)[3]=e3;(*this)[4]=e4; }
00315 Row(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5)
00316 { assert(N==6);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
00317 (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5; }
00318 Row(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5,const E& e6)
00319 { assert(N==7);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
00320 (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6; }
00321 Row(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5,const E& e6,const E& e7)
00322 { assert(N==8);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
00323 (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6;(*this)[7]=e7; }
00324 Row(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5,const E& e6,const E& e7,const E& e8)
00325 { assert(N==9);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
00326 (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6;(*this)[7]=e7;(*this)[8]=e8; }
00327
00328
00329
00330 template <class EE> explicit Row(const EE* p)
00331 { assert(p); for(int i=0;i<N;++i) d[i*STRIDE]=p[i]; }
00332 template <class EE> Row& operator=(const EE* p)
00333 { assert(p); for(int i=0;i<N;++i) d[i*STRIDE]=p[i]; return *this; }
00334
00335
00336 template <class EE, int SS> Row& operator=(const Row<N,EE,SS>& vv) {
00337 Impl::copy(*this, vv);
00338 return *this;
00339 }
00340 template <class EE, int SS> Row& operator+=(const Row<N,EE,SS>& r)
00341 { for(int i=0;i<N;++i) d[i*STRIDE] += r[i]; return *this; }
00342 template <class EE, int SS> Row& operator+=(const Row<N,negator<EE>,SS>& r)
00343 { for(int i=0;i<N;++i) d[i*STRIDE] -= -(r[i]); return *this; }
00344 template <class EE, int SS> Row& operator-=(const Row<N,EE,SS>& r)
00345 { for(int i=0;i<N;++i) d[i*STRIDE] -= r[i]; return *this; }
00346 template <class EE, int SS> Row& operator-=(const Row<N,negator<EE>,SS>& r)
00347 { for(int i=0;i<N;++i) d[i*STRIDE] += -(r[i]); return *this; }
00348
00349
00350
00351 template <class EE, int SS> Row<N,typename CNT<E>::template Result<EE>::Add>
00352 conformingAdd(const Row<N,EE,SS>& r) const {
00353 Row<N,typename CNT<E>::template Result<EE>::Add> result;
00354 Impl::conformingAdd(*this, r, result);
00355 return result;
00356 }
00357 template <class EE, int SS> Row<N,typename CNT<E>::template Result<EE>::Sub>
00358 conformingSubtract(const Row<N,EE,SS>& r) const {
00359 Row<N,typename CNT<E>::template Result<EE>::Sub> result;
00360 Impl::conformingSubtract(*this, r, result);
00361 return result;
00362 }
00363
00364
00365 template <class EE, int SS> typename CNT<E>::template Result<EE>::Mul
00366 conformingMultiply(const Vec<N,EE,SS>& r) const {
00367 return (*this)*r;
00368 }
00369
00370
00371 template <int MatNCol, class EE, int CS, int RS>
00372 Row<MatNCol,typename CNT<E>::template Result<EE>::Mul>
00373 conformingMultiply(const Mat<N,MatNCol,EE,CS,RS>& m) const {
00374 Row<MatNCol,typename CNT<E>::template Result<EE>::Mul> result;
00375 for (int j=0;j<N;++j) result[j] = conformingMultiply(m(j));
00376 return result;
00377 }
00378
00379 const E& operator[](int i) const { assert(0 <= i && i < N); return d[i*STRIDE]; }
00380 E& operator[](int i) { assert(0 <= i && i < N); return d[i*STRIDE]; }
00381 const E& operator()(int i) const { return (*this)[i]; }
00382 E& operator()(int i) { return (*this)[i]; }
00383
00384 ScalarNormSq normSqr() const { return scalarNormSqr(); }
00385 typename CNT<ScalarNormSq>::TSqrt
00386 norm() const { return CNT<ScalarNormSq>::sqrt(scalarNormSqr()); }
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 TNormalize normalize() const {
00400 if (CNT<E>::IsScalar) {
00401 return castAwayNegatorIfAny() / (SignInterpretation*norm());
00402 } else {
00403 TNormalize elementwiseNormalized;
00404 for (int j=0; j<N; ++j)
00405 elementwiseNormalized[j] = CNT<E>::normalize((*this)[j]);
00406 return elementwiseNormalized;
00407 }
00408 }
00409
00410 TInvert invert() const {assert(false); return TInvert();}
00411
00412 const Row& operator+() const { return *this; }
00413 const TNeg& operator-() const { return negate(); }
00414 TNeg& operator-() { return updNegate(); }
00415 const THerm& operator~() const { return transpose(); }
00416 THerm& operator~() { return updTranspose(); }
00417
00418 const TNeg& negate() const { return *reinterpret_cast<const TNeg*>(this); }
00419 TNeg& updNegate() { return *reinterpret_cast<TNeg*>(this); }
00420
00421 const THerm& transpose() const { return *reinterpret_cast<const THerm*>(this); }
00422 THerm& updTranspose() { return *reinterpret_cast<THerm*>(this); }
00423
00424 const TPosTrans& positionalTranspose() const
00425 { return *reinterpret_cast<const TPosTrans*>(this); }
00426 TPosTrans& updPositionalTranspose()
00427 { return *reinterpret_cast<TPosTrans*>(this); }
00428
00429 const TReal& real() const { return *reinterpret_cast<const TReal*>(this); }
00430 TReal& real() { return *reinterpret_cast< TReal*>(this); }
00431
00432
00433 const TImag& imag() const {
00434 const int offs = ImagOffset;
00435 const EImag* p = reinterpret_cast<const EImag*>(this);
00436 return *reinterpret_cast<const TImag*>(p+offs);
00437 }
00438 TImag& imag() {
00439 const int offs = ImagOffset;
00440 EImag* p = reinterpret_cast<EImag*>(this);
00441 return *reinterpret_cast<TImag*>(p+offs);
00442 }
00443
00444 const TWithoutNegator& castAwayNegatorIfAny() const {return *reinterpret_cast<const TWithoutNegator*>(this);}
00445 TWithoutNegator& updCastAwayNegatorIfAny() {return *reinterpret_cast<TWithoutNegator*>(this);}
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456 template <class EE> Row<N, typename CNT<E>::template Result<EE>::Mul>
00457 scalarMultiply(const EE& e) const {
00458 Row<N, typename CNT<E>::template Result<EE>::Mul> result;
00459 for (int j=0; j<N; ++j) result[j] = (*this)[j] * e;
00460 return result;
00461 }
00462 template <class EE> Row<N, typename CNT<EE>::template Result<E>::Mul>
00463 scalarMultiplyFromLeft(const EE& e) const {
00464 Row<N, typename CNT<EE>::template Result<E>::Mul> result;
00465 for (int j=0; j<N; ++j) result[j] = e * (*this)[j];
00466 return result;
00467 }
00468
00469
00470
00471 template <class EE> Row<N, typename CNT<E>::template Result<EE>::Dvd>
00472 scalarDivide(const EE& e) const {
00473 Row<N, typename CNT<E>::template Result<EE>::Dvd> result;
00474 for (int j=0; j<N; ++j) result[j] = (*this)[j] / e;
00475 return result;
00476 }
00477 template <class EE> Row<N, typename CNT<EE>::template Result<E>::Dvd>
00478 scalarDivideFromLeft(const EE& e) const {
00479 Row<N, typename CNT<EE>::template Result<E>::Dvd> result;
00480 for (int j=0; j<N; ++j) result[j] = e / (*this)[j];
00481 return result;
00482 }
00483
00484 template <class EE> Row<N, typename CNT<E>::template Result<EE>::Add>
00485 scalarAdd(const EE& e) const {
00486 Row<N, typename CNT<E>::template Result<EE>::Add> result;
00487 for (int j=0; j<N; ++j) result[j] = (*this)[j] + e;
00488 return result;
00489 }
00490
00491
00492 template <class EE> Row<N, typename CNT<E>::template Result<EE>::Sub>
00493 scalarSubtract(const EE& e) const {
00494 Row<N, typename CNT<E>::template Result<EE>::Sub> result;
00495 for (int j=0; j<N; ++j) result[j] = (*this)[j] - e;
00496 return result;
00497 }
00498 template <class EE> Row<N, typename CNT<EE>::template Result<E>::Sub>
00499 scalarSubtractFromLeft(const EE& e) const {
00500 Row<N, typename CNT<EE>::template Result<E>::Sub> result;
00501 for (int j=0; j<N; ++j) result[j] = e - (*this)[j];
00502 return result;
00503 }
00504
00505
00506
00507
00508 template <class EE> Row& operator =(const EE& e) {return scalarEq(e);}
00509 template <class EE> Row& operator+=(const EE& e) {return scalarPlusEq(e);}
00510 template <class EE> Row& operator-=(const EE& e) {return scalarMinusEq(e);}
00511 template <class EE> Row& operator*=(const EE& e) {return scalarTimesEq(e);}
00512 template <class EE> Row& operator/=(const EE& e) {return scalarDivideEq(e);}
00513
00514
00515
00516 template <class EE> Row& scalarEq(const EE& ee)
00517 { for(int i=0;i<N;++i) d[i*STRIDE] = ee; return *this; }
00518 template <class EE> Row& scalarPlusEq(const EE& ee)
00519 { for(int i=0;i<N;++i) d[i*STRIDE] += ee; return *this; }
00520 template <class EE> Row& scalarMinusEq(const EE& ee)
00521 { for(int i=0;i<N;++i) d[i*STRIDE] -= ee; return *this; }
00522 template <class EE> Row& scalarMinusEqFromLeft(const EE& ee)
00523 { for(int i=0;i<N;++i) d[i*STRIDE] = ee - d[i*STRIDE]; return *this; }
00524 template <class EE> Row& scalarTimesEq(const EE& ee)
00525 { for(int i=0;i<N;++i) d[i*STRIDE] *= ee; return *this; }
00526 template <class EE> Row& scalarTimesEqFromLeft(const EE& ee)
00527 { for(int i=0;i<N;++i) d[i*STRIDE] = ee * d[i*STRIDE]; return *this; }
00528 template <class EE> Row& scalarDivideEq(const EE& ee)
00529 { for(int i=0;i<N;++i) d[i*STRIDE] /= ee; return *this; }
00530 template <class EE> Row& scalarDivideEqFromLeft(const EE& ee)
00531 { for(int i=0;i<N;++i) d[i*STRIDE] = ee / d[i*STRIDE]; return *this; }
00532
00533 void setToNaN() {
00534 (*this) = CNT<ELT>::getNaN();
00535 }
00536
00537 void setToZero() {
00538 (*this) = ELT(0);
00539 }
00540
00541
00542
00543 template <int NN>
00544 const Row<NN,ELT,STRIDE>& getSubRow(int j) const {
00545 assert(0 <= j && j + NN <= N);
00546 return Row<NN,ELT,STRIDE>::getAs(&(*this)[j]);
00547 }
00548 template <int NN>
00549 Row<NN,ELT,STRIDE>& updSubRow(int j) {
00550 assert(0 <= j && j + NN <= N);
00551 return Row<NN,ELT,STRIDE>::updAs(&(*this)[j]);
00552 }
00553
00554
00555
00556
00557 Row<N-1,ELT,1> drop1(int p) const {
00558 assert(0 <= p && p < N);
00559 Row<N-1,ELT,1> out;
00560 int nxt=0;
00561 for (int i=0; i<N-1; ++i, ++nxt) {
00562 if (nxt==p) ++nxt;
00563 out[i] = (*this)[nxt];
00564 }
00565 return out;
00566 }
00567
00568
00569
00570
00571 template <class EE> Row<N+1,ELT,1> append1(const EE& v) const {
00572 Row<N+1,ELT,1> out;
00573 Row<N,ELT,1>::updAs(&out[0]) = (*this);
00574 out[N] = v;
00575 return out;
00576 }
00577
00578
00579
00580
00581
00582
00583
00584 template <class EE> Row<N+1,ELT,1> insert1(int p, const EE& v) const {
00585 assert(0 <= p && p <= N);
00586 if (p==N) return append1(v);
00587 Row<N+1,ELT,1> out;
00588 int nxt=0;
00589 for (int i=0; i<N; ++i, ++nxt) {
00590 if (i==p) out[nxt++] = v;
00591 out[nxt] = (*this)[i];
00592 }
00593 return out;
00594 }
00595
00596
00597 static const Row& getAs(const ELT* p) {return *reinterpret_cast<const Row*>(p);}
00598 static Row& updAs(ELT* p) {return *reinterpret_cast<Row*>(p);}
00599
00600
00601 template <int NN>
00602 static const Row& getSubRow(const Row<NN,ELT,STRIDE>& r, int j) {
00603 assert(0 <= j && j + N <= NN);
00604 return getAs(&r[j]);
00605 }
00606 template <int NN>
00607 static Row& updSubRow(Row<NN,ELT,STRIDE>& r, int j) {
00608 assert(0 <= j && j + N <= NN);
00609 return updAs(&r[j]);
00610 }
00611
00612 static Row<N,ELT,1> getNaN() { return Row<N,ELT,1>(CNT<ELT>::getNaN()); }
00613
00615 bool isNaN() const {
00616 for (int j=0; j<N; ++j)
00617 if (CNT<ELT>::isNaN((*this)[j]))
00618 return true;
00619 return false;
00620 }
00621
00624 bool isInf() const {
00625 bool seenInf = false;
00626 for (int j=0; j<N; ++j) {
00627 const ELT& e = (*this)[j];
00628 if (!CNT<ELT>::isFinite(e)) {
00629 if (!CNT<ELT>::isInf(e))
00630 return false;
00631 seenInf = true;
00632 }
00633 }
00634 return seenInf;
00635 }
00636
00638 bool isFinite() const {
00639 for (int j=0; j<N; ++j)
00640 if (!CNT<ELT>::isFinite((*this)[j]))
00641 return false;
00642 return true;
00643 }
00644
00647 static double getDefaultTolerance() {return CNT<ELT>::getDefaultTolerance();}
00648
00651 template <class E2, int CS2>
00652 bool isNumericallyEqual(const Row<N,E2,CS2>& r, double tol) const {
00653 for (int j=0; j<N; ++j)
00654 if (!CNT<ELT>::isNumericallyEqual((*this)(j), r(j), tol))
00655 return false;
00656 return true;
00657 }
00658
00662 template <class E2, int CS2>
00663 bool isNumericallyEqual(const Row<N,E2,CS2>& r) const {
00664 const double tol = std::max(getDefaultTolerance(),r.getDefaultTolerance());
00665 return isNumericallyEqual(r, tol);
00666 }
00667
00672 bool isNumericallyEqual
00673 (const ELT& e,
00674 double tol = getDefaultTolerance()) const
00675 {
00676 for (int j=0; j<N; ++j)
00677 if (!CNT<ELT>::isNumericallyEqual((*this)(j), e, tol))
00678 return false;
00679 return true;
00680 }
00681 private:
00682 ELT d[NActualElements];
00683 };
00684
00686
00687
00689
00690
00691 template <int N, class E1, int S1, class E2, int S2> inline
00692 typename Row<N,E1,S1>::template Result< Row<N,E2,S2> >::Add
00693 operator+(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r) {
00694 return Row<N,E1,S1>::template Result< Row<N,E2,S2> >
00695 ::AddOp::perform(l,r);
00696 }
00697
00698
00699 template <int N, class E1, int S1, class E2, int S2> inline
00700 typename Row<N,E1,S1>::template Result< Row<N,E2,S2> >::Sub
00701 operator-(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r) {
00702 return Row<N,E1,S1>::template Result< Row<N,E2,S2> >
00703 ::SubOp::perform(l,r);
00704 }
00705
00707 template <int N, class E1, int S1, class E2, int S2> inline bool
00708 operator==(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r) {
00709 for (int i=0; i < N; ++i) if (l[i] != r[i]) return false;
00710 return true;
00711 }
00713 template <int N, class E1, int S1, class E2, int S2> inline bool
00714 operator!=(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r) {return !(l==r);}
00715
00717 template <int N, class E1, int S1, class E2, int S2> inline bool
00718 operator<(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r)
00719 { for (int i=0; i < N; ++i) if (l[i] >= r[i]) return false;
00720 return true; }
00722 template <int N, class E1, int S1, class E2> inline bool
00723 operator<(const Row<N,E1,S1>& v, const E2& e)
00724 { for (int i=0; i < N; ++i) if (v[i] >= e) return false;
00725 return true; }
00726
00728 template <int N, class E1, int S1, class E2, int S2> inline bool
00729 operator>(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r)
00730 { for (int i=0; i < N; ++i) if (l[i] <= r[i]) return false;
00731 return true; }
00733 template <int N, class E1, int S1, class E2> inline bool
00734 operator>(const Row<N,E1,S1>& v, const E2& e)
00735 { for (int i=0; i < N; ++i) if (v[i] <= e) return false;
00736 return true; }
00737
00740 template <int N, class E1, int S1, class E2, int S2> inline bool
00741 operator<=(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r)
00742 { for (int i=0; i < N; ++i) if (l[i] > r[i]) return false;
00743 return true; }
00746 template <int N, class E1, int S1, class E2> inline bool
00747 operator<=(const Row<N,E1,S1>& v, const E2& e)
00748 { for (int i=0; i < N; ++i) if (v[i] > e) return false;
00749 return true; }
00750
00753 template <int N, class E1, int S1, class E2, int S2> inline bool
00754 operator>=(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r)
00755 { for (int i=0; i < N; ++i) if (l[i] < r[i]) return false;
00756 return true; }
00759 template <int N, class E1, int S1, class E2> inline bool
00760 operator>=(const Row<N,E1,S1>& v, const E2& e)
00761 { for (int i=0; i < N; ++i) if (v[i] < e) return false;
00762 return true; }
00763
00765
00767
00768
00769
00770
00771
00772
00773
00774
00775 template <int N, class E, int S> inline
00776 typename Row<N,E,S>::template Result<float>::Mul
00777 operator*(const Row<N,E,S>& l, const float& r)
00778 { return Row<N,E,S>::template Result<float>::MulOp::perform(l,r); }
00779 template <int N, class E, int S> inline
00780 typename Row<N,E,S>::template Result<float>::Mul
00781 operator*(const float& l, const Row<N,E,S>& r) {return r*l;}
00782
00783 template <int N, class E, int S> inline
00784 typename Row<N,E,S>::template Result<double>::Mul
00785 operator*(const Row<N,E,S>& l, const double& r)
00786 { return Row<N,E,S>::template Result<double>::MulOp::perform(l,r); }
00787 template <int N, class E, int S> inline
00788 typename Row<N,E,S>::template Result<double>::Mul
00789 operator*(const double& l, const Row<N,E,S>& r) {return r*l;}
00790
00791 template <int N, class E, int S> inline
00792 typename Row<N,E,S>::template Result<long double>::Mul
00793 operator*(const Row<N,E,S>& l, const long double& r)
00794 { return Row<N,E,S>::template Result<long double>::MulOp::perform(l,r); }
00795 template <int N, class E, int S> inline
00796 typename Row<N,E,S>::template Result<long double>::Mul
00797 operator*(const long double& l, const Row<N,E,S>& r) {return r*l;}
00798
00799
00800 template <int N, class E, int S> inline
00801 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Mul
00802 operator*(const Row<N,E,S>& l, int r) {return l * (typename CNT<E>::Precision)r;}
00803 template <int N, class E, int S> inline
00804 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Mul
00805 operator*(int l, const Row<N,E,S>& r) {return r * (typename CNT<E>::Precision)l;}
00806
00807
00808
00809
00810 template <int N, class E, int S, class R> inline
00811 typename Row<N,E,S>::template Result<std::complex<R> >::Mul
00812 operator*(const Row<N,E,S>& l, const std::complex<R>& r)
00813 { return Row<N,E,S>::template Result<std::complex<R> >::MulOp::perform(l,r); }
00814 template <int N, class E, int S, class R> inline
00815 typename Row<N,E,S>::template Result<std::complex<R> >::Mul
00816 operator*(const std::complex<R>& l, const Row<N,E,S>& r) {return r*l;}
00817
00818
00819 template <int N, class E, int S, class R> inline
00820 typename Row<N,E,S>::template Result<std::complex<R> >::Mul
00821 operator*(const Row<N,E,S>& l, const conjugate<R>& r) {return l*(std::complex<R>)r;}
00822 template <int N, class E, int S, class R> inline
00823 typename Row<N,E,S>::template Result<std::complex<R> >::Mul
00824 operator*(const conjugate<R>& l, const Row<N,E,S>& r) {return r*(std::complex<R>)l;}
00825
00826
00827 template <int N, class E, int S, class R> inline
00828 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Mul
00829 operator*(const Row<N,E,S>& l, const negator<R>& r) {return l * (typename negator<R>::StdNumber)(R)r;}
00830 template <int N, class E, int S, class R> inline
00831 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Mul
00832 operator*(const negator<R>& l, const Row<N,E,S>& r) {return r * (typename negator<R>::StdNumber)(R)l;}
00833
00834
00835
00836
00837
00838
00839
00840 template <int N, class E, int S> inline
00841 typename Row<N,E,S>::template Result<float>::Dvd
00842 operator/(const Row<N,E,S>& l, const float& r)
00843 { return Row<N,E,S>::template Result<float>::DvdOp::perform(l,r); }
00844 template <int N, class E, int S> inline
00845 typename CNT<float>::template Result<Row<N,E,S> >::Dvd
00846 operator/(const float& l, const Row<N,E,S>& r)
00847 { return CNT<float>::template Result<Row<N,E,S> >::DvdOp::perform(l,r); }
00848
00849 template <int N, class E, int S> inline
00850 typename Row<N,E,S>::template Result<double>::Dvd
00851 operator/(const Row<N,E,S>& l, const double& r)
00852 { return Row<N,E,S>::template Result<double>::DvdOp::perform(l,r); }
00853 template <int N, class E, int S> inline
00854 typename CNT<double>::template Result<Row<N,E,S> >::Dvd
00855 operator/(const double& l, const Row<N,E,S>& r)
00856 { return CNT<double>::template Result<Row<N,E,S> >::DvdOp::perform(l,r); }
00857
00858 template <int N, class E, int S> inline
00859 typename Row<N,E,S>::template Result<long double>::Dvd
00860 operator/(const Row<N,E,S>& l, const long double& r)
00861 { return Row<N,E,S>::template Result<long double>::DvdOp::perform(l,r); }
00862 template <int N, class E, int S> inline
00863 typename CNT<long double>::template Result<Row<N,E,S> >::Dvd
00864 operator/(const long double& l, const Row<N,E,S>& r)
00865 { return CNT<long double>::template Result<Row<N,E,S> >::DvdOp::perform(l,r); }
00866
00867
00868 template <int N, class E, int S> inline
00869 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Dvd
00870 operator/(const Row<N,E,S>& l, int r) {return l / (typename CNT<E>::Precision)r;}
00871 template <int N, class E, int S> inline
00872 typename CNT<typename CNT<E>::Precision>::template Result<Row<N,E,S> >::Dvd
00873 operator/(int l, const Row<N,E,S>& r) {return (typename CNT<E>::Precision)l / r;}
00874
00875
00876
00877
00878
00879 template <int N, class E, int S, class R> inline
00880 typename Row<N,E,S>::template Result<std::complex<R> >::Dvd
00881 operator/(const Row<N,E,S>& l, const std::complex<R>& r)
00882 { return Row<N,E,S>::template Result<std::complex<R> >::DvdOp::perform(l,r); }
00883 template <int N, class E, int S, class R> inline
00884 typename CNT<std::complex<R> >::template Result<Row<N,E,S> >::Dvd
00885 operator/(const std::complex<R>& l, const Row<N,E,S>& r)
00886 { return CNT<std::complex<R> >::template Result<Row<N,E,S> >::DvdOp::perform(l,r); }
00887
00888
00889 template <int N, class E, int S, class R> inline
00890 typename Row<N,E,S>::template Result<std::complex<R> >::Dvd
00891 operator/(const Row<N,E,S>& l, const conjugate<R>& r) {return l/(std::complex<R>)r;}
00892 template <int N, class E, int S, class R> inline
00893 typename CNT<std::complex<R> >::template Result<Row<N,E,S> >::Dvd
00894 operator/(const conjugate<R>& l, const Row<N,E,S>& r) {return (std::complex<R>)l/r;}
00895
00896
00897 template <int N, class E, int S, class R> inline
00898 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Dvd
00899 operator/(const Row<N,E,S>& l, const negator<R>& r) {return l/(typename negator<R>::StdNumber)(R)r;}
00900 template <int N, class E, int S, class R> inline
00901 typename CNT<R>::template Result<Row<N,E,S> >::Dvd
00902 operator/(const negator<R>& l, const Row<N,E,S>& r) {return (typename negator<R>::StdNumber)(R)l/r;}
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912 template <int N, class E, int S> inline
00913 typename Row<N,E,S>::template Result<float>::Add
00914 operator+(const Row<N,E,S>& l, const float& r)
00915 { return Row<N,E,S>::template Result<float>::AddOp::perform(l,r); }
00916 template <int N, class E, int S> inline
00917 typename Row<N,E,S>::template Result<float>::Add
00918 operator+(const float& l, const Row<N,E,S>& r) {return r+l;}
00919
00920 template <int N, class E, int S> inline
00921 typename Row<N,E,S>::template Result<double>::Add
00922 operator+(const Row<N,E,S>& l, const double& r)
00923 { return Row<N,E,S>::template Result<double>::AddOp::perform(l,r); }
00924 template <int N, class E, int S> inline
00925 typename Row<N,E,S>::template Result<double>::Add
00926 operator+(const double& l, const Row<N,E,S>& r) {return r+l;}
00927
00928 template <int N, class E, int S> inline
00929 typename Row<N,E,S>::template Result<long double>::Add
00930 operator+(const Row<N,E,S>& l, const long double& r)
00931 { return Row<N,E,S>::template Result<long double>::AddOp::perform(l,r); }
00932 template <int N, class E, int S> inline
00933 typename Row<N,E,S>::template Result<long double>::Add
00934 operator+(const long double& l, const Row<N,E,S>& r) {return r+l;}
00935
00936
00937 template <int N, class E, int S> inline
00938 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Add
00939 operator+(const Row<N,E,S>& l, int r) {return l + (typename CNT<E>::Precision)r;}
00940 template <int N, class E, int S> inline
00941 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Add
00942 operator+(int l, const Row<N,E,S>& r) {return r + (typename CNT<E>::Precision)l;}
00943
00944
00945
00946
00947 template <int N, class E, int S, class R> inline
00948 typename Row<N,E,S>::template Result<std::complex<R> >::Add
00949 operator+(const Row<N,E,S>& l, const std::complex<R>& r)
00950 { return Row<N,E,S>::template Result<std::complex<R> >::AddOp::perform(l,r); }
00951 template <int N, class E, int S, class R> inline
00952 typename Row<N,E,S>::template Result<std::complex<R> >::Add
00953 operator+(const std::complex<R>& l, const Row<N,E,S>& r) {return r+l;}
00954
00955
00956 template <int N, class E, int S, class R> inline
00957 typename Row<N,E,S>::template Result<std::complex<R> >::Add
00958 operator+(const Row<N,E,S>& l, const conjugate<R>& r) {return l+(std::complex<R>)r;}
00959 template <int N, class E, int S, class R> inline
00960 typename Row<N,E,S>::template Result<std::complex<R> >::Add
00961 operator+(const conjugate<R>& l, const Row<N,E,S>& r) {return r+(std::complex<R>)l;}
00962
00963
00964 template <int N, class E, int S, class R> inline
00965 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Add
00966 operator+(const Row<N,E,S>& l, const negator<R>& r) {return l + (typename negator<R>::StdNumber)(R)r;}
00967 template <int N, class E, int S, class R> inline
00968 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Add
00969 operator+(const negator<R>& l, const Row<N,E,S>& r) {return r + (typename negator<R>::StdNumber)(R)l;}
00970
00971
00972
00973
00974 template <int N, class E, int S> inline
00975 typename Row<N,E,S>::template Result<float>::Sub
00976 operator-(const Row<N,E,S>& l, const float& r)
00977 { return Row<N,E,S>::template Result<float>::SubOp::perform(l,r); }
00978 template <int N, class E, int S> inline
00979 typename CNT<float>::template Result<Row<N,E,S> >::Sub
00980 operator-(const float& l, const Row<N,E,S>& r)
00981 { return CNT<float>::template Result<Row<N,E,S> >::SubOp::perform(l,r); }
00982
00983 template <int N, class E, int S> inline
00984 typename Row<N,E,S>::template Result<double>::Sub
00985 operator-(const Row<N,E,S>& l, const double& r)
00986 { return Row<N,E,S>::template Result<double>::SubOp::perform(l,r); }
00987 template <int N, class E, int S> inline
00988 typename CNT<double>::template Result<Row<N,E,S> >::Sub
00989 operator-(const double& l, const Row<N,E,S>& r)
00990 { return CNT<double>::template Result<Row<N,E,S> >::SubOp::perform(l,r); }
00991
00992 template <int N, class E, int S> inline
00993 typename Row<N,E,S>::template Result<long double>::Sub
00994 operator-(const Row<N,E,S>& l, const long double& r)
00995 { return Row<N,E,S>::template Result<long double>::SubOp::perform(l,r); }
00996 template <int N, class E, int S> inline
00997 typename CNT<long double>::template Result<Row<N,E,S> >::Sub
00998 operator-(const long double& l, const Row<N,E,S>& r)
00999 { return CNT<long double>::template Result<Row<N,E,S> >::SubOp::perform(l,r); }
01000
01001
01002 template <int N, class E, int S> inline
01003 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Sub
01004 operator-(const Row<N,E,S>& l, int r) {return l - (typename CNT<E>::Precision)r;}
01005 template <int N, class E, int S> inline
01006 typename CNT<typename CNT<E>::Precision>::template Result<Row<N,E,S> >::Sub
01007 operator-(int l, const Row<N,E,S>& r) {return (typename CNT<E>::Precision)l - r;}
01008
01009
01010
01011
01012
01013 template <int N, class E, int S, class R> inline
01014 typename Row<N,E,S>::template Result<std::complex<R> >::Sub
01015 operator-(const Row<N,E,S>& l, const std::complex<R>& r)
01016 { return Row<N,E,S>::template Result<std::complex<R> >::SubOp::perform(l,r); }
01017 template <int N, class E, int S, class R> inline
01018 typename CNT<std::complex<R> >::template Result<Row<N,E,S> >::Sub
01019 operator-(const std::complex<R>& l, const Row<N,E,S>& r)
01020 { return CNT<std::complex<R> >::template Result<Row<N,E,S> >::SubOp::perform(l,r); }
01021
01022
01023 template <int N, class E, int S, class R> inline
01024 typename Row<N,E,S>::template Result<std::complex<R> >::Sub
01025 operator-(const Row<N,E,S>& l, const conjugate<R>& r) {return l-(std::complex<R>)r;}
01026 template <int N, class E, int S, class R> inline
01027 typename CNT<std::complex<R> >::template Result<Row<N,E,S> >::Sub
01028 operator-(const conjugate<R>& l, const Row<N,E,S>& r) {return (std::complex<R>)l-r;}
01029
01030
01031 template <int N, class E, int S, class R> inline
01032 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Sub
01033 operator-(const Row<N,E,S>& l, const negator<R>& r) {return l-(typename negator<R>::StdNumber)(R)r;}
01034 template <int N, class E, int S, class R> inline
01035 typename CNT<R>::template Result<Row<N,E,S> >::Sub
01036 operator-(const negator<R>& l, const Row<N,E,S>& r) {return (typename negator<R>::StdNumber)(R)l-r;}
01037
01038
01039
01040 template <int N, class E, int S, class CHAR, class TRAITS> inline
01041 std::basic_ostream<CHAR,TRAITS>&
01042 operator<<(std::basic_ostream<CHAR,TRAITS>& o, const Row<N,E,S>& v) {
01043 o << "[" << v[0]; for(int i=1;i<N;++i) o<<','<<v[i]; o<<']'; return o;
01044 }
01045
01048 template <int N, class E, int S, class CHAR, class TRAITS> inline
01049 std::basic_istream<CHAR,TRAITS>&
01050 operator>>(std::basic_istream<CHAR,TRAITS>& is, Row<N,E,S>& v) {
01051 CHAR openBracket, closeBracket;
01052 is >> openBracket; if (is.fail()) return is;
01053 if (openBracket==CHAR('('))
01054 closeBracket = CHAR(')');
01055 else if (openBracket==CHAR('['))
01056 closeBracket = CHAR(']');
01057 else {
01058 closeBracket = CHAR(0);
01059 is.unget(); if (is.fail()) return is;
01060 }
01061
01062 for (int i=0; i < N; ++i) {
01063 is >> v[i];
01064 if (is.fail()) return is;
01065 if (i != N-1) {
01066 CHAR c; is >> c; if (is.fail()) return is;
01067 if (c != ',') is.unget();
01068 if (is.fail()) return is;
01069 }
01070 }
01071
01072
01073
01074 if (closeBracket != CHAR(0)) {
01075 CHAR closer; is >> closer; if (is.fail()) return is;
01076 if (closer != closeBracket) {
01077 is.unget(); if (is.fail()) return is;
01078 is.setstate( std::ios::failbit );
01079 }
01080 }
01081
01082 return is;
01083 }
01084
01085 }
01086
01087
01088 #endif //SimTK_SIMMATRIX_SMALLMATRIX_ROW_H_