Beispiel #1
0
int main(int argc, char **argv)
{
  try {

    const unsigned int d = 2;
    const unsigned int pmin = 2;
    const unsigned int pmax = 10;
    const unsigned int np = pmax-pmin+1;
    bool use_pce_quad_points = false;
    bool normalize = true;
    bool sparse_grid = true;
    bool project_integrals = false;
#ifndef HAVE_STOKHOS_DAKOTA
    sparse_grid = false;
#endif
    Teuchos::Array<double> mean(np), mean_st(np), std_dev(np), std_dev_st(np);
    Teuchos::Array<double> pt(np), pt_st(np);

    Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double> > > bases(d); 
    Teuchos::Array<double> eval_pt(d, 0.5);
    double pt_true;
    
    // Loop over orders
    unsigned int n = 0;
    for (unsigned int p=pmin; p<=pmax; p++) {

      std::cout << "p = " << p << std::endl;
      
      // Create product basis
      for (unsigned int i=0; i<d; i++)
	bases[i] = Teuchos::rcp(new basis_type(p));
      Teuchos::RCP<const Stokhos::CompletePolynomialBasis<int,double> > basis = 
	Teuchos::rcp(new Stokhos::CompletePolynomialBasis<int,double>(bases));
      
      // Create approximation
      Stokhos::OrthogPolyApprox<int,double> x(basis), u(basis), v(basis),
	w(basis), w2(basis);
      for (unsigned int i=0; i<d; i++) {
	x.term(i, 1) = 1.0;
      }

      double x_pt = x.evaluate(eval_pt);
      pt_true = std::exp(std::sin(x_pt));
      
      // Quadrature
      Teuchos::RCP<const Stokhos::Quadrature<int,double> > quad;
#ifdef HAVE_STOKHOS_DAKOTA
      if (sparse_grid)
      	quad = 
	  Teuchos::rcp(new Stokhos::SparseGridQuadrature<int,double>(basis, p));
#endif
      if (!sparse_grid)
	quad = 
	  Teuchos::rcp(new Stokhos::TensorProductQuadrature<int,double>(basis));

      // Triple product tensor
      Teuchos::RCP<Stokhos::Sparse3Tensor<int,double> > Cijk =
	basis->computeTripleProductTensor(basis->size());
      
      // Quadrature expansion
      Stokhos::QuadOrthogPolyExpansion<int,double> quad_exp(basis, Cijk, quad);
      
      // Compute PCE via quadrature expansion
      quad_exp.sin(u,x);
      //quad_exp.times(u,u,10.0);
      quad_exp.exp(w,u);
	
      // Compute Stieltjes basis
      Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double> > > st_bases(1);
      Teuchos::RCP<const Stokhos::LanczosProjPCEBasis<int,double> > st_1d_basis
      	= Teuchos::rcp(new Stokhos::LanczosProjPCEBasis<int,double>(
			 p, Teuchos::rcp(&u,false), Cijk, normalize));
      st_bases[0] = st_1d_basis;
      	
      Teuchos::RCP<const Stokhos::CompletePolynomialBasis<int,double> > 
	st_basis = 
	Teuchos::rcp(new Stokhos::CompletePolynomialBasis<int,double>(st_bases));
      //std::cout << *st_basis << std::endl;

      Stokhos::OrthogPolyApprox<int,double>  u_st(st_basis), w_st(st_basis);
      u_st.term(0, 0) = st_1d_basis->getNewCoeffs(0);
      u_st.term(0, 1) = st_1d_basis->getNewCoeffs(1);
      
      // Triple product tensor
      Teuchos::RCP<Stokhos::Sparse3Tensor<int,double> > st_Cijk =
	st_basis->computeTripleProductTensor(st_basis->size());
	
      // Tensor product quadrature
      Teuchos::RCP<const Stokhos::Quadrature<int,double> > st_quad;
      if (!use_pce_quad_points) {
#ifdef HAVE_STOKHOS_DAKOTA
	if (sparse_grid)
	  st_quad = Teuchos::rcp(new Stokhos::SparseGridQuadrature<int,double>(st_basis, p));
#endif
	if (!sparse_grid)
	  st_quad = Teuchos::rcp(new Stokhos::TensorProductQuadrature<int,double>(st_basis));
      }
      else {
	Teuchos::Array<double> st_points_0;
	Teuchos::Array<double> st_weights_0;
	Teuchos::Array< Teuchos::Array<double> > st_values_0;
	st_bases[0]->getQuadPoints(p+1, st_points_0, st_weights_0, st_values_0);
	Teuchos::Array<double> st_points_1;
	Teuchos::Array<double> st_weights_1;
	Teuchos::Array< Teuchos::Array<double> > st_values_1;
	st_bases[1]->getQuadPoints(p+1, st_points_1, st_weights_1, st_values_1);
	Teuchos::RCP< Teuchos::Array< Teuchos::Array<double> > > st_points =
	  Teuchos::rcp(new Teuchos::Array< Teuchos::Array<double> >(st_points_0.size()));
	for (int i=0; i<st_points_0.size(); i++) {
	  (*st_points)[i].resize(2);
	  (*st_points)[i][0] = st_points_0[i];
	  (*st_points)[i][1] = st_points_1[i];
	}
	Teuchos::RCP< Teuchos::Array<double> > st_weights = 
	  Teuchos::rcp(new Teuchos::Array<double>(st_weights_0));
	Teuchos::RCP< const Stokhos::OrthogPolyBasis<int,double> > st_b = 
	  st_basis;
	st_quad = 
	  Teuchos::rcp(new Stokhos::UserDefinedQuadrature<int,double>(st_b,
								      st_points,
								      st_weights));
      }
      
      // Quadrature expansion
      Stokhos::QuadOrthogPolyExpansion<int,double> st_quad_exp(st_basis, 
							       st_Cijk,
							       st_quad);
      
      // Compute w_st = u_st*v_st in Stieltjes basis
      st_quad_exp.exp(w_st, u_st);
      
      // Project w_st back to original basis
      pce_quad_func st_func(w_st, *st_basis);
      quad_exp.unary_op(st_func, w2, u);

      // std::cout.precision(12);
      // std::cout << w;
      // std::cout << w2;
      // std::cout << w_st;
      mean[n] = w.mean();
      mean_st[n] = w2.mean();
      std_dev[n] = w.standard_deviation();
      std_dev_st[n] = w2.standard_deviation();
      pt[n] = w.evaluate(eval_pt);
      pt_st[n] = w2.evaluate(eval_pt);
      n++;
    }

    n = 0;
    int wi=10;
    std::cout << "Statistical error:" << std::endl;
    std::cout << "p  " 
	      << std::setw(wi) << "mean" << "  " 
	      << std::setw(wi) << "mean_st" << "  "
	      << std::setw(wi) << "std_dev" << "  "
	      << std::setw(wi) << "std_dev_st" << "  "
	      << std::setw(wi) << "point" << "  "
	      << std::setw(wi) << "point_st" << std::endl;
    for (unsigned int p=pmin; p<pmax; p++) {
      std::cout.precision(3);
      std::cout.setf(std::ios::scientific);
      std::cout << p << "  " 
		<< std::setw(wi) << rel_err(mean[n], mean[np-1]) << "  "
		<< std::setw(wi) << rel_err(mean_st[n], mean[np-1]) << "  "
		<< std::setw(wi) << rel_err(std_dev[n], std_dev[np-1]) << "  "
		<< std::setw(wi) << rel_err(std_dev_st[n], std_dev[np-1]) 
		<< "  "
		<< std::setw(wi) << rel_err(pt[n], pt_true) << "  "
		<< std::setw(wi) << rel_err(pt_st[n], pt_true) 
		<< std::endl;
      n++;
    }
      
  }
  catch (std::exception& e) {
    std::cout << e.what() << std::endl;
  }
}
int main(int argc, char **argv)
{
  try {

    const unsigned int d = 2;
    const unsigned int p = 5;

    // Create product basis
    Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double> > > bases(d);
    for (unsigned int i=0; i<d; i++)
      bases[i] = Teuchos::rcp(new basis_type(p));
    Teuchos::RCP<const Stokhos::CompletePolynomialBasis<int,double> > basis = 
      Teuchos::rcp(new Stokhos::CompletePolynomialBasis<int,double>(bases));

    // Create approximation
    Stokhos::OrthogPolyApprox<int,double> x(basis), u(basis), v(basis), 
      w(basis), w2(basis), w3(basis);
    for (unsigned int i=0; i<d; i++) {
      x.term(i, 1) = 1.0;
    }

    // Tensor product quadrature
    Teuchos::RCP<const Stokhos::Quadrature<int,double> > quad = 
      Teuchos::rcp(new Stokhos::TensorProductQuadrature<int,double>(basis));

    // Triple product tensor
    Teuchos::RCP<Stokhos::Sparse3Tensor<int,double> > Cijk =
      basis->computeTripleProductTensor();
    
    // Quadrature expansion
    Stokhos::QuadOrthogPolyExpansion<int,double> quad_exp(basis, Cijk, quad);
    
    // Compute PCE via quadrature expansion
    quad_exp.sin(u,x);
    quad_exp.exp(v,x);
    quad_exp.times(w,v,u);
    
    // Compute tensor product Stieltjes basis for u and v
    Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double> > > st_bases(2);
    st_bases[0] = 
      Teuchos::rcp(new Stokhos::StieltjesPCEBasis<int,double>(
		     p, Teuchos::rcp(&u,false), quad, true));
    st_bases[1] = 
      Teuchos::rcp(new Stokhos::StieltjesPCEBasis<int,double>(
		     p, Teuchos::rcp(&v,false), quad, true));
    Teuchos::RCP<const Stokhos::CompletePolynomialBasis<int,double> > st_basis =
      Teuchos::rcp(new Stokhos::CompletePolynomialBasis<int,double>(st_bases));
    Stokhos::OrthogPolyApprox<int,double>  u_st(st_basis), v_st(st_basis), 
      w_st(st_basis);
    u_st.term(0, 0) = u.mean();
    u_st.term(0, 1) = 1.0;
    v_st.term(0, 0) = v.mean();
    v_st.term(1, 1) = 1.0;
    
    // Use Gram-Schmidt to orthogonalize Stieltjes basis of u and v
    Teuchos::Array<double> st_points_0;
    Teuchos::Array<double> st_weights_0;
    Teuchos::Array< Teuchos::Array<double> > st_values_0;
    st_bases[0]->getQuadPoints(p+1, st_points_0, st_weights_0, st_values_0);
    Teuchos::Array<double> st_points_1;
    Teuchos::Array<double> st_weights_1;
    Teuchos::Array< Teuchos::Array<double> > st_values_1;
    st_bases[1]->getQuadPoints(p+1, st_points_1, st_weights_1, st_values_1);
    Teuchos::Array< Teuchos::Array<double> > st_points(st_points_0.size());
    for (int i=0; i<st_points_0.size(); i++) {
      st_points[i].resize(2);
      st_points[i][0] = st_points_0[i];
      st_points[i][1] = st_points_1[i];
    }
    Teuchos::Array<double> st_weights = st_weights_0;
    
    Teuchos::RCP< Stokhos::GramSchmidtBasis<int,double> > gs_basis = 
      Teuchos::rcp(new Stokhos::GramSchmidtBasis<int,double>(st_basis,
							     st_points,
							     st_weights,
							     1e-15));
    
    // Create quadrature for Gram-Schmidt basis using quad points and 
    // and weights from original basis mapped to Stieljtes basis
    Teuchos::RCP< const Teuchos::Array< Teuchos::Array<double> > > points =
      Teuchos::rcp(&st_points,false);
    Teuchos::RCP< const Teuchos::Array<double> > weights =
      Teuchos::rcp(&st_weights,false);
    Teuchos::RCP<const Stokhos::Quadrature<int,double> > gs_quad = 
      Teuchos::rcp(new Stokhos::UserDefinedQuadrature<int,double>(gs_basis,
								  points,
								  weights));

    // Triple product tensor
    Teuchos::RCP<Stokhos::Sparse3Tensor<int,double> > gs_Cijk =
      gs_basis->computeTripleProductTensor();
    
    // Gram-Schmidt quadrature expansion
    Stokhos::QuadOrthogPolyExpansion<int,double> gs_quad_exp(gs_basis, 
							     gs_Cijk,
							     gs_quad);
    
    Stokhos::OrthogPolyApprox<int,double>  u_gs(gs_basis), v_gs(gs_basis), 
      w_gs(gs_basis);
    
    // Map expansion in Stieltjes basis to Gram-Schmidt basis
    gs_basis->transformCoeffs(u_st.coeff(), u_gs.coeff());
    gs_basis->transformCoeffs(v_st.coeff(), v_gs.coeff());
    
    // Compute w_gs = u_gs*v_gs in Gram-Schmidt basis
    gs_quad_exp.times(w_gs, u_gs, v_gs);
    
    // Project w_gs back to original basis
    pce_quad_func gs_func(w_gs, *gs_basis);
    quad_exp.binary_op(gs_func, w2, u, v);

    // Triple product tensor
    Teuchos::RCP<Stokhos::Sparse3Tensor<int,double> > st_Cijk =
      st_basis->computeTripleProductTensor();

    // Stieltjes quadrature expansion
    Teuchos::RCP<const Stokhos::Quadrature<int,double> > st_quad = 
      Teuchos::rcp(new Stokhos::UserDefinedQuadrature<int,double>(st_basis,
								  points,
								  weights));
    Stokhos::QuadOrthogPolyExpansion<int,double> st_quad_exp(st_basis,
							     st_Cijk,
							     st_quad);
    
    // Compute w_st = u_st*v_st in Stieltjes basis
    st_quad_exp.times(w_st, u_st, v_st);
    
    // Project w_st back to original basis
    pce_quad_func st_func(w_st, *st_basis);
    quad_exp.binary_op(st_func, w3, u, v);
    
    std::cout.precision(12);
    std::cout << "w = " << std::endl << w;
    std::cout << "w2 = " << std::endl << w2;
    std::cout << "w3 = " << std::endl << w3;
    std::cout << "w_gs = " << std::endl << w_gs;
    std::cout << "w_st = " << std::endl << w_st;
    
    std::cout.setf(std::ios::scientific);
    std::cout << "w.mean()       = " << w.mean() << std::endl
	      << "w2.mean()      = " << w2.mean() << std::endl
	      << "w3.mean()      = " << w3.mean() << std::endl
	      << "w_gs.mean()    = " << w_gs.mean() << std::endl
	      << "w_st.mean()    = " << w_st.mean() << std::endl
	      << "w.std_dev()    = " << w.standard_deviation() << std::endl
	      << "w2.std_dev()   = " << w2.standard_deviation() << std::endl
	      << "w3.std_dev()   = " << w3.standard_deviation() << std::endl
	      << "w_gs.std_dev() = " << w_gs.standard_deviation() << std::endl
	      << "w_st.std_dev() = " << w_st.standard_deviation() << std::endl;
  }
  catch (std::exception& e) {
    std::cout << e.what() << std::endl;
  }
}