void CompCol_ICPreconditioner :: qsortRow(IntArray &src, FloatArray &val, int l, int r) { if ( r <= l ) { return; } int i = qsortRowPartition(src, val, l, r); qsortRow(src, val, l, i - 1); qsortRow(src, val, i + 1, r); }
void CompCol_ILUPreconditioner :: initialize(const DynCompCol &A) { int i, j, k, pn, qn, rn; double multiplier; // Copy dim_ [ 0 ] = A.giveNumberOfRows(); dim_ [ 1 ] = A.giveNumberOfColumns(); l_colptr_.resize(A.giveNumberOfColumns() + 1); u_colptr_.resize(A.giveNumberOfColumns() + 1); l_nz_ = 0; u_nz_ = 0; #ifndef DynCompCol_USE_STL_SETS // Get size of l and u for ( i = 0; i < dim_ [ 1 ]; i++ ) { for ( j = 0; j < A.row_ind(i)->giveSize(); j++ ) { if ( A.row_ind(i)->at(j + 1) > i ) { l_nz_++; } else { u_nz_++; } } } l_val_.resize(l_nz_); u_val_.resize(u_nz_); l_rowind_.resize(l_nz_); u_rowind_.resize(u_nz_); l_colptr_(0) = u_colptr_(0) = 0; // Split up A into l and u for ( i = 0; i < dim_ [ 1 ]; i++ ) { l_colptr_(i + 1) = l_colptr_(i); u_colptr_(i + 1) = u_colptr_(i); for ( j = 0; j < A.row_ind(i)->giveSize(); j++ ) { if ( A.row_ind(i)->at(j + 1) > i ) { k = l_colptr_(i + 1)++; l_val_(k) = A.column(i)->at(j + 1); l_rowind_(k) = A.row_ind(i)->at(j + 1); } else if ( A.row_ind(i)->at(j + 1) <= i ) { k = u_colptr_(i + 1)++; u_val_(k) = A.column(i)->at(j + 1); u_rowind_(k) = A.row_ind(i)->at(j + 1); } } } #else std :: map< int, double > :: iterator pos; // Get size of l and u for ( i = 0; i < dim_ [ 1 ]; i++ ) { for ( pos = A.column(i)->begin(); pos != A.column(i)->end(); ++pos ) { if ( pos->first > i ) { l_nz_++; } else { u_nz_++; } } } l_val_.resize(l_nz_); u_val_.resize(u_nz_); l_rowind_.resize(l_nz_); u_rowind_.resize(u_nz_); l_colptr_(0) = u_colptr_(0) = 0; // Split up A into l and u for ( i = 0; i < dim_ [ 1 ]; i++ ) { l_colptr_(i + 1) = l_colptr_(i); u_colptr_(i + 1) = u_colptr_(i); for ( pos = A.column(i)->begin(); pos != A.column(i)->end(); ++pos ) { if ( pos->first > i ) { k = l_colptr_(i + 1)++; l_val_(k) = pos->second; l_rowind_(k) = pos->first; } else if ( pos->first <= i ) { k = u_colptr_(i + 1)++; u_val_(k) = pos->second; u_rowind_(k) = pos->first; } } } #endif /* sort entries to assure entries stored with increasing row index */ for ( i = 0; i < dim_ [ 1 ]; i++ ) { qsortRow(l_rowind_, l_val_, l_colptr_(i), l_colptr_(i + 1) - 1); qsortRow(u_rowind_, u_val_, u_colptr_(i), u_colptr_(i + 1) - 1); } // Factor matrix for ( i = 0; i < dim_ [ 0 ] - 1; i++ ) { multiplier = u_val_(u_colptr_(i + 1) - 1); for ( j = l_colptr_(i); j < l_colptr_(i + 1); j++ ) { l_val_(j) /= multiplier; } for ( j = u_colptr_(i + 1); j < u_colptr_(i + 2) - 1; j++ ) { multiplier = u_val_(j); qn = j + 1; rn = l_colptr_(i + 1); for ( pn = l_colptr_( u_rowind_(j) ); pn < l_colptr_(u_rowind_(j) + 1) && l_rowind_(pn) <= i + 1; pn++ ) { while ( qn < u_colptr_(i + 2) && u_rowind_(qn) < l_rowind_(pn) ) { qn++; } if ( qn < u_colptr_(i + 2) && l_rowind_(pn) == u_rowind_(qn) ) { u_val_(qn) -= multiplier * l_val_(pn); } } for ( ; pn < l_colptr_(u_rowind_(j) + 1); pn++ ) { while ( rn < l_colptr_(i + 2) && l_rowind_(rn) < l_rowind_(pn) ) { rn++; } if ( rn < l_colptr_(i + 2) && l_rowind_(pn) == l_rowind_(rn) ) { l_val_(rn) -= multiplier * l_val_(pn); } } } } }