Home | History | Annotate | Download | only in Core
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1 (at) gmail.com>
      5 // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      6 //
      7 // This Source Code Form is subject to the terms of the Mozilla
      8 // Public License v. 2.0. If a copy of the MPL was not distributed
      9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     10 
     11 #ifndef EIGEN_DENSEBASE_H
     12 #define EIGEN_DENSEBASE_H
     13 
     14 namespace Eigen {
     15 
     16 namespace internal {
     17 
     18 // The index type defined by EIGEN_DEFAULT_DENSE_INDEX_TYPE must be a signed type.
     19 // This dummy function simply aims at checking that at compile time.
     20 static inline void check_DenseIndex_is_signed() {
     21   EIGEN_STATIC_ASSERT(NumTraits<DenseIndex>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
     22 }
     23 
     24 } // end namespace internal
     25 
     26 /** \class DenseBase
     27   * \ingroup Core_Module
     28   *
     29   * \brief Base class for all dense matrices, vectors, and arrays
     30   *
     31   * This class is the base that is inherited by all dense objects (matrix, vector, arrays,
     32   * and related expression types). The common Eigen API for dense objects is contained in this class.
     33   *
     34   * \tparam Derived is the derived type, e.g., a matrix type or an expression.
     35   *
     36   * This class can be extended with the help of the plugin mechanism described on the page
     37   * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_DENSEBASE_PLUGIN.
     38   *
     39   * \sa \ref TopicClassHierarchy
     40   */
     41 template<typename Derived> class DenseBase
     42 #ifndef EIGEN_PARSED_BY_DOXYGEN
     43   : public internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
     44                                      typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>
     45 #else
     46   : public DenseCoeffsBase<Derived>
     47 #endif // not EIGEN_PARSED_BY_DOXYGEN
     48 {
     49   public:
     50     using internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
     51                 typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>::operator*;
     52 
     53     class InnerIterator;
     54 
     55     typedef typename internal::traits<Derived>::StorageKind StorageKind;
     56 
     57     /** \brief The type of indices
     58       * \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
     59       * \sa \ref TopicPreprocessorDirectives.
     60       */
     61     typedef typename internal::traits<Derived>::Index Index;
     62 
     63     typedef typename internal::traits<Derived>::Scalar Scalar;
     64     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
     65     typedef typename NumTraits<Scalar>::Real RealScalar;
     66 
     67     typedef DenseCoeffsBase<Derived> Base;
     68     using Base::derived;
     69     using Base::const_cast_derived;
     70     using Base::rows;
     71     using Base::cols;
     72     using Base::size;
     73     using Base::rowIndexByOuterInner;
     74     using Base::colIndexByOuterInner;
     75     using Base::coeff;
     76     using Base::coeffByOuterInner;
     77     using Base::packet;
     78     using Base::packetByOuterInner;
     79     using Base::writePacket;
     80     using Base::writePacketByOuterInner;
     81     using Base::coeffRef;
     82     using Base::coeffRefByOuterInner;
     83     using Base::copyCoeff;
     84     using Base::copyCoeffByOuterInner;
     85     using Base::copyPacket;
     86     using Base::copyPacketByOuterInner;
     87     using Base::operator();
     88     using Base::operator[];
     89     using Base::x;
     90     using Base::y;
     91     using Base::z;
     92     using Base::w;
     93     using Base::stride;
     94     using Base::innerStride;
     95     using Base::outerStride;
     96     using Base::rowStride;
     97     using Base::colStride;
     98     typedef typename Base::CoeffReturnType CoeffReturnType;
     99 
    100     enum {
    101 
    102       RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
    103         /**< The number of rows at compile-time. This is just a copy of the value provided
    104           * by the \a Derived type. If a value is not known at compile-time,
    105           * it is set to the \a Dynamic constant.
    106           * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */
    107 
    108       ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
    109         /**< The number of columns at compile-time. This is just a copy of the value provided
    110           * by the \a Derived type. If a value is not known at compile-time,
    111           * it is set to the \a Dynamic constant.
    112           * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */
    113 
    114 
    115       SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
    116                                                    internal::traits<Derived>::ColsAtCompileTime>::ret),
    117         /**< This is equal to the number of coefficients, i.e. the number of
    118           * rows times the number of columns, or to \a Dynamic if this is not
    119           * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */
    120 
    121       MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
    122         /**< This value is equal to the maximum possible number of rows that this expression
    123           * might have. If this expression might have an arbitrarily high number of rows,
    124           * this value is set to \a Dynamic.
    125           *
    126           * This value is useful to know when evaluating an expression, in order to determine
    127           * whether it is possible to avoid doing a dynamic memory allocation.
    128           *
    129           * \sa RowsAtCompileTime, MaxColsAtCompileTime, MaxSizeAtCompileTime
    130           */
    131 
    132       MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime,
    133         /**< This value is equal to the maximum possible number of columns that this expression
    134           * might have. If this expression might have an arbitrarily high number of columns,
    135           * this value is set to \a Dynamic.
    136           *
    137           * This value is useful to know when evaluating an expression, in order to determine
    138           * whether it is possible to avoid doing a dynamic memory allocation.
    139           *
    140           * \sa ColsAtCompileTime, MaxRowsAtCompileTime, MaxSizeAtCompileTime
    141           */
    142 
    143       MaxSizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::MaxRowsAtCompileTime,
    144                                                       internal::traits<Derived>::MaxColsAtCompileTime>::ret),
    145         /**< This value is equal to the maximum possible number of coefficients that this expression
    146           * might have. If this expression might have an arbitrarily high number of coefficients,
    147           * this value is set to \a Dynamic.
    148           *
    149           * This value is useful to know when evaluating an expression, in order to determine
    150           * whether it is possible to avoid doing a dynamic memory allocation.
    151           *
    152           * \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime
    153           */
    154 
    155       IsVectorAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime == 1
    156                            || internal::traits<Derived>::MaxColsAtCompileTime == 1,
    157         /**< This is set to true if either the number of rows or the number of
    158           * columns is known at compile-time to be equal to 1. Indeed, in that case,
    159           * we are dealing with a column-vector (if there is only one column) or with
    160           * a row-vector (if there is only one row). */
    161 
    162       Flags = internal::traits<Derived>::Flags,
    163         /**< This stores expression \ref flags flags which may or may not be inherited by new expressions
    164           * constructed from this one. See the \ref flags "list of flags".
    165           */
    166 
    167       IsRowMajor = int(Flags) & RowMajorBit, /**< True if this expression has row-major storage order. */
    168 
    169       InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
    170                              : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
    171 
    172       CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
    173         /**< This is a rough measure of how expensive it is to read one coefficient from
    174           * this expression.
    175           */
    176 
    177       InnerStrideAtCompileTime = internal::inner_stride_at_compile_time<Derived>::ret,
    178       OuterStrideAtCompileTime = internal::outer_stride_at_compile_time<Derived>::ret
    179     };
    180 
    181     enum { ThisConstantIsPrivateInPlainObjectBase };
    182 
    183     /** \returns the number of nonzero coefficients which is in practice the number
    184       * of stored coefficients. */
    185     inline Index nonZeros() const { return size(); }
    186     /** \returns true if either the number of rows or the number of columns is equal to 1.
    187       * In other words, this function returns
    188       * \code rows()==1 || cols()==1 \endcode
    189       * \sa rows(), cols(), IsVectorAtCompileTime. */
    190 
    191     /** \returns the outer size.
    192       *
    193       * \note For a vector, this returns just 1. For a matrix (non-vector), this is the major dimension
    194       * with respect to the \ref TopicStorageOrders "storage order", i.e., the number of columns for a
    195       * column-major matrix, and the number of rows for a row-major matrix. */
    196     Index outerSize() const
    197     {
    198       return IsVectorAtCompileTime ? 1
    199            : int(IsRowMajor) ? this->rows() : this->cols();
    200     }
    201 
    202     /** \returns the inner size.
    203       *
    204       * \note For a vector, this is just the size. For a matrix (non-vector), this is the minor dimension
    205       * with respect to the \ref TopicStorageOrders "storage order", i.e., the number of rows for a
    206       * column-major matrix, and the number of columns for a row-major matrix. */
    207     Index innerSize() const
    208     {
    209       return IsVectorAtCompileTime ? this->size()
    210            : int(IsRowMajor) ? this->cols() : this->rows();
    211     }
    212 
    213     /** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are
    214       * Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does
    215       * nothing else.
    216       */
    217     void resize(Index newSize)
    218     {
    219       EIGEN_ONLY_USED_FOR_DEBUG(newSize);
    220       eigen_assert(newSize == this->size()
    221                 && "DenseBase::resize() does not actually allow to resize.");
    222     }
    223     /** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are
    224       * Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does
    225       * nothing else.
    226       */
    227     void resize(Index nbRows, Index nbCols)
    228     {
    229       EIGEN_ONLY_USED_FOR_DEBUG(nbRows);
    230       EIGEN_ONLY_USED_FOR_DEBUG(nbCols);
    231       eigen_assert(nbRows == this->rows() && nbCols == this->cols()
    232                 && "DenseBase::resize() does not actually allow to resize.");
    233     }
    234 
    235 #ifndef EIGEN_PARSED_BY_DOXYGEN
    236 
    237     /** \internal Represents a matrix with all coefficients equal to one another*/
    238     typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Derived> ConstantReturnType;
    239     /** \internal Represents a vector with linearly spaced coefficients that allows sequential access only. */
    240     typedef CwiseNullaryOp<internal::linspaced_op<Scalar,false>,Derived> SequentialLinSpacedReturnType;
    241     /** \internal Represents a vector with linearly spaced coefficients that allows random access. */
    242     typedef CwiseNullaryOp<internal::linspaced_op<Scalar,true>,Derived> RandomAccessLinSpacedReturnType;
    243     /** \internal the return type of MatrixBase::eigenvalues() */
    244     typedef Matrix<typename NumTraits<typename internal::traits<Derived>::Scalar>::Real, internal::traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
    245 
    246 #endif // not EIGEN_PARSED_BY_DOXYGEN
    247 
    248     /** Copies \a other into *this. \returns a reference to *this. */
    249     template<typename OtherDerived>
    250     Derived& operator=(const DenseBase<OtherDerived>& other);
    251 
    252     /** Special case of the template operator=, in order to prevent the compiler
    253       * from generating a default operator= (issue hit with g++ 4.1)
    254       */
    255     Derived& operator=(const DenseBase& other);
    256 
    257     template<typename OtherDerived>
    258     Derived& operator=(const EigenBase<OtherDerived> &other);
    259 
    260     template<typename OtherDerived>
    261     Derived& operator+=(const EigenBase<OtherDerived> &other);
    262 
    263     template<typename OtherDerived>
    264     Derived& operator-=(const EigenBase<OtherDerived> &other);
    265 
    266     template<typename OtherDerived>
    267     Derived& operator=(const ReturnByValue<OtherDerived>& func);
    268 
    269 #ifndef EIGEN_PARSED_BY_DOXYGEN
    270     /** Copies \a other into *this without evaluating other. \returns a reference to *this. */
    271     template<typename OtherDerived>
    272     Derived& lazyAssign(const DenseBase<OtherDerived>& other);
    273 #endif // not EIGEN_PARSED_BY_DOXYGEN
    274 
    275     CommaInitializer<Derived> operator<< (const Scalar& s);
    276 
    277     template<unsigned int Added,unsigned int Removed>
    278     const Flagged<Derived, Added, Removed> flagged() const;
    279 
    280     template<typename OtherDerived>
    281     CommaInitializer<Derived> operator<< (const DenseBase<OtherDerived>& other);
    282 
    283     Eigen::Transpose<Derived> transpose();
    284 	typedef typename internal::add_const<Transpose<const Derived> >::type ConstTransposeReturnType;
    285     ConstTransposeReturnType transpose() const;
    286     void transposeInPlace();
    287 #ifndef EIGEN_NO_DEBUG
    288   protected:
    289     template<typename OtherDerived>
    290     void checkTransposeAliasing(const OtherDerived& other) const;
    291   public:
    292 #endif
    293 
    294 
    295     static const ConstantReturnType
    296     Constant(Index rows, Index cols, const Scalar& value);
    297     static const ConstantReturnType
    298     Constant(Index size, const Scalar& value);
    299     static const ConstantReturnType
    300     Constant(const Scalar& value);
    301 
    302     static const SequentialLinSpacedReturnType
    303     LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high);
    304     static const RandomAccessLinSpacedReturnType
    305     LinSpaced(Index size, const Scalar& low, const Scalar& high);
    306     static const SequentialLinSpacedReturnType
    307     LinSpaced(Sequential_t, const Scalar& low, const Scalar& high);
    308     static const RandomAccessLinSpacedReturnType
    309     LinSpaced(const Scalar& low, const Scalar& high);
    310 
    311     template<typename CustomNullaryOp>
    312     static const CwiseNullaryOp<CustomNullaryOp, Derived>
    313     NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func);
    314     template<typename CustomNullaryOp>
    315     static const CwiseNullaryOp<CustomNullaryOp, Derived>
    316     NullaryExpr(Index size, const CustomNullaryOp& func);
    317     template<typename CustomNullaryOp>
    318     static const CwiseNullaryOp<CustomNullaryOp, Derived>
    319     NullaryExpr(const CustomNullaryOp& func);
    320 
    321     static const ConstantReturnType Zero(Index rows, Index cols);
    322     static const ConstantReturnType Zero(Index size);
    323     static const ConstantReturnType Zero();
    324     static const ConstantReturnType Ones(Index rows, Index cols);
    325     static const ConstantReturnType Ones(Index size);
    326     static const ConstantReturnType Ones();
    327 
    328     void fill(const Scalar& value);
    329     Derived& setConstant(const Scalar& value);
    330     Derived& setLinSpaced(Index size, const Scalar& low, const Scalar& high);
    331     Derived& setLinSpaced(const Scalar& low, const Scalar& high);
    332     Derived& setZero();
    333     Derived& setOnes();
    334     Derived& setRandom();
    335 
    336     template<typename OtherDerived>
    337     bool isApprox(const DenseBase<OtherDerived>& other,
    338                   const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
    339     bool isMuchSmallerThan(const RealScalar& other,
    340                            const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
    341     template<typename OtherDerived>
    342     bool isMuchSmallerThan(const DenseBase<OtherDerived>& other,
    343                            const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
    344 
    345     bool isApproxToConstant(const Scalar& value, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
    346     bool isConstant(const Scalar& value, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
    347     bool isZero(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
    348     bool isOnes(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const;
    349 
    350     inline bool hasNaN() const;
    351     inline bool allFinite() const;
    352 
    353     inline Derived& operator*=(const Scalar& other);
    354     inline Derived& operator/=(const Scalar& other);
    355 
    356     typedef typename internal::add_const_on_value_type<typename internal::eval<Derived>::type>::type EvalReturnType;
    357     /** \returns the matrix or vector obtained by evaluating this expression.
    358       *
    359       * Notice that in the case of a plain matrix or vector (not an expression) this function just returns
    360       * a const reference, in order to avoid a useless copy.
    361       */
    362     EIGEN_STRONG_INLINE EvalReturnType eval() const
    363     {
    364       // Even though MSVC does not honor strong inlining when the return type
    365       // is a dynamic matrix, we desperately need strong inlining for fixed
    366       // size types on MSVC.
    367       return typename internal::eval<Derived>::type(derived());
    368     }
    369 
    370     /** swaps *this with the expression \a other.
    371       *
    372       */
    373     template<typename OtherDerived>
    374     void swap(const DenseBase<OtherDerived>& other,
    375               int = OtherDerived::ThisConstantIsPrivateInPlainObjectBase)
    376     {
    377       SwapWrapper<Derived>(derived()).lazyAssign(other.derived());
    378     }
    379 
    380     /** swaps *this with the matrix or array \a other.
    381       *
    382       */
    383     template<typename OtherDerived>
    384     void swap(PlainObjectBase<OtherDerived>& other)
    385     {
    386       SwapWrapper<Derived>(derived()).lazyAssign(other.derived());
    387     }
    388 
    389 
    390     inline const NestByValue<Derived> nestByValue() const;
    391     inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
    392     inline ForceAlignedAccess<Derived> forceAlignedAccess();
    393     template<bool Enable> inline const typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf() const;
    394     template<bool Enable> inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf();
    395 
    396     Scalar sum() const;
    397     Scalar mean() const;
    398     Scalar trace() const;
    399 
    400     Scalar prod() const;
    401 
    402     typename internal::traits<Derived>::Scalar minCoeff() const;
    403     typename internal::traits<Derived>::Scalar maxCoeff() const;
    404 
    405     template<typename IndexType>
    406     typename internal::traits<Derived>::Scalar minCoeff(IndexType* row, IndexType* col) const;
    407     template<typename IndexType>
    408     typename internal::traits<Derived>::Scalar maxCoeff(IndexType* row, IndexType* col) const;
    409     template<typename IndexType>
    410     typename internal::traits<Derived>::Scalar minCoeff(IndexType* index) const;
    411     template<typename IndexType>
    412     typename internal::traits<Derived>::Scalar maxCoeff(IndexType* index) const;
    413 
    414     template<typename BinaryOp>
    415     typename internal::result_of<BinaryOp(typename internal::traits<Derived>::Scalar)>::type
    416     redux(const BinaryOp& func) const;
    417 
    418     template<typename Visitor>
    419     void visit(Visitor& func) const;
    420 
    421     inline const WithFormat<Derived> format(const IOFormat& fmt) const;
    422 
    423     /** \returns the unique coefficient of a 1x1 expression */
    424     CoeffReturnType value() const
    425     {
    426       EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
    427       eigen_assert(this->rows() == 1 && this->cols() == 1);
    428       return derived().coeff(0,0);
    429     }
    430 
    431     bool all(void) const;
    432     bool any(void) const;
    433     Index count() const;
    434 
    435     typedef VectorwiseOp<Derived, Horizontal> RowwiseReturnType;
    436     typedef const VectorwiseOp<const Derived, Horizontal> ConstRowwiseReturnType;
    437     typedef VectorwiseOp<Derived, Vertical> ColwiseReturnType;
    438     typedef const VectorwiseOp<const Derived, Vertical> ConstColwiseReturnType;
    439 
    440     ConstRowwiseReturnType rowwise() const;
    441     RowwiseReturnType rowwise();
    442     ConstColwiseReturnType colwise() const;
    443     ColwiseReturnType colwise();
    444 
    445     static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(Index rows, Index cols);
    446     static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(Index size);
    447     static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random();
    448 
    449     template<typename ThenDerived,typename ElseDerived>
    450     const Select<Derived,ThenDerived,ElseDerived>
    451     select(const DenseBase<ThenDerived>& thenMatrix,
    452            const DenseBase<ElseDerived>& elseMatrix) const;
    453 
    454     template<typename ThenDerived>
    455     inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
    456     select(const DenseBase<ThenDerived>& thenMatrix, const typename ThenDerived::Scalar& elseScalar) const;
    457 
    458     template<typename ElseDerived>
    459     inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
    460     select(const typename ElseDerived::Scalar& thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
    461 
    462     template<int p> RealScalar lpNorm() const;
    463 
    464     template<int RowFactor, int ColFactor>
    465     const Replicate<Derived,RowFactor,ColFactor> replicate() const;
    466     const Replicate<Derived,Dynamic,Dynamic> replicate(Index rowFacor,Index colFactor) const;
    467 
    468     typedef Reverse<Derived, BothDirections> ReverseReturnType;
    469     typedef const Reverse<const Derived, BothDirections> ConstReverseReturnType;
    470     ReverseReturnType reverse();
    471     ConstReverseReturnType reverse() const;
    472     void reverseInPlace();
    473 
    474 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::DenseBase
    475 #   include "../plugins/BlockMethods.h"
    476 #   ifdef EIGEN_DENSEBASE_PLUGIN
    477 #     include EIGEN_DENSEBASE_PLUGIN
    478 #   endif
    479 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS
    480 
    481 #ifdef EIGEN2_SUPPORT
    482 
    483     Block<Derived> corner(CornerType type, Index cRows, Index cCols);
    484     const Block<Derived> corner(CornerType type, Index cRows, Index cCols) const;
    485     template<int CRows, int CCols>
    486     Block<Derived, CRows, CCols> corner(CornerType type);
    487     template<int CRows, int CCols>
    488     const Block<Derived, CRows, CCols> corner(CornerType type) const;
    489 
    490 #endif // EIGEN2_SUPPORT
    491 
    492 
    493     // disable the use of evalTo for dense objects with a nice compilation error
    494     template<typename Dest> inline void evalTo(Dest& ) const
    495     {
    496       EIGEN_STATIC_ASSERT((internal::is_same<Dest,void>::value),THE_EVAL_EVALTO_FUNCTION_SHOULD_NEVER_BE_CALLED_FOR_DENSE_OBJECTS);
    497     }
    498 
    499   protected:
    500     /** Default constructor. Do nothing. */
    501     DenseBase()
    502     {
    503       /* Just checks for self-consistency of the flags.
    504        * Only do it when debugging Eigen, as this borders on paranoiac and could slow compilation down
    505        */
    506 #ifdef EIGEN_INTERNAL_DEBUGGING
    507       EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, int(IsRowMajor))
    508                         && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, int(!IsRowMajor))),
    509                           INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION)
    510 #endif
    511     }
    512 
    513   private:
    514     explicit DenseBase(int);
    515     DenseBase(int,int);
    516     template<typename OtherDerived> explicit DenseBase(const DenseBase<OtherDerived>&);
    517 };
    518 
    519 } // end namespace Eigen
    520 
    521 #endif // EIGEN_DENSEBASE_H
    522