Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Stokhos_StieltjesPCEBasisImp.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Stokhos Package
4 //
5 // Copyright 2009 NTESS and the Stokhos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #include "Teuchos_Assert.hpp"
11 #include "Teuchos_BLAS.hpp"
12 #include "Teuchos_TimeMonitor.hpp"
13 
14 template <typename ordinal_type, typename value_type>
17  ordinal_type p,
20  bool use_pce_quad_points_,
21  bool normalize,
22  bool project_integrals_,
24  RecurrenceBasis<ordinal_type, value_type>("Stieltjes PCE", p, normalize),
25  pce(pce_),
26  quad(quad_),
27  pce_weights(quad->getQuadWeights()),
28  basis_values(quad->getBasisAtQuadPoints()),
29  pce_vals(),
30  phi_vals(),
31  use_pce_quad_points(use_pce_quad_points_),
32  fromStieltjesMat(p+1,pce->size()),
33  project_integrals(project_integrals_),
34  basis(pce->basis()),
35  Cijk(Cijk_),
36  phi_pce_coeffs()
37 {
38  // Setup rest of recurrence basis
39  this->setup();
40 }
41 
42 template <typename ordinal_type, typename value_type>
45 {
46 }
47 
48 template <typename ordinal_type, typename value_type>
49 void
52  Teuchos::Array<value_type>& quad_points,
53  Teuchos::Array<value_type>& quad_weights,
54  Teuchos::Array< Teuchos::Array<value_type> >& quad_values) const
55 {
56 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
57  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::StieltjesPCEBasis -- compute Gauss points");
58 #endif
59 
60  // Use underlying pce's quad points, weights, values
61  if (use_pce_quad_points) {
62  quad_points = pce_vals;
63  quad_weights = pce_weights;
64  quad_values = phi_vals;
65  return;
66  }
67 
68  // Call base class
69  ordinal_type num_points =
70  static_cast<ordinal_type>(std::ceil((quad_order+1)/2.0));
71 
72  // We can't reliably generate quadrature points of order > 2*p
73  //if (!project_integrals && quad_order > 2*this->p)
74  if (quad_order > 2*this->p)
75  quad_order = 2*this->p;
77  quad_points,
78  quad_weights,
79  quad_values);
80 
81  // Fill in the rest of the points with zero weight
82  if (quad_weights.size() < num_points) {
83  ordinal_type old_size = quad_weights.size();
84  quad_weights.resize(num_points);
85  quad_points.resize(num_points);
86  quad_values.resize(num_points);
87  for (ordinal_type i=old_size; i<num_points; i++) {
88  quad_weights[i] = value_type(0);
89  quad_points[i] = quad_points[0];
90  quad_values[i].resize(this->p+1);
91  this->evaluateBases(quad_points[i], quad_values[i]);
92  }
93  }
94 }
95 
96 template <typename ordinal_type, typename value_type>
97 bool
103  Teuchos::Array<value_type>& gamma) const
104 {
105  ordinal_type nqp = phi_vals.size();
108  for (ordinal_type i=0; i<nqp; i++)
109  vals[i].resize(n);
110  stieltjes(0, n, pce_weights, pce_vals, alpha, beta, nrm, vals);
111  for (ordinal_type i=0; i<n; i++) {
112  delta[i] = value_type(1.0);
113  gamma[i] = value_type(1.0);
114  }
115 
116  // Save basis functions at quad point values
117  if (n == this->p+1)
118  phi_vals = vals;
119 
120  return false;
121 }
122 
123 template <typename ordinal_type, typename value_type>
124 void
127 {
128  // Evaluate PCE at quad points
129  const Teuchos::Array< Teuchos::Array<value_type> >& quad_points =
130  quad->getQuadPoints();
131  ordinal_type nqp = pce_weights.size();
132  pce_vals.resize(nqp);
133  phi_vals.resize(nqp);
134  for (ordinal_type i=0; i<nqp; i++) {
135  pce_vals[i] = pce->evaluate(quad_points[i], basis_values[i]);
136  phi_vals[i].resize(this->p+1);
137  }
138 
139  if (project_integrals)
140  phi_pce_coeffs.resize(basis->size());
141 
143 
144  ordinal_type sz = pce->size();
145  fromStieltjesMat.putScalar(0.0);
146  for (ordinal_type i=0; i<=this->p; i++) {
147  for (ordinal_type j=0; j<sz; j++) {
148  for (ordinal_type k=0; k<nqp; k++)
149  fromStieltjesMat(i,j) +=
150  pce_weights[k]*phi_vals[k][i]*basis_values[k][j];
151  fromStieltjesMat(i,j) /= basis->norm_squared(j);
152  }
153  }
154 }
155 
156 template <typename ordinal_type, typename value_type>
157 void
160  ordinal_type nfinish,
161  const Teuchos::Array<value_type>& weights,
162  const Teuchos::Array<value_type>& points,
166  Teuchos::Array< Teuchos::Array<value_type> >& phi_vals) const
167 {
168 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
169  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::StieltjesPCEBasis -- Discretized Stieltjes Procedure");
170 #endif
171 
172  value_type val1, val2;
173  ordinal_type start = nstart;
174  if (nstart == 0) {
175  if (project_integrals)
176  integrateBasisSquaredProj(0, a, b, weights, points, phi_vals, val1, val2);
177  else
178  integrateBasisSquared(0, a, b, weights, points, phi_vals, val1, val2);
179  nrm[0] = val1;
180  a[0] = val2/val1;
181  b[0] = value_type(1);
182  start = 1;
183  }
184  for (ordinal_type i=start; i<nfinish; i++) {
185  if (project_integrals)
186  integrateBasisSquaredProj(i, a, b, weights, points, phi_vals, val1, val2);
187  else
188  integrateBasisSquared(i, a, b, weights, points, phi_vals, val1, val2);
189  // std::cout << "i = " << i << " val1 = " << val1 << " val2 = " << val2
190  // << std::endl;
191  TEUCHOS_TEST_FOR_EXCEPTION(val1 < 0.0, std::logic_error,
192  "Stokhos::StieltjesPCEBasis::stieltjes(): "
193  << " Polynomial " << i << " out of " << nfinish
194  << " has norm " << val1
195  << "! Try increasing number of quadrature points");
196  nrm[i] = val1;
197  a[i] = val2/val1;
198  b[i] = nrm[i]/nrm[i-1];
199 
200  // std::cout << "i = " << i << " alpha = " << a[i] << " beta = " << b[i]
201  // << " nrm = " << nrm[i] << std::endl;
202  }
203 }
204 
205 template <typename ordinal_type, typename value_type>
206 void
211  const Teuchos::Array<value_type>& weights,
212  const Teuchos::Array<value_type>& points,
214  value_type& val1, value_type& val2) const
215 {
216  evaluateRecurrence(k, a, b, points, phi_vals);
217  ordinal_type nqp = weights.size();
218  val1 = value_type(0);
219  val2 = value_type(0);
220  for (ordinal_type i=0; i<nqp; i++) {
221  val1 += weights[i]*phi_vals[i][k]*phi_vals[i][k];
222  val2 += weights[i]*phi_vals[i][k]*phi_vals[i][k]*points[i];
223  }
224 }
225 
226 template <typename ordinal_type, typename value_type>
227 void
232  const Teuchos::Array<value_type>& points,
234 {
235  ordinal_type np = points.size();
236  if (k == 0)
237  for (ordinal_type i=0; i<np; i++)
238  values[i][k] = 1.0;
239  else if (k == 1)
240  for (ordinal_type i=0; i<np; i++)
241  values[i][k] = points[i] - a[k-1];
242  else
243  for (ordinal_type i=0; i<np; i++)
244  values[i][k] =
245  (points[i] - a[k-1])*values[i][k-1] - b[k-1]*values[i][k-2];
246 }
247 
248 template <typename ordinal_type, typename value_type>
249 void
252  ordinal_type k,
255  const Teuchos::Array<value_type>& weights,
256  const Teuchos::Array<value_type>& points,
258  value_type& val1, value_type& val2) const
259 {
260  ordinal_type nqp = weights.size();
261  ordinal_type npc = basis->size();
262  const Teuchos::Array<value_type>& norms = basis->norm_squared();
263 
264  // Compute PC expansion of phi_k in original basis
265  evaluateRecurrence(k, a, b, points, phi_vals);
266  for (ordinal_type j=0; j<npc; j++) {
267  value_type c = value_type(0);
268  for (ordinal_type i=0; i<nqp; i++)
269  c += weights[i]*phi_vals[i][k]*basis_values[i][j];
270  c /= norms[j];
271  phi_pce_coeffs[j] = c;
272  }
273 
274  // Compute \int phi_k^2(\eta) d\eta
275  val1 = value_type(0);
276  for (ordinal_type j=0; j<npc; j++)
277  val1 += phi_pce_coeffs[j]*phi_pce_coeffs[j]*norms[j];
278 
279  // Compute \int \eta phi_k^2(\eta) d\eta
280  val2 = value_type(0);
281  for (typename Cijk_type::k_iterator k_it = Cijk->k_begin();
282  k_it != Cijk->k_end(); ++k_it) {
283  ordinal_type l = index(k_it);
284  for (typename Cijk_type::kj_iterator j_it = Cijk->j_begin(k_it);
285  j_it != Cijk->j_end(k_it); ++j_it) {
286  ordinal_type j = index(j_it);
287  for (typename Cijk_type::kji_iterator i_it = Cijk->i_begin(j_it);
288  i_it != Cijk->i_end(j_it); ++i_it) {
289  ordinal_type i = index(i_it);
290  value_type c = value(i_it);
291  val2 += phi_pce_coeffs[i]*phi_pce_coeffs[j]*(*pce)[l]*c;
292  }
293  }
294  }
295 }
296 
297 template <typename ordinal_type, typename value_type>
298 void
301 {
303  blas.GEMV(Teuchos::TRANS, fromStieltjesMat.numRows(),
304  fromStieltjesMat.numCols(), 1.0, fromStieltjesMat.values(),
305  fromStieltjesMat.numRows(), in, 1, 0.0, out, 1);
306 }
307 
308 template <typename ordinal_type, typename value_type>
312 {
314 }
315 
316 template <typename ordinal_type, typename value_type>
320  pce(sbasis.pce),
321  quad(sbasis.quad),
322  pce_weights(quad->getQuadWeights()),
323  basis_values(quad->getBasisAtQuadPoints()),
324  pce_vals(sbasis.pce_vals),
325  phi_vals(),
326  use_pce_quad_points(sbasis.use_pce_quad_points),
327  fromStieltjesMat(p+1,pce->size()),
328  project_integrals(sbasis.project_integrals),
329  basis(pce->basis()),
330  Cijk(sbasis.Cijk),
331  phi_pce_coeffs()
332 {
333  this->setup();
334 }
virtual Teuchos::RCP< OneDOrthogPolyBasis< ordinal_type, value_type > > cloneWithOrder(ordinal_type p) const
Clone this object with the option of building a higher order basis.
#define TEUCHOS_FUNC_TIME_MONITOR(FUNCNAME)
Implementation of OneDOrthogPolyBasis based on the general three-term recurrence relationship: for ...
void integrateBasisSquaredProj(ordinal_type k, const Teuchos::Array< value_type > &a, const Teuchos::Array< value_type > &b, const Teuchos::Array< value_type > &weights, const Teuchos::Array< value_type > &points, Teuchos::Array< Teuchos::Array< value_type > > &phi_vals, value_type &val1, value_type &val2) const
Compute and by projecting onto original PCE basis.
Data structure storing a sparse 3-tensor C(i,j,k) in a a compressed format.
void GEMV(ETransp trans, const OrdinalType &m, const OrdinalType &n, const alpha_type alpha, const A_type *A, const OrdinalType &lda, const x_type *x, const OrdinalType &incx, const beta_type beta, ScalarType *y, const OrdinalType &incy) const
virtual void getQuadPoints(ordinal_type quad_order, Teuchos::Array< value_type > &points, Teuchos::Array< value_type > &weights, Teuchos::Array< Teuchos::Array< value_type > > &values) const
Compute quadrature points, weights, and values of basis polynomials at given set of points points...
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
StieltjesPCEBasis(ordinal_type p, const Teuchos::RCP< const Stokhos::OrthogPolyApprox< ordinal_type, value_type > > &pce, const Teuchos::RCP< const Stokhos::Quadrature< ordinal_type, value_type > > &quad, bool use_pce_quad_points, bool normalize=false, bool project_integrals=false, const Teuchos::RCP< const Stokhos::Sparse3Tensor< ordinal_type, value_type > > &Cijk=Teuchos::null)
Constructor.
Bi-directional iterator for traversing a sparse array.
Generates three-term recurrence using the Discretized Stieltjes procedure applied to a polynomial cha...
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Abstract base class for quadrature methods.
KOKKOS_INLINE_FUNCTION PCE< Storage > ceil(const PCE< Storage > &a)
void resize(size_type new_size, const value_type &x=value_type())
void evaluateRecurrence(ordinal_type k, const Teuchos::Array< value_type > &a, const Teuchos::Array< value_type > &b, const Teuchos::Array< value_type > &points, Teuchos::Array< Teuchos::Array< value_type > > &values) const
Evaluate polynomials via 3-term recurrence.
virtual void setup()
Setup basis after computing recurrence coefficients.
virtual bool computeRecurrenceCoefficients(ordinal_type n, Teuchos::Array< value_type > &alpha, Teuchos::Array< value_type > &beta, Teuchos::Array< value_type > &delta, Teuchos::Array< value_type > &gamma) const
Compute recurrence coefficients.
virtual void getQuadPoints(ordinal_type quad_order, Teuchos::Array< value_type > &points, Teuchos::Array< value_type > &weights, Teuchos::Array< Teuchos::Array< value_type > > &values) const
Get Gauss quadrature points, weights, and values of basis at points.
virtual void setup()
Setup basis after computing recurrence coefficients.
void transformCoeffsFromStieltjes(const value_type *in, value_type *out) const
Map expansion coefficients from this basis to original.
void integrateBasisSquared(ordinal_type k, const Teuchos::Array< value_type > &a, const Teuchos::Array< value_type > &b, const Teuchos::Array< value_type > &weights, const Teuchos::Array< value_type > &points, Teuchos::Array< Teuchos::Array< value_type > > &phi_vals, value_type &val1, value_type &val2) const
Compute and .
size_type size() const
void stieltjes(ordinal_type nstart, ordinal_type nfinish, const Teuchos::Array< value_type > &weights, const Teuchos::Array< value_type > &points, Teuchos::Array< value_type > &a, Teuchos::Array< value_type > &b, Teuchos::Array< value_type > &nrm, Teuchos::Array< Teuchos::Array< value_type > > &phi_vals) const
Compute 3-term recurrence using Stieljtes procedure.