void print ( std::ostream& o = std::cout ) { const int space = 16; string buffer(space,' '); o << buffer; std::vector< entry_type > entries; for ( typename Types::iterator ii = types.begin(); ii!=types.end(); ++ii ) { o << setw(space) << *ii; entries.push_back( *ii ); } o << '\n'; for ( row_iterator ii=row_begin(); ii!=row_end(); ++ii ) { o << setw(space) << ii->first; unsigned ctr = 0; for ( column_iterator jj=ii->second.begin(); jj!=ii->second.end(); ++jj ) { AGAIN: if ( entries[ctr++] == jj->first ) { o << setw(space) << jj->second; } else { if ( ctr >= entries.size() ) break; else { o << setw(space) << "X"; goto AGAIN; } } } while( ctr++ < entries.size() ) { o << setw(space) << "X"; } o << '\n'; } }
template <> bool Raster<ushort>::write_pgmfile(const std::string& filename,Progress* target) const { ProgressScope progress(height(),"Writing PGM image:\n"+filename,target); std::ofstream out(filename.c_str(),std::ios::binary); out << "P5" << std::endl; out << width() << " " << height() << std::endl; const ushort m=maximum_scalar_pixel_value(); out << m << std::endl; for (ConstRowIterator row=row_begin();row!=row_end();++row) { progress.step(); for (const ushort* it=row->begin();it!=row->end();++it) { const uchar p[2]={uchar((*it)>>8),uchar(*it)}; if (m>=256) { // PGM spec is most significant byte first out.write(reinterpret_cast<const char*>(p),2); } else { assert(p[0]==0); out.write(reinterpret_cast<const char*>(p+1),1); } } }
template <typename T> const typename Raster<T>::ScalarType Raster<T>::maximum_scalar_pixel_value() const { ScalarType m(scalar(*_data)); for (ConstRowIterator row=row_begin();row!=row_end();++row) for (const T* it=row->begin();it!=row->end();++it) { const ScalarType v(scalar(*it)); if (v>m) m=v; } return m; }
template <typename T> void Raster<T>::fill(const T& v) { if (contiguous()) { std::fill(contiguous_begin(),contiguous_end(),v); } else { for (RowIterator row=row_begin();row!=row_end();++row) std::fill((*row).begin(),(*row).end(),v); } }
Matrix<rows, cols, T> Matrix<rows, cols, T>::operator*(const Matrix<rows, cols, T> &rhs) const { Matrix<rows, cols, T> to_return; for (int i = 0; i < rows; ++i) { for (int j = 0; j < cols; ++j) { to_return(i, j) = std::inner_product(row_begin(i), row_end(i), rhs.col_begin(j), T(0)); } } return(to_return); }
template <> bool Raster<uchar>::write_pgmfile(const std::string& filename,Progress* target) const { ProgressScope progress(height(),"Writing PGM image:\n"+filename,target); std::ofstream out(filename.c_str(),std::ios::binary); out << "P5" << std::endl; out << width() << " " << height() << std::endl; out << "255" << std::endl; for (ConstRowIterator row=row_begin();row!=row_end();++row) { progress.step(); out.write(reinterpret_cast<const char*>(&(*(row->begin()))),row->size()); } out.close(); return out; }
Matrix<rows, rhs_cols, T> Matrix<rows, cols, T>::operator*(const Matrix<rhs_rows, rhs_cols, T> &rhs) const { if (cols != rhs_rows) throw(std::domain_error("Matrix sizes do not match up for multiplication.")); Matrix<rows, rhs_cols, T> to_return; for (int i = 0; i < rows; ++i) { for (int j = 0; j < rhs_cols; ++j) { to_return(i, j) = std::inner_product(row_begin(i), row_end(i), rhs.col_begin(j), T(0)); } } return(to_return); }
const complex_matrix_type make_ug( const matrix_type& G, const matrix_type& A, const matrix_type& D ) const { assert( G.col() == 3 ); assert( A.col() == 3 ); assert( D.col() == 1 ); assert( A.row() == D.row() ); auto const M = make_matrix(); auto const S = G * ( M.inverse() ); matrix_type s( 1, S.row() ); for ( size_type i = 0; i < S.row(); ++ i ) { s[0][i] = value_type( 0.5 ) * std::sqrt( std::inner_product( S.row_begin( i ), S.row_end( i ), S.row_begin( i ), value_type( 0 ) ) ); } auto const piomega = 3.141592553590 * feng::inner_product( array_type( M[0][0], M[1][0], M[2][0] ), feng::cross_product( array_type( M[0][1], M[1][1], M[2][1] ), array_type( M[0][2], M[1][2], M[2][2] ) ) ); auto const atomcellfacte = make_gaussian_electron( s, v0 ); const complex_matrix_type dwss = D * feng::pow( s, value_type( 2 ) ); const complex_matrix_type piag = A * G.transpose(); auto fact = feng::exp( - dwss - piag * complex_type( 0, 6.2831853071796 ) ); std::transform( fact.begin(), fact.end(), atomcellfacte.begin(), fact.begin(), [piomega]( const complex_type f, const value_type a ) { return f * a / piomega; } ); complex_matrix_type Ug( fact.col(), 1 ); for ( size_type i = 0; i < fact.col(); ++i ) { Ug[i][0] = std::accumulate( fact.col_begin( i ), fact.col_end( i ), complex_type() ); //if ( std::abs(Ug[i][0].real()) < 1.0e-8 ) Ug[i][0].real(0); //if ( std::abs(Ug[i][0].imag()) < 1.0e-8 ) Ug[i][0].imag(0); } return Ug; }
static std::shared_ptr< backend::crs<Val, Col, Ptr> > interpolation( const AMatrix &A, const std::vector<Val> &Adia, const backend::crs<Val, Col, Ptr> &P_tent, std::vector<Val> &omega ) { const size_t n = rows(P_tent); const size_t nc = cols(P_tent); auto AP = product(A, P_tent, /*sort rows: */true); omega.resize(nc, math::zero<Val>()); std::vector<Val> denum(nc, math::zero<Val>()); #pragma omp parallel { std::vector<ptrdiff_t> marker(nc, -1); // Compute A * Dinv * AP row by row and compute columnwise // scalar products necessary for computation of omega. The // actual results of matrix-matrix product are not stored. std::vector<Col> adap_col(128); std::vector<Val> adap_val(128); #pragma omp for for(ptrdiff_t ia = 0; ia < static_cast<ptrdiff_t>(n); ++ia) { adap_col.clear(); adap_val.clear(); // Form current row of ADAP matrix. for(auto a = A.row_begin(ia); a; ++a) { Col ca = a.col(); Val va = math::inverse(Adia[ca]) * a.value(); for(auto p = AP->row_begin(ca); p; ++p) { Col c = p.col(); Val v = va * p.value(); if (marker[c] < 0) { marker[c] = adap_col.size(); adap_col.push_back(c); adap_val.push_back(v); } else { adap_val[marker[c]] += v; } } } amgcl::detail::sort_row( &adap_col[0], &adap_val[0], adap_col.size() ); // Update columnwise scalar products (AP,ADAP) and (ADAP,ADAP). // 1. (AP, ADAP) for( Ptr ja = AP->ptr[ia], ea = AP->ptr[ia + 1], jb = 0, eb = adap_col.size(); ja < ea && jb < eb; ) { Col ca = AP->col[ja]; Col cb = adap_col[jb]; if (ca < cb) ++ja; else if (cb < ca) ++jb; else /*ca == cb*/ { Val v = AP->val[ja] * adap_val[jb]; #pragma omp critical omega[ca] += v; ++ja; ++jb; } } // 2. (ADAP, ADAP) (and clear marker) for(size_t j = 0, e = adap_col.size(); j < e; ++j) { Col c = adap_col[j]; Val v = adap_val[j]; #pragma omp critical denum[c] += v * v; marker[c] = -1; } } } for(size_t i = 0, m = omega.size(); i < m; ++i) omega[i] = math::inverse(denum[i]) * omega[i]; // Update AP to obtain P: P = (P_tent - D^-1 A P Omega) /* * Here we use the fact that if P(i,j) != 0, * then with necessity AP(i,j) != 0: * * AP(i,j) = sum_k(A_ik P_kj), and A_ii != 0. */ #pragma omp parallel for for(ptrdiff_t i = 0; i < static_cast<ptrdiff_t>(n); ++i) { Val dia = math::inverse(Adia[i]); for(Ptr ja = AP->ptr[i], ea = AP->ptr[i+1], jp = P_tent.ptr[i], ep = P_tent.ptr[i+1]; ja < ea; ++ja ) { Col ca = AP->col[ja]; Val va = -dia * AP->val[ja] * omega[ca]; for(; jp < ep; ++jp) { Col cp = P_tent.col[jp]; if (cp > ca) break; if (cp == ca) { va += P_tent.val[jp]; break; } } AP->val[ja] = va; } } return AP; }
spai1( const Matrix &A, const params &, const typename Backend::params &backend_prm) { typedef typename backend::value_type<Matrix>::type value_type; typedef typename backend::row_iterator<Matrix>::type row_iterator; const size_t n = backend::rows(A); const size_t m = backend::cols(A); const size_t nnz = backend::nonzeros(A); BOOST_AUTO(Aptr, A.ptr_data()); BOOST_AUTO(Acol, A.col_data()); boost::shared_ptr<Matrix> Ainv = boost::make_shared<Matrix>(); Ainv->nrows = n; Ainv->ncols = m; Ainv->ptr.assign(Aptr, Aptr + n+1); Ainv->col.assign(Acol, Acol + nnz); Ainv->val.assign(nnz, math::zero<value_type>()); #pragma omp parallel { #ifdef _OPENMP int nt = omp_get_num_threads(); int tid = omp_get_thread_num(); size_t chunk_size = (n + nt - 1) / nt; size_t chunk_start = tid * chunk_size; size_t chunk_end = std::min(n, chunk_start + chunk_size); #else size_t chunk_start = 0; size_t chunk_end = n; #endif std::vector<ptrdiff_t> marker(m, -1); std::vector<ptrdiff_t> I, J; std::vector<value_type> B, ek; amgcl::detail::QR<value_type> qr; for(size_t i = chunk_start; i < chunk_end; ++i) { ptrdiff_t row_beg = Aptr[i]; ptrdiff_t row_end = Aptr[i + 1]; I.assign(Acol + row_beg, Acol + row_end); J.clear(); for(ptrdiff_t j = row_beg; j < row_end; ++j) { ptrdiff_t c = Acol[j]; for(ptrdiff_t jj = Aptr[c], ee = Aptr[c + 1]; jj < ee; ++jj) { ptrdiff_t cc = Acol[jj]; if (marker[cc] < 0) { marker[cc] = 1; J.push_back(cc); } } } std::sort(J.begin(), J.end()); B.assign(I.size() * J.size(), math::zero<value_type>()); ek.assign(J.size(), math::zero<value_type>()); for(size_t j = 0; j < J.size(); ++j) { marker[J[j]] = j; if (J[j] == static_cast<ptrdiff_t>(i)) ek[j] = math::identity<value_type>(); } for(ptrdiff_t j = row_beg; j < row_end; ++j) { ptrdiff_t c = Acol[j]; for(row_iterator a = row_begin(A, c); a; ++a) B[marker[a.col()] * I.size() + j - row_beg] = a.value(); } qr.compute(J.size(), I.size(), &B[0], /*need Q: */false); qr.solve(&ek[0], &Ainv->val[row_beg]); for(size_t j = 0; j < J.size(); ++j) marker[J[j]] = -1; } } M = Backend::copy_matrix(Ainv, backend_prm); }
csr_row_input_iterator CompressedFormat_Impl::row_end(index_t row) const { return row_begin(row).set_end(); }