DenseBase.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) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
00005 // Copyright (C) 2008-2010 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_DENSEBASE_H
00027 #define EIGEN_DENSEBASE_H
00028 
00029 namespace Eigen {
00030 
00046 template<typename Derived> class DenseBase
00047 #ifndef EIGEN_PARSED_BY_DOXYGEN
00048   : public internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
00049                                      typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>
00050 #else
00051   : public DenseCoeffsBase<Derived>
00052 #endif // not EIGEN_PARSED_BY_DOXYGEN
00053 {
00054   public:
00055     using internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
00056                 typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>::operator*;
00057 
00058     class InnerIterator;
00059 
00060     typedef typename internal::traits<Derived>::StorageKind StorageKind;
00061 
00066     typedef typename internal::traits<Derived>::Index Index; 
00067 
00068     typedef typename internal::traits<Derived>::Scalar Scalar;
00069     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00070     typedef typename NumTraits<Scalar>::Real RealScalar;
00071 
00072     typedef DenseCoeffsBase<Derived> Base;
00073     using Base::derived;
00074     using Base::const_cast_derived;
00075     using Base::rows;
00076     using Base::cols;
00077     using Base::size;
00078     using Base::rowIndexByOuterInner;
00079     using Base::colIndexByOuterInner;
00080     using Base::coeff;
00081     using Base::coeffByOuterInner;
00082     using Base::packet;
00083     using Base::packetByOuterInner;
00084     using Base::writePacket;
00085     using Base::writePacketByOuterInner;
00086     using Base::coeffRef;
00087     using Base::coeffRefByOuterInner;
00088     using Base::copyCoeff;
00089     using Base::copyCoeffByOuterInner;
00090     using Base::copyPacket;
00091     using Base::copyPacketByOuterInner;
00092     using Base::operator();
00093     using Base::operator[];
00094     using Base::x;
00095     using Base::y;
00096     using Base::z;
00097     using Base::w;
00098     using Base::stride;
00099     using Base::innerStride;
00100     using Base::outerStride;
00101     using Base::rowStride;
00102     using Base::colStride;
00103     typedef typename Base::CoeffReturnType CoeffReturnType;
00104 
00105     enum {
00106 
00107       RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
00113       ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
00120       SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
00121                                                    internal::traits<Derived>::ColsAtCompileTime>::ret),
00126       MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
00137       MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime,
00148       MaxSizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::MaxRowsAtCompileTime,
00149                                                       internal::traits<Derived>::MaxColsAtCompileTime>::ret),
00160       IsVectorAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime == 1
00161                            || internal::traits<Derived>::MaxColsAtCompileTime == 1,
00167       Flags = internal::traits<Derived>::Flags,
00172       IsRowMajor = int(Flags) & RowMajorBit, 
00174       InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
00175                              : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
00176 
00177       CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
00182       InnerStrideAtCompileTime = internal::inner_stride_at_compile_time<Derived>::ret,
00183       OuterStrideAtCompileTime = internal::outer_stride_at_compile_time<Derived>::ret
00184     };
00185 
00186     enum { ThisConstantIsPrivateInPlainObjectBase };
00187 
00190     inline Index nonZeros() const { return size(); }
00201     Index outerSize() const
00202     {
00203       return IsVectorAtCompileTime ? 1
00204            : int(IsRowMajor) ? this->rows() : this->cols();
00205     }
00206 
00212     Index innerSize() const
00213     {
00214       return IsVectorAtCompileTime ? this->size()
00215            : int(IsRowMajor) ? this->cols() : this->rows();
00216     }
00217 
00222     void resize(Index size)
00223     {
00224       EIGEN_ONLY_USED_FOR_DEBUG(size);
00225       eigen_assert(size == this->size()
00226                 && "DenseBase::resize() does not actually allow to resize.");
00227     }
00232     void resize(Index rows, Index cols)
00233     {
00234       EIGEN_ONLY_USED_FOR_DEBUG(rows);
00235       EIGEN_ONLY_USED_FOR_DEBUG(cols);
00236       eigen_assert(rows == this->rows() && cols == this->cols()
00237                 && "DenseBase::resize() does not actually allow to resize.");
00238     }
00239 
00240 #ifndef EIGEN_PARSED_BY_DOXYGEN
00241 
00243     typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Derived> ConstantReturnType;
00245     typedef CwiseNullaryOp<internal::linspaced_op<Scalar,false>,Derived> SequentialLinSpacedReturnType;
00247     typedef CwiseNullaryOp<internal::linspaced_op<Scalar,true>,Derived> RandomAccessLinSpacedReturnType;
00249     typedef Matrix<typename NumTraits<typename internal::traits<Derived>::Scalar>::Real, internal::traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
00250 
00251 #endif // not EIGEN_PARSED_BY_DOXYGEN
00252 
00254     template<typename OtherDerived>
00255     Derived& operator=(const DenseBase<OtherDerived>& other);
00256 
00260     Derived& operator=(const DenseBase& other);
00261 
00262     template<typename OtherDerived>
00263     Derived& operator=(const EigenBase<OtherDerived> &other);
00264 
00265     template<typename OtherDerived>
00266     Derived& operator+=(const EigenBase<OtherDerived> &other);
00267 
00268     template<typename OtherDerived>
00269     Derived& operator-=(const EigenBase<OtherDerived> &other);
00270 
00271     template<typename OtherDerived>
00272     Derived& operator=(const ReturnByValue<OtherDerived>& func);
00273 
00274 #ifndef EIGEN_PARSED_BY_DOXYGEN
00275 
00276     template<typename OtherDerived>
00277     Derived& lazyAssign(const DenseBase<OtherDerived>& other);
00278 #endif // not EIGEN_PARSED_BY_DOXYGEN
00279 
00280     CommaInitializer<Derived> operator<< (const Scalar& s);
00281 
00282     template<unsigned int Added,unsigned int Removed>
00283     const Flagged<Derived, Added, Removed> flagged() const;
00284 
00285     template<typename OtherDerived>
00286     CommaInitializer<Derived> operator<< (const DenseBase<OtherDerived>& other);
00287 
00288     Eigen::Transpose<Derived> transpose();
00289     typedef const Transpose<const Derived> ConstTransposeReturnType;
00290     ConstTransposeReturnType transpose() const;
00291     void transposeInPlace();
00292 #ifndef EIGEN_NO_DEBUG
00293   protected:
00294     template<typename OtherDerived>
00295     void checkTransposeAliasing(const OtherDerived& other) const;
00296   public:
00297 #endif
00298 
00299     typedef VectorBlock<Derived> SegmentReturnType;
00300     typedef const VectorBlock<const Derived> ConstSegmentReturnType;
00301     template<int Size> struct FixedSegmentReturnType { typedef VectorBlock<Derived, Size> Type; };
00302     template<int Size> struct ConstFixedSegmentReturnType { typedef const VectorBlock<const Derived, Size> Type; };
00303     
00304     // Note: The "DenseBase::" prefixes are added to help MSVC9 to match these declarations with the later implementations.
00305     SegmentReturnType segment(Index start, Index size);
00306     typename DenseBase::ConstSegmentReturnType segment(Index start, Index size) const;
00307 
00308     SegmentReturnType head(Index size);
00309     typename DenseBase::ConstSegmentReturnType head(Index size) const;
00310 
00311     SegmentReturnType tail(Index size);
00312     typename DenseBase::ConstSegmentReturnType tail(Index size) const;
00313 
00314     template<int Size> typename FixedSegmentReturnType<Size>::Type head();
00315     template<int Size> typename ConstFixedSegmentReturnType<Size>::Type head() const;
00316 
00317     template<int Size> typename FixedSegmentReturnType<Size>::Type tail();
00318     template<int Size> typename ConstFixedSegmentReturnType<Size>::Type tail() const;
00319 
00320     template<int Size> typename FixedSegmentReturnType<Size>::Type segment(Index start);
00321     template<int Size> typename ConstFixedSegmentReturnType<Size>::Type segment(Index start) const;
00322 
00323     static const ConstantReturnType
00324     Constant(Index rows, Index cols, const Scalar& value);
00325     static const ConstantReturnType
00326     Constant(Index size, const Scalar& value);
00327     static const ConstantReturnType
00328     Constant(const Scalar& value);
00329 
00330     static const SequentialLinSpacedReturnType
00331     LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high);
00332     static const RandomAccessLinSpacedReturnType
00333     LinSpaced(Index size, const Scalar& low, const Scalar& high);
00334     static const SequentialLinSpacedReturnType
00335     LinSpaced(Sequential_t, const Scalar& low, const Scalar& high);
00336     static const RandomAccessLinSpacedReturnType
00337     LinSpaced(const Scalar& low, const Scalar& high);
00338 
00339     template<typename CustomNullaryOp>
00340     static const CwiseNullaryOp<CustomNullaryOp, Derived>
00341     NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func);
00342     template<typename CustomNullaryOp>
00343     static const CwiseNullaryOp<CustomNullaryOp, Derived>
00344     NullaryExpr(Index size, const CustomNullaryOp& func);
00345     template<typename CustomNullaryOp>
00346     static const CwiseNullaryOp<CustomNullaryOp, Derived>
00347     NullaryExpr(const CustomNullaryOp& func);
00348 
00349     static const ConstantReturnType Zero(Index rows, Index cols);
00350     static const ConstantReturnType Zero(Index size);
00351     static const ConstantReturnType Zero();
00352     static const ConstantReturnType Ones(Index rows, Index cols);
00353     static const ConstantReturnType Ones(Index size);
00354     static const ConstantReturnType Ones();
00355 
00356     void fill(const Scalar& value);
00357     Derived& setConstant(const Scalar& value);
00358     Derived& setLinSpaced(Index size, const Scalar& low, const Scalar& high);
00359     Derived& setLinSpaced(const Scalar& low, const Scalar& high);
00360     Derived& setZero();
00361     Derived& setOnes();
00362     Derived& setRandom();
00363 
00364     template<typename OtherDerived>
00365     bool isApprox(const DenseBase<OtherDerived>& other,
00366                   RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
00367     bool isMuchSmallerThan(const RealScalar& other,
00368                            RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
00369     template<typename OtherDerived>
00370     bool isMuchSmallerThan(const DenseBase<OtherDerived>& other,
00371                            RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
00372 
00373     bool isApproxToConstant(const Scalar& value, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
00374     bool isConstant(const Scalar& value, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
00375     bool isZero(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
00376     bool isOnes(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
00377 
00378     inline Derived& operator*=(const Scalar& other);
00379     inline Derived& operator/=(const Scalar& other);
00380 
00381     typedef typename internal::add_const_on_value_type<typename internal::eval<Derived>::type>::type EvalReturnType;
00387     EIGEN_STRONG_INLINE EvalReturnType eval() const
00388     {
00389       // Even though MSVC does not honor strong inlining when the return type
00390       // is a dynamic matrix, we desperately need strong inlining for fixed
00391       // size types on MSVC.
00392       return typename internal::eval<Derived>::type(derived());
00393     }
00394 
00398     template<typename OtherDerived>
00399     void swap(const DenseBase<OtherDerived>& other,
00400               int = OtherDerived::ThisConstantIsPrivateInPlainObjectBase)
00401     {
00402       SwapWrapper<Derived>(derived()).lazyAssign(other.derived());
00403     }
00404 
00408     template<typename OtherDerived>
00409     void swap(PlainObjectBase<OtherDerived>& other)
00410     {
00411       SwapWrapper<Derived>(derived()).lazyAssign(other.derived());
00412     }
00413 
00414 
00415     inline const NestByValue<Derived> nestByValue() const;
00416     inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
00417     inline ForceAlignedAccess<Derived> forceAlignedAccess();
00418     template<bool Enable> inline const typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf() const;
00419     template<bool Enable> inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf();
00420 
00421     Scalar sum() const;
00422     Scalar mean() const;
00423     Scalar trace() const;
00424 
00425     Scalar prod() const;
00426 
00427     typename internal::traits<Derived>::Scalar minCoeff() const;
00428     typename internal::traits<Derived>::Scalar maxCoeff() const;
00429 
00430     template<typename IndexType>
00431     typename internal::traits<Derived>::Scalar minCoeff(IndexType* row, IndexType* col) const;
00432     template<typename IndexType>
00433     typename internal::traits<Derived>::Scalar maxCoeff(IndexType* row, IndexType* col) const;
00434     template<typename IndexType>
00435     typename internal::traits<Derived>::Scalar minCoeff(IndexType* index) const;
00436     template<typename IndexType>
00437     typename internal::traits<Derived>::Scalar maxCoeff(IndexType* index) const;
00438 
00439     template<typename BinaryOp>
00440     typename internal::result_of<BinaryOp(typename internal::traits<Derived>::Scalar)>::type
00441     redux(const BinaryOp& func) const;
00442 
00443     template<typename Visitor>
00444     void visit(Visitor& func) const;
00445 
00446     inline const WithFormat<Derived> format(const IOFormat& fmt) const;
00447 
00449     CoeffReturnType value() const
00450     {
00451       EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
00452       eigen_assert(this->rows() == 1 && this->cols() == 1);
00453       return derived().coeff(0,0);
00454     }
00455 
00457 
00458     bool all(void) const;
00459     bool any(void) const;
00460     Index count() const;
00461 
00462     typedef VectorwiseOp<Derived, Horizontal> RowwiseReturnType;
00463     typedef const VectorwiseOp<const Derived, Horizontal> ConstRowwiseReturnType;
00464     typedef VectorwiseOp<Derived, Vertical> ColwiseReturnType;
00465     typedef const VectorwiseOp<const Derived, Vertical> ConstColwiseReturnType;
00466 
00467     ConstRowwiseReturnType rowwise() const;
00468     RowwiseReturnType rowwise();
00469     ConstColwiseReturnType colwise() const;
00470     ColwiseReturnType colwise();
00471 
00472     static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(Index rows, Index cols);
00473     static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(Index size);
00474     static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random();
00475 
00476     template<typename ThenDerived,typename ElseDerived>
00477     const Select<Derived,ThenDerived,ElseDerived>
00478     select(const DenseBase<ThenDerived>& thenMatrix,
00479            const DenseBase<ElseDerived>& elseMatrix) const;
00480 
00481     template<typename ThenDerived>
00482     inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
00483     select(const DenseBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const;
00484 
00485     template<typename ElseDerived>
00486     inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
00487     select(typename ElseDerived::Scalar thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
00488 
00489     template<int p> RealScalar lpNorm() const;
00490 
00491     template<int RowFactor, int ColFactor>
00492     const Replicate<Derived,RowFactor,ColFactor> replicate() const;
00493     const Replicate<Derived,Dynamic,Dynamic> replicate(Index rowFacor,Index colFactor) const;
00494 
00495     typedef Reverse<Derived, BothDirections> ReverseReturnType;
00496     typedef const Reverse<const Derived, BothDirections> ConstReverseReturnType;
00497     ReverseReturnType reverse();
00498     ConstReverseReturnType reverse() const;
00499     void reverseInPlace();
00500 
00501 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::DenseBase
00502 #   include "../plugins/BlockMethods.h"
00503 #   ifdef EIGEN_DENSEBASE_PLUGIN
00504 #     include EIGEN_DENSEBASE_PLUGIN
00505 #   endif
00506 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS
00507 
00508 #ifdef EIGEN2_SUPPORT
00509 
00510     Block<Derived> corner(CornerType type, Index cRows, Index cCols);
00511     const Block<Derived> corner(CornerType type, Index cRows, Index cCols) const;
00512     template<int CRows, int CCols>
00513     Block<Derived, CRows, CCols> corner(CornerType type);
00514     template<int CRows, int CCols>
00515     const Block<Derived, CRows, CCols> corner(CornerType type) const;
00516 
00517 #endif // EIGEN2_SUPPORT
00518 
00519 
00520     // disable the use of evalTo for dense objects with a nice compilation error
00521     template<typename Dest> inline void evalTo(Dest& ) const
00522     {
00523       EIGEN_STATIC_ASSERT((internal::is_same<Dest,void>::value),THE_EVAL_EVALTO_FUNCTION_SHOULD_NEVER_BE_CALLED_FOR_DENSE_OBJECTS);
00524     }
00525 
00526   protected:
00528     DenseBase()
00529     {
00530       /* Just checks for self-consistency of the flags.
00531        * Only do it when debugging Eigen, as this borders on paranoiac and could slow compilation down
00532        */
00533 #ifdef EIGEN_INTERNAL_DEBUGGING
00534       EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, int(IsRowMajor))
00535                         && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, int(!IsRowMajor))),
00536                           INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION)
00537 #endif
00538     }
00539 
00540   private:
00541     explicit DenseBase(int);
00542     DenseBase(int,int);
00543     template<typename OtherDerived> explicit DenseBase(const DenseBase<OtherDerived>&);
00544 };
00545 
00546 } // end namespace Eigen
00547 
00548 #endif // EIGEN_DENSEBASE_H