// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2006-2009 Benoit Jacob // Copyright (C) 2008 Gael Guennebaud // // Eigen is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 3 of the License, or (at your option) any later version. // // Alternatively, you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of // the License, or (at your option) any later version. // // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the // GNU General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License and a copy of the GNU General Public License along with // Eigen. If not, see . #ifndef EIGEN_MATRIXBASE_H #define EIGEN_MATRIXBASE_H /** \class MatrixBase * \ingroup Core_Module * * \brief Base class for all dense matrices, vectors, and expressions * * This class is the base that is inherited by all matrix, vector, and related expression * types. Most of the Eigen API is contained in this class, and its base classes. Other important * classes for the Eigen API are Matrix, and VectorwiseOp. * * Note that some methods are defined in other modules such as the \ref LU_Module LU module * for all functions related to matrix inversions. * * \param Derived is the derived type, e.g. a matrix type, or an expression, etc. * * When writing a function taking Eigen objects as argument, if you want your function * to take as argument any matrix, vector, or expression, just let it take a * MatrixBase argument. As an example, here is a function printFirstRow which, given * a matrix, vector, or expression \a x, prints the first row of \a x. * * \code template void printFirstRow(const Eigen::MatrixBase& x) { cout << x.row(0) << endl; } * \endcode * * \sa \ref TopicClassHierarchy */ template class MatrixBase : public DenseBase { public: #ifndef EIGEN_PARSED_BY_DOXYGEN typedef MatrixBase StorageBaseType; typedef typename ei_traits::StorageKind StorageKind; typedef typename ei_traits::Index Index; typedef typename ei_traits::Scalar Scalar; typedef typename ei_packet_traits::type PacketScalar; typedef typename NumTraits::Real RealScalar; typedef DenseBase Base; using Base::RowsAtCompileTime; using Base::ColsAtCompileTime; using Base::SizeAtCompileTime; using Base::MaxRowsAtCompileTime; using Base::MaxColsAtCompileTime; using Base::MaxSizeAtCompileTime; using Base::IsVectorAtCompileTime; using Base::Flags; using Base::CoeffReadCost; using Base::derived; using Base::const_cast_derived; using Base::rows; using Base::cols; using Base::size; using Base::coeff; using Base::coeffRef; using Base::lazyAssign; using Base::eval; using Base::operator+=; using Base::operator-=; using Base::operator*=; using Base::operator/=; typedef typename Base::CoeffReturnType CoeffReturnType; typedef typename Base::RowXpr RowXpr; typedef typename Base::ColXpr ColXpr; #endif // not EIGEN_PARSED_BY_DOXYGEN #ifndef EIGEN_PARSED_BY_DOXYGEN /** type of the equivalent square matrix */ typedef Matrix SquareMatrixType; #endif // not EIGEN_PARSED_BY_DOXYGEN /** \returns the size of the main diagonal, which is min(rows(),cols()). * \sa rows(), cols(), SizeAtCompileTime. */ inline Index diagonalSize() const { return std::min(rows(),cols()); } /** \brief The plain matrix type corresponding to this expression. * * This is not necessarily exactly the return type of eval(). In the case of plain matrices, * the return type of eval() is a const reference to a matrix, not a matrix! It is however guaranteed * that the return type of eval() is either PlainObject or const PlainObject&. */ typedef Matrix::Scalar, ei_traits::RowsAtCompileTime, ei_traits::ColsAtCompileTime, AutoAlign | (ei_traits::Flags&RowMajorBit ? RowMajor : ColMajor), ei_traits::MaxRowsAtCompileTime, ei_traits::MaxColsAtCompileTime > PlainObject; #ifndef EIGEN_PARSED_BY_DOXYGEN /** \internal Represents a matrix with all coefficients equal to one another*/ typedef CwiseNullaryOp,Derived> ConstantReturnType; /** \internal the return type of MatrixBase::adjoint() */ typedef typename ei_meta_if::IsComplex, CwiseUnaryOp, Eigen::Transpose >, Transpose >::ret AdjointReturnType; /** \internal Return type of eigenvalues() */ typedef Matrix, ei_traits::ColsAtCompileTime, 1, ColMajor> EigenvaluesReturnType; /** \internal the return type of identity */ typedef CwiseNullaryOp,Derived> IdentityReturnType; /** \internal the return type of unit vectors */ typedef Block, SquareMatrixType>, ei_traits::RowsAtCompileTime, ei_traits::ColsAtCompileTime> BasisReturnType; #endif // not EIGEN_PARSED_BY_DOXYGEN #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::MatrixBase # include "../plugins/CommonCwiseUnaryOps.h" # include "../plugins/CommonCwiseBinaryOps.h" # include "../plugins/MatrixCwiseUnaryOps.h" # include "../plugins/MatrixCwiseBinaryOps.h" # ifdef EIGEN_MATRIXBASE_PLUGIN # include EIGEN_MATRIXBASE_PLUGIN # endif #undef EIGEN_CURRENT_STORAGE_BASE_CLASS /** Special case of the template operator=, in order to prevent the compiler * from generating a default operator= (issue hit with g++ 4.1) */ Derived& operator=(const MatrixBase& other); // We cannot inherit here via Base::operator= since it is causing // trouble with MSVC. template Derived& operator=(const DenseBase& other); template Derived& operator=(const EigenBase& other); template Derived& operator=(const ReturnByValue& other); #ifndef EIGEN_PARSED_BY_DOXYGEN template Derived& lazyAssign(const ProductBase& other); #endif // not EIGEN_PARSED_BY_DOXYGEN template Derived& operator+=(const MatrixBase& other); template Derived& operator-=(const MatrixBase& other); template const typename ProductReturnType::Type operator*(const MatrixBase &other) const; template const typename LazyProductReturnType::Type lazyProduct(const MatrixBase &other) const; template Derived& operator*=(const EigenBase& other); template void applyOnTheLeft(const EigenBase& other); template void applyOnTheRight(const EigenBase& other); template const DiagonalProduct operator*(const DiagonalBase &diagonal) const; template Scalar dot(const MatrixBase& other) const; RealScalar squaredNorm() const; RealScalar norm() const; RealScalar stableNorm() const; RealScalar blueNorm() const; RealScalar hypotNorm() const; const PlainObject normalized() const; void normalize(); const AdjointReturnType adjoint() const; void adjointInPlace(); Diagonal diagonal(); const Diagonal diagonal() const; template Diagonal diagonal(); template const Diagonal diagonal() const; Diagonal diagonal(Index index); const Diagonal diagonal(Index index) const; template TriangularView part(); template const TriangularView part() const; template TriangularView triangularView(); template const TriangularView triangularView() const; template SelfAdjointView selfadjointView(); template const SelfAdjointView selfadjointView() const; const SparseView sparseView(const Scalar& m_reference = Scalar(0), typename NumTraits::Real m_epsilon = NumTraits::dummy_precision()) const; static const IdentityReturnType Identity(); static const IdentityReturnType Identity(Index rows, Index cols); static const BasisReturnType Unit(Index size, Index i); static const BasisReturnType Unit(Index i); static const BasisReturnType UnitX(); static const BasisReturnType UnitY(); static const BasisReturnType UnitZ(); static const BasisReturnType UnitW(); const DiagonalWrapper asDiagonal() const; Derived& setIdentity(); Derived& setIdentity(Index rows, Index cols); bool isIdentity(RealScalar prec = NumTraits::dummy_precision()) const; bool isDiagonal(RealScalar prec = NumTraits::dummy_precision()) const; bool isUpperTriangular(RealScalar prec = NumTraits::dummy_precision()) const; bool isLowerTriangular(RealScalar prec = NumTraits::dummy_precision()) const; template bool isOrthogonal(const MatrixBase& other, RealScalar prec = NumTraits::dummy_precision()) const; bool isUnitary(RealScalar prec = NumTraits::dummy_precision()) const; /** \returns true if each coefficients of \c *this and \a other are all exactly equal. * \warning When using floating point scalar values you probably should rather use a * fuzzy comparison such as isApprox() * \sa isApprox(), operator!= */ template inline bool operator==(const MatrixBase& other) const { return cwiseEqual(other).all(); } /** \returns true if at least one pair of coefficients of \c *this and \a other are not exactly equal to each other. * \warning When using floating point scalar values you probably should rather use a * fuzzy comparison such as isApprox() * \sa isApprox(), operator== */ template inline bool operator!=(const MatrixBase& other) const { return cwiseNotEqual(other).any(); } NoAlias noalias(); inline const ForceAlignedAccess forceAlignedAccess() const; inline ForceAlignedAccess forceAlignedAccess(); template inline typename ei_makeconst,Derived&>::ret>::type forceAlignedAccessIf() const; template inline typename ei_meta_if,Derived&>::ret forceAlignedAccessIf(); Scalar trace() const; /////////// Array module /////////// template RealScalar lpNorm() const; MatrixBase& matrix() { return *this; } const MatrixBase& matrix() const { return *this; } /** \returns an \link ArrayBase Array \endlink expression of this matrix * \sa ArrayBase::matrix() */ ArrayWrapper array() { return derived(); } const ArrayWrapper array() const { return derived(); } /////////// LU module /////////// const FullPivLU fullPivLu() const; const PartialPivLU partialPivLu() const; const PartialPivLU lu() const; const ei_inverse_impl inverse() const; template void computeInverseAndDetWithCheck( ResultType& inverse, typename ResultType::Scalar& determinant, bool& invertible, const RealScalar& absDeterminantThreshold = NumTraits::dummy_precision() ) const; template void computeInverseWithCheck( ResultType& inverse, bool& invertible, const RealScalar& absDeterminantThreshold = NumTraits::dummy_precision() ) const; Scalar determinant() const; /////////// Cholesky module /////////// const LLT llt() const; const LDLT ldlt() const; /////////// QR module /////////// const HouseholderQR householderQr() const; const ColPivHouseholderQR colPivHouseholderQr() const; const FullPivHouseholderQR fullPivHouseholderQr() const; EigenvaluesReturnType eigenvalues() const; RealScalar operatorNorm() const; /////////// SVD module /////////// JacobiSVD jacobiSvd(unsigned int computationOptions = 0) const; /////////// Geometry module /////////// template PlainObject cross(const MatrixBase& other) const; template PlainObject cross3(const MatrixBase& other) const; PlainObject unitOrthogonal(void) const; Matrix eulerAngles(Index a0, Index a1, Index a2) const; ScalarMultipleReturnType operator*(const UniformScaling& s) const; enum { SizeMinusOne = SizeAtCompileTime==Dynamic ? Dynamic : SizeAtCompileTime-1 }; typedef Block::ColsAtCompileTime==1 ? SizeMinusOne : 1, ei_traits::ColsAtCompileTime==1 ? 1 : SizeMinusOne> StartMinusOne; typedef CwiseUnaryOp::Scalar>, StartMinusOne > HNormalizedReturnType; HNormalizedReturnType hnormalized() const; // put this as separate enum value to work around possible GCC 4.3 bug (?) enum { HomogeneousReturnTypeDirection = ColsAtCompileTime==1?Vertical:Horizontal }; typedef Homogeneous HomogeneousReturnType; HomogeneousReturnType homogeneous() const; ////////// Householder module /////////// void makeHouseholderInPlace(Scalar& tau, RealScalar& beta); template void makeHouseholder(EssentialPart& essential, Scalar& tau, RealScalar& beta) const; template void applyHouseholderOnTheLeft(const EssentialPart& essential, const Scalar& tau, Scalar* workspace); template void applyHouseholderOnTheRight(const EssentialPart& essential, const Scalar& tau, Scalar* workspace); ///////// Jacobi module ///////// template void applyOnTheLeft(Index p, Index q, const JacobiRotation& j); template void applyOnTheRight(Index p, Index q, const JacobiRotation& j); ///////// MatrixFunctions module ///////// typedef typename ei_stem_function::type StemFunction; const MatrixExponentialReturnValue exp() const; const MatrixFunctionReturnValue matrixFunction(StemFunction f) const; const MatrixFunctionReturnValue cosh() const; const MatrixFunctionReturnValue sinh() const; const MatrixFunctionReturnValue cos() const; const MatrixFunctionReturnValue sin() const; #ifdef EIGEN2_SUPPORT template Derived& operator+=(const Flagged, 0, EvalBeforeAssigningBit>& other); template Derived& operator-=(const Flagged, 0, EvalBeforeAssigningBit>& other); /** \deprecated because .lazy() is deprecated * Overloaded for cache friendly product evaluation */ template Derived& lazyAssign(const Flagged& other) { return lazyAssign(other._expression()); } template const Flagged marked() const; const Flagged lazy() const; inline const Cwise cwise() const; inline Cwise cwise(); VectorBlock start(Index size); const VectorBlock start(Index size) const; VectorBlock end(Index size); const VectorBlock end(Index size) const; template VectorBlock start(); template const VectorBlock start() const; template VectorBlock end(); template const VectorBlock end() const; Minor minor(Index row, Index col); const Minor minor(Index row, Index col) const; #endif protected: MatrixBase() : Base() {} private: explicit MatrixBase(int); MatrixBase(int,int); template explicit MatrixBase(const MatrixBase&); protected: // mixing arrays and matrices is not legal template Derived& operator+=(const ArrayBase& array) {EIGEN_STATIC_ASSERT(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);} // mixing arrays and matrices is not legal template Derived& operator-=(const ArrayBase& array) {EIGEN_STATIC_ASSERT(sizeof(typename OtherDerived::Scalar)==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES);} }; #endif // EIGEN_MATRIXBASE_H