Simbody
3.4 (development)
|
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_