示例#1
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;
    }
示例#2
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;
    }