Simbody
3.4 (development)
|
00001 #ifndef SimTK_SIMMATRIX_SMALLMATRIX_VEC_H_ 00002 #define SimTK_SIMMATRIX_SMALLMATRIX_VEC_H_ 00003 00004 /* -------------------------------------------------------------------------- * 00005 * Simbody(tm): SimTKcommon * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK 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/home/simbody. * 00011 * * 00012 * Portions copyright (c) 2005-12 Stanford University and the Authors. * 00013 * Authors: Michael Sherman * 00014 * Contributors: Peter Eastman * 00015 * * 00016 * Licensed under the Apache License, Version 2.0 (the "License"); you may * 00017 * not use this file except in compliance with the License. You may obtain a * 00018 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * 00019 * * 00020 * Unless required by applicable law or agreed to in writing, software * 00021 * distributed under the License is distributed on an "AS IS" BASIS, * 00022 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 00023 * See the License for the specific language governing permissions and * 00024 * limitations under the License. * 00025 * -------------------------------------------------------------------------- */ 00026 00031 #include "SimTKcommon/internal/common.h" 00032 00033 namespace SimTK { 00034 00035 00036 // The following functions are used internally by Vec. 00037 00038 // Hide from Doxygen. 00040 namespace Impl { 00041 00042 // For those wimpy compilers that don't unroll short, constant-limit loops, 00043 // Peter Eastman added these recursive template implementations of 00044 // elementwise add, subtract, and copy. Sherm added multiply and divide. 00045 00046 template <class E1, int S1, class E2, int S2> void 00047 conformingAdd(const Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2, 00048 Vec<1,typename CNT<E1>::template Result<E2>::Add>& result) { 00049 result[0] = r1[0] + r2[0]; 00050 } 00051 template <int N, class E1, int S1, class E2, int S2> void 00052 conformingAdd(const Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2, 00053 Vec<N,typename CNT<E1>::template Result<E2>::Add>& result) { 00054 conformingAdd(reinterpret_cast<const Vec<N-1,E1,S1>&>(r1), 00055 reinterpret_cast<const Vec<N-1,E2,S2>&>(r2), 00056 reinterpret_cast<Vec<N-1,typename CNT<E1>:: 00057 template Result<E2>::Add>&>(result)); 00058 result[N-1] = r1[N-1] + r2[N-1]; 00059 } 00060 00061 template <class E1, int S1, class E2, int S2> void 00062 conformingSubtract(const Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2, 00063 Vec<1,typename CNT<E1>::template Result<E2>::Sub>& result) { 00064 result[0] = r1[0] - r2[0]; 00065 } 00066 template <int N, class E1, int S1, class E2, int S2> void 00067 conformingSubtract(const Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2, 00068 Vec<N,typename CNT<E1>::template Result<E2>::Sub>& result) { 00069 conformingSubtract(reinterpret_cast<const Vec<N-1,E1,S1>&>(r1), 00070 reinterpret_cast<const Vec<N-1,E2,S2>&>(r2), 00071 reinterpret_cast<Vec<N-1,typename CNT<E1>:: 00072 template Result<E2>::Sub>&>(result)); 00073 result[N-1] = r1[N-1] - r2[N-1]; 00074 } 00075 00076 template <class E1, int S1, class E2, int S2> void 00077 elementwiseMultiply(const Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2, 00078 Vec<1,typename CNT<E1>::template Result<E2>::Mul>& result) { 00079 result[0] = r1[0] * r2[0]; 00080 } 00081 template <int N, class E1, int S1, class E2, int S2> void 00082 elementwiseMultiply(const Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2, 00083 Vec<N,typename CNT<E1>::template Result<E2>::Mul>& result) { 00084 elementwiseMultiply(reinterpret_cast<const Vec<N-1,E1,S1>&>(r1), 00085 reinterpret_cast<const Vec<N-1,E2,S2>&>(r2), 00086 reinterpret_cast<Vec<N-1,typename CNT<E1>:: 00087 template Result<E2>::Mul>&>(result)); 00088 result[N-1] = r1[N-1] * r2[N-1]; 00089 } 00090 00091 template <class E1, int S1, class E2, int S2> void 00092 elementwiseDivide(const Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2, 00093 Vec<1,typename CNT<E1>::template Result<E2>::Dvd>& result) { 00094 result[0] = r1[0] / r2[0]; 00095 } 00096 template <int N, class E1, int S1, class E2, int S2> void 00097 elementwiseDivide(const Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2, 00098 Vec<N,typename CNT<E1>::template Result<E2>::Dvd>& result) { 00099 elementwiseDivide(reinterpret_cast<const Vec<N-1,E1,S1>&>(r1), 00100 reinterpret_cast<const Vec<N-1,E2,S2>&>(r2), 00101 reinterpret_cast<Vec<N-1,typename CNT<E1>:: 00102 template Result<E2>::Dvd>&>(result)); 00103 result[N-1] = r1[N-1] / r2[N-1]; 00104 } 00105 00106 template <class E1, int S1, class E2, int S2> void 00107 copy(Vec<1,E1,S1>& r1, const Vec<1,E2,S2>& r2) { 00108 r1[0] = r2[0]; 00109 } 00110 template <int N, class E1, int S1, class E2, int S2> void 00111 copy(Vec<N,E1,S1>& r1, const Vec<N,E2,S2>& r2) { 00112 copy(reinterpret_cast<Vec<N-1,E1,S1>&>(r1), 00113 reinterpret_cast<const Vec<N-1,E2,S2>&>(r2)); 00114 r1[N-1] = r2[N-1]; 00115 } 00116 00117 } 00130 template <int M, class ELT, int STRIDE> 00131 class Vec { 00132 public: 00138 typedef ELT E; 00140 typedef typename CNT<E>::TNeg ENeg; 00142 typedef typename CNT<E>::TWithoutNegator EWithoutNegator; 00145 typedef typename CNT<E>::TReal EReal; 00149 typedef typename CNT<E>::TImag EImag; 00152 typedef typename CNT<E>::TComplex EComplex; 00154 typedef typename CNT<E>::THerm EHerm; 00156 typedef typename CNT<E>::TPosTrans EPosTrans; 00159 typedef typename CNT<E>::TSqHermT ESqHermT; 00161 typedef typename CNT<E>::TSqTHerm ESqTHerm; 00163 typedef typename CNT<E>::TSqrt ESqrt; 00165 typedef typename CNT<E>::TAbs EAbs; 00168 typedef typename CNT<E>::TStandard EStandard; 00171 typedef typename CNT<E>::TInvert EInvert; 00173 typedef typename CNT<E>::TNormalize ENormalize; 00174 00175 typedef typename CNT<E>::Scalar EScalar; 00176 typedef typename CNT<E>::ULessScalar EULessScalar; 00177 typedef typename CNT<E>::Number ENumber; 00178 typedef typename CNT<E>::StdNumber EStdNumber; 00179 typedef typename CNT<E>::Precision EPrecision; 00180 typedef typename CNT<E>::ScalarNormSq EScalarNormSq; 00181 00184 enum { 00185 NRows = M, 00186 NCols = 1, 00187 NPackedElements = M, 00188 NActualElements = M * STRIDE, // includes trailing gap 00189 NActualScalars = CNT<E>::NActualScalars * NActualElements, 00190 RowSpacing = STRIDE, 00191 ColSpacing = NActualElements, 00192 ImagOffset = NTraits<ENumber>::ImagOffset, 00193 RealStrideFactor = 1, // composite types don't change size when 00194 // cast from complex to real or imaginary 00195 ArgDepth = ((int)CNT<E>::ArgDepth < (int)MAX_RESOLVED_DEPTH 00196 ? CNT<E>::ArgDepth + 1 00197 : MAX_RESOLVED_DEPTH), 00198 IsScalar = 0, 00199 IsULessScalar = 0, 00200 IsNumber = 0, 00201 IsStdNumber = 0, 00202 IsPrecision = 0, 00203 SignInterpretation = CNT<E>::SignInterpretation 00204 }; 00205 00206 // These are reinterpretations of the current data, so have the 00207 // same packing (stride). 00208 00210 typedef Vec<M,E,STRIDE> T; 00213 typedef Vec<M,ENeg,STRIDE> TNeg; 00216 typedef Vec<M,EWithoutNegator,STRIDE> TWithoutNegator; 00219 typedef Vec<M,EReal,STRIDE*CNT<E>::RealStrideFactor> 00220 TReal; 00223 typedef Vec<M,EImag,STRIDE*CNT<E>::RealStrideFactor> 00224 TImag; 00225 typedef Vec<M,EComplex,STRIDE> TComplex; 00229 typedef Row<M,EHerm,STRIDE> THerm; 00232 typedef Row<M,E,STRIDE> TPosTrans; 00234 typedef E TElement; 00236 typedef E TRow; 00238 typedef Vec TCol; 00239 00240 // These are the results of calculations, so are returned in new, packed 00241 // memory. Be sure to refer to element types here which are also packed. 00242 typedef Vec<M,ESqrt,1> TSqrt; // Note stride 00243 typedef Vec<M,EAbs,1> TAbs; // Note stride 00244 typedef Vec<M,EStandard,1> TStandard; 00245 typedef Row<M,EInvert,1> TInvert; 00246 typedef Vec<M,ENormalize,1> TNormalize; 00247 00248 typedef ESqHermT TSqHermT; // result of self dot product 00249 typedef SymMat<M,ESqTHerm> TSqTHerm; // result of self outer product 00250 00251 // These recurse right down to the underlying scalar type no matter how 00252 // deep the elements are. 00253 typedef EScalar Scalar; 00254 typedef EULessScalar ULessScalar; 00255 typedef ENumber Number; 00256 typedef EStdNumber StdNumber; 00257 typedef EPrecision Precision; 00258 typedef EScalarNormSq ScalarNormSq; 00263 static int size() { return M; } 00265 static int nrow() { return M; } 00267 static int ncol() { return 1; } 00268 00269 00272 ScalarNormSq scalarNormSqr() const { 00273 ScalarNormSq sum(0); 00274 for(int i=0;i<M;++i) sum += CNT<E>::scalarNormSqr(d[i*STRIDE]); 00275 return sum; 00276 } 00277 00282 TSqrt sqrt() const { 00283 TSqrt vsqrt; 00284 for(int i=0;i<M;++i) vsqrt[i] = CNT<E>::sqrt(d[i*STRIDE]); 00285 return vsqrt; 00286 } 00287 00292 TAbs abs() const { 00293 TAbs vabs; 00294 for(int i=0;i<M;++i) vabs[i] = CNT<E>::abs(d[i*STRIDE]); 00295 return vabs; 00296 } 00297 00302 TStandard standardize() const { 00303 TStandard vstd; 00304 for(int i=0;i<M;++i) vstd[i] = CNT<E>::standardize(d[i*STRIDE]); 00305 return vstd; 00306 } 00307 00311 EStandard sum() const { 00312 E sum(0); 00313 for (int i=0;i<M;++i) sum += d[i*STRIDE]; 00314 return CNT<E>::standardize(sum); 00315 } 00316 00317 00318 // This gives the resulting vector type when (v[i] op P) is applied to 00319 // each element of v. It is a vector of length M, stride 1, and element 00320 // types which are the regular composite result of E op P. Typically P is 00321 // a scalar type but it doesn't have to be. 00322 template <class P> struct EltResult { 00323 typedef Vec<M, typename CNT<E>::template Result<P>::Mul, 1> Mul; 00324 typedef Vec<M, typename CNT<E>::template Result<P>::Dvd, 1> Dvd; 00325 typedef Vec<M, typename CNT<E>::template Result<P>::Add, 1> Add; 00326 typedef Vec<M, typename CNT<E>::template Result<P>::Sub, 1> Sub; 00327 }; 00328 00329 // This is the composite result for v op P where P is some kind of 00330 // appropriately shaped non-scalar type. 00331 template <class P> struct Result { 00332 typedef MulCNTs<M,1,ArgDepth,Vec,ColSpacing,RowSpacing, 00333 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth, 00334 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> MulOp; 00335 typedef typename MulOp::Type Mul; 00336 00337 typedef MulCNTsNonConforming<M,1,ArgDepth,Vec,ColSpacing,RowSpacing, 00338 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth, 00339 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> MulOpNonConforming; 00340 typedef typename MulOpNonConforming::Type MulNon; 00341 00342 typedef DvdCNTs<M,1,ArgDepth,Vec,ColSpacing,RowSpacing, 00343 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth, 00344 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> DvdOp; 00345 typedef typename DvdOp::Type Dvd; 00346 00347 typedef AddCNTs<M,1,ArgDepth,Vec,ColSpacing,RowSpacing, 00348 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth, 00349 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> AddOp; 00350 typedef typename AddOp::Type Add; 00351 00352 typedef SubCNTs<M,1,ArgDepth,Vec,ColSpacing,RowSpacing, 00353 CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth, 00354 P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> SubOp; 00355 typedef typename SubOp::Type Sub; 00356 }; 00357 00363 template <class P> struct Substitute { 00364 typedef Vec<M,P> Type; 00365 }; 00366 00370 Vec(){ 00371 #ifndef NDEBUG 00372 setToNaN(); 00373 #endif 00374 } 00375 00376 // It's important not to use the default copy constructor or copy 00377 // assignment because the compiler doesn't understand that we may 00378 // have noncontiguous storage and will try to copy the whole array. 00379 00383 Vec(const Vec& src) { 00384 Impl::copy(*this, src); 00385 } 00390 Vec& operator=(const Vec& src) { 00391 Impl::copy(*this, src); 00392 return *this; 00393 } 00394 00397 template <int SS> Vec(const Vec<M,E,SS>& src) { 00398 Impl::copy(*this, src); 00399 } 00400 00403 template <int SS> Vec(const Vec<M,ENeg,SS>& src) { 00404 Impl::copy(*this, src); 00405 } 00406 00409 template <class EE, int SS> explicit Vec(const Vec<M,EE,SS>& src) { 00410 Impl::copy(*this, src); 00411 } 00412 00415 explicit Vec(const E& e) {for (int i=0;i<M;++i) d[i*STRIDE]=e;} 00416 00421 explicit Vec(const ENeg& ne) { 00422 const E e = ne; // requires floating point negation 00423 for (int i=0;i<M;++i) d[i*STRIDE]=e; 00424 } 00425 00430 explicit Vec(int i) {new (this) Vec(E(Precision(i)));} 00431 00432 // A bevy of constructors for Vecs up to length 9. 00433 00435 Vec(const E& e0,const E& e1) 00436 { assert(M==2);(*this)[0]=e0;(*this)[1]=e1; } 00437 Vec(const E& e0,const E& e1,const E& e2) 00438 { assert(M==3);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2; } 00439 Vec(const E& e0,const E& e1,const E& e2,const E& e3) 00440 { assert(M==4);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;(*this)[3]=e3; } 00441 Vec(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4) 00442 { assert(M==5);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2; 00443 (*this)[3]=e3;(*this)[4]=e4; } 00444 Vec(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5) 00445 { assert(M==6);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2; 00446 (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5; } 00447 Vec(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5, const E& e6) 00448 { assert(M==7);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2; 00449 (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6; } 00450 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) 00451 { assert(M==8);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2; 00452 (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6;(*this)[7]=e7; } 00453 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) 00454 { assert(M==9);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2; 00455 (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6;(*this)[7]=e7;(*this)[8]=e8; } 00456 00461 template <class EE> explicit Vec(const EE* p) 00462 { assert(p); for(int i=0;i<M;++i) d[i*STRIDE]=p[i]; } 00463 00468 template <class EE> Vec& operator=(const EE* p) 00469 { assert(p); for(int i=0;i<M;++i) d[i*STRIDE]=p[i]; return *this; } 00470 00473 template <class EE, int SS> Vec& operator=(const Vec<M,EE,SS>& vv) 00474 { Impl::copy(*this, vv); return *this; } 00475 00478 template <class EE, int SS> Vec& operator+=(const Vec<M,EE,SS>& r) 00479 { for(int i=0;i<M;++i) d[i*STRIDE] += r[i]; return *this; } 00483 template <class EE, int SS> Vec& operator+=(const Vec<M,negator<EE>,SS>& r) 00484 { for(int i=0;i<M;++i) d[i*STRIDE] -= -(r[i]); return *this; } 00485 00488 template <class EE, int SS> Vec& operator-=(const Vec<M,EE,SS>& r) 00489 { for(int i=0;i<M;++i) d[i*STRIDE] -= r[i]; return *this; } 00493 template <class EE, int SS> Vec& operator-=(const Vec<M,negator<EE>,SS>& r) 00494 { for(int i=0;i<M;++i) d[i*STRIDE] += -(r[i]); return *this; } 00495 00496 // Conforming binary ops with 'this' on left, producing new packed result. 00497 // Cases: v=v+v, v=v-v, m=v*r 00498 00500 template <class EE, int SS> Vec<M,typename CNT<E>::template Result<EE>::Add> 00501 conformingAdd(const Vec<M,EE,SS>& r) const { 00502 Vec<M,typename CNT<E>::template Result<EE>::Add> result; 00503 Impl::conformingAdd(*this, r, result); 00504 return result; 00505 } 00507 template <class EE, int SS> Vec<M,typename CNT<E>::template Result<EE>::Sub> 00508 conformingSubtract(const Vec<M,EE,SS>& r) const { 00509 Vec<M,typename CNT<E>::template Result<EE>::Sub> result; 00510 Impl::conformingSubtract(*this, r, result); 00511 return result; 00512 } 00513 00516 template <class EE, int SS> Mat<M,M,typename CNT<E>::template Result<EE>::Mul> 00517 conformingMultiply(const Row<M,EE,SS>& r) const { 00518 Mat<M,M,typename CNT<E>::template Result<EE>::Mul> result; 00519 for (int j=0;j<M;++j) result(j) = scalarMultiply(r(j)); 00520 return result; 00521 } 00522 00524 template <class EE, int SS> Vec<M,typename CNT<E>::template Result<EE>::Mul> 00525 elementwiseMultiply(const Vec<M,EE,SS>& r) const { 00526 Vec<M,typename CNT<E>::template Result<EE>::Mul> result; 00527 Impl::elementwiseMultiply(*this, r, result); 00528 return result; 00529 } 00531 template <class EE, int SS> Vec<M,typename CNT<E>::template Result<EE>::Dvd> 00532 elementwiseDivide(const Vec<M,EE,SS>& r) const { 00533 Vec<M,typename CNT<E>::template Result<EE>::Dvd> result; 00534 Impl::elementwiseDivide(*this, r, result); 00535 return result; 00536 } 00537 00541 const E& operator[](int i) const 00542 { assert(0 <= i && i < M); return d[i*STRIDE]; } 00544 const E& operator()(int i) const {return (*this)[i];} 00545 00549 E& operator[](int i) {assert(0 <= i && i < M); return d[i*STRIDE];} 00551 E& operator()(int i) {return (*this)[i];} 00552 00553 ScalarNormSq normSqr() const { return scalarNormSqr(); } 00554 typename CNT<ScalarNormSq>::TSqrt 00555 norm() const { return CNT<ScalarNormSq>::sqrt(scalarNormSqr()); } 00556 00568 TNormalize normalize() const { 00569 if (CNT<E>::IsScalar) { 00570 return castAwayNegatorIfAny() / (SignInterpretation*norm()); 00571 } else { 00572 TNormalize elementwiseNormalized; 00573 for (int i=0; i<M; ++i) 00574 elementwiseNormalized[i] = CNT<E>::normalize((*this)[i]); 00575 return elementwiseNormalized; 00576 } 00577 } 00578 00580 TInvert invert() const {assert(false); return TInvert();} // TODO default inversion 00581 00583 const Vec& operator+() const { return *this; } 00587 const TNeg& operator-() const { return negate(); } 00590 TNeg& operator-() { return updNegate(); } 00594 const THerm& operator~() const { return transpose(); } 00598 THerm& operator~() { return updTranspose(); } 00599 00601 const TNeg& negate() const { return *reinterpret_cast<const TNeg*>(this); } 00604 TNeg& updNegate() { return *reinterpret_cast< TNeg*>(this); } 00605 00607 const THerm& transpose() const { return *reinterpret_cast<const THerm*>(this); } 00610 THerm& updTranspose() { return *reinterpret_cast< THerm*>(this); } 00611 00616 const TPosTrans& positionalTranspose() const 00617 { return *reinterpret_cast<const TPosTrans*>(this); } 00619 TPosTrans& updPositionalTranspose() 00620 { return *reinterpret_cast<TPosTrans*>(this); } 00621 00626 const TReal& real() const { return *reinterpret_cast<const TReal*>(this); } 00629 TReal& real() { return *reinterpret_cast< TReal*>(this); } 00630 00631 // Had to contort these next two routines to get them through VC++ 7.net 00632 00637 const TImag& imag() const { 00638 const int offs = ImagOffset; 00639 const EImag* p = reinterpret_cast<const EImag*>(this); 00640 return *reinterpret_cast<const TImag*>(p+offs); 00641 } 00644 TImag& imag() { 00645 const int offs = ImagOffset; 00646 EImag* p = reinterpret_cast<EImag*>(this); 00647 return *reinterpret_cast<TImag*>(p+offs); 00648 } 00649 00653 const TWithoutNegator& castAwayNegatorIfAny() const 00654 { return *reinterpret_cast<const TWithoutNegator*>(this); } 00657 TWithoutNegator& updCastAwayNegatorIfAny() 00658 { return *reinterpret_cast<TWithoutNegator*>(this); } 00659 00660 // These are elementwise binary operators, (this op ee) by default but 00661 // (ee op this) if 'FromLeft' appears in the name. The result is a packed 00662 // Vec<M> but the element type may change. These are mostly used to 00663 // implement global operators. We call these "scalar" operators but 00664 // actually the "scalar" can be a composite type. 00665 00666 //TODO: consider converting 'e' to Standard Numbers as precalculation and 00667 // changing return type appropriately. 00668 template <class EE> Vec<M, typename CNT<E>::template Result<EE>::Mul> 00669 scalarMultiply(const EE& e) const { 00670 Vec<M, typename CNT<E>::template Result<EE>::Mul> result; 00671 for (int i=0; i<M; ++i) result[i] = (*this)[i] * e; 00672 return result; 00673 } 00674 template <class EE> Vec<M, typename CNT<EE>::template Result<E>::Mul> 00675 scalarMultiplyFromLeft(const EE& e) const { 00676 Vec<M, typename CNT<EE>::template Result<E>::Mul> result; 00677 for (int i=0; i<M; ++i) result[i] = e * (*this)[i]; 00678 return result; 00679 } 00680 00681 // TODO: should precalculate and store 1/e, while converting to Standard 00682 // Numbers. Note that return type should change appropriately. 00683 template <class EE> Vec<M, typename CNT<E>::template Result<EE>::Dvd> 00684 scalarDivide(const EE& e) const { 00685 Vec<M, typename CNT<E>::template Result<EE>::Dvd> result; 00686 for (int i=0; i<M; ++i) result[i] = (*this)[i] / e; 00687 return result; 00688 } 00689 template <class EE> Vec<M, typename CNT<EE>::template Result<E>::Dvd> 00690 scalarDivideFromLeft(const EE& e) const { 00691 Vec<M, typename CNT<EE>::template Result<E>::Dvd> result; 00692 for (int i=0; i<M; ++i) result[i] = e / (*this)[i]; 00693 return result; 00694 } 00695 00696 template <class EE> Vec<M, typename CNT<E>::template Result<EE>::Add> 00697 scalarAdd(const EE& e) const { 00698 Vec<M, typename CNT<E>::template Result<EE>::Add> result; 00699 for (int i=0; i<M; ++i) result[i] = (*this)[i] + e; 00700 return result; 00701 } 00702 // Add is commutative, so no 'FromLeft'. 00703 00704 template <class EE> Vec<M, typename CNT<E>::template Result<EE>::Sub> 00705 scalarSubtract(const EE& e) const { 00706 Vec<M, typename CNT<E>::template Result<EE>::Sub> result; 00707 for (int i=0; i<M; ++i) result[i] = (*this)[i] - e; 00708 return result; 00709 } 00710 template <class EE> Vec<M, typename CNT<EE>::template Result<E>::Sub> 00711 scalarSubtractFromLeft(const EE& e) const { 00712 Vec<M, typename CNT<EE>::template Result<E>::Sub> result; 00713 for (int i=0; i<M; ++i) result[i] = e - (*this)[i]; 00714 return result; 00715 } 00716 00717 // Generic assignments for any element type not listed explicitly, including scalars. 00718 // These are done repeatedly for each element and only work if the operation can 00719 // be performed leaving the original element type. 00720 template <class EE> Vec& operator =(const EE& e) {return scalarEq(e);} 00721 template <class EE> Vec& operator+=(const EE& e) {return scalarPlusEq(e);} 00722 template <class EE> Vec& operator-=(const EE& e) {return scalarMinusEq(e);} 00723 template <class EE> Vec& operator*=(const EE& e) {return scalarTimesEq(e);} 00724 template <class EE> Vec& operator/=(const EE& e) {return scalarDivideEq(e);} 00725 00726 // Generalized element assignment & computed assignment methods. These will work 00727 // for any assignment-compatible element, not just scalars. 00728 template <class EE> Vec& scalarEq(const EE& ee) 00729 { for(int i=0;i<M;++i) d[i*STRIDE] = ee; return *this; } 00730 template <class EE> Vec& scalarPlusEq(const EE& ee) 00731 { for(int i=0;i<M;++i) d[i*STRIDE] += ee; return *this; } 00732 template <class EE> Vec& scalarMinusEq(const EE& ee) 00733 { for(int i=0;i<M;++i) d[i*STRIDE] -= ee; return *this; } 00734 template <class EE> Vec& scalarMinusEqFromLeft(const EE& ee) 00735 { for(int i=0;i<M;++i) d[i*STRIDE] = ee - d[i*STRIDE]; return *this; } 00736 template <class EE> Vec& scalarTimesEq(const EE& ee) 00737 { for(int i=0;i<M;++i) d[i*STRIDE] *= ee; return *this; } 00738 template <class EE> Vec& scalarTimesEqFromLeft(const EE& ee) 00739 { for(int i=0;i<M;++i) d[i*STRIDE] = ee * d[i*STRIDE]; return *this; } 00740 template <class EE> Vec& scalarDivideEq(const EE& ee) 00741 { for(int i=0;i<M;++i) d[i*STRIDE] /= ee; return *this; } 00742 template <class EE> Vec& scalarDivideEqFromLeft(const EE& ee) 00743 { for(int i=0;i<M;++i) d[i*STRIDE] = ee / d[i*STRIDE]; return *this; } 00744 00745 // Specialize for int to avoid warnings and ambiguities. 00746 Vec& scalarEq(int ee) {return scalarEq(Precision(ee));} 00747 Vec& scalarPlusEq(int ee) {return scalarPlusEq(Precision(ee));} 00748 Vec& scalarMinusEq(int ee) {return scalarMinusEq(Precision(ee));} 00749 Vec& scalarTimesEq(int ee) {return scalarTimesEq(Precision(ee));} 00750 Vec& scalarDivideEq(int ee) {return scalarDivideEq(Precision(ee));} 00751 Vec& scalarMinusEqFromLeft(int ee) {return scalarMinusEqFromLeft(Precision(ee));} 00752 Vec& scalarTimesEqFromLeft(int ee) {return scalarTimesEqFromLeft(Precision(ee));} 00753 Vec& scalarDivideEqFromLeft(int ee) {return scalarDivideEqFromLeft(Precision(ee));} 00754 00757 void setToNaN() { 00758 (*this) = CNT<ELT>::getNaN(); 00759 } 00760 00762 void setToZero() { 00763 (*this) = ELT(0); 00764 } 00765 00771 template <int MM> 00772 const Vec<MM,ELT,STRIDE>& getSubVec(int i) const { 00773 assert(0 <= i && i + MM <= M); 00774 return Vec<MM,ELT,STRIDE>::getAs(&(*this)[i]); 00775 } 00781 template <int MM> 00782 Vec<MM,ELT,STRIDE>& updSubVec(int i) { 00783 assert(0 <= i && i + MM <= M); 00784 return Vec<MM,ELT,STRIDE>::updAs(&(*this)[i]); 00785 } 00786 00787 00791 template <int MM> 00792 static const Vec& getSubVec(const Vec<MM,ELT,STRIDE>& v, int i) { 00793 assert(0 <= i && i + M <= MM); 00794 return getAs(&v[i]); 00795 } 00799 template <int MM> 00800 static Vec& updSubVec(Vec<MM,ELT,STRIDE>& v, int i) { 00801 assert(0 <= i && i + M <= MM); 00802 return updAs(&v[i]); 00803 } 00804 00808 Vec<M-1,ELT,1> drop1(int p) const { 00809 assert(0 <= p && p < M); 00810 Vec<M-1,ELT,1> out; 00811 int nxt=0; 00812 for (int i=0; i<M-1; ++i, ++nxt) { 00813 if (nxt==p) ++nxt; // skip the loser 00814 out[i] = (*this)[nxt]; 00815 } 00816 return out; 00817 } 00818 00822 template <class EE> Vec<M+1,ELT,1> append1(const EE& v) const { 00823 Vec<M+1,ELT,1> out; 00824 Vec<M,ELT,1>::updAs(&out[0]) = (*this); 00825 out[M] = v; 00826 return out; 00827 } 00828 00829 00835 template <class EE> Vec<M+1,ELT,1> insert1(int p, const EE& v) const { 00836 assert(0 <= p && p <= M); 00837 if (p==M) return append1(v); 00838 Vec<M+1,ELT,1> out; 00839 int nxt=0; 00840 for (int i=0; i<M; ++i, ++nxt) { 00841 if (i==p) out[nxt++] = v; 00842 out[nxt] = (*this)[i]; 00843 } 00844 return out; 00845 } 00846 00849 static const Vec& getAs(const ELT* p) 00850 { return *reinterpret_cast<const Vec*>(p); } 00853 static Vec& updAs(ELT* p) 00854 { return *reinterpret_cast<Vec*>(p); } 00855 00856 00860 static Vec<M,ELT,1> getNaN() { return Vec<M,ELT,1>(CNT<ELT>::getNaN()); } 00861 00863 bool isNaN() const { 00864 for (int i=0; i<M; ++i) 00865 if (CNT<ELT>::isNaN((*this)[i])) 00866 return true; 00867 return false; 00868 } 00869 00872 bool isInf() const { 00873 bool seenInf = false; 00874 for (int i=0; i<M; ++i) { 00875 const ELT& e = (*this)[i]; 00876 if (!CNT<ELT>::isFinite(e)) { 00877 if (!CNT<ELT>::isInf(e)) 00878 return false; // something bad was found 00879 seenInf = true; 00880 } 00881 } 00882 return seenInf; 00883 } 00884 00887 bool isFinite() const { 00888 for (int i=0; i<M; ++i) 00889 if (!CNT<ELT>::isFinite((*this)[i])) 00890 return false; 00891 return true; 00892 } 00893 00896 static double getDefaultTolerance() {return CNT<ELT>::getDefaultTolerance();} 00897 00900 template <class E2, int RS2> 00901 bool isNumericallyEqual(const Vec<M,E2,RS2>& v, double tol) const { 00902 for (int i=0; i<M; ++i) 00903 if (!CNT<ELT>::isNumericallyEqual((*this)[i], v[i], tol)) 00904 return false; 00905 return true; 00906 } 00907 00911 template <class E2, int RS2> 00912 bool isNumericallyEqual(const Vec<M,E2,RS2>& v) const { 00913 const double tol = std::max(getDefaultTolerance(),v.getDefaultTolerance()); 00914 return isNumericallyEqual(v, tol); 00915 } 00916 00921 bool isNumericallyEqual 00922 (const ELT& e, 00923 double tol = getDefaultTolerance()) const 00924 { 00925 for (int i=0; i<M; ++i) 00926 if (!CNT<ELT>::isNumericallyEqual((*this)[i], e, tol)) 00927 return false; 00928 return true; 00929 } 00930 00931 // Functions to be used for Scripting in MATLAB and languages that do not support operator overloading 00933 std::string toString() const { 00934 std::stringstream stream; 00935 stream << (*this); 00936 return stream.str(); 00937 } 00938 00940 void set(int i, const E& value) 00941 { (*this)[i] = value; } 00942 00944 const E& get(int i) const 00945 { return operator[](i); } 00946 00947 private: 00948 // TODO: should be an array of scalars rather than elements to control 00949 // packing more carefully. 00950 ELT d[NActualElements]; // data 00951 }; 00952 00954 // Global operators involving two vectors. // 00955 // v+v, v-v, v==v, v!=v // 00957 00958 // v3 = v1 + v2 where all v's have the same length M. 00959 template <int M, class E1, int S1, class E2, int S2> inline 00960 typename Vec<M,E1,S1>::template Result< Vec<M,E2,S2> >::Add 00961 operator+(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) { 00962 return Vec<M,E1,S1>::template Result< Vec<M,E2,S2> > 00963 ::AddOp::perform(l,r); 00964 } 00965 00966 // v3 = v1 - v2, similar to + 00967 template <int M, class E1, int S1, class E2, int S2> inline 00968 typename Vec<M,E1,S1>::template Result< Vec<M,E2,S2> >::Sub 00969 operator-(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) { 00970 return Vec<M,E1,S1>::template Result< Vec<M,E2,S2> > 00971 ::SubOp::perform(l,r); 00972 } 00973 00975 template <int M, class E1, int S1, class E2, int S2> inline bool 00976 operator==(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) 00977 { for (int i=0; i < M; ++i) if (l[i] != r[i]) return false; 00978 return true; } 00980 template <int M, class E1, int S1, class E2, int S2> inline bool 00981 operator!=(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) {return !(l==r);} 00982 00984 template <int M, class E1, int S1, class E2> inline bool 00985 operator==(const Vec<M,E1,S1>& v, const E2& e) 00986 { for (int i=0; i < M; ++i) if (v[i] != e) return false; 00987 return true; } 00989 template <int M, class E1, int S1, class E2> inline bool 00990 operator!=(const Vec<M,E1,S1>& v, const E2& e) {return !(v==e);} 00991 00993 template <int M, class E1, int S1, class E2, int S2> inline bool 00994 operator<(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) 00995 { for (int i=0; i < M; ++i) if (l[i] >= r[i]) return false; 00996 return true; } 00998 template <int M, class E1, int S1, class E2> inline bool 00999 operator<(const Vec<M,E1,S1>& v, const E2& e) 01000 { for (int i=0; i < M; ++i) if (v[i] >= e) return false; 01001 return true; } 01002 01004 template <int M, class E1, int S1, class E2, int S2> inline bool 01005 operator>(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) 01006 { for (int i=0; i < M; ++i) if (l[i] <= r[i]) return false; 01007 return true; } 01009 template <int M, class E1, int S1, class E2> inline bool 01010 operator>(const Vec<M,E1,S1>& v, const E2& e) 01011 { for (int i=0; i < M; ++i) if (v[i] <= e) return false; 01012 return true; } 01013 01016 template <int M, class E1, int S1, class E2, int S2> inline bool 01017 operator<=(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) 01018 { for (int i=0; i < M; ++i) if (l[i] > r[i]) return false; 01019 return true; } 01022 template <int M, class E1, int S1, class E2> inline bool 01023 operator<=(const Vec<M,E1,S1>& v, const E2& e) 01024 { for (int i=0; i < M; ++i) if (v[i] > e) return false; 01025 return true; } 01026 01029 template <int M, class E1, int S1, class E2, int S2> inline bool 01030 operator>=(const Vec<M,E1,S1>& l, const Vec<M,E2,S2>& r) 01031 { for (int i=0; i < M; ++i) if (l[i] < r[i]) return false; 01032 return true; } 01035 template <int M, class E1, int S1, class E2> inline bool 01036 operator>=(const Vec<M,E1,S1>& v, const E2& e) 01037 { for (int i=0; i < M; ++i) if (v[i] < e) return false; 01038 return true; } 01039 01041 // Global operators involving a vector and a scalar. // 01043 01044 // I haven't been able to figure out a nice way to templatize for the 01045 // built-in reals without introducing a lot of unwanted type matches 01046 // as well. So we'll just grind them out explicitly here. 01047 01048 // SCALAR MULTIPLY 01049 01050 // v = v*real, real*v 01051 template <int M, class E, int S> inline 01052 typename Vec<M,E,S>::template Result<float>::Mul 01053 operator*(const Vec<M,E,S>& l, const float& r) 01054 { return Vec<M,E,S>::template Result<float>::MulOp::perform(l,r); } 01055 template <int M, class E, int S> inline 01056 typename Vec<M,E,S>::template Result<float>::Mul 01057 operator*(const float& l, const Vec<M,E,S>& r) {return r*l;} 01058 01059 template <int M, class E, int S> inline 01060 typename Vec<M,E,S>::template Result<double>::Mul 01061 operator*(const Vec<M,E,S>& l, const double& r) 01062 { return Vec<M,E,S>::template Result<double>::MulOp::perform(l,r); } 01063 template <int M, class E, int S> inline 01064 typename Vec<M,E,S>::template Result<double>::Mul 01065 operator*(const double& l, const Vec<M,E,S>& r) {return r*l;} 01066 01067 template <int M, class E, int S> inline 01068 typename Vec<M,E,S>::template Result<long double>::Mul 01069 operator*(const Vec<M,E,S>& l, const long double& r) 01070 { return Vec<M,E,S>::template Result<long double>::MulOp::perform(l,r); } 01071 template <int M, class E, int S> inline 01072 typename Vec<M,E,S>::template Result<long double>::Mul 01073 operator*(const long double& l, const Vec<M,E,S>& r) {return r*l;} 01074 01075 // v = v*int, int*v -- just convert int to v's precision float 01076 template <int M, class E, int S> inline 01077 typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Mul 01078 operator*(const Vec<M,E,S>& l, int r) {return l * (typename CNT<E>::Precision)r;} 01079 template <int M, class E, int S> inline 01080 typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Mul 01081 operator*(int l, const Vec<M,E,S>& r) {return r * (typename CNT<E>::Precision)l;} 01082 01083 // Complex, conjugate, and negator are all easy to templatize. 01084 01085 // v = v*complex, complex*v 01086 template <int M, class E, int S, class R> inline 01087 typename Vec<M,E,S>::template Result<std::complex<R> >::Mul 01088 operator*(const Vec<M,E,S>& l, const std::complex<R>& r) 01089 { return Vec<M,E,S>::template Result<std::complex<R> >::MulOp::perform(l,r); } 01090 template <int M, class E, int S, class R> inline 01091 typename Vec<M,E,S>::template Result<std::complex<R> >::Mul 01092 operator*(const std::complex<R>& l, const Vec<M,E,S>& r) {return r*l;} 01093 01094 // v = v*conjugate, conjugate*v (convert conjugate->complex) 01095 template <int M, class E, int S, class R> inline 01096 typename Vec<M,E,S>::template Result<std::complex<R> >::Mul 01097 operator*(const Vec<M,E,S>& l, const conjugate<R>& r) {return l*(std::complex<R>)r;} 01098 template <int M, class E, int S, class R> inline 01099 typename Vec<M,E,S>::template Result<std::complex<R> >::Mul 01100 operator*(const conjugate<R>& l, const Vec<M,E,S>& r) {return r*(std::complex<R>)l;} 01101 01102 // v = v*negator, negator*v: convert negator to standard number 01103 template <int M, class E, int S, class R> inline 01104 typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Mul 01105 operator*(const Vec<M,E,S>& l, const negator<R>& r) {return l * (typename negator<R>::StdNumber)(R)r;} 01106 template <int M, class E, int S, class R> inline 01107 typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Mul 01108 operator*(const negator<R>& l, const Vec<M,E,S>& r) {return r * (typename negator<R>::StdNumber)(R)l;} 01109 01110 01111 // SCALAR DIVIDE. This is a scalar operation when the scalar is on the right, 01112 // but when it is on the left it means scalar * pseudoInverse(vec), which is 01113 // a row. 01114 01115 // v = v/real, real/v 01116 template <int M, class E, int S> inline 01117 typename Vec<M,E,S>::template Result<float>::Dvd 01118 operator/(const Vec<M,E,S>& l, const float& r) 01119 { return Vec<M,E,S>::template Result<float>::DvdOp::perform(l,r); } 01120 template <int M, class E, int S> inline 01121 typename CNT<float>::template Result<Vec<M,E,S> >::Dvd 01122 operator/(const float& l, const Vec<M,E,S>& r) 01123 { return CNT<float>::template Result<Vec<M,E,S> >::DvdOp::perform(l,r); } 01124 01125 template <int M, class E, int S> inline 01126 typename Vec<M,E,S>::template Result<double>::Dvd 01127 operator/(const Vec<M,E,S>& l, const double& r) 01128 { return Vec<M,E,S>::template Result<double>::DvdOp::perform(l,r); } 01129 template <int M, class E, int S> inline 01130 typename CNT<double>::template Result<Vec<M,E,S> >::Dvd 01131 operator/(const double& l, const Vec<M,E,S>& r) 01132 { return CNT<double>::template Result<Vec<M,E,S> >::DvdOp::perform(l,r); } 01133 01134 template <int M, class E, int S> inline 01135 typename Vec<M,E,S>::template Result<long double>::Dvd 01136 operator/(const Vec<M,E,S>& l, const long double& r) 01137 { return Vec<M,E,S>::template Result<long double>::DvdOp::perform(l,r); } 01138 template <int M, class E, int S> inline 01139 typename CNT<long double>::template Result<Vec<M,E,S> >::Dvd 01140 operator/(const long double& l, const Vec<M,E,S>& r) 01141 { return CNT<long double>::template Result<Vec<M,E,S> >::DvdOp::perform(l,r); } 01142 01143 // v = v/int, int/v -- just convert int to v's precision float 01144 template <int M, class E, int S> inline 01145 typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Dvd 01146 operator/(const Vec<M,E,S>& l, int r) {return l / (typename CNT<E>::Precision)r;} 01147 template <int M, class E, int S> inline 01148 typename CNT<typename CNT<E>::Precision>::template Result<Vec<M,E,S> >::Dvd 01149 operator/(int l, const Vec<M,E,S>& r) {return (typename CNT<E>::Precision)l / r;} 01150 01151 01152 // Complex, conjugate, and negator are all easy to templatize. 01153 01154 // v = v/complex, complex/v 01155 template <int M, class E, int S, class R> inline 01156 typename Vec<M,E,S>::template Result<std::complex<R> >::Dvd 01157 operator/(const Vec<M,E,S>& l, const std::complex<R>& r) 01158 { return Vec<M,E,S>::template Result<std::complex<R> >::DvdOp::perform(l,r); } 01159 template <int M, class E, int S, class R> inline 01160 typename CNT<std::complex<R> >::template Result<Vec<M,E,S> >::Dvd 01161 operator/(const std::complex<R>& l, const Vec<M,E,S>& r) 01162 { return CNT<std::complex<R> >::template Result<Vec<M,E,S> >::DvdOp::perform(l,r); } 01163 01164 // v = v/conjugate, conjugate/v (convert conjugate->complex) 01165 template <int M, class E, int S, class R> inline 01166 typename Vec<M,E,S>::template Result<std::complex<R> >::Dvd 01167 operator/(const Vec<M,E,S>& l, const conjugate<R>& r) {return l/(std::complex<R>)r;} 01168 template <int M, class E, int S, class R> inline 01169 typename CNT<std::complex<R> >::template Result<Vec<M,E,S> >::Dvd 01170 operator/(const conjugate<R>& l, const Vec<M,E,S>& r) {return (std::complex<R>)l/r;} 01171 01172 // v = v/negator, negator/v: convert negator to number 01173 template <int M, class E, int S, class R> inline 01174 typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Dvd 01175 operator/(const Vec<M,E,S>& l, const negator<R>& r) {return l/(typename negator<R>::StdNumber)(R)r;} 01176 template <int M, class E, int S, class R> inline 01177 typename CNT<R>::template Result<Vec<M,E,S> >::Dvd 01178 operator/(const negator<R>& l, const Vec<M,E,S>& r) {return (typename negator<R>::StdNumber)(R)l/r;} 01179 01180 01181 // Add and subtract are odd as scalar ops. They behave as though the 01182 // scalar stands for a vector each of whose elements is that scalar, 01183 // and then a normal vector add or subtract is done. 01184 01185 // SCALAR ADD 01186 01187 // v = v+real, real+v 01188 template <int M, class E, int S> inline 01189 typename Vec<M,E,S>::template Result<float>::Add 01190 operator+(const Vec<M,E,S>& l, const float& r) 01191 { return Vec<M,E,S>::template Result<float>::AddOp::perform(l,r); } 01192 template <int M, class E, int S> inline 01193 typename Vec<M,E,S>::template Result<float>::Add 01194 operator+(const float& l, const Vec<M,E,S>& r) {return r+l;} 01195 01196 template <int M, class E, int S> inline 01197 typename Vec<M,E,S>::template Result<double>::Add 01198 operator+(const Vec<M,E,S>& l, const double& r) 01199 { return Vec<M,E,S>::template Result<double>::AddOp::perform(l,r); } 01200 template <int M, class E, int S> inline 01201 typename Vec<M,E,S>::template Result<double>::Add 01202 operator+(const double& l, const Vec<M,E,S>& r) {return r+l;} 01203 01204 template <int M, class E, int S> inline 01205 typename Vec<M,E,S>::template Result<long double>::Add 01206 operator+(const Vec<M,E,S>& l, const long double& r) 01207 { return Vec<M,E,S>::template Result<long double>::AddOp::perform(l,r); } 01208 template <int M, class E, int S> inline 01209 typename Vec<M,E,S>::template Result<long double>::Add 01210 operator+(const long double& l, const Vec<M,E,S>& r) {return r+l;} 01211 01212 // v = v+int, int+v -- just convert int to v's precision float 01213 template <int M, class E, int S> inline 01214 typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Add 01215 operator+(const Vec<M,E,S>& l, int r) {return l + (typename CNT<E>::Precision)r;} 01216 template <int M, class E, int S> inline 01217 typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Add 01218 operator+(int l, const Vec<M,E,S>& r) {return r + (typename CNT<E>::Precision)l;} 01219 01220 // Complex, conjugate, and negator are all easy to templatize. 01221 01222 // v = v+complex, complex+v 01223 template <int M, class E, int S, class R> inline 01224 typename Vec<M,E,S>::template Result<std::complex<R> >::Add 01225 operator+(const Vec<M,E,S>& l, const std::complex<R>& r) 01226 { return Vec<M,E,S>::template Result<std::complex<R> >::AddOp::perform(l,r); } 01227 template <int M, class E, int S, class R> inline 01228 typename Vec<M,E,S>::template Result<std::complex<R> >::Add 01229 operator+(const std::complex<R>& l, const Vec<M,E,S>& r) {return r+l;} 01230 01231 // v = v+conjugate, conjugate+v (convert conjugate->complex) 01232 template <int M, class E, int S, class R> inline 01233 typename Vec<M,E,S>::template Result<std::complex<R> >::Add 01234 operator+(const Vec<M,E,S>& l, const conjugate<R>& r) {return l+(std::complex<R>)r;} 01235 template <int M, class E, int S, class R> inline 01236 typename Vec<M,E,S>::template Result<std::complex<R> >::Add 01237 operator+(const conjugate<R>& l, const Vec<M,E,S>& r) {return r+(std::complex<R>)l;} 01238 01239 // v = v+negator, negator+v: convert negator to standard number 01240 template <int M, class E, int S, class R> inline 01241 typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Add 01242 operator+(const Vec<M,E,S>& l, const negator<R>& r) {return l + (typename negator<R>::StdNumber)(R)r;} 01243 template <int M, class E, int S, class R> inline 01244 typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Add 01245 operator+(const negator<R>& l, const Vec<M,E,S>& r) {return r + (typename negator<R>::StdNumber)(R)l;} 01246 01247 // SCALAR SUBTRACT -- careful, not commutative. 01248 01249 // v = v-real, real-v 01250 template <int M, class E, int S> inline 01251 typename Vec<M,E,S>::template Result<float>::Sub 01252 operator-(const Vec<M,E,S>& l, const float& r) 01253 { return Vec<M,E,S>::template Result<float>::SubOp::perform(l,r); } 01254 template <int M, class E, int S> inline 01255 typename CNT<float>::template Result<Vec<M,E,S> >::Sub 01256 operator-(const float& l, const Vec<M,E,S>& r) 01257 { return CNT<float>::template Result<Vec<M,E,S> >::SubOp::perform(l,r); } 01258 01259 template <int M, class E, int S> inline 01260 typename Vec<M,E,S>::template Result<double>::Sub 01261 operator-(const Vec<M,E,S>& l, const double& r) 01262 { return Vec<M,E,S>::template Result<double>::SubOp::perform(l,r); } 01263 template <int M, class E, int S> inline 01264 typename CNT<double>::template Result<Vec<M,E,S> >::Sub 01265 operator-(const double& l, const Vec<M,E,S>& r) 01266 { return CNT<double>::template Result<Vec<M,E,S> >::SubOp::perform(l,r); } 01267 01268 template <int M, class E, int S> inline 01269 typename Vec<M,E,S>::template Result<long double>::Sub 01270 operator-(const Vec<M,E,S>& l, const long double& r) 01271 { return Vec<M,E,S>::template Result<long double>::SubOp::perform(l,r); } 01272 template <int M, class E, int S> inline 01273 typename CNT<long double>::template Result<Vec<M,E,S> >::Sub 01274 operator-(const long double& l, const Vec<M,E,S>& r) 01275 { return CNT<long double>::template Result<Vec<M,E,S> >::SubOp::perform(l,r); } 01276 01277 // v = v-int, int-v // just convert int to v's precision float 01278 template <int M, class E, int S> inline 01279 typename Vec<M,E,S>::template Result<typename CNT<E>::Precision>::Sub 01280 operator-(const Vec<M,E,S>& l, int r) {return l - (typename CNT<E>::Precision)r;} 01281 template <int M, class E, int S> inline 01282 typename CNT<typename CNT<E>::Precision>::template Result<Vec<M,E,S> >::Sub 01283 operator-(int l, const Vec<M,E,S>& r) {return (typename CNT<E>::Precision)l - r;} 01284 01285 01286 // Complex, conjugate, and negator are all easy to templatize. 01287 01288 // v = v-complex, complex-v 01289 template <int M, class E, int S, class R> inline 01290 typename Vec<M,E,S>::template Result<std::complex<R> >::Sub 01291 operator-(const Vec<M,E,S>& l, const std::complex<R>& r) 01292 { return Vec<M,E,S>::template Result<std::complex<R> >::SubOp::perform(l,r); } 01293 template <int M, class E, int S, class R> inline 01294 typename CNT<std::complex<R> >::template Result<Vec<M,E,S> >::Sub 01295 operator-(const std::complex<R>& l, const Vec<M,E,S>& r) 01296 { return CNT<std::complex<R> >::template Result<Vec<M,E,S> >::SubOp::perform(l,r); } 01297 01298 // v = v-conjugate, conjugate-v (convert conjugate->complex) 01299 template <int M, class E, int S, class R> inline 01300 typename Vec<M,E,S>::template Result<std::complex<R> >::Sub 01301 operator-(const Vec<M,E,S>& l, const conjugate<R>& r) {return l-(std::complex<R>)r;} 01302 template <int M, class E, int S, class R> inline 01303 typename CNT<std::complex<R> >::template Result<Vec<M,E,S> >::Sub 01304 operator-(const conjugate<R>& l, const Vec<M,E,S>& r) {return (std::complex<R>)l-r;} 01305 01306 // v = v-negator, negator-v: convert negator to standard number 01307 template <int M, class E, int S, class R> inline 01308 typename Vec<M,E,S>::template Result<typename negator<R>::StdNumber>::Sub 01309 operator-(const Vec<M,E,S>& l, const negator<R>& r) {return l-(typename negator<R>::StdNumber)(R)r;} 01310 template <int M, class E, int S, class R> inline 01311 typename CNT<R>::template Result<Vec<M,E,S> >::Sub 01312 operator-(const negator<R>& l, const Vec<M,E,S>& r) {return (typename negator<R>::StdNumber)(R)l-r;} 01313 01314 // Vec I/O 01315 template <int M, class E, int S, class CHAR, class TRAITS> inline 01316 std::basic_ostream<CHAR,TRAITS>& 01317 operator<<(std::basic_ostream<CHAR,TRAITS>& o, const Vec<M,E,S>& v) { 01318 o << "~[" << v[0]; for(int i=1;i<M;++i) o<<','<<v[i]; o<<']'; return o; 01319 } 01320 01323 template <int M, class E, int S, class CHAR, class TRAITS> inline 01324 std::basic_istream<CHAR,TRAITS>& 01325 operator>>(std::basic_istream<CHAR,TRAITS>& is, Vec<M,E,S>& v) { 01326 CHAR tilde; 01327 is >> tilde; if (is.fail()) return is; 01328 if (tilde != CHAR('~')) { 01329 tilde = CHAR(0); 01330 is.unget(); if (is.fail()) return is; 01331 } 01332 01333 CHAR openBracket, closeBracket; 01334 is >> openBracket; if (is.fail()) return is; 01335 if (openBracket==CHAR('(')) 01336 closeBracket = CHAR(')'); 01337 else if (openBracket==CHAR('[')) 01338 closeBracket = CHAR(']'); 01339 else { 01340 closeBracket = CHAR(0); 01341 is.unget(); if (is.fail()) return is; 01342 } 01343 01344 // If we saw a "~" but then we didn't see any brackets, that's an 01345 // error. Set the fail bit and return. 01346 if (tilde != CHAR(0) && closeBracket == CHAR(0)) { 01347 is.setstate( std::ios::failbit ); 01348 return is; 01349 } 01350 01351 for (int i=0; i < M; ++i) { 01352 is >> v[i]; 01353 if (is.fail()) return is; 01354 if (i != M-1) { 01355 CHAR c; is >> c; if (is.fail()) return is; 01356 if (c != ',') is.unget(); 01357 if (is.fail()) return is; 01358 } 01359 } 01360 01361 // Get the closing bracket if there was an opening one. If we don't 01362 // see the expected character we'll set the fail bit in the istream. 01363 if (closeBracket != CHAR(0)) { 01364 CHAR closer; is >> closer; if (is.fail()) return is; 01365 if (closer != closeBracket) { 01366 is.unget(); if (is.fail()) return is; 01367 is.setstate( std::ios::failbit ); 01368 } 01369 } 01370 01371 return is; 01372 } 01373 01374 } //namespace SimTK 01375 01376 01377 #endif //SimTK_SIMMATRIX_SMALLMATRIX_VEC_H_