Simbody

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-9 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 
00167 // TODO: matrix expression templates for delaying operator execution.
00168 
00169 #include "SimTKcommon/Scalar.h"
00170 #include "SimTKcommon/SmallMatrix.h"
00171 
00172 #include "SimTKcommon/internal/MatrixHelper.h"
00173 #include "SimTKcommon/internal/MatrixCharacteristics.h"
00174 
00175 #include <iostream>
00176 #include <cassert>
00177 #include <complex>
00178 #include <cstddef>
00179 #include <limits>
00180 
00181 namespace SimTK {
00182 
00183 template <class ELT>    class MatrixBase;
00184 template <class ELT>    class VectorBase;
00185 template <class ELT>    class RowVectorBase;
00186 
00187 template <class T=Real> class MatrixView_;
00188 template <class T=Real> class DeadMatrixView_;
00189 template <class T=Real> class Matrix_;
00190 template <class T=Real> class DeadMatrix_;
00191 
00192 template <class T=Real> class VectorView_;
00193 template <class T=Real> class DeadVectorView_;
00194 template <class T=Real> class Vector_;
00195 template <class T=Real> class DeadVector_;
00196 
00197 template <class T=Real> class RowVectorView_;
00198 template <class T=Real> class DeadRowVectorView_;
00199 template <class T=Real> class RowVector_;
00200 template <class T=Real> class DeadRowVector_;
00201 
00202 template <class ELT, class VECTOR_CLASS> class VectorIterator;
00203 
00204 //  -------------------------------- MatrixBase --------------------------------
00226 //  ----------------------------------------------------------------------------
00227 template <class ELT> class MatrixBase {  
00228 public:
00229     // These typedefs are handy, but despite appearances you cannot 
00230     // treat a MatrixBase as a composite numerical type. That is,
00231     // CNT<MatrixBase> will not compile, or if it does it won't be
00232     // meaningful.
00233 
00234     typedef ELT                                 E;
00235     typedef typename CNT<E>::TNeg               ENeg;
00236     typedef typename CNT<E>::TWithoutNegator    EWithoutNegator;
00237     typedef typename CNT<E>::TReal              EReal;
00238     typedef typename CNT<E>::TImag              EImag;
00239     typedef typename CNT<E>::TComplex           EComplex;
00240     typedef typename CNT<E>::THerm              EHerm;       
00241     typedef typename CNT<E>::TPosTrans          EPosTrans;
00242 
00243     typedef typename CNT<E>::TAbs               EAbs;
00244     typedef typename CNT<E>::TStandard          EStandard;
00245     typedef typename CNT<E>::TInvert            EInvert;
00246     typedef typename CNT<E>::TNormalize         ENormalize;
00247     typedef typename CNT<E>::TSqHermT           ESqHermT;
00248     typedef typename CNT<E>::TSqTHerm           ESqTHerm;
00249 
00250     typedef typename CNT<E>::Scalar             EScalar;
00251     typedef typename CNT<E>::Number             ENumber;
00252     typedef typename CNT<E>::StdNumber          EStdNumber;
00253     typedef typename CNT<E>::Precision          EPrecision;
00254     typedef typename CNT<E>::ScalarNormSq       EScalarNormSq;
00255 
00256     typedef EScalar    Scalar;        // the underlying Scalar type
00257     typedef ENumber    Number;        // negator removed from Scalar
00258     typedef EStdNumber StdNumber;     // conjugate goes to complex
00259     typedef EPrecision Precision;     // complex removed from StdNumber
00260     typedef EScalarNormSq  ScalarNormSq;      // type of scalar^2
00261 
00262     typedef MatrixBase<E>                T;
00263     typedef MatrixBase<ENeg>             TNeg;
00264     typedef MatrixBase<EWithoutNegator>  TWithoutNegator;
00265     typedef MatrixBase<EReal>            TReal;
00266     typedef MatrixBase<EImag>            TImag;
00267     typedef MatrixBase<EComplex>         TComplex;
00268     typedef MatrixBase<EHerm>            THerm; 
00269     typedef MatrixBase<E>                TPosTrans;
00270 
00271     typedef MatrixBase<EAbs>             TAbs;
00272     typedef MatrixBase<EStandard>        TStandard;
00273     typedef MatrixBase<EInvert>          TInvert;
00274     typedef MatrixBase<ENormalize>       TNormalize;
00275     typedef MatrixBase<ESqHermT>         TSqHermT;  // ~Mat*Mat
00276     typedef MatrixBase<ESqTHerm>         TSqTHerm;  // Mat*~Mat
00277 
00278     const MatrixCommitment& getCharacterCommitment() const {return helper.getCharacterCommitment();}
00279     const MatrixCharacter& getMatrixCharacter()     const {return helper.getMatrixCharacter();}
00280 
00283     void commitTo(const MatrixCommitment& mc)
00284     {   helper.commitTo(mc); }
00285 
00286     // This gives the resulting matrix type when (m(i,j) op P) is applied to each element.
00287     // It will have element types which are the regular composite result of E op P.
00288     template <class P> struct EltResult { 
00289         typedef MatrixBase<typename CNT<E>::template Result<P>::Mul> Mul;
00290         typedef MatrixBase<typename CNT<E>::template Result<P>::Dvd> Dvd;
00291         typedef MatrixBase<typename CNT<E>::template Result<P>::Add> Add;
00292         typedef MatrixBase<typename CNT<E>::template Result<P>::Sub> Sub;
00293     };
00294 
00296     int  nrow() const {return helper.nrow();}
00298     int  ncol() const {return helper.ncol();}
00299 
00307     ptrdiff_t nelt() const {return helper.nelt();}
00308 
00310     bool isResizeable() const {return getCharacterCommitment().isResizeable();}
00311 
00312     enum { 
00313         NScalarsPerElement    = CNT<E>::NActualScalars,
00314         CppNScalarsPerElement = sizeof(E) / sizeof(Scalar)
00315     };
00316   
00320     MatrixBase() : helper(NScalarsPerElement,CppNScalarsPerElement) {}
00321 
00324     MatrixBase(int m, int n) 
00325     :   helper(NScalarsPerElement,CppNScalarsPerElement,MatrixCommitment(),m,n) {}
00326 
00332     explicit MatrixBase(const MatrixCommitment& commitment) 
00333     :   helper(NScalarsPerElement,CppNScalarsPerElement,commitment) {}
00334 
00335 
00340     MatrixBase(const MatrixCommitment& commitment, int m, int n) 
00341     :   helper(NScalarsPerElement,CppNScalarsPerElement,commitment,m,n) {}
00342 
00344     MatrixBase(const MatrixBase& b)
00345       : helper(b.helper.getCharacterCommitment(), 
00346                b.helper, typename MatrixHelper<Scalar>::DeepCopy()) { }
00347 
00350     MatrixBase(const TNeg& b)
00351       : helper(b.helper.getCharacterCommitment(),
00352                b.helper, typename MatrixHelper<Scalar>::DeepCopy()) { }
00353     
00356     MatrixBase& copyAssign(const MatrixBase& b) {
00357         helper.copyAssign(b.helper);
00358         return *this;
00359     }
00360     MatrixBase& operator=(const MatrixBase& b) { return copyAssign(b); }
00361 
00362 
00371     MatrixBase& viewAssign(const MatrixBase& src) {
00372         helper.writableViewAssign(const_cast<MatrixHelper<Scalar>&>(src.helper));
00373         return *this;
00374     }
00375 
00376     // default destructor
00377 
00384     MatrixBase(const MatrixCommitment& commitment, int m, int n, const ELT& initialValue) 
00385     :   helper(NScalarsPerElement, CppNScalarsPerElement, commitment, m, n)
00386     {   helper.fillWith(reinterpret_cast<const Scalar*>(&initialValue)); }  
00387 
00398     MatrixBase(const MatrixCommitment& commitment, int m, int n, 
00399                const ELT* cppInitialValuesByRow) 
00400     :   helper(NScalarsPerElement, CppNScalarsPerElement, commitment, m, n)
00401     {   helper.copyInByRowsFromCpp(reinterpret_cast<const Scalar*>(cppInitialValuesByRow)); }
00402      
00414 
00416     MatrixBase(const MatrixCommitment& commitment, 
00417                const MatrixCharacter&  character, 
00418                int spacing, const Scalar* data) // read only data
00419     :   helper(NScalarsPerElement, CppNScalarsPerElement, 
00420                commitment, character, spacing, data) {}  
00421 
00423     MatrixBase(const MatrixCommitment& commitment, 
00424                const MatrixCharacter&  character, 
00425                int spacing, Scalar* data) // writable data
00426     :   helper(NScalarsPerElement, CppNScalarsPerElement, 
00427                commitment, character, spacing, data) {}  
00429         
00430     // Create a new MatrixBase from an existing helper. Both shallow and deep copies are possible.
00431     MatrixBase(const MatrixCommitment& commitment, 
00432                MatrixHelper<Scalar>&   source, 
00433                const typename MatrixHelper<Scalar>::ShallowCopy& shallow) 
00434     :   helper(commitment, source, shallow) {}
00435     MatrixBase(const MatrixCommitment&      commitment, 
00436                const MatrixHelper<Scalar>&  source, 
00437                const typename MatrixHelper<Scalar>::ShallowCopy& shallow) 
00438     :   helper(commitment, source, shallow) {}
00439     MatrixBase(const MatrixCommitment&      commitment, 
00440                const MatrixHelper<Scalar>&  source, 
00441                const typename MatrixHelper<Scalar>::DeepCopy& deep)    
00442     :   helper(commitment, source, deep) {}
00443 
00447     void clear() {helper.clear();}
00448 
00449     MatrixBase& operator*=(const StdNumber& t)  { helper.scaleBy(t);              return *this; }
00450     MatrixBase& operator/=(const StdNumber& t)  { helper.scaleBy(StdNumber(1)/t); return *this; }
00451     MatrixBase& operator+=(const MatrixBase& r) { helper.addIn(r.helper);         return *this; }
00452     MatrixBase& operator-=(const MatrixBase& r) { helper.subIn(r.helper);         return *this; }  
00453 
00454     template <class EE> MatrixBase(const MatrixBase<EE>& b)
00455       : helper(MatrixCommitment(),b.helper, typename MatrixHelper<Scalar>::DeepCopy()) { }
00456 
00457     template <class EE> MatrixBase& operator=(const MatrixBase<EE>& b) 
00458       { helper = b.helper; return *this; }
00459     template <class EE> MatrixBase& operator+=(const MatrixBase<EE>& b) 
00460       { helper.addIn(b.helper); return *this; }
00461     template <class EE> MatrixBase& operator-=(const MatrixBase<EE>& b) 
00462       { helper.subIn(b.helper); return *this; }
00463 
00474     MatrixBase& operator=(const ELT& t) { 
00475         setToZero(); updDiag().setTo(t); 
00476         return *this;
00477     }
00478 
00484     template <class S> inline MatrixBase&
00485     scalarAssign(const S& s) {
00486         setToZero(); updDiag().setTo(s);
00487         return *this;
00488     }
00489 
00493     template <class S> inline MatrixBase&
00494     scalarAddInPlace(const S& s) {
00495         updDiag().elementwiseAddScalarInPlace(s);
00496     }
00497 
00498 
00502     template <class S> inline MatrixBase&
00503     scalarSubtractInPlace(const S& s) {
00504         updDiag().elementwiseSubtractScalarInPlace(s);
00505     }
00506 
00509     template <class S> inline MatrixBase&
00510     scalarSubtractFromLeftInPlace(const S& s) {
00511         negateInPlace();
00512         updDiag().elementwiseAddScalarInPlace(s); // yes, add
00513     }
00514 
00521     template <class S> inline MatrixBase&
00522     scalarMultiplyInPlace(const S&);
00523 
00527     template <class S> inline MatrixBase&
00528     scalarMultiplyFromLeftInPlace(const S&);
00529 
00536     template <class S> inline MatrixBase&
00537     scalarDivideInPlace(const S&);
00538 
00542     template <class S> inline MatrixBase&
00543     scalarDivideFromLeftInPlace(const S&);
00544 
00545 
00548     template <class EE> inline MatrixBase& 
00549     rowScaleInPlace(const VectorBase<EE>&);
00550 
00553     template <class EE> inline void 
00554     rowScale(const VectorBase<EE>& r, typename EltResult<EE>::Mul& out) const;
00555 
00556     template <class EE> inline typename EltResult<EE>::Mul 
00557     rowScale(const VectorBase<EE>& r) const {
00558         typename EltResult<EE>::Mul out(nrow(), ncol()); rowScale(r,out); return out;
00559     }
00560 
00563     template <class EE> inline MatrixBase& 
00564     colScaleInPlace(const VectorBase<EE>&);
00565 
00566     template <class EE> inline void 
00567     colScale(const VectorBase<EE>& c, typename EltResult<EE>::Mul& out) const;
00568 
00569     template <class EE> inline typename EltResult<EE>::Mul
00570     colScale(const VectorBase<EE>& c) const {
00571         typename EltResult<EE>::Mul out(nrow(), ncol()); colScale(c,out); return out;
00572     }
00573 
00574 
00579     template <class ER, class EC> inline MatrixBase& 
00580     rowAndColScaleInPlace(const VectorBase<ER>& r, const VectorBase<EC>& c);
00581 
00582     template <class ER, class EC> inline void 
00583     rowAndColScale(const VectorBase<ER>& r, const VectorBase<EC>& c, 
00584                    typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul& out) const;
00585 
00586     template <class ER, class EC> inline typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul
00587     rowAndColScale(const VectorBase<ER>& r, const VectorBase<EC>& c) const {
00588         typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul 
00589             out(nrow(), ncol()); 
00590         rowAndColScale(r,c,out); return out;
00591     }
00592 
00600     template <class S> inline MatrixBase&
00601     elementwiseAssign(const S& s);
00602 
00604     MatrixBase& elementwiseInvertInPlace();
00605 
00606     void elementwiseInvert(MatrixBase<typename CNT<E>::TInvert>& out) const;
00607 
00608     MatrixBase<typename CNT<E>::TInvert> elementwiseInvert() const {
00609         MatrixBase<typename CNT<E>::TInvert> out(nrow(), ncol());
00610         elementwiseInvert(out);
00611         return out;
00612     }
00613 
00621     template <class S> inline MatrixBase&
00622     elementwiseAddScalarInPlace(const S& s);
00623 
00624     template <class S> inline void
00625     elementwiseAddScalar(const S& s, typename EltResult<S>::Add&) const;
00626 
00627     template <class S> inline typename EltResult<S>::Add
00628     elementwiseAddScalar(const S& s) const {
00629         typename EltResult<S>::Add out(nrow(), ncol());
00630         elementwiseAddScalar(s,out);
00631         return out;
00632     }
00633 
00641     template <class S> inline MatrixBase&
00642     elementwiseSubtractScalarInPlace(const S& s);
00643 
00644     template <class S> inline void
00645     elementwiseSubtractScalar(const S& s, typename EltResult<S>::Sub&) const;
00646 
00647     template <class S> inline typename EltResult<S>::Sub
00648     elementwiseSubtractScalar(const S& s) const {
00649         typename EltResult<S>::Sub out(nrow(), ncol());
00650         elementwiseSubtractScalar(s,out);
00651         return out;
00652     }
00653 
00662     template <class S> inline MatrixBase&
00663     elementwiseSubtractFromScalarInPlace(const S& s);
00664 
00665     template <class S> inline void
00666     elementwiseSubtractFromScalar(
00667         const S&, 
00668         typename MatrixBase<S>::template EltResult<E>::Sub&) const;
00669 
00670     template <class S> inline typename MatrixBase<S>::template EltResult<E>::Sub
00671     elementwiseSubtractFromScalar(const S& s) const {
00672         typename MatrixBase<S>::template EltResult<E>::Sub out(nrow(), ncol());
00673         elementwiseSubtractFromScalar<S>(s,out);
00674         return out;
00675     }
00676 
00678     template <class EE> inline MatrixBase& 
00679     elementwiseMultiplyInPlace(const MatrixBase<EE>&);
00680 
00681     template <class EE> inline void 
00682     elementwiseMultiply(const MatrixBase<EE>&, typename EltResult<EE>::Mul&) const;
00683 
00684     template <class EE> inline typename EltResult<EE>::Mul 
00685     elementwiseMultiply(const MatrixBase<EE>& m) const {
00686         typename EltResult<EE>::Mul out(nrow(), ncol()); 
00687         elementwiseMultiply<EE>(m,out); 
00688         return out;
00689     }
00690 
00692     template <class EE> inline MatrixBase& 
00693     elementwiseMultiplyFromLeftInPlace(const MatrixBase<EE>&);
00694 
00695     template <class EE> inline void 
00696     elementwiseMultiplyFromLeft(
00697         const MatrixBase<EE>&, 
00698         typename MatrixBase<EE>::template EltResult<E>::Mul&) const;
00699 
00700     template <class EE> inline typename MatrixBase<EE>::template EltResult<E>::Mul 
00701     elementwiseMultiplyFromLeft(const MatrixBase<EE>& m) const {
00702         typename EltResult<EE>::Mul out(nrow(), ncol()); 
00703         elementwiseMultiplyFromLeft<EE>(m,out); 
00704         return out;
00705     }
00706 
00708     template <class EE> inline MatrixBase& 
00709     elementwiseDivideInPlace(const MatrixBase<EE>&);
00710 
00711     template <class EE> inline void 
00712     elementwiseDivide(const MatrixBase<EE>&, typename EltResult<EE>::Dvd&) const;
00713 
00714     template <class EE> inline typename EltResult<EE>::Dvd 
00715     elementwiseDivide(const MatrixBase<EE>& m) const {
00716         typename EltResult<EE>::Dvd out(nrow(), ncol()); 
00717         elementwiseDivide<EE>(m,out); 
00718         return out;
00719     }
00720 
00722     template <class EE> inline MatrixBase& 
00723     elementwiseDivideFromLeftInPlace(const MatrixBase<EE>&);
00724 
00725     template <class EE> inline void 
00726     elementwiseDivideFromLeft(
00727         const MatrixBase<EE>&,
00728         typename MatrixBase<EE>::template EltResult<E>::Dvd&) const;
00729 
00730     template <class EE> inline typename MatrixBase<EE>::template EltResult<EE>::Dvd 
00731     elementwiseDivideFromLeft(const MatrixBase<EE>& m) const {
00732         typename MatrixBase<EE>::template EltResult<E>::Dvd out(nrow(), ncol()); 
00733         elementwiseDivideFromLeft<EE>(m,out); 
00734         return out;
00735     }
00736 
00738     MatrixBase& setTo(const ELT& t) {helper.fillWith(reinterpret_cast<const Scalar*>(&t)); return *this;}
00739     MatrixBase& setToNaN() {helper.fillWithScalar(CNT<StdNumber>::getNaN()); return *this;}
00740     MatrixBase& setToZero() {helper.fillWithScalar(StdNumber(0)); return *this;}
00741  
00742     // View creating operators. TODO: these should be DeadMatrixViews  
00743     inline RowVectorView_<ELT> row(int i) const;   // select a row
00744     inline RowVectorView_<ELT> updRow(int i);
00745     inline VectorView_<ELT>    col(int j) const;   // select a column
00746     inline VectorView_<ELT>    updCol(int j);
00747 
00748     RowVectorView_<ELT> operator[](int i) const {return row(i);}
00749     RowVectorView_<ELT> operator[](int i)       {return updRow(i);}
00750     VectorView_<ELT>    operator()(int j) const {return col(j);}
00751     VectorView_<ELT>    operator()(int j)       {return updCol(j);}
00752      
00753     // Select a block.
00754     inline MatrixView_<ELT> block(int i, int j, int m, int n) const;
00755     inline MatrixView_<ELT> updBlock(int i, int j, int m, int n);
00756 
00757     MatrixView_<ELT> operator()(int i, int j, int m, int n) const
00758       { return block(i,j,m,n); }
00759     MatrixView_<ELT> operator()(int i, int j, int m, int n)
00760       { return updBlock(i,j,m,n); }
00761  
00762     // Hermitian transpose.
00763     inline MatrixView_<EHerm> transpose() const;
00764     inline MatrixView_<EHerm> updTranspose();
00765 
00766     MatrixView_<EHerm> operator~() const {return transpose();}
00767     MatrixView_<EHerm> operator~()       {return updTranspose();}
00768 
00769     // Select matrix diagonal (of largest leading square if rectangular).
00770     inline VectorView_<ELT> diag() const;
00771     inline VectorView_<ELT> updDiag();
00772 
00773     // Create a view of the real or imaginary elements. TODO
00774     //inline MatrixView_<EReal> real() const;
00775     //inline MatrixView_<EReal> updReal();
00776     //inline MatrixView_<EImag> imag() const;
00777     //inline MatrixView_<EImag> updImag();
00778 
00779     // Overload "real" and "imag" for both read and write as a nod to convention. TODO
00780     //MatrixView_<EReal> real() {return updReal();}
00781     //MatrixView_<EReal> imag() {return updImag();}
00782 
00783     // TODO: this routine seems ill-advised but I need it for the IVM port at the moment
00784     TInvert invert() const {  // return a newly-allocated inverse; dump negator 
00785         TInvert m(*this);
00786         m.helper.invertInPlace();
00787         return m;   // TODO - bad: makes an extra copy
00788     }
00789 
00790     void invertInPlace() {helper.invertInPlace();}
00791 
00793     void dump(const char* msg=0) const {
00794         helper.dump(msg);
00795     }
00796 
00797 
00798     // This routine is useful for implementing friendlier Matrix expressions and operators.
00799     // It maps closely to the Level-3 BLAS family of pxxmm() routines like sgemm(). The
00800     // operation performed assumes that "this" is the result, and that "this" has 
00801     // already been sized correctly to receive the result. We'll compute
00802     //     this = beta*this + alpha*A*B
00803     // If beta is 0 then "this" can be uninitialized. If alpha is 0 we promise not
00804     // to look at A or B. The routine can work efficiently even if A and/or B are transposed
00805     // by their views, so an expression like
00806     //        C += s * ~A * ~B
00807     // can be performed with the single equivalent call
00808     //        C.matmul(1., s, Tr(A), Tr(B))
00809     // where Tr(A) indicates a transposed view of the original A.
00810     // The ultimate efficiency of this call depends on the data layout and views which
00811     // are used for the three matrices.
00812     // NOTE: neither A nor B can be the same matrix as 'this', nor views of the same data
00813     // which would expose elements of 'this' that will be modified by this operation.
00814     template <class ELT_A, class ELT_B>
00815     MatrixBase& matmul(const StdNumber& beta,   // applied to 'this'
00816                        const StdNumber& alpha, const MatrixBase<ELT_A>& A, const MatrixBase<ELT_B>& B)
00817     {
00818         helper.matmul(beta,alpha,A.helper,B.helper);
00819         return *this;
00820     }
00821 
00830     const ELT& getElt(int i, int j) const { return *reinterpret_cast<const ELT*>(helper.getElt(i,j)); }
00831     ELT&       updElt(int i, int j)       { return *reinterpret_cast<      ELT*>(helper.updElt(i,j)); }
00832 
00833     const ELT& operator()(int i, int j) const {return getElt(i,j);}
00834     ELT&       operator()(int i, int j)       {return updElt(i,j);}
00835 
00840     void getAnyElt(int i, int j, ELT& value) const
00841     {   helper.getAnyElt(i,j,reinterpret_cast<Scalar*>(&value)); }
00842     ELT getAnyElt(int i, int j) const {ELT e; getAnyElt(i,j,e); return e;}
00843 
00846     // TODO: very slow! Should be optimized at least for the case
00847     //       where ELT is a Scalar.
00848     ScalarNormSq scalarNormSqr() const {
00849         const int nr=nrow(), nc=ncol();
00850         ScalarNormSq sum(0);
00851         for(int j=0;j<nc;++j) 
00852             for (int i=0; i<nr; ++i)
00853                 sum += CNT<E>::scalarNormSqr((*this)(i,j));
00854         return sum;
00855     }
00856 
00860     // TODO: very slow! Should be optimized at least for the case
00861     //       where ELT is a Scalar.
00862     void abs(TAbs& mabs) const {
00863         const int nr=nrow(), nc=ncol();
00864         mabs.resize(nr,nc);
00865         for(int j=0;j<nc;++j) 
00866             for (int i=0; i<nr; ++i)
00867                 mabs(i,j) = CNT<E>::abs((*this)(i,j));
00868     }
00869 
00872     TAbs abs() const { TAbs mabs; abs(mabs); return mabs; }
00873 
00884     TStandard standardize() const {
00885         const int nr=nrow(), nc=ncol();
00886         TStandard mstd(nr, nc);
00887         for(int j=0;j<nc;++j) 
00888             for (int i=0; i<nr; ++i)
00889                 mstd(i,j) = CNT<E>::standardize((*this)(i,j));
00890         return mstd;
00891     }
00892 
00895     ScalarNormSq normSqr() const { return scalarNormSqr(); }
00896     // TODO -- not good; unnecessary overflow
00897     typename CNT<ScalarNormSq>::TSqrt 
00898         norm() const { return CNT<ScalarNormSq>::sqrt(scalarNormSqr()); }
00899 
00902     typename CNT<ScalarNormSq>::TSqrt 
00903     normRMS() const {
00904         if (!CNT<ELT>::IsScalar)
00905             SimTK_THROW1(Exception::Cant, "normRMS() only defined for scalar elements");
00906         if (nelt() == 0)
00907             return typename CNT<ScalarNormSq>::TSqrt(0);
00908         return CNT<ScalarNormSq>::sqrt(scalarNormSqr()/nelt());
00909     }
00910 
00912     RowVectorBase<ELT> sum() const {
00913         const int cols = ncol();
00914         RowVectorBase<ELT> row(cols);
00915         for (int i = 0; i < cols; ++i)
00916             helper.colSum(i, reinterpret_cast<Scalar*>(&row[i]));
00917         return row;
00918     }
00919 
00920     //TODO: make unary +/- return a self-view so they won't reallocate?
00921     const MatrixBase& operator+() const {return *this; }
00922     const TNeg&       negate()    const {return *reinterpret_cast<const TNeg*>(this); }
00923     TNeg&             updNegate()       {return *reinterpret_cast<TNeg*>(this); }
00924 
00925     const TNeg&       operator-() const {return negate();}
00926     TNeg&             operator-()       {return updNegate();}
00927 
00928     MatrixBase& negateInPlace() {(*this) *= EPrecision(-1); return *this;}
00929  
00934     MatrixBase& resize(int m, int n)     { helper.resize(m,n); return *this; }
00940     MatrixBase& resizeKeep(int m, int n) { helper.resizeKeep(m,n); return *this; }
00941 
00942     // This prevents shape changes in a Matrix that would otherwise allow it. No harm if is
00943     // are called on a Matrix that is locked already; it always succeeds.
00944     void lockShape() {helper.lockShape();}
00945 
00946     // This allows shape changes again for a Matrix which was constructed to allow them
00947     // but had them locked with the above routine. No harm if this is called on a Matrix
00948     // that is already unlocked, but it is not allowed to call this on a Matrix which
00949     // *never* allowed resizing. An exception will be thrown in that case.
00950     void unlockShape() {helper.unlockShape();}
00951     
00952     // An assortment of handy conversions
00953     const MatrixView_<ELT>& getAsMatrixView() const { return *reinterpret_cast<const MatrixView_<ELT>*>(this); }
00954     MatrixView_<ELT>&       updAsMatrixView()       { return *reinterpret_cast<      MatrixView_<ELT>*>(this); } 
00955     const Matrix_<ELT>&     getAsMatrix()     const { return *reinterpret_cast<const Matrix_<ELT>*>(this); }
00956     Matrix_<ELT>&           updAsMatrix()           { return *reinterpret_cast<      Matrix_<ELT>*>(this); }
00957          
00958     const VectorView_<ELT>& getAsVectorView() const 
00959       { assert(ncol()==1); return *reinterpret_cast<const VectorView_<ELT>*>(this); }
00960     VectorView_<ELT>&       updAsVectorView()       
00961       { assert(ncol()==1); return *reinterpret_cast<      VectorView_<ELT>*>(this); } 
00962     const Vector_<ELT>&     getAsVector()     const 
00963       { assert(ncol()==1); return *reinterpret_cast<const Vector_<ELT>*>(this); }
00964     Vector_<ELT>&           updAsVector()           
00965       { assert(ncol()==1); return *reinterpret_cast<      Vector_<ELT>*>(this); }
00966     const VectorBase<ELT>& getAsVectorBase() const 
00967       { assert(ncol()==1); return *reinterpret_cast<const VectorBase<ELT>*>(this); }
00968     VectorBase<ELT>&       updAsVectorBase()       
00969       { assert(ncol()==1); return *reinterpret_cast<      VectorBase<ELT>*>(this); } 
00970                 
00971     const RowVectorView_<ELT>& getAsRowVectorView() const 
00972       { assert(nrow()==1); return *reinterpret_cast<const RowVectorView_<ELT>*>(this); }
00973     RowVectorView_<ELT>&       updAsRowVectorView()       
00974       { assert(nrow()==1); return *reinterpret_cast<      RowVectorView_<ELT>*>(this); } 
00975     const RowVector_<ELT>&     getAsRowVector()     const 
00976       { assert(nrow()==1); return *reinterpret_cast<const RowVector_<ELT>*>(this); }
00977     RowVector_<ELT>&           updAsRowVector()           
00978       { assert(nrow()==1); return *reinterpret_cast<      RowVector_<ELT>*>(this); }        
00979     const RowVectorBase<ELT>& getAsRowVectorBase() const 
00980       { assert(nrow()==1); return *reinterpret_cast<const RowVectorBase<ELT>*>(this); }
00981     RowVectorBase<ELT>&       updAsRowVectorBase()       
00982       { assert(nrow()==1); return *reinterpret_cast<      RowVectorBase<ELT>*>(this); } 
00983 
00984     // Access to raw data. We have to return the raw data
00985     // pointer as pointer-to-scalar because we may pack the elements tighter
00986     // than a C++ array would.
00987 
00991     int getNScalarsPerElement()  const {return NScalarsPerElement;}
00992 
00996     int getPackedSizeofElement() const {return NScalarsPerElement*sizeof(Scalar);}
00997 
00998     bool hasContiguousData() const {return helper.hasContiguousData();}
00999     ptrdiff_t getContiguousScalarDataLength() const {
01000         return helper.getContiguousDataLength();
01001     }
01002     const Scalar* getContiguousScalarData() const {
01003         return helper.getContiguousData();
01004     }
01005     Scalar* updContiguousScalarData() {
01006         return helper.updContiguousData();
01007     }
01008     void replaceContiguousScalarData(Scalar* newData, ptrdiff_t length, bool takeOwnership) {
01009         helper.replaceContiguousData(newData,length,takeOwnership);
01010     }
01011     void replaceContiguousScalarData(const Scalar* newData, ptrdiff_t length) {
01012         helper.replaceContiguousData(newData,length);
01013     }
01014     void swapOwnedContiguousScalarData(Scalar* newData, ptrdiff_t length, Scalar*& oldData) {
01015         helper.swapOwnedContiguousData(newData,length,oldData);
01016     }
01017 
01022     explicit MatrixBase(MatrixHelperRep<Scalar>* hrep) : helper(hrep) {}
01023 
01024 protected:
01025     const MatrixHelper<Scalar>& getHelper() const {return helper;}
01026     MatrixHelper<Scalar>&       updHelper()       {return helper;}
01027 
01028 private:
01029     MatrixHelper<Scalar> helper; // this is just one pointer
01030 
01031     template <class EE> friend class MatrixBase;
01032 };
01033 
01034 
01035 
01036 //  -------------------------------- VectorBase --------------------------------
01040 //  ----------------------------------------------------------------------------
01041 template <class ELT> class VectorBase : public MatrixBase<ELT> {
01042     typedef MatrixBase<ELT>                             Base;
01043     typedef typename CNT<ELT>::Scalar                   Scalar;
01044     typedef typename CNT<ELT>::Number                   Number;
01045     typedef typename CNT<ELT>::StdNumber                StdNumber;
01046     typedef VectorBase<ELT>                             T;
01047     typedef VectorBase<typename CNT<ELT>::TAbs>         TAbs;
01048     typedef VectorBase<typename CNT<ELT>::TNeg>         TNeg;
01049     typedef RowVectorView_<typename CNT<ELT>::THerm>    THerm;
01050 public:  
01051     //  ------------------------------------------------------------------------
01061 
01064     explicit VectorBase(int m=0) : Base(MatrixCommitment::Vector(), m, 1) {}
01065 
01069     VectorBase(const VectorBase& source) : Base(source) {}
01070 
01072     VectorBase(const TNeg& source) : Base(source) {}
01073 
01076     VectorBase(int m, const ELT& initialValue)
01077     :   Base(MatrixCommitment::Vector(),m,1,initialValue) {}  
01078 
01083     VectorBase(int m, const ELT* cppInitialValues)
01084     :   Base(MatrixCommitment::Vector(),m,1,cppInitialValues) {}
01086 
01087     //  ------------------------------------------------------------------------
01096 
01098     VectorBase(int m, int stride, const Scalar* s)
01099     :   Base(MatrixCommitment::Vector(m), MatrixCharacter::Vector(m),stride,s) { }
01101     VectorBase(int m, int stride, Scalar* s)
01102     :   Base(MatrixCommitment::Vector(m), MatrixCharacter::Vector(m),stride,s) { }
01104         
01105     //  ------------------------------------------------------------------------
01112 
01114     VectorBase(MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::ShallowCopy& s) 
01115     :   Base(MatrixCommitment::Vector(), h,s) { }
01117     VectorBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::ShallowCopy& s) 
01118     :   Base(MatrixCommitment::Vector(), h,s) { }
01120     VectorBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::DeepCopy& d)    
01121     :   Base(MatrixCommitment::Vector(), h,d) { }
01123 
01124     // This gives the resulting vector type when (v[i] op P) is applied to each element.
01125     // It will have element types which are the regular composite result of ELT op P.
01126     template <class P> struct EltResult { 
01127         typedef VectorBase<typename CNT<ELT>::template Result<P>::Mul> Mul;
01128         typedef VectorBase<typename CNT<ELT>::template Result<P>::Dvd> Dvd;
01129         typedef VectorBase<typename CNT<ELT>::template Result<P>::Add> Add;
01130         typedef VectorBase<typename CNT<ELT>::template Result<P>::Sub> Sub;
01131     };
01132 
01135     VectorBase& operator=(const VectorBase& b) {
01136         Base::operator=(b); return *this;
01137     }
01138 
01139     // default destructor
01140 
01141 
01142     VectorBase& operator*=(const StdNumber& t)  { Base::operator*=(t); return *this; }
01143     VectorBase& operator/=(const StdNumber& t)  { Base::operator/=(t); return *this; }
01144     VectorBase& operator+=(const VectorBase& r) { Base::operator+=(r); return *this; }
01145     VectorBase& operator-=(const VectorBase& r) { Base::operator-=(r); return *this; }  
01146 
01147 
01148     template <class EE> VectorBase& operator=(const VectorBase<EE>& b) 
01149       { Base::operator=(b);  return *this; } 
01150     template <class EE> VectorBase& operator+=(const VectorBase<EE>& b) 
01151       { Base::operator+=(b); return *this; } 
01152     template <class EE> VectorBase& operator-=(const VectorBase<EE>& b) 
01153       { Base::operator-=(b); return *this; } 
01154 
01155 
01159     VectorBase& operator=(const ELT& t) { Base::setTo(t); return *this; }  
01160 
01165     template <class EE> VectorBase& rowScaleInPlace(const VectorBase<EE>& v)
01166       { Base::template rowScaleInPlace<EE>(v); return *this; }
01167     template <class EE> inline void rowScale(const VectorBase<EE>& v, typename EltResult<EE>::Mul& out) const
01168       { Base::rowScale(v,out); }
01169     template <class EE> inline typename EltResult<EE>::Mul rowScale(const VectorBase<EE>& v) const
01170       { typename EltResult<EE>::Mul out(nrow()); Base::rowScale(v,out); return out; }
01171 
01173     VectorBase& elementwiseInvertInPlace() {
01174         Base::elementwiseInvertInPlace();
01175         return *this;
01176     }
01177 
01179     void elementwiseInvert(VectorBase<typename CNT<ELT>::TInvert>& out) const {
01180         Base::elementwiseInvert(out);
01181     }
01182 
01184     VectorBase<typename CNT<ELT>::TInvert> elementwiseInvert() const {
01185         VectorBase<typename CNT<ELT>::TInvert> out(nrow());
01186         Base::elementwiseInvert(out);
01187         return out;
01188     }
01189 
01190         // elementwise multiply
01191     template <class EE> VectorBase& elementwiseMultiplyInPlace(const VectorBase<EE>& r)
01192       { Base::template elementwiseMultiplyInPlace<EE>(r); return *this; }
01193     template <class EE> inline void elementwiseMultiply(const VectorBase<EE>& v, typename EltResult<EE>::Mul& out) const
01194       { Base::template elementwiseMultiply<EE>(v,out); }
01195     template <class EE> inline typename EltResult<EE>::Mul elementwiseMultiply(const VectorBase<EE>& v) const
01196       { typename EltResult<EE>::Mul out(nrow()); Base::template elementwiseMultiply<EE>(v,out); return out; }
01197 
01198         // elementwise multiply from left
01199     template <class EE> VectorBase& elementwiseMultiplyFromLeftInPlace(const VectorBase<EE>& r)
01200       { Base::template elementwiseMultiplyFromLeftInPlace<EE>(r); return *this; }
01201     template <class EE> inline void 
01202     elementwiseMultiplyFromLeft(
01203         const VectorBase<EE>& v, 
01204         typename VectorBase<EE>::template EltResult<ELT>::Mul& out) const
01205     { 
01206         Base::template elementwiseMultiplyFromLeft<EE>(v,out);
01207     }
01208     template <class EE> inline typename VectorBase<EE>::template EltResult<ELT>::Mul 
01209     elementwiseMultiplyFromLeft(const VectorBase<EE>& v) const
01210     { 
01211         typename VectorBase<EE>::template EltResult<ELT>::Mul out(nrow()); 
01212         Base::template elementwiseMultiplyFromLeft<EE>(v,out); 
01213         return out;
01214     }
01215 
01216         // elementwise divide
01217     template <class EE> VectorBase& elementwiseDivideInPlace(const VectorBase<EE>& r)
01218       { Base::template elementwiseDivideInPlace<EE>(r); return *this; }
01219     template <class EE> inline void elementwiseDivide(const VectorBase<EE>& v, typename EltResult<EE>::Dvd& out) const
01220       { Base::template elementwiseDivide<EE>(v,out); }
01221     template <class EE> inline typename EltResult<EE>::Dvd elementwiseDivide(const VectorBase<EE>& v) const
01222       { typename EltResult<EE>::Dvd out(nrow()); Base::template elementwiseDivide<EE>(v,out); return out; }
01223 
01224         // elementwise divide from left
01225     template <class EE> VectorBase& elementwiseDivideFromLeftInPlace(const VectorBase<EE>& r)
01226       { Base::template elementwiseDivideFromLeftInPlace<EE>(r); return *this; }
01227     template <class EE> inline void 
01228     elementwiseDivideFromLeft(
01229         const VectorBase<EE>& v, 
01230         typename VectorBase<EE>::template EltResult<ELT>::Dvd& out) const
01231     { 
01232         Base::template elementwiseDivideFromLeft<EE>(v,out);
01233     }
01234     template <class EE> inline typename VectorBase<EE>::template EltResult<ELT>::Dvd 
01235     elementwiseDivideFromLeft(const VectorBase<EE>& v) const
01236     { 
01237         typename VectorBase<EE>::template EltResult<ELT>::Dvd out(nrow()); 
01238         Base::template elementwiseDivideFromLeft<EE>(v,out); 
01239         return out;
01240     }
01241 
01242     // Implicit conversions are allowed to Vector or Matrix, but not to RowVector.   
01243     operator const Vector_<ELT>&()     const { return *reinterpret_cast<const Vector_<ELT>*>(this); }
01244     operator       Vector_<ELT>&()           { return *reinterpret_cast<      Vector_<ELT>*>(this); }
01245     operator const VectorView_<ELT>&() const { return *reinterpret_cast<const VectorView_<ELT>*>(this); }
01246     operator       VectorView_<ELT>&()       { return *reinterpret_cast<      VectorView_<ELT>*>(this); }
01247     
01248     operator const Matrix_<ELT>&()     const { return *reinterpret_cast<const Matrix_<ELT>*>(this); }
01249     operator       Matrix_<ELT>&()           { return *reinterpret_cast<      Matrix_<ELT>*>(this); } 
01250     operator const MatrixView_<ELT>&() const { return *reinterpret_cast<const MatrixView_<ELT>*>(this); }
01251     operator       MatrixView_<ELT>&()       { return *reinterpret_cast<      MatrixView_<ELT>*>(this); } 
01252 
01253 
01254     // size() for Vectors is Base::nelt() but returns int instead of ptrdiff_t.
01255     int size() const { 
01256         assert(Base::nelt() <= (ptrdiff_t)std::numeric_limits<int>::max()); 
01257         assert(Base::ncol()==1);
01258         return (int)Base::nelt();
01259     }
01260     int       nrow() const {assert(Base::ncol()==1); return Base::nrow();}
01261     int       ncol() const {assert(Base::ncol()==1); return Base::ncol();}
01262     ptrdiff_t nelt() const {assert(Base::ncol()==1); return Base::nelt();}
01263 
01264     // Override MatrixBase operators to return the right shape
01265     TAbs abs() const {TAbs result; Base::abs(result); return result;}
01266     
01267     // Override MatrixBase indexing operators          
01268     const ELT& operator[](int i) const {return *reinterpret_cast<const ELT*>(Base::getHelper().getElt(i));}
01269     ELT&       operator[](int i)       {return *reinterpret_cast<ELT*>      (Base::updHelper().updElt(i));}
01270     const ELT& operator()(int i) const {return *reinterpret_cast<const ELT*>(Base::getHelper().getElt(i));}
01271     ELT&       operator()(int i)       {return *reinterpret_cast<ELT*>      (Base::updHelper().updElt(i));}
01272          
01273     // Block (contiguous subvector) view creation      
01274     VectorView_<ELT> operator()(int i, int m) const {return Base::operator()(i,0,m,1).getAsVectorView();}
01275     VectorView_<ELT> operator()(int i, int m)       {return Base::operator()(i,0,m,1).updAsVectorView();}
01276 
01277     // Indexed view creation (arbitrary subvector). Indices must be monotonically increasing.
01278     VectorView_<ELT> index(const Array_<int>& indices) const {
01279         MatrixHelper<Scalar> h(Base::getHelper().getCharacterCommitment(), Base::getHelper(), indices);
01280         return VectorView_<ELT>(h);
01281     }
01282     VectorView_<ELT> updIndex(const Array_<int>& indices) {
01283         MatrixHelper<Scalar> h(Base::getHelper().getCharacterCommitment(), Base::updHelper(), indices);
01284         return VectorView_<ELT>(h);
01285     }
01286 
01287     VectorView_<ELT> operator()(const Array_<int>& indices) const {return index(indices);}
01288     VectorView_<ELT> operator()(const Array_<int>& indices)       {return updIndex(indices);}
01289  
01290     // Hermitian transpose.
01291     THerm transpose() const {return Base::transpose().getAsRowVectorView();}
01292     THerm updTranspose()    {return Base::updTranspose().updAsRowVectorView();}
01293 
01294     THerm operator~() const {return transpose();}
01295     THerm operator~()       {return updTranspose();}
01296 
01297     const VectorBase& operator+() const {return *this; }
01298 
01299     // Negation
01300 
01301     const TNeg& negate()    const {return *reinterpret_cast<const TNeg*>(this); }
01302     TNeg&       updNegate()       {return *reinterpret_cast<TNeg*>(this); }
01303 
01304     const TNeg& operator-() const {return negate();}
01305     TNeg&       operator-()       {return updNegate();}
01306 
01307     VectorBase& resize(int m)     {Base::resize(m,1); return *this;}
01308     VectorBase& resizeKeep(int m) {Base::resizeKeep(m,1); return *this;}
01309 
01310     //TODO: this is not re-locking the number of columns at 1.
01311     void clear() {Base::clear(); Base::resize(0,1);}
01312 
01313     ELT sum() const {ELT s; Base::getHelper().sum(reinterpret_cast<Scalar*>(&s)); return s; } // add all the elements        
01314     VectorIterator<ELT, VectorBase<ELT> > begin() {
01315         return VectorIterator<ELT, VectorBase<ELT> >(*this, 0);
01316     }
01317     VectorIterator<ELT, VectorBase<ELT> > end() {
01318         return VectorIterator<ELT, VectorBase<ELT> >(*this, size());
01319     }
01320 
01321 protected:
01322     // Create a VectorBase handle using a given helper rep. 
01323     explicit VectorBase(MatrixHelperRep<Scalar>* hrep) : Base(hrep) {}
01324 
01325 private:
01326     // NO DATA MEMBERS ALLOWED
01327 };
01328 
01329 
01330 
01331 //  ------------------------------- RowVectorBase ------------------------------
01335 //  ----------------------------------------------------------------------------
01336 template <class ELT> class RowVectorBase : public MatrixBase<ELT> {
01337     typedef MatrixBase<ELT>                             Base;
01338     typedef typename CNT<ELT>::Scalar                   Scalar;
01339     typedef typename CNT<ELT>::Number                   Number;
01340     typedef typename CNT<ELT>::StdNumber                StdNumber;
01341     typedef RowVectorBase<ELT>                          T;
01342     typedef RowVectorBase<typename CNT<ELT>::TAbs>      TAbs;
01343     typedef RowVectorBase<typename CNT<ELT>::TNeg>      TNeg;
01344     typedef VectorView_<typename CNT<ELT>::THerm>       THerm;
01345 public: 
01346     //  ------------------------------------------------------------------------
01356 
01359     explicit RowVectorBase(int n=0) : Base(MatrixCommitment::RowVector(), 1, n) {}
01360     
01364     RowVectorBase(const RowVectorBase& source) : Base(source) {}
01365 
01367     RowVectorBase(const TNeg& source) : Base(source) {}
01368 
01371     RowVectorBase(int n, const ELT& initialValue)
01372     :   Base(MatrixCommitment::RowVector(),1,n,initialValue) {}  
01373 
01378     RowVectorBase(int n, const ELT* cppInitialValues)
01379     :   Base(MatrixCommitment::RowVector(),1,n,cppInitialValues) {}
01381 
01382     //  ------------------------------------------------------------------------
01391 
01393     RowVectorBase(int n, int stride, const Scalar* s)
01394     :   Base(MatrixCommitment::RowVector(n), MatrixCharacter::RowVector(n),stride,s) { }
01396     RowVectorBase(int n, int stride, Scalar* s)
01397     :   Base(MatrixCommitment::RowVector(n), MatrixCharacter::RowVector(n),stride,s) { }
01399 
01400     //  ------------------------------------------------------------------------
01407 
01409     RowVectorBase(MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::ShallowCopy& s) 
01410     :   Base(MatrixCommitment::RowVector(), h,s) { }
01412     RowVectorBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::ShallowCopy& s) 
01413     :   Base(MatrixCommitment::RowVector(), h,s) { }
01415     RowVectorBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::DeepCopy& d)    
01416     :   Base(MatrixCommitment::RowVector(), h,d) { }
01418 
01419     // This gives the resulting rowvector type when (r(i) op P) is applied to each element.
01420     // It will have element types which are the regular composite result of ELT op P.
01421     template <class P> struct EltResult { 
01422         typedef RowVectorBase<typename CNT<ELT>::template Result<P>::Mul> Mul;
01423         typedef RowVectorBase<typename CNT<ELT>::template Result<P>::Dvd> Dvd;
01424         typedef RowVectorBase<typename CNT<ELT>::template Result<P>::Add> Add;
01425         typedef RowVectorBase<typename CNT<ELT>::template Result<P>::Sub> Sub;
01426     };
01427 
01430     RowVectorBase& operator=(const RowVectorBase& b) {
01431         Base::operator=(b); return *this;
01432     }
01433 
01434     // default destructor
01435 
01436     RowVectorBase& operator*=(const StdNumber& t)     {Base::operator*=(t); return *this;}
01437     RowVectorBase& operator/=(const StdNumber& t)     {Base::operator/=(t); return *this;}
01438     RowVectorBase& operator+=(const RowVectorBase& r) {Base::operator+=(r); return *this;}
01439     RowVectorBase& operator-=(const RowVectorBase& r) {Base::operator-=(r); return *this;}  
01440 
01441     template <class EE> RowVectorBase& operator=(const RowVectorBase<EE>& b) 
01442       { Base::operator=(b);  return *this; } 
01443     template <class EE> RowVectorBase& operator+=(const RowVectorBase<EE>& b) 
01444       { Base::operator+=(b); return *this; } 
01445     template <class EE> RowVectorBase& operator-=(const RowVectorBase<EE>& b) 
01446       { Base::operator-=(b); return *this; } 
01447 
01448     // default destructor
01449  
01453     RowVectorBase& operator=(const ELT& t) { Base::setTo(t); return *this; } 
01454 
01459     template <class EE> RowVectorBase& colScaleInPlace(const VectorBase<EE>& v)
01460       { Base::template colScaleInPlace<EE>(v); return *this; }
01461     template <class EE> inline void colScale(const VectorBase<EE>& v, typename EltResult<EE>::Mul& out) const
01462       { return Base::template colScale<EE>(v,out); }
01463     template <class EE> inline typename EltResult<EE>::Mul colScale(const VectorBase<EE>& v) const
01464       { typename EltResult<EE>::Mul out(ncol()); Base::template colScale<EE>(v,out); return out; }
01465 
01466 
01467         // elementwise multiply
01468     template <class EE> RowVectorBase& elementwiseMultiplyInPlace(const RowVectorBase<EE>& r)
01469       { Base::template elementwiseMultiplyInPlace<EE>(r); return *this; }
01470     template <class EE> inline void elementwiseMultiply(const RowVectorBase<EE>& v, typename EltResult<EE>::Mul& out) const
01471       { Base::template elementwiseMultiply<EE>(v,out); }
01472     template <class EE> inline typename EltResult<EE>::Mul elementwiseMultiply(const RowVectorBase<EE>& v) const
01473       { typename EltResult<EE>::Mul out(nrow()); Base::template elementwiseMultiply<EE>(v,out); return out; }
01474 
01475         // elementwise multiply from left
01476     template <class EE> RowVectorBase& elementwiseMultiplyFromLeftInPlace(const RowVectorBase<EE>& r)
01477       { Base::template elementwiseMultiplyFromLeftInPlace<EE>(r); return *this; }
01478     template <class EE> inline void 
01479     elementwiseMultiplyFromLeft(
01480         const RowVectorBase<EE>& v, 
01481         typename RowVectorBase<EE>::template EltResult<ELT>::Mul& out) const
01482     { 
01483         Base::template elementwiseMultiplyFromLeft<EE>(v,out);
01484     }
01485     template <class EE> inline typename RowVectorBase<EE>::template EltResult<ELT>::Mul 
01486     elementwiseMultiplyFromLeft(const RowVectorBase<EE>& v) const
01487     { 
01488         typename RowVectorBase<EE>::template EltResult<ELT>::Mul out(nrow()); 
01489         Base::template elementwiseMultiplyFromLeft<EE>(v,out); 
01490         return out;
01491     }
01492 
01493         // elementwise divide
01494     template <class EE> RowVectorBase& elementwiseDivideInPlace(const RowVectorBase<EE>& r)
01495       { Base::template elementwiseDivideInPlace<EE>(r); return *this; }
01496     template <class EE> inline void elementwiseDivide(const RowVectorBase<EE>& v, typename EltResult<EE>::Dvd& out) const
01497       { Base::template elementwiseDivide<EE>(v,out); }
01498     template <class EE> inline typename EltResult<EE>::Dvd elementwiseDivide(const RowVectorBase<EE>& v) const
01499       { typename EltResult<EE>::Dvd out(nrow()); Base::template elementwiseDivide<EE>(v,out); return out; }
01500 
01501         // elementwise divide from left
01502     template <class EE> RowVectorBase& elementwiseDivideFromLeftInPlace(const RowVectorBase<EE>& r)
01503       { Base::template elementwiseDivideFromLeftInPlace<EE>(r); return *this; }
01504     template <class EE> inline void 
01505     elementwiseDivideFromLeft(
01506         const RowVectorBase<EE>& v, 
01507         typename RowVectorBase<EE>::template EltResult<ELT>::Dvd& out) const
01508     { 
01509         Base::template elementwiseDivideFromLeft<EE>(v,out);
01510     }
01511     template <class EE> inline typename RowVectorBase<EE>::template EltResult<ELT>::Dvd 
01512     elementwiseDivideFromLeft(const RowVectorBase<EE>& v) const
01513     { 
01514         typename RowVectorBase<EE>::template EltResult<ELT>::Dvd out(nrow()); 
01515         Base::template elementwiseDivideFromLeft<EE>(v,out); 
01516         return out;
01517     }
01518 
01519     // Implicit conversions are allowed to RowVector or Matrix, but not to Vector.   
01520     operator const RowVector_<ELT>&()     const {return *reinterpret_cast<const RowVector_<ELT>*>(this);}
01521     operator       RowVector_<ELT>&()           {return *reinterpret_cast<      RowVector_<ELT>*>(this);}
01522     operator const RowVectorView_<ELT>&() const {return *reinterpret_cast<const RowVectorView_<ELT>*>(this);}
01523     operator       RowVectorView_<ELT>&()       {return *reinterpret_cast<      RowVectorView_<ELT>*>(this);}
01524     
01525     operator const Matrix_<ELT>&()     const {return *reinterpret_cast<const Matrix_<ELT>*>(this);}
01526     operator       Matrix_<ELT>&()           {return *reinterpret_cast<      Matrix_<ELT>*>(this);} 
01527     operator const MatrixView_<ELT>&() const {return *reinterpret_cast<const MatrixView_<ELT>*>(this);}
01528     operator       MatrixView_<ELT>&()       {return *reinterpret_cast<      MatrixView_<ELT>*>(this);} 
01529     
01530 
01531     // size() for RowVectors is Base::nelt() but returns int instead of ptrdiff_t.
01532     int size() const { 
01533         assert(Base::nelt() <= (ptrdiff_t)std::numeric_limits<int>::max()); 
01534         assert(Base::nrow()==1);
01535         return (int)Base::nelt();
01536     }
01537     int       nrow() const {assert(Base::nrow()==1); return Base::nrow();}
01538     int       ncol() const {assert(Base::nrow()==1); return Base::ncol();}
01539     ptrdiff_t nelt() const {assert(Base::nrow()==1); return Base::nelt();}
01540 
01541     // Override MatrixBase operators to return the right shape
01542     TAbs abs() const {
01543         TAbs result; Base::abs(result); return result;
01544     }
01545 
01546     // Override MatrixBase indexing operators          
01547     const ELT& operator[](int j) const {return *reinterpret_cast<const ELT*>(Base::getHelper().getElt(j));}
01548     ELT&       operator[](int j)       {return *reinterpret_cast<ELT*>      (Base::updHelper().updElt(j));}
01549     const ELT& operator()(int j) const {return *reinterpret_cast<const ELT*>(Base::getHelper().getElt(j));}
01550     ELT&       operator()(int j)       {return *reinterpret_cast<ELT*>      (Base::updHelper().updElt(j));}
01551          
01552     // Block (contiguous subvector) creation      
01553     RowVectorView_<ELT> operator()(int j, int n) const {return Base::operator()(0,j,1,n).getAsRowVectorView();}
01554     RowVectorView_<ELT> operator()(int j, int n)       {return Base::operator()(0,j,1,n).updAsRowVectorView();}
01555 
01556     // Indexed view creation (arbitrary subvector). Indices must be monotonically increasing.
01557     RowVectorView_<ELT> index(const Array_<int>& indices) const {
01558         MatrixHelper<Scalar> h(Base::getHelper().getCharacterCommitment(), Base::getHelper(), indices);
01559         return RowVectorView_<ELT>(h);
01560     }
01561     RowVectorView_<ELT> updIndex(const Array_<int>& indices) {
01562         MatrixHelper<Scalar> h(Base::getHelper().getCharacterCommitment(), Base::updHelper(), indices);
01563         return RowVectorView_<ELT>(h);
01564     }
01565 
01566     RowVectorView_<ELT> operator()(const Array_<int>& indices) const {return index(indices);}
01567     RowVectorView_<ELT> operator()(const Array_<int>& indices)       {return updIndex(indices);}
01568  
01569     // Hermitian transpose.
01570     THerm transpose() const {return Base::transpose().getAsVectorView();}
01571     THerm updTranspose()    {return Base::updTranspose().updAsVectorView();}
01572 
01573     THerm operator~() const {return transpose();}
01574     THerm operator~()       {return updTranspose();}
01575 
01576     const RowVectorBase& operator+() const {return *this; }
01577 
01578     // Negation
01579 
01580     const TNeg& negate()    const {return *reinterpret_cast<const TNeg*>(this); }
01581     TNeg&       updNegate()       {return *reinterpret_cast<TNeg*>(this); }
01582 
01583     const TNeg& operator-() const {return negate();}
01584     TNeg&       operator-()       {return updNegate();}
01585 
01586     RowVectorBase& resize(int n)     {Base::resize(1,n); return *this;}
01587     RowVectorBase& resizeKeep(int n) {Base::resizeKeep(1,n); return *this;}
01588 
01589     //TODO: this is not re-locking the number of rows at 1.
01590     void clear() {Base::clear(); Base::resize(1,0);}
01591 
01592     ELT sum() const {ELT s; Base::getHelper().sum(reinterpret_cast<Scalar*>(&s)); return s; } // add all the elements        
01593     VectorIterator<ELT, RowVectorBase<ELT> > begin() {
01594         return VectorIterator<ELT, RowVectorBase<ELT> >(*this, 0);
01595     }
01596     VectorIterator<ELT, RowVectorBase<ELT> > end() {
01597         return VectorIterator<ELT, RowVectorBase<ELT> >(*this, size());
01598     }
01599 
01600 protected:
01601     // Create a RowVectorBase handle using a given helper rep. 
01602     explicit RowVectorBase(MatrixHelperRep<Scalar>* hrep) : Base(hrep) {}
01603 
01604 private:
01605     // NO DATA MEMBERS ALLOWED
01606 };
01607 
01608 
01609 
01610 //  ------------------------------- MatrixView_ --------------------------------
01616 //  ----------------------------------------------------------------------------
01617 template <class ELT> class MatrixView_ : public MatrixBase<ELT> {
01618     typedef MatrixBase<ELT>                 Base;
01619     typedef typename CNT<ELT>::Scalar       S;
01620     typedef typename CNT<ELT>::StdNumber    StdNumber;
01621 public:
01622     // Default construction is suppressed.
01623     // Uses default destructor.
01624 
01625     // Create a MatrixView_ handle using a given helper rep. 
01626     explicit MatrixView_(MatrixHelperRep<S>* hrep) : Base(hrep) {}
01627 
01628     // Copy constructor is shallow. CAUTION: despite const argument, this preserves writability
01629     // if it was present in the source. This is necessary to allow temporary views to be
01630     // created and used as lvalues.
01631     MatrixView_(const MatrixView_& m) 
01632       : Base(MatrixCommitment(),
01633              const_cast<MatrixHelper<S>&>(m.getHelper()), 
01634              typename MatrixHelper<S>::ShallowCopy()) {}
01635 
01636     // Copy assignment is deep but not reallocating.
01637     MatrixView_& operator=(const MatrixView_& m) {
01638         Base::operator=(m); return *this;
01639     }
01640 
01641     // Copy construction and copy assignment from a DeadMatrixView steals the helper.
01642     MatrixView_(DeadMatrixView_<ELT>&);
01643     MatrixView_& operator=(DeadMatrixView_<ELT>&);
01644 
01645     // Ask for shallow copy    
01646     MatrixView_(const MatrixHelper<S>& h) : Base(MatrixCommitment(), h, typename MatrixHelper<S>::ShallowCopy()) { }
01647     MatrixView_(MatrixHelper<S>&       h) : Base(MatrixCommitment(), h, typename MatrixHelper<S>::ShallowCopy()) { }
01648 
01649     MatrixView_& operator=(const Matrix_<ELT>& v)     { Base::operator=(v); return *this; }
01650     MatrixView_& operator=(const ELT& e)              { Base::operator=(e); return *this; }
01651 
01652     template <class EE> MatrixView_& operator=(const MatrixBase<EE>& m)
01653       { Base::operator=(m); return *this; }
01654     template <class EE> MatrixView_& operator+=(const MatrixBase<EE>& m)
01655       { Base::operator+=(m); return *this; }
01656     template <class EE> MatrixView_& operator-=(const MatrixBase<EE>& m)
01657       { Base::operator-=(m); return *this; }
01658 
01659     MatrixView_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
01660     MatrixView_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
01661     MatrixView_& operator+=(const ELT& r)       { this->updDiag() += r; return *this; }
01662     MatrixView_& operator-=(const ELT& r)       { this->updDiag() -= r; return *this; }  
01663 
01664     operator const Matrix_<ELT>&() const { return *reinterpret_cast<const Matrix_<ELT>*>(this); }
01665     operator Matrix_<ELT>&()             { return *reinterpret_cast<Matrix_<ELT>*>(this); }      
01666 
01667 private:
01668     // NO DATA MEMBERS ALLOWED
01669     MatrixView_(); // default constructor suppressed (what's it a view of?)
01670 };
01671 
01672 
01673 
01674 //  ----------------------------- DeadMatrixView_ ------------------------------
01678 //  ----------------------------------------------------------------------------
01679 template <class ELT> class DeadMatrixView_ : public MatrixView_<ELT> {
01680     typedef MatrixView_<ELT>                Base;
01681     typedef typename CNT<ELT>::Scalar       S;
01682     typedef typename CNT<ELT>::StdNumber    StdNumber;
01683 public:
01684     // Default construction is suppressed.
01685     // Uses default destructor.
01686     
01687     // All functionality is passed through to MatrixView_.
01688     explicit DeadMatrixView_(MatrixHelperRep<S>* hrep) : Base(hrep) {}
01689     DeadMatrixView_(const Base& m) : Base(m) {}
01690     DeadMatrixView_& operator=(const Base& m) {
01691         Base::operator=(m); return *this;
01692     }
01693 
01694     // Ask for shallow copy    
01695     DeadMatrixView_(const MatrixHelper<S>& h) : Base(h) {}
01696     DeadMatrixView_(MatrixHelper<S>&       h) : Base(h) {}
01697 
01698     DeadMatrixView_& operator=(const Matrix_<ELT>& v)     { Base::operator=(v); return *this; }
01699     DeadMatrixView_& operator=(const ELT& e)              { Base::operator=(e); return *this; }
01700 
01701     template <class EE> DeadMatrixView_& operator=(const MatrixBase<EE>& m)
01702       { Base::operator=(m); return *this; }
01703     template <class EE> DeadMatrixView_& operator+=(const MatrixBase<EE>& m)
01704       { Base::operator+=(m); return *this; }
01705     template <class EE> DeadMatrixView_& operator-=(const MatrixBase<EE>& m)
01706       { Base::operator-=(m); return *this; }
01707 
01708     DeadMatrixView_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
01709     DeadMatrixView_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
01710     DeadMatrixView_& operator+=(const ELT& r)       { this->updDiag() += r; return *this; }
01711     DeadMatrixView_& operator-=(const ELT& r)       { this->updDiag() -= r; return *this; }  
01712 
01713 private:
01714     // NO DATA MEMBERS ALLOWED
01715     DeadMatrixView_(); // default constructor suppressed (what's it a view of?)
01716 };
01717 
01718 template <class ELT> inline 
01719 MatrixView_<ELT>::MatrixView_(DeadMatrixView_<ELT>& dead) 
01720 :   Base(dead.updHelper().stealRep()) {}
01721 
01722 template <class ELT> inline MatrixView_<ELT>& 
01723 MatrixView_<ELT>::operator=(DeadMatrixView_<ELT>& dead) {
01724     if (Base::getHelper().getCharacterCommitment().isSatisfiedBy(dead.getMatrixCharacter()))
01725         Base::updHelper().replaceRep(dead.updHelper().stealRep());
01726     else
01727         Base::operator=(dead);
01728     return *this;
01729 }
01730 
01731 
01732 //  ---------------------------------- Matrix_ ---------------------------------
01735 //  ----------------------------------------------------------------------------
01736 template <class ELT> class Matrix_ : public MatrixBase<ELT> {
01737     typedef typename CNT<ELT>::Scalar       S;
01738     typedef typename CNT<ELT>::Number       Number;
01739     typedef typename CNT<ELT>::StdNumber    StdNumber;
01740 
01741     typedef typename CNT<ELT>::TNeg         ENeg;
01742     typedef typename CNT<ELT>::THerm        EHerm;
01743 
01744     typedef MatrixBase<ELT>     Base;
01745     typedef MatrixBase<ENeg>    BaseNeg;
01746     typedef MatrixBase<EHerm>   BaseHerm;
01747 
01748     typedef Matrix_<ELT>        T;
01749     typedef MatrixView_<ELT>    TView;
01750     typedef Matrix_<ENeg>       TNeg;
01751 
01752 public:
01753     Matrix_() : Base() { }
01754     Matrix_(const MatrixCommitment& mc) : Base(mc) {}
01755 
01756     // Copy constructor is deep.
01757     Matrix_(const Matrix_& src) : Base(src) { }
01758 
01759     // Assignment is a deep copy and will also allow reallocation if this Matrix
01760     // doesn't have a view.
01761     Matrix_& operator=(const Matrix_& src) { 
01762         Base::operator=(src); return *this;
01763     }
01764 
01765     // Force a deep copy of the view or whatever this is.
01766     // Note that this is an implicit conversion.
01767     Matrix_(const Base& v) : Base(v) {}   // e.g., MatrixView
01768 
01769     // Allow implicit conversion from a source matrix that
01770     // has a negated version of ELT.
01771     Matrix_(const BaseNeg& v) : Base(v) {}
01772 
01773     // TODO: implicit conversion from conjugate. This is trickier
01774     // since real elements are their own conjugate so you'll get
01775     // duplicate methods defined from Matrix_(BaseHerm) and Matrix_(Base).
01776 
01777     Matrix_(int m, int n) : Base(MatrixCommitment(), m, n) {}
01778 
01779     Matrix_(int m, int n, const ELT* cppInitialValuesByRow) 
01780     :   Base(MatrixCommitment(), m, n, cppInitialValuesByRow) {}
01781     Matrix_(int m, int n, const ELT& initialValue) 
01782     :   Base(MatrixCommitment(), m, n, initialValue) {}
01783     
01784     Matrix_(int m, int n, int leadingDim, const S* data) // read only
01785     :   Base(MatrixCommitment(), MatrixCharacter::LapackFull(m,n), 
01786              leadingDim, data) {}
01787     Matrix_(int m, int n, int leadingDim, S* data) // writable
01788     :   Base(MatrixCommitment(), MatrixCharacter::LapackFull(m,n), 
01789              leadingDim, data) {}
01790     
01792     template <int M, int N, int CS, int RS>
01793     explicit Matrix_(const Mat<M,N,ELT,CS,RS>& mat)
01794     :   Base(MatrixCommitment(), M, N)
01795     {   for (int i = 0; i < M; ++i)
01796             for (int j = 0; j < N; ++j)
01797                 this->updElt(i, j) = mat(i, j); }
01798 
01799     Matrix_& operator=(const ELT& v) { Base::operator=(v); return *this; }
01800 
01801     template <class EE> Matrix_& operator=(const MatrixBase<EE>& m)
01802       { Base::operator=(m); return*this; }
01803     template <class EE> Matrix_& operator+=(const MatrixBase<EE>& m)
01804       { Base::operator+=(m); return*this; }
01805     template <class EE> Matrix_& operator-=(const MatrixBase<EE>& m)
01806       { Base::operator-=(m); return*this; }
01807 
01808     Matrix_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
01809     Matrix_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
01810     Matrix_& operator+=(const ELT& r)       { this->updDiag() += r; return *this; }
01811     Matrix_& operator-=(const ELT& r)       { this->updDiag() -= r; return *this; }  
01812 
01813     const TNeg& negate()    const {return *reinterpret_cast<const TNeg*>(this); }
01814     TNeg&       updNegate()       {return *reinterpret_cast<TNeg*>(this); }
01815 
01816     const TNeg& operator-() const {return negate();}
01817     TNeg&       operator-()       {return updNegate();}
01818    
01819 private:
01820     // NO DATA MEMBERS ALLOWED
01821 };
01822 
01823 
01824 
01825 //  -------------------------------- VectorView_ -------------------------------
01831 //  ----------------------------------------------------------------------------
01832 template <class ELT> class VectorView_ : public VectorBase<ELT> {
01833     typedef VectorBase<ELT>                             Base;
01834     typedef typename CNT<ELT>::Scalar                   S;
01835     typedef typename CNT<ELT>::Number                   Number;
01836     typedef typename CNT<ELT>::StdNumber                StdNumber;
01837     typedef VectorView_<ELT>                            T;
01838     typedef VectorView_< typename CNT<ELT>::TNeg >      TNeg;
01839     typedef RowVectorView_< typename CNT<ELT>::THerm >  THerm;
01840 public:
01841     // Default construction is suppressed.
01842     // Uses default destructor.
01843 
01844     // Create a VectorView_ handle using a given helper rep. 
01845     explicit VectorView_(MatrixHelperRep<S>* hrep) : Base(hrep) {}
01846 
01847     // Copy constructor is shallow. CAUTION: despite const argument, this preserves writability
01848     // if it was present in the source. This is necessary to allow temporary views to be
01849     // created and used as lvalues.
01850     VectorView_(const VectorView_& v) 
01851       : Base(const_cast<MatrixHelper<S>&>(v.getHelper()), typename MatrixHelper<S>::ShallowCopy()) { }
01852 
01853     // Copy assignment is deep but not reallocating.
01854     VectorView_& operator=(const VectorView_& v) {
01855         Base::operator=(v); return *this;
01856     }
01857 
01858     // Ask for shallow copy    
01859     explicit VectorView_(const MatrixHelper<S>& h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
01860     explicit VectorView_(MatrixHelper<S>&       h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
01861     
01862     VectorView_& operator=(const Base& b) { Base::operator=(b); return *this; }
01863 
01864     VectorView_& operator=(const ELT& v) { Base::operator=(v); return *this; } 
01865 
01866     template <class EE> VectorView_& operator=(const VectorBase<EE>& m)
01867       { Base::operator=(m); return*this; }
01868     template <class EE> VectorView_& operator+=(const VectorBase<EE>& m)
01869       { Base::operator+=(m); return*this; }
01870     template <class EE> VectorView_& operator-=(const VectorBase<EE>& m)
01871       { Base::operator-=(m); return*this; }
01872 
01873     VectorView_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
01874     VectorView_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
01875     VectorView_& operator+=(const ELT& b) { elementwiseAddScalarInPlace(b); return *this; } 
01876     VectorView_& operator-=(const ELT& b) { elementwiseSubtractScalarInPlace(b); return *this; } 
01877 
01878 private:
01879     // NO DATA MEMBERS ALLOWED
01880     VectorView_(); // default construction suppressed (what's it a View of?)
01881 };
01882 
01883 
01884 
01885 //  ---------------------------------- Vector_ ---------------------------------
01889 //  ----------------------------------------------------------------------------
01890 template <class ELT> class Vector_ : public VectorBase<ELT> {
01891     typedef typename CNT<ELT>::Scalar       S;
01892     typedef typename CNT<ELT>::Number       Number;
01893     typedef typename CNT<ELT>::StdNumber    StdNumber;
01894     typedef typename CNT<ELT>::TNeg         ENeg;
01895     typedef VectorBase<ELT>                 Base;
01896     typedef VectorBase<ENeg>                BaseNeg;
01897 public:
01898     Vector_() : Base() {}  // 0x1 reallocatable
01899     // Uses default destructor.
01900 
01901     // Copy constructor is deep.
01902     Vector_(const Vector_& src) : Base(src) {}
01903 
01904     // Implicit conversions.
01905     Vector_(const Base& src) : Base(src) {}    // e.g., VectorView
01906     Vector_(const BaseNeg& src) : Base(src) {}
01907 
01908     // Copy assignment is deep and can be reallocating if this Vector
01909     // has no View.
01910     Vector_& operator=(const Vector_& src) {
01911         Base::operator=(src); return*this;
01912     }
01913 
01914 
01915     explicit Vector_(int m) : Base(m) { }
01916     Vector_(int m, const ELT* cppInitialValues) : Base(m, cppInitialValues) {}
01917     Vector_(int m, const ELT& initialValue)     : Base(m, initialValue) {}
01918 
01923     Vector_(int m, const S* cppData, bool): Base(m, Base::CppNScalarsPerElement, cppData) {}
01924     Vector_(int m,       S* cppData, bool): Base(m, Base::CppNScalarsPerElement, cppData) {}
01925 
01929     Vector_(int m, int stride, const S* data, bool) : Base(m, stride, data) {}
01930     Vector_(int m, int stride,       S* data, bool) : Base(m, stride, data) {}
01931 
01933     template <int M>
01934     explicit Vector_(const Vec<M,ELT>& v) : Base(M) {
01935         for (int i = 0; i < M; ++i)
01936             this->updElt(i, 0) = v(i);
01937     }
01938 
01939     Vector_& operator=(const ELT& v) { Base::operator=(v); return *this; } 
01940 
01941     template <class EE> Vector_& operator=(const VectorBase<EE>& m)
01942       { Base::operator=(m); return*this; }
01943     template <class EE> Vector_& operator+=(const VectorBase<EE>& m)
01944       { Base::operator+=(m); return*this; }
01945     template <class EE> Vector_& operator-=(const VectorBase<EE>& m)
01946       { Base::operator-=(m); return*this; }
01947 
01948     Vector_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
01949     Vector_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
01950     Vector_& operator+=(const ELT& b) { elementwiseAddScalarInPlace(b); return *this; } 
01951     Vector_& operator-=(const ELT& b) { elementwiseSubtractScalarInPlace(b); return *this; } 
01952  
01953 private:
01954     // NO DATA MEMBERS ALLOWED
01955 };
01956 
01957 
01958 
01959 //  ------------------------------ RowVectorView_ ------------------------------
01965 //  ----------------------------------------------------------------------------
01966 template <class ELT> class RowVectorView_ : public RowVectorBase<ELT> {
01967     typedef RowVectorBase<ELT>                              Base;
01968     typedef typename CNT<ELT>::Scalar                       S;
01969     typedef typename CNT<ELT>::Number                       Number;
01970     typedef typename CNT<ELT>::StdNumber                    StdNumber;
01971     typedef RowVectorView_<ELT>                             T;
01972     typedef RowVectorView_< typename CNT<ELT>::TNeg >       TNeg;
01973     typedef VectorView_< typename CNT<ELT>::THerm >         THerm;
01974 public:
01975     // Default construction is suppressed.
01976     // Uses default destructor.
01977 
01978     // Create a RowVectorView_ handle using a given helper rep. 
01979     explicit RowVectorView_(MatrixHelperRep<S>* hrep) : Base(hrep) {}
01980 
01981     // Copy constructor is shallow. CAUTION: despite const argument, this preserves writability
01982     // if it was present in the source. This is necessary to allow temporary views to be
01983     // created and used as lvalues.
01984     RowVectorView_(const RowVectorView_& r) 
01985       : Base(const_cast<MatrixHelper<S>&>(r.getHelper()), typename MatrixHelper<S>::ShallowCopy()) { }
01986 
01987     // Copy assignment is deep but not reallocating.
01988     RowVectorView_& operator=(const RowVectorView_& r) {
01989         Base::operator=(r); return *this;
01990     }
01991 
01992     // Ask for shallow copy    
01993     explicit RowVectorView_(const MatrixHelper<S>& h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
01994     explicit RowVectorView_(MatrixHelper<S>&       h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
01995     
01996     RowVectorView_& operator=(const Base& b) { Base::operator=(b); return *this; }
01997 
01998     RowVectorView_& operator=(const ELT& v) { Base::operator=(v); return *this; } 
01999 
02000     template <class EE> RowVectorView_& operator=(const RowVectorBase<EE>& m)
02001       { Base::operator=(m); return*this; }
02002     template <class EE> RowVectorView_& operator+=(const RowVectorBase<EE>& m)
02003       { Base::operator+=(m); return*this; }
02004     template <class EE> RowVectorView_& operator-=(const RowVectorBase<EE>& m)
02005       { Base::operator-=(m); return*this; }
02006 
02007     RowVectorView_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
02008     RowVectorView_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
02009     RowVectorView_& operator+=(const ELT& b) { elementwiseAddScalarInPlace(b); return *this; } 
02010     RowVectorView_& operator-=(const ELT& b) { elementwiseSubtractScalarInPlace(b); return *this; } 
02011 
02012 private:
02013     // NO DATA MEMBERS ALLOWED
02014     RowVectorView_(); // default construction suppressed (what is it a view of?)
02015 };
02016 
02017 
02018 
02019 //  -------------------------------- RowVector_ --------------------------------
02024 //  ----------------------------------------------------------------------------
02025 template <class ELT> class RowVector_ : public RowVectorBase<ELT> {
02026     typedef typename CNT<ELT>::Scalar       S;
02027     typedef typename CNT<ELT>::Number       Number;
02028     typedef typename CNT<ELT>::StdNumber    StdNumber;
02029     typedef typename CNT<ELT>::TNeg         ENeg;
02030 
02031     typedef RowVectorBase<ELT>              Base;
02032     typedef RowVectorBase<ENeg>             BaseNeg;
02033 public:
02034     RowVector_() : Base() {}   // 1x0 reallocatable
02035     // Uses default destructor.
02036 
02037     // Copy constructor is deep.
02038     RowVector_(const RowVector_& src) : Base(src) {}
02039 
02040     // Implicit conversions.
02041     RowVector_(const Base& src) : Base(src) {}    // e.g., RowVectorView
02042     RowVector_(const BaseNeg& src) : Base(src) {}  
02043 
02044     // Copy assignment is deep and can be reallocating if this RowVector
02045     // has no View.
02046     RowVector_& operator=(const RowVector_& src) {
02047         Base::operator=(src); return*this;
02048     }
02049 
02050 
02051     explicit RowVector_(int n) : Base(n) { }
02052     RowVector_(int n, const ELT* cppInitialValues) : Base(n, cppInitialValues) {}
02053     RowVector_(int n, const ELT& initialValue)     : Base(n, initialValue) {}
02054 
02059     RowVector_(int n, const S* cppData, bool): Base(n, Base::CppNScalarsPerElement, cppData) {}
02060     RowVector_(int n,       S* cppData, bool): Base(n, Base::CppNScalarsPerElement, cppData) {}
02061 
02065     RowVector_(int n, int stride, const S* data, bool) : Base(n, stride, data) {}
02066     RowVector_(int n, int stride,       S* data, bool) : Base(n, stride, data) {}
02067     
02069     template <int M>
02070     explicit RowVector_(const Row<M,ELT>& v) : Base(M) {
02071         for (int i = 0; i < M; ++i)
02072             this->updElt(0, i) = v(i);
02073     }
02074 
02075     RowVector_& operator=(const ELT& v) { Base::operator=(v); return *this; } 
02076 
02077     template <class EE> RowVector_& operator=(const RowVectorBase<EE>& b)
02078       { Base::operator=(b); return*this; }
02079     template <class EE> RowVector_& operator+=(const RowVectorBase<EE>& b)
02080       { Base::operator+=(b); return*this; }
02081     template <class EE> RowVector_& operator-=(const RowVectorBase<EE>& b)
02082       { Base::operator-=(b); return*this; }
02083 
02084     RowVector_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
02085     RowVector_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
02086     RowVector_& operator+=(const ELT& b) { elementwiseAddScalarInPlace(b); return *this; } 
02087     RowVector_& operator-=(const ELT& b) { elementwiseSubtractScalarInPlace(b); return *this; } 
02088 
02089 private:
02090     // NO DATA MEMBERS ALLOWED
02091 };
02092 
02093 
02094 
02095 //  ------------------------ MatrixBase definitions ----------------------------
02096 
02097 template <class ELT> inline MatrixView_<ELT> 
02098 MatrixBase<ELT>::block(int i, int j, int m, int n) const { 
02099     SimTK_INDEXCHECK(i,nrow()+1,"MatrixBase::block()");
02100     SimTK_INDEXCHECK(j,ncol()+1,"MatrixBase::block()");
02101     SimTK_SIZECHECK(i+m,nrow(),"MatrixBase::block()");
02102     SimTK_SIZECHECK(j+n,ncol(),"MatrixBase::block()");
02103 
02104     MatrixHelper<Scalar> h(MatrixCommitment(),helper,i,j,m,n);    
02105     return MatrixView_<ELT>(h.stealRep()); 
02106 }
02107     
02108 template <class ELT> inline MatrixView_<ELT>
02109 MatrixBase<ELT>::updBlock(int i, int j, int m, int n) { 
02110     SimTK_INDEXCHECK(i,nrow()+1,"MatrixBase::updBlock()");
02111     SimTK_INDEXCHECK(j,ncol()+1,"MatrixBase::updBlock()");
02112     SimTK_SIZECHECK(i+m,nrow(),"MatrixBase::updBlock()");
02113     SimTK_SIZECHECK(j+n,ncol(),"MatrixBase::updBlock()");
02114 
02115     MatrixHelper<Scalar> h(MatrixCommitment(),helper,i,j,m,n);        
02116     return MatrixView_<ELT>(h.stealRep()); 
02117 }
02118 
02119 template <class E> inline MatrixView_<typename CNT<E>::THerm>
02120 MatrixBase<E>::transpose() const { 
02121     MatrixHelper<typename CNT<Scalar>::THerm> 
02122         h(MatrixCommitment(),
02123           helper, typename MatrixHelper<typename CNT<Scalar>::THerm>::TransposeView());
02124     return MatrixView_<typename CNT<E>::THerm>(h.stealRep()); 
02125 }
02126     
02127 template <class E> inline MatrixView_<typename CNT<E>::THerm>
02128 MatrixBase<E>::updTranspose() {     
02129     MatrixHelper<typename CNT<Scalar>::THerm> 
02130         h(MatrixCommitment(),
02131           helper, typename MatrixHelper<typename CNT<Scalar>::THerm>::TransposeView());
02132     return MatrixView_<typename CNT<E>::THerm>(h.stealRep()); 
02133 }
02134 
02135 template <class E> inline VectorView_<E>
02136 MatrixBase<E>::diag() const { 
02137     MatrixHelper<Scalar> h(MatrixCommitment::Vector(),
02138                            helper, typename MatrixHelper<Scalar>::DiagonalView());
02139     return VectorView_<E>(h.stealRep()); 
02140 }
02141     
02142 template <class E> inline VectorView_<E>
02143 MatrixBase<E>::updDiag() {     
02144     MatrixHelper<Scalar> h(MatrixCommitment::Vector(),
02145                            helper, typename MatrixHelper<Scalar>::DiagonalView());
02146     return VectorView_<E>(h.stealRep());
02147 }
02148 
02149 template <class ELT> inline VectorView_<ELT> 
02150 MatrixBase<ELT>::col(int j) const { 
02151     SimTK_INDEXCHECK(j,ncol(),"MatrixBase::col()");
02152 
02153     MatrixHelper<Scalar> h(MatrixCommitment::Vector(),
02154                            helper,0,j,nrow(),1);    
02155     return VectorView_<ELT>(h.stealRep()); 
02156 }
02157     
02158 template <class ELT> inline VectorView_<ELT>
02159 MatrixBase<ELT>::updCol(int j) {
02160     SimTK_INDEXCHECK(j,ncol(),"MatrixBase::updCol()");
02161 
02162     MatrixHelper<Scalar> h(MatrixCommitment::Vector(),
02163                            helper,0,j,nrow(),1);        
02164     return VectorView_<ELT>(h.stealRep()); 
02165 }
02166 
02167 template <class ELT> inline RowVectorView_<ELT> 
02168 MatrixBase<ELT>::row(int i) const { 
02169     SimTK_INDEXCHECK(i,nrow(),"MatrixBase::row()");
02170 
02171     MatrixHelper<Scalar> h(MatrixCommitment::RowVector(),
02172                            helper,i,0,1,ncol());    
02173     return RowVectorView_<ELT>(h.stealRep()); 
02174 }
02175     
02176 template <class ELT> inline RowVectorView_<ELT>
02177 MatrixBase<ELT>::updRow(int i) { 
02178     SimTK_INDEXCHECK(i,nrow(),"MatrixBase::updRow()");
02179 
02180     MatrixHelper<Scalar> h(MatrixCommitment::RowVector(),
02181                            helper,i,0,1,ncol());        
02182     return RowVectorView_<ELT>(h.stealRep()); 
02183 }
02184 
02185 // M = diag(v) * M; v must have nrow() elements.
02186 // That is, M[i] *= v[i].
02187 template <class ELT> template <class EE> inline MatrixBase<ELT>& 
02188 MatrixBase<ELT>::rowScaleInPlace(const VectorBase<EE>& v) {
02189     assert(v.nrow() == nrow());
02190     for (int i=0; i < nrow(); ++i)
02191         (*this)[i] *= v[i];
02192     return *this;
02193 }
02194 
02195 template <class ELT> template <class EE> inline void
02196 MatrixBase<ELT>::rowScale(const VectorBase<EE>& v, typename MatrixBase<ELT>::template EltResult<EE>::Mul& out) const {
02197     assert(v.nrow() == nrow());
02198     out.resize(nrow(), ncol());
02199     for (int j=0; j<ncol(); ++j)
02200         for (int i=0; i<nrow(); ++i)
02201            out(i,j) = (*this)(i,j) * v[i];
02202 }
02203 
02204 // M = M * diag(v); v must have ncol() elements
02205 // That is, M(i) *= v[i]
02206 template <class ELT> template <class EE>  inline MatrixBase<ELT>& 
02207 MatrixBase<ELT>::colScaleInPlace(const VectorBase<EE>& v) {
02208     assert(v.nrow() == ncol());
02209     for (int j=0; j < ncol(); ++j)
02210         (*this)(j) *= v[j];
02211     return *this;
02212 }
02213 
02214 template <class ELT> template <class EE> inline void
02215 MatrixBase<ELT>::colScale(const VectorBase<EE>& v, typename MatrixBase<ELT>::template EltResult<EE>::Mul& out) const {
02216     assert(v.nrow() == ncol());
02217     out.resize(nrow(), ncol());
02218     for (int j=0; j<ncol(); ++j)
02219         for (int i=0; i<nrow(); ++i)
02220            out(i,j) = (*this)(i,j) * v[j];
02221 }
02222 
02223 
02224 // M(i,j) *= r[i]*c[j]; r must have nrow() elements; c must have ncol() elements
02225 template <class ELT> template <class ER, class EC> inline MatrixBase<ELT>& 
02226 MatrixBase<ELT>::rowAndColScaleInPlace(const VectorBase<ER>& r, const VectorBase<EC>& c) {
02227     assert(r.nrow()==nrow() && c.nrow()==ncol());
02228     for (int j=0; j<ncol(); ++j)
02229         for (int i=0; i<nrow(); ++i)
02230             (*this)(i,j) *= (r[i]*c[j]);
02231     return *this;
02232 }
02233 
02234 template <class ELT> template <class ER, class EC> inline void
02235 MatrixBase<ELT>::rowAndColScale(
02236     const VectorBase<ER>& r, 
02237     const VectorBase<EC>& c,
02238     typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul& 
02239                           out) const
02240 {
02241     assert(r.nrow()==nrow() && c.nrow()==ncol());
02242     out.resize(nrow(), ncol());
02243     for (int j=0; j<ncol(); ++j)
02244         for (int i=0; i<nrow(); ++i)
02245             out(i,j) = (*this)(i,j) * (r[i]*c[j]);
02246 }
02247 
02248 
02249 // Set M(i,j) = M(i,j)^-1.
02250 template <class ELT> inline MatrixBase<ELT>& 
02251 MatrixBase<ELT>::elementwiseInvertInPlace() {
02252     const int nr=nrow(), nc=ncol();
02253     for (int j=0; j<nc; ++j)
02254         for (int i=0; i<nr; ++i) {
02255             ELT& e = updElt(i,j);
02256             e = CNT<ELT>::invert(e);
02257         }
02258     return *this;
02259 }
02260 
02261 template <class ELT> inline void
02262 MatrixBase<ELT>::elementwiseInvert(MatrixBase<typename CNT<E>::TInvert>& out) const {
02263     const int nr=nrow(), nc=ncol();
02264     out.resize(nr,nc);
02265     for (int j=0; j<nc; ++j)
02266         for (int i=0; i<nr; ++i)
02267             out(i,j) = CNT<ELT>::invert((*this)(i,j));
02268 }
02269 
02270 // M(i,j) += s
02271 template <class ELT> template <class S> inline MatrixBase<ELT>& 
02272 MatrixBase<ELT>::elementwiseAddScalarInPlace(const S& s) {
02273     for (int j=0; j<ncol(); ++j)
02274         for (int i=0; i<nrow(); ++i)
02275             (*this)(i,j) += s;
02276     return *this;
02277 }
02278 
02279 template <class ELT> template <class S> inline void 
02280 MatrixBase<ELT>::elementwiseAddScalar(
02281     const S& s,
02282     typename MatrixBase<ELT>::template EltResult<S>::Add& out) const
02283 {
02284     const int nr=nrow(), nc=ncol();
02285     out.resize(nr,nc);
02286     for (int j=0; j<nc; ++j)
02287         for (int i=0; i<nr; ++i)
02288             out(i,j) = (*this)(i,j) + s;
02289 }
02290 
02291 // M(i,j) -= s
02292 template <class ELT> template <class S> inline MatrixBase<ELT>& 
02293 MatrixBase<ELT>::elementwiseSubtractScalarInPlace(const S& s) {
02294     for (int j=0; j<ncol(); ++j)
02295         for (int i=0; i<nrow(); ++i)
02296             (*this)(i,j) -= s;
02297     return *this;
02298 }
02299 
02300 template <class ELT> template <class S> inline void 
02301 MatrixBase<ELT>::elementwiseSubtractScalar(
02302     const S& s,
02303     typename MatrixBase<ELT>::template EltResult<S>::Sub& out) const
02304 {
02305     const int nr=nrow(), nc=ncol();
02306     out.resize(nr,nc);
02307     for (int j=0; j<nc; ++j)
02308         for (int i=0; i<nr; ++i)
02309             out(i,j) = (*this)(i,j) - s;
02310 }
02311 
02312 // M(i,j) = s - M(i,j)
02313 template <class ELT> template <class S> inline MatrixBase<ELT>& 
02314 MatrixBase<ELT>::elementwiseSubtractFromScalarInPlace(const S& s) {
02315     const int nr=nrow(), nc=ncol();
02316     for (int j=0; j<nc; ++j)
02317         for (int i=0; i<nr; ++i) {
02318             ELT& e = updElt(i,j);
02319             e = s - e;
02320         }
02321     return *this;
02322 }
02323 
02324 template <class ELT> template <class S> inline void 
02325 MatrixBase<ELT>::elementwiseSubtractFromScalar(
02326     const S& s,
02327     typename MatrixBase<S>::template EltResult<ELT>::Sub& out) const
02328 {
02329     const int nr=nrow(), nc=ncol();
02330     out.resize(nr,nc);
02331     for (int j=0; j<nc; ++j)
02332         for (int i=0; i<nr; ++i)
02333             out(i,j) = s - (*this)(i,j);
02334 }
02335 
02336 // M(i,j) *= R(i,j); R must have same dimensions as this
02337 template <class ELT> template <class EE> inline MatrixBase<ELT>& 
02338 MatrixBase<ELT>::elementwiseMultiplyInPlace(const MatrixBase<EE>& r) {
02339     const int nr=nrow(), nc=ncol();
02340     assert(r.nrow()==nr && r.ncol()==nc);
02341     for (int j=0; j<nc; ++j)
02342         for (int i=0; i<nr; ++i)
02343             (*this)(i,j) *= r(i,j);
02344     return *this;
02345 }
02346 
02347 template <class ELT> template <class EE> inline void 
02348 MatrixBase<ELT>::elementwiseMultiply(
02349     const MatrixBase<EE>& r, 
02350     typename MatrixBase<ELT>::template EltResult<EE>::Mul& out) const
02351 {
02352     const int nr=nrow(), nc=ncol();
02353     assert(r.nrow()==nr && r.ncol()==nc);
02354     out.resize(nr,nc);
02355     for (int j=0; j<nc; ++j)
02356         for (int i=0; i<nr; ++i)
02357             out(i,j) = (*this)(i,j) * r(i,j);
02358 }
02359 
02360 // M(i,j) = R(i,j) * M(i,j); R must have same dimensions as this
02361 template <class ELT> template <class EE> inline MatrixBase<ELT>& 
02362 MatrixBase<ELT>::elementwiseMultiplyFromLeftInPlace(const MatrixBase<EE>& r) {
02363     const int nr=nrow(), nc=ncol();
02364     assert(r.nrow()==nr && r.ncol()==nc);
02365     for (int j=0; j<nc; ++j)
02366         for (int i=0; i<nr; ++i) {
02367             ELT& e = updElt(i,j);
02368             e = r(i,j) * e;
02369         }
02370     return *this;
02371 }
02372 
02373 template <class ELT> template <class EE> inline void 
02374 MatrixBase<ELT>::elementwiseMultiplyFromLeft(
02375     const MatrixBase<EE>& r, 
02376     typename MatrixBase<EE>::template EltResult<ELT>::Mul& out) const
02377 {
02378     const int nr=nrow(), nc=ncol();
02379     assert(r.nrow()==nr && r.ncol()==nc);
02380     out.resize(nr,nc);
02381     for (int j=0; j<nc; ++j)
02382         for (int i=0; i<nr; ++i)
02383             out(i,j) =  r(i,j) * (*this)(i,j);
02384 }
02385 
02386 // M(i,j) /= R(i,j); R must have same dimensions as this
02387 template <class ELT> template <class EE> inline MatrixBase<ELT>& 
02388 MatrixBase<ELT>::elementwiseDivideInPlace(const MatrixBase<EE>& r) {
02389     const int nr=nrow(), nc=ncol();
02390     assert(r.nrow()==nr && r.ncol()==nc);
02391     for (int j=0; j<nc; ++j)
02392         for (int i=0; i<nr; ++i)
02393             (*this)(i,j) /= r(i,j);
02394     return *this;
02395 }
02396 
02397 template <class ELT> template <class EE> inline void 
02398 MatrixBase<ELT>::elementwiseDivide(
02399     const MatrixBase<EE>& r,
02400     typename MatrixBase<ELT>::template EltResult<EE>::Dvd& out) const
02401 {
02402     const int nr=nrow(), nc=ncol();
02403     assert(r.nrow()==nr && r.ncol()==nc);
02404     out.resize(nr,nc);
02405     for (int j=0; j<nc; ++j)
02406         for (int i=0; i<nr; ++i)
02407             out(i,j) = (*this)(i,j) / r(i,j);
02408 }
02409 // M(i,j) = R(i,j) / M(i,j); R must have same dimensions as this
02410 template <class ELT> template <class EE> inline MatrixBase<ELT>& 
02411 MatrixBase<ELT>::elementwiseDivideFromLeftInPlace(const MatrixBase<EE>& r) {
02412     const int nr=nrow(), nc=ncol();
02413     assert(r.nrow()==nr && r.ncol()==nc);
02414     for (int j=0; j<nc; ++j)
02415         for (int i=0; i<nr; ++i) {
02416             ELT& e = updElt(i,j);
02417             e = r(i,j) / e;
02418         }
02419     return *this;
02420 }
02421 
02422 template <class ELT> template <class EE> inline void 
02423 MatrixBase<ELT>::elementwiseDivideFromLeft(
02424     const MatrixBase<EE>& r,
02425     typename MatrixBase<EE>::template EltResult<ELT>::Dvd& out) const
02426 {
02427     const int nr=nrow(), nc=ncol();
02428     assert(r.nrow()==nr && r.ncol()==nc);
02429     out.resize(nr,nc);
02430     for (int j=0; j<nc; ++j)
02431         for (int i=0; i<nr; ++i)
02432             out(i,j) = r(i,j) / (*this)(i,j);
02433 }
02434 
02435 /*
02436 template <class ELT> inline MatrixView_< typename CNT<ELT>::TReal > 
02437 MatrixBase<ELT>::real() const { 
02438     if (!CNT<ELT>::IsComplex) { // known at compile time
02439         return MatrixView_< typename CNT<ELT>::TReal >( // this is just ELT
02440             MatrixHelper(helper,0,0,nrow(),ncol()));    // a view of the whole matrix
02441     }
02442     // Elements are complex -- helper uses underlying precision (real) type.
02443     MatrixHelper<Precision> h(helper,typename MatrixHelper<Precision>::RealView);    
02444     return MatrixView_< typename CNT<ELT>::TReal >(h); 
02445 }
02446 */
02447 
02448 
02449 //  ----------------------------------------------------------------------------
02453 
02454 // + and - allow mixed element types, but will fail to compile if the elements aren't
02455 // compatible. At run time these will fail if the dimensions are incompatible.
02456 template <class E1, class E2>
02457 Matrix_<typename CNT<E1>::template Result<E2>::Add>
02458 operator+(const MatrixBase<E1>& l, const MatrixBase<E2>& r) {
02459     return Matrix_<typename CNT<E1>::template Result<E2>::Add>(l) += r;
02460 }
02461 
02462 template <class E>
02463 Matrix_<E> operator+(const MatrixBase<E>& l, const typename CNT<E>::T& r) {
02464     return Matrix_<E>(l) += r;
02465 }
02466 
02467 template <class E>
02468 Matrix_<E> operator+(const typename CNT<E>::T& l, const MatrixBase<E>& r) {
02469     return Matrix_<E>(r) += l;
02470 }
02471 
02472 template <class E1, class E2>
02473 Matrix_<typename CNT<E1>::template Result<E2>::Sub>
02474 operator-(const MatrixBase<E1>& l, const MatrixBase<E2>& r) {
02475     return Matrix_<typename CNT<E1>::template Result<E2>::Sub>(l) -= r;
02476 }
02477 
02478 template <class E>
02479 Matrix_<E> operator-(const MatrixBase<E>& l, const typename CNT<E>::T& r) {
02480     return Matrix_<E>(l) -= r;
02481 }
02482 
02483 template <class E>
02484 Matrix_<E> operator-(const typename CNT<E>::T& l, const MatrixBase<E>& r) {
02485     Matrix_<E> temp(r.nrow(), r.ncol());
02486     temp = l;
02487     return (temp -= r);
02488 }
02489 
02490 // Scalar multiply and divide. You might wish the scalar could be
02491 // a templatized type "E2", but that would create horrible ambiguities since
02492 // E2 would match not only scalar types but everything else including
02493 // matrices.
02494 template <class E> Matrix_<E>
02495 operator*(const MatrixBase<E>& l, const typename CNT<E>::StdNumber& r) 
02496   { return Matrix_<E>(l)*=r; }
02497 
02498 template <class E> Matrix_<E>
02499 operator*(const typename CNT<E>::StdNumber& l, const MatrixBase<E>& r) 
02500   { return Matrix_<E>(r)*=l; }
02501 
02502 template <class E> Matrix_<E>
02503 operator/(const MatrixBase<E>& l, const typename CNT<E>::StdNumber& r) 
02504   { return Matrix_<E>(l)/=r; }
02505 
02506 // Handle ints explicitly.
02507 template <class E> Matrix_<E>
02508 operator*(const MatrixBase<E>& l, int r) 
02509   { return Matrix_<E>(l)*= typename CNT<E>::StdNumber(r); }
02510 
02511 template <class E> Matrix_<E>
02512 operator*(int l, const MatrixBase<E>& r) 
02513   { return Matrix_<E>(r)*= typename CNT<E>::StdNumber(l); }
02514 
02515 template <class E> Matrix_<E>
02516 operator/(const MatrixBase<E>& l, int r) 
02517   { return Matrix_<E>(l)/= typename CNT<E>::StdNumber(r); }
02518 
02520 
02524 
02525 template <class E1, class E2>
02526 Vector_<typename CNT<E1>::template Result<E2>::Add>
02527 operator+(const VectorBase<E1>& l, const VectorBase<E2>& r) {
02528     return Vector_<typename CNT<E1>::template Result<E2>::Add>(l) += r;
02529 }
02530 template <class E>
02531 Vector_<E> operator+(const VectorBase<E>& l, const typename CNT<E>::T& r) {
02532     return Vector_<E>(l) += r;
02533 }
02534 template <class E>
02535 Vector_<E> operator+(const typename CNT<E>::T& l, const VectorBase<E>& r) {
02536     return Vector_<E>(r) += l;
02537 }
02538 template <class E1, class E2>
02539 Vector_<typename CNT<E1>::template Result<E2>::Sub>
02540 operator-(const VectorBase<E1>& l, const VectorBase<E2>& r) {
02541     return Vector_<typename CNT<E1>::template Result<E2>::Sub>(l) -= r;
02542 }
02543 template <class E>
02544 Vector_<E> operator-(const VectorBase<E>& l, const typename CNT<E>::T& r) {
02545     return Vector_<E>(l) -= r;
02546 }
02547 template <class E>
02548 Vector_<E> operator-(const typename CNT<E>::T& l, const VectorBase<E>& r) {
02549     Vector_<E> temp(r.size());
02550     temp = l;
02551     return (temp -= r);
02552 }
02553 
02554 template <class E> Vector_<E>
02555 operator*(const VectorBase<E>& l, const typename CNT<E>::StdNumber& r) 
02556   { return Vector_<E>(l)*=r; }
02557 
02558 template <class E> Vector_<E>
02559 operator*(const typename CNT<E>::StdNumber& l, const VectorBase<E>& r) 
02560   { return Vector_<E>(r)*=l; }
02561 
02562 template <class E> Vector_<E>
02563 operator/(const VectorBase<E>& l, const typename CNT<E>::StdNumber& r) 
02564   { return Vector_<E>(l)/=r; }
02565 
02566 // Handle ints explicitly
02567 template <class E> Vector_<E>
02568 operator*(const VectorBase<E>& l, int r) 
02569   { return Vector_<E>(l)*= typename CNT<E>::StdNumber(r); }
02570 
02571 template <class E> Vector_<E>
02572 operator*(int l, const VectorBase<E>& r) 
02573   { return Vector_<E>(r)*= typename CNT<E>::StdNumber(l); }
02574 
02575 template <class E> Vector_<E>
02576 operator/(const VectorBase<E>& l, int r) 
02577   { return Vector_<E>(l)/= typename CNT<E>::StdNumber(r); }
02578 
02580 
02584 
02585 template <class E1, class E2>
02586 RowVector_<typename CNT<E1>::template Result<E2>::Add>
02587 operator+(const RowVectorBase<E1>& l, const RowVectorBase<E2>& r) {
02588     return RowVector_<typename CNT<E1>::template Result<E2>::Add>(l) += r;
02589 }
02590 template <class E>
02591 RowVector_<E> operator+(const RowVectorBase<E>& l, const typename CNT<E>::T& r) {
02592     return RowVector_<E>(l) += r;
02593 }
02594 template <class E>
02595 RowVector_<E> operator+(const typename CNT<E>::T& l, const RowVectorBase<E>& r) {
02596     return RowVector_<E>(r) += l;
02597 }
02598 template <class E1, class E2>
02599 RowVector_<typename CNT<E1>::template Result<E2>::Sub>
02600 operator-(const RowVectorBase<E1>& l, const RowVectorBase<E2>& r) {
02601     return RowVector_<typename CNT<E1>::template Result<E2>::Sub>(l) -= r;
02602 }
02603 template <class E>
02604 RowVector_<E> operator-(const RowVectorBase<E>& l, const typename CNT<E>::T& r) {
02605     return RowVector_<E>(l) -= r;
02606 }
02607 template <class E>
02608 RowVector_<E> operator-(const typename CNT<E>::T& l, const RowVectorBase<E>& r) {
02609     RowVector_<E> temp(r.size());
02610     temp = l;
02611     return (temp -= r);
02612 }
02613 
02614 template <class E> RowVector_<E>
02615 operator*(const RowVectorBase<E>& l, const typename CNT<E>::StdNumber& r) 
02616   { return RowVector_<E>(l)*=r; }
02617 
02618 template <class E> RowVector_<E>
02619 operator*(const typename CNT<E>::StdNumber& l, const RowVectorBase<E>& r) 
02620   { return RowVector_<E>(r)*=l; }
02621 
02622 template <class E> RowVector_<E>
02623 operator/(const RowVectorBase<E>& l, const typename CNT<E>::StdNumber& r) 
02624   { return RowVector_<E>(l)/=r; }
02625 
02626 // Handle ints explicitly.
02627 template <class E> RowVector_<E>
02628 operator*(const RowVectorBase<E>& l, int r) 
02629   { return RowVector_<E>(l)*= typename CNT<E>::StdNumber(r); }
02630 
02631 template <class E> RowVector_<E>
02632 operator*(int l, const RowVectorBase<E>& r) 
02633   { return RowVector_<E>(r)*= typename CNT<E>::StdNumber(l); }
02634 
02635 template <class E> RowVector_<E>
02636 operator/(const RowVectorBase<E>& l, int r) 
02637   { return RowVector_<E>(l)/= typename CNT<E>::StdNumber(r); }
02638 
02640 
02641 
02646 
02647     // TODO: these should use LAPACK!
02648 
02649 // Dot product
02650 template <class E1, class E2> 
02651 typename CNT<E1>::template Result<E2>::Mul
02652 operator*(const RowVectorBase<E1>& r, const VectorBase<E2>& v) {
02653     assert(r.ncol() == v.nrow());
02654     typename CNT<E1>::template Result<E2>::Mul sum(0);
02655     for (int j=0; j < r.ncol(); ++j)
02656         sum += r(j) * v[j];
02657     return sum;
02658 }
02659 
02660 template <class E1, class E2> 
02661 Vector_<typename CNT<E1>::template Result<E2>::Mul>
02662 operator*(const MatrixBase<E1>& m, const VectorBase<E2>& v) {
02663     assert(m.ncol() == v.nrow());
02664     Vector_<typename CNT<E1>::template Result<E2>::Mul> res(m.nrow());
02665     for (int i=0; i< m.nrow(); ++i)
02666         res[i] = m[i]*v;
02667     return res;
02668 }
02669 
02670 template <class E1, class E2> 
02671 Matrix_<typename CNT<E1>::template Result<E2>::Mul>
02672 operator*(const MatrixBase<E1>& m1, const MatrixBase<E2>& m2) {
02673     assert(m1.ncol() == m2.nrow());
02674     Matrix_<typename CNT<E1>::template Result<E2>::Mul> 
02675         res(m1.nrow(),m2.ncol());
02676 
02677     for (int j=0; j < res.ncol(); ++j)
02678         for (int i=0; i < res.nrow(); ++i)
02679             res(i,j) = m1[i] * m2(j);
02680 
02681     return res;
02682 }
02683 
02685 
02686 // This "private" static method is used to implement VectorView's 
02687 // fillVectorViewFromStream() and Vector's readVectorFromStream() 
02688 // namespace-scope static methods, which are in turn used to implement 
02689 // VectorView's and 
02690 // Vector's stream extraction operators ">>". This method has to be in the 
02691 // header file so that we don't need to pass streams through the API, but it 
02692 // is not intended for use by users and has no Doxygen presence, unlike 
02693 // fillArrayFromStream() and readArrayFromStream() and (more commonly)
02694 // the extraction operators.
02695 template <class T> static inline 
02696 std::istream& readVectorFromStreamHelper
02697    (std::istream& in, bool isFixedSize, Vector_<T>& out)
02698 {
02699     // If already failed, bad, or eof, set failed bit and return without 
02700     // touching the Vector.
02701     if (!in.good()) {in.setstate(std::ios::failbit); return in;}
02702 
02703     // If the passed-in Vector isn't resizeable, then we have to treat it as
02704     // a fixed size VectorView regardless of the setting of the isFixedSize
02705     // argument.
02706     if (!out.isResizeable())
02707         isFixedSize = true; // might be overriding the argument here
02708 
02709     // numRequired will be ignored unless isFixedSize==true.
02710     const int numRequired = isFixedSize ? out.size() : 0;
02711 
02712     if (!isFixedSize)
02713         out.clear(); // We're going to replace the entire contents of the Array.
02714 
02715     // Skip initial whitespace. If that results in eof this may be a successful
02716     // read of a 0-length, unbracketed Vector. That is OK for either a
02717     // variable-length Vector or a fixed-length VectorView of length zero.
02718     std::ws(in); if (in.fail()) return in;
02719     if (in.eof()) {
02720         if (isFixedSize && numRequired != 0)
02721             in.setstate(std::ios_base::failbit); // zero elements not OK
02722         return in;
02723     }
02724     
02725     // Here the stream is good and the next character is non-white.
02726     assert(in.good());
02727 
02728     // Use this for raw i/o (peeks and gets).
02729     typename       std::iostream::int_type ch;
02730     const typename std::iostream::int_type EOFch = 
02731         std::iostream::traits_type::eof();
02732 
02733     // First we'll look for the optional "~". If found, the brackets become
02734     // required.
02735     bool tildeFound = false;
02736     ch = in.peek(); if (in.fail()) return in;
02737     assert(ch != EOFch); // we already checked above
02738     if ((char)ch == '~') {
02739         tildeFound = true;
02740         in.get(); // absorb the tilde
02741         // Eat whitespace after the tilde to see what's next.
02742         if (in.good()) std::ws(in);
02743         // If we hit eof after the tilde we don't like the formatting.
02744         if (!in.good()) {in.setstate(std::ios_base::failbit); return in;}
02745     }
02746 
02747     // Here the stream is good, the next character is non-white, and we
02748     // might have seen a tilde.
02749     assert(in.good());
02750 
02751     // Now see if the sequence is bare or surrounded by (), or [].
02752     bool lookForCloser = true;
02753     char openBracket, closeBracket;
02754     ch = in.peek(); if (in.fail()) return in;
02755     assert(ch != EOFch); // we already checked above
02756 
02757     openBracket = (char)ch;
02758     if      (openBracket=='(') {in.get(); closeBracket = ')';}
02759     else if (openBracket=='[') {in.get(); closeBracket = ']';}
02760     else lookForCloser = false;
02761 
02762     // If we found a tilde, the opening bracket was mandatory. If we didn't
02763     // find one then we reject the formatting.
02764     if (tildeFound && !lookForCloser)
02765     {   in.setstate(std::ios_base::failbit); return in;}
02766 
02767     // If lookForCloser is true, then closeBracket contains the terminating
02768     // delimiter, otherwise we're not going to quit until eof.
02769 
02770     // Eat whitespace after the opening bracket to see what's next.
02771     if (in.good()) std::ws(in);
02772 
02773     // If we're at eof now it must be because the open bracket was the
02774     // last non-white character in the stream, which is an error.
02775     if (!in.good()) {
02776         if (in.eof()) {
02777             assert(lookForCloser); // or we haven't read anything that could eof
02778             in.setstate(std::ios::failbit);
02779         }
02780         return in;
02781     }
02782 
02783     // istream is good and next character is non-white; ready to read first
02784     // value or terminator.
02785 
02786     // We need to figure out whether the elements are space- or comma-
02787     // separated and then insist on consistency.
02788     bool commaOK = true, commaRequired = false;
02789     bool terminatorSeen = false;
02790     int nextIndex = 0;
02791     while (true) {
02792         char c;
02793 
02794         // Here at the top of this loop, we have already successfully read 
02795         // n=nextIndex values of type T. For fixed-size reads, it might be
02796         // the case that n==numRequired already, but we still may need to
02797         // look for a closing bracket before we can declare victory.
02798         // The stream is good() (not at eof) but it might be the case that 
02799         // there is nothing but white space left; we don't know yet because
02800         // if we have satisfied the fixed-size count and are not expecting
02801         // a terminator then we should quit without absorbing the trailing
02802         // white space.
02803         assert(in.good());
02804 
02805         // Look for closing bracket before trying to read value.
02806         if (lookForCloser) {
02807             // Eat white space to find the closing bracket.
02808             std::ws(in); if (!in.good()) break; // eof?
02809             ch = in.peek(); assert(ch != EOFch);
02810             if (!in.good()) break;
02811             c = (char)ch;
02812             if (c == closeBracket) {   
02813                 in.get(); // absorb the closing bracket
02814                 terminatorSeen = true; 
02815                 break; 
02816             }
02817             // next char not a closing bracket; fall through
02818         }
02819 
02820         // We didn't look or didn't find a closing bracket. The istream is good 
02821         // but we might be looking at white space.
02822 
02823         // If we already got all the elements we want, break for final checks.
02824         if (isFixedSize && (nextIndex == numRequired))
02825             break; // that's a full count.
02826 
02827         // Look for comma before value, except the first time.
02828         if (commaOK && nextIndex != 0) {
02829             // Eat white space to find the comma.
02830             std::ws(in); if (!in.good()) break; // eof?
02831             ch = in.peek(); assert(ch != EOFch);
02832             if (!in.good()) break;
02833             c = (char)ch;
02834             if (c == ',') {
02835                 in.get(); // absorb comma
02836                 commaRequired = true; // all commas from now on
02837             } else { // next char not a comma
02838                 if (commaRequired) // bad, e.g.: v1, v2, v3 v4 
02839                 {   in.setstate(std::ios::failbit); break; }
02840                 else commaOK = false; // saw: v1 v2 (no commas now)
02841             }
02842             if (!in.good()) break; // might be eof
02843         }
02844 
02845         // No closing bracket yet; don't have enough elements; skipped comma 
02846         // if any; istream is good; might be looking at white space.
02847         assert(in.good());
02848 
02849         // Now read in an element of type T.
02850         // The extractor T::operator>>() will ignore leading white space.
02851         if (!isFixedSize)
02852             out.resizeKeep(out.size()+1); // grow by one (default consructed)
02853         in >> out[nextIndex]; if (in.fail()) break;
02854         ++nextIndex;
02855 
02856         if (!in.good()) break; // might be eof
02857     }
02858 
02859     // We will get here under a number of circumstances:
02860     //  - the fail bit is set in the istream, or
02861     //  - we reached eof
02862     //  - we saw a closing brace
02863     //  - we got all the elements we wanted (for a fixed-size read)
02864     // Note that it is possible that we consumed everything except some
02865     // trailing white space (meaning we're not technically at eof), but
02866     // for consistency with built-in operator>>()'s we won't try to absorb
02867     // that trailing white space.
02868 
02869     if (!in.fail()) {
02870         if (lookForCloser && !terminatorSeen)
02871             in.setstate(std::ios::failbit); // missing terminator
02872 
02873         if (isFixedSize && nextIndex != numRequired)
02874             in.setstate(std::ios::failbit); // wrong number of values
02875     }
02876 
02877     return in;
02878 }
02879 
02880 
02881 
02882 //------------------------------------------------------------------------------
02883 //                          RELATED GLOBAL OPERATORS
02884 //------------------------------------------------------------------------------
02885 // These are logically part of the Matrix_<T> class but are not actually 
02886 // class members; that is, they are in the SimTK namespace.
02887 
02895 
02902 template <class T> inline std::ostream&
02903 operator<<(std::ostream& o, const VectorBase<T>& v)
02904 { o << "~["; for(int i=0;i<v.size();++i) o<<(i>0?" ":"")<<v[i]; 
02905     return o << "]"; }
02906 
02913 template <class T> inline std::ostream&
02914 operator<<(std::ostream& o, const RowVectorBase<T>& v)
02915 { o << "["; for(int i=0;i<v.size();++i) o<<(i>0?" ":"")<<v[i]; 
02916     return o << "]"; }
02917 
02925 template <class T> inline std::ostream&
02926 operator<<(std::ostream& o, const MatrixBase<T>& m) {
02927     for (int i=0;i<m.nrow();++i)
02928         o << std::endl << m[i];
02929     if (m.nrow()) o << std::endl;
02930     return o; 
02931 }
02932 
02933 
02965 template <class T> static inline 
02966 std::istream& readVectorFromStream(std::istream& in, Vector_<T>& out)
02967 {   return readVectorFromStreamHelper<T>(in, false /*variable sizez*/, out); }
02968 
02969 
02970 
02995 template <class T> static inline 
02996 std::istream& fillVectorFromStream(std::istream& in, Vector_<T>& out)
02997 {   return readVectorFromStreamHelper<T>(in, true /*fixed size*/, out); }
02998 
03003 template <class T> static inline 
03004 std::istream& fillVectorViewFromStream(std::istream& in, VectorView_<T>& out)
03005 {   return readVectorFromStreamHelper<T>(in, true /*fixed size*/, out); }
03006 
03007 
03017 template <class T> inline
03018 std::istream& operator>>(std::istream& in, Vector_<T>& out) 
03019 {   return readVectorFromStream<T>(in, out); }
03020 
03028 template <class T> inline
03029 std::istream& operator>>(std::istream& in, VectorView_<T>& out) 
03030 {   return fillVectorViewFromStream<T>(in, out); }
03031 
03034 // Friendly abbreviations for vectors and matrices with scalar elements.
03035 
03036 typedef Vector_<Real>           Vector;
03037 typedef Vector_<float>          fVector;
03038 typedef Vector_<double>         dVector;
03039 typedef Vector_<Complex>        ComplexVector;
03040 typedef Vector_<fComplex>       fComplexVector;
03041 typedef Vector_<dComplex>       dComplexVector;
03042 
03043 typedef VectorView_<Real>       VectorView;
03044 typedef VectorView_<float>      fVectorView;
03045 typedef VectorView_<double>     dVectorView;
03046 typedef VectorView_<Complex>    ComplexVectorView;
03047 typedef VectorView_<fComplex>   fComplexVectorView;
03048 typedef VectorView_<dComplex>   dComplexVectorView;
03049 
03050 typedef RowVector_<Real>        RowVector;
03051 typedef RowVector_<float>       fRowVector;
03052 typedef RowVector_<double>      dRowVector;
03053 typedef RowVector_<Complex>     ComplexRowVector;
03054 typedef RowVector_<fComplex>    fComplexRowVector;
03055 typedef RowVector_<dComplex>    dComplexRowVector;
03056 
03057 typedef RowVectorView_<Real>    RowVectorView;
03058 typedef RowVectorView_<float>   fRowVectorView;
03059 typedef RowVectorView_<double>  dRowVectorView;
03060 typedef RowVectorView_<Complex> ComplexRowVectorView;
03061 typedef RowVectorView_<fComplex> fComplexRowVectorView;
03062 typedef RowVectorView_<dComplex> dComplexRowVectorView;
03063 
03064 typedef Matrix_<Real>           Matrix;
03065 typedef Matrix_<float>          fMatrix;
03066 typedef Matrix_<double>         dMatrix;
03067 typedef Matrix_<Complex>        ComplexMatrix;
03068 typedef Matrix_<fComplex>       fComplexMatrix;
03069 typedef Matrix_<dComplex>       dComplexMatrix;
03070 
03071 typedef MatrixView_<Real>       MatrixView;
03072 typedef MatrixView_<float>      fMatrixView;
03073 typedef MatrixView_<double>     dMatrixView;
03074 typedef MatrixView_<Complex>    ComplexMatrixView;
03075 typedef MatrixView_<fComplex>   fComplexMatrixView;
03076 typedef MatrixView_<dComplex>   dComplexMatrixView;
03077 
03078 
03083 template <class ELT, class VECTOR_CLASS>
03084 class VectorIterator {
03085 public:
03086     typedef ELT value_type;
03087     typedef int difference_type;
03088     typedef ELT& reference;
03089     typedef ELT* pointer;
03090     typedef std::random_access_iterator_tag iterator_category;
03091     VectorIterator(VECTOR_CLASS& vector, int index) : vector(vector), index(index) {
03092     }
03093     VectorIterator(const VectorIterator& iter) : vector(iter.vector), index(iter.index) {
03094     }
03095     VectorIterator& operator=(const VectorIterator& iter) {
03096         vector = iter.vector;
03097         index = iter.index;
03098         return *this;
03099     }
03100     ELT& operator*() {
03101         assert (index >= 0 && index < vector.size());
03102         return vector[index];
03103     }
03104     ELT& operator[](int i) {
03105         assert (i >= 0 && i < vector.size());
03106         return vector[i];
03107     }
03108     VectorIterator operator++() {
03109         assert (index < vector.size());
03110         ++index;
03111         return *this;
03112     }
03113     VectorIterator operator++(int) {
03114         assert (index < vector.size());
03115         VectorIterator current = *this;
03116         ++index;
03117         return current;
03118     }
03119     VectorIterator operator--() {
03120         assert (index > 0);
03121         --index;
03122         return *this;
03123     }
03124     VectorIterator operator--(int) {
03125         assert (index > 0);
03126         VectorIterator current = *this;
03127         --index;
03128         return current;
03129     }
03130     bool operator<(VectorIterator iter) const {
03131         return (index < iter.index);
03132     }
03133     bool operator>(VectorIterator iter) const {
03134         return (index > iter.index);
03135     }
03136     bool operator<=(VectorIterator iter) const {
03137         return (index <= iter.index);
03138     }
03139     bool operator>=(VectorIterator iter) const {
03140         return (index >= iter.index);
03141     }
03142     int operator-(VectorIterator iter) const {
03143         return (index - iter.index);
03144     }
03145     VectorIterator operator-(int n) const {
03146         return VectorIterator(vector, index-n);
03147     }
03148     VectorIterator operator+(int n) const {
03149         return VectorIterator(vector, index+n);
03150     }
03151     bool operator==(VectorIterator iter) const {
03152         return (index == iter.index);
03153     }
03154     bool operator!=(VectorIterator iter) const {
03155         return (index != iter.index);
03156     }
03157 private:
03158     VECTOR_CLASS& vector;
03159     int index;
03160 };
03161 
03162 } //namespace SimTK
03163 
03164 #endif //SimTK_SIMMATRIX_BIGMATRIX_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines