Simbody
|
00001 #ifndef SimTK_SIMMATRIX_SMALLMATRIX_VEC_H_ 00002 #define SimTK_SIMMATRIX_SMALLMATRIX_VEC_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * SimTK Core: SimTK Simmatrix(tm) * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK Core biosimulation toolkit originating from * 00008 * Simbios, the NIH National Center for Physics-Based Simulation of * 00009 * Biological Structures at Stanford, funded under the NIH Roadmap for * 00010 * Medical Research, grant U54 GM072970. See https://simtk.org. * 00011 * * 00012 * Portions copyright (c) 2005-10 Stanford University and the Authors. * 00013 * Authors: Michael Sherman * 00014 * Contributors: Peter Eastman * 00015 * * 00016 * Permission is hereby granted, free of charge, to any person obtaining a * 00017 * copy of this software and associated documentation files (the "Software"), * 00018 * to deal in the Software without restriction, including without limitation * 00019 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 00020 * and/or sell copies of the Software, and to permit persons to whom the * 00021 * Software is furnished to do so, subject to the following conditions: * 00022 * * 00023 * The above copyright notice and this permission notice shall be included in * 00024 * all copies or substantial portions of the Software. * 00025 * * 00026 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 00027 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 00028 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 00029 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 00030 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 00031 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 00032 * USE OR OTHER DEALINGS IN THE SOFTWARE. * 00033 * -------------------------------------------------------------------------- */ 00034 00039 #include "SimTKcommon/internal/common.h" 00040 00041 namespace SimTK { 00042 00043 00044 // The following functions are used internally by Vec. 00045 00046 namespace Impl { 00047 00048 // For those wimpy compilers that don't unroll short, constant-limit loops, Peter Eastman added these 00049 // recursive template implementations of add and subtract. 00050 00051 template <class E1, int S1, class E2, int S2> void 00052 conformingAdd(const Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2, Vec<1,typename CNT<E1>::template Result<E2>::Add>& result) { 00053 result[0] = r1[0] + r2[0]; 00054 } 00055 template <int N, class E1, int S1, class E2, int S2> void 00056 conformingAdd(const Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2, Vec<N,typename CNT<E1>::template Result<E2>::Add>& result) { 00057 conformingAdd(reinterpret_cast<const Vec<N-1,E1,S1>&>(r1), reinterpret_cast<const Vec<N-1,E2,S2>&>(r2), reinterpret_cast<Vec<N-1,typename CNT<E1>::template Result<E2>::Add>&>(result)); 00058 result[N-1] = r1[N-1] + r2[N-1]; 00059 } 00060 template <class E1, int S1, class E2, int S2> void 00061 conformingSubtract(const Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2, Vec<1,typename CNT<E1>::template Result<E2>::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 Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2, Vec<N,typename CNT<E1>::template Result<E2>::Sub>& result) { 00066 conformingSubtract(reinterpret_cast<const Vec<N-1,E1,S1>&>(r1), reinterpret_cast<const Vec<N-1,E2,S2>&>(r2), reinterpret_cast<Vec<N-1,typename CNT<E1>::template Result<E2>::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(Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2) { 00071 r1[0] = r2[0]; 00072 } 00073 template <int N, class E1, int S1, class E2, int S2> void 00074 copy(Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2) { 00075 copy(reinterpret_cast<Vec<N-1,E1,S1>&>(r1), reinterpret_cast<const Vec<N-1,E2,S2>&>(r2)); 00076 r1[N-1] = r2[N-1]; 00077 } 00078 00079 } 00080 00082 template <int M, class ELT, int STRIDE> 00083 class Vec { 00084 typedef ELT E; 00085 typedef typename CNT<E>::TNeg ENeg; 00086 typedef typename CNT<E>::TWithoutNegator EWithoutNegator; 00087 typedef typename CNT<E>::TReal EReal; 00088 typedef typename CNT<E>::TImag EImag; 00089 typedef typename CNT<E>::TComplex EComplex; 00090 typedef typename CNT<E>::THerm EHerm; 00091 typedef typename CNT<E>::TPosTrans EPosTrans; 00092 typedef typename CNT<E>::TSqHermT ESqHermT; 00093 typedef typename CNT<E>::TSqTHerm ESqTHerm; 00094 00095 typedef typename CNT<E>::TSqrt ESqrt; 00096 typedef typename CNT<E>::TAbs EAbs; 00097 typedef typename CNT<E>::TStandard EStandard; 00098 typedef typename CNT<E>::TInvert EInvert; 00099 typedef typename CNT<E>::TNormalize ENormalize; 00100 00101 typedef typename CNT<E>::Scalar EScalar; 00102 typedef typename CNT<E>::ULessScalar EULessScalar; 00103 typedef typename CNT<E>::Number ENumber; 00104 typedef typename CNT<E>::StdNumber EStdNumber; 00105 typedef typename CNT<E>::Precision EPrecision; 00106 typedef typename CNT<E>::ScalarNormSq EScalarNormSq; 00107 00108 public: 00109 00110 enum { 00111 NRows = M, 00112 NCols = 1, 00113 NPackedElements = M, 00114 NActualElements = M * STRIDE, // includes trailing gap 00115 NActualScalars = CNT<E>::NActualScalars * NActualElements, 00116 RowSpacing = STRIDE, 00117 ColSpacing = NActualElements, 00118 ImagOffset = NTraits<ENumber>::ImagOffset, 00119 RealStrideFactor = 1, // composite types don't change size when 00120 // cast from complex to real or imaginary 00121 ArgDepth = ((int)CNT<E>::ArgDepth < (int)MAX_RESOLVED_DEPTH 00122 ? CNT<E>::ArgDepth + 1 00123 : MAX_RESOLVED_DEPTH), 00124 IsScalar = 0, 00125 IsULessScalar = 0, 00126 IsNumber = 0, 00127 IsStdNumber = 0, 00128 IsPrecision = 0, 00129 SignInterpretation = CNT<E>::SignInterpretation 00130 }; 00131 00132 // These are reinterpretations of the current data, so have the 00133 // same packing (stride). 00134 typedef Vec<M,E,STRIDE> T; 00135 typedef Vec<M,ENeg,STRIDE> TNeg; 00136 typedef Vec<M,EWithoutNegator,STRIDE> TWithoutNegator; 00137 00138 typedef Vec<M,EReal,STRIDE*CNT<E>::RealStrideFactor> 00139 TReal; 00140 typedef Vec<M,EImag,STRIDE*CNT<E>::RealStrideFactor> 00141 TImag; 00142 typedef Vec<M,EComplex,STRIDE> TComplex; 00143 typedef Row<M,EHerm,STRIDE> THerm; 00144 typedef Row<M,E,STRIDE> TPosTrans; 00145 typedef E TElement; 00146 typedef E TRow; 00147 typedef Vec TCol; 00148 00149 // These are the results of calculations, so are returned in new, packed 00150 // memory. Be sure to refer to element types here which are also packed. 00151 typedef Vec<M,ESqrt,1> TSqrt; // Note stride 00152 typedef Vec<M,EAbs,1> TAbs; // Note stride 00153 typedef Vec<M,EStandard,1> TStandard; 00154 typedef Row<M,EInvert,1> TInvert; 00155 typedef Vec<M,ENormalize,1> TNormalize; 00156 00157 typedef ESqHermT TSqHermT; // result of self dot product 00158 typedef SymMat<M,ESqTHerm> TSqTHerm; // result of self outer product 00159 00160 // These recurse right down to the underlying scalar type no matter how 00161 // deep the elements are. 00162 typedef EScalar Scalar; 00163 typedef EULessScalar ULessScalar; 00164 typedef ENumber Number; 00165 typedef EStdNumber StdNumber; 00166 typedef EPrecision Precision; 00167 typedef EScalarNormSq ScalarNormSq; 00168 00169 int size() const { return M; } 00170 int nrow() const { return M; } 00171 int ncol() const { return 1; } 00172 00173 00174 // Scalar norm square is sum( conjugate squares of all scalars ) 00175 ScalarNormSq scalarNormSqr() const { 00176 ScalarNormSq sum(0); 00177 for(int i=0;i<M;++i) sum += CNT<E>::scalarNormSqr(d[i*STRIDE]); 00178 return sum; 00179 } 00180 00181 // sqrt() is elementwise square root; that is, the return value has the same 00182 // dimension as this Vec but with each element replaced by whatever it thinks 00183 // its square root is. 00184 TSqrt sqrt() const { 00185 TSqrt vsqrt; 00186 for(int i=0;i<M;++i) vsqrt[i] = CNT<E>::sqrt(d[i*STRIDE]); 00187 return vsqrt; 00188 } 00189 00190 // abs() is elementwise absolute value; that is, the return value has the same 00191 // dimension as this Vec but with each element replaced by whatever it thinks 00192 // its absolute value is. 00193 TAbs abs() const { 00194 TAbs vabs; 00195 for(int i=0;i<M;++i) vabs[i] = CNT<E>::abs(d[i*STRIDE]); 00196 return vabs; 00197 } 00198 00199 TStandard standardize() const { 00200 TStandard vstd; 00201 for(int i=0;i<M;++i) vstd[i] = CNT<E>::standardize(d[i*STRIDE]); 00202 return vstd; 00203 } 00204 00205 // Sum just adds up all the elements, getting rid of negators and 00206 // conjugates in the process. 00207 EStandard sum() const { 00208 E sum(0); 00209 for (int i=0;i<M;++i) sum += d[i*STRIDE]; 00210 return CNT<E>::standardize(sum); 00211 } 00212 00213 00214 // This gives the resulting vector type when (v[i] op P) is applied to each element of v. 00215 // It is a vector of length M, stride 1, and element types which are the regular 00216 // composite result of E op P. Typically P is a scalar type but it doesn't have to be. 00217 template <class P> struct EltResult { 00218 typedef Vec<M, typename CNT<E>::template Result<P>::Mul, 1> Mul; 00219 typedef Vec<M, typename CNT<E>::template Result<P>::Dvd, 1> Dvd; 00220 typedef Vec<M, typename CNT<E>::template Result<P>::Add, 1> Add; 00221 typedef Vec<M, typename CNT<E>::template Result<P>::Sub, 1> Sub; 00222 }; 00223 00224 // This is the composite result for v op P where P is some kind of appropriately shaped 00225 // non-scalar type. 00226 template <class P> struct Result { 00227 typedef MulCNTs<M,1,ArgDepth,Vec,ColSpacing,RowSpacing, 00228 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth, 00229 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> MulOp; 00230 typedef typename MulOp::Type Mul; 00231 00232 typedef MulCNTsNonConforming<M,1,ArgDepth,Vec,ColSpacing,RowSpacing, 00233 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth, 00234 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> MulOpNonConforming; 00235 typedef typename MulOpNonConforming::Type MulNon; 00236 00237 typedef DvdCNTs<M,1,ArgDepth,Vec,ColSpacing,RowSpacing, 00238 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth, 00239 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> DvdOp; 00240 typedef typename DvdOp::Type Dvd; 00241 00242 typedef AddCNTs<M,1,ArgDepth,Vec,ColSpacing,RowSpacing, 00243 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth, 00244 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> AddOp; 00245 typedef typename AddOp::Type Add; 00246 00247 typedef SubCNTs<M,1,ArgDepth,Vec,ColSpacing,RowSpacing, 00248 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth, 00249 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> SubOp; 00250 typedef typename SubOp::Type Sub; 00251 }; 00252 00253 // Shape-preserving element substitution (always packed) 00254 template <class P> struct Substitute { 00255 typedef Vec<M,P> Type; 00256 }; 00257 00258 // Default construction initializes to NaN when debugging but 00259 // is left uninitialized otherwise. 00260 Vec(){ 00261 #ifndef NDEBUG 00262 setToNaN(); 00263 #endif 00264 } 00265 00266 // It's important not to use the default copy constructor or copy 00267 // assignment because the compiler doesn't understand that we may 00268 // have noncontiguous storage and will try to copy the whole array. 00269 Vec(const Vec& src) { 00270 Impl::copy(*this, src); 00271 } 00272 Vec& operator=(const Vec& src) { // no harm if src and 'this' are the same 00273 Impl::copy(*this, src); 00274 return *this; 00275 } 00276 00277 // We want an implicit conversion from a Vec of the same length 00278 // and element type but with a different stride. 00279 template <int SS> Vec(const Vec<M,E,SS>& src) { 00280 Impl::copy(*this, src); 00281 } 00282 00283 // We want an implicit conversion from a Vec of the same length 00284 // and *negated* element type (possibly with a different stride). 00285 00286 template <int SS> Vec(const Vec<M,ENeg,SS>& src) { 00287 Impl::copy(*this, src); 00288 } 00289 00290 // Construct a Vec from a Vec of the same length, with any 00291 // stride. Works as long as the element types are compatible. 00292 template <class EE, int SS> explicit Vec(const Vec<M,EE,SS>& vv) { 00293 Impl::copy(*this, vv); 00294 } 00295 00296 // Construction using an element assigns to each element. 00297 explicit Vec(const E& e) 00298 { for (int i=0;i<M;++i) d[i*STRIDE]=e; } 00299 00300 // Construction using a negated element assigns to each element. 00301 explicit Vec(const ENeg& ne) 00302 { for (int i=0;i<M;++i) d[i*STRIDE]=ne; } 00303 00304 // Given an int, turn it into a suitable floating point number 00305 // and then feed that to the above single-element constructor. 00306 explicit Vec(int i) 00307 { new (this) Vec(E(Precision(i))); } 00308 00309 // A bevy of constructors for Vecs up to length 6. 00310 Vec(const E& e0,const E& e1) 00311 { assert(M==2);(*this)[0]=e0;(*this)[1]=e1; } 00312 Vec(const E& e0,const E& e1,const E& e2) 00313 { assert(M==3);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2; } 00314 Vec(const E& e0,const E& e1,const E& e2,const E& e3) 00315 { assert(M==4);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;(*this)[3]=e3; } 00316 Vec(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4) 00317 { assert(M==5);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2; 00318 (*this)[3]=e3;(*this)[4]=e4; } 00319 Vec(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5) 00320 { assert(M==6);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2; 00321 (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5; } 00322 Vec(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5, const E& e6) 00323 { assert(M==7);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2; 00324 (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6; } 00325 Vec(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5, const E& e6, const E& e7) 00326 { assert(M==8);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2; 00327 (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6;(*this)[7]=e7; } 00328 Vec(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) 00329 { assert(M==9);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2; 00330 (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6;(*this)[7]=e7;(*this)[8]=e8; } 00331 00332 // Construction or assignment from a pointer to anything assumes we're pointing 00333 // at an element list of the right length. 00334 template <class EE> explicit Vec(const EE* p) 00335 { assert(p); for(int i=0;i<M;++i) d[i*STRIDE]=p[i]; } 00336 template <class EE> Vec& operator=(const EE* p) 00337 { assert(p); for(int i=0;i<M;++i) d[i*STRIDE]=p[i]; return *this; } 00338 00339 // Conforming assignment ops. 00340 template <class EE, int SS> Vec& operator=(const Vec<M,EE,SS>& vv) { 00341 Impl::copy(*this, vv); 00342 return *this; 00343 } 00344 template <class EE, int SS> Vec& operator+=(const Vec<M,EE,SS>& r) 00345 { for(int i=0;i<M;++i) d[i*STRIDE] += r[i]; return *this; } 00346 template <class EE, int SS> Vec& operator+=(const Vec<M,negator<EE>,SS>& r) 00347 { for(int i=0;i<M;++i) d[i*STRIDE] -= -(r[i]); return *this; } 00348 template <class EE, int SS> Vec& operator-=(const Vec<M,EE,SS>& r) 00349 { for(int i=0;i<M;++i) d[i*STRIDE] -= r[i]; return *this; } 00350 template <class EE, int SS> Vec& operator-=(const Vec<M,negator<EE>,SS>& r) 00351 { for(int i=0;i<M;++i) d[i*STRIDE] += -(r[i]); return *this; } 00352 00353 // Conforming binary ops with 'this' on left, producing new packed result. 00354 // Cases: v=v+v, v=v-v, m=v*r 00355 template <class EE, int SS> Vec<M,typename CNT<E>::template Result<EE>::Add> 00356 conformingAdd(const Vec<M,EE,SS>& r) const { 00357 Vec<M,typename CNT<E>::template Result<EE>::Add> result; 00358 Impl::conformingAdd(*this, r, result); 00359 return result; 00360 } 00361 template <class EE, int SS> Vec<M,typename CNT<E>::template Result<EE>::Sub> 00362 conformingSubtract(const Vec<M,EE,SS>& r) const { 00363 Vec<M,typename CNT<E>::template Result<EE>::Sub> result; 00364 Impl::conformingSubtract(*this, r, result); 00365 return result; 00366 } 00367 00368 // outer product (m = col*row) 00369 template <class EE, int SS> Mat<M,M,typename CNT<E>::template Result<EE>::Mul> 00370 conformingMultiply(const Row<M,EE,SS>& r) const { 00371 Mat<M,M,typename CNT<E>::template Result<EE>::Mul> result; 00372 for (int j=0;j<M;++j) result(j) = scalarMultiply(r(j)); 00373 return result; 00374 } 00375 00376 const E& operator[](int i) const { assert(0 <= i && i < M); return d[i*STRIDE]; } 00377 E& operator[](int i) { assert(0 <= i && i < M); return d[i*STRIDE]; } 00378 const E& operator()(int i) const { return (*this)[i]; } 00379 E& operator()(int i) { return (*this)[i]; } 00380 00381 ScalarNormSq normSqr() const { return scalarNormSqr(); } 00382 typename CNT<ScalarNormSq>::TSqrt 00383 norm() const { return CNT<ScalarNormSq>::sqrt(scalarNormSqr()); } 00384 00385 // If the elements of this Vec are scalars, the result is what you get by 00386 // dividing each element by the norm() calculated above. If the elements are 00387 // *not* scalars, then the elements are *separately* normalized. That means 00388 // you will get a different answer from Vec<2,Vec3>::normalize() than you 00389 // would from a Vec<6>::normalize() containing the same scalars. 00390 // 00391 // Normalize returns a vector of the same dimension but in new, packed storage 00392 // and with a return type that does not include negator<> even if the original 00393 // Vec<> does, because we can eliminate the negation here almost for free. 00394 // But we can't standardize (change conjugate to complex) for free, so we'll retain 00395 // conjugates if there are any. 00396 TNormalize normalize() const { 00397 if (CNT<E>::IsScalar) { 00398 return castAwayNegatorIfAny() / (SignInterpretation*norm()); 00399 } else { 00400 TNormalize elementwiseNormalized; 00401 for (int i=0; i<M; ++i) 00402 elementwiseNormalized[i] = CNT<E>::normalize((*this)[i]); 00403 return elementwiseNormalized; 00404 } 00405 } 00406 00407 TInvert invert() const {assert(false); return TInvert();} // TODO default inversion 00408 00409 const Vec& operator+() const { return *this; } 00410 const TNeg& operator-() const { return negate(); } 00411 TNeg& operator-() { return updNegate(); } 00412 const THerm& operator~() const { return transpose(); } 00413 THerm& operator~() { return updTranspose(); } 00414 00415 const TNeg& negate() const { return *reinterpret_cast<const TNeg*>(this); } 00416 TNeg& updNegate() { return *reinterpret_cast< TNeg*>(this); } 00417 00418 const THerm& transpose() const { return *reinterpret_cast<const THerm*>(this); } 00419 THerm& updTranspose() { return *reinterpret_cast< THerm*>(this); } 00420 00421 const TPosTrans& positionalTranspose() const 00422 { return *reinterpret_cast<const TPosTrans*>(this); } 00423 TPosTrans& updPositionalTranspose() 00424 { return *reinterpret_cast<TPosTrans*>(this); } 00425 00426 const TReal& real() const { return *reinterpret_cast<const TReal*>(this); } 00427 TReal& real() { return *reinterpret_cast< TReal*>(this); } 00428 00429 // Had to contort these routines to get them through VC++ 7.net 00430 const TImag& imag() const { 00431 const int offs = ImagOffset; 00432 const EImag* p = reinterpret_cast<const EImag*>(this); 00433 return *reinterpret_cast<const TImag*>(p+offs); 00434 } 00435 TImag& imag() { 00436 const int offs = ImagOffset; 00437 EImag* p = reinterpret_cast<EImag*>(this); 00438 return *reinterpret_cast<TImag*>(p+offs); 00439 } 00440 00441 const TWithoutNegator& castAwayNegatorIfAny() const {return *reinterpret_cast<const TWithoutNegator*>(this);} 00442 TWithoutNegator& updCastAwayNegatorIfAny() {return *reinterpret_cast<TWithoutNegator*>(this);} 00443 00444 // These are elementwise binary operators, (this op ee) by default but 00445 // (ee op this) if 'FromLeft' appears in the name. The result is a packed 00446 // Vec<M> but the element type may change. These are mostly used to 00447 // implement global operators. We call these "scalar" operators but 00448 // actually the "scalar" can be a composite type. 00449 00450 //TODO: consider converting 'e' to Standard Numbers as precalculation and 00451 // changing return type appropriately. 00452 template <class EE> Vec<M, typename CNT<E>::template Result<EE>::Mul> 00453 scalarMultiply(const EE& e) const { 00454 Vec<M, typename CNT<E>::template Result<EE>::Mul> result; 00455 for (int i=0; i<M; ++i) result[i] = (*this)[i] * e; 00456 return result; 00457 } 00458 template <class EE> Vec<M, typename CNT<EE>::template Result<E>::Mul> 00459 scalarMultiplyFromLeft(const EE& e) const { 00460 Vec<M, typename CNT<EE>::template Result<E>::Mul> result; 00461 for (int i=0; i<M; ++i) result[i] = e * (*this)[i]; 00462 return result; 00463 } 00464 00465 // TODO: should precalculate and store 1/e, while converting to Standard 00466 // Numbers. Note that return type should change appropriately. 00467 template <class EE> Vec<M, typename CNT<E>::template Result<EE>::Dvd> 00468 scalarDivide(const EE& e) const { 00469 Vec<M, typename CNT<E>::template Result<EE>::Dvd> result; 00470 for (int i=0; i<M; ++i) result[i] = (*this)[i] / e; 00471 return result; 00472 } 00473 template <class EE> Vec<M, typename CNT<EE>::template Result<E>::Dvd> 00474 scalarDivideFromLeft(const EE& e) const { 00475 Vec<M, typename CNT<EE>::template Result<E>::Dvd> result; 00476 for (int i=0; i<M; ++i) result[i] = e / (*this)[i]; 00477 return result; 00478 } 00479 00480 template <class EE> Vec<M, typename CNT<E>::template Result<EE>::Add> 00481 scalarAdd(const EE& e) const { 00482 Vec<M, typename CNT<E>::template Result<EE>::Add> result; 00483 for (int i=0; i<M; ++i) result[i] = (*this)[i] + e; 00484 return result; 00485 } 00486 // Add is commutative, so no 'FromLeft'. 00487 00488 template <class EE> Vec<M, typename CNT<E>::template Result<EE>::Sub> 00489 scalarSubtract(const EE& e) const { 00490 Vec<M, typename CNT<E>::template Result<EE>::Sub> result; 00491 for (int i=0; i<M; ++i) result[i] = (*this)[i] - e; 00492 return result; 00493 } 00494 template <class EE> Vec<M, typename CNT<EE>::template Result<E>::Sub> 00495 scalarSubtractFromLeft(const EE& e) const { 00496 Vec<M, typename CNT<EE>::template Result<E>::Sub> result; 00497 for (int i=0; i<M; ++i) result[i] = e - (*this)[i]; 00498 return result; 00499 } 00500 00501 // Generic assignments for any element type not listed explicitly, including scalars. 00502 // These are done repeatedly for each element and only work if the operation can 00503 // be performed leaving the original element type. 00504 template <class EE> Vec& operator =(const EE& e) {return scalarEq(e);} 00505 template <class EE> Vec& operator+=(const EE& e) {return scalarPlusEq(e);} 00506 template <class EE> Vec& operator-=(const EE& e) {return scalarMinusEq(e);} 00507 template <class EE> Vec& operator*=(const EE& e) {return scalarTimesEq(e);} 00508 template <class EE> Vec& operator/=(const EE& e) {return scalarDivideEq(e);} 00509 00510 // Generalized element assignment & computed assignment methods. These will work 00511 // for any assignment-compatible element, not just scalars. 00512 template <class EE> Vec& scalarEq(const EE& ee) 00513 { for(int i=0;i<M;++i) d[i*STRIDE] = ee; return *this; } 00514 template <class EE> Vec& scalarPlusEq(const EE& ee) 00515 { for(int i=0;i<M;++i) d[i*STRIDE] += ee; return *this; } 00516 template <class EE> Vec& scalarMinusEq(const EE& ee) 00517 { for(int i=0;i<M;++i) d[i*STRIDE] -= ee; return *this; } 00518 template <class EE> Vec& scalarMinusEqFromLeft(const EE& ee) 00519 { for(int i=0;i<M;++i) d[i*STRIDE] = ee - d[i*STRIDE]; return *this; } 00520 template <class EE> Vec& scalarTimesEq(const EE& ee) 00521 { for(int i=0;i<M;++i) d[i*STRIDE] *= ee; return *this; } 00522 template <class EE> Vec& scalarTimesEqFromLeft(const EE& ee) 00523 { for(int i=0;i<M;++i) d[i*STRIDE] = ee * d[i*STRIDE]; return *this; } 00524 template <class EE> Vec& scalarDivideEq(const EE& ee) 00525 { for(int i=0;i<M;++i) d[i*STRIDE] /= ee; return *this; } 00526 template <class EE> Vec& scalarDivideEqFromLeft(const EE& ee) 00527 { for(int i=0;i<M;++i) d[i*STRIDE] = ee / d[i*STRIDE]; return *this; } 00528 00529 void setToNaN() { 00530 (*this) = CNT<ELT>::getNaN(); 00531 } 00532 00533 void setToZero() { 00534 (*this) = ELT(0); 00535 } 00536 00537 // Extract a sub-Vec with size known at compile time. These have to be 00538 // called with explicit template arguments, e.g. getSubVec<3>(i). 00539 template <int MM> 00540 const Vec<MM,ELT,STRIDE>& getSubVec(int i) const { 00541 assert(0 <= i && i + MM <= M); 00542 return Vec<MM,ELT,STRIDE>::getAs(&(*this)[i]); 00543 } 00544 template <int MM> 00545 Vec<MM,ELT,STRIDE>& updSubVec(int i) { 00546 assert(0 <= i && i + MM <= M); 00547 return Vec<MM,ELT,STRIDE>::updAs(&(*this)[i]); 00548 } 00549 00550 // Return a vector one smaller than this one by dropping the element 00551 // at the indicated position p. The result is packed but has same 00552 // element type as this one. 00553 Vec<M-1,ELT,1> drop1(int p) const { 00554 assert(0 <= p && p < M); 00555 Vec<M-1,ELT,1> out; 00556 int nxt=0; 00557 for (int i=0; i<M-1; ++i, ++nxt) { 00558 if (nxt==p) ++nxt; // skip the loser 00559 out[i] = (*this)[nxt]; 00560 } 00561 return out; 00562 } 00563 00564 // Return a vector one larger than this one by adding an element 00565 // to the end. The result is packed but has same element type as 00566 // this one. Works for any assignment compatible element. 00567 template <class EE> Vec<M+1,ELT,1> append1(const EE& v) const { 00568 Vec<M+1,ELT,1> out; 00569 Vec<M,ELT,1>::updAs(&out[0]) = (*this); 00570 out[M] = v; 00571 return out; 00572 } 00573 00574 00575 // Return a vector one larger than this one by inserting an element 00576 // *before* the indicated one. The result is packed but has same element type as 00577 // this one. Works for any assignment compatible element. The index 00578 // can be one greater than normally allowed in which case the element 00579 // is appended. 00580 template <class EE> Vec<M+1,ELT,1> insert1(int p, const EE& v) const { 00581 assert(0 <= p && p <= M); 00582 if (p==M) return append1(v); 00583 Vec<M+1,ELT,1> out; 00584 int nxt=0; 00585 for (int i=0; i<M; ++i, ++nxt) { 00586 if (i==p) out[nxt++] = v; 00587 out[nxt] = (*this)[i]; 00588 } 00589 return out; 00590 } 00591 00592 // These assume we are given a pointer to d[0] of a Vec<M,E,S> like this one. 00593 static const Vec& getAs(const ELT* p) {return *reinterpret_cast<const Vec*>(p);} 00594 static Vec& updAs(ELT* p) {return *reinterpret_cast<Vec*>(p);} 00595 00596 // Extract a subvector from a longer one. Element type and stride must match. 00597 template <int MM> 00598 static const Vec& getSubVec(const Vec<MM,ELT,STRIDE>& v, int i) { 00599 assert(0 <= i && i + M <= MM); 00600 return getAs(&v[i]); 00601 } 00602 template <int MM> 00603 static Vec& updSubVec(Vec<MM,ELT,STRIDE>& v, int i) { 00604 assert(0 <= i && i + M <= MM); 00605 return updAs(&v[i]); 00606 } 00607 00608 static Vec<M,ELT,1> getNaN() { return Vec<M,ELT,1>(CNT<ELT>::getNaN()); } 00609 00611 bool isNaN() const { 00612 for (int i=0; i<M; ++i) 00613 if (CNT<ELT>::isNaN((*this)[i])) 00614 return true; 00615 return false; 00616 } 00617 00620 bool isInf() const { 00621 bool seenInf = false; 00622 for (int i=0; i<M; ++i) { 00623 const ELT& e = (*this)[i]; 00624 if (!CNT<ELT>::isFinite(e)) { 00625 if (!CNT<ELT>::isInf(e)) 00626 return false; // something bad was found 00627 seenInf = true; 00628 } 00629 } 00630 return seenInf; 00631 } 00632 00634 bool isFinite() const { 00635 for (int i=0; i<M; ++i) 00636 if (!CNT<ELT>::isFinite((*this)[i])) 00637 return false; 00638 return true; 00639 } 00640 00643 static double getDefaultTolerance() {return CNT<ELT>::getDefaultTolerance();} 00644 00647 template <class E2, int RS2> 00648 bool isNumericallyEqual(const Vec<M,E2,RS2>& v, double tol) const { 00649 for (int i=0; i<M; ++i) 00650 if (!CNT<ELT>::isNumericallyEqual((*this)[i], v[i], tol)) 00651 return false; 00652 return true; 00653 } 00654 00658 template <class E2, int RS2> 00659 bool isNumericallyEqual(const Vec<M,E2,RS2>& v) const { 00660 const double tol = std::max(getDefaultTolerance(),v.getDefaultTolerance()); 00661 return isNumericallyEqual(v, tol); 00662 } 00663 00668 bool isNumericallyEqual 00669 (const ELT& e, 00670 double tol = getDefaultTolerance()) const 00671 { 00672 for (int i=0; i<M; ++i) 00673 if (!CNT<ELT>::isNumericallyEqual((*this)[i], e, tol)) 00674 return false; 00675 return true; 00676 } 00677 private: 00678 ELT d[NActualElements]; // data 00679 }; 00680 00682 // Global operators involving two vectors. // 00683 // v+v, v-v, v==v, v!=v // 00685 00686 // v3 = v1 + v2 where all v's have the same length M. 00687 template <int M, class E1, int S1, class E2, int S2> inline 00688 typename Vec<M,E1,S1>::template Result< Vec<M,E2,S2> >::Add 00689 operator+(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) { 00690 return Vec<M,E1,S1>::template Result< Vec<M,E2,S2> > 00691 ::AddOp::perform(l,r); 00692 } 00693 00694 // v3 = v1 - v2, similar to + 00695 template <int M, class E1, int S1, class E2, int S2> inline 00696 typename Vec<M,E1,S1>::template Result< Vec<M,E2,S2> >::Sub 00697 operator-(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) { 00698 return Vec<M,E1,S1>::template Result< Vec<M,E2,S2> > 00699 ::SubOp::perform(l,r); 00700 } 00701 00703 template <int M, class E1, int S1, class E2, int S2> inline bool 00704 operator==(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) 00705 { for (int i=0; i < M; ++i) if (l[i] != r[i]) return false; 00706 return true; } 00708 template <int M, class E1, int S1, class E2, int S2> inline bool 00709 operator!=(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) {return !(l==r);} 00710 00712 template <int M, class E1, int S1, class E2> inline bool 00713 operator==(const Vec<M,E1,S1>& v, const E2& e) 00714 { for (int i=0; i < M; ++i) if (v[i] != e) return false; 00715 return true; } 00717 template <int M, class E1, int S1, class E2> inline bool 00718 operator!=(const Vec<M,E1,S1>& v, const E2& e) {return !(v==e);} 00719 00721 template <int M, class E1, int S1, class E2, int S2> inline bool 00722 operator<(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) 00723 { for (int i=0; i < M; ++i) if (l[i] >= r[i]) return false; 00724 return true; } 00726 template <int M, class E1, int S1, class E2> inline bool 00727 operator<(const Vec<M,E1,S1>& v, const E2& e) 00728 { for (int i=0; i < M; ++i) if (v[i] >= e) return false; 00729 return true; } 00730 00732 template <int M, class E1, int S1, class E2, int S2> inline bool 00733 operator>(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) 00734 { for (int i=0; i < M; ++i) if (l[i] <= r[i]) return false; 00735 return true; } 00737 template <int M, class E1, int S1, class E2> inline bool 00738 operator>(const Vec<M,E1,S1>& v, const E2& e) 00739 { for (int i=0; i < M; ++i) if (v[i] <= e) return false; 00740 return true; } 00741 00744 template <int M, class E1, int S1, class E2, int S2> inline bool 00745 operator<=(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) 00746 { for (int i=0; i < M; ++i) if (l[i] > r[i]) return false; 00747 return true; } 00750 template <int M, class E1, int S1, class E2> inline bool 00751 operator<=(const Vec<M,E1,S1>& v, const E2& e) 00752 { for (int i=0; i < M; ++i) if (v[i] > e) return false; 00753 return true; } 00754 00757 template <int M, class E1, int S1, class E2, int S2> inline bool 00758 operator>=(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) 00759 { for (int i=0; i < M; ++i) if (l[i] < r[i]) return false; 00760 return true; } 00763 template <int M, class E1, int S1, class E2> inline bool 00764 operator>=(const Vec<M,E1,S1>& v, const E2& e) 00765 { for (int i=0; i < M; ++i) if (v[i] < e) return false; 00766 return true; } 00767 00769 // Global operators involving a vector and a scalar. // 00771 00772 // I haven't been able to figure out a nice way to templatize for the 00773 // built-in reals without introducing a lot of unwanted type matches 00774 // as well. So we'll just grind them out explicitly here. 00775 00776 // SCALAR MULTIPLY 00777 00778 // v = v*real, real*v 00779 template <int M, class E, int S> inline 00780 typename Vec<M,E,S>::template Result<float>::Mul 00781 operator*(const Vec<M,E,S>& l, const float& r) 00782 { return Vec<M,E,S>::template Result<float>::MulOp::perform(l,r); } 00783 template <int M, class E, int S> inline 00784 typename Vec<M,E,S>::template Result<float>::Mul 00785 operator*(const float& l, const Vec<M,E,S>& r) {return r*l;} 00786 00787 template <int M, class E, int S> inline 00788 typename Vec<M,E,S>::template Result<double>::Mul 00789 operator*(const Vec<M,E,S>& l, const double& r) 00790 { return Vec<M,E,S>::template Result<double>::MulOp::perform(l,r); } 00791 template <int M, class E, int S> inline 00792 typename Vec<M,E,S>::template Result<double>::Mul 00793 operator*(const double& l, const Vec<M,E,S>& r) {return r*l;} 00794 00795 template <int M, class E, int S> inline 00796 typename Vec<M,E,S>::template Result<long double>::Mul 00797 operator*(const Vec<M,E,S>& l, const long double& r) 00798 { return Vec<M,E,S>::template Result<long double>::MulOp::perform(l,r); } 00799 template <int M, class E, int S> inline 00800 typename Vec<M,E,S>::template Result<long double>::Mul 00801 operator*(const long double& l, const Vec<M,E,S>& r) {return r*l;} 00802 00803 // v = v*int, int*v -- just convert int to v's precision float 00804 template <int M, class E, int S> inline 00805 typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Mul 00806 operator*(const Vec<M,E,S>& l, int r) {return l * (typename CNT<E>::Precision)r;} 00807 template <int M, class E, int S> inline 00808 typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Mul 00809 operator*(int l, const Vec<M,E,S>& r) {return r * (typename CNT<E>::Precision)l;} 00810 00811 // Complex, conjugate, and negator are all easy to templatize. 00812 00813 // v = v*complex, complex*v 00814 template <int M, class E, int S, class R> inline 00815 typename Vec<M,E,S>::template Result<std::complex<R> >::Mul 00816 operator*(const Vec<M,E,S>& l, const std::complex<R>& r) 00817 { return Vec<M,E,S>::template Result<std::complex<R> >::MulOp::perform(l,r); } 00818 template <int M, class E, int S, class R> inline 00819 typename Vec<M,E,S>::template Result<std::complex<R> >::Mul 00820 operator*(const std::complex<R>& l, const Vec<M,E,S>& r) {return r*l;} 00821 00822 // v = v*conjugate, conjugate*v (convert conjugate->complex) 00823 template <int M, class E, int S, class R> inline 00824 typename Vec<M,E,S>::template Result<std::complex<R> >::Mul 00825 operator*(const Vec<M,E,S>& l, const conjugate<R>& r) {return l*(std::complex<R>)r;} 00826 template <int M, class E, int S, class R> inline 00827 typename Vec<M,E,S>::template Result<std::complex<R> >::Mul 00828 operator*(const conjugate<R>& l, const Vec<M,E,S>& r) {return r*(std::complex<R>)l;} 00829 00830 // v = v*negator, negator*v: convert negator to standard number 00831 template <int M, class E, int S, class R> inline 00832 typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Mul 00833 operator*(const Vec<M,E,S>& l, const negator<R>& r) {return l * (typename negator<R>::StdNumber)(R)r;} 00834 template <int M, class E, int S, class R> inline 00835 typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Mul 00836 operator*(const negator<R>& l, const Vec<M,E,S>& r) {return r * (typename negator<R>::StdNumber)(R)l;} 00837 00838 00839 // SCALAR DIVIDE. This is a scalar operation when the scalar is on the right, 00840 // but when it is on the left it means scalar * pseudoInverse(vec), which is 00841 // a row. 00842 00843 // v = v/real, real/v 00844 template <int M, class E, int S> inline 00845 typename Vec<M,E,S>::template Result<float>::Dvd 00846 operator/(const Vec<M,E,S>& l, const float& r) 00847 { return Vec<M,E,S>::template Result<float>::DvdOp::perform(l,r); } 00848 template <int M, class E, int S> inline 00849 typename CNT<float>::template Result<Vec<M,E,S> >::Dvd 00850 operator/(const float& l, const Vec<M,E,S>& r) 00851 { return CNT<float>::template Result<Vec<M,E,S> >::DvdOp::perform(l,r); } 00852 00853 template <int M, class E, int S> inline 00854 typename Vec<M,E,S>::template Result<double>::Dvd 00855 operator/(const Vec<M,E,S>& l, const double& r) 00856 { return Vec<M,E,S>::template Result<double>::DvdOp::perform(l,r); } 00857 template <int M, class E, int S> inline 00858 typename CNT<double>::template Result<Vec<M,E,S> >::Dvd 00859 operator/(const double& l, const Vec<M,E,S>& r) 00860 { return CNT<double>::template Result<Vec<M,E,S> >::DvdOp::perform(l,r); } 00861 00862 template <int M, class E, int S> inline 00863 typename Vec<M,E,S>::template Result<long double>::Dvd 00864 operator/(const Vec<M,E,S>& l, const long double& r) 00865 { return Vec<M,E,S>::template Result<long double>::DvdOp::perform(l,r); } 00866 template <int M, class E, int S> inline 00867 typename CNT<long double>::template Result<Vec<M,E,S> >::Dvd 00868 operator/(const long double& l, const Vec<M,E,S>& r) 00869 { return CNT<long double>::template Result<Vec<M,E,S> >::DvdOp::perform(l,r); } 00870 00871 // v = v/int, int/v -- just convert int to v's precision float 00872 template <int M, class E, int S> inline 00873 typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Dvd 00874 operator/(const Vec<M,E,S>& l, int r) {return l / (typename CNT<E>::Precision)r;} 00875 template <int M, class E, int S> inline 00876 typename CNT<typename CNT<E>::Precision>::template Result<Vec<M,E,S> >::Dvd 00877 operator/(int l, const Vec<M,E,S>& r) {return (typename CNT<E>::Precision)l / r;} 00878 00879 00880 // Complex, conjugate, and negator are all easy to templatize. 00881 00882 // v = v/complex, complex/v 00883 template <int M, class E, int S, class R> inline 00884 typename Vec<M,E,S>::template Result<std::complex<R> >::Dvd 00885 operator/(const Vec<M,E,S>& l, const std::complex<R>& r) 00886 { return Vec<M,E,S>::template Result<std::complex<R> >::DvdOp::perform(l,r); } 00887 template <int M, class E, int S, class R> inline 00888 typename CNT<std::complex<R> >::template Result<Vec<M,E,S> >::Dvd 00889 operator/(const std::complex<R>& l, const Vec<M,E,S>& r) 00890 { return CNT<std::complex<R> >::template Result<Vec<M,E,S> >::DvdOp::perform(l,r); } 00891 00892 // v = v/conjugate, conjugate/v (convert conjugate->complex) 00893 template <int M, class E, int S, class R> inline 00894 typename Vec<M,E,S>::template Result<std::complex<R> >::Dvd 00895 operator/(const Vec<M,E,S>& l, const conjugate<R>& r) {return l/(std::complex<R>)r;} 00896 template <int M, class E, int S, class R> inline 00897 typename CNT<std::complex<R> >::template Result<Vec<M,E,S> >::Dvd 00898 operator/(const conjugate<R>& l, const Vec<M,E,S>& r) {return (std::complex<R>)l/r;} 00899 00900 // v = v/negator, negator/v: convert negator to number 00901 template <int M, class E, int S, class R> inline 00902 typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Dvd 00903 operator/(const Vec<M,E,S>& l, const negator<R>& r) {return l/(typename negator<R>::StdNumber)(R)r;} 00904 template <int M, class E, int S, class R> inline 00905 typename CNT<R>::template Result<Vec<M,E,S> >::Dvd 00906 operator/(const negator<R>& l, const Vec<M,E,S>& r) {return (typename negator<R>::StdNumber)(R)l/r;} 00907 00908 00909 // Add and subtract are odd as scalar ops. They behave as though the 00910 // scalar stands for a vector each of whose elements is that scalar, 00911 // and then a normal vector add or subtract is done. 00912 00913 // SCALAR ADD 00914 00915 // v = v+real, real+v 00916 template <int M, class E, int S> inline 00917 typename Vec<M,E,S>::template Result<float>::Add 00918 operator+(const Vec<M,E,S>& l, const float& r) 00919 { return Vec<M,E,S>::template Result<float>::AddOp::perform(l,r); } 00920 template <int M, class E, int S> inline 00921 typename Vec<M,E,S>::template Result<float>::Add 00922 operator+(const float& l, const Vec<M,E,S>& r) {return r+l;} 00923 00924 template <int M, class E, int S> inline 00925 typename Vec<M,E,S>::template Result<double>::Add 00926 operator+(const Vec<M,E,S>& l, const double& r) 00927 { return Vec<M,E,S>::template Result<double>::AddOp::perform(l,r); } 00928 template <int M, class E, int S> inline 00929 typename Vec<M,E,S>::template Result<double>::Add 00930 operator+(const double& l, const Vec<M,E,S>& r) {return r+l;} 00931 00932 template <int M, class E, int S> inline 00933 typename Vec<M,E,S>::template Result<long double>::Add 00934 operator+(const Vec<M,E,S>& l, const long double& r) 00935 { return Vec<M,E,S>::template Result<long double>::AddOp::perform(l,r); } 00936 template <int M, class E, int S> inline 00937 typename Vec<M,E,S>::template Result<long double>::Add 00938 operator+(const long double& l, const Vec<M,E,S>& r) {return r+l;} 00939 00940 // v = v+int, int+v -- just convert int to v's precision float 00941 template <int M, class E, int S> inline 00942 typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Add 00943 operator+(const Vec<M,E,S>& l, int r) {return l + (typename CNT<E>::Precision)r;} 00944 template <int M, class E, int S> inline 00945 typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Add 00946 operator+(int l, const Vec<M,E,S>& r) {return r + (typename CNT<E>::Precision)l;} 00947 00948 // Complex, conjugate, and negator are all easy to templatize. 00949 00950 // v = v+complex, complex+v 00951 template <int M, class E, int S, class R> inline 00952 typename Vec<M,E,S>::template Result<std::complex<R> >::Add 00953 operator+(const Vec<M,E,S>& l, const std::complex<R>& r) 00954 { return Vec<M,E,S>::template Result<std::complex<R> >::AddOp::perform(l,r); } 00955 template <int M, class E, int S, class R> inline 00956 typename Vec<M,E,S>::template Result<std::complex<R> >::Add 00957 operator+(const std::complex<R>& l, const Vec<M,E,S>& r) {return r+l;} 00958 00959 // v = v+conjugate, conjugate+v (convert conjugate->complex) 00960 template <int M, class E, int S, class R> inline 00961 typename Vec<M,E,S>::template Result<std::complex<R> >::Add 00962 operator+(const Vec<M,E,S>& l, const conjugate<R>& r) {return l+(std::complex<R>)r;} 00963 template <int M, class E, int S, class R> inline 00964 typename Vec<M,E,S>::template Result<std::complex<R> >::Add 00965 operator+(const conjugate<R>& l, const Vec<M,E,S>& r) {return r+(std::complex<R>)l;} 00966 00967 // v = v+negator, negator+v: convert negator to standard number 00968 template <int M, class E, int S, class R> inline 00969 typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Add 00970 operator+(const Vec<M,E,S>& l, const negator<R>& r) {return l + (typename negator<R>::StdNumber)(R)r;} 00971 template <int M, class E, int S, class R> inline 00972 typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Add 00973 operator+(const negator<R>& l, const Vec<M,E,S>& r) {return r + (typename negator<R>::StdNumber)(R)l;} 00974 00975 // SCALAR SUBTRACT -- careful, not commutative. 00976 00977 // v = v-real, real-v 00978 template <int M, class E, int S> inline 00979 typename Vec<M,E,S>::template Result<float>::Sub 00980 operator-(const Vec<M,E,S>& l, const float& r) 00981 { return Vec<M,E,S>::template Result<float>::SubOp::perform(l,r); } 00982 template <int M, class E, int S> inline 00983 typename CNT<float>::template Result<Vec<M,E,S> >::Sub 00984 operator-(const float& l, const Vec<M,E,S>& r) 00985 { return CNT<float>::template Result<Vec<M,E,S> >::SubOp::perform(l,r); } 00986 00987 template <int M, class E, int S> inline 00988 typename Vec<M,E,S>::template Result<double>::Sub 00989 operator-(const Vec<M,E,S>& l, const double& r) 00990 { return Vec<M,E,S>::template Result<double>::SubOp::perform(l,r); } 00991 template <int M, class E, int S> inline 00992 typename CNT<double>::template Result<Vec<M,E,S> >::Sub 00993 operator-(const double& l, const Vec<M,E,S>& r) 00994 { return CNT<double>::template Result<Vec<M,E,S> >::SubOp::perform(l,r); } 00995 00996 template <int M, class E, int S> inline 00997 typename Vec<M,E,S>::template Result<long double>::Sub 00998 operator-(const Vec<M,E,S>& l, const long double& r) 00999 { return Vec<M,E,S>::template Result<long double>::SubOp::perform(l,r); } 01000 template <int M, class E, int S> inline 01001 typename CNT<long double>::template Result<Vec<M,E,S> >::Sub 01002 operator-(const long double& l, const Vec<M,E,S>& r) 01003 { return CNT<long double>::template Result<Vec<M,E,S> >::SubOp::perform(l,r); } 01004 01005 // v = v-int, int-v // just convert int to v's precision float 01006 template <int M, class E, int S> inline 01007 typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Sub 01008 operator-(const Vec<M,E,S>& l, int r) {return l - (typename CNT<E>::Precision)r;} 01009 template <int M, class E, int S> inline 01010 typename CNT<typename CNT<E>::Precision>::template Result<Vec<M,E,S> >::Sub 01011 operator-(int l, const Vec<M,E,S>& r) {return (typename CNT<E>::Precision)l - r;} 01012 01013 01014 // Complex, conjugate, and negator are all easy to templatize. 01015 01016 // v = v-complex, complex-v 01017 template <int M, class E, int S, class R> inline 01018 typename Vec<M,E,S>::template Result<std::complex<R> >::Sub 01019 operator-(const Vec<M,E,S>& l, const std::complex<R>& r) 01020 { return Vec<M,E,S>::template Result<std::complex<R> >::SubOp::perform(l,r); } 01021 template <int M, class E, int S, class R> inline 01022 typename CNT<std::complex<R> >::template Result<Vec<M,E,S> >::Sub 01023 operator-(const std::complex<R>& l, const Vec<M,E,S>& r) 01024 { return CNT<std::complex<R> >::template Result<Vec<M,E,S> >::SubOp::perform(l,r); } 01025 01026 // v = v-conjugate, conjugate-v (convert conjugate->complex) 01027 template <int M, class E, int S, class R> inline 01028 typename Vec<M,E,S>::template Result<std::complex<R> >::Sub 01029 operator-(const Vec<M,E,S>& l, const conjugate<R>& r) {return l-(std::complex<R>)r;} 01030 template <int M, class E, int S, class R> inline 01031 typename CNT<std::complex<R> >::template Result<Vec<M,E,S> >::Sub 01032 operator-(const conjugate<R>& l, const Vec<M,E,S>& r) {return (std::complex<R>)l-r;} 01033 01034 // v = v-negator, negator-v: convert negator to standard number 01035 template <int M, class E, int S, class R> inline 01036 typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Sub 01037 operator-(const Vec<M,E,S>& l, const negator<R>& r) {return l-(typename negator<R>::StdNumber)(R)r;} 01038 template <int M, class E, int S, class R> inline 01039 typename CNT<R>::template Result<Vec<M,E,S> >::Sub 01040 operator-(const negator<R>& l, const Vec<M,E,S>& r) {return (typename negator<R>::StdNumber)(R)l-r;} 01041 01042 // Vec I/O 01043 template <int M, class E, int S, class CHAR, class TRAITS> inline 01044 std::basic_ostream<CHAR,TRAITS>& 01045 operator<<(std::basic_ostream<CHAR,TRAITS>& o, const Vec<M,E,S>& v) { 01046 o << "~[" << v[0]; for(int i=1;i<M;++i) o<<','<<v[i]; o<<']'; return o; 01047 } 01048 01051 template <int M, class E, int S, class CHAR, class TRAITS> inline 01052 std::basic_istream<CHAR,TRAITS>& 01053 operator>>(std::basic_istream<CHAR,TRAITS>& is, Vec<M,E,S>& v) { 01054 CHAR tilde; 01055 is >> tilde; if (is.fail()) return is; 01056 if (tilde != CHAR('~')) { 01057 tilde = CHAR(0); 01058 is.unget(); if (is.fail()) return is; 01059 } 01060 01061 CHAR openBracket, closeBracket; 01062 is >> openBracket; if (is.fail()) return is; 01063 if (openBracket==CHAR('(')) 01064 closeBracket = CHAR(')'); 01065 else if (openBracket==CHAR('[')) 01066 closeBracket = CHAR(']'); 01067 else { 01068 closeBracket = CHAR(0); 01069 is.unget(); if (is.fail()) return is; 01070 } 01071 01072 // If we saw a "~" but then we didn't see any brackets, that's an 01073 // error. Set the fail bit and return. 01074 if (tilde != CHAR(0) && closeBracket == CHAR(0)) { 01075 is.setstate( std::ios::failbit ); 01076 return is; 01077 } 01078 01079 for (int i=0; i < M; ++i) { 01080 is >> v[i]; 01081 if (is.fail()) return is; 01082 if (i != M-1) { 01083 CHAR c; is >> c; if (is.fail()) return is; 01084 if (c != ',') is.unget(); 01085 if (is.fail()) return is; 01086 } 01087 } 01088 01089 // Get the closing bracket if there was an opening one. If we don't 01090 // see the expected character we'll set the fail bit in the istream. 01091 if (closeBracket != CHAR(0)) { 01092 CHAR closer; is >> closer; if (is.fail()) return is; 01093 if (closer != closeBracket) { 01094 is.unget(); if (is.fail()) return is; 01095 is.setstate( std::ios::failbit ); 01096 } 01097 } 01098 01099 return is; 01100 } 01101 01102 } //namespace SimTK 01103 01104 01105 #endif //SimTK_SIMMATRIX_SMALLMATRIX_VEC_H_