MatrixBase.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
5 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
6 //
7 // Eigen is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 3 of the License, or (at your option) any later version.
11 //
12 // Alternatively, you can redistribute it and/or
13 // modify it under the terms of the GNU General Public License as
14 // published by the Free Software Foundation; either version 2 of
15 // the License, or (at your option) any later version.
16 //
17 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License and a copy of the GNU General Public License along with
24 // Eigen. If not, see <http://www.gnu.org/licenses/>.
25 
26 #ifndef EIGEN_MATRIXBASE_H
27 #define EIGEN_MATRIXBASE_H
28 
29 namespace Eigen {
30 
63 template<typename Derived> class MatrixBase
64  : public DenseBase<Derived>
65 {
66  public:
67 #ifndef EIGEN_PARSED_BY_DOXYGEN
68  typedef MatrixBase StorageBaseType;
69  typedef typename internal::traits<Derived>::StorageKind StorageKind;
70  typedef typename internal::traits<Derived>::Index Index;
71  typedef typename internal::traits<Derived>::Scalar Scalar;
72  typedef typename internal::packet_traits<Scalar>::type PacketScalar;
73  typedef typename NumTraits<Scalar>::Real RealScalar;
74 
75  typedef DenseBase<Derived> Base;
83  using Base::Flags;
84  using Base::CoeffReadCost;
85 
86  using Base::derived;
87  using Base::const_cast_derived;
88  using Base::rows;
89  using Base::cols;
90  using Base::size;
91  using Base::coeff;
92  using Base::coeffRef;
93  using Base::lazyAssign;
94  using Base::eval;
95  using Base::operator+=;
96  using Base::operator-=;
97  using Base::operator*=;
98  using Base::operator/=;
99 
100  typedef typename Base::CoeffReturnType CoeffReturnType;
101  typedef typename Base::ConstTransposeReturnType ConstTransposeReturnType;
102  typedef typename Base::RowXpr RowXpr;
103  typedef typename Base::ColXpr ColXpr;
104 #endif // not EIGEN_PARSED_BY_DOXYGEN
105 
106 
107 
108 #ifndef EIGEN_PARSED_BY_DOXYGEN
109 
112 #endif // not EIGEN_PARSED_BY_DOXYGEN
113 
116  inline Index diagonalSize() const { return (std::min)(rows(),cols()); }
125  internal::traits<Derived>::RowsAtCompileTime,
126  internal::traits<Derived>::ColsAtCompileTime,
127  AutoAlign | (internal::traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor),
128  internal::traits<Derived>::MaxRowsAtCompileTime,
129  internal::traits<Derived>::MaxColsAtCompileTime
131 
132 #ifndef EIGEN_PARSED_BY_DOXYGEN
133 
134  typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,Derived> ConstantReturnType;
139  >::type AdjointReturnType;
141  typedef Matrix<std::complex<RealScalar>, internal::traits<Derived>::ColsAtCompileTime, 1, ColMajor> EigenvaluesReturnType;
143  typedef CwiseNullaryOp<internal::scalar_identity_op<Scalar>,Derived> IdentityReturnType;
146  internal::traits<Derived>::RowsAtCompileTime,
147  internal::traits<Derived>::ColsAtCompileTime> BasisReturnType;
148 #endif // not EIGEN_PARSED_BY_DOXYGEN
149 
150 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::MatrixBase
151 # include "../plugins/CommonCwiseUnaryOps.h"
152 # include "../plugins/CommonCwiseBinaryOps.h"
153 # include "../plugins/MatrixCwiseUnaryOps.h"
154 # include "../plugins/MatrixCwiseBinaryOps.h"
155 # ifdef EIGEN_MATRIXBASE_PLUGIN
156 # include EIGEN_MATRIXBASE_PLUGIN
157 # endif
158 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS
159 
163  Derived& operator=(const MatrixBase& other);
164 
165  // We cannot inherit here via Base::operator= since it is causing
166  // trouble with MSVC.
167 
168  template <typename OtherDerived>
169  Derived& operator=(const DenseBase<OtherDerived>& other);
170 
171  template <typename OtherDerived>
172  Derived& operator=(const EigenBase<OtherDerived>& other);
174  template<typename OtherDerived>
175  Derived& operator=(const ReturnByValue<OtherDerived>& other);
176 
177 #ifndef EIGEN_PARSED_BY_DOXYGEN
178  template<typename ProductDerived, typename Lhs, typename Rhs>
179  Derived& lazyAssign(const ProductBase<ProductDerived, Lhs,Rhs>& other);
180 #endif // not EIGEN_PARSED_BY_DOXYGEN
181 
182  template<typename OtherDerived>
183  Derived& operator+=(const MatrixBase<OtherDerived>& other);
184  template<typename OtherDerived>
185  Derived& operator-=(const MatrixBase<OtherDerived>& other);
186 
187  template<typename OtherDerived>
189  operator*(const MatrixBase<OtherDerived> &other) const;
190 
191  template<typename OtherDerived>
193  lazyProduct(const MatrixBase<OtherDerived> &other) const;
194 
195  template<typename OtherDerived>
196  Derived& operator*=(const EigenBase<OtherDerived>& other);
197 
198  template<typename OtherDerived>
199  void applyOnTheLeft(const EigenBase<OtherDerived>& other);
200 
201  template<typename OtherDerived>
202  void applyOnTheRight(const EigenBase<OtherDerived>& other);
203 
204  template<typename DiagonalDerived>
207 
208  template<typename OtherDerived>
209  typename internal::scalar_product_traits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType
210  dot(const MatrixBase<OtherDerived>& other) const;
211 
212  #ifdef EIGEN2_SUPPORT
213  template<typename OtherDerived>
214  Scalar eigen2_dot(const MatrixBase<OtherDerived>& other) const;
215  #endif
216 
217  RealScalar squaredNorm() const;
218  RealScalar norm() const;
219  RealScalar stableNorm() const;
220  RealScalar blueNorm() const;
221  RealScalar hypotNorm() const;
222  const PlainObject normalized() const;
223  void normalize();
224 
225  const AdjointReturnType adjoint() const;
226  void adjointInPlace();
227 
231  const ConstDiagonalReturnType diagonal() const;
232 
233  template<int Index> struct DiagonalIndexReturnType { typedef Diagonal<Derived,Index> Type; };
234  template<int Index> struct ConstDiagonalIndexReturnType { typedef const Diagonal<const Derived,Index> Type; };
235 
236  template<int Index> typename DiagonalIndexReturnType<Index>::Type diagonal();
237  template<int Index> typename ConstDiagonalIndexReturnType<Index>::Type diagonal() const;
238 
239  // Note: The "MatrixBase::" prefixes are added to help MSVC9 to match these declarations with the later implementations.
240  // On the other hand they confuse MSVC8...
241  #if (defined _MSC_VER) && (_MSC_VER >= 1500) // 2008 or later
242  typename MatrixBase::template DiagonalIndexReturnType<Dynamic>::Type diagonal(Index index);
243  typename MatrixBase::template ConstDiagonalIndexReturnType<Dynamic>::Type diagonal(Index index) const;
244  #else
247  #endif
248 
249  #ifdef EIGEN2_SUPPORT
250  template<unsigned int Mode> typename internal::eigen2_part_return_type<Derived, Mode>::type part();
251  template<unsigned int Mode> const typename internal::eigen2_part_return_type<Derived, Mode>::type part() const;
252 
253  // huuuge hack. make Eigen2's matrix.part<Diagonal>() work in eigen3. Problem: Diagonal is now a class template instead
254  // of an integer constant. Solution: overload the part() method template wrt template parameters list.
255  template<template<typename T, int n> class U>
257  { return diagonal().asDiagonal(); }
258  #endif // EIGEN2_SUPPORT
259 
260  template<unsigned int Mode> struct TriangularViewReturnType { typedef TriangularView<Derived, Mode> Type; };
261  template<unsigned int Mode> struct ConstTriangularViewReturnType { typedef const TriangularView<const Derived, Mode> Type; };
262 
263  template<unsigned int Mode> typename TriangularViewReturnType<Mode>::Type triangularView();
264  template<unsigned int Mode> typename ConstTriangularViewReturnType<Mode>::Type triangularView() const;
265 
266  template<unsigned int UpLo> struct SelfAdjointViewReturnType { typedef SelfAdjointView<Derived, UpLo> Type; };
267  template<unsigned int UpLo> struct ConstSelfAdjointViewReturnType { typedef const SelfAdjointView<const Derived, UpLo> Type; };
268 
269  template<unsigned int UpLo> typename SelfAdjointViewReturnType<UpLo>::Type selfadjointView();
270  template<unsigned int UpLo> typename ConstSelfAdjointViewReturnType<UpLo>::Type selfadjointView() const;
271 
272  const SparseView<Derived> sparseView(const Scalar& m_reference = Scalar(0),
273  typename NumTraits<Scalar>::Real m_epsilon = NumTraits<Scalar>::dummy_precision()) const;
274  static const IdentityReturnType Identity();
275  static const IdentityReturnType Identity(Index rows, Index cols);
276  static const BasisReturnType Unit(Index size, Index i);
277  static const BasisReturnType Unit(Index i);
278  static const BasisReturnType UnitX();
279  static const BasisReturnType UnitY();
280  static const BasisReturnType UnitZ();
281  static const BasisReturnType UnitW();
282 
285 
286  Derived& setIdentity();
287  Derived& setIdentity(Index rows, Index cols);
288 
291 
294 
295  template<typename OtherDerived>
296  bool isOrthogonal(const MatrixBase<OtherDerived>& other,
299 
304  template<typename OtherDerived>
305  inline bool operator==(const MatrixBase<OtherDerived>& other) const
306  { return cwiseEqual(other).all(); }
307 
312  template<typename OtherDerived>
313  inline bool operator!=(const MatrixBase<OtherDerived>& other) const
314  { return cwiseNotEqual(other).any(); }
315 
317 
318  inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
320  template<bool Enable> inline typename internal::add_const_on_value_type<typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type>::type forceAlignedAccessIf() const;
321  template<bool Enable> inline typename internal::conditional<Enable,ForceAlignedAccess<Derived>,Derived&>::type forceAlignedAccessIf();
322 
323  Scalar trace() const;
324 
326 
327  template<int p> RealScalar lpNorm() const;
328 
329  MatrixBase<Derived>& matrix() { return *this; }
330  const MatrixBase<Derived>& matrix() const { return *this; }
331 
334  ArrayWrapper<Derived> array() { return derived(); }
335  const ArrayWrapper<const Derived> array() const { return derived(); }
336 
338 
339  const FullPivLU<PlainObject> fullPivLu() const;
341 
342  #if EIGEN2_SUPPORT_STAGE < STAGE20_RESOLVE_API_CONFLICTS
343  const LU<PlainObject> lu() const;
344  #endif
345 
346  #ifdef EIGEN2_SUPPORT
347  const LU<PlainObject> eigen2_lu() const;
348  #endif
349 
350  #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS
351  const PartialPivLU<PlainObject> lu() const;
352  #endif
353 
354  #ifdef EIGEN2_SUPPORT
355  template<typename ResultType>
356  void computeInverse(MatrixBase<ResultType> *result) const {
357  *result = this->inverse();
358  }
359  #endif
360 
361  const internal::inverse_impl<Derived> inverse() const;
362  template<typename ResultType>
364  ResultType& inverse,
365  typename ResultType::Scalar& determinant,
366  bool& invertible,
367  const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision()
368  ) const;
369  template<typename ResultType>
371  ResultType& inverse,
372  bool& invertible,
373  const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision()
374  ) const;
375  Scalar determinant() const;
376 
378 
379  const LLT<PlainObject> llt() const;
380  const LDLT<PlainObject> ldlt() const;
381 
383 
384  const HouseholderQR<PlainObject> householderQr() const;
385  const ColPivHouseholderQR<PlainObject> colPivHouseholderQr() const;
386  const FullPivHouseholderQR<PlainObject> fullPivHouseholderQr() const;
387 
388  #ifdef EIGEN2_SUPPORT
389  const QR<PlainObject> qr() const;
390  #endif
391 
392  EigenvaluesReturnType eigenvalues() const;
393  RealScalar operatorNorm() const;
394 
396 
397  JacobiSVD<PlainObject> jacobiSvd(unsigned int computationOptions = 0) const;
398 
399  #ifdef EIGEN2_SUPPORT
400  SVD<PlainObject> svd() const;
401  #endif
402 
404 
405  #ifndef EIGEN_PARSED_BY_DOXYGEN
406 
407  template<typename OtherDerived> struct cross_product_return_type {
408  typedef typename internal::scalar_product_traits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType Scalar;
409  typedef Matrix<Scalar,MatrixBase::RowsAtCompileTime,MatrixBase::ColsAtCompileTime> type;
410  };
411  #endif // EIGEN_PARSED_BY_DOXYGEN
412  template<typename OtherDerived>
413  typename cross_product_return_type<OtherDerived>::type
414  cross(const MatrixBase<OtherDerived>& other) const;
415  template<typename OtherDerived>
416  PlainObject cross3(const MatrixBase<OtherDerived>& other) const;
417  PlainObject unitOrthogonal(void) const;
418  Matrix<Scalar,3,1> eulerAngles(Index a0, Index a1, Index a2) const;
419 
420  #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS
421  ScalarMultipleReturnType operator*(const UniformScaling<Scalar>& s) const;
422  // put this as separate enum value to work around possible GCC 4.3 bug (?)
426  #endif
427 
428  enum {
430  };
431  typedef Block<const Derived,
432  internal::traits<Derived>::ColsAtCompileTime==1 ? SizeMinusOne : 1,
433  internal::traits<Derived>::ColsAtCompileTime==1 ? 1 : SizeMinusOne> ConstStartMinusOne;
436 
437  const HNormalizedReturnType hnormalized() const;
438 
440 
441  void makeHouseholderInPlace(Scalar& tau, RealScalar& beta);
442  template<typename EssentialPart>
443  void makeHouseholder(EssentialPart& essential,
444  Scalar& tau, RealScalar& beta) const;
445  template<typename EssentialPart>
446  void applyHouseholderOnTheLeft(const EssentialPart& essential,
447  const Scalar& tau,
448  Scalar* workspace);
449  template<typename EssentialPart>
450  void applyHouseholderOnTheRight(const EssentialPart& essential,
451  const Scalar& tau,
452  Scalar* workspace);
453 
455 
456  template<typename OtherScalar>
458  template<typename OtherScalar>
460 
462 
463  typedef typename internal::stem_function<Scalar>::type StemFunction;
472 
473 #ifdef EIGEN2_SUPPORT
474  template<typename ProductDerived, typename Lhs, typename Rhs>
475  Derived& operator+=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0,
476  EvalBeforeAssigningBit>& other);
477 
478  template<typename ProductDerived, typename Lhs, typename Rhs>
479  Derived& operator-=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0,
480  EvalBeforeAssigningBit>& other);
481 
484  template<typename OtherDerived>
485  Derived& lazyAssign(const Flagged<OtherDerived, 0, EvalBeforeAssigningBit>& other)
486  { return lazyAssign(other._expression()); }
487 
488  template<unsigned int Added>
489  const Flagged<Derived, Added, 0> marked() const;
490  const Flagged<Derived, 0, EvalBeforeAssigningBit> lazy() const;
491 
492  inline const Cwise<Derived> cwise() const;
493  inline Cwise<Derived> cwise();
494 
495  VectorBlock<Derived> start(Index size);
496  const VectorBlock<const Derived> start(Index size) const;
497  VectorBlock<Derived> end(Index size);
498  const VectorBlock<const Derived> end(Index size) const;
499  template<int Size> VectorBlock<Derived,Size> start();
500  template<int Size> const VectorBlock<const Derived,Size> start() const;
501  template<int Size> VectorBlock<Derived,Size> end();
502  template<int Size> const VectorBlock<const Derived,Size> end() const;
503 
504  Minor<Derived> minor(Index row, Index col);
505  const Minor<Derived> minor(Index row, Index col) const;
506 #endif
507 
508  protected:
509  MatrixBase() : Base() {}
510 
511  private:
512  explicit MatrixBase(int);
513  MatrixBase(int,int);
514  template<typename OtherDerived> explicit MatrixBase(const MatrixBase<OtherDerived>&);
515  protected:
516  // mixing arrays and matrices is not legal
517  template<typename OtherDerived> Derived& operator+=(const ArrayBase<OtherDerived>& )
518  {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;}
519  // mixing arrays and matrices is not legal
520  template<typename OtherDerived> Derived& operator-=(const ArrayBase<OtherDerived>& )
521  {EIGEN_STATIC_ASSERT(std::ptrdiff_t(sizeof(typename OtherDerived::Scalar))==-1,YOU_CANNOT_MIX_ARRAYS_AND_MATRICES); return *this;}
522 };
523 
524 } // end namespace Eigen
525 
526 #endif // EIGEN_MATRIXBASE_H