BlockSparseMatrix.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) 2013 Desire Nuentsa <desire.nuentsa_wakam@inria.fr>
5 // Copyright (C) 2013 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_SPARSEBLOCKMATRIX_H
12 #define EIGEN_SPARSEBLOCKMATRIX_H
13 
14 // IWYU pragma: private
15 #include "./InternalHeaderCheck.h"
16 
17 namespace Eigen {
57 template <typename Scalar_, int _BlockAtCompileTime = Dynamic, int Options_ = ColMajor, typename StorageIndex_ = int>
58 class BlockSparseMatrix;
59 
60 template <typename BlockSparseMatrixT>
61 class BlockSparseMatrixView;
62 
63 namespace internal {
64 template <typename Scalar_, int _BlockAtCompileTime, int Options_, typename Index_>
65 struct traits<BlockSparseMatrix<Scalar_, _BlockAtCompileTime, Options_, Index_> > {
66  typedef Scalar_ Scalar;
67  typedef Index_ Index;
68  typedef Sparse StorageKind; // FIXME Where is it used ??
69  typedef MatrixXpr XprKind;
70  enum {
71  RowsAtCompileTime = Dynamic,
72  ColsAtCompileTime = Dynamic,
73  MaxRowsAtCompileTime = Dynamic,
74  MaxColsAtCompileTime = Dynamic,
75  BlockSize = _BlockAtCompileTime,
76  Flags = Options_ | NestByRefBit | LvalueBit,
77  CoeffReadCost = NumTraits<Scalar>::ReadCost,
78  SupportedAccessPatterns = InnerRandomAccessPattern
79  };
80 };
81 template <typename BlockSparseMatrixT>
82 struct traits<BlockSparseMatrixView<BlockSparseMatrixT> > {
83  typedef Ref<
86  typedef Ref<
89 };
90 
91 // Function object to sort a triplet list
92 template <typename Iterator, bool IsColMajor>
93 struct TripletComp {
94  typedef typename Iterator::value_type Triplet;
95  bool operator()(const Triplet& a, const Triplet& b) {
96  if (IsColMajor)
97  return ((a.col() == b.col() && a.row() < b.row()) || (a.col() < b.col()));
98  else
99  return ((a.row() == b.row() && a.col() < b.col()) || (a.row() < b.row()));
100  }
101 };
102 } // end namespace internal
103 
104 /* Proxy to view the block sparse matrix as a regular sparse matrix */
105 template <typename BlockSparseMatrixT>
106 class BlockSparseMatrixView : public SparseMatrixBase<BlockSparseMatrixT> {
107  public:
111  typedef BlockSparseMatrixT Nested;
112  enum {
113  Flags = BlockSparseMatrixT::Options,
114  Options = BlockSparseMatrixT::Options,
115  RowsAtCompileTime = BlockSparseMatrixT::RowsAtCompileTime,
116  ColsAtCompileTime = BlockSparseMatrixT::ColsAtCompileTime,
117  MaxColsAtCompileTime = BlockSparseMatrixT::MaxColsAtCompileTime,
118  MaxRowsAtCompileTime = BlockSparseMatrixT::MaxRowsAtCompileTime
119  };
120 
121  public:
122  BlockSparseMatrixView(const BlockSparseMatrixT& spblockmat) : m_spblockmat(spblockmat) {}
123 
124  Index outerSize() const { return (Flags & RowMajorBit) == 1 ? this->rows() : this->cols(); }
125  Index cols() const { return m_spblockmat.blockCols(); }
126  Index rows() const { return m_spblockmat.blockRows(); }
127  Scalar coeff(Index row, Index col) { return m_spblockmat.coeff(row, col); }
128  Scalar coeffRef(Index row, Index col) { return m_spblockmat.coeffRef(row, col); }
129  // Wrapper to iterate over all blocks
130  class InnerIterator : public BlockSparseMatrixT::BlockInnerIterator {
131  public:
133  : BlockSparseMatrixT::BlockInnerIterator(mat.m_spblockmat, outer) {}
134  };
135 
136  protected:
137  const BlockSparseMatrixT& m_spblockmat;
138 };
139 
140 // Proxy to view a regular vector as a block vector
141 template <typename BlockSparseMatrixT, typename VectorType>
143  public:
144  enum {
145  BlockSize = BlockSparseMatrixT::BlockSize,
146  ColsAtCompileTime = VectorType::ColsAtCompileTime,
147  RowsAtCompileTime = VectorType::RowsAtCompileTime,
148  Flags = VectorType::Flags
149  };
150  typedef Ref<const Matrix<typename BlockSparseMatrixT::Scalar, (RowsAtCompileTime == 1) ? 1 : BlockSize,
151  (ColsAtCompileTime == 1) ? 1 : BlockSize> >
154 
155  public:
156  BlockVectorView(const BlockSparseMatrixT& spblockmat, const VectorType& vec) : m_spblockmat(spblockmat), m_vec(vec) {}
157  inline Index cols() const { return m_vec.cols(); }
158  inline Index size() const { return m_spblockmat.blockRows(); }
159  inline Scalar coeff(Index bi) const {
160  Index startRow = m_spblockmat.blockRowsIndex(bi);
161  Index rowSize = m_spblockmat.blockRowsIndex(bi + 1) - startRow;
162  return m_vec.middleRows(startRow, rowSize);
163  }
164  inline Scalar coeff(Index bi, Index j) const {
165  Index startRow = m_spblockmat.blockRowsIndex(bi);
166  Index rowSize = m_spblockmat.blockRowsIndex(bi + 1) - startRow;
167  return m_vec.block(startRow, j, rowSize, 1);
168  }
169 
170  protected:
171  const BlockSparseMatrixT& m_spblockmat;
173 };
174 
175 template <typename VectorType, typename Index>
176 class BlockVectorReturn;
177 
178 // Proxy to view a regular vector as a block vector
179 template <typename BlockSparseMatrixT, typename VectorType>
181  public:
182  enum {
183  ColsAtCompileTime = VectorType::ColsAtCompileTime,
184  RowsAtCompileTime = VectorType::RowsAtCompileTime,
185  Flags = VectorType::Flags
186  };
189 
190  public:
191  BlockVectorReturn(const BlockSparseMatrixT& spblockmat, VectorType& vec) : m_spblockmat(spblockmat), m_vec(vec) {}
192  inline Index size() const { return m_spblockmat.blockRows(); }
193  inline Scalar coeffRef(Index bi) {
194  Index startRow = m_spblockmat.blockRowsIndex(bi);
195  Index rowSize = m_spblockmat.blockRowsIndex(bi + 1) - startRow;
196  return m_vec.middleRows(startRow, rowSize);
197  }
198  inline Scalar coeffRef(Index bi, Index j) {
199  Index startRow = m_spblockmat.blockRowsIndex(bi);
200  Index rowSize = m_spblockmat.blockRowsIndex(bi + 1) - startRow;
201  return m_vec.block(startRow, j, rowSize, 1);
202  }
203 
204  protected:
205  const BlockSparseMatrixT& m_spblockmat;
207 };
208 
209 // Block version of the sparse dense product
210 template <typename Lhs, typename Rhs>
212 
213 namespace internal {
214 
215 template <typename BlockSparseMatrixT, typename VecType>
216 struct traits<BlockSparseTimeDenseProduct<BlockSparseMatrixT, VecType> > {
221  enum {
222  RowsAtCompileTime = Dynamic,
223  ColsAtCompileTime = Dynamic,
224  MaxRowsAtCompileTime = Dynamic,
225  MaxColsAtCompileTime = Dynamic,
226  Flags = 0,
228  };
229 };
230 } // end namespace internal
231 
232 template <typename Lhs, typename Rhs>
233 class BlockSparseTimeDenseProduct : public ProductBase<BlockSparseTimeDenseProduct<Lhs, Rhs>, Lhs, Rhs> {
234  public:
235  EIGEN_PRODUCT_PUBLIC_INTERFACE(BlockSparseTimeDenseProduct)
236 
237  BlockSparseTimeDenseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs, rhs) {}
238 
239  template <typename Dest>
240  void scaleAndAddTo(Dest& dest, const typename Rhs::Scalar& alpha) const {
241  BlockVectorReturn<Lhs, Dest> tmpDest(m_lhs, dest);
243  tmpDest, alpha);
244  }
245 
246  private:
248 };
249 
250 template <typename Scalar_, int _BlockAtCompileTime, int Options_, typename StorageIndex_>
252  : public SparseMatrixBase<BlockSparseMatrix<Scalar_, _BlockAtCompileTime, Options_, StorageIndex_> > {
253  public:
254  typedef Scalar_ Scalar;
256  typedef StorageIndex_ StorageIndex;
257  typedef
260 
261  enum {
262  Options = Options_,
264  BlockSize = _BlockAtCompileTime,
270  IsColMajor = Flags & RowMajorBit ? 0 : 1
271  };
275  typedef std::conditional_t<_BlockAtCompileTime == Dynamic, Scalar, BlockScalar> BlockScalarReturnType;
277 
278  public:
279  // Default constructor
281  : m_innerBSize(0),
282  m_outerBSize(0),
283  m_innerOffset(0),
284  m_outerOffset(0),
285  m_nonzerosblocks(0),
286  m_values(0),
287  m_blockPtr(0),
288  m_indices(0),
289  m_outerIndex(0),
291 
297  : m_innerBSize(IsColMajor ? brow : bcol),
298  m_outerBSize(IsColMajor ? bcol : brow),
299  m_innerOffset(0),
300  m_outerOffset(0),
301  m_nonzerosblocks(0),
302  m_values(0),
303  m_blockPtr(0),
304  m_indices(0),
305  m_outerIndex(0),
307 
312  : m_innerBSize(other.m_innerBSize),
313  m_outerBSize(other.m_outerBSize),
315  m_nonzeros(other.m_nonzeros),
316  m_blockPtr(0),
317  m_blockSize(other.m_blockSize) {
318  // should we allow copying between variable-size blocks and fixed-size blocks ??
319  eigen_assert(m_blockSize == BlockSize && " CAN NOT COPY BETWEEN FIXED-SIZE AND VARIABLE-SIZE BLOCKS");
320 
323  std::copy(other.m_values, other.m_values + m_nonzeros, m_values);
324 
326 
329  }
330 
331  friend void swap(BlockSparseMatrix& first, BlockSparseMatrix& second) {
332  std::swap(first.m_innerBSize, second.m_innerBSize);
333  std::swap(first.m_outerBSize, second.m_outerBSize);
334  std::swap(first.m_innerOffset, second.m_innerOffset);
335  std::swap(first.m_outerOffset, second.m_outerOffset);
336  std::swap(first.m_nonzerosblocks, second.m_nonzerosblocks);
337  std::swap(first.m_nonzeros, second.m_nonzeros);
338  std::swap(first.m_values, second.m_values);
339  std::swap(first.m_blockPtr, second.m_blockPtr);
340  std::swap(first.m_indices, second.m_indices);
341  std::swap(first.m_outerIndex, second.m_outerIndex);
342  std::swap(first.m_BlockSize, second.m_blockSize);
343  }
344 
346  // Copy-and-swap paradigm ... avoid leaked data if thrown
347  swap(*this, other);
348  return *this;
349  }
350 
351  // Destructor
353  delete[] m_outerIndex;
354  delete[] m_innerOffset;
355  delete[] m_outerOffset;
356  delete[] m_indices;
357  delete[] m_blockPtr;
358  delete[] m_values;
359  }
360 
365  template <typename MatrixType>
367  EIGEN_STATIC_ASSERT((m_blockSize != Dynamic), THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE);
368 
369  *this = spmat;
370  }
371 
380  template <typename MatrixType>
381  inline BlockSparseMatrix& operator=(const MatrixType& spmat) {
382  eigen_assert((m_innerBSize != 0 && m_outerBSize != 0) &&
383  "Trying to assign to a zero-size matrix, call resize() first");
384  eigen_assert(((MatrixType::Options & RowMajorBit) != IsColMajor) && "Wrong storage order");
386  MatrixPatternType blockPattern(blockRows(), blockCols());
387  m_nonzeros = 0;
388 
389  // First, compute the number of nonzero blocks and their locations
390  for (StorageIndex bj = 0; bj < m_outerBSize; ++bj) {
391  // Browse each outer block and compute the structure
392  std::vector<bool> nzblocksFlag(m_innerBSize, false); // Record the existing blocks
393  blockPattern.startVec(bj);
394  for (StorageIndex j = blockOuterIndex(bj); j < blockOuterIndex(bj + 1); ++j) {
395  typename MatrixType::InnerIterator it_spmat(spmat, j);
396  for (; it_spmat; ++it_spmat) {
397  StorageIndex bi = innerToBlock(it_spmat.index()); // Index of the current nonzero block
398  if (!nzblocksFlag[bi]) {
399  // Save the index of this nonzero block
400  nzblocksFlag[bi] = true;
401  blockPattern.insertBackByOuterInnerUnordered(bj, bi) = true;
402  // Compute the total number of nonzeros (including explicit zeros in blocks)
404  }
405  }
406  } // end current outer block
407  }
408  blockPattern.finalize();
409 
410  // Allocate the internal arrays
411  setBlockStructure(blockPattern);
412 
413  for (StorageIndex nz = 0; nz < m_nonzeros; ++nz) m_values[nz] = Scalar(0);
414  for (StorageIndex bj = 0; bj < m_outerBSize; ++bj) {
415  // Now copy the values
416  for (StorageIndex j = blockOuterIndex(bj); j < blockOuterIndex(bj + 1); ++j) {
417  // Browse the outer block column by column (for column-major matrices)
418  typename MatrixType::InnerIterator it_spmat(spmat, j);
419  for (; it_spmat; ++it_spmat) {
420  StorageIndex idx = 0; // Position of this block in the column block
421  StorageIndex bi = innerToBlock(it_spmat.index()); // Index of the current nonzero block
422  // Go to the inner block where this element belongs to
423  while (bi > m_indices[m_outerIndex[bj] + idx]) ++idx; // Not expensive for ordered blocks
424  StorageIndex idxVal; // Get the right position in the array of values for this element
425  if (m_blockSize == Dynamic) {
426  // Offset from all blocks before ...
427  idxVal = m_blockPtr[m_outerIndex[bj] + idx];
428  // ... and offset inside the block
429  idxVal += (j - blockOuterIndex(bj)) * blockOuterSize(bj) + it_spmat.index() - m_innerOffset[bi];
430  } else {
431  // All blocks before
432  idxVal = (m_outerIndex[bj] + idx) * m_blockSize * m_blockSize;
433  // inside the block
434  idxVal += (j - blockOuterIndex(bj)) * m_blockSize + (it_spmat.index() % m_blockSize);
435  }
436  // Insert the value
437  m_values[idxVal] = it_spmat.value();
438  } // end of this column
439  } // end of this block
440  } // end of this outer block
441 
442  return *this;
443  }
444 
462  template <typename MatrixType>
463  void setBlockStructure(const MatrixType& blockPattern) {
464  resize(blockPattern.rows(), blockPattern.cols());
465  reserve(blockPattern.nonZeros());
466 
467  // Browse the block pattern and set up the various pointers
468  m_outerIndex[0] = 0;
469  if (m_blockSize == Dynamic) m_blockPtr[0] = 0;
470  for (StorageIndex nz = 0; nz < m_nonzeros; ++nz) m_values[nz] = Scalar(0);
471  for (StorageIndex bj = 0; bj < m_outerBSize; ++bj) {
472  // Browse each outer block
473 
474  // First, copy and save the indices of nonzero blocks
475  // FIXME : find a way to avoid this ...
476  std::vector<int> nzBlockIdx;
477  typename MatrixType::InnerIterator it(blockPattern, bj);
478  for (; it; ++it) {
479  nzBlockIdx.push_back(it.index());
480  }
481  std::sort(nzBlockIdx.begin(), nzBlockIdx.end());
482 
483  // Now, fill block indices and (eventually) pointers to blocks
484  for (StorageIndex idx = 0; idx < nzBlockIdx.size(); ++idx) {
485  StorageIndex offset = m_outerIndex[bj] + idx; // offset in m_indices
486  m_indices[offset] = nzBlockIdx[idx];
487  if (m_blockSize == Dynamic)
488  m_blockPtr[offset] = m_blockPtr[offset - 1] + blockInnerSize(nzBlockIdx[idx]) * blockOuterSize(bj);
489  // There is no blockPtr for fixed-size blocks... not needed !???
490  }
491  // Save the pointer to the next outer block
492  m_outerIndex[bj + 1] = m_outerIndex[bj] + nzBlockIdx.size();
493  }
494  }
495 
499  inline void resize(Index brow, Index bcol) {
500  m_innerBSize = IsColMajor ? brow : bcol;
501  m_outerBSize = IsColMajor ? bcol : brow;
502  }
503 
509  inline void setBlockSize(Index blockSize) { m_blockSize = blockSize; }
510 
520  inline void setBlockLayout(const VectorXi& rowBlocks, const VectorXi& colBlocks) {
521  const VectorXi& innerBlocks = IsColMajor ? rowBlocks : colBlocks;
522  const VectorXi& outerBlocks = IsColMajor ? colBlocks : rowBlocks;
523  eigen_assert(m_innerBSize == innerBlocks.size() && "CHECK THE NUMBER OF ROW OR COLUMN BLOCKS");
524  eigen_assert(m_outerBSize == outerBlocks.size() && "CHECK THE NUMBER OF ROW OR COLUMN BLOCKS");
525  m_outerBSize = outerBlocks.size();
526  // starting index of blocks... cumulative sums
529  m_innerOffset[0] = 0;
530  m_outerOffset[0] = 0;
531  std::partial_sum(&innerBlocks[0], &innerBlocks[m_innerBSize - 1] + 1, &m_innerOffset[1]);
532  std::partial_sum(&outerBlocks[0], &outerBlocks[m_outerBSize - 1] + 1, &m_outerOffset[1]);
533 
534  // Compute the total number of nonzeros
535  m_nonzeros = 0;
536  for (StorageIndex bj = 0; bj < m_outerBSize; ++bj)
537  for (StorageIndex bi = 0; bi < m_innerBSize; ++bi) m_nonzeros += outerBlocks[bj] * innerBlocks[bi];
538  }
539 
550  inline void reserve(const Index nonzerosblocks) {
551  eigen_assert((m_innerBSize != 0 && m_outerBSize != 0) &&
552  "TRYING TO RESERVE ZERO-SIZE MATRICES, CALL resize() first");
553 
554  // FIXME Should free if already allocated
556 
557  m_nonzerosblocks = nonzerosblocks;
558  if (m_blockSize != Dynamic) {
559  m_nonzeros = nonzerosblocks * (m_blockSize * m_blockSize);
560  m_blockPtr = 0;
561  } else {
562  // m_nonzeros is already computed in setBlockLayout()
564  }
566  m_values = new Scalar[m_nonzeros];
567  }
568 
579  template <typename InputIterator>
580  void setFromTriplets(const InputIterator& begin, const InputIterator& end) {
581  eigen_assert((m_innerBSize != 0 && m_outerBSize != 0) && "ZERO BLOCKS, PLEASE CALL resize() before");
582 
583  /* First, sort the triplet list
584  * FIXME This can be unnecessarily expensive since only the inner indices have to be sorted
585  * The best approach is like in SparseMatrix::setFromTriplets()
586  */
588  std::sort(begin, end, tripletcomp);
589 
590  /* Count the number of rows and column blocks,
591  * and the number of nonzero blocks per outer dimension
592  */
593  VectorXi rowBlocks(m_innerBSize); // Size of each block row
594  VectorXi colBlocks(m_outerBSize); // Size of each block column
595  rowBlocks.setZero();
596  colBlocks.setZero();
597  VectorXi nzblock_outer(m_outerBSize); // Number of nz blocks per outer vector
598  VectorXi nz_outer(m_outerBSize); // Number of nz per outer vector...for variable-size blocks
599  nzblock_outer.setZero();
600  nz_outer.setZero();
601  for (InputIterator it(begin); it != end; ++it) {
602  eigen_assert(it->row() >= 0 && it->row() < this->blockRows() && it->col() >= 0 && it->col() < this->blockCols());
603  eigen_assert((it->value().rows() == it->value().cols() && (it->value().rows() == m_blockSize)) ||
604  (m_blockSize == Dynamic));
605 
606  if (m_blockSize == Dynamic) {
607  eigen_assert((rowBlocks[it->row()] == 0 || rowBlocks[it->row()] == it->value().rows()) &&
608  "NON CORRESPONDING SIZES FOR ROW BLOCKS");
609  eigen_assert((colBlocks[it->col()] == 0 || colBlocks[it->col()] == it->value().cols()) &&
610  "NON CORRESPONDING SIZES FOR COLUMN BLOCKS");
611  rowBlocks[it->row()] = it->value().rows();
612  colBlocks[it->col()] = it->value().cols();
613  }
614  nz_outer(IsColMajor ? it->col() : it->row()) += it->value().rows() * it->value().cols();
615  nzblock_outer(IsColMajor ? it->col() : it->row())++;
616  }
617  // Allocate member arrays
618  if (m_blockSize == Dynamic) setBlockLayout(rowBlocks, colBlocks);
619  StorageIndex nzblocks = nzblock_outer.sum();
620  reserve(nzblocks);
621 
622  // Temporary markers
623  VectorXi block_id(m_outerBSize); // To be used as a block marker during insertion
624 
625  // Setup outer index pointers and markers
626  m_outerIndex[0] = 0;
627  if (m_blockSize == Dynamic) m_blockPtr[0] = 0;
628  for (StorageIndex bj = 0; bj < m_outerBSize; ++bj) {
629  m_outerIndex[bj + 1] = m_outerIndex[bj] + nzblock_outer(bj);
630  block_id(bj) = m_outerIndex[bj];
631  if (m_blockSize == Dynamic) {
632  m_blockPtr[m_outerIndex[bj + 1]] = m_blockPtr[m_outerIndex[bj]] + nz_outer(bj);
633  }
634  }
635 
636  // Fill the matrix
637  for (InputIterator it(begin); it != end; ++it) {
638  StorageIndex outer = IsColMajor ? it->col() : it->row();
639  StorageIndex inner = IsColMajor ? it->row() : it->col();
640  m_indices[block_id(outer)] = inner;
641  StorageIndex block_size = it->value().rows() * it->value().cols();
642  StorageIndex nz_marker = blockPtr(block_id[outer]);
643  memcpy(&(m_values[nz_marker]), it->value().data(), block_size * sizeof(Scalar));
644  if (m_blockSize == Dynamic) {
645  m_blockPtr[block_id(outer) + 1] = m_blockPtr[block_id(outer)] + block_size;
646  }
647  block_id(outer)++;
648  }
649 
650  // An alternative when the outer indices are sorted...no need to use an array of markers
651  // for(Index bcol = 0; bcol < m_outerBSize; ++bcol)
652  // {
653  // Index id = 0, id_nz = 0, id_nzblock = 0;
654  // for(InputIterator it(begin); it!=end; ++it)
655  // {
656  // while (id<bcol) // one pass should do the job unless there are empty columns
657  // {
658  // id++;
659  // m_outerIndex[id+1]=m_outerIndex[id];
660  // }
661  // m_outerIndex[id+1] += 1;
662  // m_indices[id_nzblock]=brow;
663  // Index block_size = it->value().rows()*it->value().cols();
664  // m_blockPtr[id_nzblock+1] = m_blockPtr[id_nzblock] + block_size;
665  // id_nzblock++;
666  // memcpy(&(m_values[id_nz]),it->value().data(), block_size*sizeof(Scalar));
667  // id_nz += block_size;
668  // }
669  // while(id < m_outerBSize-1) // Empty columns at the end
670  // {
671  // id++;
672  // m_outerIndex[id+1]=m_outerIndex[id];
673  // }
674  // }
675  }
676 
680  inline Index rows() const {
681  // return blockRows();
682  return (IsColMajor ? innerSize() : outerSize());
683  }
684 
688  inline Index cols() const {
689  // return blockCols();
690  return (IsColMajor ? outerSize() : innerSize());
691  }
692 
693  inline Index innerSize() const {
694  if (m_blockSize == Dynamic)
695  return m_innerOffset[m_innerBSize];
696  else
697  return (m_innerBSize * m_blockSize);
698  }
699 
700  inline Index outerSize() const {
701  if (m_blockSize == Dynamic)
702  return m_outerOffset[m_outerBSize];
703  else
704  return (m_outerBSize * m_blockSize);
705  }
707  inline Index blockRows() const { return (IsColMajor ? m_innerBSize : m_outerBSize); }
709  inline Index blockCols() const { return (IsColMajor ? m_outerBSize : m_innerBSize); }
710 
711  inline Index outerBlocks() const { return m_outerBSize; }
712  inline Index innerBlocks() const { return m_innerBSize; }
713 
715  inline Index outerToBlock(Index outer) const {
716  eigen_assert(outer < outerSize() && "OUTER INDEX OUT OF BOUNDS");
717 
718  if (m_blockSize != Dynamic) return (outer / m_blockSize); // Integer division
719 
720  StorageIndex b_outer = 0;
721  while (m_outerOffset[b_outer] <= outer) ++b_outer;
722  return b_outer - 1;
723  }
725  inline Index innerToBlock(Index inner) const {
726  eigen_assert(inner < innerSize() && "OUTER INDEX OUT OF BOUNDS");
727 
728  if (m_blockSize != Dynamic) return (inner / m_blockSize); // Integer division
729 
730  StorageIndex b_inner = 0;
731  while (m_innerOffset[b_inner] <= inner) ++b_inner;
732  return b_inner - 1;
733  }
734 
739  eigen_assert(brow < blockRows() && "BLOCK ROW INDEX OUT OF BOUNDS");
740  eigen_assert(bcol < blockCols() && "BLOCK nzblocksFlagCOLUMN OUT OF BOUNDS");
741 
742  StorageIndex rsize = IsColMajor ? blockInnerSize(brow) : blockOuterSize(bcol);
743  StorageIndex csize = IsColMajor ? blockOuterSize(bcol) : blockInnerSize(brow);
744  StorageIndex inner = IsColMajor ? brow : bcol;
745  StorageIndex outer = IsColMajor ? bcol : brow;
746  StorageIndex offset = m_outerIndex[outer];
747  while (offset < m_outerIndex[outer + 1] && m_indices[offset] != inner) offset++;
748  if (m_indices[offset] == inner) {
749  return Map<BlockScalar>(&(m_values[blockPtr(offset)]), rsize, csize);
750  } else {
751  // FIXME the block does not exist, Insert it !!!!!!!!!
752  eigen_assert("DYNAMIC INSERTION IS NOT YET SUPPORTED");
753  }
754  }
755 
760  eigen_assert(brow < blockRows() && "BLOCK ROW INDEX OUT OF BOUNDS");
761  eigen_assert(bcol < blockCols() && "BLOCK COLUMN OUT OF BOUNDS");
762 
763  StorageIndex rsize = IsColMajor ? blockInnerSize(brow) : blockOuterSize(bcol);
764  StorageIndex csize = IsColMajor ? blockOuterSize(bcol) : blockInnerSize(brow);
765  StorageIndex inner = IsColMajor ? brow : bcol;
766  StorageIndex outer = IsColMajor ? bcol : brow;
767  StorageIndex offset = m_outerIndex[outer];
768  while (offset < m_outerIndex[outer + 1] && m_indices[offset] != inner) offset++;
769  if (m_indices[offset] == inner) {
770  return Map<const BlockScalar>(&(m_values[blockPtr(offset)]), rsize, csize);
771  } else
772  // return BlockScalar::Zero(rsize, csize);
773  eigen_assert("NOT YET SUPPORTED");
774  }
775 
776  // Block Matrix times vector product
777  template <typename VecType>
780  }
781 
783  inline Index nonZerosBlocks() const { return m_nonzerosblocks; }
785  inline Index nonZeros() const { return m_nonzeros; }
786 
787  inline BlockScalarReturnType* valuePtr() { return static_cast<BlockScalarReturnType*>(m_values); }
788  // inline Scalar *valuePtr(){ return m_values; }
789  inline StorageIndex* innerIndexPtr() { return m_indices; }
790  inline const StorageIndex* innerIndexPtr() const { return m_indices; }
792  inline const StorageIndex* outerIndexPtr() const { return m_outerIndex; }
793 
795  inline bool isCompressed() const { return true; }
799  inline Index blockRowsIndex(Index bi) const { return IsColMajor ? blockInnerIndex(bi) : blockOuterIndex(bi); }
800 
804  inline Index blockColsIndex(Index bj) const { return IsColMajor ? blockOuterIndex(bj) : blockInnerIndex(bj); }
805 
806  inline Index blockOuterIndex(Index bj) const {
807  return (m_blockSize == Dynamic) ? m_outerOffset[bj] : (bj * m_blockSize);
808  }
809  inline Index blockInnerIndex(Index bi) const {
810  return (m_blockSize == Dynamic) ? m_innerOffset[bi] : (bi * m_blockSize);
811  }
812 
813  // Not needed ???
814  inline Index blockInnerSize(Index bi) const {
815  return (m_blockSize == Dynamic) ? (m_innerOffset[bi + 1] - m_innerOffset[bi]) : m_blockSize;
816  }
817  inline Index blockOuterSize(Index bj) const {
818  return (m_blockSize == Dynamic) ? (m_outerOffset[bj + 1] - m_outerOffset[bj]) : m_blockSize;
819  }
820 
824  class InnerIterator; // Browse column by column
825 
829  class BlockInnerIterator; // Browse block by block
830 
831  friend std::ostream& operator<<(std::ostream& s, const BlockSparseMatrix& m) {
832  for (StorageIndex j = 0; j < m.outerBlocks(); ++j) {
833  BlockInnerIterator itb(m, j);
834  for (; itb; ++itb) {
835  s << "(" << itb.row() << ", " << itb.col() << ")\n";
836  s << itb.value() << "\n";
837  }
838  }
839  s << std::endl;
840  return s;
841  }
842 
846  Index blockPtr(Index id) const {
847  if (m_blockSize == Dynamic)
848  return m_blockPtr[id];
849  else
850  return id * m_blockSize * m_blockSize;
851  // return blockDynIdx(id, std::conditional_t<(BlockSize==Dynamic), internal::true_type, internal::false_type>());
852  }
853 
854  protected:
855  // inline Index blockDynIdx(Index id, internal::true_type) const
856  // {
857  // return m_blockPtr[id];
858  // }
859  // inline Index blockDynIdx(Index id, internal::false_type) const
860  // {
861  // return id * BlockSize * BlockSize;
862  // }
863 
864  // To be implemented
865  // Insert a block at a particular location... need to make a room for that
867 
868  Index m_innerBSize; // Number of block rows
869  Index m_outerBSize; // Number of block columns
870  StorageIndex* m_innerOffset; // Starting index of each inner block (size m_innerBSize+1)
871  StorageIndex* m_outerOffset; // Starting index of each outer block (size m_outerBSize+1)
872  Index m_nonzerosblocks; // Total nonzeros blocks (lower than m_innerBSize x m_outerBSize)
873  Index m_nonzeros; // Total nonzeros elements
874  Scalar* m_values; // Values stored block column after block column (size m_nonzeros)
875  StorageIndex* m_blockPtr; // Pointer to the beginning of each block in m_values, size m_nonzeroblocks ... null for
876  // fixed-size blocks
877  StorageIndex* m_indices; // Inner block indices, size m_nonzerosblocks ... OK
878  StorageIndex* m_outerIndex; // Starting pointer of each block column in m_indices (size m_outerBSize)... OK
879  Index m_blockSize; // Size of a block for fixed-size blocks, otherwise -1
880 };
881 
882 template <typename Scalar_, int _BlockAtCompileTime, int Options_, typename StorageIndex_>
883 class BlockSparseMatrix<Scalar_, _BlockAtCompileTime, Options_, StorageIndex_>::BlockInnerIterator {
884  public:
885  enum { Flags = Options_ };
886 
888  : m_mat(mat), m_outer(outer), m_id(mat.m_outerIndex[outer]), m_end(mat.m_outerIndex[outer + 1]) {}
889 
891  m_id++;
892  return *this;
893  }
894 
895  inline const Map<const BlockScalar> value() const {
896  return Map<const BlockScalar>(&(m_mat.m_values[m_mat.blockPtr(m_id)]), rows(), cols());
897  }
899  return Map<BlockScalar>(&(m_mat.m_values[m_mat.blockPtr(m_id)]), rows(), cols());
900  }
901  // Block inner index
902  inline Index index() const { return m_mat.m_indices[m_id]; }
903  inline Index outer() const { return m_outer; }
904  // block row index
905  inline Index row() const { return index(); }
906  // block column index
907  inline Index col() const { return outer(); }
908  // FIXME Number of rows in the current block
909  inline Index rows() const {
910  return (m_mat.m_blockSize == Dynamic) ? (m_mat.m_innerOffset[index() + 1] - m_mat.m_innerOffset[index()])
911  : m_mat.m_blockSize;
912  }
913  // Number of columns in the current block ...
914  inline Index cols() const {
915  return (m_mat.m_blockSize == Dynamic) ? (m_mat.m_outerOffset[m_outer + 1] - m_mat.m_outerOffset[m_outer])
916  : m_mat.m_blockSize;
917  }
918  inline operator bool() const { return (m_id < m_end); }
919 
920  protected:
922  const Index m_outer;
925 };
926 
927 template <typename Scalar_, int _BlockAtCompileTime, int Options_, typename StorageIndex_>
928 class BlockSparseMatrix<Scalar_, _BlockAtCompileTime, Options_, StorageIndex_>::InnerIterator {
929  public:
931  : m_mat(mat),
932  m_outerB(mat.outerToBlock(outer)),
933  m_outer(outer),
934  itb(mat, mat.outerToBlock(outer)),
935  m_offset(outer - mat.blockOuterIndex(m_outerB)) {
936  if (itb) {
937  m_id = m_mat.blockInnerIndex(itb.index());
938  m_start = m_id;
939  m_end = m_mat.blockInnerIndex(itb.index() + 1);
940  }
941  }
943  m_id++;
944  if (m_id >= m_end) {
945  ++itb;
946  if (itb) {
947  m_id = m_mat.blockInnerIndex(itb.index());
948  m_start = m_id;
949  m_end = m_mat.blockInnerIndex(itb.index() + 1);
950  }
951  }
952  return *this;
953  }
954  inline const Scalar& value() const { return itb.value().coeff(m_id - m_start, m_offset); }
955  inline Scalar& valueRef() { return itb.valueRef().coeff(m_id - m_start, m_offset); }
956  inline Index index() const { return m_id; }
957  inline Index outer() const { return m_outer; }
958  inline Index col() const { return outer(); }
959  inline Index row() const { return index(); }
960  inline operator bool() const { return itb; }
961 
962  protected:
964  const Index m_outer;
966  BlockInnerIterator itb; // Iterator through the blocks
967  const Index m_offset; // Position of this column in the block
968  Index m_start; // starting inner index of this block
969  Index m_id; // current inner index in the block
970  Index m_end; // starting inner index of the next block
971 };
972 } // end namespace Eigen
973 
974 #endif // EIGEN_SPARSEBLOCKMATRIX_H
#define eigen_assert(x)
Definition: Macros.h:910
m col(1)
m row(1)
#define EIGEN_STATIC_ASSERT(X, MSG)
Definition: StaticAssert.h:26
Scalar * b
Definition: benchVecAdd.cpp:17
SCALAR Scalar
Definition: bench_gemm.cpp:45
MatrixXf MatrixType
Definition: benchmark-blocking-sizes.cpp:52
Definition: BlockSparseMatrix.h:130
InnerIterator(const BlockSparseMatrixView &mat, Index outer)
Definition: BlockSparseMatrix.h:132
Definition: BlockSparseMatrix.h:106
Index outerSize() const
Definition: BlockSparseMatrix.h:124
BlockSparseMatrixView(const BlockSparseMatrixT &spblockmat)
Definition: BlockSparseMatrix.h:122
BlockSparseMatrixT Nested
Definition: BlockSparseMatrix.h:111
Ref< typename BlockSparseMatrixT::BlockScalar > Scalar
Definition: BlockSparseMatrix.h:108
Scalar coeff(Index row, Index col)
Definition: BlockSparseMatrix.h:127
BlockSparseMatrixT::Index Index
Definition: BlockSparseMatrix.h:110
Index rows() const
Definition: BlockSparseMatrix.h:126
Scalar coeffRef(Index row, Index col)
Definition: BlockSparseMatrix.h:128
const BlockSparseMatrixT & m_spblockmat
Definition: BlockSparseMatrix.h:137
@ MaxColsAtCompileTime
Definition: BlockSparseMatrix.h:117
@ RowsAtCompileTime
Definition: BlockSparseMatrix.h:115
@ MaxRowsAtCompileTime
Definition: BlockSparseMatrix.h:118
@ ColsAtCompileTime
Definition: BlockSparseMatrix.h:116
@ Options
Definition: BlockSparseMatrix.h:114
Index cols() const
Definition: BlockSparseMatrix.h:125
Ref< typename BlockSparseMatrixT::BlockRealScalar > RealScalar
Definition: BlockSparseMatrix.h:109
Definition: BlockSparseMatrix.h:883
Index rows() const
Definition: BlockSparseMatrix.h:909
Index outer() const
Definition: BlockSparseMatrix.h:903
const BlockSparseMatrix< Scalar_, _BlockAtCompileTime, Options_, StorageIndex > & m_mat
Definition: BlockSparseMatrix.h:921
const Map< const BlockScalar > value() const
Definition: BlockSparseMatrix.h:895
Index cols() const
Definition: BlockSparseMatrix.h:914
Index index() const
Definition: BlockSparseMatrix.h:902
Index row() const
Definition: BlockSparseMatrix.h:905
Index col() const
Definition: BlockSparseMatrix.h:907
BlockInnerIterator(const BlockSparseMatrix &mat, const Index outer)
Definition: BlockSparseMatrix.h:887
Index m_id
Definition: BlockSparseMatrix.h:923
BlockInnerIterator & operator++()
Definition: BlockSparseMatrix.h:890
const Index m_outer
Definition: BlockSparseMatrix.h:922
Map< BlockScalar > valueRef()
Definition: BlockSparseMatrix.h:898
Index m_end
Definition: BlockSparseMatrix.h:924
Definition: BlockSparseMatrix.h:928
const Index m_offset
Definition: BlockSparseMatrix.h:967
InnerIterator(const BlockSparseMatrix &mat, Index outer)
Definition: BlockSparseMatrix.h:930
const Scalar & value() const
Definition: BlockSparseMatrix.h:954
Index m_id
Definition: BlockSparseMatrix.h:969
Index col() const
Definition: BlockSparseMatrix.h:958
Index index() const
Definition: BlockSparseMatrix.h:956
Index outer() const
Definition: BlockSparseMatrix.h:957
Index m_end
Definition: BlockSparseMatrix.h:970
Index row() const
Definition: BlockSparseMatrix.h:959
BlockInnerIterator itb
Definition: BlockSparseMatrix.h:966
InnerIterator & operator++()
Definition: BlockSparseMatrix.h:942
const Index m_outer
Definition: BlockSparseMatrix.h:964
Index m_start
Definition: BlockSparseMatrix.h:968
Scalar & valueRef()
Definition: BlockSparseMatrix.h:955
const Index m_outerB
Definition: BlockSparseMatrix.h:965
const BlockSparseMatrix & m_mat
Definition: BlockSparseMatrix.h:963
A versatile sparse matrix representation where each element is a block.
Definition: BlockSparseMatrix.h:252
BlockSparseMatrix & operator=(const MatrixType &spmat)
Assignment from a sparse matrix with the same storage order.
Definition: BlockSparseMatrix.h:381
Index innerToBlock(Index inner) const
Definition: BlockSparseMatrix.h:725
void setBlockStructure(const MatrixType &blockPattern)
Set the nonzero block pattern of the matrix.
Definition: BlockSparseMatrix.h:463
const StorageIndex * outerIndexPtr() const
Definition: BlockSparseMatrix.h:792
Index blockInnerIndex(Index bi) const
Definition: BlockSparseMatrix.h:809
Index blockCols() const
Definition: BlockSparseMatrix.h:709
friend std::ostream & operator<<(std::ostream &s, const BlockSparseMatrix &m)
Definition: BlockSparseMatrix.h:831
BlockSparseMatrix(Index brow, Index bcol)
Construct and resize.
Definition: BlockSparseMatrix.h:296
BlockSparseMatrix & operator=(BlockSparseMatrix other)
Definition: BlockSparseMatrix.h:345
Index outerSize() const
Definition: BlockSparseMatrix.h:700
Matrix< Scalar, _BlockAtCompileTime, _BlockAtCompileTime, IsColMajor ? ColMajor :RowMajor > BlockScalar
Definition: BlockSparseMatrix.h:272
Index blockPtr(Index id) const
Definition: BlockSparseMatrix.h:846
Index m_blockSize
Definition: BlockSparseMatrix.h:879
StorageIndex * m_indices
Definition: BlockSparseMatrix.h:877
Index m_innerBSize
Definition: BlockSparseMatrix.h:868
internal::ref_selector< BlockSparseMatrix< Scalar_, _BlockAtCompileTime, Options_, StorageIndex_ > >::type Nested
Definition: BlockSparseMatrix.h:259
StorageIndex * innerIndexPtr()
Definition: BlockSparseMatrix.h:789
Scalar * m_values
Definition: BlockSparseMatrix.h:874
Index innerBlocks() const
Definition: BlockSparseMatrix.h:712
Matrix< RealScalar, _BlockAtCompileTime, _BlockAtCompileTime, IsColMajor ? ColMajor :RowMajor > BlockRealScalar
Definition: BlockSparseMatrix.h:274
void reserve(const Index nonzerosblocks)
Allocate the internal array of pointers to blocks and their inner indices.
Definition: BlockSparseMatrix.h:550
BlockSparseMatrix()
Definition: BlockSparseMatrix.h:280
Index outerToBlock(Index outer) const
Definition: BlockSparseMatrix.h:715
Map< const BlockScalar > coeff(Index brow, Index bcol) const
Definition: BlockSparseMatrix.h:759
Index blockOuterIndex(Index bj) const
Definition: BlockSparseMatrix.h:806
Index blockRowsIndex(Index bi) const
Definition: BlockSparseMatrix.h:799
Index cols() const
Definition: BlockSparseMatrix.h:688
StorageIndex * m_outerOffset
Definition: BlockSparseMatrix.h:871
BlockSparseMatrix(const MatrixType &spmat)
Constructor from a sparse matrix.
Definition: BlockSparseMatrix.h:366
Index rows() const
Definition: BlockSparseMatrix.h:680
StorageIndex_ StorageIndex
Definition: BlockSparseMatrix.h:256
Index innerSize() const
Definition: BlockSparseMatrix.h:693
void setFromTriplets(const InputIterator &begin, const InputIterator &end)
Fill values in a matrix from a triplet list.
Definition: BlockSparseMatrix.h:580
void setBlockLayout(const VectorXi &rowBlocks, const VectorXi &colBlocks)
Set the row and column block layouts,.
Definition: BlockSparseMatrix.h:520
Ref< BlockScalar > coeffRef(Index brow, Index bcol)
Definition: BlockSparseMatrix.h:738
NumTraits< Scalar >::Real RealScalar
Definition: BlockSparseMatrix.h:255
StorageIndex * m_blockPtr
Definition: BlockSparseMatrix.h:875
Index m_nonzerosblocks
Definition: BlockSparseMatrix.h:872
Index nonZeros() const
Definition: BlockSparseMatrix.h:785
@ IsColMajor
Definition: BlockSparseMatrix.h:270
@ MaxColsAtCompileTime
Definition: BlockSparseMatrix.h:268
@ RowsAtCompileTime
Definition: BlockSparseMatrix.h:265
@ IsVectorAtCompileTime
Definition: BlockSparseMatrix.h:269
@ BlockSize
Definition: BlockSparseMatrix.h:264
@ ColsAtCompileTime
Definition: BlockSparseMatrix.h:266
@ MaxRowsAtCompileTime
Definition: BlockSparseMatrix.h:267
@ Options
Definition: BlockSparseMatrix.h:262
StorageIndex * m_innerOffset
Definition: BlockSparseMatrix.h:870
Index blockInnerSize(Index bi) const
Definition: BlockSparseMatrix.h:814
BlockSparseMatrix(const BlockSparseMatrix &other)
Copy-constructor.
Definition: BlockSparseMatrix.h:311
StorageIndex * outerIndexPtr()
Definition: BlockSparseMatrix.h:791
StorageIndex * m_outerIndex
Definition: BlockSparseMatrix.h:878
Index blockRows() const
Definition: BlockSparseMatrix.h:707
Index blockOuterSize(Index bj) const
Definition: BlockSparseMatrix.h:817
void resize(Index brow, Index bcol)
Set the number of rows and columns blocks.
Definition: BlockSparseMatrix.h:499
~BlockSparseMatrix()
Definition: BlockSparseMatrix.h:352
const StorageIndex * innerIndexPtr() const
Definition: BlockSparseMatrix.h:790
Scalar_ Scalar
Definition: BlockSparseMatrix.h:254
friend void swap(BlockSparseMatrix &first, BlockSparseMatrix &second)
Definition: BlockSparseMatrix.h:331
std::conditional_t< _BlockAtCompileTime==Dynamic, Scalar, BlockScalar > BlockScalarReturnType
Definition: BlockSparseMatrix.h:275
Index outerBlocks() const
Definition: BlockSparseMatrix.h:711
BlockSparseMatrix< Scalar, BlockSize, IsColMajor ? ColMajor :RowMajor, StorageIndex > PlainObject
Definition: BlockSparseMatrix.h:276
Index m_nonzeros
Definition: BlockSparseMatrix.h:873
bool isCompressed() const
for compatibility purposes with the SparseMatrix class
Definition: BlockSparseMatrix.h:795
BlockSparseTimeDenseProduct< BlockSparseMatrix, VecType > operator*(const VecType &lhs) const
Definition: BlockSparseMatrix.h:778
BlockScalarReturnType * valuePtr()
Definition: BlockSparseMatrix.h:787
Index blockColsIndex(Index bj) const
Definition: BlockSparseMatrix.h:804
Index nonZerosBlocks() const
Definition: BlockSparseMatrix.h:783
void setBlockSize(Index blockSize)
set the block size at runtime for fixed-size block layout
Definition: BlockSparseMatrix.h:509
Index m_outerBSize
Definition: BlockSparseMatrix.h:869
Map< BlockScalar > insert(Index brow, Index bcol)
Definition: BlockSparseMatrix.h:233
BlockSparseTimeDenseProduct & operator=(const BlockSparseTimeDenseProduct &)
void scaleAndAddTo(Dest &dest, const typename Rhs::Scalar &alpha) const
Definition: BlockSparseMatrix.h:240
Definition: BlockSparseMatrix.h:180
Ref< Matrix< typename VectorType::Scalar, RowsAtCompileTime, ColsAtCompileTime > > Scalar
Definition: BlockSparseMatrix.h:187
Scalar coeffRef(Index bi)
Definition: BlockSparseMatrix.h:193
BlockSparseMatrixT::Index Index
Definition: BlockSparseMatrix.h:188
BlockVectorReturn(const BlockSparseMatrixT &spblockmat, VectorType &vec)
Definition: BlockSparseMatrix.h:191
@ ColsAtCompileTime
Definition: BlockSparseMatrix.h:183
@ RowsAtCompileTime
Definition: BlockSparseMatrix.h:184
const BlockSparseMatrixT & m_spblockmat
Definition: BlockSparseMatrix.h:205
VectorType & m_vec
Definition: BlockSparseMatrix.h:206
Index size() const
Definition: BlockSparseMatrix.h:192
Scalar coeffRef(Index bi, Index j)
Definition: BlockSparseMatrix.h:198
Definition: BlockSparseMatrix.h:142
BlockVectorView(const BlockSparseMatrixT &spblockmat, const VectorType &vec)
Definition: BlockSparseMatrix.h:156
Index size() const
Definition: BlockSparseMatrix.h:158
Ref< const Matrix< typename BlockSparseMatrixT::Scalar,(RowsAtCompileTime==1) ? 1 :BlockSize,(ColsAtCompileTime==1) ? 1 :BlockSize > > Scalar
Definition: BlockSparseMatrix.h:152
BlockSparseMatrixT::Index Index
Definition: BlockSparseMatrix.h:153
Index cols() const
Definition: BlockSparseMatrix.h:157
const BlockSparseMatrixT & m_spblockmat
Definition: BlockSparseMatrix.h:171
Scalar coeff(Index bi) const
Definition: BlockSparseMatrix.h:159
@ ColsAtCompileTime
Definition: BlockSparseMatrix.h:146
@ BlockSize
Definition: BlockSparseMatrix.h:145
@ RowsAtCompileTime
Definition: BlockSparseMatrix.h:147
const VectorType & m_vec
Definition: BlockSparseMatrix.h:172
Scalar coeff(Index bi, Index j) const
Definition: BlockSparseMatrix.h:164
An InnerIterator allows to loop over the element of any matrix expression.
Definition: CoreIterators.h:37
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:96
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186
A matrix or vector expression mapping an existing expression.
Definition: Ref.h:264
Base class of any sparse matrices or sparse expressions.
Definition: SparseMatrixBase.h:30
static constexpr lastp1_t end
Definition: IndexedViewHelper.h:79
const unsigned int LvalueBit
Definition: Constants.h:148
const unsigned int RowMajorBit
Definition: Constants.h:70
RealScalar s
Definition: level1_cplx_impl.h:130
RealScalar alpha
Definition: level1_cplx_impl.h:151
EIGEN_BLAS_FUNC() swap(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Definition: level1_impl.h:117
EIGEN_BLAS_FUNC() copy(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Definition: level1_impl.h:32
const Scalar * a
Definition: level2_cplx_impl.h:32
int * m
Definition: level2_cplx_impl.h:294
@ Lhs
Definition: TensorContractionMapper.h:20
@ Rhs
Definition: TensorContractionMapper.h:20
void sparse_time_dense_product(const SparseLhsType &lhs, const DenseRhsType &rhs, DenseResType &res, const AlphaType &alpha)
Definition: SparseDenseProduct.h:165
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
const unsigned int NestByRefBit
Definition: Constants.h:173
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
const int InnerRandomAccessPattern
Definition: SparseUtil.h:42
const int Dynamic
Definition: Constants.h:25
Extend namespace for flags.
Definition: fsi_chan_precond_driver.cc:56
const unsigned nz
Definition: ConstraintElementsUnitTest.cpp:32
type
Definition: compute_granudrum_aor.py:141
Definition: Eigen_Colamd.h:49
Definition: Constants.h:519
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:43
Definition: Constants.h:534
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:217
Definition: Constants.h:522
Definition: BlockSparseMatrix.h:93
bool operator()(const Triplet &a, const Triplet &b)
Definition: BlockSparseMatrix.h:95
Iterator::value_type Triplet
Definition: BlockSparseMatrix.h:94
Definition: XprHelper.h:506
Ref< Matrix< typename BlockSparseMatrixT::RealScalar, BlockSparseMatrixT::BlockSize, BlockSparseMatrixT::BlockSize > > RealScalar
Definition: BlockSparseMatrix.h:88
Ref< Matrix< typename BlockSparseMatrixT::Scalar, BlockSparseMatrixT::BlockSize, BlockSparseMatrixT::BlockSize > > Scalar
Definition: BlockSparseMatrix.h:85
BlockSparseMatrixT::Index Index
Definition: BlockSparseMatrix.h:220
BlockSparseMatrixT::Scalar Scalar
Definition: BlockSparseMatrix.h:219
Definition: ForwardDeclarations.h:21
Definition: fft_test_shared.h:66
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2