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