| 91 | |
| 92 | template <typename SparseMatrixType, int BlockRows, int BlockCols> |
| 93 | class sparse_matrix_block_impl : public SparseCompressedBase<Block<SparseMatrixType, BlockRows, BlockCols, true> > { |
| 94 | typedef internal::remove_all_t<typename SparseMatrixType::Nested> MatrixTypeNested_; |
| 95 | typedef Block<SparseMatrixType, BlockRows, BlockCols, true> BlockType; |
| 96 | typedef SparseCompressedBase<Block<SparseMatrixType, BlockRows, BlockCols, true> > Base; |
| 97 | using Base::convert_index; |
| 98 | |
| 99 | public: |
| 100 | enum { IsRowMajor = internal::traits<BlockType>::IsRowMajor }; |
| 101 | EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType) |
| 102 | protected: |
| 103 | typedef typename Base::IndexVector IndexVector; |
| 104 | enum { OuterSize = IsRowMajor ? BlockRows : BlockCols }; |
| 105 | |
| 106 | public: |
| 107 | inline sparse_matrix_block_impl(SparseMatrixType& xpr, Index i) |
| 108 | : m_matrix(xpr), m_outerStart(convert_index(i)), m_outerSize(OuterSize) {} |
| 109 | |
| 110 | inline sparse_matrix_block_impl(SparseMatrixType& xpr, Index startRow, Index startCol, Index blockRows, |
| 111 | Index blockCols) |
| 112 | : m_matrix(xpr), |
| 113 | m_outerStart(convert_index(IsRowMajor ? startRow : startCol)), |
| 114 | m_outerSize(convert_index(IsRowMajor ? blockRows : blockCols)) {} |
| 115 | |
| 116 | template <typename OtherDerived> |
| 117 | inline BlockType& operator=(const SparseMatrixBase<OtherDerived>& other) { |
| 118 | typedef internal::remove_all_t<typename SparseMatrixType::Nested> NestedMatrixType_; |
| 119 | NestedMatrixType_& matrix = m_matrix; |
| 120 | // This assignment is slow if this vector set is not empty |
| 121 | // and/or it is not at the end of the nonzeros of the underlying matrix. |
| 122 | |
| 123 | // 1 - eval to a temporary to avoid transposition and/or aliasing issues |
| 124 | Ref<const SparseMatrix<Scalar, IsRowMajor ? RowMajor : ColMajor, StorageIndex> > tmp(other.derived()); |
| 125 | eigen_internal_assert(tmp.outerSize() == m_outerSize.value()); |
| 126 | |
| 127 | // 2 - let's check whether there is enough allocated memory |
| 128 | Index nnz = tmp.nonZeros(); |
| 129 | Index start = |
| 130 | m_outerStart == 0 ? 0 : m_matrix.outerIndexPtr()[m_outerStart]; // starting position of the current block |
| 131 | Index end = m_matrix.outerIndexPtr()[m_outerStart + m_outerSize.value()]; // ending position of the current block |
| 132 | Index block_size = end - start; // available room in the current block |
| 133 | Index tail_size = m_matrix.outerIndexPtr()[m_matrix.outerSize()] - end; |
| 134 | |
| 135 | Index free_size = m_matrix.isCompressed() ? Index(matrix.data().allocatedSize()) + block_size : block_size; |
| 136 | |
| 137 | Index tmp_start = tmp.outerIndexPtr()[0]; |
| 138 | |
| 139 | bool update_trailing_pointers = false; |
| 140 | if (nnz > free_size) { |
| 141 | // realloc manually to reduce copies |
| 142 | typename SparseMatrixType::Storage newdata(m_matrix.data().allocatedSize() - block_size + nnz); |
| 143 | |
| 144 | internal::smart_copy(m_matrix.valuePtr(), m_matrix.valuePtr() + start, newdata.valuePtr()); |
| 145 | internal::smart_copy(m_matrix.innerIndexPtr(), m_matrix.innerIndexPtr() + start, newdata.indexPtr()); |
| 146 | |
| 147 | internal::smart_copy(tmp.valuePtr() + tmp_start, tmp.valuePtr() + tmp_start + nnz, newdata.valuePtr() + start); |
| 148 | internal::smart_copy(tmp.innerIndexPtr() + tmp_start, tmp.innerIndexPtr() + tmp_start + nnz, |
| 149 | newdata.indexPtr() + start); |
| 150 |
nothing calls this directly
no test coverage detected