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