Eigen  3.2.9
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
SparseMatrixBase.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_SPARSEMATRIXBASE_H
11 #define EIGEN_SPARSEMATRIXBASE_H
12 
13 namespace Eigen {
14 
26 template<typename Derived> class SparseMatrixBase
27 #ifndef EIGEN_PARSED_BY_DOXYGEN
28  : public internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
29  typename NumTraits<typename internal::traits<Derived>::Scalar>::Real,
30  EigenBase<Derived> >
31 #else
32  : public EigenBase<Derived>
33 #endif // not EIGEN_PARSED_BY_DOXYGEN
34 {
35  public:
36 
37  typedef typename internal::traits<Derived>::Scalar Scalar;
38  typedef typename internal::packet_traits<Scalar>::type PacketScalar;
39  typedef typename internal::traits<Derived>::StorageKind StorageKind;
40  typedef typename internal::traits<Derived>::Index Index;
41  typedef typename internal::traits<Derived>::Index StorageIndex;
42  typedef typename internal::add_const_on_value_type_if_arithmetic<
43  typename internal::packet_traits<Scalar>::type
44  >::type PacketReturnType;
45 
47 
48  template<typename OtherDerived>
49  Derived& operator=(const EigenBase<OtherDerived> &other)
50  {
51  other.derived().evalTo(derived());
52  return derived();
53  }
54 
55  enum {
56 
57  RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
63  ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
70  SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
71  internal::traits<Derived>::ColsAtCompileTime>::ret),
76  MaxRowsAtCompileTime = RowsAtCompileTime,
77  MaxColsAtCompileTime = ColsAtCompileTime,
78 
79  MaxSizeAtCompileTime = (internal::size_at_compile_time<MaxRowsAtCompileTime,
80  MaxColsAtCompileTime>::ret),
81 
88  Flags = internal::traits<Derived>::Flags,
93  CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
98  IsRowMajor = Flags&RowMajorBit ? 1 : 0,
99 
100  InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
101  : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
103  #ifndef EIGEN_PARSED_BY_DOXYGEN
104  _HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0 // workaround sunCC
105  #endif
106  };
107 
109  typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
112  >::type AdjointReturnType;
113 
114 
116 
118 #ifndef EIGEN_PARSED_BY_DOXYGEN
119 
125  typedef typename NumTraits<Scalar>::Real RealScalar;
126 
129  typedef typename internal::conditional<_HasDirectAccess, const Scalar&, Scalar>::type CoeffReturnType;
130 
135  typedef Matrix<Scalar,EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime),
136  EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType;
137 
138  inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
139  inline Derived& derived() { return *static_cast<Derived*>(this); }
140  inline Derived& const_cast_derived() const
141  { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); }
142 
143  typedef internal::special_scalar_op_base<Derived, Scalar, RealScalar, EigenBase<Derived> > Base;
144  using Base::operator*;
145 #endif // not EIGEN_PARSED_BY_DOXYGEN
146 
147 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase
148 # include "../plugins/CommonCwiseUnaryOps.h"
149 # include "../plugins/CommonCwiseBinaryOps.h"
150 # include "../plugins/MatrixCwiseUnaryOps.h"
151 # include "../plugins/MatrixCwiseBinaryOps.h"
152 # include "../plugins/BlockMethods.h"
153 # ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN
154 # include EIGEN_SPARSEMATRIXBASE_PLUGIN
155 # endif
156 # undef EIGEN_CURRENT_STORAGE_BASE_CLASS
157 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS
160  inline Index rows() const { return derived().rows(); }
162  inline Index cols() const { return derived().cols(); }
165  inline Index size() const { return rows() * cols(); }
168  inline Index nonZeros() const { return derived().nonZeros(); }
173  inline bool isVector() const { return rows()==1 || cols()==1; }
176  Index outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); }
179  Index innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
180 
181  bool isRValue() const { return m_isRValue; }
182  Derived& markAsRValue() { m_isRValue = true; return derived(); }
183 
184  SparseMatrixBase() : m_isRValue(false) { /* TODO check flags */ }
186 
187  template<typename OtherDerived>
188  Derived& operator=(const ReturnByValue<OtherDerived>& other)
189  {
190  other.evalTo(derived());
191  return derived();
192  }
193 
194 
195  template<typename OtherDerived>
196  inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other)
197  {
198  return assign(other.derived());
199  }
200 
201  inline Derived& operator=(const Derived& other)
202  {
203 // if (other.isRValue())
204 // derived().swap(other.const_cast_derived());
205 // else
206  return assign(other.derived());
207  }
209  protected:
210 
211  template<typename OtherDerived>
212  inline Derived& assign(const OtherDerived& other)
213  {
214  const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
215  const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols();
216  if ((!transpose) && other.isRValue())
217  {
218  // eval without temporary
219  derived().resize(other.rows(), other.cols());
220  derived().setZero();
221  derived().reserve((std::max)(this->rows(),this->cols())*2);
222  for (Index j=0; j<outerSize; ++j)
223  {
224  derived().startVec(j);
225  for (typename OtherDerived::InnerIterator it(other, j); it; ++it)
226  {
227  Scalar v = it.value();
228  derived().insertBackByOuterInner(j,it.index()) = v;
229  }
230  }
231  derived().finalize();
232  }
233  else
234  {
235  assignGeneric(other);
236  }
237  return derived();
238  }
239 
240  template<typename OtherDerived>
241  inline void assignGeneric(const OtherDerived& other)
242  {
243  //const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
244  eigen_assert(( ((internal::traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) ||
245  (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) &&
246  "the transpose operation is supposed to be handled in SparseMatrix::operator=");
247 
248  enum { Flip = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit) };
249 
250  const Index outerSize = other.outerSize();
251  //typedef typename internal::conditional<transpose, LinkedVectorMatrix<Scalar,Flags&RowMajorBit>, Derived>::type TempType;
252  // thanks to shallow copies, we always eval to a tempary
253  Derived temp(other.rows(), other.cols());
254 
255  temp.reserve((std::max)(this->rows(),this->cols())*2);
256  for (Index j=0; j<outerSize; ++j)
257  {
258  temp.startVec(j);
259  for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it)
260  {
261  Scalar v = it.value();
262  temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v;
263  }
264  }
265  temp.finalize();
266 
267  derived() = temp.markAsRValue();
268  }
269 
270  public:
271 
272  template<typename Lhs, typename Rhs>
273  inline Derived& operator=(const SparseSparseProduct<Lhs,Rhs>& product);
274 
275  friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m)
276  {
277  typedef typename Derived::Nested Nested;
278  typedef typename internal::remove_all<Nested>::type NestedCleaned;
279 
280  if (Flags&RowMajorBit)
281  {
282  const Nested nm(m.derived());
283  for (Index row=0; row<nm.outerSize(); ++row)
284  {
285  Index col = 0;
286  for (typename NestedCleaned::InnerIterator it(nm.derived(), row); it; ++it)
287  {
288  for ( ; col<it.index(); ++col)
289  s << "0 ";
290  s << it.value() << " ";
291  ++col;
292  }
293  for ( ; col<m.cols(); ++col)
294  s << "0 ";
295  s << std::endl;
296  }
297  }
298  else
299  {
300  const Nested nm(m.derived());
301  if (m.cols() == 1) {
302  Index row = 0;
303  for (typename NestedCleaned::InnerIterator it(nm.derived(), 0); it; ++it)
304  {
305  for ( ; row<it.index(); ++row)
306  s << "0" << std::endl;
307  s << it.value() << std::endl;
308  ++row;
309  }
310  for ( ; row<m.rows(); ++row)
311  s << "0" << std::endl;
312  }
313  else
314  {
316  s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit, Index> >&>(trans);
317  }
318  }
319  return s;
320  }
321 
322  template<typename OtherDerived>
323  Derived& operator+=(const SparseMatrixBase<OtherDerived>& other);
324  template<typename OtherDerived>
325  Derived& operator-=(const SparseMatrixBase<OtherDerived>& other);
326 
327  Derived& operator*=(const Scalar& other);
328  Derived& operator/=(const Scalar& other);
329 
330  template<typename OtherDerived> struct CwiseProductDenseReturnType {
331  typedef CwiseBinaryOp<internal::scalar_product_op<typename internal::scalar_product_traits<
332  typename internal::traits<Derived>::Scalar,
333  typename internal::traits<OtherDerived>::Scalar
334  >::ReturnType>,
335  const Derived,
336  const OtherDerived
337  > Type;
338  };
339 
340  template<typename OtherDerived>
341  EIGEN_STRONG_INLINE const typename CwiseProductDenseReturnType<OtherDerived>::Type
342  cwiseProduct(const MatrixBase<OtherDerived> &other) const;
343 
344  // sparse * sparse
345  template<typename OtherDerived>
346  const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type
347  operator*(const SparseMatrixBase<OtherDerived> &other) const;
348 
349  // sparse * diagonal
350  template<typename OtherDerived>
351  const SparseDiagonalProduct<Derived,OtherDerived>
352  operator*(const DiagonalBase<OtherDerived> &other) const;
353 
354  // diagonal * sparse
355  template<typename OtherDerived> friend
356  const SparseDiagonalProduct<OtherDerived,Derived>
357  operator*(const DiagonalBase<OtherDerived> &lhs, const SparseMatrixBase& rhs)
358  { return SparseDiagonalProduct<OtherDerived,Derived>(lhs.derived(), rhs.derived()); }
359 
361  template<typename OtherDerived> friend
362  const typename DenseSparseProductReturnType<OtherDerived,Derived>::Type
363  operator*(const MatrixBase<OtherDerived>& lhs, const Derived& rhs)
364  { return typename DenseSparseProductReturnType<OtherDerived,Derived>::Type(lhs.derived(),rhs); }
367  template<typename OtherDerived>
368  const typename SparseDenseProductReturnType<Derived,OtherDerived>::Type
370  { return typename SparseDenseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); }
371 
373  SparseSymmetricPermutationProduct<Derived,Upper|Lower> twistedBy(const PermutationMatrix<Dynamic,Dynamic,Index>& perm) const
374  {
375  return SparseSymmetricPermutationProduct<Derived,Upper|Lower>(derived(), perm);
376  }
377 
378  template<typename OtherDerived>
379  Derived& operator*=(const SparseMatrixBase<OtherDerived>& other);
380 
381  #ifdef EIGEN2_SUPPORT
382  // deprecated
383  template<typename OtherDerived>
385  solveTriangular(const MatrixBase<OtherDerived>& other) const;
386 
387  // deprecated
388  template<typename OtherDerived>
389  void solveTriangularInPlace(MatrixBase<OtherDerived>& other) const;
390  #endif // EIGEN2_SUPPORT
391 
392  template<int Mode>
393  inline const SparseTriangularView<Derived, Mode> triangularView() const;
394 
395  template<unsigned int UpLo> inline const SparseSelfAdjointView<Derived, UpLo> selfadjointView() const;
396  template<unsigned int UpLo> inline SparseSelfAdjointView<Derived, UpLo> selfadjointView();
397 
398  template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const;
399  template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const;
400  RealScalar squaredNorm() const;
401  RealScalar norm() const;
402  RealScalar blueNorm() const;
403 
404  Transpose<Derived> transpose() { return derived(); }
405  const Transpose<const Derived> transpose() const { return derived(); }
406  const AdjointReturnType adjoint() const { return transpose(); }
407 
408  // inner-vector
411  InnerVectorReturnType innerVector(Index outer);
412  const ConstInnerVectorReturnType innerVector(Index outer) const;
414  // set of inner-vectors
417  InnerVectorsReturnType innerVectors(Index outerStart, Index outerSize);
418  const ConstInnerVectorsReturnType innerVectors(Index outerStart, Index outerSize) const;
419 
421  template<typename DenseDerived>
422  void evalTo(MatrixBase<DenseDerived>& dst) const
423  {
424  dst.setZero();
425  for (Index j=0; j<outerSize(); ++j)
426  for (typename Derived::InnerIterator i(derived(),j); i; ++i)
427  dst.coeffRef(i.row(),i.col()) = i.value();
428  }
431  {
432  return derived();
433  }
434 
435  template<typename OtherDerived>
436  bool isApprox(const SparseMatrixBase<OtherDerived>& other,
437  const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const
438  { return toDense().isApprox(other.toDense(),prec); }
439 
440  template<typename OtherDerived>
441  bool isApprox(const MatrixBase<OtherDerived>& other,
442  const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const
443  { return toDense().isApprox(other,prec); }
444 
450  inline const typename internal::eval<Derived>::type eval() const
451  { return typename internal::eval<Derived>::type(derived()); }
452 
453  Scalar sum() const;
455  protected:
456 
457  bool m_isRValue;
458 };
459 
460 } // end namespace Eigen
462 #endif // EIGEN_SPARSEMATRIXBASE_H
Generic expression of a matrix where all coefficients are defined by a functor.
Definition: CwiseNullaryOp.h:49
friend const DenseSparseProductReturnType< OtherDerived, Derived >::Type operator*(const MatrixBase< OtherDerived > &lhs, const Derived &rhs)
Definition: SparseMatrixBase.h:363
const internal::eval< Derived >::type eval() const
Definition: SparseMatrixBase.h:450
A versatible sparse matrix representation.
Definition: SparseMatrix.h:85
RowXpr row(Index i)
Definition: SparseMatrixBase.h:750
Expression of the transpose of a matrix.
Definition: Transpose.h:57
Definition: SparseMatrixBase.h:63
Definition: SparseMatrixBase.h:82
Definition: SparseMatrixBase.h:93
Definition: SparseMatrixBase.h:70
Derived & setZero()
Definition: CwiseNullaryOp.h:499
Pseudo expression to manipulate a triangular sparse matrix as a selfadjoint matrix.
Definition: SparseSelfAdjointView.h:49
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:88
SparseSymmetricPermutationProduct< Derived, Upper|Lower > twistedBy(const PermutationMatrix< Dynamic, Dynamic, Index > &perm) const
Definition: SparseMatrixBase.h:373
const CwiseBinaryOp< internal::scalar_product_op< typename Derived::Scalar, typename OtherDerived::Scalar >, const Derived, const OtherDerived > cwiseProduct(const Eigen::SparseMatrixBase< OtherDerived > &other) const
Definition: SparseMatrixBase.h:23
Index outerSize() const
Definition: SparseMatrixBase.h:176
Definition: EigenBase.h:26
Index cols() const
Definition: SparseMatrixBase.h:162
Definition: SparseMatrixBase.h:57
Generic expression where a coefficient-wise binary operator is applied to two expressions.
Definition: CwiseBinaryOp.h:107
Base class of any sparse matrices or sparse expressions.
Definition: ForwardDeclarations.h:239
Derived & derived()
Definition: EigenBase.h:34
Index size() const
Definition: SparseMatrixBase.h:165
const ScalarMultipleReturnType operator*(const Scalar &scalar) const
Definition: SparseMatrixBase.h:50
Index innerSize() const
Definition: SparseMatrixBase.h:179
Expression of a fixed-size or dynamic-size block.
Definition: Block.h:103
bool isVector() const
Definition: SparseMatrixBase.h:173
Index nonZeros() const
Definition: SparseMatrixBase.h:168
const unsigned int RowMajorBit
Definition: Constants.h:53
InnerVectorReturnType innerVector(Index outer)
Definition: SparseBlock.h:380
const unsigned int DirectAccessBit
Definition: Constants.h:142
CoeffReturnType value() const
Definition: DenseBase.h:422
InnerVectorsReturnType innerVectors(Index outerStart, Index outerSize)
Definition: SparseBlock.h:395
Generic expression where a coefficient-wise unary operator is applied to an expression.
Definition: CwiseUnaryOp.h:59
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:127
Index rows() const
Definition: SparseMatrixBase.h:160
const SparseDenseProductReturnType< Derived, OtherDerived >::Type operator*(const MatrixBase< OtherDerived > &other) const
Definition: SparseMatrixBase.h:369
Definition: SparseMatrixBase.h:88
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:48
ColXpr col(Index i)
Definition: SparseMatrixBase.h:733