Пример #1
0
    VectorType solve(const MatrixType & matrix, VectorType const & rhs, cg_tag const & tag, PreconditionerType const & precond)
    {
      typedef typename viennacl::result_of::value_type<VectorType>::type        ScalarType;
      typedef typename viennacl::result_of::cpu_value_type<ScalarType>::type    CPU_ScalarType;
      unsigned int problem_size = viennacl::traits::size(rhs);

      VectorType result(problem_size);
      viennacl::traits::clear(result);

      VectorType residual = rhs;
      VectorType tmp(problem_size);
      VectorType z = rhs;

      precond.apply(z);
      VectorType p = z;

      CPU_ScalarType ip_rr = viennacl::linalg::inner_prod(residual, z);
      CPU_ScalarType alpha;
      CPU_ScalarType new_ip_rr = 0;
      CPU_ScalarType beta;
      CPU_ScalarType norm_rhs_squared = ip_rr;
      CPU_ScalarType new_ipp_rr_over_norm_rhs;

      if (norm_rhs_squared == 0) //solution is zero if RHS norm is zero
        return result;

      for (unsigned int i = 0; i < tag.max_iterations(); ++i)
      {
        tag.iters(i+1);
        tmp = viennacl::linalg::prod(matrix, p);

        alpha = ip_rr / viennacl::linalg::inner_prod(tmp, p);

        result += alpha * p;
        residual -= alpha * tmp;
        z = residual;
        precond.apply(z);

        new_ip_rr = viennacl::linalg::inner_prod(residual, z);
        new_ipp_rr_over_norm_rhs = new_ip_rr / norm_rhs_squared;
        if (std::fabs(new_ipp_rr_over_norm_rhs) < tag.tolerance() *  tag.tolerance())    //squared norms involved here
          break;

        beta = new_ip_rr / ip_rr;
        ip_rr = new_ip_rr;

        p = z + beta*p;
      }

      //store last error estimate:
      tag.error(std::sqrt(std::fabs(new_ip_rr / norm_rhs_squared)));

      return result;
    }
Пример #2
0
    VectorType solve(const MatrixType & matrix, VectorType const & rhs, cg_tag const & tag)
    {
      //typedef typename VectorType::value_type      ScalarType;
      typedef typename viennacl::result_of::value_type<VectorType>::type        ScalarType;
      typedef typename viennacl::result_of::cpu_value_type<ScalarType>::type    CPU_ScalarType;
      //std::cout << "Starting CG" << std::endl;
      std::size_t problem_size = viennacl::traits::size(rhs);
      VectorType result(problem_size);
      viennacl::traits::clear(result);

      VectorType residual = rhs;
      VectorType p = rhs;
      VectorType tmp(problem_size);

      CPU_ScalarType ip_rr = viennacl::linalg::inner_prod(rhs,rhs);
      CPU_ScalarType alpha;
      CPU_ScalarType new_ip_rr = 0;
      CPU_ScalarType beta;
      CPU_ScalarType norm_rhs = std::sqrt(ip_rr);

      //std::cout << "Starting CG solver iterations... " << std::endl;
      if (norm_rhs == 0) //solution is zero if RHS norm is zero
        return result;

      for (unsigned int i = 0; i < tag.max_iterations(); ++i)
      {
        tag.iters(i+1);
        tmp = viennacl::linalg::prod(matrix, p);

        alpha = ip_rr / viennacl::linalg::inner_prod(tmp, p);
        result += alpha * p;
        residual -= alpha * tmp;

        new_ip_rr = viennacl::linalg::norm_2(residual);
        if (new_ip_rr / norm_rhs < tag.tolerance())
          break;
        new_ip_rr *= new_ip_rr;

        beta = new_ip_rr / ip_rr;
        ip_rr = new_ip_rr;

        p = residual + beta * p;
      }

      //store last error estimate:
      tag.error(std::sqrt(new_ip_rr) / norm_rhs);

      return result;
    }
Пример #3
0
    VectorType solve(const MatrixType & matrix, VectorType const & rhs, cg_tag const & tag, PreconditionerType const & precond)
    {
      typedef typename VectorType::value_type      ScalarType;
      typedef typename viennacl::tools::CPU_SCALAR_TYPE_DEDUCER<ScalarType>::ResultType    CPU_ScalarType;
      
      VectorType result(rhs.size());
      result.clear();
      
      VectorType residual = rhs;
      VectorType tmp(rhs.size());
      VectorType z = rhs;

      precond.apply(z);
      VectorType p = z;

      ScalarType ip_rr = viennacl::linalg::inner_prod(residual, z);
      ScalarType alpha;
      ScalarType new_ip_rr = 0;
      ScalarType beta;
      ScalarType norm_rhs = ip_rr;
      
      for (unsigned int i = 0; i < tag.iterations(); ++i)
      {
        tag.iters(i+1);
        tmp = viennacl::linalg::prod(matrix, p);
        alpha = ip_rr / viennacl::linalg::inner_prod(tmp, p);
        result += alpha * p;
        residual -= alpha * tmp;
        z = residual;
        precond.apply(z);
        
        new_ip_rr = viennacl::linalg::inner_prod(residual, z);
        if (std::fabs(new_ip_rr / norm_rhs) < tag.tolerance() *  tag.tolerance())    //squared norms involved here
          break;
        
        beta = new_ip_rr / ip_rr;
        ip_rr = new_ip_rr;
        p = z + beta*p;
      } 

      //store last error estimate:
      tag.error(sqrt(std::fabs(new_ip_rr / norm_rhs)));

      return result;
    }
Пример #4
0
    VectorType solve(const MatrixType & matrix, VectorType const & rhs, cg_tag const & tag)
    {
      typedef typename VectorType::value_type      ScalarType;
      VectorType result(rhs.size());
      result.clear();

      VectorType residual = rhs;
      VectorType p = rhs;
      VectorType tmp(rhs.size());

      ScalarType ip_rr = viennacl::linalg::inner_prod(rhs,rhs);
      ScalarType alpha;
      ScalarType new_ip_rr = 0;
      ScalarType beta;
      ScalarType norm_rhs = ip_rr;
      
      //std::cout << "Starting CG solver... " << std::endl;
      
      for (unsigned int i = 0; i < tag.iterations(); ++i)
      {
        tag.iters(i+1);
        tmp = viennacl::linalg::prod(matrix, p);

        alpha = ip_rr / viennacl::linalg::inner_prod(tmp, p);
        result += alpha * p;
        residual -= alpha * tmp;
        
        new_ip_rr = viennacl::linalg::inner_prod(residual,residual);
        if (new_ip_rr / norm_rhs < tag.tolerance() *  tag.tolerance())//squared norms involved here
          break;
        
        beta = new_ip_rr / ip_rr;
        ip_rr = new_ip_rr;

        p = residual + beta*p;
      } 
      
      //store last error estimate:
      tag.error(sqrt(new_ip_rr / norm_rhs));
      
      return result;
    }