Пример #1
0
  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';
      }
  }
Пример #2
0
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);
	    }
	}
    }
Пример #3
0
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;
}
Пример #4
0
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);
    }
}
Пример #5
0
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);
}
Пример #6
0
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;
}
Пример #7
0
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);
}
Пример #8
0
    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;
    }
Пример #9
0
        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;
        }
Пример #10
0
    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);
    }
Пример #11
0
csr_row_input_iterator CompressedFormat_Impl::row_end(index_t row) const
{
    return row_begin(row).set_end();
}