Simbody  3.4 (development)
BigMatrix.h
Go to the documentation of this file.
00001 #ifndef SimTK_SIMMATRIX_BIGMATRIX_H_
00002 #define SimTK_SIMMATRIX_BIGMATRIX_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                       Simbody(tm): SimTKcommon                             *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK biosimulation toolkit originating from           *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody.  *
00011  *                                                                            *
00012  * Portions copyright (c) 2005-12 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
00017  * not use this file except in compliance with the License. You may obtain a  *
00018  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
00019  *                                                                            *
00020  * Unless required by applicable law or agreed to in writing, software        *
00021  * distributed under the License is distributed on an "AS IS" BASIS,          *
00022  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
00023  * See the License for the specific language governing permissions and        *
00024  * limitations under the License.                                             *
00025  * -------------------------------------------------------------------------- */
00026 
00159 // TODO: matrix expression templates for delaying operator execution.
00160 
00161 #include "SimTKcommon/Scalar.h"
00162 #include "SimTKcommon/SmallMatrix.h"
00163 
00164 #include "SimTKcommon/internal/MatrixHelper.h"
00165 #include "SimTKcommon/internal/MatrixCharacteristics.h"
00166 
00167 #include <iostream>
00168 #include <cassert>
00169 #include <complex>
00170 #include <cstddef>
00171 #include <limits>
00172 
00173 namespace SimTK {
00174 
00175 template <class ELT>    class MatrixBase;
00176 template <class ELT>    class VectorBase;
00177 template <class ELT>    class RowVectorBase;
00178 
00179 template <class T=Real> class MatrixView_;
00180 template <class T=Real> class DeadMatrixView_;
00181 template <class T=Real> class Matrix_;
00182 template <class T=Real> class DeadMatrix_;
00183 
00184 template <class T=Real> class VectorView_;
00185 template <class T=Real> class DeadVectorView_;
00186 template <class T=Real> class Vector_;
00187 template <class T=Real> class DeadVector_;
00188 
00189 template <class T=Real> class RowVectorView_;
00190 template <class T=Real> class DeadRowVectorView_;
00191 template <class T=Real> class RowVector_;
00192 template <class T=Real> class DeadRowVector_;
00193 
00194 template <class ELT, class VECTOR_CLASS> class VectorIterator;
00195 
00196 //  -------------------------------- MatrixBase --------------------------------
00218 //  ----------------------------------------------------------------------------
00219 template <class ELT> class MatrixBase {  
00220 public:
00221     // These typedefs are handy, but despite appearances you cannot 
00222     // treat a MatrixBase as a composite numerical type. That is,
00223     // CNT<MatrixBase> will not compile, or if it does it won't be
00224     // meaningful.
00225 
00226     typedef ELT                                 E;
00227     typedef typename CNT<E>::TNeg               ENeg;
00228     typedef typename CNT<E>::TWithoutNegator    EWithoutNegator;
00229     typedef typename CNT<E>::TReal              EReal;
00230     typedef typename CNT<E>::TImag              EImag;
00231     typedef typename CNT<E>::TComplex           EComplex;
00232     typedef typename CNT<E>::THerm              EHerm;       
00233     typedef typename CNT<E>::TPosTrans          EPosTrans;
00234 
00235     typedef typename CNT<E>::TAbs               EAbs;
00236     typedef typename CNT<E>::TStandard          EStandard;
00237     typedef typename CNT<E>::TInvert            EInvert;
00238     typedef typename CNT<E>::TNormalize         ENormalize;
00239     typedef typename CNT<E>::TSqHermT           ESqHermT;
00240     typedef typename CNT<E>::TSqTHerm           ESqTHerm;
00241 
00242     typedef typename CNT<E>::Scalar             EScalar;
00243     typedef typename CNT<E>::Number             ENumber;
00244     typedef typename CNT<E>::StdNumber          EStdNumber;
00245     typedef typename CNT<E>::Precision          EPrecision;
00246     typedef typename CNT<E>::ScalarNormSq       EScalarNormSq;
00247 
00248     typedef EScalar    Scalar;        // the underlying Scalar type
00249     typedef ENumber    Number;        // negator removed from Scalar
00250     typedef EStdNumber StdNumber;     // conjugate goes to complex
00251     typedef EPrecision Precision;     // complex removed from StdNumber
00252     typedef EScalarNormSq  ScalarNormSq;      // type of scalar^2
00253 
00254     typedef MatrixBase<E>                T;
00255     typedef MatrixBase<ENeg>             TNeg;
00256     typedef MatrixBase<EWithoutNegator>  TWithoutNegator;
00257     typedef MatrixBase<EReal>            TReal;
00258     typedef MatrixBase<EImag>            TImag;
00259     typedef MatrixBase<EComplex>         TComplex;
00260     typedef MatrixBase<EHerm>            THerm; 
00261     typedef MatrixBase<E>                TPosTrans;
00262 
00263     typedef MatrixBase<EAbs>             TAbs;
00264     typedef MatrixBase<EStandard>        TStandard;
00265     typedef MatrixBase<EInvert>          TInvert;
00266     typedef MatrixBase<ENormalize>       TNormalize;
00267     typedef MatrixBase<ESqHermT>         TSqHermT;  // ~Mat*Mat
00268     typedef MatrixBase<ESqTHerm>         TSqTHerm;  // Mat*~Mat
00269 
00270     const MatrixCommitment& getCharacterCommitment() const {return helper.getCharacterCommitment();}
00271     const MatrixCharacter& getMatrixCharacter()     const {return helper.getMatrixCharacter();}
00272 
00275     void commitTo(const MatrixCommitment& mc)
00276     {   helper.commitTo(mc); }
00277 
00278     // This gives the resulting matrix type when (m(i,j) op P) is applied to each element.
00279     // It will have element types which are the regular composite result of E op P.
00280     template <class P> struct EltResult { 
00281         typedef MatrixBase<typename CNT<E>::template Result<P>::Mul> Mul;
00282         typedef MatrixBase<typename CNT<E>::template Result<P>::Dvd> Dvd;
00283         typedef MatrixBase<typename CNT<E>::template Result<P>::Add> Add;
00284         typedef MatrixBase<typename CNT<E>::template Result<P>::Sub> Sub;
00285     };
00286 
00288     int  nrow() const {return helper.nrow();}
00290     int  ncol() const {return helper.ncol();}
00291 
00299     ptrdiff_t nelt() const {return helper.nelt();}
00300 
00302     bool isResizeable() const {return getCharacterCommitment().isResizeable();}
00303 
00304     enum { 
00305         NScalarsPerElement    = CNT<E>::NActualScalars,
00306         CppNScalarsPerElement = sizeof(E) / sizeof(Scalar)
00307     };
00308   
00312     MatrixBase() : helper(NScalarsPerElement,CppNScalarsPerElement) {}
00313 
00316     MatrixBase(int m, int n) 
00317     :   helper(NScalarsPerElement,CppNScalarsPerElement,MatrixCommitment(),m,n) {}
00318 
00324     explicit MatrixBase(const MatrixCommitment& commitment) 
00325     :   helper(NScalarsPerElement,CppNScalarsPerElement,commitment) {}
00326 
00327 
00332     MatrixBase(const MatrixCommitment& commitment, int m, int n) 
00333     :   helper(NScalarsPerElement,CppNScalarsPerElement,commitment,m,n) {}
00334 
00336     MatrixBase(const MatrixBase& b)
00337       : helper(b.helper.getCharacterCommitment(), 
00338                b.helper, typename MatrixHelper<Scalar>::DeepCopy()) { }
00339 
00342     MatrixBase(const TNeg& b)
00343       : helper(b.helper.getCharacterCommitment(),
00344                b.helper, typename MatrixHelper<Scalar>::DeepCopy()) { }
00345     
00348     MatrixBase& copyAssign(const MatrixBase& b) {
00349         helper.copyAssign(b.helper);
00350         return *this;
00351     }
00352     MatrixBase& operator=(const MatrixBase& b) { return copyAssign(b); }
00353 
00354 
00363     MatrixBase& viewAssign(const MatrixBase& src) {
00364         helper.writableViewAssign(const_cast<MatrixHelper<Scalar>&>(src.helper));
00365         return *this;
00366     }
00367 
00368     // default destructor
00369 
00376     MatrixBase(const MatrixCommitment& commitment, int m, int n, const ELT& initialValue) 
00377     :   helper(NScalarsPerElement, CppNScalarsPerElement, commitment, m, n)
00378     {   helper.fillWith(reinterpret_cast<const Scalar*>(&initialValue)); }  
00379 
00390     MatrixBase(const MatrixCommitment& commitment, int m, int n, 
00391                const ELT* cppInitialValuesByRow) 
00392     :   helper(NScalarsPerElement, CppNScalarsPerElement, commitment, m, n)
00393     {   helper.copyInByRowsFromCpp(reinterpret_cast<const Scalar*>(cppInitialValuesByRow)); }
00394      
00406 
00408     MatrixBase(const MatrixCommitment& commitment, 
00409                const MatrixCharacter&  character, 
00410                int spacing, const Scalar* data) // read only data
00411     :   helper(NScalarsPerElement, CppNScalarsPerElement, 
00412                commitment, character, spacing, data) {}  
00413 
00415     MatrixBase(const MatrixCommitment& commitment, 
00416                const MatrixCharacter&  character, 
00417                int spacing, Scalar* data) // writable data
00418     :   helper(NScalarsPerElement, CppNScalarsPerElement, 
00419                commitment, character, spacing, data) {}  
00421         
00422     // Create a new MatrixBase from an existing helper. Both shallow and deep copies are possible.
00423     MatrixBase(const MatrixCommitment& commitment, 
00424                MatrixHelper<Scalar>&   source, 
00425                const typename MatrixHelper<Scalar>::ShallowCopy& shallow) 
00426     :   helper(commitment, source, shallow) {}
00427     MatrixBase(const MatrixCommitment&      commitment, 
00428                const MatrixHelper<Scalar>&  source, 
00429                const typename MatrixHelper<Scalar>::ShallowCopy& shallow) 
00430     :   helper(commitment, source, shallow) {}
00431     MatrixBase(const MatrixCommitment&      commitment, 
00432                const MatrixHelper<Scalar>&  source, 
00433                const typename MatrixHelper<Scalar>::DeepCopy& deep)    
00434     :   helper(commitment, source, deep) {}
00435 
00439     void clear() {helper.clear();}
00440 
00441     MatrixBase& operator*=(const StdNumber& t)  { helper.scaleBy(t);              return *this; }
00442     MatrixBase& operator/=(const StdNumber& t)  { helper.scaleBy(StdNumber(1)/t); return *this; }
00443     MatrixBase& operator+=(const MatrixBase& r) { helper.addIn(r.helper);         return *this; }
00444     MatrixBase& operator-=(const MatrixBase& r) { helper.subIn(r.helper);         return *this; }  
00445 
00446     template <class EE> MatrixBase(const MatrixBase<EE>& b)
00447       : helper(MatrixCommitment(),b.helper, typename MatrixHelper<Scalar>::DeepCopy()) { }
00448 
00449     template <class EE> MatrixBase& operator=(const MatrixBase<EE>& b) 
00450       { helper = b.helper; return *this; }
00451     template <class EE> MatrixBase& operator+=(const MatrixBase<EE>& b) 
00452       { helper.addIn(b.helper); return *this; }
00453     template <class EE> MatrixBase& operator-=(const MatrixBase<EE>& b) 
00454       { helper.subIn(b.helper); return *this; }
00455 
00466     MatrixBase& operator=(const ELT& t) { 
00467         setToZero(); updDiag().setTo(t); 
00468         return *this;
00469     }
00470 
00476     template <class S> inline MatrixBase&
00477     scalarAssign(const S& s) {
00478         setToZero(); updDiag().setTo(s);
00479         return *this;
00480     }
00481 
00485     template <class S> inline MatrixBase&
00486     scalarAddInPlace(const S& s) {
00487         updDiag().elementwiseAddScalarInPlace(s);
00488     }
00489 
00490 
00494     template <class S> inline MatrixBase&
00495     scalarSubtractInPlace(const S& s) {
00496         updDiag().elementwiseSubtractScalarInPlace(s);
00497     }
00498 
00501     template <class S> inline MatrixBase&
00502     scalarSubtractFromLeftInPlace(const S& s) {
00503         negateInPlace();
00504         updDiag().elementwiseAddScalarInPlace(s); // yes, add
00505     }
00506 
00513     template <class S> inline MatrixBase&
00514     scalarMultiplyInPlace(const S&);
00515 
00519     template <class S> inline MatrixBase&
00520     scalarMultiplyFromLeftInPlace(const S&);
00521 
00528     template <class S> inline MatrixBase&
00529     scalarDivideInPlace(const S&);
00530 
00534     template <class S> inline MatrixBase&
00535     scalarDivideFromLeftInPlace(const S&);
00536 
00537 
00540     template <class EE> inline MatrixBase& 
00541     rowScaleInPlace(const VectorBase<EE>&);
00542 
00545     template <class EE> inline void 
00546     rowScale(const VectorBase<EE>& r, typename EltResult<EE>::Mul& out) const;
00547 
00548     template <class EE> inline typename EltResult<EE>::Mul 
00549     rowScale(const VectorBase<EE>& r) const {
00550         typename EltResult<EE>::Mul out(nrow(), ncol()); rowScale(r,out); return out;
00551     }
00552 
00555     template <class EE> inline MatrixBase& 
00556     colScaleInPlace(const VectorBase<EE>&);
00557 
00558     template <class EE> inline void 
00559     colScale(const VectorBase<EE>& c, typename EltResult<EE>::Mul& out) const;
00560 
00561     template <class EE> inline typename EltResult<EE>::Mul
00562     colScale(const VectorBase<EE>& c) const {
00563         typename EltResult<EE>::Mul out(nrow(), ncol()); colScale(c,out); return out;
00564     }
00565 
00566 
00571     template <class ER, class EC> inline MatrixBase& 
00572     rowAndColScaleInPlace(const VectorBase<ER>& r, const VectorBase<EC>& c);
00573 
00574     template <class ER, class EC> inline void 
00575     rowAndColScale(const VectorBase<ER>& r, const VectorBase<EC>& c, 
00576                    typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul& out) const;
00577 
00578     template <class ER, class EC> inline typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul
00579     rowAndColScale(const VectorBase<ER>& r, const VectorBase<EC>& c) const {
00580         typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul 
00581             out(nrow(), ncol()); 
00582         rowAndColScale(r,c,out); return out;
00583     }
00584 
00592     template <class S> inline MatrixBase&
00593     elementwiseAssign(const S& s);
00594 
00596     MatrixBase& elementwiseAssign(int s)
00597     {   return elementwiseAssign<Real>(Real(s)); }
00598 
00600     MatrixBase& elementwiseInvertInPlace();
00601 
00602     void elementwiseInvert(MatrixBase<typename CNT<E>::TInvert>& out) const;
00603 
00604     MatrixBase<typename CNT<E>::TInvert> elementwiseInvert() const {
00605         MatrixBase<typename CNT<E>::TInvert> out(nrow(), ncol());
00606         elementwiseInvert(out);
00607         return out;
00608     }
00609 
00617     template <class S> inline MatrixBase&
00618     elementwiseAddScalarInPlace(const S& s);
00619 
00620     template <class S> inline void
00621     elementwiseAddScalar(const S& s, typename EltResult<S>::Add&) const;
00622 
00623     template <class S> inline typename EltResult<S>::Add
00624     elementwiseAddScalar(const S& s) const {
00625         typename EltResult<S>::Add out(nrow(), ncol());
00626         elementwiseAddScalar(s,out);
00627         return out;
00628     }
00629 
00637     template <class S> inline MatrixBase&
00638     elementwiseSubtractScalarInPlace(const S& s);
00639 
00640     template <class S> inline void
00641     elementwiseSubtractScalar(const S& s, typename EltResult<S>::Sub&) const;
00642 
00643     template <class S> inline typename EltResult<S>::Sub
00644     elementwiseSubtractScalar(const S& s) const {
00645         typename EltResult<S>::Sub out(nrow(), ncol());
00646         elementwiseSubtractScalar(s,out);
00647         return out;
00648     }
00649 
00658     template <class S> inline MatrixBase&
00659     elementwiseSubtractFromScalarInPlace(const S& s);
00660 
00661     template <class S> inline void
00662     elementwiseSubtractFromScalar(
00663         const S&, 
00664         typename MatrixBase<S>::template EltResult<E>::Sub&) const;
00665 
00666     template <class S> inline typename MatrixBase<S>::template EltResult<E>::Sub
00667     elementwiseSubtractFromScalar(const S& s) const {
00668         typename MatrixBase<S>::template EltResult<E>::Sub out(nrow(), ncol());
00669         elementwiseSubtractFromScalar<S>(s,out);
00670         return out;
00671     }
00672 
00674     template <class EE> inline MatrixBase& 
00675     elementwiseMultiplyInPlace(const MatrixBase<EE>&);
00676 
00677     template <class EE> inline void 
00678     elementwiseMultiply(const MatrixBase<EE>&, typename EltResult<EE>::Mul&) const;
00679 
00680     template <class EE> inline typename EltResult<EE>::Mul 
00681     elementwiseMultiply(const MatrixBase<EE>& m) const {
00682         typename EltResult<EE>::Mul out(nrow(), ncol()); 
00683         elementwiseMultiply<EE>(m,out); 
00684         return out;
00685     }
00686 
00688     template <class EE> inline MatrixBase& 
00689     elementwiseMultiplyFromLeftInPlace(const MatrixBase<EE>&);
00690 
00691     template <class EE> inline void 
00692     elementwiseMultiplyFromLeft(
00693         const MatrixBase<EE>&, 
00694         typename MatrixBase<EE>::template EltResult<E>::Mul&) const;
00695 
00696     template <class EE> inline typename MatrixBase<EE>::template EltResult<E>::Mul 
00697     elementwiseMultiplyFromLeft(const MatrixBase<EE>& m) const {
00698         typename EltResult<EE>::Mul out(nrow(), ncol()); 
00699         elementwiseMultiplyFromLeft<EE>(m,out); 
00700         return out;
00701     }
00702 
00704     template <class EE> inline MatrixBase& 
00705     elementwiseDivideInPlace(const MatrixBase<EE>&);
00706 
00707     template <class EE> inline void 
00708     elementwiseDivide(const MatrixBase<EE>&, typename EltResult<EE>::Dvd&) const;
00709 
00710     template <class EE> inline typename EltResult<EE>::Dvd 
00711     elementwiseDivide(const MatrixBase<EE>& m) const {
00712         typename EltResult<EE>::Dvd out(nrow(), ncol()); 
00713         elementwiseDivide<EE>(m,out); 
00714         return out;
00715     }
00716 
00718     template <class EE> inline MatrixBase& 
00719     elementwiseDivideFromLeftInPlace(const MatrixBase<EE>&);
00720 
00721     template <class EE> inline void 
00722     elementwiseDivideFromLeft(
00723         const MatrixBase<EE>&,
00724         typename MatrixBase<EE>::template EltResult<E>::Dvd&) const;
00725 
00726     template <class EE> inline typename MatrixBase<EE>::template EltResult<EE>::Dvd 
00727     elementwiseDivideFromLeft(const MatrixBase<EE>& m) const {
00728         typename MatrixBase<EE>::template EltResult<E>::Dvd out(nrow(), ncol()); 
00729         elementwiseDivideFromLeft<EE>(m,out); 
00730         return out;
00731     }
00732 
00734     MatrixBase& setTo(const ELT& t) {helper.fillWith(reinterpret_cast<const Scalar*>(&t)); return *this;}
00735     MatrixBase& setToNaN() {helper.fillWithScalar(CNT<StdNumber>::getNaN()); return *this;}
00736     MatrixBase& setToZero() {helper.fillWithScalar(StdNumber(0)); return *this;}
00737  
00738     // View creating operators. TODO: these should be DeadMatrixViews  
00739     inline RowVectorView_<ELT> row(int i) const;   // select a row
00740     inline RowVectorView_<ELT> updRow(int i);
00741     inline VectorView_<ELT>    col(int j) const;   // select a column
00742     inline VectorView_<ELT>    updCol(int j);
00743 
00744     RowVectorView_<ELT> operator[](int i) const {return row(i);}
00745     RowVectorView_<ELT> operator[](int i)       {return updRow(i);}
00746     VectorView_<ELT>    operator()(int j) const {return col(j);}
00747     VectorView_<ELT>    operator()(int j)       {return updCol(j);}
00748      
00749     // Select a block.
00750     inline MatrixView_<ELT> block(int i, int j, int m, int n) const;
00751     inline MatrixView_<ELT> updBlock(int i, int j, int m, int n);
00752 
00753     MatrixView_<ELT> operator()(int i, int j, int m, int n) const
00754       { return block(i,j,m,n); }
00755     MatrixView_<ELT> operator()(int i, int j, int m, int n)
00756       { return updBlock(i,j,m,n); }
00757  
00758     // Hermitian transpose.
00759     inline MatrixView_<EHerm> transpose() const;
00760     inline MatrixView_<EHerm> updTranspose();
00761 
00762     MatrixView_<EHerm> operator~() const {return transpose();}
00763     MatrixView_<EHerm> operator~()       {return updTranspose();}
00764 
00767     inline VectorView_<ELT> diag() const;
00770     inline VectorView_<ELT> updDiag();
00773     VectorView_<ELT> diag() {return updDiag();}
00774 
00775     // Create a view of the real or imaginary elements. TODO
00776     //inline MatrixView_<EReal> real() const;
00777     //inline MatrixView_<EReal> updReal();
00778     //inline MatrixView_<EImag> imag() const;
00779     //inline MatrixView_<EImag> updImag();
00780 
00781     // Overload "real" and "imag" for both read and write as a nod to convention. TODO
00782     //MatrixView_<EReal> real() {return updReal();}
00783     //MatrixView_<EReal> imag() {return updImag();}
00784 
00785     // TODO: this routine seems ill-advised but I need it for the IVM port at the moment
00786     TInvert invert() const {  // return a newly-allocated inverse; dump negator 
00787         TInvert m(*this);
00788         m.helper.invertInPlace();
00789         return m;   // TODO - bad: makes an extra copy
00790     }
00791 
00792     void invertInPlace() {helper.invertInPlace();}
00793 
00795     void dump(const char* msg=0) const {
00796         helper.dump(msg);
00797     }
00798 
00799 
00800     // This routine is useful for implementing friendlier Matrix expressions and operators.
00801     // It maps closely to the Level-3 BLAS family of pxxmm() routines like sgemm(). The
00802     // operation performed assumes that "this" is the result, and that "this" has 
00803     // already been sized correctly to receive the result. We'll compute
00804     //     this = beta*this + alpha*A*B
00805     // If beta is 0 then "this" can be uninitialized. If alpha is 0 we promise not
00806     // to look at A or B. The routine can work efficiently even if A and/or B are transposed
00807     // by their views, so an expression like
00808     //        C += s * ~A * ~B
00809     // can be performed with the single equivalent call
00810     //        C.matmul(1., s, Tr(A), Tr(B))
00811     // where Tr(A) indicates a transposed view of the original A.
00812     // The ultimate efficiency of this call depends on the data layout and views which
00813     // are used for the three matrices.
00814     // NOTE: neither A nor B can be the same matrix as 'this', nor views of the same data
00815     // which would expose elements of 'this' that will be modified by this operation.
00816     template <class ELT_A, class ELT_B>
00817     MatrixBase& matmul(const StdNumber& beta,   // applied to 'this'
00818                        const StdNumber& alpha, const MatrixBase<ELT_A>& A, const MatrixBase<ELT_B>& B)
00819     {
00820         helper.matmul(beta,alpha,A.helper,B.helper);
00821         return *this;
00822     }
00823 
00832     const ELT& getElt(int i, int j) const { return *reinterpret_cast<const ELT*>(helper.getElt(i,j)); }
00833     ELT&       updElt(int i, int j)       { return *reinterpret_cast<      ELT*>(helper.updElt(i,j)); }
00834 
00835     const ELT& operator()(int i, int j) const {return getElt(i,j);}
00836     ELT&       operator()(int i, int j)       {return updElt(i,j);}
00837 
00842     void getAnyElt(int i, int j, ELT& value) const
00843     {   helper.getAnyElt(i,j,reinterpret_cast<Scalar*>(&value)); }
00844     ELT getAnyElt(int i, int j) const {ELT e; getAnyElt(i,j,e); return e;}
00845 
00848     // TODO: very slow! Should be optimized at least for the case
00849     //       where ELT is a Scalar.
00850     ScalarNormSq scalarNormSqr() const {
00851         const int nr=nrow(), nc=ncol();
00852         ScalarNormSq sum(0);
00853         for(int j=0;j<nc;++j) 
00854             for (int i=0; i<nr; ++i)
00855                 sum += CNT<E>::scalarNormSqr((*this)(i,j));
00856         return sum;
00857     }
00858 
00862     // TODO: very slow! Should be optimized at least for the case
00863     //       where ELT is a Scalar.
00864     void abs(TAbs& mabs) const {
00865         const int nr=nrow(), nc=ncol();
00866         mabs.resize(nr,nc);
00867         for(int j=0;j<nc;++j) 
00868             for (int i=0; i<nr; ++i)
00869                 mabs(i,j) = CNT<E>::abs((*this)(i,j));
00870     }
00871 
00875     TAbs abs() const { TAbs mabs; abs(mabs); return mabs; }
00876 
00887     TStandard standardize() const {
00888         const int nr=nrow(), nc=ncol();
00889         TStandard mstd(nr, nc);
00890         for(int j=0;j<nc;++j) 
00891             for (int i=0; i<nr; ++i)
00892                 mstd(i,j) = CNT<E>::standardize((*this)(i,j));
00893         return mstd;
00894     }
00895 
00899     ScalarNormSq normSqr() const { return scalarNormSqr(); }
00900     // TODO -- not good; unnecessary overflow
00901     typename CNT<ScalarNormSq>::TSqrt 
00902         norm() const { return CNT<ScalarNormSq>::sqrt(scalarNormSqr()); }
00903 
00907     typename CNT<ScalarNormSq>::TSqrt 
00908     normRMS() const {
00909         if (!CNT<ELT>::IsScalar)
00910             SimTK_THROW1(Exception::Cant, "normRMS() only defined for scalar elements");
00911         if (nelt() == 0)
00912             return typename CNT<ScalarNormSq>::TSqrt(0);
00913         return CNT<ScalarNormSq>::sqrt(scalarNormSqr()/nelt());
00914     }
00915 
00917     RowVector_<ELT> colSum() const {
00918         const int cols = ncol();
00919         RowVector_<ELT> row(cols);
00920         for (int j = 0; j < cols; ++j)
00921             helper.colSum(j, reinterpret_cast<Scalar*>(&row[j]));
00922         return row;
00923     }
00925     RowVector_<ELT> sum() const {return colSum();}
00926 
00928     Vector_<ELT> rowSum() const {
00929         const int rows = nrow();
00930         Vector_<ELT> col(rows);
00931         for (int i = 0; i < rows; ++i)
00932             helper.rowSum(i, reinterpret_cast<Scalar*>(&col[i]));
00933         return col;
00934     }
00935 
00936     //TODO: make unary +/- return a self-view so they won't reallocate?
00937     const MatrixBase& operator+() const {return *this; }
00938     const TNeg&       negate()    const {return *reinterpret_cast<const TNeg*>(this); }
00939     TNeg&             updNegate()       {return *reinterpret_cast<TNeg*>(this); }
00940 
00941     const TNeg&       operator-() const {return negate();}
00942     TNeg&             operator-()       {return updNegate();}
00943 
00944     MatrixBase& negateInPlace() {(*this) *= EPrecision(-1); return *this;}
00945  
00950     MatrixBase& resize(int m, int n)     { helper.resize(m,n); return *this; }
00956     MatrixBase& resizeKeep(int m, int n) { helper.resizeKeep(m,n); return *this; }
00957 
00958     // This prevents shape changes in a Matrix that would otherwise allow it. No harm if is
00959     // are called on a Matrix that is locked already; it always succeeds.
00960     void lockShape() {helper.lockShape();}
00961 
00962     // This allows shape changes again for a Matrix which was constructed to allow them
00963     // but had them locked with the above routine. No harm if this is called on a Matrix
00964     // that is already unlocked, but it is not allowed to call this on a Matrix which
00965     // *never* allowed resizing. An exception will be thrown in that case.
00966     void unlockShape() {helper.unlockShape();}
00967     
00968     // An assortment of handy conversions
00969     const MatrixView_<ELT>& getAsMatrixView() const { return *reinterpret_cast<const MatrixView_<ELT>*>(this); }
00970     MatrixView_<ELT>&       updAsMatrixView()       { return *reinterpret_cast<      MatrixView_<ELT>*>(this); } 
00971     const Matrix_<ELT>&     getAsMatrix()     const { return *reinterpret_cast<const Matrix_<ELT>*>(this); }
00972     Matrix_<ELT>&           updAsMatrix()           { return *reinterpret_cast<      Matrix_<ELT>*>(this); }
00973          
00974     const VectorView_<ELT>& getAsVectorView() const 
00975       { assert(ncol()==1); return *reinterpret_cast<const VectorView_<ELT>*>(this); }
00976     VectorView_<ELT>&       updAsVectorView()       
00977       { assert(ncol()==1); return *reinterpret_cast<      VectorView_<ELT>*>(this); } 
00978     const Vector_<ELT>&     getAsVector()     const 
00979       { assert(ncol()==1); return *reinterpret_cast<const Vector_<ELT>*>(this); }
00980     Vector_<ELT>&           updAsVector()           
00981       { assert(ncol()==1); return *reinterpret_cast<      Vector_<ELT>*>(this); }
00982     const VectorBase<ELT>& getAsVectorBase() const 
00983       { assert(ncol()==1); return *reinterpret_cast<const VectorBase<ELT>*>(this); }
00984     VectorBase<ELT>&       updAsVectorBase()       
00985       { assert(ncol()==1); return *reinterpret_cast<      VectorBase<ELT>*>(this); } 
00986                 
00987     const RowVectorView_<ELT>& getAsRowVectorView() const 
00988       { assert(nrow()==1); return *reinterpret_cast<const RowVectorView_<ELT>*>(this); }
00989     RowVectorView_<ELT>&       updAsRowVectorView()       
00990       { assert(nrow()==1); return *reinterpret_cast<      RowVectorView_<ELT>*>(this); } 
00991     const RowVector_<ELT>&     getAsRowVector()     const 
00992       { assert(nrow()==1); return *reinterpret_cast<const RowVector_<ELT>*>(this); }
00993     RowVector_<ELT>&           updAsRowVector()           
00994       { assert(nrow()==1); return *reinterpret_cast<      RowVector_<ELT>*>(this); }        
00995     const RowVectorBase<ELT>& getAsRowVectorBase() const 
00996       { assert(nrow()==1); return *reinterpret_cast<const RowVectorBase<ELT>*>(this); }
00997     RowVectorBase<ELT>&       updAsRowVectorBase()       
00998       { assert(nrow()==1); return *reinterpret_cast<      RowVectorBase<ELT>*>(this); } 
00999 
01000     // Access to raw data. We have to return the raw data
01001     // pointer as pointer-to-scalar because we may pack the elements tighter
01002     // than a C++ array would.
01003 
01007     int getNScalarsPerElement()  const {return NScalarsPerElement;}
01008 
01012     int getPackedSizeofElement() const {return NScalarsPerElement*sizeof(Scalar);}
01013 
01014     bool hasContiguousData() const {return helper.hasContiguousData();}
01015     ptrdiff_t getContiguousScalarDataLength() const {
01016         return helper.getContiguousDataLength();
01017     }
01018     const Scalar* getContiguousScalarData() const {
01019         return helper.getContiguousData();
01020     }
01021     Scalar* updContiguousScalarData() {
01022         return helper.updContiguousData();
01023     }
01024     void replaceContiguousScalarData(Scalar* newData, ptrdiff_t length, bool takeOwnership) {
01025         helper.replaceContiguousData(newData,length,takeOwnership);
01026     }
01027     void replaceContiguousScalarData(const Scalar* newData, ptrdiff_t length) {
01028         helper.replaceContiguousData(newData,length);
01029     }
01030     void swapOwnedContiguousScalarData(Scalar* newData, ptrdiff_t length, Scalar*& oldData) {
01031         helper.swapOwnedContiguousData(newData,length,oldData);
01032     }
01033 
01038     explicit MatrixBase(MatrixHelperRep<Scalar>* hrep) : helper(hrep) {}
01039 
01040 protected:
01041     const MatrixHelper<Scalar>& getHelper() const {return helper;}
01042     MatrixHelper<Scalar>&       updHelper()       {return helper;}
01043 
01044 private:
01045     MatrixHelper<Scalar> helper; // this is just one pointer
01046 
01047     template <class EE> friend class MatrixBase;
01048 };
01049 
01050 
01051 
01052 //  -------------------------------- VectorBase --------------------------------
01056 //  ----------------------------------------------------------------------------
01057 template <class ELT> class VectorBase : public MatrixBase<ELT> {
01058     typedef MatrixBase<ELT>                             Base;
01059     typedef typename Base::ScalarNormSq                 ScalarNormSq;
01060     typedef typename Base::EAbs                         EAbs;
01061     typedef typename CNT<ELT>::Scalar                   Scalar;
01062     typedef typename CNT<ELT>::Number                   Number;
01063     typedef typename CNT<ELT>::StdNumber                StdNumber;
01064     typedef VectorBase<ELT>                             T;
01065     typedef VectorBase<typename CNT<ELT>::TAbs>         TAbs;
01066     typedef VectorBase<typename CNT<ELT>::TNeg>         TNeg;
01067     typedef RowVectorView_<typename CNT<ELT>::THerm>    THerm;
01068 public:  
01069     //  ------------------------------------------------------------------------
01079 
01082     explicit VectorBase(int m=0) : Base(MatrixCommitment::Vector(), m, 1) {}
01083 
01087     VectorBase(const VectorBase& source) : Base(source) {}
01088 
01090     VectorBase(const TNeg& source) : Base(source) {}
01091 
01094     VectorBase(int m, const ELT& initialValue)
01095     :   Base(MatrixCommitment::Vector(),m,1,initialValue) {}  
01096 
01101     VectorBase(int m, const ELT* cppInitialValues)
01102     :   Base(MatrixCommitment::Vector(),m,1,cppInitialValues) {}
01104 
01105     //  ------------------------------------------------------------------------
01114 
01116     VectorBase(int m, int stride, const Scalar* s)
01117     :   Base(MatrixCommitment::Vector(m), MatrixCharacter::Vector(m),stride,s) { }
01119     VectorBase(int m, int stride, Scalar* s)
01120     :   Base(MatrixCommitment::Vector(m), MatrixCharacter::Vector(m),stride,s) { }
01122         
01123     //  ------------------------------------------------------------------------
01130 
01132     VectorBase(MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::ShallowCopy& s) 
01133     :   Base(MatrixCommitment::Vector(), h,s) { }
01135     VectorBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::ShallowCopy& s) 
01136     :   Base(MatrixCommitment::Vector(), h,s) { }
01138     VectorBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::DeepCopy& d)    
01139     :   Base(MatrixCommitment::Vector(), h,d) { }
01141 
01142     // This gives the resulting vector type when (v[i] op P) is applied to each element.
01143     // It will have element types which are the regular composite result of ELT op P.
01144     template <class P> struct EltResult { 
01145         typedef VectorBase<typename CNT<ELT>::template Result<P>::Mul> Mul;
01146         typedef VectorBase<typename CNT<ELT>::template Result<P>::Dvd> Dvd;
01147         typedef VectorBase<typename CNT<ELT>::template Result<P>::Add> Add;
01148         typedef VectorBase<typename CNT<ELT>::template Result<P>::Sub> Sub;
01149     };
01150 
01153     VectorBase& operator=(const VectorBase& b) {
01154         Base::operator=(b); return *this;
01155     }
01156 
01157     // default destructor
01158 
01159 
01160     VectorBase& operator*=(const StdNumber& t)  { Base::operator*=(t); return *this; }
01161     VectorBase& operator/=(const StdNumber& t)  { Base::operator/=(t); return *this; }
01162     VectorBase& operator+=(const VectorBase& r) { Base::operator+=(r); return *this; }
01163     VectorBase& operator-=(const VectorBase& r) { Base::operator-=(r); return *this; }  
01164 
01165 
01166     template <class EE> VectorBase& operator=(const VectorBase<EE>& b) 
01167       { Base::operator=(b);  return *this; } 
01168     template <class EE> VectorBase& operator+=(const VectorBase<EE>& b) 
01169       { Base::operator+=(b); return *this; } 
01170     template <class EE> VectorBase& operator-=(const VectorBase<EE>& b) 
01171       { Base::operator-=(b); return *this; } 
01172 
01173 
01177     VectorBase& operator=(const ELT& t) { Base::setTo(t); return *this; }  
01178 
01183     template <class EE> VectorBase& rowScaleInPlace(const VectorBase<EE>& v)
01184     { Base::template rowScaleInPlace<EE>(v); return *this; }
01185     template <class EE> inline void rowScale(const VectorBase<EE>& v, typename EltResult<EE>::Mul& out) const
01186     { Base::rowScale(v,out); }
01187     template <class EE> inline typename EltResult<EE>::Mul rowScale(const VectorBase<EE>& v) const
01188     { typename EltResult<EE>::Mul out(nrow()); Base::rowScale(v,out); return out; }
01189 
01194     typename CNT<ScalarNormSq>::TSqrt 
01195     normRMS(int* worstOne=0) const {
01196         if (!CNT<ELT>::IsScalar)
01197             SimTK_THROW1(Exception::Cant, 
01198                 "Vector::normRMS() only defined for scalar elements.");
01199         const int n = nrow();
01200         if (n == 0) {
01201             if (worstOne) *worstOne = -1;
01202             return typename CNT<ScalarNormSq>::TSqrt(0);
01203         }
01204 
01205         ScalarNormSq sumsq = 0;
01206         if (worstOne) {
01207             *worstOne = 0;
01208             ScalarNormSq maxsq = 0; 
01209             for (int i=0; i<n; ++i) {
01210                 const ScalarNormSq v2 = square((*this)[i]);
01211                 if (v2 > maxsq) maxsq=v2, *worstOne=i;
01212                 sumsq += v2;
01213             }
01214         } else { // don't track the worst element
01215             for (int i=0; i<n; ++i) {
01216                 const ScalarNormSq v2 = square((*this)[i]);
01217                 sumsq += v2;
01218             }
01219         }
01220 
01221         return CNT<ScalarNormSq>::sqrt(sumsq/n);
01222     }
01223 
01229     template <class EE>
01230     typename CNT<ScalarNormSq>::TSqrt 
01231     weightedNormRMS(const VectorBase<EE>& w, int* worstOne=0) const {
01232         if (!CNT<ELT>::IsScalar || !CNT<EE>::IsScalar)
01233             SimTK_THROW1(Exception::Cant, 
01234             "Vector::weightedNormRMS() only defined for scalar elements"
01235             " and weights.");
01236         const int n = nrow();
01237         assert(w.nrow()==n);
01238         if (n == 0) {
01239             if (worstOne) *worstOne = -1;
01240             return typename CNT<ScalarNormSq>::TSqrt(0);
01241         }
01242 
01243         ScalarNormSq sumsq = 0;
01244         if (worstOne) {
01245             *worstOne = 0;
01246             ScalarNormSq maxsq = 0; 
01247             for (int i=0; i<n; ++i) {
01248                 const ScalarNormSq wv2 = square(w[i]*(*this)[i]);
01249                 if (wv2 > maxsq) maxsq=wv2, *worstOne=i;
01250                 sumsq += wv2;
01251             }
01252         } else { // don't track the worst element
01253             for (int i=0; i<n; ++i) {
01254                 const ScalarNormSq wv2 = square(w[i]*(*this)[i]);
01255                 sumsq += wv2;
01256             }
01257         }
01258 
01259         return CNT<ScalarNormSq>::sqrt(sumsq/n);
01260     }
01261 
01266     EAbs normInf(int* worstOne=0) const {
01267         if (!CNT<ELT>::IsScalar)
01268             SimTK_THROW1(Exception::Cant, 
01269                 "Vector::normInf() only defined for scalar elements.");
01270         const int n = nrow();
01271         if (n == 0) {
01272             if (worstOne) *worstOne = -1;
01273             return EAbs(0);
01274         }
01275 
01276         EAbs maxabs = 0;
01277         if (worstOne) {
01278             *worstOne = 0;
01279             for (int i=0; i<n; ++i) {
01280                 const EAbs a = std::abs((*this)[i]);
01281                 if (a > maxabs) maxabs=a, *worstOne=i;
01282             }
01283         } else { // don't track the worst element
01284             for (int i=0; i<n; ++i) {
01285                 const EAbs a = std::abs((*this)[i]);
01286                 if (a > maxabs) maxabs=a;
01287             }
01288         }
01289 
01290         return maxabs;
01291     }
01292 
01298     template <class EE>
01299     EAbs weightedNormInf(const VectorBase<EE>& w, int* worstOne=0) const {
01300         if (!CNT<ELT>::IsScalar || !CNT<EE>::IsScalar)
01301             SimTK_THROW1(Exception::Cant, 
01302             "Vector::weightedNormInf() only defined for scalar elements"
01303             " and weights.");
01304         const int n = nrow();
01305         assert(w.nrow()==n);
01306         if (n == 0) {
01307             if (worstOne) *worstOne = -1;
01308             return EAbs(0);
01309         }
01310 
01311         EAbs maxabs = 0;
01312         if (worstOne) {
01313             *worstOne = 0;
01314             for (int i=0; i<n; ++i) {
01315                 const EAbs wv = std::abs(w[i]*(*this)[i]);
01316                 if (wv > maxabs) maxabs=wv, *worstOne=i;
01317             }
01318         } else { // don't track the worst element
01319             for (int i=0; i<n; ++i) {
01320                 const EAbs wv = std::abs(w[i]*(*this)[i]);
01321                 if (wv > maxabs) maxabs=wv;
01322             }
01323         }
01324 
01325         return maxabs;
01326     }
01327 
01329     VectorBase& elementwiseInvertInPlace() {
01330         Base::elementwiseInvertInPlace();
01331         return *this;
01332     }
01333 
01335     void elementwiseInvert(VectorBase<typename CNT<ELT>::TInvert>& out) const {
01336         Base::elementwiseInvert(out);
01337     }
01338 
01340     VectorBase<typename CNT<ELT>::TInvert> elementwiseInvert() const {
01341         VectorBase<typename CNT<ELT>::TInvert> out(nrow());
01342         Base::elementwiseInvert(out);
01343         return out;
01344     }
01345 
01346     // elementwise multiply
01347     template <class EE> VectorBase& elementwiseMultiplyInPlace(const VectorBase<EE>& r)
01348     { Base::template elementwiseMultiplyInPlace<EE>(r); return *this; }
01349     template <class EE> inline void elementwiseMultiply(const VectorBase<EE>& v, typename EltResult<EE>::Mul& out) const
01350     { Base::template elementwiseMultiply<EE>(v,out); }
01351     template <class EE> inline typename EltResult<EE>::Mul elementwiseMultiply(const VectorBase<EE>& v) const
01352     { typename EltResult<EE>::Mul out(nrow()); Base::template elementwiseMultiply<EE>(v,out); return out; }
01353 
01354     // elementwise multiply from left
01355     template <class EE> VectorBase& elementwiseMultiplyFromLeftInPlace(const VectorBase<EE>& r)
01356     { Base::template elementwiseMultiplyFromLeftInPlace<EE>(r); return *this; }
01357     template <class EE> inline void 
01358     elementwiseMultiplyFromLeft(
01359         const VectorBase<EE>& v, 
01360         typename VectorBase<EE>::template EltResult<ELT>::Mul& out) const
01361     { 
01362         Base::template elementwiseMultiplyFromLeft<EE>(v,out);
01363     }
01364     template <class EE> inline typename VectorBase<EE>::template EltResult<ELT>::Mul 
01365     elementwiseMultiplyFromLeft(const VectorBase<EE>& v) const
01366     { 
01367         typename VectorBase<EE>::template EltResult<ELT>::Mul out(nrow()); 
01368         Base::template elementwiseMultiplyFromLeft<EE>(v,out); 
01369         return out;
01370     }
01371 
01372     // elementwise divide
01373     template <class EE> VectorBase& elementwiseDivideInPlace(const VectorBase<EE>& r)
01374     { Base::template elementwiseDivideInPlace<EE>(r); return *this; }
01375     template <class EE> inline void elementwiseDivide(const VectorBase<EE>& v, typename EltResult<EE>::Dvd& out) const
01376     { Base::template elementwiseDivide<EE>(v,out); }
01377     template <class EE> inline typename EltResult<EE>::Dvd elementwiseDivide(const VectorBase<EE>& v) const
01378     { typename EltResult<EE>::Dvd out(nrow()); Base::template elementwiseDivide<EE>(v,out); return out; }
01379 
01380     // elementwise divide from left
01381     template <class EE> VectorBase& elementwiseDivideFromLeftInPlace(const VectorBase<EE>& r)
01382     { Base::template elementwiseDivideFromLeftInPlace<EE>(r); return *this; }
01383     template <class EE> inline void 
01384     elementwiseDivideFromLeft(
01385         const VectorBase<EE>& v, 
01386         typename VectorBase<EE>::template EltResult<ELT>::Dvd& out) const
01387     { 
01388         Base::template elementwiseDivideFromLeft<EE>(v,out);
01389     }
01390     template <class EE> inline typename VectorBase<EE>::template EltResult<ELT>::Dvd 
01391     elementwiseDivideFromLeft(const VectorBase<EE>& v) const
01392     { 
01393         typename VectorBase<EE>::template EltResult<ELT>::Dvd out(nrow()); 
01394         Base::template elementwiseDivideFromLeft<EE>(v,out); 
01395         return out;
01396     }
01397 
01398     // Implicit conversions are allowed to Vector or Matrix, but not to RowVector.   
01399     operator const Vector_<ELT>&()     const { return *reinterpret_cast<const Vector_<ELT>*>(this); }
01400     operator       Vector_<ELT>&()           { return *reinterpret_cast<      Vector_<ELT>*>(this); }
01401     operator const VectorView_<ELT>&() const { return *reinterpret_cast<const VectorView_<ELT>*>(this); }
01402     operator       VectorView_<ELT>&()       { return *reinterpret_cast<      VectorView_<ELT>*>(this); }
01403     
01404     operator const Matrix_<ELT>&()     const { return *reinterpret_cast<const Matrix_<ELT>*>(this); }
01405     operator       Matrix_<ELT>&()           { return *reinterpret_cast<      Matrix_<ELT>*>(this); } 
01406     operator const MatrixView_<ELT>&() const { return *reinterpret_cast<const MatrixView_<ELT>*>(this); }
01407     operator       MatrixView_<ELT>&()       { return *reinterpret_cast<      MatrixView_<ELT>*>(this); } 
01408 
01409 
01410     // size() for Vectors is Base::nelt() but returns int instead of ptrdiff_t.
01411     int size() const { 
01412     assert(Base::nelt() <= (ptrdiff_t)std::numeric_limits<int>::max()); 
01413     assert(Base::ncol()==1);
01414     return (int)Base::nelt();
01415     }
01416     int       nrow() const {assert(Base::ncol()==1); return Base::nrow();}
01417     int       ncol() const {assert(Base::ncol()==1); return Base::ncol();}
01418     ptrdiff_t nelt() const {assert(Base::ncol()==1); return Base::nelt();}
01419 
01420     // Override MatrixBase operators to return the right shape
01421     TAbs abs() const {TAbs result; Base::abs(result); return result;}
01422     
01423     // Override MatrixBase indexing operators          
01424     const ELT& operator[](int i) const {return *reinterpret_cast<const ELT*>(Base::getHelper().getElt(i));}
01425     ELT&       operator[](int i)       {return *reinterpret_cast<ELT*>      (Base::updHelper().updElt(i));}
01426     const ELT& operator()(int i) const {return *reinterpret_cast<const ELT*>(Base::getHelper().getElt(i));}
01427     ELT&       operator()(int i)       {return *reinterpret_cast<ELT*>      (Base::updHelper().updElt(i));}
01428          
01429     // Block (contiguous subvector) view creation      
01430     VectorView_<ELT> operator()(int i, int m) const {return Base::operator()(i,0,m,1).getAsVectorView();}
01431     VectorView_<ELT> operator()(int i, int m)       {return Base::operator()(i,0,m,1).updAsVectorView();}
01432 
01433     // Indexed view creation (arbitrary subvector). Indices must be 
01434     // monotonically increasing.
01435     VectorView_<ELT> index(const Array_<int>& indices) const {
01436         MatrixHelper<Scalar> h(Base::getHelper().getCharacterCommitment(), 
01437                                Base::getHelper(), indices);
01438         return VectorView_<ELT>(h);
01439     }
01440     VectorView_<ELT> updIndex(const Array_<int>& indices) {
01441         MatrixHelper<Scalar> h(Base::getHelper().getCharacterCommitment(), 
01442                                Base::updHelper(), indices);
01443         return VectorView_<ELT>(h);
01444     }
01445 
01446     VectorView_<ELT> operator()(const Array_<int>& indices) const {return index(indices);}
01447     VectorView_<ELT> operator()(const Array_<int>& indices)       {return updIndex(indices);}
01448  
01449     // Hermitian transpose.
01450     THerm transpose() const {return Base::transpose().getAsRowVectorView();}
01451     THerm updTranspose()    {return Base::updTranspose().updAsRowVectorView();}
01452 
01453     THerm operator~() const {return transpose();}
01454     THerm operator~()       {return updTranspose();}
01455 
01456     const VectorBase& operator+() const {return *this; }
01457 
01458     // Negation
01459 
01460     const TNeg& negate()    const {return *reinterpret_cast<const TNeg*>(this); }
01461     TNeg&       updNegate()       {return *reinterpret_cast<TNeg*>(this); }
01462 
01463     const TNeg& operator-() const {return negate();}
01464     TNeg&       operator-()       {return updNegate();}
01465 
01466     VectorBase& resize(int m)     {Base::resize(m,1); return *this;}
01467     VectorBase& resizeKeep(int m) {Base::resizeKeep(m,1); return *this;}
01468 
01469     //TODO: this is not re-locking the number of columns at 1.
01470     void clear() {Base::clear(); Base::resize(0,1);}
01471 
01472     ELT sum() const {ELT s; Base::getHelper().sum(reinterpret_cast<Scalar*>(&s)); return s; } // add all the elements        
01473     VectorIterator<ELT, VectorBase<ELT> > begin() {
01474         return VectorIterator<ELT, VectorBase<ELT> >(*this, 0);
01475     }
01476     VectorIterator<ELT, VectorBase<ELT> > end() {
01477         return VectorIterator<ELT, VectorBase<ELT> >(*this, size());
01478     }
01479 
01480 protected:
01481     // Create a VectorBase handle using a given helper rep. 
01482     explicit VectorBase(MatrixHelperRep<Scalar>* hrep) : Base(hrep) {}
01483 
01484 private:
01485     // NO DATA MEMBERS ALLOWED
01486 };
01487 
01488 
01489 
01490 //  ------------------------------- RowVectorBase ------------------------------
01494 //  ----------------------------------------------------------------------------
01495 template <class ELT> class RowVectorBase : public MatrixBase<ELT> {
01496     typedef MatrixBase<ELT>                             Base;
01497     typedef typename CNT<ELT>::Scalar                   Scalar;
01498     typedef typename CNT<ELT>::Number                   Number;
01499     typedef typename CNT<ELT>::StdNumber                StdNumber;
01500     typedef RowVectorBase<ELT>                          T;
01501     typedef RowVectorBase<typename CNT<ELT>::TAbs>      TAbs;
01502     typedef RowVectorBase<typename CNT<ELT>::TNeg>      TNeg;
01503     typedef VectorView_<typename CNT<ELT>::THerm>       THerm;
01504 public: 
01505     //  ------------------------------------------------------------------------
01515 
01518     explicit RowVectorBase(int n=0) : Base(MatrixCommitment::RowVector(), 1, n) {}
01519     
01523     RowVectorBase(const RowVectorBase& source) : Base(source) {}
01524 
01526     RowVectorBase(const TNeg& source) : Base(source) {}
01527 
01530     RowVectorBase(int n, const ELT& initialValue)
01531     :   Base(MatrixCommitment::RowVector(),1,n,initialValue) {}  
01532 
01537     RowVectorBase(int n, const ELT* cppInitialValues)
01538     :   Base(MatrixCommitment::RowVector(),1,n,cppInitialValues) {}
01540 
01541     //  ------------------------------------------------------------------------
01550 
01552     RowVectorBase(int n, int stride, const Scalar* s)
01553     :   Base(MatrixCommitment::RowVector(n), MatrixCharacter::RowVector(n),stride,s) { }
01555     RowVectorBase(int n, int stride, Scalar* s)
01556     :   Base(MatrixCommitment::RowVector(n), MatrixCharacter::RowVector(n),stride,s) { }
01558 
01559     //  ------------------------------------------------------------------------
01566 
01568     RowVectorBase(MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::ShallowCopy& s) 
01569     :   Base(MatrixCommitment::RowVector(), h,s) { }
01571     RowVectorBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::ShallowCopy& s) 
01572     :   Base(MatrixCommitment::RowVector(), h,s) { }
01574     RowVectorBase(const MatrixHelper<Scalar>& h, const typename MatrixHelper<Scalar>::DeepCopy& d)    
01575     :   Base(MatrixCommitment::RowVector(), h,d) { }
01577 
01578     // This gives the resulting rowvector type when (r(i) op P) is applied to each element.
01579     // It will have element types which are the regular composite result of ELT op P.
01580     template <class P> struct EltResult { 
01581         typedef RowVectorBase<typename CNT<ELT>::template Result<P>::Mul> Mul;
01582         typedef RowVectorBase<typename CNT<ELT>::template Result<P>::Dvd> Dvd;
01583         typedef RowVectorBase<typename CNT<ELT>::template Result<P>::Add> Add;
01584         typedef RowVectorBase<typename CNT<ELT>::template Result<P>::Sub> Sub;
01585     };
01586 
01589     RowVectorBase& operator=(const RowVectorBase& b) {
01590         Base::operator=(b); return *this;
01591     }
01592 
01593     // default destructor
01594 
01595     RowVectorBase& operator*=(const StdNumber& t)     {Base::operator*=(t); return *this;}
01596     RowVectorBase& operator/=(const StdNumber& t)     {Base::operator/=(t); return *this;}
01597     RowVectorBase& operator+=(const RowVectorBase& r) {Base::operator+=(r); return *this;}
01598     RowVectorBase& operator-=(const RowVectorBase& r) {Base::operator-=(r); return *this;}  
01599 
01600     template <class EE> RowVectorBase& operator=(const RowVectorBase<EE>& b) 
01601       { Base::operator=(b);  return *this; } 
01602     template <class EE> RowVectorBase& operator+=(const RowVectorBase<EE>& b) 
01603       { Base::operator+=(b); return *this; } 
01604     template <class EE> RowVectorBase& operator-=(const RowVectorBase<EE>& b) 
01605       { Base::operator-=(b); return *this; } 
01606 
01607     // default destructor
01608  
01612     RowVectorBase& operator=(const ELT& t) { Base::setTo(t); return *this; } 
01613 
01618     template <class EE> RowVectorBase& colScaleInPlace(const VectorBase<EE>& v)
01619     { Base::template colScaleInPlace<EE>(v); return *this; }
01620     template <class EE> inline void colScale(const VectorBase<EE>& v, typename EltResult<EE>::Mul& out) const
01621     { return Base::template colScale<EE>(v,out); }
01622     template <class EE> inline typename EltResult<EE>::Mul colScale(const VectorBase<EE>& v) const
01623     { typename EltResult<EE>::Mul out(ncol()); Base::template colScale<EE>(v,out); return out; }
01624 
01625 
01626     // elementwise multiply
01627     template <class EE> RowVectorBase& elementwiseMultiplyInPlace(const RowVectorBase<EE>& r)
01628     { Base::template elementwiseMultiplyInPlace<EE>(r); return *this; }
01629     template <class EE> inline void elementwiseMultiply(const RowVectorBase<EE>& v, typename EltResult<EE>::Mul& out) const
01630     { Base::template elementwiseMultiply<EE>(v,out); }
01631     template <class EE> inline typename EltResult<EE>::Mul elementwiseMultiply(const RowVectorBase<EE>& v) const
01632     { typename EltResult<EE>::Mul out(nrow()); Base::template elementwiseMultiply<EE>(v,out); return out; }
01633 
01634     // elementwise multiply from left
01635     template <class EE> RowVectorBase& elementwiseMultiplyFromLeftInPlace(const RowVectorBase<EE>& r)
01636     { Base::template elementwiseMultiplyFromLeftInPlace<EE>(r); return *this; }
01637     template <class EE> inline void 
01638     elementwiseMultiplyFromLeft(
01639         const RowVectorBase<EE>& v, 
01640         typename RowVectorBase<EE>::template EltResult<ELT>::Mul& out) const
01641     { 
01642         Base::template elementwiseMultiplyFromLeft<EE>(v,out);
01643     }
01644     template <class EE> inline 
01645     typename RowVectorBase<EE>::template EltResult<ELT>::Mul 
01646     elementwiseMultiplyFromLeft(const RowVectorBase<EE>& v) const {
01647         typename RowVectorBase<EE>::template EltResult<ELT>::Mul out(nrow()); 
01648         Base::template elementwiseMultiplyFromLeft<EE>(v,out); 
01649         return out;
01650     }
01651 
01652     // elementwise divide
01653     template <class EE> RowVectorBase& elementwiseDivideInPlace(const RowVectorBase<EE>& r)
01654     { Base::template elementwiseDivideInPlace<EE>(r); return *this; }
01655     template <class EE> inline void elementwiseDivide(const RowVectorBase<EE>& v, typename EltResult<EE>::Dvd& out) const
01656     { Base::template elementwiseDivide<EE>(v,out); }
01657     template <class EE> inline typename EltResult<EE>::Dvd elementwiseDivide(const RowVectorBase<EE>& v) const
01658     { typename EltResult<EE>::Dvd out(nrow()); Base::template elementwiseDivide<EE>(v,out); return out; }
01659 
01660     // elementwise divide from left
01661     template <class EE> RowVectorBase& elementwiseDivideFromLeftInPlace(const RowVectorBase<EE>& r)
01662     { Base::template elementwiseDivideFromLeftInPlace<EE>(r); return *this; }
01663     template <class EE> inline void 
01664     elementwiseDivideFromLeft
01665        (const RowVectorBase<EE>& v, 
01666         typename RowVectorBase<EE>::template EltResult<ELT>::Dvd& out) const { 
01667         Base::template elementwiseDivideFromLeft<EE>(v,out);
01668     }
01669     template <class EE> inline 
01670     typename RowVectorBase<EE>::template EltResult<ELT>::Dvd 
01671     elementwiseDivideFromLeft(const RowVectorBase<EE>& v) const { 
01672         typename RowVectorBase<EE>::template EltResult<ELT>::Dvd out(nrow()); 
01673         Base::template elementwiseDivideFromLeft<EE>(v,out); 
01674         return out;
01675     }
01676 
01677     // Implicit conversions are allowed to RowVector or Matrix, but not to Vector.   
01678     operator const RowVector_<ELT>&()     const {return *reinterpret_cast<const RowVector_<ELT>*>(this);}
01679     operator       RowVector_<ELT>&()           {return *reinterpret_cast<      RowVector_<ELT>*>(this);}
01680     operator const RowVectorView_<ELT>&() const {return *reinterpret_cast<const RowVectorView_<ELT>*>(this);}
01681     operator       RowVectorView_<ELT>&()       {return *reinterpret_cast<      RowVectorView_<ELT>*>(this);}
01682     
01683     operator const Matrix_<ELT>&()     const {return *reinterpret_cast<const Matrix_<ELT>*>(this);}
01684     operator       Matrix_<ELT>&()           {return *reinterpret_cast<      Matrix_<ELT>*>(this);} 
01685     operator const MatrixView_<ELT>&() const {return *reinterpret_cast<const MatrixView_<ELT>*>(this);}
01686     operator       MatrixView_<ELT>&()       {return *reinterpret_cast<      MatrixView_<ELT>*>(this);} 
01687     
01688 
01689     // size() for RowVectors is Base::nelt() but returns int instead of ptrdiff_t.
01690     int size() const { 
01691         assert(Base::nelt() <= (ptrdiff_t)std::numeric_limits<int>::max()); 
01692         assert(Base::nrow()==1);
01693         return (int)Base::nelt();
01694     }
01695     int       nrow() const {assert(Base::nrow()==1); return Base::nrow();}
01696     int       ncol() const {assert(Base::nrow()==1); return Base::ncol();}
01697     ptrdiff_t nelt() const {assert(Base::nrow()==1); return Base::nelt();}
01698 
01699     // Override MatrixBase operators to return the right shape
01700     TAbs abs() const {
01701         TAbs result; Base::abs(result); return result;
01702     }
01703 
01704     // Override MatrixBase indexing operators          
01705     const ELT& operator[](int j) const {return *reinterpret_cast<const ELT*>(Base::getHelper().getElt(j));}
01706     ELT&       operator[](int j)       {return *reinterpret_cast<ELT*>      (Base::updHelper().updElt(j));}
01707     const ELT& operator()(int j) const {return *reinterpret_cast<const ELT*>(Base::getHelper().getElt(j));}
01708     ELT&       operator()(int j)       {return *reinterpret_cast<ELT*>      (Base::updHelper().updElt(j));}
01709          
01710     // Block (contiguous subvector) creation      
01711     RowVectorView_<ELT> operator()(int j, int n) const {return Base::operator()(0,j,1,n).getAsRowVectorView();}
01712     RowVectorView_<ELT> operator()(int j, int n)       {return Base::operator()(0,j,1,n).updAsRowVectorView();}
01713 
01714     // Indexed view creation (arbitrary subvector). Indices must be monotonically increasing.
01715     RowVectorView_<ELT> index(const Array_<int>& indices) const {
01716         MatrixHelper<Scalar> h(Base::getHelper().getCharacterCommitment(), Base::getHelper(), indices);
01717         return RowVectorView_<ELT>(h);
01718     }
01719     RowVectorView_<ELT> updIndex(const Array_<int>& indices) {
01720         MatrixHelper<Scalar> h(Base::getHelper().getCharacterCommitment(), Base::updHelper(), indices);
01721         return RowVectorView_<ELT>(h);
01722     }
01723 
01724     RowVectorView_<ELT> operator()(const Array_<int>& indices) const {return index(indices);}
01725     RowVectorView_<ELT> operator()(const Array_<int>& indices)       {return updIndex(indices);}
01726  
01727     // Hermitian transpose.
01728     THerm transpose() const {return Base::transpose().getAsVectorView();}
01729     THerm updTranspose()    {return Base::updTranspose().updAsVectorView();}
01730 
01731     THerm operator~() const {return transpose();}
01732     THerm operator~()       {return updTranspose();}
01733 
01734     const RowVectorBase& operator+() const {return *this; }
01735 
01736     // Negation
01737 
01738     const TNeg& negate()    const {return *reinterpret_cast<const TNeg*>(this); }
01739     TNeg&       updNegate()       {return *reinterpret_cast<TNeg*>(this); }
01740 
01741     const TNeg& operator-() const {return negate();}
01742     TNeg&       operator-()       {return updNegate();}
01743 
01744     RowVectorBase& resize(int n)     {Base::resize(1,n); return *this;}
01745     RowVectorBase& resizeKeep(int n) {Base::resizeKeep(1,n); return *this;}
01746 
01747     //TODO: this is not re-locking the number of rows at 1.
01748     void clear() {Base::clear(); Base::resize(1,0);}
01749 
01750     ELT sum() const {ELT s; Base::getHelper().sum(reinterpret_cast<Scalar*>(&s)); return s; } // add all the elements        
01751     VectorIterator<ELT, RowVectorBase<ELT> > begin() {
01752         return VectorIterator<ELT, RowVectorBase<ELT> >(*this, 0);
01753     }
01754     VectorIterator<ELT, RowVectorBase<ELT> > end() {
01755         return VectorIterator<ELT, RowVectorBase<ELT> >(*this, size());
01756     }
01757 
01758 protected:
01759     // Create a RowVectorBase handle using a given helper rep. 
01760     explicit RowVectorBase(MatrixHelperRep<Scalar>* hrep) : Base(hrep) {}
01761 
01762 private:
01763     // NO DATA MEMBERS ALLOWED
01764 };
01765 
01766 
01767 
01768 //  ------------------------------- MatrixView_ --------------------------------
01774 //  ----------------------------------------------------------------------------
01775 template <class ELT> class MatrixView_ : public MatrixBase<ELT> {
01776     typedef MatrixBase<ELT>                 Base;
01777     typedef typename CNT<ELT>::Scalar       S;
01778     typedef typename CNT<ELT>::StdNumber    StdNumber;
01779 public:
01780     // Default construction is suppressed.
01781     // Uses default destructor.
01782 
01783     // Create a MatrixView_ handle using a given helper rep. 
01784     explicit MatrixView_(MatrixHelperRep<S>* hrep) : Base(hrep) {}
01785 
01786     // Copy constructor is shallow. CAUTION: despite const argument, this preserves writability
01787     // if it was present in the source. This is necessary to allow temporary views to be
01788     // created and used as lvalues.
01789     MatrixView_(const MatrixView_& m) 
01790       : Base(MatrixCommitment(),
01791              const_cast<MatrixHelper<S>&>(m.getHelper()), 
01792              typename MatrixHelper<S>::ShallowCopy()) {}
01793 
01794     // Copy assignment is deep but not reallocating.
01795     MatrixView_& operator=(const MatrixView_& m) {
01796         Base::operator=(m); return *this;
01797     }
01798 
01799     // Copy construction and copy assignment from a DeadMatrixView steals the helper.
01800     MatrixView_(DeadMatrixView_<ELT>&);
01801     MatrixView_& operator=(DeadMatrixView_<ELT>&);
01802 
01803     // Ask for shallow copy    
01804     MatrixView_(const MatrixHelper<S>& h) : Base(MatrixCommitment(), h, typename MatrixHelper<S>::ShallowCopy()) { }
01805     MatrixView_(MatrixHelper<S>&       h) : Base(MatrixCommitment(), h, typename MatrixHelper<S>::ShallowCopy()) { }
01806 
01807     MatrixView_& operator=(const Matrix_<ELT>& v)     { Base::operator=(v); return *this; }
01808     MatrixView_& operator=(const ELT& e)              { Base::operator=(e); return *this; }
01809 
01810     template <class EE> MatrixView_& operator=(const MatrixBase<EE>& m)
01811       { Base::operator=(m); return *this; }
01812     template <class EE> MatrixView_& operator+=(const MatrixBase<EE>& m)
01813       { Base::operator+=(m); return *this; }
01814     template <class EE> MatrixView_& operator-=(const MatrixBase<EE>& m)
01815       { Base::operator-=(m); return *this; }
01816 
01817     MatrixView_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
01818     MatrixView_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
01819     MatrixView_& operator+=(const ELT& r)       { this->updDiag() += r; return *this; }
01820     MatrixView_& operator-=(const ELT& r)       { this->updDiag() -= r; return *this; }  
01821 
01822     operator const Matrix_<ELT>&() const { return *reinterpret_cast<const Matrix_<ELT>*>(this); }
01823     operator Matrix_<ELT>&()             { return *reinterpret_cast<Matrix_<ELT>*>(this); }      
01824 
01825 private:
01826     // NO DATA MEMBERS ALLOWED
01827     MatrixView_(); // default constructor suppressed (what's it a view of?)
01828 };
01829 
01830 
01831 
01832 //  ----------------------------- DeadMatrixView_ ------------------------------
01836 //  ----------------------------------------------------------------------------
01837 template <class ELT> class DeadMatrixView_ : public MatrixView_<ELT> {
01838     typedef MatrixView_<ELT>                Base;
01839     typedef typename CNT<ELT>::Scalar       S;
01840     typedef typename CNT<ELT>::StdNumber    StdNumber;
01841 public:
01842     // Default construction is suppressed.
01843     // Uses default destructor.
01844     
01845     // All functionality is passed through to MatrixView_.
01846     explicit DeadMatrixView_(MatrixHelperRep<S>* hrep) : Base(hrep) {}
01847     DeadMatrixView_(const Base& m) : Base(m) {}
01848     DeadMatrixView_& operator=(const Base& m) {
01849         Base::operator=(m); return *this;
01850     }
01851 
01852     // Ask for shallow copy    
01853     DeadMatrixView_(const MatrixHelper<S>& h) : Base(h) {}
01854     DeadMatrixView_(MatrixHelper<S>&       h) : Base(h) {}
01855 
01856     DeadMatrixView_& operator=(const Matrix_<ELT>& v)     { Base::operator=(v); return *this; }
01857     DeadMatrixView_& operator=(const ELT& e)              { Base::operator=(e); return *this; }
01858 
01859     template <class EE> DeadMatrixView_& operator=(const MatrixBase<EE>& m)
01860       { Base::operator=(m); return *this; }
01861     template <class EE> DeadMatrixView_& operator+=(const MatrixBase<EE>& m)
01862       { Base::operator+=(m); return *this; }
01863     template <class EE> DeadMatrixView_& operator-=(const MatrixBase<EE>& m)
01864       { Base::operator-=(m); return *this; }
01865 
01866     DeadMatrixView_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
01867     DeadMatrixView_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
01868     DeadMatrixView_& operator+=(const ELT& r)       { this->updDiag() += r; return *this; }
01869     DeadMatrixView_& operator-=(const ELT& r)       { this->updDiag() -= r; return *this; }  
01870 
01871 private:
01872     // NO DATA MEMBERS ALLOWED
01873     DeadMatrixView_(); // default constructor suppressed (what's it a view of?)
01874 };
01875 
01876 template <class ELT> inline 
01877 MatrixView_<ELT>::MatrixView_(DeadMatrixView_<ELT>& dead) 
01878 :   Base(dead.updHelper().stealRep()) {}
01879 
01880 template <class ELT> inline MatrixView_<ELT>& 
01881 MatrixView_<ELT>::operator=(DeadMatrixView_<ELT>& dead) {
01882     if (Base::getHelper().getCharacterCommitment().isSatisfiedBy(dead.getMatrixCharacter()))
01883         Base::updHelper().replaceRep(dead.updHelper().stealRep());
01884     else
01885         Base::operator=(dead);
01886     return *this;
01887 }
01888 
01889 
01890 //  ---------------------------------- Matrix_ ---------------------------------
01893 //  ----------------------------------------------------------------------------
01894 template <class ELT> class Matrix_ : public MatrixBase<ELT> {
01895     typedef typename CNT<ELT>::Scalar       S;
01896     typedef typename CNT<ELT>::Number       Number;
01897     typedef typename CNT<ELT>::StdNumber    StdNumber;
01898 
01899     typedef typename CNT<ELT>::TNeg         ENeg;
01900     typedef typename CNT<ELT>::THerm        EHerm;
01901 
01902     typedef MatrixBase<ELT>     Base;
01903     typedef MatrixBase<ENeg>    BaseNeg;
01904     typedef MatrixBase<EHerm>   BaseHerm;
01905 
01906     typedef Matrix_<ELT>        T;
01907     typedef MatrixView_<ELT>    TView;
01908     typedef Matrix_<ENeg>       TNeg;
01909 
01910 public:
01911     Matrix_() : Base() { }
01912     Matrix_(const MatrixCommitment& mc) : Base(mc) {}
01913 
01914     // Copy constructor is deep.
01915     Matrix_(const Matrix_& src) : Base(src) { }
01916 
01917     // Assignment is a deep copy and will also allow reallocation if this Matrix
01918     // doesn't have a view.
01919     Matrix_& operator=(const Matrix_& src) { 
01920         Base::operator=(src); return *this;
01921     }
01922 
01923     // Force a deep copy of the view or whatever this is.
01924     // Note that this is an implicit conversion.
01925     Matrix_(const Base& v) : Base(v) {}   // e.g., MatrixView
01926 
01927     // Allow implicit conversion from a source matrix that
01928     // has a negated version of ELT.
01929     Matrix_(const BaseNeg& v) : Base(v) {}
01930 
01931     // TODO: implicit conversion from conjugate. This is trickier
01932     // since real elements are their own conjugate so you'll get
01933     // duplicate methods defined from Matrix_(BaseHerm) and Matrix_(Base).
01934 
01935     Matrix_(int m, int n) : Base(MatrixCommitment(), m, n) {}
01936 
01937     Matrix_(int m, int n, const ELT* cppInitialValuesByRow) 
01938     :   Base(MatrixCommitment(), m, n, cppInitialValuesByRow) {}
01939     Matrix_(int m, int n, const ELT& initialValue) 
01940     :   Base(MatrixCommitment(), m, n, initialValue) {}
01941     
01942     Matrix_(int m, int n, int leadingDim, const S* data) // read only
01943     :   Base(MatrixCommitment(), MatrixCharacter::LapackFull(m,n), 
01944              leadingDim, data) {}
01945     Matrix_(int m, int n, int leadingDim, S* data) // writable
01946     :   Base(MatrixCommitment(), MatrixCharacter::LapackFull(m,n), 
01947              leadingDim, data) {}
01948     
01950     template <int M, int N, int CS, int RS>
01951     explicit Matrix_(const Mat<M,N,ELT,CS,RS>& mat)
01952     :   Base(MatrixCommitment(), M, N)
01953     {   for (int i = 0; i < M; ++i)
01954             for (int j = 0; j < N; ++j)
01955                 this->updElt(i, j) = mat(i, j); }
01956 
01957     Matrix_& operator=(const ELT& v) { Base::operator=(v); return *this; }
01958 
01959     template <class EE> Matrix_& operator=(const MatrixBase<EE>& m)
01960       { Base::operator=(m); return*this; }
01961     template <class EE> Matrix_& operator+=(const MatrixBase<EE>& m)
01962       { Base::operator+=(m); return*this; }
01963     template <class EE> Matrix_& operator-=(const MatrixBase<EE>& m)
01964       { Base::operator-=(m); return*this; }
01965 
01966     Matrix_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
01967     Matrix_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
01968     Matrix_& operator+=(const ELT& r)       { this->updDiag() += r; return *this; }
01969     Matrix_& operator-=(const ELT& r)       { this->updDiag() -= r; return *this; }  
01970 
01971     const TNeg& negate()    const {return *reinterpret_cast<const TNeg*>(this); }
01972     TNeg&       updNegate()       {return *reinterpret_cast<TNeg*>(this); }
01973 
01974     const TNeg& operator-() const {return negate();}
01975     TNeg&       operator-()       {return updNegate();}
01976    
01977     // Functions to be used for Scripting in MATLAB and languages that do not support operator overloading
01979     std::string toString() const {
01980         std::stringstream stream;
01981         stream <<  (*this) ;
01982         return stream.str(); 
01983     }
01985     const ELT& get(int i,int j) const { return this->getElt(i,j); }
01987     void       set(int i,int j, const ELT& value)       { this->updElt(i,j)=value; }
01988 
01989 private:
01990     // NO DATA MEMBERS ALLOWED
01991 };
01992 
01993 
01994 
01995 //  -------------------------------- VectorView_ -------------------------------
02001 //  ----------------------------------------------------------------------------
02002 template <class ELT> class VectorView_ : public VectorBase<ELT> {
02003     typedef VectorBase<ELT>                             Base;
02004     typedef typename CNT<ELT>::Scalar                   S;
02005     typedef typename CNT<ELT>::Number                   Number;
02006     typedef typename CNT<ELT>::StdNumber                StdNumber;
02007     typedef VectorView_<ELT>                            T;
02008     typedef VectorView_< typename CNT<ELT>::TNeg >      TNeg;
02009     typedef RowVectorView_< typename CNT<ELT>::THerm >  THerm;
02010 public:
02011     // Default construction is suppressed.
02012     // Uses default destructor.
02013 
02014     // Create a VectorView_ handle using a given helper rep. 
02015     explicit VectorView_(MatrixHelperRep<S>* hrep) : Base(hrep) {}
02016 
02017     // Copy constructor is shallow. CAUTION: despite const argument, this preserves writability
02018     // if it was present in the source. This is necessary to allow temporary views to be
02019     // created and used as lvalues.
02020     VectorView_(const VectorView_& v) 
02021       : Base(const_cast<MatrixHelper<S>&>(v.getHelper()), typename MatrixHelper<S>::ShallowCopy()) { }
02022 
02023     // Copy assignment is deep but not reallocating.
02024     VectorView_& operator=(const VectorView_& v) {
02025         Base::operator=(v); return *this;
02026     }
02027 
02028     // Ask for shallow copy    
02029     explicit VectorView_(const MatrixHelper<S>& h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
02030     explicit VectorView_(MatrixHelper<S>&       h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
02031     
02032     VectorView_& operator=(const Base& b) { Base::operator=(b); return *this; }
02033 
02034     VectorView_& operator=(const ELT& v) { Base::operator=(v); return *this; } 
02035 
02036     template <class EE> VectorView_& operator=(const VectorBase<EE>& m)
02037       { Base::operator=(m); return*this; }
02038     template <class EE> VectorView_& operator+=(const VectorBase<EE>& m)
02039       { Base::operator+=(m); return*this; }
02040     template <class EE> VectorView_& operator-=(const VectorBase<EE>& m)
02041       { Base::operator-=(m); return*this; }
02042 
02043     VectorView_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
02044     VectorView_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
02045     VectorView_& operator+=(const ELT& b) { this->elementwiseAddScalarInPlace(b); return *this; }
02046     VectorView_& operator-=(const ELT& b) { this->elementwiseSubtractScalarInPlace(b); return *this; }
02047 
02048 private:
02049     // NO DATA MEMBERS ALLOWED
02050     VectorView_(); // default construction suppressed (what's it a View of?)
02051 };
02052 
02053 
02054 
02055 //  ---------------------------------- Vector_ ---------------------------------
02059 //  ----------------------------------------------------------------------------
02060 template <class ELT> class Vector_ : public VectorBase<ELT> {
02061     typedef typename CNT<ELT>::Scalar       S;
02062     typedef typename CNT<ELT>::Number       Number;
02063     typedef typename CNT<ELT>::StdNumber    StdNumber;
02064     typedef typename CNT<ELT>::TNeg         ENeg;
02065     typedef VectorBase<ELT>                 Base;
02066     typedef VectorBase<ENeg>                BaseNeg;
02067 public:
02068     Vector_() : Base() {}  // 0x1 reallocatable
02069     // Uses default destructor.
02070 
02071     // Copy constructor is deep.
02072     Vector_(const Vector_& src) : Base(src) {}
02073 
02074     // Implicit conversions.
02075     Vector_(const Base& src) : Base(src) {}    // e.g., VectorView
02076     Vector_(const BaseNeg& src) : Base(src) {}
02077 
02078     // Copy assignment is deep and can be reallocating if this Vector
02079     // has no View.
02080     Vector_& operator=(const Vector_& src) {
02081         Base::operator=(src); return*this;
02082     }
02083 
02084 
02085     explicit Vector_(int m) : Base(m) { }
02086     Vector_(int m, const ELT* cppInitialValues) : Base(m, cppInitialValues) {}
02087     Vector_(int m, const ELT& initialValue)     : Base(m, initialValue) {}
02088 
02093     Vector_(int m, const S* cppData, bool): Base(m, Base::CppNScalarsPerElement, cppData) {}
02094     Vector_(int m,       S* cppData, bool): Base(m, Base::CppNScalarsPerElement, cppData) {}
02095 
02099     Vector_(int m, int stride, const S* data, bool) : Base(m, stride, data) {}
02100     Vector_(int m, int stride,       S* data, bool) : Base(m, stride, data) {}
02101 
02103     template <int M>
02104     explicit Vector_(const Vec<M,ELT>& v) : Base(M) {
02105         for (int i = 0; i < M; ++i)
02106             this->updElt(i, 0) = v(i);
02107     }
02108 
02109     Vector_& operator=(const ELT& v) { Base::operator=(v); return *this; } 
02110 
02111     template <class EE> Vector_& operator=(const VectorBase<EE>& m)
02112       { Base::operator=(m); return*this; }
02113     template <class EE> Vector_& operator+=(const VectorBase<EE>& m)
02114       { Base::operator+=(m); return*this; }
02115     template <class EE> Vector_& operator-=(const VectorBase<EE>& m)
02116       { Base::operator-=(m); return*this; }
02117 
02118     Vector_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
02119     Vector_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
02120     Vector_& operator+=(const ELT& b) { this->elementwiseAddScalarInPlace(b); return *this; }
02121     Vector_& operator-=(const ELT& b) { this->elementwiseSubtractScalarInPlace(b); return *this; }
02122  
02123     // Functions to be used for Scripting in MATLAB and languages that do not support operator overloading
02125     std::string toString() const {
02126         std::stringstream stream;
02127         stream <<  (*this) ;
02128         return stream.str(); 
02129     }
02131     const ELT& get(int i) const { return (*this)[i]; }
02133     void  set (int i, const ELT& value)  { (*this)[i]=value; }
02134    
02135 private:
02136     // NO DATA MEMBERS ALLOWED
02137 };
02138 
02139 
02140 
02141 //  ------------------------------ RowVectorView_ ------------------------------
02147 //  ----------------------------------------------------------------------------
02148 template <class ELT> class RowVectorView_ : public RowVectorBase<ELT> {
02149     typedef RowVectorBase<ELT>                              Base;
02150     typedef typename CNT<ELT>::Scalar                       S;
02151     typedef typename CNT<ELT>::Number                       Number;
02152     typedef typename CNT<ELT>::StdNumber                    StdNumber;
02153     typedef RowVectorView_<ELT>                             T;
02154     typedef RowVectorView_< typename CNT<ELT>::TNeg >       TNeg;
02155     typedef VectorView_< typename CNT<ELT>::THerm >         THerm;
02156 public:
02157     // Default construction is suppressed.
02158     // Uses default destructor.
02159 
02160     // Create a RowVectorView_ handle using a given helper rep. 
02161     explicit RowVectorView_(MatrixHelperRep<S>* hrep) : Base(hrep) {}
02162 
02163     // Copy constructor is shallow. CAUTION: despite const argument, this preserves writability
02164     // if it was present in the source. This is necessary to allow temporary views to be
02165     // created and used as lvalues.
02166     RowVectorView_(const RowVectorView_& r) 
02167       : Base(const_cast<MatrixHelper<S>&>(r.getHelper()), typename MatrixHelper<S>::ShallowCopy()) { }
02168 
02169     // Copy assignment is deep but not reallocating.
02170     RowVectorView_& operator=(const RowVectorView_& r) {
02171         Base::operator=(r); return *this;
02172     }
02173 
02174     // Ask for shallow copy    
02175     explicit RowVectorView_(const MatrixHelper<S>& h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
02176     explicit RowVectorView_(MatrixHelper<S>&       h) : Base(h, typename MatrixHelper<S>::ShallowCopy()) { }
02177     
02178     RowVectorView_& operator=(const Base& b) { Base::operator=(b); return *this; }
02179 
02180     RowVectorView_& operator=(const ELT& v) { Base::operator=(v); return *this; } 
02181 
02182     template <class EE> RowVectorView_& operator=(const RowVectorBase<EE>& m)
02183       { Base::operator=(m); return*this; }
02184     template <class EE> RowVectorView_& operator+=(const RowVectorBase<EE>& m)
02185       { Base::operator+=(m); return*this; }
02186     template <class EE> RowVectorView_& operator-=(const RowVectorBase<EE>& m)
02187       { Base::operator-=(m); return*this; }
02188 
02189     RowVectorView_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
02190     RowVectorView_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
02191     RowVectorView_& operator+=(const ELT& b) { this->elementwiseAddScalarInPlace(b); return *this; }
02192     RowVectorView_& operator-=(const ELT& b) { this->elementwiseSubtractScalarInPlace(b); return *this; }
02193 
02194 private:
02195     // NO DATA MEMBERS ALLOWED
02196     RowVectorView_(); // default construction suppressed (what is it a view of?)
02197 };
02198 
02199 
02200 
02201 //  -------------------------------- RowVector_ --------------------------------
02206 //  ----------------------------------------------------------------------------
02207 template <class ELT> class RowVector_ : public RowVectorBase<ELT> {
02208     typedef typename CNT<ELT>::Scalar       S;
02209     typedef typename CNT<ELT>::Number       Number;
02210     typedef typename CNT<ELT>::StdNumber    StdNumber;
02211     typedef typename CNT<ELT>::TNeg         ENeg;
02212 
02213     typedef RowVectorBase<ELT>              Base;
02214     typedef RowVectorBase<ENeg>             BaseNeg;
02215 public:
02216     RowVector_() : Base() {}   // 1x0 reallocatable
02217     // Uses default destructor.
02218 
02219     // Copy constructor is deep.
02220     RowVector_(const RowVector_& src) : Base(src) {}
02221 
02222     // Implicit conversions.
02223     RowVector_(const Base& src) : Base(src) {}    // e.g., RowVectorView
02224     RowVector_(const BaseNeg& src) : Base(src) {}  
02225 
02226     // Copy assignment is deep and can be reallocating if this RowVector
02227     // has no View.
02228     RowVector_& operator=(const RowVector_& src) {
02229         Base::operator=(src); return*this;
02230     }
02231 
02232 
02233     explicit RowVector_(int n) : Base(n) { }
02234     RowVector_(int n, const ELT* cppInitialValues) : Base(n, cppInitialValues) {}
02235     RowVector_(int n, const ELT& initialValue)     : Base(n, initialValue) {}
02236 
02241     RowVector_(int n, const S* cppData, bool): Base(n, Base::CppNScalarsPerElement, cppData) {}
02242     RowVector_(int n,       S* cppData, bool): Base(n, Base::CppNScalarsPerElement, cppData) {}
02243 
02247     RowVector_(int n, int stride, const S* data, bool) : Base(n, stride, data) {}
02248     RowVector_(int n, int stride,       S* data, bool) : Base(n, stride, data) {}
02249     
02251     template <int M>
02252     explicit RowVector_(const Row<M,ELT>& v) : Base(M) {
02253         for (int i = 0; i < M; ++i)
02254             this->updElt(0, i) = v(i);
02255     }
02256 
02257     RowVector_& operator=(const ELT& v) { Base::operator=(v); return *this; } 
02258 
02259     template <class EE> RowVector_& operator=(const RowVectorBase<EE>& b)
02260       { Base::operator=(b); return*this; }
02261     template <class EE> RowVector_& operator+=(const RowVectorBase<EE>& b)
02262       { Base::operator+=(b); return*this; }
02263     template <class EE> RowVector_& operator-=(const RowVectorBase<EE>& b)
02264       { Base::operator-=(b); return*this; }
02265 
02266     RowVector_& operator*=(const StdNumber& t) { Base::operator*=(t); return *this; }
02267     RowVector_& operator/=(const StdNumber& t) { Base::operator/=(t); return *this; }
02268     RowVector_& operator+=(const ELT& b) { this->elementwiseAddScalarInPlace(b); return *this; }
02269     RowVector_& operator-=(const ELT& b) { this->elementwiseSubtractScalarInPlace(b); return *this; }
02270 
02271 private:
02272     // NO DATA MEMBERS ALLOWED
02273 };
02274 
02275 
02276 
02277 //  ------------------------ MatrixBase definitions ----------------------------
02278 
02279 template <class ELT> inline MatrixView_<ELT> 
02280 MatrixBase<ELT>::block(int i, int j, int m, int n) const { 
02281     SimTK_INDEXCHECK(i,nrow()+1,"MatrixBase::block()");
02282     SimTK_INDEXCHECK(j,ncol()+1,"MatrixBase::block()");
02283     SimTK_SIZECHECK(i+m,nrow(),"MatrixBase::block()");
02284     SimTK_SIZECHECK(j+n,ncol(),"MatrixBase::block()");
02285 
02286     MatrixHelper<Scalar> h(MatrixCommitment(),helper,i,j,m,n);    
02287     return MatrixView_<ELT>(h.stealRep()); 
02288 }
02289     
02290 template <class ELT> inline MatrixView_<ELT>
02291 MatrixBase<ELT>::updBlock(int i, int j, int m, int n) { 
02292     SimTK_INDEXCHECK(i,nrow()+1,"MatrixBase::updBlock()");
02293     SimTK_INDEXCHECK(j,ncol()+1,"MatrixBase::updBlock()");
02294     SimTK_SIZECHECK(i+m,nrow(),"MatrixBase::updBlock()");
02295     SimTK_SIZECHECK(j+n,ncol(),"MatrixBase::updBlock()");
02296 
02297     MatrixHelper<Scalar> h(MatrixCommitment(),helper,i,j,m,n);        
02298     return MatrixView_<ELT>(h.stealRep()); 
02299 }
02300 
02301 template <class E> inline MatrixView_<typename CNT<E>::THerm>
02302 MatrixBase<E>::transpose() const { 
02303     MatrixHelper<typename CNT<Scalar>::THerm> 
02304         h(MatrixCommitment(),
02305           helper, typename MatrixHelper<typename CNT<Scalar>::THerm>::TransposeView());
02306     return MatrixView_<typename CNT<E>::THerm>(h.stealRep()); 
02307 }
02308     
02309 template <class E> inline MatrixView_<typename CNT<E>::THerm>
02310 MatrixBase<E>::updTranspose() {     
02311     MatrixHelper<typename CNT<Scalar>::THerm> 
02312         h(MatrixCommitment(),
02313           helper, typename MatrixHelper<typename CNT<Scalar>::THerm>::TransposeView());
02314     return MatrixView_<typename CNT<E>::THerm>(h.stealRep()); 
02315 }
02316 
02317 template <class E> inline VectorView_<E>
02318 MatrixBase<E>::diag() const { 
02319     MatrixHelper<Scalar> h(MatrixCommitment::Vector(),
02320                            helper, typename MatrixHelper<Scalar>::DiagonalView());
02321     return VectorView_<E>(h.stealRep()); 
02322 }
02323     
02324 template <class E> inline VectorView_<E>
02325 MatrixBase<E>::updDiag() {     
02326     MatrixHelper<Scalar> h(MatrixCommitment::Vector(),
02327                            helper, typename MatrixHelper<Scalar>::DiagonalView());
02328     return VectorView_<E>(h.stealRep());
02329 }
02330 
02331 template <class ELT> inline VectorView_<ELT> 
02332 MatrixBase<ELT>::col(int j) const { 
02333     SimTK_INDEXCHECK(j,ncol(),"MatrixBase::col()");
02334 
02335     MatrixHelper<Scalar> h(MatrixCommitment::Vector(),
02336                            helper,0,j,nrow(),1);    
02337     return VectorView_<ELT>(h.stealRep()); 
02338 }
02339     
02340 template <class ELT> inline VectorView_<ELT>
02341 MatrixBase<ELT>::updCol(int j) {
02342     SimTK_INDEXCHECK(j,ncol(),"MatrixBase::updCol()");
02343 
02344     MatrixHelper<Scalar> h(MatrixCommitment::Vector(),
02345                            helper,0,j,nrow(),1);        
02346     return VectorView_<ELT>(h.stealRep()); 
02347 }
02348 
02349 template <class ELT> inline RowVectorView_<ELT> 
02350 MatrixBase<ELT>::row(int i) const { 
02351     SimTK_INDEXCHECK(i,nrow(),"MatrixBase::row()");
02352 
02353     MatrixHelper<Scalar> h(MatrixCommitment::RowVector(),
02354                            helper,i,0,1,ncol());    
02355     return RowVectorView_<ELT>(h.stealRep()); 
02356 }
02357     
02358 template <class ELT> inline RowVectorView_<ELT>
02359 MatrixBase<ELT>::updRow(int i) { 
02360     SimTK_INDEXCHECK(i,nrow(),"MatrixBase::updRow()");
02361 
02362     MatrixHelper<Scalar> h(MatrixCommitment::RowVector(),
02363                            helper,i,0,1,ncol());        
02364     return RowVectorView_<ELT>(h.stealRep()); 
02365 }
02366 
02367 // M = diag(v) * M; v must have nrow() elements.
02368 // That is, M[i] *= v[i].
02369 template <class ELT> template <class EE> inline MatrixBase<ELT>& 
02370 MatrixBase<ELT>::rowScaleInPlace(const VectorBase<EE>& v) {
02371     assert(v.nrow() == nrow());
02372     for (int i=0; i < nrow(); ++i)
02373         (*this)[i] *= v[i];
02374     return *this;
02375 }
02376 
02377 template <class ELT> template <class EE> inline void
02378 MatrixBase<ELT>::rowScale(const VectorBase<EE>& v, typename MatrixBase<ELT>::template EltResult<EE>::Mul& out) const {
02379     assert(v.nrow() == nrow());
02380     out.resize(nrow(), ncol());
02381     for (int j=0; j<ncol(); ++j)
02382         for (int i=0; i<nrow(); ++i)
02383            out(i,j) = (*this)(i,j) * v[i];
02384 }
02385 
02386 // M = M * diag(v); v must have ncol() elements
02387 // That is, M(i) *= v[i]
02388 template <class ELT> template <class EE>  inline MatrixBase<ELT>& 
02389 MatrixBase<ELT>::colScaleInPlace(const VectorBase<EE>& v) {
02390     assert(v.nrow() == ncol());
02391     for (int j=0; j < ncol(); ++j)
02392         (*this)(j) *= v[j];
02393     return *this;
02394 }
02395 
02396 template <class ELT> template <class EE> inline void
02397 MatrixBase<ELT>::colScale(const VectorBase<EE>& v, typename MatrixBase<ELT>::template EltResult<EE>::Mul& out) const {
02398     assert(v.nrow() == ncol());
02399     out.resize(nrow(), ncol());
02400     for (int j=0; j<ncol(); ++j)
02401         for (int i=0; i<nrow(); ++i)
02402            out(i,j) = (*this)(i,j) * v[j];
02403 }
02404 
02405 
02406 // M(i,j) *= r[i]*c[j]; r must have nrow() elements; c must have ncol() elements
02407 template <class ELT> template <class ER, class EC> inline MatrixBase<ELT>& 
02408 MatrixBase<ELT>::rowAndColScaleInPlace(const VectorBase<ER>& r, const VectorBase<EC>& c) {
02409     assert(r.nrow()==nrow() && c.nrow()==ncol());
02410     for (int j=0; j<ncol(); ++j)
02411         for (int i=0; i<nrow(); ++i)
02412             (*this)(i,j) *= (r[i]*c[j]);
02413     return *this;
02414 }
02415 
02416 template <class ELT> template <class ER, class EC> inline void
02417 MatrixBase<ELT>::rowAndColScale(
02418     const VectorBase<ER>& r, 
02419     const VectorBase<EC>& c,
02420     typename EltResult<typename VectorBase<ER>::template EltResult<EC>::Mul>::Mul& 
02421                           out) const
02422 {
02423     assert(r.nrow()==nrow() && c.nrow()==ncol());
02424     out.resize(nrow(), ncol());
02425     for (int j=0; j<ncol(); ++j)
02426         for (int i=0; i<nrow(); ++i)
02427             out(i,j) = (*this)(i,j) * (r[i]*c[j]);
02428 }
02429 
02430 // M(i,j) = s
02431 template <class ELT> template <class S> inline MatrixBase<ELT>& 
02432 MatrixBase<ELT>::elementwiseAssign(const S& s) {
02433     for (int j=0; j<ncol(); ++j)
02434     for (int i=0; i<nrow(); ++i)
02435         (*this)(i,j) = s;
02436     return *this;
02437 }
02438 
02439 // Set M(i,j) = M(i,j)^-1.
02440 template <class ELT> inline MatrixBase<ELT>& 
02441 MatrixBase<ELT>::elementwiseInvertInPlace() {
02442     const int nr=nrow(), nc=ncol();
02443     for (int j=0; j<nc; ++j)
02444         for (int i=0; i<nr; ++i) {
02445             ELT& e = updElt(i,j);
02446             e = CNT<ELT>::invert(e);
02447         }
02448     return *this;
02449 }
02450 
02451 template <class ELT> inline void
02452 MatrixBase<ELT>::elementwiseInvert(MatrixBase<typename CNT<E>::TInvert>& out) const {
02453     const int nr=nrow(), nc=ncol();
02454     out.resize(nr,nc);
02455     for (int j=0; j<nc; ++j)
02456         for (int i=0; i<nr; ++i)
02457             out(i,j) = CNT<ELT>::invert((*this)(i,j));
02458 }
02459 
02460 // M(i,j) += s
02461 template <class ELT> template <class S> inline MatrixBase<ELT>& 
02462 MatrixBase<ELT>::elementwiseAddScalarInPlace(const S& s) {
02463     for (int j=0; j<ncol(); ++j)
02464         for (int i=0; i<nrow(); ++i)
02465             (*this)(i,j) += s;
02466     return *this;
02467 }
02468 
02469 template <class ELT> template <class S> inline void 
02470 MatrixBase<ELT>::elementwiseAddScalar(
02471     const S& s,
02472     typename MatrixBase<ELT>::template EltResult<S>::Add& out) const
02473 {
02474     const int nr=nrow(), nc=ncol();
02475     out.resize(nr,nc);
02476     for (int j=0; j<nc; ++j)
02477         for (int i=0; i<nr; ++i)
02478             out(i,j) = (*this)(i,j) + s;
02479 }
02480 
02481 // M(i,j) -= s
02482 template <class ELT> template <class S> inline MatrixBase<ELT>& 
02483 MatrixBase<ELT>::elementwiseSubtractScalarInPlace(const S& s) {
02484     for (int j=0; j<ncol(); ++j)
02485         for (int i=0; i<nrow(); ++i)
02486             (*this)(i,j) -= s;
02487     return *this;
02488 }
02489 
02490 template <class ELT> template <class S> inline void 
02491 MatrixBase<ELT>::elementwiseSubtractScalar(
02492     const S& s,
02493     typename MatrixBase<ELT>::template EltResult<S>::Sub& out) const
02494 {
02495     const int nr=nrow(), nc=ncol();
02496     out.resize(nr,nc);
02497     for (int j=0; j<nc; ++j)
02498         for (int i=0; i<nr; ++i)
02499             out(i,j) = (*this)(i,j) - s;
02500 }
02501 
02502 // M(i,j) = s - M(i,j)
02503 template <class ELT> template <class S> inline MatrixBase<ELT>& 
02504 MatrixBase<ELT>::elementwiseSubtractFromScalarInPlace(const S& s) {
02505     const int nr=nrow(), nc=ncol();
02506     for (int j=0; j<nc; ++j)
02507         for (int i=0; i<nr; ++i) {
02508             ELT& e = updElt(i,j);
02509             e = s - e;
02510         }
02511     return *this;
02512 }
02513 
02514 template <class ELT> template <class S> inline void 
02515 MatrixBase<ELT>::elementwiseSubtractFromScalar(
02516     const S& s,
02517     typename MatrixBase<S>::template EltResult<ELT>::Sub& out) const
02518 {
02519     const int nr=nrow(), nc=ncol();
02520     out.resize(nr,nc);
02521     for (int j=0; j<nc; ++j)
02522         for (int i=0; i<nr; ++i)
02523             out(i,j) = s - (*this)(i,j);
02524 }
02525 
02526 // M(i,j) *= R(i,j); R must have same dimensions as this
02527 template <class ELT> template <class EE> inline MatrixBase<ELT>& 
02528 MatrixBase<ELT>::elementwiseMultiplyInPlace(const MatrixBase<EE>& r) {
02529     const int nr=nrow(), nc=ncol();
02530     assert(r.nrow()==nr && r.ncol()==nc);
02531     for (int j=0; j<nc; ++j)
02532         for (int i=0; i<nr; ++i)
02533             (*this)(i,j) *= r(i,j);
02534     return *this;
02535 }
02536 
02537 template <class ELT> template <class EE> inline void 
02538 MatrixBase<ELT>::elementwiseMultiply(
02539     const MatrixBase<EE>& r, 
02540     typename MatrixBase<ELT>::template EltResult<EE>::Mul& out) const
02541 {
02542     const int nr=nrow(), nc=ncol();
02543     assert(r.nrow()==nr && r.ncol()==nc);
02544     out.resize(nr,nc);
02545     for (int j=0; j<nc; ++j)
02546         for (int i=0; i<nr; ++i)
02547             out(i,j) = (*this)(i,j) * r(i,j);
02548 }
02549 
02550 // M(i,j) = R(i,j) * M(i,j); R must have same dimensions as this
02551 template <class ELT> template <class EE> inline MatrixBase<ELT>& 
02552 MatrixBase<ELT>::elementwiseMultiplyFromLeftInPlace(const MatrixBase<EE>& r) {
02553     const int nr=nrow(), nc=ncol();
02554     assert(r.nrow()==nr && r.ncol()==nc);
02555     for (int j=0; j<nc; ++j)
02556         for (int i=0; i<nr; ++i) {
02557             ELT& e = updElt(i,j);
02558             e = r(i,j) * e;
02559         }
02560     return *this;
02561 }
02562 
02563 template <class ELT> template <class EE> inline void 
02564 MatrixBase<ELT>::elementwiseMultiplyFromLeft(
02565     const MatrixBase<EE>& r, 
02566     typename MatrixBase<EE>::template EltResult<ELT>::Mul& out) const
02567 {
02568     const int nr=nrow(), nc=ncol();
02569     assert(r.nrow()==nr && r.ncol()==nc);
02570     out.resize(nr,nc);
02571     for (int j=0; j<nc; ++j)
02572         for (int i=0; i<nr; ++i)
02573             out(i,j) =  r(i,j) * (*this)(i,j);
02574 }
02575 
02576 // M(i,j) /= R(i,j); R must have same dimensions as this
02577 template <class ELT> template <class EE> inline MatrixBase<ELT>& 
02578 MatrixBase<ELT>::elementwiseDivideInPlace(const MatrixBase<EE>& r) {
02579     const int nr=nrow(), nc=ncol();
02580     assert(r.nrow()==nr && r.ncol()==nc);
02581     for (int j=0; j<nc; ++j)
02582         for (int i=0; i<nr; ++i)
02583             (*this)(i,j) /= r(i,j);
02584     return *this;
02585 }
02586 
02587 template <class ELT> template <class EE> inline void 
02588 MatrixBase<ELT>::elementwiseDivide(
02589     const MatrixBase<EE>& r,
02590     typename MatrixBase<ELT>::template EltResult<EE>::Dvd& out) const
02591 {
02592     const int nr=nrow(), nc=ncol();
02593     assert(r.nrow()==nr && r.ncol()==nc);
02594     out.resize(nr,nc);
02595     for (int j=0; j<nc; ++j)
02596         for (int i=0; i<nr; ++i)
02597             out(i,j) = (*this)(i,j) / r(i,j);
02598 }
02599 // M(i,j) = R(i,j) / M(i,j); R must have same dimensions as this
02600 template <class ELT> template <class EE> inline MatrixBase<ELT>& 
02601 MatrixBase<ELT>::elementwiseDivideFromLeftInPlace(const MatrixBase<EE>& r) {
02602     const int nr=nrow(), nc=ncol();
02603     assert(r.nrow()==nr && r.ncol()==nc);
02604     for (int j=0; j<nc; ++j)
02605         for (int i=0; i<nr; ++i) {
02606             ELT& e = updElt(i,j);
02607             e = r(i,j) / e;
02608         }
02609     return *this;
02610 }
02611 
02612 template <class ELT> template <class EE> inline void 
02613 MatrixBase<ELT>::elementwiseDivideFromLeft(
02614     const MatrixBase<EE>& r,
02615     typename MatrixBase<EE>::template EltResult<ELT>::Dvd& out) const
02616 {
02617     const int nr=nrow(), nc=ncol();
02618     assert(r.nrow()==nr && r.ncol()==nc);
02619     out.resize(nr,nc);
02620     for (int j=0; j<nc; ++j)
02621         for (int i=0; i<nr; ++i)
02622             out(i,j) = r(i,j) / (*this)(i,j);
02623 }
02624 
02625 /*
02626 template <class ELT> inline MatrixView_< typename CNT<ELT>::TReal > 
02627 MatrixBase<ELT>::real() const { 
02628     if (!CNT<ELT>::IsComplex) { // known at compile time
02629         return MatrixView_< typename CNT<ELT>::TReal >( // this is just ELT
02630             MatrixHelper(helper,0,0,nrow(),ncol()));    // a view of the whole matrix
02631     }
02632     // Elements are complex -- helper uses underlying precision (real) type.
02633     MatrixHelper<Precision> h(helper,typename MatrixHelper<Precision>::RealView);    
02634     return MatrixView_< typename CNT<ELT>::TReal >(h); 
02635 }
02636 */
02637 
02638 
02639 //  ----------------------------------------------------------------------------
02643 
02644 // + and - allow mixed element types, but will fail to compile if the elements aren't
02645 // compatible. At run time these will fail if the dimensions are incompatible.
02646 template <class E1, class E2>
02647 Matrix_<typename CNT<E1>::template Result<E2>::Add>
02648 operator+(const MatrixBase<E1>& l, const MatrixBase<E2>& r) {
02649     return Matrix_<typename CNT<E1>::template Result<E2>::Add>(l) += r;
02650 }
02651 
02652 template <class E>
02653 Matrix_<E> operator+(const MatrixBase<E>& l, const typename CNT<E>::T& r) {
02654     return Matrix_<E>(l) += r;
02655 }
02656 
02657 template <class E>
02658 Matrix_<E> operator+(const typename CNT<E>::T& l, const MatrixBase<E>& r) {
02659     return Matrix_<E>(r) += l;
02660 }
02661 
02662 template <class E1, class E2>
02663 Matrix_<typename CNT<E1>::template Result<E2>::Sub>
02664 operator-(const MatrixBase<E1>& l, const MatrixBase<E2>& r) {
02665     return Matrix_<typename CNT<E1>::template Result<E2>::Sub>(l) -= r;
02666 }
02667 
02668 template <class E>
02669 Matrix_<E> operator-(const MatrixBase<E>& l, const typename CNT<E>::T& r) {
02670     return Matrix_<E>(l) -= r;
02671 }
02672 
02673 template <class E>
02674 Matrix_<E> operator-(const typename CNT<E>::T& l, const MatrixBase<E>& r) {
02675     Matrix_<E> temp(r.nrow(), r.ncol());
02676     temp = l;
02677     return (temp -= r);
02678 }
02679 
02680 // Scalar multiply and divide. You might wish the scalar could be
02681 // a templatized type "E2", but that would create horrible ambiguities since
02682 // E2 would match not only scalar types but everything else including
02683 // matrices.
02684 template <class E> Matrix_<E>
02685 operator*(const MatrixBase<E>& l, const typename CNT<E>::StdNumber& r) 
02686   { return Matrix_<E>(l)*=r; }
02687 
02688 template <class E> Matrix_<E>
02689 operator*(const typename CNT<E>::StdNumber& l, const MatrixBase<E>& r) 
02690   { return Matrix_<E>(r)*=l; }
02691 
02692 template <class E> Matrix_<E>
02693 operator/(const MatrixBase<E>& l, const typename CNT<E>::StdNumber& r) 
02694   { return Matrix_<E>(l)/=r; }
02695 
02696 // Handle ints explicitly.
02697 template <class E> Matrix_<E>
02698 operator*(const MatrixBase<E>& l, int r) 
02699   { return Matrix_<E>(l)*= typename CNT<E>::StdNumber(r); }
02700 
02701 template <class E> Matrix_<E>
02702 operator*(int l, const MatrixBase<E>& r) 
02703   { return Matrix_<E>(r)*= typename CNT<E>::StdNumber(l); }
02704 
02705 template <class E> Matrix_<E>
02706 operator/(const MatrixBase<E>& l, int r) 
02707   { return Matrix_<E>(l)/= typename CNT<E>::StdNumber(r); }
02708 
02710 
02714 
02715 template <class E1, class E2>
02716 Vector_<typename CNT<E1>::template Result<E2>::Add>
02717 operator+(const VectorBase<E1>& l, const VectorBase<E2>& r) {
02718     return Vector_<typename CNT<E1>::template Result<E2>::Add>(l) += r;
02719 }
02720 template <class E>
02721 Vector_<E> operator+(const VectorBase<E>& l, const typename CNT<E>::T& r) {
02722     return Vector_<E>(l) += r;
02723 }
02724 template <class E>
02725 Vector_<E> operator+(const typename CNT<E>::T& l, const VectorBase<E>& r) {
02726     return Vector_<E>(r) += l;
02727 }
02728 template <class E1, class E2>
02729 Vector_<typename CNT<E1>::template Result<E2>::Sub>
02730 operator-(const VectorBase<E1>& l, const VectorBase<E2>& r) {
02731     return Vector_<typename CNT<E1>::template Result<E2>::Sub>(l) -= r;
02732 }
02733 template <class E>
02734 Vector_<E> operator-(const VectorBase<E>& l, const typename CNT<E>::T& r) {
02735     return Vector_<E>(l) -= r;
02736 }
02737 template <class E>
02738 Vector_<E> operator-(const typename CNT<E>::T& l, const VectorBase<E>& r) {
02739     Vector_<E> temp(r.size());
02740     temp = l;
02741     return (temp -= r);
02742 }
02743 
02744 // Scalar multiply and divide.
02745 
02746 template <class E> Vector_<E>
02747 operator*(const VectorBase<E>& l, const typename CNT<E>::StdNumber& r) 
02748   { return Vector_<E>(l)*=r; }
02749 
02750 template <class E> Vector_<E>
02751 operator*(const typename CNT<E>::StdNumber& l, const VectorBase<E>& r) 
02752   { return Vector_<E>(r)*=l; }
02753 
02754 template <class E> Vector_<E>
02755 operator/(const VectorBase<E>& l, const typename CNT<E>::StdNumber& r) 
02756   { return Vector_<E>(l)/=r; }
02757 
02758 // Handle ints explicitly
02759 template <class E> Vector_<E>
02760 operator*(const VectorBase<E>& l, int r) 
02761   { return Vector_<E>(l)*= typename CNT<E>::StdNumber(r); }
02762 
02763 template <class E> Vector_<E>
02764 operator*(int l, const VectorBase<E>& r) 
02765   { return Vector_<E>(r)*= typename CNT<E>::StdNumber(l); }
02766 
02767 template <class E> Vector_<E>
02768 operator/(const VectorBase<E>& l, int r) 
02769   { return Vector_<E>(l)/= typename CNT<E>::StdNumber(r); }
02770 
02771 // These are fancier "scalars"; whether they are allowed depends on
02772 // whether the element type and the CNT are compatible.
02773 
02774 // Vector * Vec
02775 template <class E1, int M, class E2, int S> 
02776 Vector_<typename CNT<E1>::template Result< Vec<M,E2,S> >::Mul>
02777 operator*(const VectorBase<E1>& v, const Vec<M,E2,S>& s) {
02778     Vector_<typename CNT<E1>::template Result< Vec<M,E2,S> >::Mul> res(v.nrow());
02779     for (int i=0; i < v.nrow(); ++i)
02780         res[i] = v[i]*s; 
02781     return res;
02782 }
02783 
02784 // Vec * Vector
02785 template <class E1, int M, class E2, int S> 
02786 Vector_<typename Vec<M,E2,S>::template Result<E1>::Mul>
02787 operator*(const Vec<M,E2,S>& s, const VectorBase<E1>& v) {
02788     Vector_<typename Vec<M,E2,S>::template Result<E1>::Mul> res(v.nrow());
02789     for (int i=0; i < v.nrow(); ++i)
02790         res[i] = s*v[i]; 
02791     return res;
02792 }
02793 
02794 // Vector * Row
02795 template <class E1, int N, class E2, int S> 
02796 Vector_<typename CNT<E1>::template Result< Row<N,E2,S> >::Mul>
02797 operator*(const VectorBase<E1>& v, const Row<N,E2,S>& s) {
02798     Vector_<typename CNT<E1>::template Result< Row<N,E2,S> >::Mul> res(v.nrow());
02799     for (int i=0; i < v.nrow(); ++i)
02800         res[i] = v[i]*s; 
02801     return res;
02802 }
02803 
02804 // Row * Vector
02805 template <class E1, int N, class E2, int S> 
02806 Vector_<typename Row<N,E2,S>::template Result<E1>::Mul>
02807 operator*(const Row<N,E2,S>& s, const VectorBase<E1>& v) {
02808     Vector_<typename Row<N,E2,S>::template Result<E1>::Mul> res(v.nrow());
02809     for (int i=0; i < v.nrow(); ++i)
02810         res[i] = s*v[i]; 
02811     return res;
02812 }
02813 
02814 // Vector * Mat
02815 template <class E1, int M, int N, class E2, int S1, int S2> 
02816 Vector_<typename CNT<E1>::template Result< Mat<M,N,E2,S1,S2> >::Mul>
02817 operator*(const VectorBase<E1>& v, const Mat<M,N,E2,S1,S2>& s) {
02818     Vector_<typename CNT<E1>::template Result< Mat<M,N,E2,S1,S2> >::Mul> res(v.nrow());
02819     for (int i=0; i < v.nrow(); ++i)
02820         res[i] = v[i]*s; 
02821     return res;
02822 }
02823 
02824 // Mat * Vector
02825 template <class E1, int M, int N, class E2, int S1, int S2> 
02826 Vector_<typename Mat<M,N,E2,S1,S2>::template Result<E1>::Mul>
02827 operator*(const Mat<M,N,E2,S1,S2>& s, const VectorBase<E1>& v) {
02828     Vector_<typename Mat<M,N,E2,S1,S2>::template Result<E1>::Mul> res(v.nrow());
02829     for (int i=0; i < v.nrow(); ++i)
02830         res[i] = s*v[i]; 
02831     return res;
02832 }
02833 
02834 // Vector * SymMat
02835 template <class E1, int M, class E2, int S> 
02836 Vector_<typename CNT<E1>::template Result< SymMat<M,E2,S> >::Mul>
02837 operator*(const VectorBase<E1>& v, const SymMat<M,E2,S>& s) {
02838     Vector_<typename CNT<E1>::template Result< SymMat<M,E2,S> >::Mul> res(v.nrow());
02839     for (int i=0; i < v.nrow(); ++i)
02840         res[i] = v[i]*s; 
02841     return res;
02842 }
02843 
02844 // SymMat * Vector
02845 template <class E1, int M, class E2, int S> 
02846 Vector_<typename SymMat<M,E2,S>::template Result<E1>::Mul>
02847 operator*(const SymMat<M,E2,S>& s, const VectorBase<E1>& v) {
02848     Vector_<typename SymMat<M,E2,S>::template Result<E1>::Mul> res(v.nrow());
02849     for (int i=0; i < v.nrow(); ++i)
02850         res[i] = s*v[i]; 
02851     return res;
02852 }
02853 
02855 
02859 
02860 template <class E1, class E2>
02861 RowVector_<typename CNT<E1>::template Result<E2>::Add>
02862 operator+(const RowVectorBase<E1>& l, const RowVectorBase<E2>& r) {
02863     return RowVector_<typename CNT<E1>::template Result<E2>::Add>(l) += r;
02864 }
02865 template <class E>
02866 RowVector_<E> operator+(const RowVectorBase<E>& l, const typename CNT<E>::T& r) {
02867     return RowVector_<E>(l) += r;
02868 }
02869 template <class E>
02870 RowVector_<E> operator+(const typename CNT<E>::T& l, const RowVectorBase<E>& r) {
02871     return RowVector_<E>(r) += l;
02872 }
02873 template <class E1, class E2>
02874 RowVector_<typename CNT<E1>::template Result<E2>::Sub>
02875 operator-(const RowVectorBase<E1>& l, const RowVectorBase<E2>& r) {
02876     return RowVector_<typename CNT<E1>::template Result<E2>::Sub>(l) -= r;
02877 }
02878 template <class E>
02879 RowVector_<E> operator-(const RowVectorBase<E>& l, const typename CNT<E>::T& r) {
02880     return RowVector_<E>(l) -= r;
02881 }
02882 template <class E>
02883 RowVector_<E> operator-(const typename CNT<E>::T& l, const RowVectorBase<E>& r) {
02884     RowVector_<E> temp(r.size());
02885     temp = l;
02886     return (temp -= r);
02887 }
02888 
02889 // Scalar multiply and divide 
02890 
02891 template <class E> RowVector_<E>
02892 operator*(const RowVectorBase<E>& l, const typename CNT<E>::StdNumber& r) 
02893   { return RowVector_<E>(l)*=r; }
02894 
02895 template <class E> RowVector_<E>
02896 operator*(const typename CNT<E>::StdNumber& l, const RowVectorBase<E>& r) 
02897   { return RowVector_<E>(r)*=l; }
02898 
02899 template <class E> RowVector_<E>
02900 operator/(const RowVectorBase<E>& l, const typename CNT<E>::StdNumber& r) 
02901   { return RowVector_<E>(l)/=r; }
02902 
02903 // Handle ints explicitly.
02904 template <class E> RowVector_<E>
02905 operator*(const RowVectorBase<E>& l, int r) 
02906   { return RowVector_<E>(l)*= typename CNT<E>::StdNumber(r); }
02907 
02908 template <class E> RowVector_<E>
02909 operator*(int l, const RowVectorBase<E>& r) 
02910   { return RowVector_<E>(r)*= typename CNT<E>::StdNumber(l); }
02911 
02912 template <class E> RowVector_<E>
02913 operator/(const RowVectorBase<E>& l, int r) 
02914   { return RowVector_<E>(l)/= typename CNT<E>::StdNumber(r); }
02915 
02916 
02917 // These are fancier "scalars"; whether they are allowed depends on
02918 // whether the element type and the CNT are compatible.
02919 
02920 // RowVector * Vec
02921 template <class E1, int M, class E2, int S> 
02922 RowVector_<typename CNT<E1>::template Result< Vec<M,E2,S> >::Mul>
02923 operator*(const RowVectorBase<E1>& v, const Vec<M,E2,S>& s) {
02924     RowVector_<typename CNT<E1>::template Result< Vec<M,E2,S> >::Mul> res(v.ncol());
02925     for (int i=0; i < v.ncol(); ++i)
02926         res[i] = v[i]*s; 
02927     return res;
02928 }
02929 
02930 // Vec * RowVector
02931 template <class E1, int M, class E2, int S> 
02932 RowVector_<typename Vec<M,E2,S>::template Result<E1>::Mul>
02933 operator*(const Vec<M,E2,S>& s, const RowVectorBase<E1>& v) {
02934     RowVector_<typename Vec<M,E2,S>::template Result<E1>::Mul> res(v.ncol());
02935     for (int i=0; i < v.ncol(); ++i)
02936         res[i] = s*v[i]; 
02937     return res;
02938 }
02939 
02940 // RowVector * Row
02941 template <class E1, int N, class E2, int S> 
02942 RowVector_<typename CNT<E1>::template Result< Row<N,E2,S> >::Mul>
02943 operator*(const RowVectorBase<E1>& v, const Row<N,E2,S>& s) {
02944     RowVector_<typename CNT<E1>::template Result< Row<N,E2,S> >::Mul> res(v.ncol());
02945     for (int i=0; i < v.ncol(); ++i)
02946         res[i] = v[i]*s; 
02947     return res;
02948 }
02949 
02950 // Row * RowVector
02951 template <class E1, int N, class E2, int S> 
02952 RowVector_<typename Row<N,E2,S>::template Result<E1>::Mul>
02953 operator*(const Row<N,E2,S>& s, const RowVectorBase<E1>& v) {
02954     RowVector_<typename Row<N,E2,S>::template Result<E1>::Mul> res(v.ncol());
02955     for (int i=0; i < v.ncol(); ++i)
02956         res[i] = s*v[i]; 
02957     return res;
02958 }
02959 
02960 // RowVector * Mat
02961 template <class E1, int M, int N, class E2, int S1, int S2> 
02962 RowVector_<typename CNT<E1>::template Result< Mat<M,N,E2,S1,S2> >::Mul>
02963 operator*(const RowVectorBase<E1>& v, const Mat<M,N,E2,S1,S2>& s) {
02964     RowVector_<typename CNT<E1>::template Result< Mat<M,N,E2,S1,S2> >::Mul> res(v.ncol());
02965     for (int i=0; i < v.ncol(); ++i)
02966         res[i] = v[i]*s; 
02967     return res;
02968 }
02969 
02970 // Mat * RowVector
02971 template <class E1, int M, int N, class E2, int S1, int S2> 
02972 RowVector_<typename Mat<M,N,E2,S1,S2>::template Result<E1>::Mul>
02973 operator*(const Mat<M,N,E2,S1,S2>& s, const RowVectorBase<E1>& v) {
02974     RowVector_<typename Mat<M,N,E2,S1,S2>::template Result<E1>::Mul> res(v.ncol());
02975     for (int i=0; i < v.ncol(); ++i)
02976         res[i] = s*v[i]; 
02977     return res;
02978 }
02979 
02980 // RowVector * SymMat
02981 template <class E1, int M, class E2, int S> 
02982 RowVector_<typename CNT<E1>::template Result< SymMat<M,E2,S> >::Mul>
02983 operator*(const RowVectorBase<E1>& v, const SymMat<M,E2,S>& s) {
02984     RowVector_<typename CNT<E1>::template Result< SymMat<M,E2,S> >::Mul> res(v.ncol());
02985     for (int i=0; i < v.ncol(); ++i)
02986         res[i] = v[i]*s; 
02987     return res;
02988 }
02989 
02990 // SymMat * RowVector
02991 template <class E1, int M, class E2, int S> 
02992 RowVector_<typename SymMat<M,E2,S>::template Result<E1>::Mul>
02993 operator*(const SymMat<M,E2,S>& s, const RowVectorBase<E1>& v) {
02994     RowVector_<typename SymMat<M,E2,S>::template Result<E1>::Mul> res(v.ncol());
02995     for (int i=0; i < v.ncol(); ++i)
02996         res[i] = s*v[i]; 
02997     return res;
02998 }
02999 
03001 
03002 
03007 
03008     // TODO: these should use LAPACK!
03009 
03010 // Dot product
03011 template <class E1, class E2> 
03012 typename CNT<E1>::template Result<E2>::Mul
03013 operator*(const RowVectorBase<E1>& r, const VectorBase<E2>& v) {
03014     assert(r.ncol() == v.nrow());
03015     typename CNT<E1>::template Result<E2>::Mul sum(0);
03016     for (int j=0; j < r.ncol(); ++j)
03017         sum += r(j) * v[j];
03018     return sum;
03019 }
03020 
03021 template <class E1, class E2> 
03022 Vector_<typename CNT<E1>::template Result<E2>::Mul>
03023 operator*(const MatrixBase<E1>& m, const VectorBase<E2>& v) {
03024     assert(m.ncol() == v.nrow());
03025     Vector_<typename CNT<E1>::template Result<E2>::Mul> res(m.nrow());
03026     for (int i=0; i< m.nrow(); ++i)
03027         res[i] = m[i]*v;
03028     return res;
03029 }
03030 
03031 template <class E1, class E2> 
03032 Matrix_<typename CNT<E1>::template Result<E2>::Mul>
03033 operator*(const MatrixBase<E1>& m1, const MatrixBase<E2>& m2) {
03034     assert(m1.ncol() == m2.nrow());
03035     Matrix_<typename CNT<E1>::template Result<E2>::Mul> 
03036         res(m1.nrow(),m2.ncol());
03037 
03038     for (int j=0; j < res.ncol(); ++j)
03039         for (int i=0; i < res.nrow(); ++i)
03040             res(i,j) = m1[i] * m2(j);
03041 
03042     return res;
03043 }
03044 
03046 
03047 // This "private" static method is used to implement VectorView's 
03048 // fillVectorViewFromStream() and Vector's readVectorFromStream() 
03049 // namespace-scope static methods, which are in turn used to implement 
03050 // VectorView's and 
03051 // Vector's stream extraction operators ">>". This method has to be in the 
03052 // header file so that we don't need to pass streams through the API, but it 
03053 // is not intended for use by users and has no Doxygen presence, unlike 
03054 // fillArrayFromStream() and readArrayFromStream() and (more commonly)
03055 // the extraction operators.
03056 template <class T> static inline 
03057 std::istream& readVectorFromStreamHelper
03058    (std::istream& in, bool isFixedSize, Vector_<T>& out)
03059 {
03060     // If already failed, bad, or eof, set failed bit and return without 
03061     // touching the Vector.
03062     if (!in.good()) {in.setstate(std::ios::failbit); return in;}
03063 
03064     // If the passed-in Vector isn't resizeable, then we have to treat it as
03065     // a fixed size VectorView regardless of the setting of the isFixedSize
03066     // argument.
03067     if (!out.isResizeable())
03068         isFixedSize = true; // might be overriding the argument here
03069 
03070     // numRequired will be ignored unless isFixedSize==true.
03071     const int numRequired = isFixedSize ? out.size() : 0;
03072 
03073     if (!isFixedSize)
03074         out.clear(); // We're going to replace the entire contents of the Array.
03075 
03076     // Skip initial whitespace. If that results in eof this may be a successful
03077     // read of a 0-length, unbracketed Vector. That is OK for either a
03078     // variable-length Vector or a fixed-length VectorView of length zero.
03079     std::ws(in); if (in.fail()) return in;
03080     if (in.eof()) {
03081         if (isFixedSize && numRequired != 0)
03082             in.setstate(std::ios_base::failbit); // zero elements not OK
03083         return in;
03084     }
03085     
03086     // Here the stream is good and the next character is non-white.
03087     assert(in.good());
03088 
03089     // Use this for raw i/o (peeks and gets).
03090     typename       std::iostream::int_type ch;
03091     const typename std::iostream::int_type EOFch = 
03092         std::iostream::traits_type::eof();
03093 
03094     // First we'll look for the optional "~". If found, the brackets become
03095     // required.
03096     bool tildeFound = false;
03097     ch = in.peek(); if (in.fail()) return in;
03098     assert(ch != EOFch); // we already checked above
03099     if ((char)ch == '~') {
03100         tildeFound = true;
03101         in.get(); // absorb the tilde
03102         // Eat whitespace after the tilde to see what's next.
03103         if (in.good()) std::ws(in);
03104         // If we hit eof after the tilde we don't like the formatting.
03105         if (!in.good()) {in.setstate(std::ios_base::failbit); return in;}
03106     }
03107 
03108     // Here the stream is good, the next character is non-white, and we
03109     // might have seen a tilde.
03110     assert(in.good());
03111 
03112     // Now see if the sequence is bare or surrounded by (), or [].
03113     bool lookForCloser = true;
03114     char openBracket, closeBracket;
03115     ch = in.peek(); if (in.fail()) return in;
03116     assert(ch != EOFch); // we already checked above
03117 
03118     openBracket = (char)ch;
03119     if      (openBracket=='(') {in.get(); closeBracket = ')';}
03120     else if (openBracket=='[') {in.get(); closeBracket = ']';}
03121     else lookForCloser = false;
03122 
03123     // If we found a tilde, the opening bracket was mandatory. If we didn't
03124     // find one then we reject the formatting.
03125     if (tildeFound && !lookForCloser)
03126     {   in.setstate(std::ios_base::failbit); return in;}
03127 
03128     // If lookForCloser is true, then closeBracket contains the terminating
03129     // delimiter, otherwise we're not going to quit until eof.
03130 
03131     // Eat whitespace after the opening bracket to see what's next.
03132     if (in.good()) std::ws(in);
03133 
03134     // If we're at eof now it must be because the open bracket was the
03135     // last non-white character in the stream, which is an error.
03136     if (!in.good()) {
03137         if (in.eof()) {
03138             assert(lookForCloser); // or we haven't read anything that could eof
03139             in.setstate(std::ios::failbit);
03140         }
03141         return in;
03142     }
03143 
03144     // istream is good and next character is non-white; ready to read first
03145     // value or terminator.
03146 
03147     // We need to figure out whether the elements are space- or comma-
03148     // separated and then insist on consistency.
03149     bool commaOK = true, commaRequired = false;
03150     bool terminatorSeen = false;
03151     int nextIndex = 0;
03152     while (true) {
03153         char c;
03154 
03155         // Here at the top of this loop, we have already successfully read 
03156         // n=nextIndex values of type T. For fixed-size reads, it might be
03157         // the case that n==numRequired already, but we still may need to
03158         // look for a closing bracket before we can declare victory.
03159         // The stream is good() (not at eof) but it might be the case that 
03160         // there is nothing but white space left; we don't know yet because
03161         // if we have satisfied the fixed-size count and are not expecting
03162         // a terminator then we should quit without absorbing the trailing
03163         // white space.
03164         assert(in.good());
03165 
03166         // Look for closing bracket before trying to read value.
03167         if (lookForCloser) {
03168             // Eat white space to find the closing bracket.
03169             std::ws(in); if (!in.good()) break; // eof?
03170             ch = in.peek(); assert(ch != EOFch);
03171             if (!in.good()) break;
03172             c = (char)ch;
03173             if (c == closeBracket) {   
03174                 in.get(); // absorb the closing bracket
03175                 terminatorSeen = true; 
03176                 break; 
03177             }
03178             // next char not a closing bracket; fall through
03179         }
03180 
03181         // We didn't look or didn't find a closing bracket. The istream is good 
03182         // but we might be looking at white space.
03183 
03184         // If we already got all the elements we want, break for final checks.
03185         if (isFixedSize && (nextIndex == numRequired))
03186             break; // that's a full count.
03187 
03188         // Look for comma before value, except the first time.
03189         if (commaOK && nextIndex != 0) {
03190             // Eat white space to find the comma.
03191             std::ws(in); if (!in.good()) break; // eof?
03192             ch = in.peek(); assert(ch != EOFch);
03193             if (!in.good()) break;
03194             c = (char)ch;
03195             if (c == ',') {
03196                 in.get(); // absorb comma
03197                 commaRequired = true; // all commas from now on
03198             } else { // next char not a comma
03199                 if (commaRequired) // bad, e.g.: v1, v2, v3 v4 
03200                 {   in.setstate(std::ios::failbit); break; }
03201                 else commaOK = false; // saw: v1 v2 (no commas now)
03202             }
03203             if (!in.good()) break; // might be eof
03204         }
03205 
03206         // No closing bracket yet; don't have enough elements; skipped comma 
03207         // if any; istream is good; might be looking at white space.
03208         assert(in.good());
03209 
03210         // Now read in an element of type T.
03211         // The extractor T::operator>>() will ignore leading white space.
03212         if (!isFixedSize)
03213             out.resizeKeep(out.size()+1); // grow by one (default consructed)
03214         in >> out[nextIndex]; if (in.fail()) break;
03215         ++nextIndex;
03216 
03217         if (!in.good()) break; // might be eof
03218     }
03219 
03220     // We will get here under a number of circumstances:
03221     //  - the fail bit is set in the istream, or
03222     //  - we reached eof
03223     //  - we saw a closing brace
03224     //  - we got all the elements we wanted (for a fixed-size read)
03225     // Note that it is possible that we consumed everything except some
03226     // trailing white space (meaning we're not technically at eof), but
03227     // for consistency with built-in operator>>()'s we won't try to absorb
03228     // that trailing white space.
03229 
03230     if (!in.fail()) {
03231         if (lookForCloser && !terminatorSeen)
03232             in.setstate(std::ios::failbit); // missing terminator
03233 
03234         if (isFixedSize && nextIndex != numRequired)
03235             in.setstate(std::ios::failbit); // wrong number of values
03236     }
03237 
03238     return in;
03239 }
03240 
03241 
03242 
03243 //------------------------------------------------------------------------------
03244 //                          RELATED GLOBAL OPERATORS
03245 //------------------------------------------------------------------------------
03246 // These are logically part of the Matrix_<T> class but are not actually 
03247 // class members; that is, they are in the SimTK namespace.
03248 
03256 
03260 template <class E> inline void
03261 writeUnformatted(std::ostream& o, const VectorBase<E>& v) {
03262     const int sz = v.size();
03263     for (int i=0; i < sz; ++i) {
03264         if (i != 0) o << " ";
03265         writeUnformatted(o, v[i]);
03266     }
03267 } 
03270 template <class E> inline void
03271 writeUnformatted(std::ostream& o, const VectorView_<E>& v) 
03272 {   writeUnformatted(o, static_cast< const VectorBase<E> >(v)); }
03273 
03276 template <class E> inline void
03277 writeUnformatted(std::ostream& o, const Vector_<E>& v) 
03278 {   writeUnformatted(o, static_cast< const VectorBase<E> >(v)); }
03279 
03283 template <class E> inline void
03284 writeUnformatted(std::ostream& o, const RowVectorBase<E>& v) 
03285 {   writeUnformatted(o, ~v); }
03286 
03289 template <class E> inline void
03290 writeUnformatted(std::ostream& o, const RowVectorView_<E>& v) 
03291 {   writeUnformatted(o, static_cast< const RowVectorBase<E> >(v)); }
03292 
03295 template <class E> inline void
03296 writeUnformatted(std::ostream& o, const RowVector_<E>& v) 
03297 {   writeUnformatted(o, static_cast< const RowVectorBase<E> >(v)); }
03298 
03302 template <class E> inline void
03303 writeUnformatted(std::ostream& o, const MatrixBase<E>& v) {
03304     const int nr = v.nrow();
03305     for (int i=0; i < nr; ++i) {
03306         if (i != 0) o << std::endl;
03307         writeUnformatted(o, v[i]);
03308     }
03309 }
03312 template <class E> inline void
03313 writeUnformatted(std::ostream& o, const MatrixView_<E>& v) 
03314 {   writeUnformatted(o, static_cast< const MatrixBase<E> >(v)); }
03315 
03318 template <class E> inline void
03319 writeUnformatted(std::ostream& o, const Matrix_<E>& v) 
03320 {   writeUnformatted(o, static_cast< const MatrixBase<E> >(v)); }
03321 
03324 template <class E> inline bool
03325 readUnformatted(std::istream& in, VectorView_<E>& v) {
03326     for (int i=0; i < v.size(); ++i)
03327         if (!readUnformatted(in, v[i])) return false;
03328     return true;
03329 }
03330 
03332 template <class E> inline bool
03333 readUnformatted(std::istream& in, Vector_<E>& v) {
03334     if (!v.isResizeable())
03335         return readUnformatted(in, v.updAsVectorView());
03336 
03337     Array_<E,int> a;
03338     if (!readUnformatted(in,a)) return false;
03339     v.resize(a.size());
03340     for (int i=0; i<a.size(); ++i)
03341         v[i] = a[i];
03342     return true;
03343 }
03344 
03347 template <class E> inline bool
03348 readUnformatted(std::istream& in, RowVectorView_<E>& v) 
03349 {   VectorView_<E> vt(~v);
03350     return readUnformatted<E>(in, vt); }
03351 
03354 template <class E> inline bool
03355 readUnformatted(std::istream& in, RowVector_<E>& v) 
03356 {   Vector_<E> vt(~v);
03357     return readUnformatted<E>(in, vt); }
03358 
03363 template <class E> inline bool
03364 readUnformatted(std::istream& in, MatrixView_<E>& v) { 
03365     for (int row=0; row < v.nrow(); ++row) {
03366         RowVectorView_<E> oneRow(v[row]);
03367         if (!readUnformatted<E>(in, oneRow)) return false;
03368     }
03369     return true;
03370 }
03371 
03376 template <class E> inline bool
03377 fillUnformatted(std::istream& in, Matrix_<E>& v) {
03378     return readUnformatted<E>(in, v.updAsMatrixView());
03379 }
03380 
03383 template <class E> inline bool
03384 readUnformatted(std::istream& in, Matrix_<E>& v) {
03385     SimTK_ASSERT_ALWAYS(!"implemented", 
03386         "SimTK::readUnformatted(istream, Matrix) is not implemented; try"
03387         " SimTK::fillUnformatted(istream, Matrix) instead.");
03388     return false;
03389 }
03390   
03397 template <class T> inline std::ostream&
03398 operator<<(std::ostream& o, const VectorBase<T>& v)
03399 {   o << "~["; 
03400     if (v.size()) {
03401         o << v[0];
03402         for (int i=1; i < v.size(); ++i) o << " " << v[i];
03403     }
03404     return o << "]"; 
03405 }
03406 
03413 template <class T> inline std::ostream&
03414 operator<<(std::ostream& o, const RowVectorBase<T>& v)
03415 {   o << "["; 
03416     if (v.size()) {
03417         o << v[0];
03418         for (int i=1; i < v.size(); ++i) o << " " << v[i];
03419     }
03420     return o << "]"; 
03421 }
03422 
03430 template <class T> inline std::ostream&
03431 operator<<(std::ostream& o, const MatrixBase<T>& m) {
03432     for (int i=0;i<m.nrow();++i)
03433         o << std::endl << m[i];
03434     if (m.nrow()) o << std::endl;
03435     return o; 
03436 }
03437 
03438 
03470 template <class T> static inline 
03471 std::istream& readVectorFromStream(std::istream& in, Vector_<T>& out)
03472 {   return readVectorFromStreamHelper<T>(in, false /*variable sizez*/, out); }
03473 
03474 
03475 
03500 template <class T> static inline 
03501 std::istream& fillVectorFromStream(std::istream& in, Vector_<T>& out)
03502 {   return readVectorFromStreamHelper<T>(in, true /*fixed size*/, out); }
03503 
03508 template <class T> static inline 
03509 std::istream& fillVectorViewFromStream(std::istream& in, VectorView_<T>& out)
03510 {   return readVectorFromStreamHelper<T>(in, true /*fixed size*/, out); }
03511 
03512 
03522 template <class T> inline
03523 std::istream& operator>>(std::istream& in, Vector_<T>& out) 
03524 {   return readVectorFromStream<T>(in, out); }
03525 
03533 template <class T> inline
03534 std::istream& operator>>(std::istream& in, VectorView_<T>& out) 
03535 {   return fillVectorViewFromStream<T>(in, out); }
03536 
03539 // Friendly abbreviations for vectors and matrices with scalar elements.
03540 
03541 typedef Vector_<Real>           Vector;
03542 typedef Vector_<float>          fVector;
03543 typedef Vector_<double>         dVector;
03544 typedef Vector_<Complex>        ComplexVector;
03545 typedef Vector_<fComplex>       fComplexVector;
03546 typedef Vector_<dComplex>       dComplexVector;
03547 
03548 typedef VectorView_<Real>       VectorView;
03549 typedef VectorView_<float>      fVectorView;
03550 typedef VectorView_<double>     dVectorView;
03551 typedef VectorView_<Complex>    ComplexVectorView;
03552 typedef VectorView_<fComplex>   fComplexVectorView;
03553 typedef VectorView_<dComplex>   dComplexVectorView;
03554 
03555 typedef RowVector_<Real>        RowVector;
03556 typedef RowVector_<float>       fRowVector;
03557 typedef RowVector_<double>      dRowVector;
03558 typedef RowVector_<Complex>     ComplexRowVector;
03559 typedef RowVector_<fComplex>    fComplexRowVector;
03560 typedef RowVector_<dComplex>    dComplexRowVector;
03561 
03562 typedef RowVectorView_<Real>    RowVectorView;
03563 typedef RowVectorView_<float>   fRowVectorView;
03564 typedef RowVectorView_<double>  dRowVectorView;
03565 typedef RowVectorView_<Complex> ComplexRowVectorView;
03566 typedef RowVectorView_<fComplex> fComplexRowVectorView;
03567 typedef RowVectorView_<dComplex> dComplexRowVectorView;
03568 
03569 typedef Matrix_<Real>           Matrix;
03570 typedef Matrix_<float>          fMatrix;
03571 typedef Matrix_<double>         dMatrix;
03572 typedef Matrix_<Complex>        ComplexMatrix;
03573 typedef Matrix_<fComplex>       fComplexMatrix;
03574 typedef Matrix_<dComplex>       dComplexMatrix;
03575 
03576 typedef MatrixView_<Real>       MatrixView;
03577 typedef MatrixView_<float>      fMatrixView;
03578 typedef MatrixView_<double>     dMatrixView;
03579 typedef MatrixView_<Complex>    ComplexMatrixView;
03580 typedef MatrixView_<fComplex>   fComplexMatrixView;
03581 typedef MatrixView_<dComplex>   dComplexMatrixView;
03582 
03583 
03588 template <class ELT, class VECTOR_CLASS>
03589 class VectorIterator {
03590 public:
03591     typedef ELT value_type;
03592     typedef ptrdiff_t difference_type;
03593     typedef ELT& reference;
03594     typedef ELT* pointer;
03595     typedef std::random_access_iterator_tag iterator_category;
03596     VectorIterator(VECTOR_CLASS& vector, ptrdiff_t index) : vector(vector), index(index) {
03597     }
03598     VectorIterator(const VectorIterator& iter) : vector(iter.vector), index(iter.index) {
03599     }
03600     VectorIterator& operator=(const VectorIterator& iter) {
03601         vector = iter.vector;
03602         index = iter.index;
03603         return *this;
03604     }
03605     ELT& operator*() {
03606         assert (index >= 0 && index < vector.size());
03607         return vector[(int)index];
03608     }
03609     ELT& operator[](ptrdiff_t i) {
03610         assert (i >= 0 && i < vector.size());
03611         return vector[(int)i];
03612     }
03613     VectorIterator operator++() {
03614         assert (index < vector.size());
03615         ++index;
03616         return *this;
03617     }
03618     VectorIterator operator++(int) {
03619         assert (index < vector.size());
03620         VectorIterator current = *this;
03621         ++index;
03622         return current;
03623     }
03624     VectorIterator operator--() {
03625         assert (index > 0);
03626         --index;
03627         return *this;
03628     }
03629     VectorIterator operator--(int) {
03630         assert (index > 0);
03631         VectorIterator current = *this;
03632         --index;
03633         return current;
03634     }
03635     bool operator<(VectorIterator iter) const {
03636         return (index < iter.index);
03637     }
03638     bool operator>(VectorIterator iter) const {
03639         return (index > iter.index);
03640     }
03641     bool operator<=(VectorIterator iter) const {
03642         return (index <= iter.index);
03643     }
03644     bool operator>=(VectorIterator iter) const {
03645         return (index >= iter.index);
03646     }
03647     ptrdiff_t operator-(VectorIterator iter) const {
03648         return (index - iter.index);
03649     }
03650     VectorIterator operator-(ptrdiff_t n) const {
03651         return VectorIterator(vector, index-n);
03652     }
03653     VectorIterator operator+(ptrdiff_t n) const {
03654         return VectorIterator(vector, index+n);
03655     }
03656     bool operator==(VectorIterator iter) const {
03657         return (index == iter.index);
03658     }
03659     bool operator!=(VectorIterator iter) const {
03660         return (index != iter.index);
03661     }
03662 private:
03663     VECTOR_CLASS& vector;
03664     ptrdiff_t index;
03665 };
03666 
03667 } //namespace SimTK
03668 
03669 #endif //SimTK_SIMMATRIX_BIGMATRIX_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines