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 14namespace Eigen { 15 16namespace 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. 20static 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 */ 41template<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 /** \internal Copies \a other into *this without evaluating other. \returns a reference to *this. */ 270 template<typename OtherDerived> 271 Derived& lazyAssign(const DenseBase<OtherDerived>& other); 272 273 /** \internal Evaluates \a other into *this. \returns a reference to *this. */ 274 template<typename OtherDerived> 275 Derived& lazyAssign(const ReturnByValue<OtherDerived>& other); 276 277 CommaInitializer<Derived> operator<< (const Scalar& s); 278 279 template<unsigned int Added,unsigned int Removed> 280 const Flagged<Derived, Added, Removed> flagged() const; 281 282 template<typename OtherDerived> 283 CommaInitializer<Derived> operator<< (const DenseBase<OtherDerived>& other); 284 285 Eigen::Transpose<Derived> transpose(); 286 typedef typename internal::add_const<Transpose<const Derived> >::type ConstTransposeReturnType; 287 ConstTransposeReturnType transpose() const; 288 void transposeInPlace(); 289#ifndef EIGEN_NO_DEBUG 290 protected: 291 template<typename OtherDerived> 292 void checkTransposeAliasing(const OtherDerived& other) const; 293 public: 294#endif 295 296 297 static const ConstantReturnType 298 Constant(Index rows, Index cols, const Scalar& value); 299 static const ConstantReturnType 300 Constant(Index size, const Scalar& value); 301 static const ConstantReturnType 302 Constant(const Scalar& value); 303 304 static const SequentialLinSpacedReturnType 305 LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high); 306 static const RandomAccessLinSpacedReturnType 307 LinSpaced(Index size, const Scalar& low, const Scalar& high); 308 static const SequentialLinSpacedReturnType 309 LinSpaced(Sequential_t, const Scalar& low, const Scalar& high); 310 static const RandomAccessLinSpacedReturnType 311 LinSpaced(const Scalar& low, const Scalar& high); 312 313 template<typename CustomNullaryOp> 314 static const CwiseNullaryOp<CustomNullaryOp, Derived> 315 NullaryExpr(Index rows, Index cols, const CustomNullaryOp& func); 316 template<typename CustomNullaryOp> 317 static const CwiseNullaryOp<CustomNullaryOp, Derived> 318 NullaryExpr(Index size, const CustomNullaryOp& func); 319 template<typename CustomNullaryOp> 320 static const CwiseNullaryOp<CustomNullaryOp, Derived> 321 NullaryExpr(const CustomNullaryOp& func); 322 323 static const ConstantReturnType Zero(Index rows, Index cols); 324 static const ConstantReturnType Zero(Index size); 325 static const ConstantReturnType Zero(); 326 static const ConstantReturnType Ones(Index rows, Index cols); 327 static const ConstantReturnType Ones(Index size); 328 static const ConstantReturnType Ones(); 329 330 void fill(const Scalar& value); 331 Derived& setConstant(const Scalar& value); 332 Derived& setLinSpaced(Index size, const Scalar& low, const Scalar& high); 333 Derived& setLinSpaced(const Scalar& low, const Scalar& high); 334 Derived& setZero(); 335 Derived& setOnes(); 336 Derived& setRandom(); 337 338 template<typename OtherDerived> 339 bool isApprox(const DenseBase<OtherDerived>& other, 340 const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const; 341 bool isMuchSmallerThan(const RealScalar& other, 342 const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const; 343 template<typename OtherDerived> 344 bool isMuchSmallerThan(const DenseBase<OtherDerived>& other, 345 const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const; 346 347 bool isApproxToConstant(const Scalar& value, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const; 348 bool isConstant(const Scalar& value, const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const; 349 bool isZero(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const; 350 bool isOnes(const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const; 351 352 inline bool hasNaN() const; 353 inline bool allFinite() const; 354 355 inline Derived& operator*=(const Scalar& other); 356 inline Derived& operator/=(const Scalar& other); 357 358 typedef typename internal::add_const_on_value_type<typename internal::eval<Derived>::type>::type EvalReturnType; 359 /** \returns the matrix or vector obtained by evaluating this expression. 360 * 361 * Notice that in the case of a plain matrix or vector (not an expression) this function just returns 362 * a const reference, in order to avoid a useless copy. 363 */ 364 EIGEN_STRONG_INLINE EvalReturnType eval() const 365 { 366 // Even though MSVC does not honor strong inlining when the return type 367 // is a dynamic matrix, we desperately need strong inlining for fixed 368 // size types on MSVC. 369 return typename internal::eval<Derived>::type(derived()); 370 } 371 372 /** swaps *this with the expression \a other. 373 * 374 */ 375 template<typename OtherDerived> 376 void swap(const DenseBase<OtherDerived>& other, 377 int = OtherDerived::ThisConstantIsPrivateInPlainObjectBase) 378 { 379 SwapWrapper<Derived>(derived()).lazyAssign(other.derived()); 380 } 381 382 /** swaps *this with the matrix or array \a other. 383 * 384 */ 385 template<typename OtherDerived> 386 void swap(PlainObjectBase<OtherDerived>& other) 387 { 388 SwapWrapper<Derived>(derived()).lazyAssign(other.derived()); 389 } 390 391 392 inline const NestByValue<Derived> nestByValue() const; 393 inline const ForceAlignedAccess<Derived> forceAlignedAccess() const; 394 inline ForceAlignedAccess<Derived> forceAlignedAccess(); 395 template<bool Enable> inline const typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf() const; 396 template<bool Enable> inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf(); 397 398 Scalar sum() const; 399 Scalar mean() const; 400 Scalar trace() const; 401 402 Scalar prod() const; 403 404 typename internal::traits<Derived>::Scalar minCoeff() const; 405 typename internal::traits<Derived>::Scalar maxCoeff() const; 406 407 template<typename IndexType> 408 typename internal::traits<Derived>::Scalar minCoeff(IndexType* row, IndexType* col) const; 409 template<typename IndexType> 410 typename internal::traits<Derived>::Scalar maxCoeff(IndexType* row, IndexType* col) const; 411 template<typename IndexType> 412 typename internal::traits<Derived>::Scalar minCoeff(IndexType* index) const; 413 template<typename IndexType> 414 typename internal::traits<Derived>::Scalar maxCoeff(IndexType* index) const; 415 416 template<typename BinaryOp> 417 typename internal::result_of<BinaryOp(typename internal::traits<Derived>::Scalar)>::type 418 redux(const BinaryOp& func) const; 419 420 template<typename Visitor> 421 void visit(Visitor& func) const; 422 423 inline const WithFormat<Derived> format(const IOFormat& fmt) const; 424 425 /** \returns the unique coefficient of a 1x1 expression */ 426 CoeffReturnType value() const 427 { 428 EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) 429 eigen_assert(this->rows() == 1 && this->cols() == 1); 430 return derived().coeff(0,0); 431 } 432 433 bool all(void) const; 434 bool any(void) const; 435 Index count() const; 436 437 typedef VectorwiseOp<Derived, Horizontal> RowwiseReturnType; 438 typedef const VectorwiseOp<const Derived, Horizontal> ConstRowwiseReturnType; 439 typedef VectorwiseOp<Derived, Vertical> ColwiseReturnType; 440 typedef const VectorwiseOp<const Derived, Vertical> ConstColwiseReturnType; 441 442 ConstRowwiseReturnType rowwise() const; 443 RowwiseReturnType rowwise(); 444 ConstColwiseReturnType colwise() const; 445 ColwiseReturnType colwise(); 446 447 static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(Index rows, Index cols); 448 static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(Index size); 449 static const CwiseNullaryOp<internal::scalar_random_op<Scalar>,Derived> Random(); 450 451 template<typename ThenDerived,typename ElseDerived> 452 const Select<Derived,ThenDerived,ElseDerived> 453 select(const DenseBase<ThenDerived>& thenMatrix, 454 const DenseBase<ElseDerived>& elseMatrix) const; 455 456 template<typename ThenDerived> 457 inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType> 458 select(const DenseBase<ThenDerived>& thenMatrix, const typename ThenDerived::Scalar& elseScalar) const; 459 460 template<typename ElseDerived> 461 inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived > 462 select(const typename ElseDerived::Scalar& thenScalar, const DenseBase<ElseDerived>& elseMatrix) const; 463 464 template<int p> RealScalar lpNorm() const; 465 466 template<int RowFactor, int ColFactor> 467 inline const Replicate<Derived,RowFactor,ColFactor> replicate() const; 468 469 typedef Replicate<Derived,Dynamic,Dynamic> ReplicateReturnType; 470 inline const ReplicateReturnType replicate(Index rowFacor,Index colFactor) const; 471 472 typedef Reverse<Derived, BothDirections> ReverseReturnType; 473 typedef const Reverse<const Derived, BothDirections> ConstReverseReturnType; 474 ReverseReturnType reverse(); 475 ConstReverseReturnType reverse() const; 476 void reverseInPlace(); 477 478#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::DenseBase 479# include "../plugins/BlockMethods.h" 480# ifdef EIGEN_DENSEBASE_PLUGIN 481# include EIGEN_DENSEBASE_PLUGIN 482# endif 483#undef EIGEN_CURRENT_STORAGE_BASE_CLASS 484 485#ifdef EIGEN2_SUPPORT 486 487 Block<Derived> corner(CornerType type, Index cRows, Index cCols); 488 const Block<Derived> corner(CornerType type, Index cRows, Index cCols) const; 489 template<int CRows, int CCols> 490 Block<Derived, CRows, CCols> corner(CornerType type); 491 template<int CRows, int CCols> 492 const Block<Derived, CRows, CCols> corner(CornerType type) const; 493 494#endif // EIGEN2_SUPPORT 495 496 497 // disable the use of evalTo for dense objects with a nice compilation error 498 template<typename Dest> inline void evalTo(Dest& ) const 499 { 500 EIGEN_STATIC_ASSERT((internal::is_same<Dest,void>::value),THE_EVAL_EVALTO_FUNCTION_SHOULD_NEVER_BE_CALLED_FOR_DENSE_OBJECTS); 501 } 502 503 protected: 504 /** Default constructor. Do nothing. */ 505 DenseBase() 506 { 507 /* Just checks for self-consistency of the flags. 508 * Only do it when debugging Eigen, as this borders on paranoiac and could slow compilation down 509 */ 510#ifdef EIGEN_INTERNAL_DEBUGGING 511 EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, int(IsRowMajor)) 512 && EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, int(!IsRowMajor))), 513 INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION) 514#endif 515 } 516 517 private: 518 explicit DenseBase(int); 519 DenseBase(int,int); 520 template<typename OtherDerived> explicit DenseBase(const DenseBase<OtherDerived>&); 521}; 522 523} // end namespace Eigen 524 525#endif // EIGEN_DENSEBASE_H 526