BigMatrix.h

Go to the documentation of this file.
00001 #ifndef SimTK_SIMMATRIX_BIGMATRIX_H_
00002 #define SimTK_SIMMATRIX_BIGMATRIX_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-8 Stanford University and the Authors.         *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
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 
00108 #include "SimTKcommon/Scalar.h"
00109 #include "SimTKcommon/SmallMatrix.h"
00110 
00111 #include "SimTKcommon/internal/MatrixHelper.h"
00112 
00113 #include <iostream>
00114 #include <cassert>
00115 #include <complex>
00116 #include <cstddef>
00117 #include <limits>
00118 
00119 namespace SimTK {
00120 
00121 template <class ELT>    class MatrixBase;
00122 template <class ELT>    class VectorBase;
00123 template <class ELT>    class RowVectorBase;
00124 
00125 template <class T=Real> class MatrixView_;
00126 template <class T=Real> class TmpMatrixView_;
00127 template <class T=Real> class Matrix_;
00128 template <class T=Real> class DeadMatrix_;
00129 
00130 template <class T=Real> class VectorView_;
00131 template <class T=Real> class TmpVectorView_;
00132 template <class T=Real> class Vector_;
00133 template <class T=Real> class DeadVector_;
00134 
00135 template <class T=Real> class RowVectorView_;
00136 template <class T=Real> class TmpRowVectorView_;
00137 template <class T=Real> class RowVector_;
00138 template <class T=Real> class DeadRowVector_;
00139 
00140 template <class ELT, class VECTOR_CLASS> class VectorIterator;
00141 
00164 template <class ELT> class MatrixBase {  
00165 public:
00166     // These typedefs are handy, but despite appearances you cannot 
00167     // treat a MatrixBase as a composite numerical type. That is,
00168     // CNT<MatrixBase> will not compile, or if it does it won't be
00169     // meaningful.
00170 
00171     typedef ELT                                 E;
00172     typedef typename CNT<E>::TNeg               ENeg;
00173     typedef typename CNT<E>::TWithoutNegator    EWithoutNegator;
00174     typedef typename CNT<E>::TReal              EReal;
00175     typedef typename CNT<E>::TImag              EImag;
00176     typedef typename CNT<E>::TComplex           EComplex;
00177     typedef typename CNT<E>::THerm              EHerm;       
00178     typedef typename CNT<E>::TPosTrans          EPosTrans;
00179 
00180     typedef typename CNT<E>::TAbs               EAbs;
00181     typedef typename CNT<E>::TStandard          EStandard;
00182     typedef typename CNT<E>::TInvert            EInvert;
00183     typedef typename CNT<E>::TNormalize         ENormalize;
00184     typedef typename CNT<E>::TSqHermT           ESqHermT;
00185     typedef typename CNT<E>::TSqTHerm           ESqTHerm;
00186 
00187     typedef typename CNT<E>::Scalar             EScalar;
00188     typedef typename CNT<E>::Number             ENumber;
00189     typedef typename CNT<E>::StdNumber          EStdNumber;
00190     typedef typename CNT<E>::Precision          EPrecision;
00191     typedef typename CNT<E>::ScalarSq           EScalarSq;
00192 
00193     typedef EScalar    Scalar;        // the underlying Scalar type
00194     typedef ENumber    Number;        // negator removed from Scalar
00195     typedef EStdNumber StdNumber;     // conjugate goes to complex
00196     typedef EPrecision Precision;     // complex removed from StdNumber
00197     typedef EScalarSq  ScalarSq;
00198 
00199     typedef MatrixBase<E>                T;
00200     typedef MatrixBase<ENeg>             TNeg;
00201     typedef MatrixBase<EWithoutNegator>  TWithoutNegator;
00202     typedef MatrixBase<EReal>            TReal;
00203     typedef MatrixBase<EImag>            TImag;
00204     typedef MatrixBase<EComplex>         TComplex;
00205     typedef MatrixBase<EHerm>            THerm; 
00206     typedef MatrixBase<E>                TPosTrans;
00207 
00208     typedef MatrixBase<EAbs>             TAbs;
00209     typedef MatrixBase<EStandard>        TStandard;
00210     typedef MatrixBase<EInvert>          TInvert;
00211     typedef MatrixBase<ENormalize>       TNormalize;
00212     typedef MatrixBase<ESqHermT>         TSqHermT;  // ~Mat*Mat
00213     typedef MatrixBase<ESqTHerm>         TSqTHerm;  // Mat*~Mat
00214 
00215 
00216     void setMatrixStructure(MatrixStructures::Structure structure) {
00217         helper.setMatrixStructure( structure);  // default Uncommitted
00218     }
00219     MatrixStructures::Structure getMatrixStructure() const {
00220         return helper.getMatrixStructure();
00221     }
00222     void setMatrixShape(MatrixShapes::Shape shape) {
00223         helper.setMatrixShape( shape);          // default Uncommitted
00224     }
00225     MatrixShapes::Shape getMatrixShape() const  {
00226         return helper.getMatrixShape();
00227     }
00228     void setMatrixSparsity(MatrixSparseFormats::Sparsity sparsity) {
00229         helper.setMatrixSparsity( sparsity);    // default Uncommitted
00230     }
00231     MatrixSparseFormats::Sparsity getMatrixSparsity() const  {
00232         return helper.getMatrixSparsity();
00233     }
00234     void setMatrixStorage(MatrixStorageFormats::Storage storage) {
00235         helper.setMatrixStorage( storage);      // default Uncommitted
00236     }
00237     MatrixStorageFormats::Storage getMatrixStorage() const  {
00238         return helper.getMatrixStorage();
00239     }
00240 
00241     void setMatrixCondition(MatrixConditions::Condition condition) {
00242         helper.setMatrixCondition(condition);  //  default Uncommitted
00243     }
00244     MatrixConditions::Condition getMatrixCondition() const  {
00245         return helper.getMatrixCondition();
00246     }
00247 
00248 
00249     // This gives the resulting matrix type when (m(i,j) op P) is applied to each element.
00250     // It will have element types which are the regular composite result of E op P.
00251     template <class P> struct EltResult { 
00252         typedef MatrixBase<typename CNT<E>::template Result<P>::Mul> Mul;
00253         typedef MatrixBase<typename CNT<E>::template Result<P>::Dvd> Dvd;
00254         typedef MatrixBase<typename CNT<E>::template Result<P>::Add> Add;
00255         typedef MatrixBase<typename CNT<E>::template Result<P>::Sub> Sub;
00256     };
00257        
00258     // Product of dimensions may be > 32 bits.
00259     long size() const { return helper.size(); }
00260     int  nrow() const { return helper.nrow(); }
00261     int  ncol() const { return helper.ncol(); }
00262 
00263     // Scalar norm square is sum( squares of all scalars )
00264     // TODO: very slow! Should be optimized at least for the case
00265     //       where ELT is a Scalar.
00266     ScalarSq scalarNormSqr() const {
00267         const int nr=nrow(), nc=ncol();
00268         ScalarSq sum(0);
00269         for(int j=0;j<nc;++j) 
00270             for (int i=0; i<nr; ++i)
00271                 sum += CNT<E>::scalarNormSqr((*this)(i,j));
00272         return sum;
00273     }
00274 
00275     // abs() is elementwise absolute value; that is, the return value has the same
00276     // dimension as this Matrix but with each element replaced by whatever it thinks
00277     // its absolute value is.
00278     // TODO: very slow! Should be optimized at least for the case
00279     //       where ELT is a Scalar.
00280     void abs(TAbs& mabs) const {
00281         const int nr=nrow(), nc=ncol();
00282         mabs.resize(nr,nc);
00283         for(int j=0;j<nc;++j) 
00284             for (int i=0; i<nr; ++i)
00285                 mabs(i,j) = CNT<E>::abs((*this)(i,j));
00286     }
00287 
00288     TAbs abs() const { TAbs mabs; abs(mabs); return mabs; }
00289 
00290     // Return a Matrix of the same shape and contents as this one but
00291     // with the element type converted to one based on the standard
00292     // C++ scalar types: float, double, long double or complex<float>,
00293     // complex<double>, complex<long double>. That is, negator<>
00294     // and conjugate<> are eliminated from the element type by 
00295     // performing any needed negations computationally.
00296     TStandard standardize() const {
00297         const int nr=nrow(), nc=ncol();
00298         TStandard mstd(nr, nc);
00299         for(int j=0;j<nc;++j) 
00300             for (int i=0; i<nr; ++i)
00301                 mstd(i,j) = CNT<E>::standardize((*this)(i,j));
00302         return mstd;
00303     }
00304 
00305     enum { 
00306         NScalarsPerElement    = CNT<E>::NActualScalars,
00307         CppNScalarsPerElement = sizeof(E) / sizeof(Scalar)
00308     };
00309   
00310     MatrixBase() : helper(NScalarsPerElement,CppNScalarsPerElement)  { }
00311 
00312     // This restores the MatrixBase to its just-constructed state.
00313     void clear() {
00314         helper.clear();
00315     }
00316 
00317     
00318     // Copy constructor is a deep copy (not appropriate for views!).    
00319     MatrixBase(const MatrixBase& b)
00320       : helper(b.helper, typename MatrixHelper<Scalar>::DeepCopy()) { }
00321     
00322     // Copy assignment is a deep copy but behavior depends on type of lhs: if view, rhs
00323     // must match. If owner, we reallocate and copy rhs.
00324     MatrixBase& copyAssign(const MatrixBase& b) {
00325         helper.copyAssign(b.helper);
00326         return *this;
00327     }
00328     MatrixBase& operator=(const MatrixBase& b) { return copyAssign(b); }
00329 
00330     // View assignment is a shallow copy, meaning that we disconnect the MatrixBase 
00331     // from whatever it used to refer to (destructing as necessary), then make it a new view
00332     // for the data descriptor referenced by the source.
00333     // CAUTION: we always take the source as const, but that is ignored in 
00334     // determining whether the resulting view is writable. Instead, that is
00335     // inherited from the writability status of the source. We have to do this
00336     // in order to allow temporary view objects to be writable -- the compiler
00337     // creates temporaries like m(i,j,m,n) as const.
00338 
00339     MatrixBase& viewAssign(const MatrixBase& src) {
00340         helper.writableViewAssign(const_cast<MatrixHelper<Scalar>&>(src.helper));
00341         return *this;
00342     }
00343 
00344     // default destructor
00345 
00346 
00347     MatrixBase(int m, int n, bool lockNrow=false, bool lockNcol=false) 
00348       : helper(NScalarsPerElement, CppNScalarsPerElement, m, n, lockNrow, lockNcol)  { }
00349         
00350     // Non-resizeable owner sharing pre-allocated raw data
00351     MatrixBase(int m, int n, int leadingDim, const Scalar* s)
00352       : helper(NScalarsPerElement, CppNScalarsPerElement, m, n, leadingDim, s) { }    // read only
00353     MatrixBase(int m, int n, int leadingDim, Scalar* s)
00354       : helper(NScalarsPerElement, CppNScalarsPerElement, m, n, leadingDim, s) { }    // writable
00355             
00356     MatrixBase(int m, int n, const ELT& t) 
00357       : helper(NScalarsPerElement, CppNScalarsPerElement, m, n)
00358       { helper.fillWith(reinterpret_cast<const Scalar*>(&t)); }    
00359     MatrixBase(int m, int n, bool lockNrow, bool lockNcol, const ELT& t) 
00360       : helper(NScalarsPerElement, CppNScalarsPerElement, m, n, lockNrow, lockNcol)
00361       { helper.fillWith(reinterpret_cast<const Scalar*>(&t)); }
00362         
00363     MatrixBase(int m, int n, const ELT* p) 
00364       : helper(NScalarsPerElement, CppNScalarsPerElement, m, n)
00365       { helper.copyInByRows(reinterpret_cast<const Scalar*>(p)); }
00366     MatrixBase(int m, int n,  bool lockNrow, bool lockNcol, const ELT* p) 
00367       : helper(NScalarsPerElement, CppNScalarsPerElement, m, n, lockNrow, lockNcol)
00368       { helper.copyInByRows(reinterpret_cast<const Scalar*>(p)); }
00369         
00370     // Create a new MatrixBase from an existing helper. Both shallow and deep copies are possible.
00371     MatrixBase(MatrixHelper<Scalar>&       h, const typename MatrixHelper<Scalar>::ShallowCopy& s) : helper(h,s) { }
00372     MatrixBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::ShallowCopy& s) : helper(h,s) { }
00373     MatrixBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::DeepCopy& d)    : helper(h,d) { }
00374 
00375 
00376     MatrixBase& operator*=(const StdNumber& t)  { helper.scaleBy(t);              return *this; }
00377     MatrixBase& operator/=(const StdNumber& t)  { helper.scaleBy(StdNumber(1)/t); return *this; }
00378     MatrixBase& operator+=(const MatrixBase& r) { helper.addIn(r.helper);         return *this; }
00379     MatrixBase& operator-=(const MatrixBase& r) { helper.subIn(r.helper);         return *this; }  
00380 
00381     template <class EE> MatrixBase(const MatrixBase<EE>& b)
00382       : helper(b.helper, typename MatrixHelper<Scalar>::DeepCopy()) { }
00383 
00384     template <class EE> MatrixBase& operator=(const MatrixBase<EE>& b) 
00385       { helper = b.helper; return *this; }
00386     template <class EE> MatrixBase& operator+=(const MatrixBase<EE>& b) 
00387       { helper.addIn(b.helper); return *this; }
00388     template <class EE> MatrixBase& operator-=(const MatrixBase<EE>& b) 
00389       { helper.subIn(b.helper); return *this; }
00390 
00391     // Matrix assignment to an element sets only the *diagonal* elements to
00392     // the indicated value; everything else is set to zero. This is particularly
00393     // useful for setting a Matrix to zero or to the identity; for other values
00394     // it create as Matrix which acts like the scalar. That is, if the scalar
00395     // is s and we do M=s, then multiplying another Matrix B by the resulting 
00396     // diagonal matrix M gives the same result as multiplying B by s. That is
00397     // (M=s)*B == s*B.
00398     //
00399     // NOTE: this must be overridden for Vector and RowVector since then scalar
00400     // assignment is defined to copy the scalar to every element.
00401     MatrixBase& operator=(const ELT& t) { 
00402         setToZero(); updDiag().setTo(t); 
00403         return *this;
00404     }
00405 
00411     template <class S> inline MatrixBase&
00412     scalarAssign(const S& s) {
00413         setToZero(); updDiag().setTo(s);
00414         return *this;
00415     }
00416 
00420     template <class S> inline MatrixBase&
00421     scalarAddInPlace(const S& s) {
00422         updDiag().elementwiseAddScalarInPlace(s);
00423     }
00424 
00425 
00429     template <class S> inline MatrixBase&
00430     scalarSubtractInPlace(const S& s) {
00431         updDiag().elementwiseSubtractScalarInPlace(s);
00432     }
00433 
00436     template <class S> inline MatrixBase&
00437     scalarSubtractFromLeftInPlace(const S& s) {
00438         negateInPlace();
00439         updDiag().elementwiseAddScalarInPlace(s); // yes, add
00440     }
00441 
00448     template <class S> inline MatrixBase&
00449     scalarMultiplyInPlace(const S&);
00450 
00454     template <class S> inline MatrixBase&
00455     scalarMultiplyFromLeftInPlace(const S&);
00456 
00463     template <class S> inline MatrixBase&
00464     scalarDivideInPlace(const S&);
00465 
00469     template <class S> inline MatrixBase&
00470     scalarDivideFromLeftInPlace(const S&);
00471 
00472 
00473     // M = diag(r) * M; r must have nrow() elements.
00474     // That is, M[i] *= r[i].
00475     template <class EE> inline MatrixBase& 
00476     rowScaleInPlace(const VectorBase<EE>&);
00477 
00478     // Return type is a new matrix which will have the same dimensions as 'this' but
00479     // will have element types appropriate for the elementwise multiply being performed.
00480     template <class EE> inline void 
00481     rowScale(const VectorBase<EE>& r, typename EltResult<EE>::Mul& out) const;
00482 
00483     template <class EE> inline typename EltResult<EE>::Mul 
00484     rowScale(const VectorBase<EE>& r) const {
00485         typename EltResult<EE>::Mul out(nrow(), ncol()); rowScale(r,out); return out;
00486     }
00487 
00488     // M = M * diag(c); c must have ncol() elements
00489     // That is, M(j) *= c[j]
00490     template <class EE> inline MatrixBase& 
00491     colScaleInPlace(const VectorBase<EE>&);
00492 
00493     template <class EE> inline void 
00494     colScale(const VectorBase<EE>& c, typename EltResult<EE>::Mul& out) const;
00495 
00496     template <class EE> inline typename EltResult<EE>::Mul
00497     colScale(const VectorBase<EE>& c) const {
00498         typename EltResult<EE>::Mul out(nrow(), ncol()); colScale(c,out); return out;
00499     }
00500 
00501     // Having a combined row & column scaling operator means we can go through the matrix
00502     // memory once instead of twice.
00503 
00504     // M = diag(r) * M * diag(c); r must have nrow() elements;  must have ncol() elements
00505     // That is, M(i,j) *= r[i]*c[j]
00506     template <class ER, class EC> inline MatrixBase& 
00507     rowAndColScaleInPlace(const VectorBase<ER>& r, const VectorBase<EC>& c);
00508 
00509     template <class ER, class EC> inline void 
00510     rowAndColScale(const VectorBase<ER>& r, const VectorBase<EC>& c, 
00511                    typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul& out) const;
00512 
00513     template <class ER, class EC> inline typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul
00514     rowAndColScale(const VectorBase<ER>& r, const VectorBase<EC>& c) const {
00515         typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul 
00516             out(nrow(), ncol()); 
00517         rowAndColScale(r,c,out); return out;
00518     }
00519 
00527     template <class S> inline MatrixBase&
00528     elementwiseAssign(const S& s);
00529 
00531     MatrixBase& elementwiseInvertInPlace();
00532 
00533     void elementwiseInvert(MatrixBase<typename CNT<E>::TInvert>& out) const;
00534 
00535     MatrixBase<typename CNT<E>::TInvert> elementwiseInvert() const {
00536         MatrixBase<typename CNT<E>::TInvert> out(nrow(), ncol());
00537         elementwiseInvert(out);
00538         return out;
00539     }
00540 
00548     template <class S> inline MatrixBase&
00549     elementwiseAddScalarInPlace(const S& s);
00550 
00551     template <class S> inline void
00552     elementwiseAddScalar(const S& s, typename EltResult<S>::Add&) const;
00553 
00554     template <class S> inline typename EltResult<S>::Add
00555     elementwiseAddScalar(const S& s) const {
00556         typename EltResult<S>::Add out(nrow(), ncol());
00557         elementwiseAddScalar(s,out);
00558         return out;
00559     }
00560 
00568     template <class S> inline MatrixBase&
00569     elementwiseSubtractScalarInPlace(const S& s);
00570 
00571     template <class S> inline void
00572     elementwiseSubtractScalar(const S& s, typename EltResult<S>::Sub&) const;
00573 
00574     template <class S> inline typename EltResult<S>::Sub
00575     elementwiseSubtractScalar(const S& s) const {
00576         typename EltResult<S>::Sub out(nrow(), ncol());
00577         elementwiseSubtractScalar(s,out);
00578         return out;
00579     }
00580 
00589     template <class S> inline MatrixBase&
00590     elementwiseSubtractFromScalarInPlace(const S& s);
00591 
00592     template <class S> inline void
00593     elementwiseSubtractFromScalar(
00594         const S&, 
00595         typename MatrixBase<S>::template EltResult<E>::Sub&) const;
00596 
00597     template <class S> inline typename MatrixBase<S>::template EltResult<E>::Sub
00598     elementwiseSubtractFromScalar(const S& s) const {
00599         typename MatrixBase<S>::template EltResult<E>::Sub out(nrow(), ncol());
00600         elementwiseSubtractFromScalar<S>(s,out);
00601         return out;
00602     }
00603 
00604     // M(i,j) *= R(i,j); R must have same dimensions as this
00605     template <class EE> inline MatrixBase& 
00606     elementwiseMultiplyInPlace(const MatrixBase<EE>&);
00607 
00608     template <class EE> inline void 
00609     elementwiseMultiply(const MatrixBase<EE>&, typename EltResult<EE>::Mul&) const;
00610 
00611     template <class EE> inline typename EltResult<EE>::Mul 
00612     elementwiseMultiply(const MatrixBase<EE>& m) const {
00613         typename EltResult<EE>::Mul out(nrow(), ncol()); 
00614         elementwiseMultiply<EE>(m,out); 
00615         return out;
00616     }
00617 
00618     // M(i,j) = R(i,j) * M(i,j); R must have same dimensions as this
00619     template <class EE> inline MatrixBase& 
00620     elementwiseMultiplyFromLeftInPlace(const MatrixBase<EE>&);
00621 
00622     template <class EE> inline void 
00623     elementwiseMultiplyFromLeft(
00624         const MatrixBase<EE>&, 
00625         typename MatrixBase<EE>::template EltResult<E>::Mul&) const;
00626 
00627     template <class EE> inline typename MatrixBase<EE>::template EltResult<E>::Mul 
00628     elementwiseMultiplyFromLeft(const MatrixBase<EE>& m) const {
00629         typename EltResult<EE>::Mul out(nrow(), ncol()); 
00630         elementwiseMultiplyFromLeft<EE>(m,out); 
00631         return out;
00632     }
00633 
00634     // M(i,j) /= R(i,j); R must have same dimensions as this
00635     template <class EE> inline MatrixBase& 
00636     elementwiseDivideInPlace(const MatrixBase<EE>&);
00637 
00638     template <class EE> inline void 
00639     elementwiseDivide(const MatrixBase<EE>&, typename EltResult<EE>::Dvd&) const;
00640 
00641     template <class EE> inline typename EltResult<EE>::Dvd 
00642     elementwiseDivide(const MatrixBase<EE>& m) const {
00643         typename EltResult<EE>::Dvd out(nrow(), ncol()); 
00644         elementwiseDivide<EE>(m,out); 
00645         return out;
00646     }
00647 
00648     // M(i,j) = R(i,j) / M(i,j); R must have same dimensions as this
00649     template <class EE> inline MatrixBase& 
00650     elementwiseDivideFromLeftInPlace(const MatrixBase<EE>&);
00651 
00652     template <class EE> inline void 
00653     elementwiseDivideFromLeft(
00654         const MatrixBase<EE>&,
00655         typename MatrixBase<EE>::template EltResult<E>::Dvd&) const;
00656 
00657     template <class EE> inline typename MatrixBase<EE>::template EltResult<EE>::Dvd 
00658     elementwiseDivideFromLeft(const MatrixBase<EE>& m) const {
00659         typename MatrixBase<EE>::template EltResult<E>::Dvd out(nrow(), ncol()); 
00660         elementwiseDivideFromLeft<EE>(m,out); 
00661         return out;
00662     }
00663 
00664     // fill every element in current allocation with given element (or NaN or 0)
00665     MatrixBase& setTo(const ELT& t) {helper.fillWith(reinterpret_cast<const Scalar*>(&t)); return *this;}
00666     MatrixBase& setToNaN() {helper.fillWithScalar(CNT<StdNumber>::getNaN()); return *this;}
00667     MatrixBase& setToZero() {helper.fillWithScalar(StdNumber(0)); return *this;}
00668  
00669     // View creating operators. TODO: these should be DeadMatrixViews  
00670     inline RowVectorView_<ELT> row(int i) const;   // select a row
00671     inline RowVectorView_<ELT> updRow(int i);
00672     inline VectorView_<ELT>    col(int j) const;   // select a column
00673     inline VectorView_<ELT>    updCol(int j);
00674 
00675     RowVectorView_<ELT> operator[](int i) const {return row(i);}
00676     RowVectorView_<ELT> operator[](int i)       {return updRow(i);}
00677     VectorView_<ELT>    operator()(int j) const {return col(j);}
00678     VectorView_<ELT>    operator()(int j)       {return updCol(j);}
00679      
00680     // Select a block.
00681     inline MatrixView_<ELT> block(int i, int j, int m, int n) const;
00682     inline MatrixView_<ELT> updBlock(int i, int j, int m, int n);
00683 
00684     MatrixView_<ELT> operator()(int i, int j, int m, int n) const
00685       { return block(i,j,m,n); }
00686     MatrixView_<ELT> operator()(int i, int j, int m, int n)
00687       { return updBlock(i,j,m,n); }
00688  
00689     // Hermitian transpose.
00690     inline MatrixView_<EHerm> transpose() const;
00691     inline MatrixView_<EHerm> updTranspose();
00692 
00693     MatrixView_<EHerm> operator~() const {return transpose();}
00694     MatrixView_<EHerm> operator~()       {return updTranspose();}
00695 
00696     // Select matrix diagonal (of largest leading square if rectangular).
00697     inline VectorView_<ELT> diag() const;
00698     inline VectorView_<ELT> updDiag();
00699 
00700     // Create a view of the real or imaginary elements. TODO
00701     //inline MatrixView_<EReal> real() const;
00702     //inline MatrixView_<EReal> updReal();
00703     //inline MatrixView_<EImag> imag() const;
00704     //inline MatrixView_<EImag> updImag();
00705 
00706     // Overload "real" and "imag" for both read and write as a nod to convention. TODO
00707     //MatrixView_<EReal> real() {return updReal();}
00708     //MatrixView_<EReal> imag() {return updImag();}
00709 
00710     // TODO: this routine seems ill-advised but I need it for the IVM port at the moment
00711     TInvert invert() const {  // return a newly-allocated inverse; dump negator 
00712         TInvert m(*this);
00713         m.helper.invertInPlace();
00714         return m;   // TODO - bad: makes an extra copy
00715     }
00716 
00717     // Matlab-compatible debug output.
00718     void dump(const char* msg=0) const {
00719         helper.dump(msg);
00720     }
00721 
00722 
00723     // This routine is useful for implementing friendlier Matrix expressions and operators.
00724     // It maps closely to the Level-3 BLAS family of pxxmm() routines like sgemm(). The
00725     // operation performed assumes that "this" is the result, and that "this" has 
00726     // already been sized correctly to receive the result. We'll compute
00727     //     this = beta*this + alpha*A*B
00728     // If beta is 0 then "this" can be uninitialized. If alpha is 0 we promise not
00729     // to look at A or B. The routine can work efficiently even if A and/or B are transposed
00730     // by their views, so an expression like
00731     //        C += s * ~A * ~B
00732     // can be performed with the single equivalent call
00733     //        C.matmul(1., s, Tr(A), Tr(B))
00734     // where Tr(A) indicates a transposed view of the original A.
00735     // The ultimate efficiency of this call depends on the data layout and views which
00736     // are used for the three matrices.
00737     // NOTE: neither A nor B can be the same matrix as 'this', nor views of the same data
00738     // which would expose elements of 'this' that will be modified by this operation.
00739     template <class ELT_A, class ELT_B>
00740     MatrixBase& matmul(const StdNumber& beta,   // applied to 'this'
00741                        const StdNumber& alpha, const MatrixBase<ELT_A>& A, const MatrixBase<ELT_B>& B)
00742     {
00743         helper.matmul(beta,alpha,A.helper,B.helper);
00744         return *this;
00745     }
00746 
00747     // Element selection    
00748     const ELT& getElt(int i, int j) const { return *reinterpret_cast<const ELT*>(helper.getElt(i,j)); }
00749     ELT&       updElt(int i, int j)       { return *reinterpret_cast<      ELT*>(helper.updElt(i,j)); }
00750 
00751     const ELT& operator()(int i, int j) const {return getElt(i,j);}
00752     ELT&       operator()(int i, int j)       {return updElt(i,j);}
00753 
00754     // This is the scalar Frobenius norm, and its square. Note: if this is a Matrix then the Frobenius
00755     // norm is NOT the same as the 2-norm, although they are equivalent for Vectors.
00756     ScalarSq normSqr() const { return scalarNormSqr(); }
00757     ScalarSq norm()    const { return std::sqrt(scalarNormSqr()); } // TODO -- not good; unnecessary overflow
00758 
00759     // We only allow RMS norm if the elements are scalars. If there are no elements in this Matrix,
00760     // we'll define its RMS norm to be 0, although NaN might be a better choice.
00761     ScalarSq normRMS() const {
00762         if (!CNT<ELT>::IsScalar)
00763             SimTK_THROW1(Exception::Cant, "normRMS() only defined for scalar elements");
00764         const long nelt = (long)nrow()*(long)ncol();
00765         if (nelt == 0)
00766             return ScalarSq(0);
00767         return std::sqrt(scalarNormSqr()/nelt);
00768     }
00769 
00770 
00771     RowVectorBase<ELT> sum() const {
00772         const int cols = ncol();
00773         RowVectorBase<ELT> row(cols);
00774         for (int i = 0; i < cols; ++i)
00775             helper.colSum(i, reinterpret_cast<Scalar*>(&row[i]));
00776         return row;
00777     }
00778 
00779     //TODO: make unary +/- return a self-view so they won't reallocate?
00780     const MatrixBase& operator+() const {return *this; }
00781     const TNeg&       negate()    const {return *reinterpret_cast<const TNeg*>(this); }
00782     TNeg&             updNegate()       {return *reinterpret_cast<TNeg*>(this); }
00783 
00784     const TNeg&       operator-() const {return negate();}
00785     TNeg&             operator-()       {return updNegate();}
00786 
00787     MatrixBase& negateInPlace() {(*this) *= EPrecision(-1);}
00788  
00789     MatrixBase& resize(int m, int n)     { helper.resize(m,n); return *this; }
00790     MatrixBase& resizeKeep(int m, int n) { helper.resizeKeep(m,n); return *this; }
00791 
00792     // These prevent shape changes in a Matrix that would otherwise allow it. No harm if they
00793     // are called on a Matrix that is locked already; they always succeed.
00794     void lockNRows() {helper.lockNRows();}
00795     void lockNCols() {helper.lockNCols();}
00796     void lockShape() {helper.lockShape();}
00797 
00798     // These allow shape changes again for a Matrix which was constructed to allow them
00799     // but had them locked with the above routines. No harm if these are called on a Matrix
00800     // that is already unlocked, but it is not allowed to call them on a Matrix which
00801     // *never* allowed resizing. An exception will be thrown in that case.
00802     void unlockNRows() {helper.unlockNRows();}
00803     void unlockNCols() {helper.unlockNCols();}
00804     void unlockShape() {helper.unlockShape();}
00805     
00806     // An assortment of handy conversions
00807     const MatrixView_<ELT>& getAsMatrixView() const { return *reinterpret_cast<const MatrixView_<ELT>*>(this); }
00808     MatrixView_<ELT>&       updAsMatrixView()       { return *reinterpret_cast<      MatrixView_<ELT>*>(this); } 
00809     const Matrix_<ELT>&     getAsMatrix()     const { return *reinterpret_cast<const Matrix_<ELT>*>(this); }
00810     Matrix_<ELT>&           updAsMatrix()           { return *reinterpret_cast<      Matrix_<ELT>*>(this); }
00811          
00812     const VectorView_<ELT>& getAsVectorView() const 
00813       { assert(ncol()==1); return *reinterpret_cast<const VectorView_<ELT>*>(this); }
00814     VectorView_<ELT>&       updAsVectorView()       
00815       { assert(ncol()==1); return *reinterpret_cast<      VectorView_<ELT>*>(this); } 
00816     const Vector_<ELT>&     getAsVector()     const 
00817       { assert(ncol()==1); return *reinterpret_cast<const Vector_<ELT>*>(this); }
00818     Vector_<ELT>&           updAsVector()           
00819       { assert(ncol()==1); return *reinterpret_cast<      Vector_<ELT>*>(this); }
00820     const VectorBase<ELT>& getAsVectorBase() const 
00821       { assert(ncol()==1); return *reinterpret_cast<const VectorBase<ELT>*>(this); }
00822     VectorBase<ELT>&       updAsVectorBase()       
00823       { assert(ncol()==1); return *reinterpret_cast<      VectorBase<ELT>*>(this); } 
00824                 
00825     const RowVectorView_<ELT>& getAsRowVectorView() const 
00826       { assert(nrow()==1); return *reinterpret_cast<const RowVectorView_<ELT>*>(this); }
00827     RowVectorView_<ELT>&       updAsRowVectorView()       
00828       { assert(nrow()==1); return *reinterpret_cast<      RowVectorView_<ELT>*>(this); } 
00829     const RowVector_<ELT>&     getAsRowVector()     const 
00830       { assert(nrow()==1); return *reinterpret_cast<const RowVector_<ELT>*>(this); }
00831     RowVector_<ELT>&           updAsRowVector()           
00832       { assert(nrow()==1); return *reinterpret_cast<      RowVector_<ELT>*>(this); }        
00833     const RowVectorBase<ELT>& getAsRowVectorBase() const 
00834       { assert(nrow()==1); return *reinterpret_cast<const RowVectorBase<ELT>*>(this); }
00835     RowVectorBase<ELT>&       updAsRowVectorBase()       
00836       { assert(nrow()==1); return *reinterpret_cast<      RowVectorBase<ELT>*>(this); } 
00837 
00838     // Access to raw data. We have to return the raw data
00839     // pointer as pointer-to-scalar because we may pack the elements tighter
00840     // than a C++ array would.
00841 
00842     // This is the number of consecutive scalars used to represent one
00843     // element of type ELT. This may be fewer than C++ would use for the
00844     // element, since it may introduce some padding.
00845     int getNScalarsPerElement()  const {return NScalarsPerElement;}
00846 
00847     // This is like sizeof(ELT), but returning the number of bytes we use
00848     // to store the element which may be fewer than what C++ would use.
00849     int getPackedSizeofElement() const {return NScalarsPerElement*sizeof(Scalar);}
00850 
00851     bool hasContiguousData() const {return helper.hasContiguousData();}
00852     long getContiguousScalarDataLength() const {
00853         return helper.getContiguousDataLength();
00854     }
00855     const Scalar* getContiguousScalarData() const {
00856         return helper.getContiguousData();
00857     }
00858     Scalar* updContiguousScalarData() {
00859         return helper.updContiguousData();
00860     }
00861     void replaceContiguousScalarData(Scalar* newData, long length, bool takeOwnership) {
00862         helper.replaceContiguousData(newData,length,takeOwnership);
00863     }
00864     void replaceContiguousScalarData(const Scalar* newData, long length) {
00865         helper.replaceContiguousData(newData,length);
00866     }
00867     void swapOwnedContiguousScalarData(Scalar* newData, int length, Scalar*& oldData) {
00868         helper.swapOwnedContiguousData(newData,length,oldData);
00869     }
00870 protected:
00871     MatrixHelper<Scalar> helper; // this is just one pointer
00872 
00873     template <class EE> friend class MatrixBase;
00874 };
00875 
00881 template <class ELT> class VectorBase : public MatrixBase<ELT> {
00882     typedef MatrixBase<ELT>                             Base;
00883     typedef typename CNT<ELT>::Scalar                   Scalar;
00884     typedef typename CNT<ELT>::Number                   Number;
00885     typedef typename CNT<ELT>::StdNumber                StdNumber;
00886     typedef VectorBase<ELT>                             T;
00887     typedef VectorBase<typename CNT<ELT>::TAbs>         TAbs;
00888     typedef VectorBase<typename CNT<ELT>::TNeg>         TNeg;
00889     typedef RowVectorView_<typename CNT<ELT>::THerm>    THerm;
00890 public:     
00891     VectorBase() : Base(0,1,false,true) { } // a 0x1 matrix locked at 1 column
00892 
00893     // Copy constructor is a deep copy (not appropriate for views!).
00894     VectorBase(const VectorBase& b) : Base(b) { }
00895     
00896     // Copy assignment is deep copy but behavior depends on type of lhs: if view, rhs
00897     // must match. If owner, we reallocate and copy rhs.
00898     VectorBase& operator=(const VectorBase& b) {
00899         Base::operator=(b); return *this;
00900     }
00901 
00902     // default destructor
00903 
00904 
00905     explicit VectorBase(int m, bool lockNrow=false)
00906       : Base(m,1,lockNrow,true) { }
00907         
00908     // Non-resizeable owner sharing pre-allocated raw data
00909     VectorBase(int m, int leadingDim, const Scalar* s)
00910       : Base(m,1,leadingDim,s) { }
00911     VectorBase(int m, int leadingDim, Scalar* s)
00912       : Base(m,1,leadingDim,s) { }
00913             
00914     VectorBase(int m, const ELT& t) : Base(m,1,t) { }  
00915     VectorBase(int m, bool lockNrow, const ELT& t) 
00916       : Base(m,1,lockNrow,true,t) { }
00917         
00918     VectorBase(int m, const ELT* p) : Base(m,1,p) { }
00919     VectorBase(int m, bool lockNrow, const ELT* p) 
00920       : Base(m, 1, lockNrow, true, p) { }
00921         
00922     // Create a new VectorBase from an existing helper. Both shallow and deep copies are possible.
00923     VectorBase(MatrixHelper<Scalar>&       h, const typename MatrixHelper<Scalar>::ShallowCopy& s) : Base(h,s) { }
00924     VectorBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::ShallowCopy& s) : Base(h,s) { }
00925     VectorBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::DeepCopy& d)    : Base(h,d) { }
00926 
00927     // This gives the resulting vector type when (v[i] op P) is applied to each element.
00928     // It will have element types which are the regular composite result of ELT op P.
00929     template <class P> struct EltResult { 
00930         typedef VectorBase<typename CNT<ELT>::template Result<P>::Mul> Mul;
00931         typedef VectorBase<typename CNT<ELT>::template Result<P>::Dvd> Dvd;
00932         typedef VectorBase<typename CNT<ELT>::template Result<P>::Add> Add;
00933         typedef VectorBase<typename CNT<ELT>::template Result<P>::Sub> Sub;
00934     };
00935 
00936     VectorBase& operator*=(const StdNumber& t)  { Base::operator*=(t); return *this; }
00937     VectorBase& operator/=(const StdNumber& t)  { Base::operator/=(t); return *this; }
00938     VectorBase& operator+=(const VectorBase& r) { Base::operator+=(r); return *this; }
00939     VectorBase& operator-=(const VectorBase& r) { Base::operator-=(r); return *this; }  
00940 
00941 
00942     template <class EE> VectorBase& operator=(const VectorBase<EE>& b) 
00943       { Base::operator=(b);  return *this; } 
00944     template <class EE> VectorBase& operator+=(const VectorBase<EE>& b) 
00945       { Base::operator+=(b); return *this; } 
00946     template <class EE> VectorBase& operator-=(const VectorBase<EE>& b) 
00947       { Base::operator-=(b); return *this; } 
00948 
00949 
00950     // Fill current allocation with copies of element. Note that this is not the 
00951     // same behavior as assignment for Matrices, where only the diagonal is set (and
00952     // everything else is set to zero.)
00953     VectorBase& operator=(const ELT& t) { Base::setTo(t); return *this; }  
00954 
00955     // There's only one column here so it's a bit wierd to use rowScale rather than
00956     // elementwiseMultiply, but there's nothing really wrong with it. Using colScale
00957     // would be really wacky since it is the same as a scalar multiply. We won't support
00958     // colScale here except through inheritance where it will not be much use.
00959     template <class EE> VectorBase& rowScaleInPlace(const VectorBase<EE>& v)
00960       { Base::template rowScaleInPlace<EE>(v); return *this; }
00961     template <class EE> inline void rowScale(const VectorBase<EE>& v, typename EltResult<EE>::Mul& out) const
00962       { Base::rowScale(v,out); }
00963     template <class EE> inline typename EltResult<EE>::Mul rowScale(const VectorBase<EE>& v) const
00964       { typename EltResult<EE>::Mul out(nrow()); Base::rowScale(v,out); return out; }
00965 
00967     VectorBase& elementwiseInvertInPlace() {
00968         Base::elementwiseInvertInPlace();
00969         return *this;
00970     }
00971 
00973     void elementwiseInvert(VectorBase<typename CNT<ELT>::TInvert>& out) const {
00974         Base::elementwiseInvert(out);
00975     }
00976 
00978     VectorBase<typename CNT<ELT>::TInvert> elementwiseInvert() const {
00979         VectorBase<typename CNT<ELT>::TInvert> out(nrow());
00980         Base::elementwiseInvert(out);
00981         return out;
00982     }
00983 
00984         // elementwise multiply
00985     template <class EE> VectorBase& elementwiseMultiplyInPlace(const VectorBase<EE>& r)
00986       { Base::template elementwiseMultiplyInPlace<EE>(r); return *this; }
00987     template <class EE> inline void elementwiseMultiply(const VectorBase<EE>& v, typename EltResult<EE>::Mul& out) const
00988       { Base::template elementwiseMultiply<EE>(v,out); }
00989     template <class EE> inline typename EltResult<EE>::Mul elementwiseMultiply(const VectorBase<EE>& v) const
00990       { typename EltResult<EE>::Mul out(nrow()); Base::template elementwiseMultiply<EE>(v,out); return out; }
00991 
00992         // elementwise multiply from left
00993     template <class EE> VectorBase& elementwiseMultiplyFromLeftInPlace(const VectorBase<EE>& r)
00994       { Base::template elementwiseMultiplyFromLeftInPlace<EE>(r); return *this; }
00995     template <class EE> inline void 
00996     elementwiseMultiplyFromLeft(
00997         const VectorBase<EE>& v, 
00998         typename VectorBase<EE>::template EltResult<ELT>::Mul& out) const
00999     { 
01000         Base::template elementwiseMultiplyFromLeft<EE>(v,out);
01001     }
01002     template <class EE> inline typename VectorBase<EE>::template EltResult<ELT>::Mul 
01003     elementwiseMultiplyFromLeft(const VectorBase<EE>& v) const
01004     { 
01005         typename VectorBase<EE>::template EltResult<ELT>::Mul out(nrow()); 
01006         Base::template elementwiseMultiplyFromLeft<EE>(v,out); 
01007         return out;
01008     }
01009 
01010         // elementwise divide
01011     template <class EE> VectorBase& elementwiseDivideInPlace(const VectorBase<EE>& r)
01012       { Base::template elementwiseDivideInPlace<EE>(r); return *this; }
01013     template <class EE> inline void elementwiseDivide(const VectorBase<EE>& v, typename EltResult<EE>::Dvd& out) const
01014       { Base::template elementwiseDivide<EE>(v,out); }
01015     template <class EE> inline typename EltResult<EE>::Dvd elementwiseDivide(const VectorBase<EE>& v) const
01016       { typename EltResult<EE>::Dvd out(nrow()); Base::template elementwiseDivide<EE>(v,out); return out; }
01017 
01018         // elementwise divide from left
01019     template <class EE> VectorBase& elementwiseDivideFromLeftInPlace(const VectorBase<EE>& r)
01020       { Base::template elementwiseDivideFromLeftInPlace<EE>(r); return *this; }
01021     template <class EE> inline void 
01022     elementwiseDivideFromLeft(
01023         const VectorBase<EE>& v, 
01024         typename VectorBase<EE>::template EltResult<ELT>::Dvd& out) const
01025     { 
01026         Base::template elementwiseDivideFromLeft<EE>(v,out);
01027     }
01028     template <class EE> inline typename VectorBase<EE>::template EltResult<ELT>::Dvd 
01029     elementwiseDivideFromLeft(const VectorBase<EE>& v) const
01030     { 
01031         typename VectorBase<EE>::template EltResult<ELT>::Dvd out(nrow()); 
01032         Base::template elementwiseDivideFromLeft<EE>(v,out); 
01033         return out;
01034     }
01035 
01036     // Implicit conversions are allowed to Vector or Matrix, but not to RowVector.   
01037     operator const Vector_<ELT>&()     const { return *reinterpret_cast<const Vector_<ELT>*>(this); }
01038     operator       Vector_<ELT>&()           { return *reinterpret_cast<      Vector_<ELT>*>(this); }
01039     operator const VectorView_<ELT>&() const { return *reinterpret_cast<const VectorView_<ELT>*>(this); }
01040     operator       VectorView_<ELT>&()       { return *reinterpret_cast<      VectorView_<ELT>*>(this); }
01041     
01042     operator const Matrix_<ELT>&()     const { return *reinterpret_cast<const Matrix_<ELT>*>(this); }
01043     operator       Matrix_<ELT>&()           { return *reinterpret_cast<      Matrix_<ELT>*>(this); } 
01044     operator const MatrixView_<ELT>&() const { return *reinterpret_cast<const MatrixView_<ELT>*>(this); }
01045     operator       MatrixView_<ELT>&()       { return *reinterpret_cast<      MatrixView_<ELT>*>(this); } 
01046 
01047 
01048     // Override MatrixBase size() for Vectors to return int instead of long.
01049     int size() const { 
01050         assert(Base::size() <= (long)std::numeric_limits<int>::max()); 
01051         assert(Base::ncol()==1);
01052         return (int)Base::size();
01053     }
01054     int nrow() const { assert(Base::ncol()==1); return Base::nrow(); }
01055     int ncol() const { assert(Base::ncol()==1); return Base::ncol(); }
01056 
01057     // Override MatrixBase operators to return the right shape
01058     TAbs abs() const {TAbs result; Base::abs(result); return result;}
01059     
01060     // Override MatrixBase indexing operators          
01061     const ELT& operator[](int i) const {return Base::operator()(i,0);}
01062     ELT&       operator[](int i)       {return Base::operator()(i,0);}
01063     const ELT& operator()(int i) const {return Base::operator()(i,0);}
01064     ELT&       operator()(int i)       {return Base::operator()(i,0);}
01065          
01066     // View creation      
01067     VectorView_<ELT> operator()(int i, int m) const {return Base::operator()(i,0,m,1).getAsVectorView();}
01068     VectorView_<ELT> operator()(int i, int m)       {return Base::operator()(i,0,m,1).updAsVectorView();}
01069  
01070     // Hermitian transpose.
01071     THerm transpose() const {return Base::transpose().getAsRowVectorView();}
01072     THerm updTranspose()    {return Base::updTranspose().updAsRowVectorView();}
01073 
01074     THerm operator~() const {return transpose();}
01075     THerm operator~()       {return updTranspose();}
01076 
01077     const VectorBase& operator+() const {return *this; }
01078 
01079     // Negation
01080 
01081     const TNeg& negate()    const {return *reinterpret_cast<const TNeg*>(this); }
01082     TNeg&       updNegate()       {return *reinterpret_cast<TNeg*>(this); }
01083 
01084     const TNeg& operator-() const {return negate();}
01085     TNeg&       operator-()       {return updNegate();}
01086 
01087     VectorBase& resize(int m)     {Base::resize(m,1); return *this;}
01088     VectorBase& resizeKeep(int m) {Base::resizeKeep(m,1); return *this;}
01089 
01090     //TODO: this is not re-locking the number of columns at 1.
01091     void clear() {Base::clear(); Base::resize(0,1);}
01092 
01093     ELT sum() const {ELT s; Base::helper.sum(reinterpret_cast<Scalar*>(&s)); return s; } // add all the elements        
01094     VectorIterator<ELT, VectorBase<ELT> > begin() {
01095         return VectorIterator<ELT, VectorBase<ELT> >(*this, 0);
01096     }
01097     VectorIterator<ELT, VectorBase<ELT> > end() {
01098         return VectorIterator<ELT, VectorBase<ELT> >(*this, size());
01099     }
01100 private:
01101     // NO DATA MEMBERS ALLOWED
01102 };
01103 
01104 
01110 template <class ELT> class RowVectorBase : public MatrixBase<ELT> {
01111     typedef MatrixBase<ELT>                             Base;
01112     typedef typename CNT<ELT>::Scalar                   Scalar;
01113     typedef typename CNT<ELT>::Number                   Number;
01114     typedef typename CNT<ELT>::StdNumber                StdNumber;
01115     typedef RowVectorBase<ELT>                          T;
01116     typedef RowVectorBase<typename CNT<ELT>::TAbs>      TAbs;
01117     typedef RowVectorBase<typename CNT<ELT>::TNeg>      TNeg;
01118     typedef VectorView_<typename CNT<ELT>::THerm>       THerm;
01119 public:     
01120     RowVectorBase() : Base(1,0,true,false) { } // a 1x0 matrix locked at 1 row
01121     
01122     // Copy constructor is a deep copy (not appropriate for views!).    
01123     RowVectorBase(const RowVectorBase& b) : Base(b) { }
01124 
01125     // Copy assignment is deep copy but behavior depends on type of lhs: if view, rhs
01126     // must match. If owner, we reallocate and copy rhs.
01127     RowVectorBase& operator=(const RowVectorBase& b) {
01128         Base::operator=(b); return *this;
01129     }
01130 
01131     // default destructor
01132 
01133 
01134     explicit RowVectorBase(int n, bool lockNcol=false)
01135       : Base(1,n,true,lockNcol) { }
01136         
01137     // Non-resizeable owner sharing pre-allocated raw data
01138     RowVectorBase(int n, int leadingDim, const Scalar* s)
01139       : Base(1,n,leadingDim,s) { }
01140     RowVectorBase(int n, int leadingDim, Scalar* s)
01141       : Base(1,n,leadingDim,s) { }
01142             
01143     RowVectorBase(int n, const ELT& t) : Base(1,n,t) { }  
01144     RowVectorBase(int n, bool lockNcol, const ELT& t) 
01145       : Base(1,n,true,lockNcol,t) { }
01146         
01147     RowVectorBase(int n, const ELT* p) : Base(1,n,p) { }
01148     RowVectorBase(int n, bool lockNcol, const ELT* p) 
01149       : Base(1, n, true, lockNcol, p) { }
01150         
01151     // Create a new RowVectorBase from an existing helper. Both shallow and deep copies are possible.
01152     RowVectorBase(MatrixHelper<Scalar>&       h, const typename MatrixHelper<Scalar>::ShallowCopy& s) : Base(h,s) { }
01153     RowVectorBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::ShallowCopy& s) : Base(h,s) { }
01154     RowVectorBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::DeepCopy& d)    : Base(h,d) { }
01155 
01156     // This gives the resulting rowvector type when (r(i) op P) is applied to each element.
01157     // It will have element types which are the regular composite result of ELT op P.
01158     template <class P> struct EltResult { 
01159         typedef RowVectorBase<typename CNT<ELT>::template Result<P>::Mul> Mul;
01160         typedef RowVectorBase<typename CNT<ELT>::template Result<P>::Dvd> Dvd;
01161         typedef RowVectorBase<typename CNT<ELT>::template Result<P>::Add> Add;
01162         typedef RowVectorBase<typename CNT<ELT>::template Result<P>::Sub> Sub;
01163     };
01164 
01165     RowVectorBase& operator*=(const StdNumber& t)     {Base::operator*=(t); return *this;}
01166     RowVectorBase& operator/=(const StdNumber& t)     {Base::operator/=(t); return *this;}
01167     RowVectorBase& operator+=(const RowVectorBase& r) {Base::operator+=(r); return *this;}
01168     RowVectorBase& operator-=(const RowVectorBase& r) {Base::operator-=(r); return *this;}  
01169 
01170     template <class EE> RowVectorBase& operator=(const RowVectorBase<EE>& b) 
01171       { Base::operator=(b);  return *this; } 
01172     template <class EE> RowVectorBase& operator+=(const RowVectorBase<EE>& b) 
01173       { Base::operator+=(b); return *this; } 
01174     template <class EE> RowVectorBase& operator-=(const RowVectorBase<EE>& b) 
01175       { Base::operator-=(b); return *this; } 
01176 
01177     // default destructor
01178  
01179     // Fill current allocation with copies of element. Note that this is not the 
01180     // same behavior as assignment for Matrices, where only the diagonal is set (and
01181     // everything else is set to zero.)
01182     RowVectorBase& operator=(const ELT& t) { Base::setTo(t); return *this; } 
01183 
01184     // There's only one row here so it's a bit wierd to use colScale rather than
01185     // elementwiseMultiply, but there's nothing really wrong with it. Using rowScale
01186     // would be really wacky since it is the same as a scalar multiply. We won't support
01187     // rowScale here except through inheritance where it will not be much use.
01188 
01189     template <class EE> RowVectorBase& colScaleInPlace(const VectorBase<EE>& v)
01190       { Base::template colScaleInPlace<EE>(v); return *this; }
01191     template <class EE> inline void colScale(const VectorBase<EE>& v, typename EltResult<EE>::Mul& out) const
01192       { return Base::template colScale<EE>(v,out); }
01193     template <class EE> inline typename EltResult<EE>::Mul colScale(const VectorBase<EE>& v) const
01194       { typename EltResult<EE>::Mul out(ncol()); Base::template colScale<EE>(v,out); return out; }
01195 
01196 
01197         // elementwise multiply
01198     template <class EE> RowVectorBase& elementwiseMultiplyInPlace(const RowVectorBase<EE>& r)
01199       { Base::template elementwiseMultiplyInPlace<EE>(r); return *this; }
01200     template <class EE> inline void elementwiseMultiply(const RowVectorBase<EE>& v, typename EltResult<EE>::Mul& out) const
01201       { Base::template elementwiseMultiply<EE>(v,out); }
01202     template <class EE> inline typename EltResult<EE>::Mul elementwiseMultiply(const RowVectorBase<EE>& v) const
01203       { typename EltResult<EE>::Mul out(nrow()); Base::template elementwiseMultiply<EE>(v,out); return out; }
01204 
01205         // elementwise multiply from left
01206     template <class EE> RowVectorBase& elementwiseMultiplyFromLeftInPlace(const RowVectorBase<EE>& r)
01207       { Base::template elementwiseMultiplyFromLeftInPlace<EE>(r); return *this; }
01208     template <class EE> inline void 
01209     elementwiseMultiplyFromLeft(
01210         const RowVectorBase<EE>& v, 
01211         typename RowVectorBase<EE>::template EltResult<ELT>::Mul& out) const
01212     { 
01213         Base::template elementwiseMultiplyFromLeft<EE>(v,out);
01214     }
01215     template <class EE> inline typename RowVectorBase<EE>::template EltResult<ELT>::Mul 
01216     elementwiseMultiplyFromLeft(const RowVectorBase<EE>& v) const
01217     { 
01218         typename RowVectorBase<EE>::template EltResult<ELT>::Mul out(nrow()); 
01219         Base::template elementwiseMultiplyFromLeft<EE>(v,out); 
01220         return out;
01221     }
01222 
01223         // elementwise divide
01224     template <class EE> RowVectorBase& elementwiseDivideInPlace(const RowVectorBase<EE>& r)
01225       { Base::template elementwiseDivideInPlace<EE>(r); return *this; }
01226     template <class EE> inline void elementwiseDivide(const RowVectorBase<EE>& v, typename EltResult<EE>::Dvd& out) const
01227       { Base::template elementwiseDivide<EE>(v,out); }
01228     template <class EE> inline typename EltResult<EE>::Dvd elementwiseDivide(const RowVectorBase<EE>& v) const
01229       { typename EltResult<EE>::Dvd out(nrow()); Base::template elementwiseDivide<EE>(v,out); return out; }
01230 
01231         // elementwise divide from left
01232     template <class EE> RowVectorBase& elementwiseDivideFromLeftInPlace(const RowVectorBase<EE>& r)
01233       { Base::template elementwiseDivideFromLeftInPlace<EE>(r); return *this; }
01234     template <class EE> inline void 
01235     elementwiseDivideFromLeft(
01236         const RowVectorBase<EE>& v, 
01237         typename RowVectorBase<EE>::template EltResult<ELT>::Dvd& out) const
01238     { 
01239         Base::template elementwiseDivideFromLeft<EE>(v,out);
01240     }
01241     template <class EE> inline typename RowVectorBase<EE>::template EltResult<ELT>::Dvd 
01242     elementwiseDivideFromLeft(const RowVectorBase<EE>& v) const
01243     { 
01244         typename RowVectorBase<EE>::template EltResult<ELT>::Dvd out(nrow()); 
01245         Base::template elementwiseDivideFromLeft<EE>(v,out); 
01246         return out;
01247     }
01248 
01249     // Implicit conversions are allowed to RowVector or Matrix, but not to Vector.   
01250     operator const RowVector_<ELT>&()     const {return *reinterpret_cast<const RowVector_<ELT>*>(this);}
01251     operator       RowVector_<ELT>&()           {return *reinterpret_cast<      RowVector_<ELT>*>(this);}
01252     operator const RowVectorView_<ELT>&() const {return *reinterpret_cast<const RowVectorView_<ELT>*>(this);}
01253     operator       RowVectorView_<ELT>&()       {return *reinterpret_cast<      RowVectorView_<ELT>*>(this);}
01254     
01255     operator const Matrix_<ELT>&()     const {return *reinterpret_cast<const Matrix_<ELT>*>(this);}
01256     operator       Matrix_<ELT>&()           {return *reinterpret_cast<      Matrix_<ELT>*>(this);} 
01257     operator const MatrixView_<ELT>&() const {return *reinterpret_cast<const MatrixView_<ELT>*>(this);}
01258     operator       MatrixView_<ELT>&()       {return *reinterpret_cast<      MatrixView_<ELT>*>(this);} 
01259     
01260 
01261     // Override MatrixBase size() for RowVectors to return int instead of long.
01262     int size() const { 
01263         assert(Base::size() <= (long)std::numeric_limits<int>::max()); 
01264         assert(Base::nrow()==1);
01265         return (int)Base::size();
01266     }
01267     int nrow() const { assert(Base::nrow()==1); return Base::nrow(); }
01268     int ncol() const { assert(Base::nrow()==1); return Base::ncol(); }
01269 
01270     // Override MatrixBase operators to return the right shape
01271     TAbs abs() const {
01272         TAbs result; Base::abs(result); return result;
01273     }
01274 
01275     // Override MatrixBase indexing operators          
01276     const ELT& operator[](int j) const {return Base::operator()(0,j);}
01277     ELT&       operator[](int j)       {return Base::operator()(0,j);}
01278     const ELT& operator()(int j) const {return Base::operator()(0,j);}
01279     ELT&       operator()(int j)       {return Base::operator()(0,j);}
01280          
01281     // View creation      
01282     RowVectorView_<ELT> operator()(int j, int n) const {return Base::operator()(0,j,1,n).getAsRowVectorView();}
01283     RowVectorView_<ELT> operator()(int j, int n)       {return Base::operator()(0,j,1,n).updAsRowVectorView();}
01284  
01285     // Hermitian transpose.
01286     THerm transpose() const {return Base::transpose().getAsVectorView();}
01287     THerm updTranspose()    {return Base::updTranspose().updAsVectorView();}
01288 
01289     THerm operator~() const {return transpose();}
01290     THerm operator~()       {return updTranspose();}
01291 
01292     const RowVectorBase& operator+() const {return *this; }
01293 
01294     // Negation
01295 
01296     const TNeg& negate()    const {return *reinterpret_cast<const TNeg*>(this); }
01297     TNeg&       updNegate()       {return *reinterpret_cast<TNeg*>(this); }
01298 
01299     const TNeg& operator-() const {return negate();}
01300     TNeg&       operator-()       {return updNegate();}
01301 
01302     RowVectorBase& resize(int n)     {Base::resize(1,n); return *this;}
01303     RowVectorBase& resizeKeep(int n) {Base::resizeKeep(1,n); return *this;}
01304 
01305     //TODO: this is not re-locking the number of rows at 1.
01306     void clear() {Base::clear(); Base::resize(1,0);}
01307 
01308     ELT sum() const {ELT s; Base::helper.sum(reinterpret_cast<Scalar*>(&s)); return s; } // add all the elements        
01309     VectorIterator<ELT, RowVectorBase<ELT> > begin() {
01310         return VectorIterator<ELT, RowVectorBase<ELT> >(*this, 0);
01311     }
01312     VectorIterator<ELT, RowVectorBase<ELT> > end() {
01313         return VectorIterator<ELT, RowVectorBase<ELT> >(*this, size());
01314     }
01315 private:
01316     // NO DATA MEMBERS ALLOWED
01317 };
01318 
01322 template <class ELT> class TmpMatrixView_ : public MatrixBase<ELT> {
01323     typedef MatrixBase<ELT> Base;
01324     typedef typename MatrixBase<ELT>::Scalar Scalar;
01325 public:
01326     TmpMatrixView_() : Base() { }
01327     TmpMatrixView_(int m, int n) : Base(m,n) { }
01328     explicit TmpMatrixView_(const MatrixHelper<Scalar>& h) : Base(h) { }
01329     
01330     operator const Matrix_<ELT>&() const { return *reinterpret_cast<const Matrix_<ELT>*>(this); }
01331     operator Matrix_<ELT>&()             { return *reinterpret_cast<Matrix_<ELT>*>(this); }
01332     
01333     TmpMatrixView_* clone() const { return new TmpMatrixView_(*this); } 
01334 private:
01335     // NO DATA MEMBERS ALLOWED
01336 };
01337 
01345 template <class ELT> class MatrixView_ : public MatrixBase<ELT> {
01346     typedef MatrixBase<ELT>                 Base;
01347     typedef typename CNT<ELT>::Scalar       S;
01348     typedef typename CNT<ELT>::StdNumber    StdNumber;
01349 public:
01350     // Default construction is suppressed.
01351     // Uses default destructor.
01352 
01353     // Copy constructor is shallow. CAUTION: despite const argument, this preserves writability
01354     // if it was present in the source. This is necessary to allow temporary views to be
01355     // created and used as lvalues.
01356     MatrixView_(const MatrixView_& m) 
01357       : Base(const_cast<MatrixHelper<S>&>(m.helper), typename MatrixHelper<S>::ShallowCopy()) { }
01358 
01359     // Copy assignment is deep but not reallocating.
01360     MatrixView_& operator=(const MatrixView_& m) {
01361         Base::operator=(m); return *this;
01362     }
01363 
01364     // Ask for shallow copy    
01365     MatrixView_(const MatrixHelper<S>& h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
01366     MatrixView_(MatrixHelper<S>&       h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
01367 
01368     MatrixView_& operator=(const Matrix_<ELT>& v)     { Base::operator=(v); return *this; }
01369     MatrixView_& operator=(const ELT& e)              { Base::operator=(e); return *this; }
01370 
01371     template <class EE> MatrixView_& operator=(const MatrixBase<EE>& m)
01372       { Base::operator=(m); return *this; }
01373     template <class EE> MatrixView_& operator+=(const MatrixBase<EE>& m)
01374       { Base::operator+=(m); return *this; }
01375     template <class EE> MatrixView_& operator-=(const MatrixBase<EE>& m)
01376       { Base::operator-=(m); return *this; }
01377 
01378     MatrixView_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
01379     MatrixView_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
01380     MatrixView_& operator+=(const ELT& r)       { this->updDiag() += r; return *this; }
01381     MatrixView_& operator-=(const ELT& r)       { this->updDiag() -= r; return *this; }  
01382 
01383     operator const Matrix_<ELT>&() const { return *reinterpret_cast<const Matrix_<ELT>*>(this); }
01384     operator Matrix_<ELT>&()             { return *reinterpret_cast<Matrix_<ELT>*>(this); }      
01385 
01386 private:
01387     // NO DATA MEMBERS ALLOWED
01388     MatrixView_(); // default constructor suppressed (what's it a view of?)
01389 };
01390 
01391 template <class ELT> inline MatrixView_<ELT> 
01392 MatrixBase<ELT>::block(int i, int j, int m, int n) const { 
01393     SimTK_INDEXCHECK(0,i,nrow()+1,"MatrixBase::block()");
01394     SimTK_INDEXCHECK(0,j,ncol()+1,"MatrixBase::block()");
01395     SimTK_SIZECHECK(i+m,nrow(),"MatrixBase::block()");
01396     SimTK_SIZECHECK(j+n,ncol(),"MatrixBase::block()");
01397 
01398     MatrixHelper<Scalar> h(helper,i,j,m,n);    
01399     return MatrixView_<ELT>(h); 
01400 }
01401     
01402 template <class ELT> inline MatrixView_<ELT>
01403 MatrixBase<ELT>::updBlock(int i, int j, int m, int n) { 
01404     SimTK_INDEXCHECK(0,i,nrow()+1,"MatrixBase::updBlock()");
01405     SimTK_INDEXCHECK(0,j,ncol()+1,"MatrixBase::updBlock()");
01406     SimTK_SIZECHECK(i+m,nrow(),"MatrixBase::updBlock()");
01407     SimTK_SIZECHECK(j+n,ncol(),"MatrixBase::updBlock()");
01408 
01409     MatrixHelper<Scalar> h(helper,i,j,m,n);        
01410     return MatrixView_<ELT>(h); 
01411 }
01412 
01413 template <class E> inline MatrixView_<typename CNT<E>::THerm>
01414 MatrixBase<E>::transpose() const { 
01415     MatrixHelper<typename CNT<Scalar>::THerm> 
01416         h(helper, typename MatrixHelper<typename CNT<Scalar>::THerm>::TransposeView());
01417     return MatrixView_<typename CNT<E>::THerm>(h); 
01418 }
01419     
01420 template <class E> inline MatrixView_<typename CNT<E>::THerm>
01421 MatrixBase<E>::updTranspose() {     
01422     MatrixHelper<typename CNT<Scalar>::THerm> 
01423         h(helper, typename MatrixHelper<typename CNT<Scalar>::THerm>::TransposeView());
01424     return MatrixView_<typename CNT<E>::THerm>(h); 
01425 }
01426 
01427 template <class E> inline VectorView_<E>
01428 MatrixBase<E>::diag() const { 
01429     MatrixHelper<Scalar> h(helper, typename MatrixHelper<Scalar>::DiagonalView());
01430     return VectorView_<E>(h); 
01431 }
01432     
01433 template <class E> inline VectorView_<E>
01434 MatrixBase<E>::updDiag() {     
01435     MatrixHelper<Scalar> h(helper, typename MatrixHelper<Scalar>::DiagonalView());
01436     return VectorView_<E>(h);
01437 }
01438 
01439 template <class ELT> inline VectorView_<ELT> 
01440 MatrixBase<ELT>::col(int j) const { 
01441     SimTK_INDEXCHECK(0,j,ncol(),"MatrixBase::col()");
01442 
01443     MatrixHelper<Scalar> h(helper,0,j,nrow(),1);    
01444     return VectorView_<ELT>(h); 
01445 }
01446     
01447 template <class ELT> inline VectorView_<ELT>
01448 MatrixBase<ELT>::updCol(int j) {
01449     SimTK_INDEXCHECK(0,j,ncol(),"MatrixBase::updCol()");
01450 
01451     MatrixHelper<Scalar> h(helper,0,j,nrow(),1);        
01452     return VectorView_<ELT>(h); 
01453 }
01454 
01455 template <class ELT> inline RowVectorView_<ELT> 
01456 MatrixBase<ELT>::row(int i) const { 
01457     SimTK_INDEXCHECK(0,i,nrow(),"MatrixBase::row()");
01458 
01459     MatrixHelper<Scalar> h(helper,i,0,1,ncol());    
01460     return RowVectorView_<ELT>(h); 
01461 }
01462     
01463 template <class ELT> inline RowVectorView_<ELT>
01464 MatrixBase<ELT>::updRow(int i) { 
01465     SimTK_INDEXCHECK(0,i,nrow(),"MatrixBase::updRow()");
01466 
01467     MatrixHelper<Scalar> h(helper,i,0,1,ncol());        
01468     return RowVectorView_<ELT>(h); 
01469 }
01470 
01471 // M = diag(v) * M; v must have nrow() elements.
01472 // That is, M[i] *= v[i].
01473 template <class ELT> template <class EE> inline MatrixBase<ELT>& 
01474 MatrixBase<ELT>::rowScaleInPlace(const VectorBase<EE>& v) {
01475     assert(v.nrow() == nrow());
01476     for (int i=0; i < nrow(); ++i)
01477         (*this)[i] *= v[i];
01478     return *this;
01479 }
01480 
01481 template <class ELT> template <class EE> inline void
01482 MatrixBase<ELT>::rowScale(const VectorBase<EE>& v, typename MatrixBase<ELT>::template EltResult<EE>::Mul& out) const {
01483     assert(v.nrow() == nrow());
01484     out.resize(nrow(), ncol());
01485     for (int j=0; j<ncol(); ++j)
01486         for (int i=0; i<nrow(); ++i)
01487            out(i,j) = (*this)(i,j) * v[i];
01488 }
01489 
01490 // M = M * diag(v); v must have ncol() elements
01491 // That is, M(i) *= v[i]
01492 template <class ELT> template <class EE>  inline MatrixBase<ELT>& 
01493 MatrixBase<ELT>::colScaleInPlace(const VectorBase<EE>& v) {
01494     assert(v.nrow() == ncol());
01495     for (int j=0; j < ncol(); ++j)
01496         (*this)(j) *= v[j];
01497     return *this;
01498 }
01499 
01500 template <class ELT> template <class EE> inline void
01501 MatrixBase<ELT>::colScale(const VectorBase<EE>& v, typename MatrixBase<ELT>::template EltResult<EE>::Mul& out) const {
01502     assert(v.nrow() == ncol());
01503     out.resize(nrow(), ncol());
01504     for (int j=0; j<ncol(); ++j)
01505         for (int i=0; i<nrow(); ++i)
01506            out(i,j) = (*this)(i,j) * v[j];
01507 }
01508 
01509 
01510 // M(i,j) *= r[i]*c[j]; r must have nrow() elements; c must have ncol() elements
01511 template <class ELT> template <class ER, class EC> inline MatrixBase<ELT>& 
01512 MatrixBase<ELT>::rowAndColScaleInPlace(const VectorBase<ER>& r, const VectorBase<EC>& c) {
01513     assert(r.nrow()==nrow() && c.nrow()==ncol());
01514     for (int j=0; j<ncol(); ++j)
01515         for (int i=0; i<nrow(); ++i)
01516             (*this)(i,j) *= (r[i]*c[j]);
01517     return *this;
01518 }
01519 
01520 template <class ELT> template <class ER, class EC> inline void
01521 MatrixBase<ELT>::rowAndColScale(
01522     const VectorBase<ER>& r, 
01523     const VectorBase<EC>& c,
01524     typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul& 
01525                           out) const
01526 {
01527     assert(r.nrow()==nrow() && c.nrow()==ncol());
01528     out.resize(nrow(), ncol());
01529     for (int j=0; j<ncol(); ++j)
01530         for (int i=0; i<nrow(); ++i)
01531             out(i,j) = (*this)(i,j) * (r[i]*c[j]);
01532 }
01533 
01534 
01535 // Set M(i,j) = M(i,j)^-1.
01536 template <class ELT> inline MatrixBase<ELT>& 
01537 MatrixBase<ELT>::elementwiseInvertInPlace() {
01538     const int nr=nrow(), nc=ncol();
01539     for (int j=0; j<nc; ++j)
01540         for (int i=0; i<nr; ++i) {
01541             ELT& e = updElt(i,j);
01542             e = CNT<ELT>::invert(e);
01543         }
01544     return *this;
01545 }
01546 
01547 template <class ELT> inline void
01548 MatrixBase<ELT>::elementwiseInvert(MatrixBase<typename CNT<E>::TInvert>& out) const {
01549     const int nr=nrow(), nc=ncol();
01550     out.resize(nr,nc);
01551     for (int j=0; j<nc; ++j)
01552         for (int i=0; i<nr; ++i)
01553             out(i,j) = CNT<ELT>::invert((*this)(i,j));
01554 }
01555 
01556 // M(i,j) += s
01557 template <class ELT> template <class S> inline MatrixBase<ELT>& 
01558 MatrixBase<ELT>::elementwiseAddScalarInPlace(const S& s) {
01559     for (int j=0; j<ncol(); ++j)
01560         for (int i=0; i<nrow(); ++i)
01561             (*this)(i,j) += s;
01562     return *this;
01563 }
01564 
01565 template <class ELT> template <class S> inline void 
01566 MatrixBase<ELT>::elementwiseAddScalar(
01567     const S& s,
01568     typename MatrixBase<ELT>::template EltResult<S>::Add& out) const
01569 {
01570     const int nr=nrow(), nc=ncol();
01571     out.resize(nr,nc);
01572     for (int j=0; j<nc; ++j)
01573         for (int i=0; i<nr; ++i)
01574             out(i,j) = (*this)(i,j) + s;
01575 }
01576 
01577 // M(i,j) -= s
01578 template <class ELT> template <class S> inline MatrixBase<ELT>& 
01579 MatrixBase<ELT>::elementwiseSubtractScalarInPlace(const S& s) {
01580     for (int j=0; j<ncol(); ++j)
01581         for (int i=0; i<nrow(); ++i)
01582             (*this)(i,j) -= s;
01583     return *this;
01584 }
01585 
01586 template <class ELT> template <class S> inline void 
01587 MatrixBase<ELT>::elementwiseSubtractScalar(
01588     const S& s,
01589     typename MatrixBase<ELT>::template EltResult<S>::Sub& out) const
01590 {
01591     const int nr=nrow(), nc=ncol();
01592     out.resize(nr,nc);
01593     for (int j=0; j<nc; ++j)
01594         for (int i=0; i<nr; ++i)
01595             out(i,j) = (*this)(i,j) - s;
01596 }
01597 
01598 // M(i,j) = s - M(i,j)
01599 template <class ELT> template <class S> inline MatrixBase<ELT>& 
01600 MatrixBase<ELT>::elementwiseSubtractFromScalarInPlace(const S& s) {
01601     const int nr=nrow(), nc=ncol();
01602     for (int j=0; j<nc; ++j)
01603         for (int i=0; i<nr; ++i) {
01604             ELT& e = updElt(i,j);
01605             e = s - e;
01606         }
01607     return *this;
01608 }
01609 
01610 template <class ELT> template <class S> inline void 
01611 MatrixBase<ELT>::elementwiseSubtractFromScalar(
01612     const S& s,
01613     typename MatrixBase<S>::template EltResult<ELT>::Sub& out) const
01614 {
01615     const int nr=nrow(), nc=ncol();
01616     out.resize(nr,nc);
01617     for (int j=0; j<nc; ++j)
01618         for (int i=0; i<nr; ++i)
01619             out(i,j) = s - (*this)(i,j);
01620 }
01621 
01622 // M(i,j) *= R(i,j); R must have same dimensions as this
01623 template <class ELT> template <class EE> inline MatrixBase<ELT>& 
01624 MatrixBase<ELT>::elementwiseMultiplyInPlace(const MatrixBase<EE>& r) {
01625     const int nr=nrow(), nc=ncol();
01626     assert(r.nrow()==nr && r.ncol()==nc);
01627     for (int j=0; j<nc; ++j)
01628         for (int i=0; i<nr; ++i)
01629             (*this)(i,j) *= r(i,j);
01630     return *this;
01631 }
01632 
01633 template <class ELT> template <class EE> inline void 
01634 MatrixBase<ELT>::elementwiseMultiply(
01635     const MatrixBase<EE>& r, 
01636     typename MatrixBase<ELT>::template EltResult<EE>::Mul& out) const
01637 {
01638     const int nr=nrow(), nc=ncol();
01639     assert(r.nrow()==nr && r.ncol()==nc);
01640     out.resize(nr,nc);
01641     for (int j=0; j<nc; ++j)
01642         for (int i=0; i<nr; ++i)
01643             out(i,j) = (*this)(i,j) * r(i,j);
01644 }
01645 
01646 // M(i,j) = R(i,j) * M(i,j); R must have same dimensions as this
01647 template <class ELT> template <class EE> inline MatrixBase<ELT>& 
01648 MatrixBase<ELT>::elementwiseMultiplyFromLeftInPlace(const MatrixBase<EE>& r) {
01649     const int nr=nrow(), nc=ncol();
01650     assert(r.nrow()==nr && r.ncol()==nc);
01651     for (int j=0; j<nc; ++j)
01652         for (int i=0; i<nr; ++i) {
01653             ELT& e = updElt(i,j);
01654             e = r(i,j) * e;
01655         }
01656     return *this;
01657 }
01658 
01659 template <class ELT> template <class EE> inline void 
01660 MatrixBase<ELT>::elementwiseMultiplyFromLeft(
01661     const MatrixBase<EE>& r, 
01662     typename MatrixBase<EE>::template EltResult<ELT>::Mul& out) const
01663 {
01664     const int nr=nrow(), nc=ncol();
01665     assert(r.nrow()==nr && r.ncol()==nc);
01666     out.resize(nr,nc);
01667     for (int j=0; j<nc; ++j)
01668         for (int i=0; i<nr; ++i)
01669             out(i,j) =  r(i,j) * (*this)(i,j);
01670 }
01671 
01672 // M(i,j) /= R(i,j); R must have same dimensions as this
01673 template <class ELT> template <class EE> inline MatrixBase<ELT>& 
01674 MatrixBase<ELT>::elementwiseDivideInPlace(const MatrixBase<EE>& r) {
01675     const int nr=nrow(), nc=ncol();
01676     assert(r.nrow()==nr && r.ncol()==nc);
01677     for (int j=0; j<nc; ++j)
01678         for (int i=0; i<nr; ++i)
01679             (*this)(i,j) /= r(i,j);
01680     return *this;
01681 }
01682 
01683 template <class ELT> template <class EE> inline void 
01684 MatrixBase<ELT>::elementwiseDivide(
01685     const MatrixBase<EE>& r,
01686     typename MatrixBase<ELT>::template EltResult<EE>::Dvd& out) const
01687 {
01688     const int nr=nrow(), nc=ncol();
01689     assert(r.nrow()==nr && r.ncol()==nc);
01690     out.resize(nr,nc);
01691     for (int j=0; j<nc; ++j)
01692         for (int i=0; i<nr; ++i)
01693             out(i,j) = (*this)(i,j) / r(i,j);
01694 }
01695 // M(i,j) = R(i,j) / M(i,j); R must have same dimensions as this
01696 template <class ELT> template <class EE> inline MatrixBase<ELT>& 
01697 MatrixBase<ELT>::elementwiseDivideFromLeftInPlace(const MatrixBase<EE>& r) {
01698     const int nr=nrow(), nc=ncol();
01699     assert(r.nrow()==nr && r.ncol()==nc);
01700     for (int j=0; j<nc; ++j)
01701         for (int i=0; i<nr; ++i) {
01702             ELT& e = updElt(i,j);
01703             e = r(i,j) / e;
01704         }
01705     return *this;
01706 }
01707 
01708 template <class ELT> template <class EE> inline void 
01709 MatrixBase<ELT>::elementwiseDivideFromLeft(
01710     const MatrixBase<EE>& r,
01711     typename MatrixBase<EE>::template EltResult<ELT>::Dvd& out) const
01712 {
01713     const int nr=nrow(), nc=ncol();
01714     assert(r.nrow()==nr && r.ncol()==nc);
01715     out.resize(nr,nc);
01716     for (int j=0; j<nc; ++j)
01717         for (int i=0; i<nr; ++i)
01718             out(i,j) = r(i,j) / (*this)(i,j);
01719 }
01720 
01721 /*
01722 template <class ELT> inline MatrixView_< typename CNT<ELT>::TReal > 
01723 MatrixBase<ELT>::real() const { 
01724     if (!CNT<ELT>::IsComplex) { // known at compile time
01725         return MatrixView_< typename CNT<ELT>::TReal >( // this is just ELT
01726             MatrixHelper(helper,0,0,nrow(),ncol()));    // a view of the whole matrix
01727     }
01728     // Elements are complex -- helper uses underlying precision (real) type.
01729     MatrixHelper<Precision> h(helper,typename MatrixHelper<Precision>::RealView);    
01730     return MatrixView_< typename CNT<ELT>::TReal >(h); 
01731 }
01732 */
01733 
01734 
01739 template <class ELT> class Matrix_ : public MatrixBase<ELT> {
01740     typedef MatrixBase<ELT> Base;
01741     typedef typename CNT<ELT>::Scalar            S;
01742     typedef typename CNT<ELT>::Number            Number;
01743     typedef typename CNT<ELT>::StdNumber         StdNumber;
01744 
01745     typedef Matrix_<ELT>                         T;
01746     typedef MatrixView_<ELT>                     TView;
01747     typedef Matrix_< typename CNT<ELT>::TNeg >   TNeg;
01748 
01749 public:
01750     Matrix_() : Base() { }
01751 
01752     // Copy constructor is deep.
01753     Matrix_(const Matrix_& src) : Base(src) { }
01754 
01755     // Assignment is a deep copy and will also allow reallocation if this Matrix
01756     // doesn't have a view.
01757     Matrix_& operator=(const Matrix_& src) { 
01758         Base::operator=(src); return *this;
01759     }
01760 
01761     // Force a deep copy of the view or whatever this is.    
01762     /*explicit*/ Matrix_(const Base& v) : Base(v) { }   // e.g., MatrixView
01763 
01764     Matrix_(int m, int n) : Base(m,n) { }
01765     Matrix_(int m, int n, const ELT* initValsByRow) : Base(m,n,initValsByRow) { }
01766     Matrix_(int m, int n, const ELT& ival) : Base(m,n,ival) { }
01767     
01768     Matrix_(int m, int n, int leadingDim, const S* s): Base(m,n,leadingDim,s) { }
01769     Matrix_(int m, int n, int leadingDim,       S* s): Base(m,n,leadingDim,s) { }
01770     
01772     template <int M, int N>
01773     explicit Matrix_(const Mat<M,N,ELT>& mat) : Base(M, N) {
01774         for (int i = 0; i < M; ++i)
01775             for (int j = 0; j < N; ++j)
01776                 this->updElt(i, j) = mat(i, j);
01777     }
01778 
01779     Matrix_& operator=(const ELT& v) { Base::operator=(v); return *this; }
01780 
01781     template <class EE> Matrix_& operator=(const MatrixBase<EE>& m)
01782       { Base::operator=(m); return*this; }
01783     template <class EE> Matrix_& operator+=(const MatrixBase<EE>& m)
01784       { Base::operator+=(m); return*this; }
01785     template <class EE> Matrix_& operator-=(const MatrixBase<EE>& m)
01786       { Base::operator-=(m); return*this; }
01787 
01788     Matrix_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
01789     Matrix_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
01790     Matrix_& operator+=(const ELT& r)       { this->updDiag() += r; return *this; }
01791     Matrix_& operator-=(const ELT& r)       { this->updDiag() -= r; return *this; }  
01792 
01793     const TNeg& negate()    const {return *reinterpret_cast<const TNeg*>(this); }
01794     TNeg&       updNegate()       {return *reinterpret_cast<TNeg*>(this); }
01795 
01796     const TNeg& operator-() const {return negate();}
01797     TNeg&       operator-()       {return updNegate();}
01798    
01799 private:
01800     // NO DATA MEMBERS ALLOWED
01801 };
01802 
01803 template <class ELT> class VectorView_ : public VectorBase<ELT> {
01804     typedef VectorBase<ELT>                             Base;
01805     typedef typename CNT<ELT>::Scalar                   S;
01806     typedef typename CNT<ELT>::Number                   Number;
01807     typedef typename CNT<ELT>::StdNumber                StdNumber;
01808     typedef VectorView_<ELT>                            T;
01809     typedef VectorView_< typename CNT<ELT>::TNeg >      TNeg;
01810     typedef RowVectorView_< typename CNT<ELT>::THerm >  THerm;
01811 public:
01812     // Default construction is suppressed.
01813     // Uses default destructor.
01814 
01815     // Copy constructor is shallow. CAUTION: despite const argument, this preserves writability
01816     // if it was present in the source. This is necessary to allow temporary views to be
01817     // created and used as lvalues.
01818     VectorView_(const VectorView_& v) 
01819       : Base(const_cast<MatrixHelper<S>&>(v.helper), typename MatrixHelper<S>::ShallowCopy()) { }
01820 
01821     // Copy assignment is deep but not reallocating.
01822     VectorView_& operator=(const VectorView_& v) {
01823         Base::operator=(v); return *this;
01824     }
01825 
01826     // Ask for shallow copy    
01827     explicit VectorView_(const MatrixHelper<S>& h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
01828     explicit VectorView_(MatrixHelper<S>&       h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
01829     
01830     VectorView_& operator=(const Base& b) { Base::operator=(b); return *this; }
01831 
01832     VectorView_& operator=(const ELT& v) { Base::operator=(v); return *this; } 
01833 
01834     template <class EE> VectorView_& operator=(const VectorBase<EE>& m)
01835       { Base::operator=(m); return*this; }
01836     template <class EE> VectorView_& operator+=(const VectorBase<EE>& m)
01837       { Base::operator+=(m); return*this; }
01838     template <class EE> VectorView_& operator-=(const VectorBase<EE>& m)
01839       { Base::operator-=(m); return*this; }
01840 
01841     VectorView_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
01842     VectorView_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
01843     VectorView_& operator+=(const ELT& b) { elementwiseAddScalarInPlace(b); return *this; } 
01844     VectorView_& operator-=(const ELT& b) { elementwiseSubtractScalarInPlace(b); return *this; } 
01845 
01846 private:
01847     // NO DATA MEMBERS ALLOWED
01848     VectorView_(); // default construction suppressed (what's it a View of?)
01849 };
01850 
01854 template <class ELT> class TmpVectorViewT : public VectorBase<ELT> {
01855     typedef VectorBase<ELT>             Base;
01856     typedef typename CNT<ELT>::Scalar   S;
01857 public:
01858     TmpVectorViewT() : Base() { }
01859     explicit TmpVectorViewT(int m) : Base(m,1,false) { }
01860     explicit TmpVectorViewT(const MatrixHelper<S>& h) : Base(h) { }
01861     
01862     operator const Vector_<ELT>&() const { return *reinterpret_cast<const Vector_<ELT>*>(this); }
01863     operator Vector_<ELT>&()             { return *reinterpret_cast<Vector_<ELT>*>(this); }
01864     
01865     TmpVectorViewT* clone() const { return new TmpVectorViewT(*this); } 
01866 private:
01867     // NO DATA MEMBERS ALLOWED
01868 };
01869 
01870 template <class ELT> class Vector_ : public VectorBase<ELT> {
01871     typedef VectorBase<ELT>                 Base;
01872     typedef typename CNT<ELT>::Scalar       S;
01873     typedef typename CNT<ELT>::Number       Number;
01874     typedef typename CNT<ELT>::StdNumber    StdNumber;
01875 public:
01876     Vector_() : Base() { }  // 0x1 reallocatable
01877     // Uses default destructor.
01878 
01879     // Copy constructor is deep.
01880     Vector_(const Vector_& src) : Base(src) { }
01881 
01882     // Copy assignment is deep and can be reallocating if this Vector
01883     // has no View.
01884     Vector_& operator=(const Vector_& src) {
01885         Base::operator=(src); return*this;
01886     }
01887 
01888     explicit Vector_(const Base& src) : Base(src) { }    // e.g., VectorView
01889 
01890     explicit Vector_(int m) : Base(m,false) { }
01891     Vector_(int m, const ELT* initVals) : Base(m,false,initVals) { }
01892     Vector_(int m, const ELT& ival) : Base(m,false,ival) { }
01893 
01894     // Construct a Vector which uses borrowed space.
01895     // Last parameter is a dummy to avoid overload conflicts when ELT=S.    
01896     Vector_(int m, const S* s, bool): Base(m,m,s) { }
01897     Vector_(int m,       S* s, bool): Base(m,m,s) { }
01898     
01900     template <int M>
01901     explicit Vector_(const Vec<M,ELT>& v) : Base(M) {
01902         for (int i = 0; i < M; ++i)
01903             this->updElt(i, 0) = v(i);
01904     }
01905 
01906     Vector_& operator=(const ELT& v) { Base::operator=(v); return *this; } 
01907 
01908     template <class EE> Vector_& operator=(const VectorBase<EE>& m)
01909       { Base::operator=(m); return*this; }
01910     template <class EE> Vector_& operator+=(const VectorBase<EE>& m)
01911       { Base::operator+=(m); return*this; }
01912     template <class EE> Vector_& operator-=(const VectorBase<EE>& m)
01913       { Base::operator-=(m); return*this; }
01914 
01915     Vector_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
01916     Vector_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
01917     Vector_& operator+=(const ELT& b) { elementwiseAddScalarInPlace(b); return *this; } 
01918     Vector_& operator-=(const ELT& b) { elementwiseSubtractScalarInPlace(b); return *this; } 
01919  
01920 private:
01921     // NO DATA MEMBERS ALLOWED
01922 };
01923 
01924 
01925 template <class ELT> class RowVectorView_ : public RowVectorBase<ELT> {
01926     typedef RowVectorBase<ELT>                              Base;
01927     typedef typename CNT<ELT>::Scalar                       S;
01928     typedef typename CNT<ELT>::Number                       Number;
01929     typedef typename CNT<ELT>::StdNumber                    StdNumber;
01930     typedef RowVectorView_<ELT>                             T;
01931     typedef RowVectorView_< typename CNT<ELT>::TNeg >       TNeg;
01932     typedef VectorView_< typename CNT<ELT>::THerm >         THerm;
01933 public:
01934     // Default construction is suppressed.
01935     // Uses default destructor.
01936 
01937     // Copy constructor is shallow. CAUTION: despite const argument, this preserves writability
01938     // if it was present in the source. This is necessary to allow temporary views to be
01939     // created and used as lvalues.
01940     RowVectorView_(const RowVectorView_& r) 
01941       : Base(const_cast<MatrixHelper<S>&>(r.helper), typename MatrixHelper<S>::ShallowCopy()) { }
01942 
01943     // Copy assignment is deep but not reallocating.
01944     RowVectorView_& operator=(const RowVectorView_& r) {
01945         Base::operator=(r); return *this;
01946     }
01947 
01948     // Ask for shallow copy    
01949     explicit RowVectorView_(const MatrixHelper<S>& h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
01950     explicit RowVectorView_(MatrixHelper<S>&       h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
01951     
01952     RowVectorView_& operator=(const Base& b) { Base::operator=(b); return *this; }
01953 
01954     RowVectorView_& operator=(const ELT& v) { Base::operator=(v); return *this; } 
01955 
01956     template <class EE> RowVectorView_& operator=(const RowVectorBase<EE>& m)
01957       { Base::operator=(m); return*this; }
01958     template <class EE> RowVectorView_& operator+=(const RowVectorBase<EE>& m)
01959       { Base::operator+=(m); return*this; }
01960     template <class EE> RowVectorView_& operator-=(const RowVectorBase<EE>& m)
01961       { Base::operator-=(m); return*this; }
01962 
01963     RowVectorView_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
01964     RowVectorView_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
01965     RowVectorView_& operator+=(const ELT& b) { elementwiseAddScalarInPlace(b); return *this; } 
01966     RowVectorView_& operator-=(const ELT& b) { elementwiseSubtractScalarInPlace(b); return *this; } 
01967 
01968 private:
01969     // NO DATA MEMBERS ALLOWED
01970     RowVectorView_(); // default construction suppressed (what is it a view of?)
01971 };
01972 
01976 template <class ELT> class TmpRowVectorView_ : public RowVectorBase<ELT> {
01977     typedef RowVectorBase<ELT>          Base;
01978     typedef typename CNT<ELT>::Scalar   S;
01979 public:
01980     TmpRowVectorView_() : Base() { }
01981     TmpRowVectorView_(int n) : Base(n,false) { }
01982     TmpRowVectorView_(const MatrixHelper<S>& h) : Base(h) { }
01983     
01984     operator const RowVector_<ELT>&() const { return *reinterpret_cast<const RowVector_<ELT>*>(this); }
01985     operator RowVector_<ELT>&()             { return *reinterpret_cast<RowVector_<ELT>*>(this); }
01986     
01987     TmpRowVectorView_* clone() const { return new TmpRowVectorView_(*this); } 
01988 private:
01989     // NO DATA MEMBERS ALLOWED
01990 };
01991 
01992 
01993 template <class ELT> class RowVector_ : public RowVectorBase<ELT> {
01994     typedef RowVectorBase<ELT>              Base;
01995     typedef typename CNT<ELT>::Scalar       S;
01996     typedef typename CNT<ELT>::Number       Number;
01997     typedef typename CNT<ELT>::StdNumber    StdNumber;
01998 public:
01999     RowVector_() : Base() { }   // 1x0 reallocatable
02000     // Uses default destructor.
02001 
02002     // Copy constructor is deep.
02003     RowVector_(const RowVector_& src) : Base(src) { }
02004 
02005     // Copy assignment is deep and can be reallocating if this RowVector
02006     // has no View.
02007     RowVector_& operator=(const RowVector_& src) {
02008         Base::operator=(src); return*this;
02009     }
02010 
02011     explicit RowVector_(const Base& src) : Base(src) { }    // e.g., RowVectorView
02012 
02013     explicit RowVector_(int n) : Base(n,false) { }
02014     RowVector_(int n, const ELT* initVals) : Base(n,false,initVals) { }
02015     RowVector_(int n, const ELT& ival)     : Base(n,false,ival) { }
02016 
02017     // Construct a RowVector which uses borrowed space.
02018     // Last parameter is a dummy to avoid overload conflicts when ELT=S.    
02019     RowVector_(int n, const S* s, bool): Base(n,1,s) { }
02020     RowVector_(int n,       S* s, bool): Base(n,1,s) { }
02021     
02023     template <int M>
02024     explicit RowVector_(const Row<M,ELT>& v) : Base(M) {
02025         for (int i = 0; i < M; ++i)
02026             this->updElt(0, i) = v(i);
02027     }
02028 
02029     RowVector_& operator=(const ELT& v) { Base::operator=(v); return *this; } 
02030 
02031     template <class EE> RowVector_& operator=(const RowVectorBase<EE>& b)
02032       { Base::operator=(b); return*this; }
02033     template <class EE> RowVector_& operator+=(const RowVectorBase<EE>& b)
02034       { Base::operator+=(b); return*this; }
02035     template <class EE> RowVector_& operator-=(const RowVectorBase<EE>& b)
02036       { Base::operator-=(b); return*this; }
02037 
02038     RowVector_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
02039     RowVector_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
02040     RowVector_& operator+=(const ELT& b) { elementwiseAddScalarInPlace(b); return *this; } 
02041     RowVector_& operator-=(const ELT& b) { elementwiseSubtractScalarInPlace(b); return *this; } 
02042 
02043 private:
02044     // NO DATA MEMBERS ALLOWED
02045 };
02046 
02047     // GLOBAL OPERATORS: Matrix_
02048 
02049 // + and - allow mixed element types, but will fail to compile if the elements aren't
02050 // compatible. At run time these will fail if the dimensions are incompatible.
02051 template <class E1, class E2>
02052 Matrix_<typename CNT<E1>::template Result<E2>::Add>
02053 operator+(const MatrixBase<E1>& l, const MatrixBase<E2>& r) {
02054     return Matrix_<typename CNT<E1>::template Result<E2>::Add>(l) += r;
02055 }
02056 
02057 template <class E>
02058 Matrix_<E> operator+(const MatrixBase<E>& l, const typename CNT<E>::T& r) {
02059     return Matrix_<E>(l) += r;
02060 }
02061 
02062 template <class E>
02063 Matrix_<E> operator+(const typename CNT<E>::T& l, const MatrixBase<E>& r) {
02064     return Matrix_<E>(r) += l;
02065 }
02066 
02067 template <class E1, class E2>
02068 Matrix_<typename CNT<E1>::template Result<E2>::Sub>
02069 operator-(const MatrixBase<E1>& l, const MatrixBase<E2>& r) {
02070     return Matrix_<typename CNT<E1>::template Result<E2>::Sub>(l) -= r;
02071 }
02072 
02073 template <class E>
02074 Matrix_<E> operator-(const MatrixBase<E>& l, const typename CNT<E>::T& r) {
02075     return Matrix_<E>(l) -= r;
02076 }
02077 
02078 template <class E>
02079 Matrix_<E> operator-(const typename CNT<E>::T& l, const MatrixBase<E>& r) {
02080     Matrix_<E> temp(r.nrow(), r.ncol());
02081     temp = l;
02082     return (temp -= r);
02083 }
02084 
02085 // Scalar multiply and divide. You might wish the scalar could be
02086 // a templatized type "E2", but that would create horrible ambiguities since
02087 // E2 would match not only scalar types but everything else including
02088 // matrices.
02089 template <class E> Matrix_<E>
02090 operator*(const MatrixBase<E>& l, const typename CNT<E>::StdNumber& r) 
02091   { return Matrix_<E>(l)*=r; }
02092 
02093 template <class E> Matrix_<E>
02094 operator*(const typename CNT<E>::StdNumber& l, const MatrixBase<E>& r) 
02095   { return Matrix_<E>(r)*=l; }
02096 
02097 template <class E> Matrix_<E>
02098 operator/(const MatrixBase<E>& l, const typename CNT<E>::StdNumber& r) 
02099   { return Matrix_<E>(l)/=r; }
02100 
02101     // GLOBAL OPERATORS: Vector_
02102 
02103 template <class E1, class E2>
02104 Vector_<typename CNT<E1>::template Result<E2>::Add>
02105 operator+(const VectorBase<E1>& l, const VectorBase<E2>& r) {
02106     return Vector_<typename CNT<E1>::template Result<E2>::Add>(l) += r;
02107 }
02108 template <class E>
02109 Vector_<E> operator+(const VectorBase<E>& l, const typename CNT<E>::T& r) {
02110     return Vector_<E>(l) += r;
02111 }
02112 template <class E>
02113 Vector_<E> operator+(const typename CNT<E>::T& l, const VectorBase<E>& r) {
02114     return Vector_<E>(r) += l;
02115 }
02116 template <class E1, class E2>
02117 Vector_<typename CNT<E1>::template Result<E2>::Sub>
02118 operator-(const VectorBase<E1>& l, const VectorBase<E2>& r) {
02119     return Vector_<typename CNT<E1>::template Result<E2>::Sub>(l) -= r;
02120 }
02121 template <class E>
02122 Vector_<E> operator-(const VectorBase<E>& l, const typename CNT<E>::T& r) {
02123     return Vector_<E>(l) -= r;
02124 }
02125 template <class E>
02126 Vector_<E> operator-(const typename CNT<E>::T& l, const VectorBase<E>& r) {
02127     Vector_<E> temp(r.size());
02128     temp = l;
02129     return (temp -= r);
02130 }
02131 
02132 template <class E> Vector_<E>
02133 operator*(const VectorBase<E>& l, const typename CNT<E>::StdNumber& r) 
02134   { return Vector_<E>(l)*=r; }
02135 
02136 template <class E> Vector_<E>
02137 operator*(const typename CNT<E>::StdNumber& l, const VectorBase<E>& r) 
02138   { return Vector_<E>(r)*=l; }
02139 
02140 template <class E> Vector_<E>
02141 operator/(const VectorBase<E>& l, const typename CNT<E>::StdNumber& r) 
02142   { return Vector_<E>(l)/=r; }
02143 
02144     // GLOBAL OPERATORS: RowVector_
02145 
02146 template <class E1, class E2>
02147 RowVector_<typename CNT<E1>::template Result<E2>::Add>
02148 operator+(const RowVectorBase<E1>& l, const RowVectorBase<E2>& r) {
02149     return RowVector_<typename CNT<E1>::template Result<E2>::Add>(l) += r;
02150 }
02151 template <class E>
02152 RowVector_<E> operator+(const RowVectorBase<E>& l, const typename CNT<E>::T& r) {
02153     return RowVector_<E>(l) += r;
02154 }
02155 template <class E>
02156 RowVector_<E> operator+(const typename CNT<E>::T& l, const RowVectorBase<E>& r) {
02157     return RowVector_<E>(r) += l;
02158 }
02159 template <class E1, class E2>
02160 RowVector_<typename CNT<E1>::template Result<E2>::Sub>
02161 operator-(const RowVectorBase<E1>& l, const RowVectorBase<E2>& r) {
02162     return RowVector_<typename CNT<E1>::template Result<E2>::Sub>(l) -= r;
02163 }
02164 template <class E>
02165 RowVector_<E> operator-(const RowVectorBase<E>& l, const typename CNT<E>::T& r) {
02166     return RowVector_<E>(l) -= r;
02167 }
02168 template <class E>
02169 RowVector_<E> operator-(const typename CNT<E>::T& l, const RowVectorBase<E>& r) {
02170     RowVector_<E> temp(r.size());
02171     temp = l;
02172     return (temp -= r);
02173 }
02174 
02175 template <class E> RowVector_<E>
02176 operator*(const RowVectorBase<E>& l, const typename CNT<E>::StdNumber& r) 
02177   { return RowVector_<E>(l)*=r; }
02178 
02179 template <class E> RowVector_<E>
02180 operator*(const typename CNT<E>::StdNumber& l, const RowVectorBase<E>& r) 
02181   { return RowVector_<E>(r)*=l; }
02182 
02183 template <class E> RowVector_<E>
02184 operator/(const RowVectorBase<E>& l, const typename CNT<E>::StdNumber& r) 
02185   { return RowVector_<E>(l)/=r; }
02186 
02187 
02188     // GLOBAL OPERATORS: mixed
02189 
02190     // TODO: these should use LAPACK!
02191 
02192 // Dot product
02193 template <class E1, class E2> 
02194 typename CNT<E1>::template Result<E2>::Mul
02195 operator*(const RowVectorBase<E1>& r, const VectorBase<E2>& v) {
02196     assert(r.ncol() == v.nrow());
02197     typename CNT<E1>::template Result<E2>::Mul sum(0);
02198     for (int j=0; j < r.ncol(); ++j)
02199         sum += r(j) * v[j];
02200     return sum;
02201 }
02202 
02203 template <class E1, class E2> 
02204 Vector_<typename CNT<E1>::template Result<E2>::Mul>
02205 operator*(const MatrixBase<E1>& m, const VectorBase<E2>& v) {
02206     assert(m.ncol() == v.nrow());
02207     Vector_<typename CNT<E1>::template Result<E2>::Mul> res(m.nrow());
02208     for (int i=0; i< m.nrow(); ++i)
02209         res[i] = m[i]*v;
02210     return res;
02211 }
02212 
02213 template <class E1, class E2> 
02214 Matrix_<typename CNT<E1>::template Result<E2>::Mul>
02215 operator*(const MatrixBase<E1>& m1, const MatrixBase<E2>& m2) {
02216     assert(m1.ncol() == m2.nrow());
02217     Matrix_<typename CNT<E1>::template Result<E2>::Mul> 
02218         res(m1.nrow(),m2.ncol());
02219 
02220     for (int j=0; j < res.ncol(); ++j)
02221         for (int i=0; i < res.nrow(); ++i)
02222             res(i,j) = m1[i] * m2(j);
02223 
02224     return res;
02225 }
02226 
02227     // GLOBAL OPERATORS: I/O
02228 
02229 template <class T> inline std::ostream&
02230 operator<<(std::ostream& o, const VectorBase<T>& v)
02231 { o << "~["; for(int i=0;i<v.size();++i) o<<(i>0?" ":"")<<v[i]; 
02232     return o << "]"; }
02233 
02234 template <class T> inline std::ostream&
02235 operator<<(std::ostream& o, const RowVectorBase<T>& v)
02236 { o << "["; for(int i=0;i<v.size();++i) o<<(i>0?" ":"")<<v[i]; 
02237     return o << "]"; }
02238 
02239 template <class T> inline std::ostream&
02240 operator<<(std::ostream& o, const MatrixBase<T>& m) {
02241     for (int i=0;i<m.nrow();++i)
02242         o << std::endl << m[i];
02243     if (m.nrow()) o << std::endl;
02244     return o; 
02245 }
02246 
02247 
02248 // Friendly abbreviations for default precision vectors and matrices.
02249 
02250 typedef Vector_<Real>           Vector;
02251 typedef Vector_<Complex>        ComplexVector;
02252 
02253 typedef VectorView_<Real>       VectorView;
02254 typedef VectorView_<Complex>    ComplexVectorView;
02255 
02256 typedef RowVector_<Real>        RowVector;
02257 typedef RowVector_<Complex>     ComplexRowVector;
02258 
02259 typedef RowVectorView_<Real>    RowVectorView;
02260 typedef RowVectorView_<Complex> ComplexRowVectorView;
02261 
02262 typedef Matrix_<Real>           Matrix;
02263 typedef Matrix_<Complex>        ComplexMatrix;
02264 
02265 typedef MatrixView_<Real>       MatrixView;
02266 typedef MatrixView_<Complex>    ComplexMatrixView;
02267 
02268 
02269     
02270 // Not all combinations of structure/sparsity/storage/condition
02271 // are allowed. 
02272 
02273 class MatrixShape {
02274 public:
02275 
02276     MatrixShape() : shape(MatrixShapes::Uncommitted) { }
02277     // implicit conversion
02278     MatrixShape(MatrixShapes::Shape s) : shape(s) { }
02279     MatrixShapes::Shape shape;
02280 };
02281 
02282 class MatrixSize {
02283 public:
02284     enum Freedom {
02285         Uncommitted = 0x00,    // nrow, ncol variable
02286         FixedNRows  = 0x01,    // can't vary nrows
02287         FixedNCols  = 0x02,    // can't vary ncols
02288         Fixed       = FixedNRows | FixedNCols
02289     };
02290 
02291     MatrixSize() 
02292       : freedom(Uncommitted), nrow(0), ncol(0) { }
02293 
02294     MatrixSize(Freedom f, long nr, long nc) 
02295       : freedom(f), nrow(nr), ncol(nc) { }
02296 
02297     Freedom freedom;
02298     long nrow;
02299     long ncol;
02300 };
02301 
02302 class MatrixStructure {
02303 public:
02304 
02305     MatrixStructure() : structure(MatrixStructures::Uncommitted) { }
02306     
02307     // implicit conversion
02308     MatrixStructure(MatrixStructures::Structure ms) : structure(ms) { }
02309 
02310     MatrixStructures::Structure structure;
02311 };
02312 
02313 class MatrixSparsity {
02314 public:
02315 
02316     // If Banded, how stuck are we on a particular bandwidth?
02317     enum BandwidthFreedom {
02318         Free        = 0x00,    // upper & lower are free
02319         FixedUpper  = 0x01,
02320         FixedLower  = 0x02,
02321         Fixed       = FixedUpper | FixedLower
02322     };
02323 
02324     MatrixSparsity() 
02325       : sparsity(MatrixSparseFormats::Uncommitted), lowerBandwidth(-1), upperBandwidth(-1)
02326     {
02327     }
02328 
02329     MatrixSparsity(int lower, int upper) 
02330       : sparsity(MatrixSparseFormats::Banded), lowerBandwidth(lower), upperBandwidth(upper)
02331     {
02332         assert(lower >= 0 && upper >= 0);
02333     }
02334 
02335     MatrixSparseFormats::Sparsity sparsity;
02336     int lowerBandwidth;
02337     int upperBandwidth;
02338 };
02339 
02340 class MatrixStorage {
02341 public:
02342 
02343     enum Position {
02344         Lower,              // lower is default
02345         Upper
02346     };
02347 
02348     // OR-able
02349     enum Assumptions {
02350         None         = 0x00,
02351         UnitDiagonal = 0x01
02352     };
02353 
02354     MatrixStorage() 
02355       : storage(MatrixStorageFormats::Uncommitted), position(Lower), assumptions(None)
02356     {
02357     }
02358     
02359     // also serves as implicit conversion from Storage type
02360     MatrixStorage(MatrixStorageFormats::Storage s, Position p=Lower, Assumptions a=None) 
02361         : storage(s), position(p), assumptions(a)
02362     {
02363     }
02364 
02365     MatrixStorageFormats::Storage     storage;
02366     Position    position;
02367     Assumptions assumptions;
02368 
02369     // All the 2d formats allow a leading dimension larger
02370     // than the number of rows, producing a gap between
02371     // each column.
02372     int leadingDimension;
02373 
02374     // 1d formats allow spacing between elements. Stride==1
02375     // means packed.
02376     int stride;
02377 };
02378 
02379 class MatrixCondition {
02380 public:
02381 
02382     MatrixCondition() : condition(MatrixConditions::Uncommitted) { }
02383     // implicit conversion
02384     MatrixCondition(MatrixConditions::Condition c) : condition(c) { }
02385 
02386     MatrixConditions::Condition condition;
02387 };
02388 
02393 template <class ELT, class VECTOR_CLASS>
02394 class VectorIterator {
02395 public:
02396     typedef ELT value_type;
02397     typedef int difference_type;
02398     typedef ELT& reference;
02399     typedef ELT* pointer;
02400     typedef std::random_access_iterator_tag iterator_category;
02401     VectorIterator(VECTOR_CLASS& vector, int index) : vector(vector), index(index) {
02402     }
02403     VectorIterator(const VectorIterator& iter) : vector(iter.vector), index(iter.index) {
02404     }
02405     VectorIterator& operator=(const VectorIterator& iter) {
02406         vector = iter.vector;
02407         index = iter.index;
02408         return *this;
02409     }
02410     ELT& operator*() {
02411         assert (index >= 0 && index < vector.size());
02412         return vector[index];
02413     }
02414     ELT& operator[](int i) {
02415         assert (i >= 0 && i < vector.size());
02416         return vector[i];
02417     }
02418     VectorIterator operator++() {
02419         assert (index < vector.size());
02420         ++index;
02421         return *this;
02422     }
02423     VectorIterator operator++(int) {
02424         assert (index < vector.size());
02425         VectorIterator current = *this;
02426         ++index;
02427         return current;
02428     }
02429     VectorIterator operator--() {
02430         assert (index > 0);
02431         --index;
02432         return *this;
02433     }
02434     VectorIterator operator--(int) {
02435         assert (index > 0);
02436         VectorIterator current = *this;
02437         --index;
02438         return current;
02439     }
02440     bool operator<(VectorIterator iter) const {
02441         return (index < iter.index);
02442     }
02443     bool operator>(VectorIterator iter) const {
02444         return (index > iter.index);
02445     }
02446     bool operator<=(VectorIterator iter) const {
02447         return (index <= iter.index);
02448     }
02449     bool operator>=(VectorIterator iter) const {
02450         return (index >= iter.index);
02451     }
02452     int operator-(VectorIterator iter) const {
02453         return (index - iter.index);
02454     }
02455     VectorIterator operator-(int n) const {
02456         return VectorIterator(vector, index-n);
02457     }
02458     VectorIterator operator+(int n) const {
02459         return VectorIterator(vector, index+n);
02460     }
02461     bool operator==(VectorIterator iter) const {
02462         return (index == iter.index);
02463     }
02464     bool operator!=(VectorIterator iter) const {
02465         return (index != iter.index);
02466     }
02467 private:
02468     VECTOR_CLASS& vector;
02469     int index;
02470 };
02471 
02472 } //namespace SimTK
02473 
02474 #endif //SimTK_SIMMATRIX_BIGMATRIX_H_

Generated on Fri Sep 26 07:44:08 2008 for SimTKcore by  doxygen 1.5.6