12 #ifndef BOGUS_EIGEN_SPARSE_CONVERSIONS_HPP
13 #define BOGUS_EIGEN_SPARSE_CONVERSIONS_HPP
15 #include "SparseHeader.hpp"
17 #include "../Block/SparseBlockMatrix.hpp"
18 #include "../Block/Access.hpp"
19 #include "../Block/SparseBlockIndexComputer.hpp"
27 template<
typename EigenDerived,
typename BogusDerived >
28 void convert(
const Eigen::SparseMatrixBase< EigenDerived >& source,
29 SparseBlockMatrixBase< BogusDerived >& dest,
30 int destRowsPerBlock = 0,
int destColsPerBlock = 0
33 typedef BlockMatrixTraits< BogusDerived > Traits ;
34 typedef typename Traits::Index Index ;
35 typedef typename Traits::BlockPtr BlockPtr ;
37 const Index RowsPerBlock = destRowsPerBlock
38 ? (Index) destRowsPerBlock
39 : (Index) Traits::RowsPerBlock ;
40 const Index ColsPerBlock = destColsPerBlock
41 ? (Index) destColsPerBlock
42 : (Index) Traits::ColsPerBlock ;
44 assert( RowsPerBlock != (Index) -1 ) ;
45 assert( ColsPerBlock != (Index) -1 ) ;
48 ( ( (
bool) Eigen::SparseMatrixBase< EigenDerived >::IsRowMajor )
49 ^ ( (
bool) Traits::is_col_major ) ),
50 MATRICES_ORDERING_IS_INCONSISTENT ) ;
52 assert( 0 == ( source.rows() % RowsPerBlock ) ) ;
53 assert( 0 == ( source.cols() % ColsPerBlock ) ) ;
56 dest.setRows( source.rows() / RowsPerBlock, RowsPerBlock ) ;
57 dest.setCols( source.cols() / ColsPerBlock, ColsPerBlock ) ;
59 const Index blockSize = Traits::is_col_major ? ColsPerBlock : RowsPerBlock ;
60 for( Index outer = 0 ; outer < dest.majorIndex().outerSize() ; ++outer )
63 std::map < Index, BlockPtr > nzBlocks ;
65 for( Index i = 0 ; i < blockSize ; ++i )
67 for(
typename EigenDerived::InnerIterator innerIt( source.derived(), outer*blockSize + i ) ;
70 const Index blockId = (Index) ( innerIt.index() ) / blockSize ;
71 if( Traits::is_symmetric && blockId > outer ) break ;
72 nzBlocks[ blockId ] = 0 ;
77 for(
typename std::map< Index, BlockPtr >::iterator bIt = nzBlocks.begin() ; bIt != nzBlocks.end() ; ++bIt )
79 bIt->second = (BlockPtr) dest.nBlocks() ;
80 dest.template insertByOuterInner< true >( outer, bIt->first ).setZero( RowsPerBlock, ColsPerBlock ) ;
84 for( Index i = 0 ; i < blockSize ; ++i )
86 for(
typename EigenDerived::InnerIterator innerIt( source.derived(), outer*blockSize + i ) ;
89 const Index blockId = (Index) ( innerIt.index() ) / blockSize ;
90 if( Traits::is_symmetric && blockId > outer ) break ;
91 const Index binn = innerIt.index() - blockId * blockSize ;
92 const Index brow = Traits::is_col_major ? binn : i ;
93 const Index bcol = Traits::is_col_major ? i : binn ;
95 dest.block( nzBlocks[ blockId ] ) ( brow, bcol ) = innerIt.value() ;
100 if( Traits::is_symmetric )
102 typename std::map< Index, BlockPtr >::const_iterator diagPtr = nzBlocks.find( outer ) ;
103 if( diagPtr != nzBlocks.end() )
105 const typename Traits::BlockType diagBlock = dest.block( diagPtr->second ) ;
106 dest.block( diagPtr->second ) = .5 * ( diagBlock + TransposeIf< Traits::is_symmetric >::get( diagBlock ) ) ;
116 template<
typename BogusDerived,
typename EigenScalar,
int EigenOptions,
typename EigenIndex >
117 void convert(
const SparseBlockMatrixBase< BogusDerived >& source,
118 Eigen::SparseMatrix< EigenScalar, EigenOptions, EigenIndex >& dest )
120 typedef BlockMatrixTraits< BogusDerived > Traits ;
121 typedef typename Traits::Index Index ;
123 typedef Eigen::SparseMatrix< EigenScalar, EigenOptions, EigenIndex > EigenMatrixType ;
125 typedef SparseBlockIndexGetter< BogusDerived, Traits::is_symmetric ||
126 ( (bool) EigenMatrixType::IsRowMajor ) != ( (bool) Traits::is_col_major ) > IndexGetter ;
129 dest.resize( source.rows(), source.cols() ) ;
131 typename BogusDerived::UncompressedIndexType auxIndex ;
132 const typename IndexGetter::ReturnType& index = IndexGetter::getOrCompute( source, auxIndex ) ;
134 const std::vector< Index > &outerOffsets =
135 ( (bool) EigenMatrixType::IsRowMajor ) == ( (bool) Traits::is_col_major )
136 ? source.majorIndex().innerOffsets : source.minorIndex().innerOffsets ;
138 for( Index outerBlock = 0 ; outerBlock < index.outerSize() ; ++outerBlock )
140 for( Index outer = outerOffsets[ outerBlock ] ; outer < outerOffsets[ outerBlock+1 ] ; ++outer )
142 dest.startVec( outer ) ;
143 for(
typename IndexGetter::ReturnType::InnerIterator it( index, outerBlock ) ;
146 for( Index inner = index.innerOffsets[ it.inner() ] ; inner < index.innerOffsets[ it.inner()+1 ] ; ++inner )
148 if( Traits::is_symmetric && inner > outer ) break ;
150 const Index bout = outer - outerOffsets[ outerBlock ] ;
151 const Index binn = inner - index.innerOffsets[ it.inner() ] ;
152 const Index bcol = EigenMatrixType::IsRowMajor ? binn : bout ;
153 const Index brow = EigenMatrixType::IsRowMajor ? bout : binn ;
154 const EigenScalar val = source.block( it.ptr() )( brow, bcol ) ;
156 dest.insertBackByOuterInner( outer, inner ) = val;