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