Simbody  3.4 (development)
Row.h
Go to the documentation of this file.
00001 #ifndef SimTK_SIMMATRIX_SMALLMATRIX_ROW_H_
00002 #define SimTK_SIMMATRIX_SMALLMATRIX_ROW_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 
00034 namespace SimTK {
00035 
00036 // The following functions are used internally by Row.
00037 
00038 namespace Impl {
00039 
00040 // For those wimpy compilers that don't unroll short, constant-limit loops, 
00041 // Peter Eastman added these recursive template implementations of 
00042 // elementwise add, subtract, and copy. Sherm added multiply and divide.
00043 
00044 template <class E1, int S1, class E2, int S2> void
00045 conformingAdd(const Row<1,E1,S1>& r1, const Row<1,E2,S2>& r2, 
00046               Row<1,typename CNT<E1>::template Result<E2>::Add>& result) {
00047     result[0] = r1[0] + r2[0];
00048 }
00049 template <int N, class E1, int S1, class E2, int S2> void
00050 conformingAdd(const Row<N,E1,S1>& r1, const Row<N,E2,S2>& r2, 
00051               Row<N,typename CNT<E1>::template Result<E2>::Add>& result) {
00052     conformingAdd(reinterpret_cast<const Row<N-1,E1,S1>&>(r1), 
00053                   reinterpret_cast<const Row<N-1,E2,S2>&>(r2), 
00054                   reinterpret_cast<Row<N-1,typename CNT<E1>::
00055                               template Result<E2>::Add>&>(result));
00056     result[N-1] = r1[N-1] + r2[N-1];
00057 }
00058 
00059 template <class E1, int S1, class E2, int S2> void
00060 conformingSubtract(const Row<1,E1,S1>& r1, const Row<1,E2,S2>& r2, 
00061                    Row<1,typename CNT<E1>::template Result<E2>::Sub>& result) {
00062     result[0] = r1[0] - r2[0];
00063 }
00064 template <int N, class E1, int S1, class E2, int S2> void
00065 conformingSubtract(const Row<N,E1,S1>& r1, const Row<N,E2,S2>& r2,
00066                    Row<N,typename CNT<E1>::template Result<E2>::Sub>& result) {
00067     conformingSubtract(reinterpret_cast<const Row<N-1,E1,S1>&>(r1), 
00068                        reinterpret_cast<const Row<N-1,E2,S2>&>(r2), 
00069                        reinterpret_cast<Row<N-1,typename CNT<E1>::
00070                                    template Result<E2>::Sub>&>(result));
00071     result[N-1] = r1[N-1] - r2[N-1];
00072 }
00073 
00074 template <class E1, int S1, class E2, int S2> void
00075 elementwiseMultiply(const Row<1,E1,S1>& r1, const Row<1,E2,S2>& r2, 
00076               Row<1,typename CNT<E1>::template Result<E2>::Mul>& result) {
00077     result[0] = r1[0] * r2[0];
00078 }
00079 template <int N, class E1, int S1, class E2, int S2> void
00080 elementwiseMultiply(const Row<N,E1,S1>& r1, const Row<N,E2,S2>& r2, 
00081               Row<N,typename CNT<E1>::template Result<E2>::Mul>& result) {
00082     elementwiseMultiply(reinterpret_cast<const Row<N-1,E1,S1>&>(r1), 
00083                         reinterpret_cast<const Row<N-1,E2,S2>&>(r2), 
00084                         reinterpret_cast<Row<N-1,typename CNT<E1>::
00085                                     template Result<E2>::Mul>&>(result));
00086     result[N-1] = r1[N-1] * r2[N-1];
00087 }
00088 
00089 template <class E1, int S1, class E2, int S2> void
00090 elementwiseDivide(const Row<1,E1,S1>& r1, const Row<1,E2,S2>& r2, 
00091               Row<1,typename CNT<E1>::template Result<E2>::Dvd>& result) {
00092     result[0] = r1[0] / r2[0];
00093 }
00094 template <int N, class E1, int S1, class E2, int S2> void
00095 elementwiseDivide(const Row<N,E1,S1>& r1, const Row<N,E2,S2>& r2, 
00096               Row<N,typename CNT<E1>::template Result<E2>::Dvd>& result) {
00097     elementwiseDivide(reinterpret_cast<const Row<N-1,E1,S1>&>(r1), 
00098                         reinterpret_cast<const Row<N-1,E2,S2>&>(r2), 
00099                         reinterpret_cast<Row<N-1,typename CNT<E1>::
00100                                     template Result<E2>::Dvd>&>(result));
00101     result[N-1] = r1[N-1] / r2[N-1];
00102 }
00103 
00104 template <class E1, int S1, class E2, int S2> void
00105 copy(Row<1,E1,S1>& r1, const Row<1,E2,S2>& r2) {
00106     r1[0] = r2[0];
00107 }
00108 template <int N, class E1, int S1, class E2, int S2> void
00109 copy(Row<N,E1,S1>& r1, const Row<N,E2,S2>& r2) {
00110     copy(reinterpret_cast<Row<N-1,E1,S1>&>(r1), 
00111          reinterpret_cast<const Row<N-1,E2,S2>&>(r2));
00112     r1[N-1] = r2[N-1];
00113 }
00114 
00115 }
00116 
00118 template <int N, class ELT, int STRIDE> class Row {
00119     typedef ELT                                 E;
00120     typedef typename CNT<E>::TNeg               ENeg;
00121     typedef typename CNT<E>::TWithoutNegator    EWithoutNegator;
00122     typedef typename CNT<E>::TReal              EReal;
00123     typedef typename CNT<E>::TImag              EImag;
00124     typedef typename CNT<E>::TComplex           EComplex;
00125     typedef typename CNT<E>::THerm              EHerm;
00126     typedef typename CNT<E>::TPosTrans          EPosTrans;
00127     typedef typename CNT<E>::TSqHermT           ESqHermT;
00128     typedef typename CNT<E>::TSqTHerm           ESqTHerm;
00129 
00130     typedef typename CNT<E>::TSqrt              ESqrt;
00131     typedef typename CNT<E>::TAbs               EAbs;
00132     typedef typename CNT<E>::TStandard          EStandard;
00133     typedef typename CNT<E>::TInvert            EInvert;
00134     typedef typename CNT<E>::TNormalize         ENormalize;
00135 
00136     typedef typename CNT<E>::Scalar             EScalar;
00137     typedef typename CNT<E>::ULessScalar        EULessScalar;
00138     typedef typename CNT<E>::Number             ENumber;
00139     typedef typename CNT<E>::StdNumber          EStdNumber;
00140     typedef typename CNT<E>::Precision          EPrecision;
00141     typedef typename CNT<E>::ScalarNormSq       EScalarNormSq;
00142 
00143 public:
00144 
00145     enum {
00146         NRows               = 1,
00147         NCols               = N,
00148         NPackedElements     = N,
00149         NActualElements     = N * STRIDE,   // includes trailing gap
00150         NActualScalars      = CNT<E>::NActualScalars * NActualElements,
00151         RowSpacing          = NActualElements,
00152         ColSpacing          = STRIDE,
00153         ImagOffset          = NTraits<ENumber>::ImagOffset,
00154         RealStrideFactor    = 1, // composite types don't change size when
00155                                  // cast from complex to real or imaginary
00156         ArgDepth            = ((int)CNT<E>::ArgDepth < (int)MAX_RESOLVED_DEPTH 
00157                                 ? CNT<E>::ArgDepth + 1 
00158                                 : MAX_RESOLVED_DEPTH),
00159         IsScalar            = 0,
00160         IsULessScalar       = 0,
00161         IsNumber            = 0,
00162         IsStdNumber         = 0,
00163         IsPrecision         = 0,
00164         SignInterpretation  = CNT<E>::SignInterpretation
00165     };
00166 
00167     typedef Row<N,E,STRIDE>                 T;
00168     typedef Row<N,ENeg,STRIDE>              TNeg;
00169     typedef Row<N,EWithoutNegator,STRIDE>   TWithoutNegator;
00170 
00171     typedef Row<N,EReal,STRIDE*CNT<E>::RealStrideFactor>         
00172                                             TReal;
00173     typedef Row<N,EImag,STRIDE*CNT<E>::RealStrideFactor>         
00174                                             TImag;
00175     typedef Row<N,EComplex,STRIDE>          TComplex;
00176     typedef Vec<N,EHerm,STRIDE>             THerm;
00177     typedef Vec<N,E,STRIDE>                 TPosTrans;
00178     typedef E                               TElement;
00179     typedef Row                             TRow;
00180     typedef E                               TCol;
00181 
00182     // These are the results of calculations, so are returned in new, packed
00183     // memory. Be sure to refer to element types here which are also packed.
00184     typedef Vec<N,ESqrt,1>                  TSqrt;      // Note stride
00185     typedef Row<N,EAbs,1>                   TAbs;       // Note stride
00186     typedef Row<N,EStandard,1>              TStandard;
00187     typedef Vec<N,EInvert,1>                TInvert;    // packed
00188     typedef Row<N,ENormalize,1>             TNormalize;
00189 
00190     typedef SymMat<N,ESqHermT>              TSqHermT;   // result of self outer product
00191     typedef EScalarNormSq                   TSqTHerm;   // result of self dot product
00192 
00193     // These recurse right down to the underlying scalar type no matter how
00194     // deep the elements are.
00195     typedef EScalar                         Scalar;
00196     typedef EULessScalar                    ULessScalar;
00197     typedef ENumber                         Number;
00198     typedef EStdNumber                      StdNumber;
00199     typedef EPrecision                      Precision;
00200     typedef EScalarNormSq                   ScalarNormSq;
00201 
00202     static int size() { return N; }
00203     static int nrow() { return 1; }
00204     static int ncol() { return N; }
00205 
00206 
00207     // Scalar norm square is sum( conjugate squares of all scalars )
00208     ScalarNormSq scalarNormSqr() const { 
00209         ScalarNormSq sum(0);
00210         for(int i=0;i<N;++i) sum += CNT<E>::scalarNormSqr(d[i*STRIDE]);
00211         return sum;
00212     }
00213 
00214     // sqrt() is elementwise square root; that is, the return value has the same
00215     // dimension as this Vec but with each element replaced by whatever it thinks
00216     // its square root is.
00217     TSqrt sqrt() const {
00218         TSqrt rsqrt;
00219         for(int i=0;i<N;++i) rsqrt[i] = CNT<E>::sqrt(d[i*STRIDE]);
00220         return rsqrt;
00221     }
00222 
00223     // abs() is elementwise absolute value; that is, the return value has the same
00224     // dimension as this Row but with each element replaced by whatever it thinks
00225     // its absolute value is.
00226     TAbs abs() const {
00227         TAbs rabs;
00228         for(int i=0;i<N;++i) rabs[i] = CNT<E>::abs(d[i*STRIDE]);
00229         return rabs;
00230     }
00231 
00232     TStandard standardize() const {
00233         TStandard rstd;
00234         for(int i=0;i<N;++i) rstd[i] = CNT<E>::standardize(d[i*STRIDE]);
00235         return rstd;
00236     }
00237 
00238     // Sum just adds up all the elements, getting rid of negators and
00239     // conjugates in the process.
00240     EStandard sum() const {
00241         E sum(0);
00242         for (int i=0;i<N;++i) sum += d[i*STRIDE];
00243         return CNT<E>::standardize(sum);
00244     }
00245 
00246     // This gives the resulting rowvector type when (v[i] op P) is applied to each element of v.
00247     // It is a row of length N, stride 1, and element types which are the regular
00248     // composite result of E op P. Typically P is a scalar type but it doesn't have to be.
00249     template <class P> struct EltResult { 
00250         typedef Row<N, typename CNT<E>::template Result<P>::Mul, 1> Mul;
00251         typedef Row<N, typename CNT<E>::template Result<P>::Dvd, 1> Dvd;
00252         typedef Row<N, typename CNT<E>::template Result<P>::Add, 1> Add;
00253         typedef Row<N, typename CNT<E>::template Result<P>::Sub, 1> Sub;
00254     };
00255 
00256     // This is the composite result for v op P where P is some kind of appropriately shaped
00257     // non-scalar type.
00258     template <class P> struct Result { 
00259         typedef MulCNTs<1,N,ArgDepth,Row,ColSpacing,RowSpacing,
00260             CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00261             P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> MulOp;
00262         typedef typename MulOp::Type Mul;
00263 
00264         typedef MulCNTsNonConforming<1,N,ArgDepth,Row,ColSpacing,RowSpacing,
00265             CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00266             P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> MulOpNonConforming;
00267         typedef typename MulOpNonConforming::Type MulNon;
00268 
00269 
00270         typedef DvdCNTs<1,N,ArgDepth,Row,ColSpacing,RowSpacing,
00271             CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00272             P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> DvdOp;
00273         typedef typename DvdOp::Type Dvd;
00274 
00275         typedef AddCNTs<1,N,ArgDepth,Row,ColSpacing,RowSpacing,
00276             CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00277             P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> AddOp;
00278         typedef typename AddOp::Type Add;
00279 
00280         typedef SubCNTs<1,N,ArgDepth,Row,ColSpacing,RowSpacing,
00281             CNT<P>::NRows, CNT<P>::NCols, CNT<P>::ArgDepth,
00282             P, CNT<P>::ColSpacing, CNT<P>::RowSpacing> SubOp;
00283         typedef typename SubOp::Type Sub;
00284     };
00285 
00286     // Shape-preserving element substitution (always packed)
00287     template <class P> struct Substitute {
00288         typedef Row<N,P> Type;
00289     };
00290 
00291     // Default construction initializes to NaN when debugging but
00292     // is left uninitialized otherwise.
00293     Row(){ 
00294     #ifndef NDEBUG
00295         setToNaN();
00296     #endif
00297     }
00298 
00299     // It's important not to use the default copy constructor or copy
00300     // assignment because the compiler doesn't understand that we may
00301     // have noncontiguous storage and will try to copy the whole array.
00302     Row(const Row& src) {
00303         Impl::copy(*this, src);
00304     }
00305     Row& operator=(const Row& src) {    // no harm if src and 'this' are the same
00306         Impl::copy(*this, src);
00307         return *this;
00308     }
00309 
00310     // We want an implicit conversion from a Row of the same length
00311     // and element type but with a different stride.
00312     template <int SS> Row(const Row<N,E,SS>& src) {
00313         Impl::copy(*this, src);
00314     }
00315 
00316     // We want an implicit conversion from a Row of the same length
00317     // and *negated* element type, possibly with a different stride.
00318     template <int SS> Row(const Row<N,ENeg,SS>& src) {
00319         Impl::copy(*this, src);
00320     }
00321 
00322     // Construct a Row from a Row of the same length, with any
00323     // stride. Works as long as the element types are compatible.
00324     template <class EE, int SS> explicit Row(const Row<N,EE,SS>& vv) {
00325         Impl::copy(*this, vv);
00326     }
00327 
00328     // Construction using an element assigns to each element.
00329     explicit Row(const E& e)
00330       { for (int i=0;i<N;++i) d[i*STRIDE]=e; }
00331 
00332     // Construction using a negated element assigns to each element.
00333     explicit Row(const ENeg& ne)
00334       { for (int i=0;i<N;++i) d[i*STRIDE]=ne; }
00335 
00336     // Given an int, turn it into a suitable floating point number
00337     // and then feed that to the above single-element constructor.
00338     explicit Row(int i) 
00339       { new (this) Row(E(Precision(i))); }
00340 
00341     // A bevy of constructors for Rows up to length 6.
00342     Row(const E& e0,const E& e1)
00343       { assert(N==2);(*this)[0]=e0;(*this)[1]=e1; }
00344     Row(const E& e0,const E& e1,const E& e2)
00345       { assert(N==3);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2; }
00346     Row(const E& e0,const E& e1,const E& e2,const E& e3)
00347       { assert(N==4);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;(*this)[3]=e3; }
00348     Row(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4)
00349       { assert(N==5);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
00350         (*this)[3]=e3;(*this)[4]=e4; }
00351     Row(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5)
00352       { assert(N==6);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
00353         (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5; }
00354     Row(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5,const E& e6)
00355       { assert(N==7);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
00356         (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6; }
00357     Row(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5,const E& e6,const E& e7)
00358       { assert(N==8);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
00359         (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6;(*this)[7]=e7; }
00360     Row(const E& e0,const E& e1,const E& e2,const E& e3,const E& e4,const E& e5,const E& e6,const E& e7,const E& e8)
00361       { assert(N==9);(*this)[0]=e0;(*this)[1]=e1;(*this)[2]=e2;
00362         (*this)[3]=e3;(*this)[4]=e4;(*this)[5]=e5;(*this)[6]=e6;(*this)[7]=e7;(*this)[8]=e8; }
00363 
00364     // Construction from a pointer to anything assumes we're pointing
00365     // at an element list of the right length.
00366     template <class EE> explicit Row(const EE* p)
00367       { assert(p); for(int i=0;i<N;++i) d[i*STRIDE]=p[i]; }
00368     template <class EE> Row& operator=(const EE* p)
00369       { assert(p); for(int i=0;i<N;++i) d[i*STRIDE]=p[i]; return *this; }
00370 
00371     // Conforming assignment ops.
00372     template <class EE, int SS> Row& operator=(const Row<N,EE,SS>& vv) {
00373         Impl::copy(*this, vv);
00374         return *this;
00375     }
00376     template <class EE, int SS> Row& operator+=(const Row<N,EE,SS>& r)
00377       { for(int i=0;i<N;++i) d[i*STRIDE] += r[i]; return *this; }
00378     template <class EE, int SS> Row& operator+=(const Row<N,negator<EE>,SS>& r)
00379       { for(int i=0;i<N;++i) d[i*STRIDE] -= -(r[i]); return *this; }
00380     template <class EE, int SS> Row& operator-=(const Row<N,EE,SS>& r)
00381       { for(int i=0;i<N;++i) d[i*STRIDE] -= r[i]; return *this; }
00382     template <class EE, int SS> Row& operator-=(const Row<N,negator<EE>,SS>& r)
00383       { for(int i=0;i<N;++i) d[i*STRIDE] += -(r[i]); return *this; }
00384 
00385     // Conforming binary ops with 'this' on left, producing new packed result.
00386     // Cases: r=r+r, r=r-r, s=r*v r=r*m
00387 
00389     template <class EE, int SS> Row<N,typename CNT<E>::template Result<EE>::Add>
00390     conformingAdd(const Row<N,EE,SS>& r) const {
00391         Row<N,typename CNT<E>::template Result<EE>::Add> result;
00392         Impl::conformingAdd(*this, r, result);
00393         return result;
00394     }
00395 
00397     template <class EE, int SS> Row<N,typename CNT<E>::template Result<EE>::Sub>
00398     conformingSubtract(const Row<N,EE,SS>& r) const {
00399         Row<N,typename CNT<E>::template Result<EE>::Sub> result;
00400         Impl::conformingSubtract(*this, r, result);
00401         return result;
00402     }
00403 
00405     template <class EE, int SS> typename CNT<E>::template Result<EE>::Mul
00406     conformingMultiply(const Vec<N,EE,SS>& r) const {
00407         return (*this)*r;
00408     }
00409 
00411     template <int MatNCol, class EE, int CS, int RS> 
00412     Row<MatNCol,typename CNT<E>::template Result<EE>::Mul>
00413     conformingMultiply(const Mat<N,MatNCol,EE,CS,RS>& m) const {
00414         Row<MatNCol,typename CNT<E>::template Result<EE>::Mul> result;
00415         for (int j=0;j<N;++j) result[j] = conformingMultiply(m(j));
00416         return result;
00417     }
00418 
00420     template <class EE, int SS> Row<N,typename CNT<E>::template Result<EE>::Mul>
00421     elementwiseMultiply(const Row<N,EE,SS>& r) const {
00422         Row<N,typename CNT<E>::template Result<EE>::Mul> result;
00423         Impl::elementwiseMultiply(*this, r, result);
00424         return result;
00425     }
00426 
00428     template <class EE, int SS> Row<N,typename CNT<E>::template Result<EE>::Dvd>
00429     elementwiseDivide(const Row<N,EE,SS>& r) const {
00430         Row<N,typename CNT<E>::template Result<EE>::Dvd> result;
00431         Impl::elementwiseDivide(*this, r, result);
00432         return result;
00433     }
00434 
00435     const E& operator[](int i) const { assert(0 <= i && i < N); return d[i*STRIDE]; }
00436     E&       operator[](int i)       { assert(0 <= i && i < N); return d[i*STRIDE]; }
00437     const E& operator()(int i) const { return (*this)[i]; }
00438     E&       operator()(int i)       { return (*this)[i]; }
00439 
00440     ScalarNormSq normSqr() const { return scalarNormSqr(); }
00441     typename CNT<ScalarNormSq>::TSqrt 
00442         norm() const { return CNT<ScalarNormSq>::sqrt(scalarNormSqr()); }
00443 
00444     // If the elements of this Row are scalars, the result is what you get by
00445     // dividing each element by the norm() calculated above. If the elements are
00446     // *not* scalars, then the elements are *separately* normalized. That means
00447     // you will get a different answer from Row<2,Row3>::normalize() than you
00448     // would from a Row<6>::normalize() containing the same scalars.
00449     //
00450     // Normalize returns a row of the same dimension but in new, packed storage
00451     // and with a return type that does not include negator<> even if the original
00452     // Row<> does, because we can eliminate the negation here almost for free.
00453     // But we can't standardize (change conjugate to complex) for free, so we'll retain
00454     // conjugates if there are any.
00455     TNormalize normalize() const {
00456         if (CNT<E>::IsScalar) {
00457             return castAwayNegatorIfAny() / (SignInterpretation*norm());
00458         } else {
00459             TNormalize elementwiseNormalized;
00460             for (int j=0; j<N; ++j) 
00461                 elementwiseNormalized[j] = CNT<E>::normalize((*this)[j]);
00462             return elementwiseNormalized;
00463         }
00464     }
00465 
00466     TInvert invert() const {assert(false); return TInvert();} // TODO default inversion
00467 
00468     const Row&   operator+() const { return *this; }
00469     const TNeg&  operator-() const { return negate(); }
00470     TNeg&        operator-()       { return updNegate(); }
00471     const THerm& operator~() const { return transpose(); }
00472     THerm&       operator~()       { return updTranspose(); }
00473 
00474     const TNeg&  negate() const { return *reinterpret_cast<const TNeg*>(this); }
00475     TNeg&        updNegate()    { return *reinterpret_cast<TNeg*>(this); }
00476 
00477     const THerm& transpose()    const { return *reinterpret_cast<const THerm*>(this); }
00478     THerm&       updTranspose()       { return *reinterpret_cast<THerm*>(this); }
00479 
00480     const TPosTrans& positionalTranspose() const
00481         { return *reinterpret_cast<const TPosTrans*>(this); }
00482     TPosTrans&       updPositionalTranspose()
00483         { return *reinterpret_cast<TPosTrans*>(this); }
00484 
00485     const TReal& real() const { return *reinterpret_cast<const TReal*>(this); }
00486     TReal&       real()       { return *reinterpret_cast<      TReal*>(this); }
00487 
00488     // Had to contort these routines to get them through VC++ 7.net
00489     const TImag& imag()    const { 
00490         const int offs = ImagOffset;
00491         const EImag* p = reinterpret_cast<const EImag*>(this);
00492         return *reinterpret_cast<const TImag*>(p+offs);
00493     }
00494     TImag& imag() { 
00495         const int offs = ImagOffset;
00496         EImag* p = reinterpret_cast<EImag*>(this);
00497         return *reinterpret_cast<TImag*>(p+offs);
00498     }
00499 
00500     const TWithoutNegator& castAwayNegatorIfAny() const {return *reinterpret_cast<const TWithoutNegator*>(this);}
00501     TWithoutNegator&       updCastAwayNegatorIfAny()    {return *reinterpret_cast<TWithoutNegator*>(this);}
00502 
00503 
00504     // These are elementwise binary operators, (this op ee) by default but 
00505     // (ee op this) if 'FromLeft' appears in the name. The result is a packed 
00506     // Row<N> but the element type may change. These are mostly used to 
00507     // implement global operators. We call these "scalar" operators but 
00508     // actually the "scalar" can be a composite type.
00509 
00510     //TODO: consider converting 'e' to Standard Numbers as precalculation and 
00511     // changing return type appropriately.
00512     template <class EE> Row<N, typename CNT<E>::template Result<EE>::Mul>
00513     scalarMultiply(const EE& e) const {
00514         Row<N, typename CNT<E>::template Result<EE>::Mul> result;
00515         for (int j=0; j<N; ++j) result[j] = (*this)[j] * e;
00516         return result;
00517     }
00518     template <class EE> Row<N, typename CNT<EE>::template Result<E>::Mul>
00519     scalarMultiplyFromLeft(const EE& e) const {
00520         Row<N, typename CNT<EE>::template Result<E>::Mul> result;
00521         for (int j=0; j<N; ++j) result[j] = e * (*this)[j];
00522         return result;
00523     }
00524 
00525     // TODO: should precalculate and store 1/e, while converting to Standard 
00526     // Numbers. Note that return type should change appropriately.
00527     template <class EE> Row<N, typename CNT<E>::template Result<EE>::Dvd>
00528     scalarDivide(const EE& e) const {
00529         Row<N, typename CNT<E>::template Result<EE>::Dvd> result;
00530         for (int j=0; j<N; ++j) result[j] = (*this)[j] / e;
00531         return result;
00532     }
00533     template <class EE> Row<N, typename CNT<EE>::template Result<E>::Dvd>
00534     scalarDivideFromLeft(const EE& e) const {
00535         Row<N, typename CNT<EE>::template Result<E>::Dvd> result;
00536         for (int j=0; j<N; ++j) result[j] = e / (*this)[j];
00537         return result;
00538     }
00539 
00540     template <class EE> Row<N, typename CNT<E>::template Result<EE>::Add>
00541     scalarAdd(const EE& e) const {
00542         Row<N, typename CNT<E>::template Result<EE>::Add> result;
00543         for (int j=0; j<N; ++j) result[j] = (*this)[j] + e;
00544         return result;
00545     }
00546     // Add is commutative, so no 'FromLeft'.
00547 
00548     template <class EE> Row<N, typename CNT<E>::template Result<EE>::Sub>
00549     scalarSubtract(const EE& e) const {
00550         Row<N, typename CNT<E>::template Result<EE>::Sub> result;
00551         for (int j=0; j<N; ++j) result[j] = (*this)[j] - e;
00552         return result;
00553     }
00554     template <class EE> Row<N, typename CNT<EE>::template Result<E>::Sub>
00555     scalarSubtractFromLeft(const EE& e) const {
00556         Row<N, typename CNT<EE>::template Result<E>::Sub> result;
00557         for (int j=0; j<N; ++j) result[j] = e - (*this)[j];
00558         return result;
00559     }
00560 
00561     // Generic assignments for any element type not listed explicitly, including scalars.
00562     // These are done repeatedly for each element and only work if the operation can
00563     // be performed leaving the original element type.
00564     template <class EE> Row& operator =(const EE& e) {return scalarEq(e);}
00565     template <class EE> Row& operator+=(const EE& e) {return scalarPlusEq(e);}
00566     template <class EE> Row& operator-=(const EE& e) {return scalarMinusEq(e);}
00567     template <class EE> Row& operator*=(const EE& e) {return scalarTimesEq(e);}
00568     template <class EE> Row& operator/=(const EE& e) {return scalarDivideEq(e);}
00569 
00570     // Generalized scalar assignment & computed assignment methods. These will work
00571     // for any assignment-compatible element, not just scalars.
00572     template <class EE> Row& scalarEq(const EE& ee)
00573       { for(int i=0;i<N;++i) d[i*STRIDE] = ee; return *this; }
00574     template <class EE> Row& scalarPlusEq(const EE& ee)
00575       { for(int i=0;i<N;++i) d[i*STRIDE] += ee; return *this; }
00576     template <class EE> Row& scalarMinusEq(const EE& ee)
00577       { for(int i=0;i<N;++i) d[i*STRIDE] -= ee; return *this; }
00578     template <class EE> Row& scalarMinusEqFromLeft(const EE& ee)
00579       { for(int i=0;i<N;++i) d[i*STRIDE] = ee - d[i*STRIDE]; return *this; }
00580     template <class EE> Row& scalarTimesEq(const EE& ee)
00581       { for(int i=0;i<N;++i) d[i*STRIDE] *= ee; return *this; }
00582     template <class EE> Row& scalarTimesEqFromLeft(const EE& ee)
00583       { for(int i=0;i<N;++i) d[i*STRIDE] = ee * d[i*STRIDE]; return *this; }
00584     template <class EE> Row& scalarDivideEq(const EE& ee)
00585       { for(int i=0;i<N;++i) d[i*STRIDE] /= ee; return *this; }
00586     template <class EE> Row& scalarDivideEqFromLeft(const EE& ee)
00587       { for(int i=0;i<N;++i) d[i*STRIDE] = ee / d[i*STRIDE]; return *this; }
00588 
00589 
00590     // Specialize for int to avoid warnings and ambiguities.
00591     Row& scalarEq(int ee)       {return scalarEq(Precision(ee));}
00592     Row& scalarPlusEq(int ee)   {return scalarPlusEq(Precision(ee));}
00593     Row& scalarMinusEq(int ee)  {return scalarMinusEq(Precision(ee));}
00594     Row& scalarTimesEq(int ee)  {return scalarTimesEq(Precision(ee));}
00595     Row& scalarDivideEq(int ee) {return scalarDivideEq(Precision(ee));}
00596     Row& scalarMinusEqFromLeft(int ee)  {return scalarMinusEqFromLeft(Precision(ee));}
00597     Row& scalarTimesEqFromLeft(int ee)  {return scalarTimesEqFromLeft(Precision(ee));}
00598     Row& scalarDivideEqFromLeft(int ee) {return scalarDivideEqFromLeft(Precision(ee));}
00599 
00602     void setToNaN() {
00603         (*this) = CNT<ELT>::getNaN();
00604     }
00605 
00607     void setToZero() {
00608         (*this) = ELT(0);
00609     }
00610 
00616     template <int NN>
00617     const Row<NN,ELT,STRIDE>& getSubRow(int j) const {
00618         assert(0 <= j && j + NN <= N);
00619         return Row<NN,ELT,STRIDE>::getAs(&(*this)[j]);
00620     }
00626     template <int NN>
00627     Row<NN,ELT,STRIDE>& updSubRow(int j) {
00628         assert(0 <= j && j + NN <= N);
00629         return Row<NN,ELT,STRIDE>::updAs(&(*this)[j]);
00630     }
00631 
00635     template <int NN>
00636     static const Row& getSubRow(const Row<NN,ELT,STRIDE>& r, int j) {
00637         assert(0 <= j && j + N <= NN);
00638         return getAs(&r[j]);
00639     }
00643     template <int NN>
00644     static Row& updSubRow(Row<NN,ELT,STRIDE>& r, int j) {
00645         assert(0 <= j && j + N <= NN);
00646         return updAs(&r[j]);
00647     }
00648 
00652     Row<N-1,ELT,1> drop1(int p) const {
00653         assert(0 <= p && p < N);
00654         Row<N-1,ELT,1> out;
00655         int nxt=0;
00656         for (int i=0; i<N-1; ++i, ++nxt) {
00657             if (nxt==p) ++nxt;  // skip the loser
00658             out[i] = (*this)[nxt];
00659         }
00660         return out;
00661     }
00662 
00666     template <class EE> Row<N+1,ELT,1> append1(const EE& v) const {
00667         Row<N+1,ELT,1> out;
00668         Row<N,ELT,1>::updAs(&out[0]) = (*this);
00669         out[N] = v;
00670         return out;
00671     }
00672 
00673 
00679     template <class EE> Row<N+1,ELT,1> insert1(int p, const EE& v) const {
00680         assert(0 <= p && p <= N);
00681         if (p==N) return append1(v);
00682         Row<N+1,ELT,1> out;
00683         int nxt=0;
00684         for (int i=0; i<N; ++i, ++nxt) {
00685             if (i==p) out[nxt++] = v;
00686             out[nxt] = (*this)[i];
00687         }
00688         return out;
00689     }
00690 
00693     static const Row& getAs(const ELT* p)  {return *reinterpret_cast<const Row*>(p);}
00696     static Row&       updAs(ELT* p)        {return *reinterpret_cast<Row*>(p);}
00697 
00701     static Row<N,ELT,1> getNaN() { return Row<N,ELT,1>(CNT<ELT>::getNaN()); }
00702 
00704     bool isNaN() const {
00705         for (int j=0; j<N; ++j)
00706             if (CNT<ELT>::isNaN((*this)[j]))
00707                 return true;
00708         return false;
00709     }
00710 
00713     bool isInf() const {
00714         bool seenInf = false;
00715         for (int j=0; j<N; ++j) {
00716             const ELT& e = (*this)[j];
00717             if (!CNT<ELT>::isFinite(e)) {
00718                 if (!CNT<ELT>::isInf(e)) 
00719                     return false; // something bad was found
00720                 seenInf = true; 
00721             }
00722         }
00723         return seenInf;
00724     }
00725 
00728     bool isFinite() const {
00729         for (int j=0; j<N; ++j)
00730             if (!CNT<ELT>::isFinite((*this)[j]))
00731                 return false;
00732         return true;
00733     }
00734 
00737     static double getDefaultTolerance() {return CNT<ELT>::getDefaultTolerance();}
00738 
00741     template <class E2, int CS2>
00742     bool isNumericallyEqual(const Row<N,E2,CS2>& r, double tol) const {
00743         for (int j=0; j<N; ++j)
00744             if (!CNT<ELT>::isNumericallyEqual((*this)(j), r(j), tol))
00745                 return false;
00746         return true;
00747     }
00748 
00752     template <class E2, int CS2>
00753     bool isNumericallyEqual(const Row<N,E2,CS2>& r) const {
00754         const double tol = std::max(getDefaultTolerance(),r.getDefaultTolerance());
00755         return isNumericallyEqual(r, tol);
00756     }
00757 
00762     bool isNumericallyEqual
00763        (const ELT& e,
00764         double     tol = getDefaultTolerance()) const 
00765     {
00766         for (int j=0; j<N; ++j)
00767             if (!CNT<ELT>::isNumericallyEqual((*this)(j), e, tol))
00768                 return false;
00769         return true;
00770     }
00771 private:
00772     ELT d[NActualElements];    // data
00773 };
00774 
00776 // Global operators involving two rows.    //
00777 //   v+v, v-v, v==v, v!=v                  //
00779 
00780 // v3 = v1 + v2 where all v's have the same length N. 
00781 template <int N, class E1, int S1, class E2, int S2> inline
00782 typename Row<N,E1,S1>::template Result< Row<N,E2,S2> >::Add
00783 operator+(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r) { 
00784     return Row<N,E1,S1>::template Result< Row<N,E2,S2> >
00785         ::AddOp::perform(l,r);
00786 }
00787 
00788 // v3 = v1 - v2, similar to +
00789 template <int N, class E1, int S1, class E2, int S2> inline
00790 typename Row<N,E1,S1>::template Result< Row<N,E2,S2> >::Sub
00791 operator-(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r) { 
00792     return Row<N,E1,S1>::template Result< Row<N,E2,S2> >
00793         ::SubOp::perform(l,r);
00794 }
00795 
00797 template <int N, class E1, int S1, class E2, int S2> inline bool
00798 operator==(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r) { 
00799     for (int i=0; i < N; ++i) if (l[i] != r[i]) return false;
00800     return true;
00801 }
00803 template <int N, class E1, int S1, class E2, int S2> inline bool
00804 operator!=(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r) {return !(l==r);} 
00805 
00807 template <int N, class E1, int S1, class E2, int S2> inline bool
00808 operator<(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r) 
00809 {   for (int i=0; i < N; ++i) if (l[i] >= r[i]) return false;
00810     return true; }
00812 template <int N, class E1, int S1, class E2> inline bool
00813 operator<(const Row<N,E1,S1>& v, const E2& e) 
00814 {   for (int i=0; i < N; ++i) if (v[i] >= e) return false;
00815     return true; }
00816 
00818 template <int N, class E1, int S1, class E2, int S2> inline bool
00819 operator>(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r) 
00820 {   for (int i=0; i < N; ++i) if (l[i] <= r[i]) return false;
00821     return true; }
00823 template <int N, class E1, int S1, class E2> inline bool
00824 operator>(const Row<N,E1,S1>& v, const E2& e) 
00825 {   for (int i=0; i < N; ++i) if (v[i] <= e) return false;
00826     return true; }
00827 
00830 template <int N, class E1, int S1, class E2, int S2> inline bool
00831 operator<=(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r) 
00832 {   for (int i=0; i < N; ++i) if (l[i] > r[i]) return false;
00833     return true; }
00836 template <int N, class E1, int S1, class E2> inline bool
00837 operator<=(const Row<N,E1,S1>& v, const E2& e) 
00838 {   for (int i=0; i < N; ++i) if (v[i] > e) return false;
00839     return true; }
00840 
00843 template <int N, class E1, int S1, class E2, int S2> inline bool
00844 operator>=(const Row<N,E1,S1>& l, const Row<N,E2,S2>& r) 
00845 {   for (int i=0; i < N; ++i) if (l[i] < r[i]) return false;
00846     return true; }
00849 template <int N, class E1, int S1, class E2> inline bool
00850 operator>=(const Row<N,E1,S1>& v, const E2& e) 
00851 {   for (int i=0; i < N; ++i) if (v[i] < e) return false;
00852     return true; }
00853 
00855 // Global operators involving a row and a scalar. //
00857 
00858 // I haven't been able to figure out a nice way to templatize for the
00859 // built-in reals without introducing a lot of unwanted type matches
00860 // as well. So we'll just grind them out explicitly here.
00861 
00862 // SCALAR MULTIPLY
00863 
00864 // v = v*real, real*v 
00865 template <int N, class E, int S> inline
00866 typename Row<N,E,S>::template Result<float>::Mul
00867 operator*(const Row<N,E,S>& l, const float& r)
00868   { return Row<N,E,S>::template Result<float>::MulOp::perform(l,r); }
00869 template <int N, class E, int S> inline
00870 typename Row<N,E,S>::template Result<float>::Mul
00871 operator*(const float& l, const Row<N,E,S>& r) {return r*l;}
00872 
00873 template <int N, class E, int S> inline
00874 typename Row<N,E,S>::template Result<double>::Mul
00875 operator*(const Row<N,E,S>& l, const double& r)
00876   { return Row<N,E,S>::template Result<double>::MulOp::perform(l,r); }
00877 template <int N, class E, int S> inline
00878 typename Row<N,E,S>::template Result<double>::Mul
00879 operator*(const double& l, const Row<N,E,S>& r) {return r*l;}
00880 
00881 template <int N, class E, int S> inline
00882 typename Row<N,E,S>::template Result<long double>::Mul
00883 operator*(const Row<N,E,S>& l, const long double& r)
00884   { return Row<N,E,S>::template Result<long double>::MulOp::perform(l,r); }
00885 template <int N, class E, int S> inline
00886 typename Row<N,E,S>::template Result<long double>::Mul
00887 operator*(const long double& l, const Row<N,E,S>& r) {return r*l;}
00888 
00889 // v = v*int, int*v -- just convert int to v's precision float
00890 template <int N, class E, int S> inline
00891 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Mul
00892 operator*(const Row<N,E,S>& l, int r) {return l * (typename CNT<E>::Precision)r;}
00893 template <int N, class E, int S> inline
00894 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Mul
00895 operator*(int l, const Row<N,E,S>& r) {return r * (typename CNT<E>::Precision)l;}
00896 
00897 // Complex, conjugate, and negator are all easy to templatize.
00898 
00899 // v = v*complex, complex*v
00900 template <int N, class E, int S, class R> inline
00901 typename Row<N,E,S>::template Result<std::complex<R> >::Mul
00902 operator*(const Row<N,E,S>& l, const std::complex<R>& r)
00903   { return Row<N,E,S>::template Result<std::complex<R> >::MulOp::perform(l,r); }
00904 template <int N, class E, int S, class R> inline
00905 typename Row<N,E,S>::template Result<std::complex<R> >::Mul
00906 operator*(const std::complex<R>& l, const Row<N,E,S>& r) {return r*l;}
00907 
00908 // v = v*conjugate, conjugate*v (convert conjugate->complex)
00909 template <int N, class E, int S, class R> inline
00910 typename Row<N,E,S>::template Result<std::complex<R> >::Mul
00911 operator*(const Row<N,E,S>& l, const conjugate<R>& r) {return l*(std::complex<R>)r;}
00912 template <int N, class E, int S, class R> inline
00913 typename Row<N,E,S>::template Result<std::complex<R> >::Mul
00914 operator*(const conjugate<R>& l, const Row<N,E,S>& r) {return r*(std::complex<R>)l;}
00915 
00916 // v = v*negator, negator*v: convert negator to standard number
00917 template <int N, class E, int S, class R> inline
00918 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Mul
00919 operator*(const Row<N,E,S>& l, const negator<R>& r) {return l * (typename negator<R>::StdNumber)(R)r;}
00920 template <int N, class E, int S, class R> inline
00921 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Mul
00922 operator*(const negator<R>& l, const Row<N,E,S>& r) {return r * (typename negator<R>::StdNumber)(R)l;}
00923 
00924 
00925 // SCALAR DIVIDE. This is a scalar operation when the scalar is on the right,
00926 // but when it is on the left it means scalar * pseudoInverse(row), which is 
00927 // a vec.
00928 
00929 // v = v/real, real/v 
00930 template <int N, class E, int S> inline
00931 typename Row<N,E,S>::template Result<float>::Dvd
00932 operator/(const Row<N,E,S>& l, const float& r)
00933   { return Row<N,E,S>::template Result<float>::DvdOp::perform(l,r); }
00934 template <int N, class E, int S> inline
00935 typename CNT<float>::template Result<Row<N,E,S> >::Dvd
00936 operator/(const float& l, const Row<N,E,S>& r)
00937   { return CNT<float>::template Result<Row<N,E,S> >::DvdOp::perform(l,r); }
00938 
00939 template <int N, class E, int S> inline
00940 typename Row<N,E,S>::template Result<double>::Dvd
00941 operator/(const Row<N,E,S>& l, const double& r)
00942   { return Row<N,E,S>::template Result<double>::DvdOp::perform(l,r); }
00943 template <int N, class E, int S> inline
00944 typename CNT<double>::template Result<Row<N,E,S> >::Dvd
00945 operator/(const double& l, const Row<N,E,S>& r)
00946   { return CNT<double>::template Result<Row<N,E,S> >::DvdOp::perform(l,r); }
00947 
00948 template <int N, class E, int S> inline
00949 typename Row<N,E,S>::template Result<long double>::Dvd
00950 operator/(const Row<N,E,S>& l, const long double& r)
00951   { return Row<N,E,S>::template Result<long double>::DvdOp::perform(l,r); }
00952 template <int N, class E, int S> inline
00953 typename CNT<long double>::template Result<Row<N,E,S> >::Dvd
00954 operator/(const long double& l, const Row<N,E,S>& r)
00955   { return CNT<long double>::template Result<Row<N,E,S> >::DvdOp::perform(l,r); }
00956 
00957 // v = v/int, int/v -- just convert int to v's precision float
00958 template <int N, class E, int S> inline
00959 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Dvd
00960 operator/(const Row<N,E,S>& l, int r) {return l / (typename CNT<E>::Precision)r;}
00961 template <int N, class E, int S> inline
00962 typename CNT<typename CNT<E>::Precision>::template Result<Row<N,E,S> >::Dvd
00963 operator/(int l, const Row<N,E,S>& r) {return (typename CNT<E>::Precision)l / r;}
00964 
00965 
00966 // Complex, conjugate, and negator are all easy to templatize.
00967 
00968 // v = v/complex, complex/v
00969 template <int N, class E, int S, class R> inline
00970 typename Row<N,E,S>::template Result<std::complex<R> >::Dvd
00971 operator/(const Row<N,E,S>& l, const std::complex<R>& r)
00972   { return Row<N,E,S>::template Result<std::complex<R> >::DvdOp::perform(l,r); }
00973 template <int N, class E, int S, class R> inline
00974 typename CNT<std::complex<R> >::template Result<Row<N,E,S> >::Dvd
00975 operator/(const std::complex<R>& l, const Row<N,E,S>& r)
00976   { return CNT<std::complex<R> >::template Result<Row<N,E,S> >::DvdOp::perform(l,r); }
00977 
00978 // v = v/conjugate, conjugate/v (convert conjugate->complex)
00979 template <int N, class E, int S, class R> inline
00980 typename Row<N,E,S>::template Result<std::complex<R> >::Dvd
00981 operator/(const Row<N,E,S>& l, const conjugate<R>& r) {return l/(std::complex<R>)r;}
00982 template <int N, class E, int S, class R> inline
00983 typename CNT<std::complex<R> >::template Result<Row<N,E,S> >::Dvd
00984 operator/(const conjugate<R>& l, const Row<N,E,S>& r) {return (std::complex<R>)l/r;}
00985 
00986 // v = v/negator, negator/v: convert negator to number
00987 template <int N, class E, int S, class R> inline
00988 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Dvd
00989 operator/(const Row<N,E,S>& l, const negator<R>& r) {return l/(typename negator<R>::StdNumber)(R)r;}
00990 template <int N, class E, int S, class R> inline
00991 typename CNT<R>::template Result<Row<N,E,S> >::Dvd
00992 operator/(const negator<R>& l, const Row<N,E,S>& r) {return (typename negator<R>::StdNumber)(R)l/r;}
00993 
00994 
00995 // Add and subtract are odd as scalar ops. They behave as though the
00996 // scalar stands for a vector each of whose elements is that scalar,
00997 // and then a normal vector add or subtract is done.
00998 
00999 // SCALAR ADD
01000 
01001 // v = v+real, real+v 
01002 template <int N, class E, int S> inline
01003 typename Row<N,E,S>::template Result<float>::Add
01004 operator+(const Row<N,E,S>& l, const float& r)
01005   { return Row<N,E,S>::template Result<float>::AddOp::perform(l,r); }
01006 template <int N, class E, int S> inline
01007 typename Row<N,E,S>::template Result<float>::Add
01008 operator+(const float& l, const Row<N,E,S>& r) {return r+l;}
01009 
01010 template <int N, class E, int S> inline
01011 typename Row<N,E,S>::template Result<double>::Add
01012 operator+(const Row<N,E,S>& l, const double& r)
01013   { return Row<N,E,S>::template Result<double>::AddOp::perform(l,r); }
01014 template <int N, class E, int S> inline
01015 typename Row<N,E,S>::template Result<double>::Add
01016 operator+(const double& l, const Row<N,E,S>& r) {return r+l;}
01017 
01018 template <int N, class E, int S> inline
01019 typename Row<N,E,S>::template Result<long double>::Add
01020 operator+(const Row<N,E,S>& l, const long double& r)
01021   { return Row<N,E,S>::template Result<long double>::AddOp::perform(l,r); }
01022 template <int N, class E, int S> inline
01023 typename Row<N,E,S>::template Result<long double>::Add
01024 operator+(const long double& l, const Row<N,E,S>& r) {return r+l;}
01025 
01026 // v = v+int, int+v -- just convert int to v's precision float
01027 template <int N, class E, int S> inline
01028 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Add
01029 operator+(const Row<N,E,S>& l, int r) {return l + (typename CNT<E>::Precision)r;}
01030 template <int N, class E, int S> inline
01031 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Add
01032 operator+(int l, const Row<N,E,S>& r) {return r + (typename CNT<E>::Precision)l;}
01033 
01034 // Complex, conjugate, and negator are all easy to templatize.
01035 
01036 // v = v+complex, complex+v
01037 template <int N, class E, int S, class R> inline
01038 typename Row<N,E,S>::template Result<std::complex<R> >::Add
01039 operator+(const Row<N,E,S>& l, const std::complex<R>& r)
01040   { return Row<N,E,S>::template Result<std::complex<R> >::AddOp::perform(l,r); }
01041 template <int N, class E, int S, class R> inline
01042 typename Row<N,E,S>::template Result<std::complex<R> >::Add
01043 operator+(const std::complex<R>& l, const Row<N,E,S>& r) {return r+l;}
01044 
01045 // v = v+conjugate, conjugate+v (convert conjugate->complex)
01046 template <int N, class E, int S, class R> inline
01047 typename Row<N,E,S>::template Result<std::complex<R> >::Add
01048 operator+(const Row<N,E,S>& l, const conjugate<R>& r) {return l+(std::complex<R>)r;}
01049 template <int N, class E, int S, class R> inline
01050 typename Row<N,E,S>::template Result<std::complex<R> >::Add
01051 operator+(const conjugate<R>& l, const Row<N,E,S>& r) {return r+(std::complex<R>)l;}
01052 
01053 // v = v+negator, negator+v: convert negator to standard number
01054 template <int N, class E, int S, class R> inline
01055 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Add
01056 operator+(const Row<N,E,S>& l, const negator<R>& r) {return l + (typename negator<R>::StdNumber)(R)r;}
01057 template <int N, class E, int S, class R> inline
01058 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Add
01059 operator+(const negator<R>& l, const Row<N,E,S>& r) {return r + (typename negator<R>::StdNumber)(R)l;}
01060 
01061 // SCALAR SUBTRACT -- careful, not commutative.
01062 
01063 // v = v-real, real-v 
01064 template <int N, class E, int S> inline
01065 typename Row<N,E,S>::template Result<float>::Sub
01066 operator-(const Row<N,E,S>& l, const float& r)
01067   { return Row<N,E,S>::template Result<float>::SubOp::perform(l,r); }
01068 template <int N, class E, int S> inline
01069 typename CNT<float>::template Result<Row<N,E,S> >::Sub
01070 operator-(const float& l, const Row<N,E,S>& r)
01071   { return CNT<float>::template Result<Row<N,E,S> >::SubOp::perform(l,r); }
01072 
01073 template <int N, class E, int S> inline
01074 typename Row<N,E,S>::template Result<double>::Sub
01075 operator-(const Row<N,E,S>& l, const double& r)
01076   { return Row<N,E,S>::template Result<double>::SubOp::perform(l,r); }
01077 template <int N, class E, int S> inline
01078 typename CNT<double>::template Result<Row<N,E,S> >::Sub
01079 operator-(const double& l, const Row<N,E,S>& r)
01080   { return CNT<double>::template Result<Row<N,E,S> >::SubOp::perform(l,r); }
01081 
01082 template <int N, class E, int S> inline
01083 typename Row<N,E,S>::template Result<long double>::Sub
01084 operator-(const Row<N,E,S>& l, const long double& r)
01085   { return Row<N,E,S>::template Result<long double>::SubOp::perform(l,r); }
01086 template <int N, class E, int S> inline
01087 typename CNT<long double>::template Result<Row<N,E,S> >::Sub
01088 operator-(const long double& l, const Row<N,E,S>& r)
01089   { return CNT<long double>::template Result<Row<N,E,S> >::SubOp::perform(l,r); }
01090 
01091 // v = v-int, int-v // just convert int to v's precision float
01092 template <int N, class E, int S> inline
01093 typename Row<N,E,S>::template Result<typename CNT<E>::Precision>::Sub
01094 operator-(const Row<N,E,S>& l, int r) {return l - (typename CNT<E>::Precision)r;}
01095 template <int N, class E, int S> inline
01096 typename CNT<typename CNT<E>::Precision>::template Result<Row<N,E,S> >::Sub
01097 operator-(int l, const Row<N,E,S>& r) {return (typename CNT<E>::Precision)l - r;}
01098 
01099 
01100 // Complex, conjugate, and negator are all easy to templatize.
01101 
01102 // v = v-complex, complex-v
01103 template <int N, class E, int S, class R> inline
01104 typename Row<N,E,S>::template Result<std::complex<R> >::Sub
01105 operator-(const Row<N,E,S>& l, const std::complex<R>& r)
01106   { return Row<N,E,S>::template Result<std::complex<R> >::SubOp::perform(l,r); }
01107 template <int N, class E, int S, class R> inline
01108 typename CNT<std::complex<R> >::template Result<Row<N,E,S> >::Sub
01109 operator-(const std::complex<R>& l, const Row<N,E,S>& r)
01110   { return CNT<std::complex<R> >::template Result<Row<N,E,S> >::SubOp::perform(l,r); }
01111 
01112 // v = v-conjugate, conjugate-v (convert conjugate->complex)
01113 template <int N, class E, int S, class R> inline
01114 typename Row<N,E,S>::template Result<std::complex<R> >::Sub
01115 operator-(const Row<N,E,S>& l, const conjugate<R>& r) {return l-(std::complex<R>)r;}
01116 template <int N, class E, int S, class R> inline
01117 typename CNT<std::complex<R> >::template Result<Row<N,E,S> >::Sub
01118 operator-(const conjugate<R>& l, const Row<N,E,S>& r) {return (std::complex<R>)l-r;}
01119 
01120 // v = v-negator, negator-v: convert negator to standard number
01121 template <int N, class E, int S, class R> inline
01122 typename Row<N,E,S>::template Result<typename negator<R>::StdNumber>::Sub
01123 operator-(const Row<N,E,S>& l, const negator<R>& r) {return l-(typename negator<R>::StdNumber)(R)r;}
01124 template <int N, class E, int S, class R> inline
01125 typename CNT<R>::template Result<Row<N,E,S> >::Sub
01126 operator-(const negator<R>& l, const Row<N,E,S>& r) {return (typename negator<R>::StdNumber)(R)l-r;}
01127 
01128 
01129 // Row I/O
01130 template <int N, class E, int S, class CHAR, class TRAITS> inline
01131 std::basic_ostream<CHAR,TRAITS>&
01132 operator<<(std::basic_ostream<CHAR,TRAITS>& o, const Row<N,E,S>& v) {
01133     o << "[" << v[0]; for(int i=1;i<N;++i) o<<','<<v[i]; o<<']'; return o;
01134 }
01135 
01138 template <int N, class E, int S, class CHAR, class TRAITS> inline
01139 std::basic_istream<CHAR,TRAITS>&
01140 operator>>(std::basic_istream<CHAR,TRAITS>& is, Row<N,E,S>& v) {
01141     CHAR openBracket, closeBracket;
01142     is >> openBracket; if (is.fail()) return is;
01143     if (openBracket==CHAR('('))
01144         closeBracket = CHAR(')');
01145     else if (openBracket==CHAR('['))
01146         closeBracket = CHAR(']');
01147     else {
01148         closeBracket = CHAR(0);
01149         is.unget(); if (is.fail()) return is;
01150     }
01151 
01152     for (int i=0; i < N; ++i) {
01153         is >> v[i];
01154         if (is.fail()) return is;
01155         if (i != N-1) {
01156             CHAR c; is >> c; if (is.fail()) return is;
01157             if (c != ',') is.unget();
01158             if (is.fail()) return is;
01159         }
01160     }
01161 
01162     // Get the closing bracket if there was an opening one. If we don't
01163     // see the expected character we'll set the fail bit in the istream.
01164     if (closeBracket != CHAR(0)) {
01165         CHAR closer; is >> closer; if (is.fail()) return is;
01166         if (closer != closeBracket) {
01167             is.unget(); if (is.fail()) return is;
01168             is.setstate( std::ios::failbit );
01169         }
01170     }
01171 
01172     return is;
01173 }
01174 
01175 } //namespace SimTK
01176 
01177 
01178 #endif //SimTK_SIMMATRIX_SMALLMATRIX_ROW_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines