Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Stokhos_MonoProjPCEBasisImp.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_LAPACK.hpp"
13 #include "Teuchos_TimeMonitor.hpp"
15 
16 template <typename ordinal_type, typename value_type>
19  ordinal_type p,
23  bool limit_integration_order_) :
24  RecurrenceBasis<ordinal_type, value_type>("Monomial Projection", p, true),
25  limit_integration_order(limit_integration_order_),
26  pce_sz(pce.basis()->size()),
27  pce_norms(pce.basis()->norm_squared()),
28  a(pce_sz),
29  b(pce_sz),
30  basis_vecs(pce_sz, p+1),
31  new_pce(p+1)
32 {
33  // If the original basis is normalized, we can use the standard QR
34  // factorization. For simplicity, we renormalize the PCE coefficients
35  // for a normalized basis
37  for (ordinal_type i=0; i<pce_sz; i++) {
38  pce_norms[i] = std::sqrt(pce_norms[i]);
39  normalized_pce[i] *= pce_norms[i];
40  }
41 
42  // Evaluate PCE at quad points
43  ordinal_type nqp = quad.size();
44  Teuchos::Array<value_type> pce_vals(nqp);
45  const Teuchos::Array<value_type>& weights = quad.getQuadWeights();
46  const Teuchos::Array< Teuchos::Array<value_type> >& quad_points =
47  quad.getQuadPoints();
48  const Teuchos::Array< Teuchos::Array<value_type> >& basis_values =
49  quad.getBasisAtQuadPoints();
50  for (ordinal_type i=0; i<nqp; i++) {
51  pce_vals[i] = normalized_pce.evaluate(quad_points[i], basis_values[i]);
52  }
53 
54  // Form Kylov matrix up to order pce_sz
55  matrix_type K(pce_sz, pce_sz);
56 
57  // Compute matrix
58  matrix_type A(pce_sz, pce_sz);
60  for (typename Cijk_type::k_iterator k_it = Cijk.k_begin();
61  k_it != Cijk.k_end(); ++k_it) {
62  ordinal_type k = index(k_it);
63  for (typename Cijk_type::kj_iterator j_it = Cijk.j_begin(k_it);
64  j_it != Cijk.j_end(k_it); ++j_it) {
65  ordinal_type j = index(j_it);
66  value_type val = 0;
67  for (typename Cijk_type::kji_iterator i_it = Cijk.i_begin(j_it);
68  i_it != Cijk.i_end(j_it); ++i_it) {
69  ordinal_type i = index(i_it);
70  value_type c = value(i_it) / (pce_norms[j]*pce_norms[k]);
71  val += pce[i]*c;
72  }
73  A(k,j) = val;
74  }
75  }
76 
77  // Each column i is given by projection of the i-th order monomial
78  // onto original basis
79  vector_type u0 = Teuchos::getCol(Teuchos::View, K, 0);
80  u0(0) = 1.0;
81  for (ordinal_type i=1; i<pce_sz; i++)
82  u0(i) = 0.0;
83  for (ordinal_type k=1; k<pce_sz; k++) {
84  vector_type u = Teuchos::getCol(Teuchos::View, K, k);
85  vector_type up = Teuchos::getCol(Teuchos::View, K, k-1);
86  u.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, A, up, 0.0);
87  }
88  /*
89  for (ordinal_type j=0; j<pce_sz; j++) {
90  for (ordinal_type i=0; i<pce_sz; i++) {
91  value_type val = 0.0;
92  for (ordinal_type k=0; k<nqp; k++)
93  val += weights[k]*std::pow(pce_vals[k],j)*basis_values[k][i];
94  K(i,j) = val;
95  }
96  }
97  */
98 
99  std::cout << K << std::endl << std::endl;
100 
101  // Compute QR factorization of K
102  ordinal_type ws_size, info;
103  value_type ws_size_query;
104  Teuchos::Array<value_type> tau(pce_sz);
106  lapack.GEQRF(pce_sz, pce_sz, K.values(), K.stride(), &tau[0],
107  &ws_size_query, -1, &info);
108  TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error,
109  "GEQRF returned value " << info);
110  ws_size = static_cast<ordinal_type>(ws_size_query);
111  Teuchos::Array<value_type> work(ws_size);
112  lapack.GEQRF(pce_sz, pce_sz, K.values(), K.stride(), &tau[0],
113  &work[0], ws_size, &info);
114  TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error,
115  "GEQRF returned value " << info);
116 
117  // Get Q
118  lapack.ORGQR(pce_sz, pce_sz, pce_sz, K.values(), K.stride(), &tau[0],
119  &ws_size_query, -1, &info);
120  TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error,
121  "ORGQR returned value " << info);
122  ws_size = static_cast<ordinal_type>(ws_size_query);
123  work.resize(ws_size);
124  lapack.ORGQR(pce_sz, pce_sz, pce_sz, K.values(), K.stride(), &tau[0],
125  &work[0], ws_size, &info);
126  TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error,
127  "ORGQR returned value " << info);
128 
129  // Get basis vectors
130  for (ordinal_type j=0; j<p+1; j++)
131  for (ordinal_type i=0; i<pce_sz; i++)
132  basis_vecs(i,j) = K(i,j);
133 
134 
135  // Compute T = Q'*A*Q
136  matrix_type prod(pce_sz,pce_sz);
137  prod.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, K, A, 0.0);
138  matrix_type T(pce_sz,pce_sz);
139  T.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, prod, K, 0.0);
140 
141  //std::cout << T << std::endl;
142 
143  // Recursion coefficients are diagonal and super diagonal
144  b[0] = 1.0;
145  for (ordinal_type i=0; i<pce_sz-1; i++) {
146  a[i] = T(i,i);
147  b[i+1] = T(i,i+1);
148  }
149  a[pce_sz-1] = T(pce_sz-1,pce_sz-1);
150 
151  // Setup rest of basis
152  this->setup();
153 
154  // Project original PCE into the new basis
155  vector_type u(pce_sz);
156  for (ordinal_type i=0; i<pce_sz; i++)
157  u[i] = normalized_pce[i];
159  0.0);
160  for (ordinal_type i=0; i<=p; i++)
161  new_pce[i] /= this->norms[i];
162 }
163 
164 template <typename ordinal_type, typename value_type>
167 {
168 }
169 
170 template <typename ordinal_type, typename value_type>
171 void
174  Teuchos::Array<value_type>& quad_points,
175  Teuchos::Array<value_type>& quad_weights,
176  Teuchos::Array< Teuchos::Array<value_type> >& quad_values) const
177 {
178 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
179  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::MonoProjPCEBasis -- compute Gauss points");
180 #endif
181 
182  // Call base class
183  ordinal_type num_points =
184  static_cast<ordinal_type>(std::ceil((quad_order+1)/2.0));
185 
186  // We can't always reliably generate quadrature points of order > 2*p
187  // when using sparse grids for the underlying quadrature
188  if (limit_integration_order && quad_order > 2*this->p)
189  quad_order = 2*this->p;
191  quad_points,
192  quad_weights,
193  quad_values);
194 
195  // Fill in the rest of the points with zero weight
196  if (quad_weights.size() < num_points) {
197  ordinal_type old_size = quad_weights.size();
198  quad_weights.resize(num_points);
199  quad_points.resize(num_points);
200  quad_values.resize(num_points);
201  for (ordinal_type i=old_size; i<num_points; i++) {
202  quad_weights[i] = value_type(0);
203  quad_points[i] = quad_points[0];
204  quad_values[i].resize(this->p+1);
205  evaluateBases(quad_points[i], quad_values[i]);
206  }
207  }
208 }
209 
210 template <typename ordinal_type, typename value_type>
214 {
216  p,*this));
217 }
218 
219 template <typename ordinal_type, typename value_type>
223 {
224  return new_pce[i];
225 }
226 
227 template <typename ordinal_type, typename value_type>
228 void
230 transformCoeffs(const value_type *in, value_type *out) const
231 {
232  // Transform coefficients to normalized basis
234  blas.GEMV(Teuchos::NO_TRANS, pce_sz, this->p+1,
235  value_type(1.0), basis_vecs.values(), pce_sz,
236  in, ordinal_type(1), value_type(0.0), out, ordinal_type(1));
237 
238  // Transform from normalized to original
239  for (ordinal_type i=0; i<pce_sz; i++)
240  out[i] /= pce_norms[i];
241 }
242 
243 template <typename ordinal_type, typename value_type>
244 bool
250  Teuchos::Array<value_type>& gamma) const
251 {
252  // Get recurrence coefficients from the full set we already computed
253  for (ordinal_type i=0; i<n; i++) {
254  alpha[i] = a[i];
255  beta[i] = b[i];
256  delta[i] = value_type(1.0);
257  gamma[i] = b[i];
258 
259  std::cout << "i = " << i << " alpha = " << alpha[i] << " beta = " << beta[i]
260  << " gamma = " << gamma[i] << std::endl;
261  }
262 
263  return true;
264 }
265 
266 template <typename ordinal_type, typename value_type>
269  RecurrenceBasis<ordinal_type, value_type>("Lanczos PCE", p, false),
270  limit_integration_order(basis.limit_integration_order),
271  pce_sz(basis.pce_sz),
272  pce_norms(basis.pce_norms),
273  a(basis.a),
274  b(basis.b),
275  basis_vecs(basis.basis_vecs),
276  new_pce(basis.new_pce)
277 {
278  this->setup();
279 }
ScalarType * values() const
KOKKOS_INLINE_FUNCTION PCE< Storage > sqrt(const PCE< Storage > &a)
void ORGQR(const OrdinalType &m, const OrdinalType &n, const OrdinalType &k, ScalarType *A, const OrdinalType &lda, const ScalarType *TAU, ScalarType *WORK, const OrdinalType &lwork, OrdinalType *info) const
#define TEUCHOS_FUNC_TIME_MONITOR(FUNCNAME)
value_type getNewCoeffs(ordinal_type i) const
Get new coefficients in this new basis.
Generates three-term recurrence using the Lanczos procedure applied to a polynomial chaos expansion i...
Teuchos::Array< value_type > norms
Norms.
Implementation of OneDOrthogPolyBasis based on the general three-term recurrence relationship: for ...
k_iterator k_begin() const
Iterator pointing to first k entry.
value_type evaluate(const Teuchos::Array< value_type > &point) const
Evaluate polynomial approximation at a point.
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
int multiply(ETransp transa, ETransp transb, ScalarType alpha, const SerialDenseMatrix< OrdinalType, ScalarType > &A, const SerialDenseMatrix< OrdinalType, ScalarType > &B, ScalarType beta)
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...
kj_iterator j_begin(const k_iterator &k) const
Iterator pointing to first j entry for given k.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
virtual ordinal_type size() const =0
Get number of quadrature points.
virtual const Teuchos::Array< Teuchos::Array< value_type > > & getBasisAtQuadPoints() const =0
Get values of basis at quadrature points.
matrix_type basis_vecs
Basis vectors.
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.
kj_iterator j_end(const k_iterator &k) const
Iterator pointing to last j entry for given k.
virtual const Teuchos::Array< value_type > & getQuadWeights() const =0
Get quadrature weights.
virtual const Teuchos::Array< Teuchos::Array< value_type > > & getQuadPoints() const =0
Get quadrature points.
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 transformCoeffs(const value_type *in, value_type *out) const
Map expansion coefficients from this basis to original.
void resize(size_type new_size, const value_type &x=value_type())
Teuchos::Array< value_type > pce_norms
Basis norms.
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.
k_iterator k_end() const
Iterator pointing to last k entry.
Stokhos::Sparse3Tensor< int, double > Cijk_type
virtual void setup()
Setup basis after computing recurrence coefficients.
expr val()
ordinal_type pce_sz
Size of PC expansion.
void GEQRF(const OrdinalType &m, const OrdinalType &n, ScalarType *A, const OrdinalType &lda, ScalarType *TAU, ScalarType *WORK, const OrdinalType &lwork, OrdinalType *info) const
Teuchos::Array< value_type > b
Stores full set of beta coefficients.
Teuchos::Array< value_type > a
Stores full set of alpha coefficients.
size_type size() const
ordinal_type p
Order of basis.
MonoProjPCEBasis(ordinal_type p, const Stokhos::OrthogPolyApprox< ordinal_type, value_type > &pce, const Stokhos::Quadrature< ordinal_type, value_type > &quad, const Stokhos::Sparse3Tensor< ordinal_type, value_type > &Cijk, bool limit_integration_order=false)
Constructor.
vector_type new_pce
Projection of pce in new basis.
kji_iterator i_begin(const kj_iterator &j) const
Iterator pointing to first i entry for given j and k.
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.
kji_iterator i_end(const kj_iterator &j) const
Iterator pointing to last i entry for given j and k.
OrdinalType stride() const