template< class T , class const_iterator > size_t SparseMatrixInterface< T , const_iterator >::entries( void ) const { size_t entries = 0; for( size_t i=0 ; i double SparseMatrixInterface< T , const_iterator >::squareNorm( void ) const { double n=0; for( size_t i=0 ; iValue * iter->Value; } return n; } template< class T , class const_iterator > double SparseMatrixInterface< T , const_iterator >::squareASymmetricNorm( void ) const { double n=0; for( size_t i=0 ; iN; const_iterator e = end( j ); double value = 0; for( const_iterator iter2 = begin( j ) ; iter2!=e ; iter2++ ) { int k = iter2->N; if( k==i ) value += iter2->Value; } n += (iter1->Value-value) * (iter1->Value-value); } } return n; } template< class T , class const_iterator > double SparseMatrixInterface< T , const_iterator >::squareASymmetricNorm( int& idx1 , int& idx2 ) const { double n=0; double max=0; for( size_t i=0 ; iN; const_iterator e = end( j ); double value = 0; for( const_iterator iter2 = begin( j ) ; iter2!=e ; iter2++ ) { int k = iter2->N; if( k==i ) value += iter2->Value; } double temp = (iter->Value-value) * (iter->Value-value); n += temp; if( temp>=max ) idx1 = i , idx2 = j , max=temp; } } return n; } template< class T , class const_iterator > template< class T2 > void SparseMatrixInterface< T , const_iterator >::multiply( ConstPointer( T2 ) In , Pointer( T2 ) Out , int multiplyFlag ) const { ConstPointer( T2 ) in = In; #pragma omp parallel for for( int i=0 ; iN ] * iter->Value ); if( multiplyFlag & MULTIPLY_NEGATE ) temp = -temp; if( multiplyFlag & MULTIPLY_ADD ) Out[i] += temp; else Out[i] = temp; } } template< class T , class const_iterator > template< class T2 > void SparseMatrixInterface< T , const_iterator >::multiplyScaled( T scale , ConstPointer( T2 ) In , Pointer( T2 ) Out , int multiplyFlag ) const { ConstPointer( T2 ) in = In; #pragma omp parallel for for( int i=0 ; iN ] * iter->Value; temp *= scale; if( multiplyFlag & MULTIPLY_NEGATE ) temp = -temp; if( multiplyFlag & MULTIPLY_ADD ) Out[i] += temp; else Out[i] = temp; } } template< class T , class const_iterator > void SparseMatrixInterface< T , const_iterator >::setDiagonal( Pointer( T ) diagonal ) const { #pragma omp parallel for for( int i=0 ; iN==i ) diagonal[i] += iter->Value; } } template< class T , class const_iterator > void SparseMatrixInterface< T , const_iterator >::setDiagonalR( Pointer( T ) diagonal ) const { #pragma omp parallel for for( int i=0 ; iN==i ) diagonal[i] += iter->Value; if( diagonal[i] ) diagonal[i] = (T)( 1./diagonal[i] ); } } template< class T , class const_iterator > template< class T2 > void SparseMatrixInterface< T , const_iterator >::jacobiIteration( ConstPointer( T ) diagonal , ConstPointer( T2 ) b , ConstPointer( T2 ) in , Pointer( T2 ) out , bool dReciprocal ) const { multiply( in , out ); if( dReciprocal ) #pragma omp parallel for for( int i=0 ; i template< class T2 > void SparseMatrixInterface< T , const_iterator >::gsIteration( ConstPointer( T ) diagonal , ConstPointer( T2 ) b , Pointer( T2 ) x , bool forward , bool dReciprocal ) const { if( dReciprocal ) { #define ITERATE( j ) \ { \ T2 _b = b[j]; \ const_iterator e = end( j ); \ for( const_iterator iter = begin( j ) ; iter!=e ; iter++ ) _b -= x[iter->N] * iter->Value; \ x[j] += _b * diagonal[j]; \ } if( forward ) for( int j=0 ; j=0 ; j-- ){ ITERATE( j ); } #undef ITERATE } else { #define ITERATE( j ) \ { \ T2 _b = b[j]; \ const_iterator e = end( j ); \ for( const_iterator iter = begin( j ) ; iter!=e ; iter++ ) _b -= x[iter->N] * iter->Value; \ x[j] += _b / diagonal[j]; \ } if( forward ) for( int j=0 ; j=0 ; j-- ){ ITERATE( j ); } #undef ITERATE } } template< class T , class const_iterator > template< class T2 > void SparseMatrixInterface< T , const_iterator >::gsIteration( const std::vector< int >& multiColorIndices , ConstPointer( T ) diagonal , ConstPointer( T2 ) b , Pointer( T2 ) x , bool dReciprocal ) const { if( dReciprocal ) #pragma omp parallel for for( int j=0 ; j<(int)multiColorIndices.size() ; j++ ) { int jj = multiColorIndices[j]; T2 _b = b[jj]; const_iterator e = end( jj ); for( const_iterator iter = begin( jj ) ; iter!=e ; iter++ ) _b -= x[iter->N] * iter->Value; x[jj] += _b * diagonal[jj]; } else #pragma omp parallel for for( int j=0 ; j<(int)multiColorIndices.size() ; j++ ) { int jj = multiColorIndices[j]; T2 _b = b[jj]; const_iterator e = end( jj ); for( const_iterator iter = begin( jj ) ; iter!=e ; iter++ ) _b -= x[iter->N] * iter->Value; x[jj] += _b / diagonal[jj]; } } template< class T , class const_iterator > template< class T2 > void SparseMatrixInterface< T , const_iterator >::gsIteration( const std::vector< std::vector< int > >& multiColorIndices , ConstPointer( T ) diagonal , ConstPointer( T2 ) b , Pointer( T2 ) x , bool forward , bool dReciprocal ) const { #ifdef _WIN32 #define SetOMPParallel __pragma( omp parallel for ) #else // !_WIN32 #define SetOMPParallel _Pragma( "omp parallel for" ) #endif // _WIN32 if( dReciprocal ) { #define ITERATE( indices ) \ { \ SetOMPParallel \ for( int k=0 ; kN] * iter->Value; \ x[jj] += _b * diagonal[jj]; \ } \ } if( forward ) for( int j=0 ; j=0 ; j-- ){ ITERATE( multiColorIndices[j] ); } #undef ITERATE } else { #define ITERATE( indices ) \ { \ SetOMPParallel \ for( int k=0 ; kN] * iter->Value; \ x[jj] += _b / diagonal[jj]; \ } \ } if( forward ) for( int j=0 ; j=0 ; j-- ){ ITERATE( multiColorIndices[j] ); } #undef ITERATE } #undef SetOMPParallel } template< class SPDFunctor , class T , typename Real , class TDotTFunctor > int SolveCG( const SPDFunctor& M , int dim , ConstPointer( T ) b , int iters , Pointer( T ) x , double eps , TDotTFunctor Dot ) { eps *= eps; Pointer( T ) r = AllocPointer< T >( dim ); Pointer( T ) d = AllocPointer< T >( dim ); Pointer( T ) q = AllocPointer< T >( dim ); Real delta_new = 0 , delta_0; M( ( ConstPointer( T ) )x , r ); #pragma omp parallel for reduction( + : delta_new ) for( int i=0 ; ieps*delta_0 ; ii++ ) { M( ( ConstPointer( T ) )d , q ); Real dDotQ = 0; #pragma omp parallel for reduction( + : dDotQ ) for( int i=0 ; i int SolveCG( const SPDFunctor& M , const Preconditioner& P , int dim , ConstPointer( T ) b , int iters , Pointer( T ) x , double eps , TDotTFunctor Dot ) { eps *= eps; Pointer( T ) r = AllocPointer< T >( dim ); Pointer( T ) d = AllocPointer< T >( dim ); Pointer( T ) q = AllocPointer< T >( dim ); Pointer( T ) Pb = AllocPointer< T >( dim ); Pointer( T ) temp = AllocPointer< T >( dim ); auto PM = [&] ( ConstPointer(T) x , Pointer(T) y ) { M( x , temp ); P( ( ConstPointer(T) )temp , y ); }; Real delta_new = 0 , delta_0; P( b , Pb ); PM( ( ConstPointer( T ) )x , r ); #pragma omp parallel for reduction( + : delta_new ) for( int i=0 ; ieps*delta_0 ; ii++ ) { PM( ( ConstPointer( T ) )d , q ); Real dDotQ = 0; #pragma omp parallel for reduction( + : dDotQ ) for( int i=0 ; i