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