Eigen  3.2.7
 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 <[email protected]>
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::add_const_on_value_type_if_arithmetic<
42  typename internal::packet_traits<Scalar>::type
43  >::type PacketReturnType;
44 
46 
47  template<typename OtherDerived>
48  Derived& operator=(const EigenBase<OtherDerived> &other)
49  {
50  other.derived().evalTo(derived());
51  return derived();
52  }
53 
54  enum {
55 
56  RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
62  ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
69  SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
70  internal::traits<Derived>::ColsAtCompileTime>::ret),
75  MaxRowsAtCompileTime = RowsAtCompileTime,
76  MaxColsAtCompileTime = ColsAtCompileTime,
77 
78  MaxSizeAtCompileTime = (internal::size_at_compile_time<MaxRowsAtCompileTime,
79  MaxColsAtCompileTime>::ret),
80 
87  Flags = internal::traits<Derived>::Flags,
92  CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
97  IsRowMajor = Flags&RowMajorBit ? 1 : 0,
98 
99  InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
100  : int(IsRowMajor) ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
101 
102  #ifndef EIGEN_PARSED_BY_DOXYGEN
103  _HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0 // workaround sunCC
104  #endif
105  };
106 
108  typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
111  >::type AdjointReturnType;
112 
113 
115 
116 
117 #ifndef EIGEN_PARSED_BY_DOXYGEN
118 
124  typedef typename NumTraits<Scalar>::Real RealScalar;
125 
128  typedef typename internal::conditional<_HasDirectAccess, const Scalar&, Scalar>::type CoeffReturnType;
129 
132 
134  typedef Matrix<Scalar,EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime),
135  EIGEN_SIZE_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType;
136 
137  inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
138  inline Derived& derived() { return *static_cast<Derived*>(this); }
139  inline Derived& const_cast_derived() const
140  { return *static_cast<Derived*>(const_cast<SparseMatrixBase*>(this)); }
142  typedef internal::special_scalar_op_base<Derived, Scalar, RealScalar, EigenBase<Derived> > Base;
143  using Base::operator*;
144 #endif // not EIGEN_PARSED_BY_DOXYGEN
145 
146 #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase
147 # include "../plugins/CommonCwiseUnaryOps.h"
148 # include "../plugins/CommonCwiseBinaryOps.h"
149 # include "../plugins/MatrixCwiseUnaryOps.h"
150 # include "../plugins/MatrixCwiseBinaryOps.h"
151 # include "../plugins/BlockMethods.h"
152 # ifdef EIGEN_SPARSEMATRIXBASE_PLUGIN
153 # include EIGEN_SPARSEMATRIXBASE_PLUGIN
154 # endif
155 # undef EIGEN_CURRENT_STORAGE_BASE_CLASS
156 #undef EIGEN_CURRENT_STORAGE_BASE_CLASS
159  inline Index rows() const { return derived().rows(); }
161  inline Index cols() const { return derived().cols(); }
164  inline Index size() const { return rows() * cols(); }
167  inline Index nonZeros() const { return derived().nonZeros(); }
172  inline bool isVector() const { return rows()==1 || cols()==1; }
175  Index outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); }
178  Index innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
179 
180  bool isRValue() const { return m_isRValue; }
181  Derived& markAsRValue() { m_isRValue = true; return derived(); }
182 
183  SparseMatrixBase() : m_isRValue(false) { /* TODO check flags */ }
184 
185 
186  template<typename OtherDerived>
187  Derived& operator=(const ReturnByValue<OtherDerived>& other)
188  {
189  other.evalTo(derived());
190  return derived();
191  }
192 
193 
194  template<typename OtherDerived>
195  inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other)
196  {
197  return assign(other.derived());
198  }
199 
200  inline Derived& operator=(const Derived& other)
201  {
202 // if (other.isRValue())
203 // derived().swap(other.const_cast_derived());
204 // else
205  return assign(other.derived());
206  }
207 
208  protected:
209 
210  template<typename OtherDerived>
211  inline Derived& assign(const OtherDerived& other)
212  {
213  const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
214  const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols();
215  if ((!transpose) && other.isRValue())
216  {
217  // eval without temporary
218  derived().resize(other.rows(), other.cols());
219  derived().setZero();
220  derived().reserve((std::max)(this->rows(),this->cols())*2);
221  for (Index j=0; j<outerSize; ++j)
222  {
223  derived().startVec(j);
224  for (typename OtherDerived::InnerIterator it(other, j); it; ++it)
225  {
226  Scalar v = it.value();
227  derived().insertBackByOuterInner(j,it.index()) = v;
228  }
229  }
230  derived().finalize();
231  }
232  else
233  {
234  assignGeneric(other);
235  }
236  return derived();
237  }
239  template<typename OtherDerived>
240  inline void assignGeneric(const OtherDerived& other)
241  {
242  //const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
243  eigen_assert(( ((internal::traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) ||
244  (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) &&
245  "the transpose operation is supposed to be handled in SparseMatrix::operator=");
246 
247  enum { Flip = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit) };
248 
249  const Index outerSize = other.outerSize();
250  //typedef typename internal::conditional<transpose, LinkedVectorMatrix<Scalar,Flags&RowMajorBit>, Derived>::type TempType;
251  // thanks to shallow copies, we always eval to a tempary
252  Derived temp(other.rows(), other.cols());
254  temp.reserve((std::max)(this->rows(),this->cols())*2);
255  for (Index j=0; j<outerSize; ++j)
256  {
257  temp.startVec(j);
258  for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it)
259  {
260  Scalar v = it.value();
261  temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v;
262  }
263  }
264  temp.finalize();
265 
266  derived() = temp.markAsRValue();
267  }
268 
269  public:
270 
271  template<typename Lhs, typename Rhs>
272  inline Derived& operator=(const SparseSparseProduct<Lhs,Rhs>& product);
273 
274  friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m)
275  {
276  typedef typename Derived::Nested Nested;
277  typedef typename internal::remove_all<Nested>::type NestedCleaned;
278 
279  if (Flags&RowMajorBit)
280  {
281  const Nested nm(m.derived());
282  for (Index row=0; row<nm.outerSize(); ++row)
283  {
284  Index col = 0;
285  for (typename NestedCleaned::InnerIterator it(nm.derived(), row); it; ++it)
286  {
287  for ( ; col<it.index(); ++col)
288  s << "0 ";
289  s << it.value() << " ";
290  ++col;
291  }
292  for ( ; col<m.cols(); ++col)
293  s << "0 ";
294  s << std::endl;
295  }
296  }
297  else
298  {
299  const Nested nm(m.derived());
300  if (m.cols() == 1) {
301  Index row = 0;
302  for (typename NestedCleaned::InnerIterator it(nm.derived(), 0); it; ++it)
303  {
304  for ( ; row<it.index(); ++row)
305  s << "0" << std::endl;
306  s << it.value() << std::endl;
307  ++row;
308  }
309  for ( ; row<m.rows(); ++row)
310  s << "0" << std::endl;
311  }
312  else
313  {
315  s << static_cast<const SparseMatrixBase<SparseMatrix<Scalar, RowMajorBit, Index> >&>(trans);
316  }
317  }
318  return s;
319  }
320 
321  template<typename OtherDerived>
322  Derived& operator+=(const SparseMatrixBase<OtherDerived>& other);
323  template<typename OtherDerived>
324  Derived& operator-=(const SparseMatrixBase<OtherDerived>& other);
325 
326  Derived& operator*=(const Scalar& other);
327  Derived& operator/=(const Scalar& other);
329  template<typename OtherDerived> struct CwiseProductDenseReturnType {
330  typedef CwiseBinaryOp<internal::scalar_product_op<typename internal::scalar_product_traits<
331  typename internal::traits<Derived>::Scalar,
332  typename internal::traits<OtherDerived>::Scalar
333  >::ReturnType>,
334  const Derived,
335  const OtherDerived
336  > Type;
337  };
338 
339  template<typename OtherDerived>
340  EIGEN_STRONG_INLINE const typename CwiseProductDenseReturnType<OtherDerived>::Type
341  cwiseProduct(const MatrixBase<OtherDerived> &other) const;
342 
343  // sparse * sparse
344  template<typename OtherDerived>
345  const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type
346  operator*(const SparseMatrixBase<OtherDerived> &other) const;
347 
348  // sparse * diagonal
349  template<typename OtherDerived>
350  const SparseDiagonalProduct<Derived,OtherDerived>
351  operator*(const DiagonalBase<OtherDerived> &other) const;
352 
353  // diagonal * sparse
354  template<typename OtherDerived> friend
355  const SparseDiagonalProduct<OtherDerived,Derived>
356  operator*(const DiagonalBase<OtherDerived> &lhs, const SparseMatrixBase& rhs)
357  { return SparseDiagonalProduct<OtherDerived,Derived>(lhs.derived(), rhs.derived()); }
360  template<typename OtherDerived> friend
361  const typename DenseSparseProductReturnType<OtherDerived,Derived>::Type
362  operator*(const MatrixBase<OtherDerived>& lhs, const Derived& rhs)
363  { return typename DenseSparseProductReturnType<OtherDerived,Derived>::Type(lhs.derived(),rhs); }
364 
366  template<typename OtherDerived>
367  const typename SparseDenseProductReturnType<Derived,OtherDerived>::Type
369  { return typename SparseDenseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); }
370 
372  SparseSymmetricPermutationProduct<Derived,Upper|Lower> twistedBy(const PermutationMatrix<Dynamic,Dynamic,Index>& perm) const
373  {
374  return SparseSymmetricPermutationProduct<Derived,Upper|Lower>(derived(), perm);
375  }
376 
377  template<typename OtherDerived>
378  Derived& operator*=(const SparseMatrixBase<OtherDerived>& other);
379 
380  #ifdef EIGEN2_SUPPORT
381  // deprecated
382  template<typename OtherDerived>
384  solveTriangular(const MatrixBase<OtherDerived>& other) const;
385 
386  // deprecated
387  template<typename OtherDerived>
388  void solveTriangularInPlace(MatrixBase<OtherDerived>& other) const;
389  #endif // EIGEN2_SUPPORT
390 
391  template<int Mode>
392  inline const SparseTriangularView<Derived, Mode> triangularView() const;
393 
394  template<unsigned int UpLo> inline const SparseSelfAdjointView<Derived, UpLo> selfadjointView() const;
395  template<unsigned int UpLo> inline SparseSelfAdjointView<Derived, UpLo> selfadjointView();
396 
397  template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const;
398  template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const;
399  RealScalar squaredNorm() const;
400  RealScalar norm() const;
401  RealScalar blueNorm() const;
402 
403  Transpose<Derived> transpose() { return derived(); }
404  const Transpose<const Derived> transpose() const { return derived(); }
405  const AdjointReturnType adjoint() const { return transpose(); }
407  // inner-vector
410  InnerVectorReturnType innerVector(Index outer);
411  const ConstInnerVectorReturnType innerVector(Index outer) const;
412 
413  // set of inner-vectors
416  InnerVectorsReturnType innerVectors(Index outerStart, Index outerSize);
417  const ConstInnerVectorsReturnType innerVectors(Index outerStart, Index outerSize) const;
418 
420  template<typename DenseDerived>
421  void evalTo(MatrixBase<DenseDerived>& dst) const
422  {
423  dst.setZero();
424  for (Index j=0; j<outerSize(); ++j)
425  for (typename Derived::InnerIterator i(derived(),j); i; ++i)
426  dst.coeffRef(i.row(),i.col()) = i.value();
427  }
428 
430  {
431  return derived();
432  }
433 
434  template<typename OtherDerived>
435  bool isApprox(const SparseMatrixBase<OtherDerived>& other,
436  const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const
437  { return toDense().isApprox(other.toDense(),prec); }
438 
439  template<typename OtherDerived>
440  bool isApprox(const MatrixBase<OtherDerived>& other,
441  const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const
442  { return toDense().isApprox(other,prec); }
443 
449  inline const typename internal::eval<Derived>::type eval() const
450  { return typename internal::eval<Derived>::type(derived()); }
451 
452  Scalar sum() const;
453 
454  protected:
455 
456  bool m_isRValue;
457 };
458 
459 } // end namespace Eigen
460 
461 #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:362
const internal::eval< Derived >::type eval() const
Definition: SparseMatrixBase.h:449
Definition: SparseMatrixBase.h:81
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
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:372
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:175
Definition: EigenBase.h:26
Definition: SparseMatrixBase.h:62
Index cols() const
Definition: SparseMatrixBase.h:161
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
Definition: SparseMatrixBase.h:87
Index size() const
Definition: SparseMatrixBase.h:164
const ScalarMultipleReturnType operator*(const Scalar &scalar) const
Definition: SparseMatrixBase.h:50
Index innerSize() const
Definition: SparseMatrixBase.h:178
Definition: SparseMatrixBase.h:69
Expression of a fixed-size or dynamic-size block.
Definition: Block.h:103
bool isVector() const
Definition: SparseMatrixBase.h:172
Index nonZeros() const
Definition: SparseMatrixBase.h:167
const unsigned int RowMajorBit
Definition: Constants.h:53
InnerVectorReturnType innerVector(Index outer)
Definition: SparseBlock.h:380
Definition: SparseMatrixBase.h:56
const unsigned int DirectAccessBit
Definition: Constants.h:142
CoeffReturnType value() const
Definition: DenseBase.h:422
Definition: SparseMatrixBase.h:92
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:159
const SparseDenseProductReturnType< Derived, OtherDerived >::Type operator*(const MatrixBase< OtherDerived > &other) const
Definition: SparseMatrixBase.h:368
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:48
ColXpr col(Index i)
Definition: SparseMatrixBase.h:733