MatrixBase.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
00005 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
00006 //
00007 // Eigen is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public
00009 // License as published by the Free Software Foundation; either
00010 // version 3 of the License, or (at your option) any later version.
00011 //
00012 // Alternatively, you can redistribute it and/or
00013 // modify it under the terms of the GNU General Public License as
00014 // published by the Free Software Foundation; either version 2 of
00015 // the License, or (at your option) any later version.
00016 //
00017 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00018 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00019 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00020 // GNU General Public License for more details.
00021 //
00022 // You should have received a copy of the GNU Lesser General Public
00023 // License and a copy of the GNU General Public License along with
00024 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00025 
00026 #ifndef EIGEN_MATRIXBASE_H
00027 #define EIGEN_MATRIXBASE_H
00028 
00029 namespace Eigen {
00030 
00063 template<typename Derived> class MatrixBase
00064   : public DenseBase<Derived>
00065 {
00066   public:
00067 #ifndef EIGEN_PARSED_BY_DOXYGEN
00068     typedef MatrixBase StorageBaseType;
00069     typedef typename internal::traits<Derived>::StorageKind StorageKind;
00070     typedef typename internal::traits<Derived>::Index Index;
00071     typedef typename internal::traits<Derived>::Scalar Scalar;
00072     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00073     typedef typename NumTraits<Scalar>::Real RealScalar;
00074 
00075     typedef DenseBase<Derived> Base;
00076     using Base::RowsAtCompileTime;
00077     using Base::ColsAtCompileTime;
00078     using Base::SizeAtCompileTime;
00079     using Base::MaxRowsAtCompileTime;
00080     using Base::MaxColsAtCompileTime;
00081     using Base::MaxSizeAtCompileTime;
00082     using Base::IsVectorAtCompileTime;
00083     using Base::Flags;
00084     using Base::CoeffReadCost;
00085 
00086     using Base::derived;
00087     using Base::const_cast_derived;
00088     using Base::rows;
00089     using Base::cols;
00090     using Base::size;
00091     using Base::coeff;
00092     using Base::coeffRef;
00093     using Base::lazyAssign;
00094     using Base::eval;
00095     using Base::operator+=;
00096     using Base::operator-=;
00097     using Base::operator*=;
00098     using Base::operator/=;
00099 
00100     typedef typename Base::CoeffReturnType CoeffReturnType;
00101     typedef typename Base::ConstTransposeReturnType ConstTransposeReturnType;
00102     typedef typename Base::RowXpr RowXpr;
00103     typedef typename Base::ColXpr ColXpr;
00104 #endif // not EIGEN_PARSED_BY_DOXYGEN
00105 
00106 
00107 
00108 #ifndef EIGEN_PARSED_BY_DOXYGEN
00109 
00110     typedef Matrix<Scalar,EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime),
00111                           EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType;
00112 #endif // not EIGEN_PARSED_BY_DOXYGEN
00113 
00116     inline Index diagonalSize() const { return (std::min)(rows(),cols()); }
00117 
00124     typedef Matrix<typename internal::traits<Derived>::Scalar,
00125                 internal::traits<Derived>::RowsAtCompileTime,
00126                 internal::traits<Derived>::ColsAtCompileTime,
00127                 AutoAlign | (internal::traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor),
00128                 internal::traits<Derived>::MaxRowsAtCompileTime,
00129                 internal::traits<Derived>::MaxColsAtCompileTime
00130           > PlainObject;
00131 
00132 #ifndef EIGEN_PARSED_BY_DOXYGEN
00133 
00134     typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Derived> ConstantReturnType;
00136     typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
00137                         CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, ConstTransposeReturnType>,
00138                         ConstTransposeReturnType
00139                      >::type AdjointReturnType;
00141     typedef Matrix<std::complex<RealScalar>, internal::traits<Derived>::ColsAtCompileTime, 1, ColMajor> EigenvaluesReturnType;
00143     typedef CwiseNullaryOp<internal::scalar_identity_op<Scalar>,Derived> IdentityReturnType;
00145     typedef Block<const CwiseNullaryOp<internal::scalar_identity_op<Scalar>, SquareMatrixType>,
00146                   internal::traits<Derived>::RowsAtCompileTime,
00147                   internal::traits<Derived>::ColsAtCompileTime> BasisReturnType;
00148 #endif // not EIGEN_PARSED_BY_DOXYGEN
00149 
00150 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::MatrixBase
00151 #   include "../plugins/CommonCwiseUnaryOps.h"
00152 #   include "../plugins/CommonCwiseBinaryOps.h"
00153 #   include "../plugins/MatrixCwiseUnaryOps.h"
00154 #   include "../plugins/MatrixCwiseBinaryOps.h"
00155 #   ifdef EIGEN_MATRIXBASE_PLUGIN
00156 #     include EIGEN_MATRIXBASE_PLUGIN
00157 #   endif
00158 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS
00159 
00163     Derived& operator=(const MatrixBase& other);
00164 
00165     // We cannot inherit here via Base::operator= since it is causing
00166     // trouble with MSVC.
00167 
00168     template <typename OtherDerived>
00169     Derived& operator=(const DenseBase<OtherDerived>& other);
00170 
00171     template <typename OtherDerived>
00172     Derived& operator=(const EigenBase<OtherDerived>& other);
00173 
00174     template<typename OtherDerived>
00175     Derived& operator=(const ReturnByValue<OtherDerived>& other);
00176 
00177 #ifndef EIGEN_PARSED_BY_DOXYGEN
00178     template<typename ProductDerived, typename Lhs, typename Rhs>
00179     Derived& lazyAssign(const ProductBase<ProductDerived, Lhs,Rhs>& other);
00180 #endif // not EIGEN_PARSED_BY_DOXYGEN
00181 
00182     template<typename OtherDerived>
00183     Derived& operator+=(const MatrixBase<OtherDerived>& other);
00184     template<typename OtherDerived>
00185     Derived& operator-=(const MatrixBase<OtherDerived>& other);
00186 
00187     template<typename OtherDerived>
00188     const typename ProductReturnType<Derived,OtherDerived>::Type
00189     operator*(const MatrixBase<OtherDerived> &other) const;
00190 
00191     template<typename OtherDerived>
00192     const typename LazyProductReturnType<Derived,OtherDerived>::Type
00193     lazyProduct(const MatrixBase<OtherDerived> &other) const;
00194 
00195     template<typename OtherDerived>
00196     Derived& operator*=(const EigenBase<OtherDerived>& other);
00197 
00198     template<typename OtherDerived>
00199     void applyOnTheLeft(const EigenBase<OtherDerived>& other);
00200 
00201     template<typename OtherDerived>
00202     void applyOnTheRight(const EigenBase<OtherDerived>& other);
00203 
00204     template<typename DiagonalDerived>
00205     const DiagonalProduct<Derived, DiagonalDerived, OnTheRight>
00206     operator*(const DiagonalBase<DiagonalDerived> &diagonal) const;
00207 
00208     template<typename OtherDerived>
00209     typename internal::scalar_product_traits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType
00210     dot(const MatrixBase<OtherDerived>& other) const;
00211 
00212     #ifdef EIGEN2_SUPPORT
00213       template<typename OtherDerived>
00214       Scalar eigen2_dot(const MatrixBase<OtherDerived>& other) const;
00215     #endif
00216 
00217     RealScalar squaredNorm() const;
00218     RealScalar norm() const;
00219     RealScalar stableNorm() const;
00220     RealScalar blueNorm() const;
00221     RealScalar hypotNorm() const;
00222     const PlainObject normalized() const;
00223     void normalize();
00224 
00225     const AdjointReturnType adjoint() const;
00226     void adjointInPlace();
00227 
00228     typedef Diagonal<Derived> DiagonalReturnType;
00229     DiagonalReturnType diagonal();
00230     typedef const Diagonal<const Derived> ConstDiagonalReturnType;
00231     const ConstDiagonalReturnType diagonal() const;
00232 
00233     template<int Index> struct DiagonalIndexReturnType { typedef Diagonal<Derived,Index> Type; };
00234     template<int Index> struct ConstDiagonalIndexReturnType { typedef const Diagonal<const Derived,Index> Type; };
00235 
00236     template<int Index> typename DiagonalIndexReturnType<Index>::Type diagonal();
00237     template<int Index> typename ConstDiagonalIndexReturnType<Index>::Type diagonal() const;
00238 
00239     // Note: The "MatrixBase::" prefixes are added to help MSVC9 to match these declarations with the later implementations.
00240     // On the other hand they confuse MSVC8...
00241     #if (defined _MSC_VER) && (_MSC_VER >= 1500) // 2008 or later
00242     typename MatrixBase::template DiagonalIndexReturnType<Dynamic>::Type diagonal(Index index);
00243     typename MatrixBase::template ConstDiagonalIndexReturnType<Dynamic>::Type diagonal(Index index) const;
00244     #else
00245     typename DiagonalIndexReturnType<Dynamic>::Type diagonal(Index index);
00246     typename ConstDiagonalIndexReturnType<Dynamic>::Type diagonal(Index index) const;
00247     #endif
00248 
00249     #ifdef EIGEN2_SUPPORT
00250     template<unsigned int Mode> typename internal::eigen2_part_return_type<Derived, Mode>::type part();
00251     template<unsigned int Mode> const typename internal::eigen2_part_return_type<Derived, Mode>::type part() const;
00252     
00253     // huuuge hack. make Eigen2's matrix.part<Diagonal>() work in eigen3. Problem: Diagonal is now a class template instead
00254     // of an integer constant. Solution: overload the part() method template wrt template parameters list.
00255     template<template<typename T, int n> class U>
00256     const DiagonalWrapper<ConstDiagonalReturnType> part() const
00257     { return diagonal().asDiagonal(); }
00258     #endif // EIGEN2_SUPPORT
00259 
00260     template<unsigned int Mode> struct TriangularViewReturnType { typedef TriangularView<Derived, Mode> Type; };
00261     template<unsigned int Mode> struct ConstTriangularViewReturnType { typedef const TriangularView<const Derived, Mode> Type; };
00262 
00263     template<unsigned int Mode> typename TriangularViewReturnType<Mode>::Type triangularView();
00264     template<unsigned int Mode> typename ConstTriangularViewReturnType<Mode>::Type triangularView() const;
00265 
00266     template<unsigned int UpLo> struct SelfAdjointViewReturnType { typedef SelfAdjointView<Derived, UpLo> Type; };
00267     template<unsigned int UpLo> struct ConstSelfAdjointViewReturnType { typedef const SelfAdjointView<const Derived, UpLo> Type; };
00268 
00269     template<unsigned int UpLo> typename SelfAdjointViewReturnType<UpLo>::Type selfadjointView();
00270     template<unsigned int UpLo> typename ConstSelfAdjointViewReturnType<UpLo>::Type selfadjointView() const;
00271 
00272     const SparseView<Derived> sparseView(const Scalar& m_reference = Scalar(0),
00273                                          typename NumTraits<Scalar>::Real m_epsilon = NumTraits<Scalar>::dummy_precision()) const;
00274     static const IdentityReturnType Identity();
00275     static const IdentityReturnType Identity(Index rows, Index cols);
00276     static const BasisReturnType Unit(Index size, Index i);
00277     static const BasisReturnType Unit(Index i);
00278     static const BasisReturnType UnitX();
00279     static const BasisReturnType UnitY();
00280     static const BasisReturnType UnitZ();
00281     static const BasisReturnType UnitW();
00282 
00283     const DiagonalWrapper<const Derived> asDiagonal() const;
00284     const PermutationWrapper<const Derived> asPermutation() const;
00285 
00286     Derived& setIdentity();
00287     Derived& setIdentity(Index rows, Index cols);
00288 
00289     bool isIdentity(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
00290     bool isDiagonal(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
00291 
00292     bool isUpperTriangular(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
00293     bool isLowerTriangular(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
00294 
00295     template<typename OtherDerived>
00296     bool isOrthogonal(const MatrixBase<OtherDerived>& other,
00297                       RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
00298     bool isUnitary(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
00299 
00304     template<typename OtherDerived>
00305     inline bool operator==(const MatrixBase<OtherDerived>& other) const
00306     { return cwiseEqual(other).all(); }
00307 
00312     template<typename OtherDerived>
00313     inline bool operator!=(const MatrixBase<OtherDerived>& other) const
00314     { return cwiseNotEqual(other).any(); }
00315 
00316     NoAlias<Derived,Eigen::MatrixBase > noalias();
00317 
00318     inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
00319     inline ForceAlignedAccess<Derived> forceAlignedAccess();
00320     template<bool Enable> inline typename internal::add_const_on_value_type<typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type>::type forceAlignedAccessIf() const;
00321     template<bool Enable> inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf();
00322 
00323     Scalar trace() const;
00324 
00326 
00327     template<int p> RealScalar lpNorm() const;
00328 
00329     MatrixBase<Derived>& matrix() { return *this; }
00330     const MatrixBase<Derived>& matrix() const { return *this; }
00331 
00334     ArrayWrapper<Derived> array() { return derived(); }
00335     const ArrayWrapper<const Derived> array() const { return derived(); }
00336 
00338 
00339     const FullPivLU<PlainObject> fullPivLu() const;
00340     const PartialPivLU<PlainObject> partialPivLu() const;
00341 
00342     #if EIGEN2_SUPPORT_STAGE < STAGE20_RESOLVE_API_CONFLICTS
00343     const LU<PlainObject> lu() const;
00344     #endif
00345 
00346     #ifdef EIGEN2_SUPPORT
00347     const LU<PlainObject> eigen2_lu() const;
00348     #endif
00349 
00350     #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS
00351     const PartialPivLU<PlainObject> lu() const;
00352     #endif
00353     
00354     #ifdef EIGEN2_SUPPORT
00355     template<typename ResultType>
00356     void computeInverse(MatrixBase<ResultType> *result) const {
00357       *result = this->inverse();
00358     }
00359     #endif
00360 
00361     const internal::inverse_impl<Derived> inverse() const;
00362     template<typename ResultType>
00363     void computeInverseAndDetWithCheck(
00364       ResultType& inverse,
00365       typename ResultType::Scalar& determinant,
00366       bool& invertible,
00367       const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision()
00368     ) const;
00369     template<typename ResultType>
00370     void computeInverseWithCheck(
00371       ResultType& inverse,
00372       bool& invertible,
00373       const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision()
00374     ) const;
00375     Scalar determinant() const;
00376 
00378 
00379     const LLT<PlainObject>  llt() const;
00380     const LDLT<PlainObject> ldlt() const;
00381 
00383 
00384     const HouseholderQR<PlainObject> householderQr() const;
00385     const ColPivHouseholderQR<PlainObject> colPivHouseholderQr() const;
00386     const FullPivHouseholderQR<PlainObject> fullPivHouseholderQr() const;
00387     
00388     #ifdef EIGEN2_SUPPORT
00389     const QR<PlainObject> qr() const;
00390     #endif
00391 
00392     EigenvaluesReturnType eigenvalues() const;
00393     RealScalar operatorNorm() const;
00394 
00396 
00397     JacobiSVD<PlainObject> jacobiSvd(unsigned int computationOptions = 0) const;
00398 
00399     #ifdef EIGEN2_SUPPORT
00400     SVD<PlainObject> svd() const;
00401     #endif
00402 
00404 
00405     #ifndef EIGEN_PARSED_BY_DOXYGEN
00406 
00407     template<typename OtherDerived> struct cross_product_return_type {
00408       typedef typename internal::scalar_product_traits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType Scalar;
00409       typedef Matrix<Scalar,MatrixBase::RowsAtCompileTime,MatrixBase::ColsAtCompileTime> type;
00410     };
00411     #endif // EIGEN_PARSED_BY_DOXYGEN
00412     template<typename OtherDerived>
00413     typename cross_product_return_type<OtherDerived>::type
00414     cross(const MatrixBase<OtherDerived>& other) const;
00415     template<typename OtherDerived>
00416     PlainObject cross3(const MatrixBase<OtherDerived>& other) const;
00417     PlainObject unitOrthogonal(void) const;
00418     Matrix<Scalar,3,1> eulerAngles(Index a0, Index a1, Index a2) const;
00419     
00420     #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS
00421     ScalarMultipleReturnType operator*(const UniformScaling<Scalar>& s) const;
00422     // put this as separate enum value to work around possible GCC 4.3 bug (?)
00423     enum { HomogeneousReturnTypeDirection = ColsAtCompileTime==1?Vertical:Horizontal };
00424     typedef Homogeneous<Derived, HomogeneousReturnTypeDirection> HomogeneousReturnType;
00425     HomogeneousReturnType homogeneous() const;
00426     #endif
00427     
00428     enum {
00429       SizeMinusOne = SizeAtCompileTime==Dynamic ? Dynamic : SizeAtCompileTime-1
00430     };
00431     typedef Block<const Derived,
00432                   internal::traits<Derived>::ColsAtCompileTime==1 ? SizeMinusOne : 1,
00433                   internal::traits<Derived>::ColsAtCompileTime==1 ? 1 : SizeMinusOne> ConstStartMinusOne;
00434     typedef CwiseUnaryOp<internal::scalar_quotient1_op<typename internal::traits<Derived>::Scalar>,
00435                 const ConstStartMinusOne > HNormalizedReturnType;
00436 
00437     const HNormalizedReturnType hnormalized() const;
00438 
00440 
00441     void makeHouseholderInPlace(Scalar& tau, RealScalar& beta);
00442     template<typename EssentialPart>
00443     void makeHouseholder(EssentialPart& essential,
00444                          Scalar& tau, RealScalar& beta) const;
00445     template<typename EssentialPart>
00446     void applyHouseholderOnTheLeft(const EssentialPart& essential,
00447                                    const Scalar& tau,
00448                                    Scalar* workspace);
00449     template<typename EssentialPart>
00450     void applyHouseholderOnTheRight(const EssentialPart& essential,
00451                                     const Scalar& tau,
00452                                     Scalar* workspace);
00453 
00455 
00456     template<typename OtherScalar>
00457     void applyOnTheLeft(Index p, Index q, const JacobiRotation<OtherScalar>& j);
00458     template<typename OtherScalar>
00459     void applyOnTheRight(Index p, Index q, const JacobiRotation<OtherScalar>& j);
00460 
00462 
00463     typedef typename internal::stem_function<Scalar>::type StemFunction;
00464     const MatrixExponentialReturnValue<Derived> exp() const;
00465     const MatrixFunctionReturnValue<Derived> matrixFunction(StemFunction f) const;
00466     const MatrixFunctionReturnValue<Derived> cosh() const;
00467     const MatrixFunctionReturnValue<Derived> sinh() const;
00468     const MatrixFunctionReturnValue<Derived> cos() const;
00469     const MatrixFunctionReturnValue<Derived> sin() const;
00470     const MatrixSquareRootReturnValue<Derived> sqrt() const;
00471     const MatrixLogarithmReturnValue<Derived> log() const;
00472 
00473 #ifdef EIGEN2_SUPPORT
00474     template<typename ProductDerived, typename Lhs, typename Rhs>
00475     Derived& operator+=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0,
00476                                       EvalBeforeAssigningBit>& other);
00477 
00478     template<typename ProductDerived, typename Lhs, typename Rhs>
00479     Derived& operator-=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0,
00480                                       EvalBeforeAssigningBit>& other);
00481 
00484     template<typename OtherDerived>
00485     Derived& lazyAssign(const Flagged<OtherDerived, 0, EvalBeforeAssigningBit>& other)
00486     { return lazyAssign(other._expression()); }
00487 
00488     template<unsigned int Added>
00489     const Flagged<Derived, Added, 0> marked() const;
00490     const Flagged<Derived, 0, EvalBeforeAssigningBit> lazy() const;
00491 
00492     inline const Cwise<Derived> cwise() const;
00493     inline Cwise<Derived> cwise();
00494 
00495     VectorBlock<Derived> start(Index size);
00496     const VectorBlock<const Derived> start(Index size) const;
00497     VectorBlock<Derived> end(Index size);
00498     const VectorBlock<const Derived> end(Index size) const;
00499     template<int Size> VectorBlock<Derived,Size> start();
00500     template<int Size> const VectorBlock<const Derived,Size> start() const;
00501     template<int Size> VectorBlock<Derived,Size> end();
00502     template<int Size> const VectorBlock<const Derived,Size> end() const;
00503 
00504     Minor<Derived> minor(Index row, Index col);
00505     const Minor<Derived> minor(Index row, Index col) const;
00506 #endif
00507 
00508   protected:
00509     MatrixBase() : Base() {}
00510 
00511   private:
00512     explicit MatrixBase(int);
00513     MatrixBase(int,int);
00514     template<typename OtherDerived> explicit MatrixBase(const MatrixBase<OtherDerived>&);
00515   protected:
00516     // mixing arrays and matrices is not legal
00517     template<typename OtherDerived> Derived& operator+=(const ArrayBase<OtherDerived>& )
00518     {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;}
00519     // mixing arrays and matrices is not legal
00520     template<typename OtherDerived> Derived& operator-=(const ArrayBase<OtherDerived>& )
00521     {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;}
00522 };
00523 
00524 } // end namespace Eigen
00525 
00526 #endif // EIGEN_MATRIXBASE_H