Simbody

Vec.h

Go to the documentation of this file.
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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines