Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Stokhos_HouseTriDiagPCEBasisImp.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 limit_integration_order_) :
21  RecurrenceBasis<ordinal_type, value_type>("Householder Tridiagonalization PCE", p, true),
22  limit_integration_order(limit_integration_order_),
23  pce_sz(pce.basis()->size()),
24  a(pce_sz+1),
25  b(pce_sz),
26  basis_vecs(pce_sz, p+1),
27  new_pce(p+1)
28 {
29  pce_norms = pce.basis()->norm_squared();
30 
31  // Compute matrix -- rescale basis to unit norm
32  matrix_type A(pce_sz+1, pce_sz+1);
33  A(0,0) = 1.0;
34  for (ordinal_type i=0; i<pce_sz; i++) {
35  A(0,i+1) = 1.0/pce_sz;
36  A(i+1,0) = 1.0/pce_sz;
37  }
39  for (typename Cijk_type::k_iterator k_it = Cijk.k_begin();
40  k_it != Cijk.k_end(); ++k_it) {
41  ordinal_type k = index(k_it);
42  for (typename Cijk_type::kj_iterator j_it = Cijk.j_begin(k_it);
43  j_it != Cijk.j_end(k_it); ++j_it) {
44  ordinal_type j = index(j_it);
45  value_type val = 0;
46  for (typename Cijk_type::kji_iterator i_it = Cijk.i_begin(j_it);
47  i_it != Cijk.i_end(j_it); ++i_it) {
48  ordinal_type i = index(i_it);
49  value_type c = value(i_it) / std::sqrt(pce_norms[i]*pce_norms[j]*pce_norms[k]);
50  val += std::sqrt(pce_norms[i])*pce[i]*c;
51  }
52  A(k+1,j+1) = val;
53  }
54  }
55 
56  // Call LAPACK Householder tridiagonalization algorithm
57  // Householder vectors are stored in lower-triangular part
58  ordinal_type ws_size, info;
59  value_type ws_size_query;
60  Teuchos::Array<value_type> tau(pce_sz-1);
61  lapack.SYTRD('L', pce_sz+1, A.values(), A.stride(), &a[0], &b[0], &tau[0],
62  &ws_size_query, -1, &info);
63  TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error,
64  "SYTRD returned value " << info);
65  ws_size = static_cast<ordinal_type>(ws_size_query);
66  Teuchos::Array<value_type> work(ws_size);
67  lapack.SYTRD('L', pce_sz+1, A.values(), A.stride(), &a[0], &b[0], &tau[0],
68  &work[0], ws_size, &info);
69  TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error,
70  "SYTRD returned value " << info);
71 
72  // Set sub-diagonal terms to zero
73  for (ordinal_type j=0; j<pce_sz; j++)
74  A(j+1,j) = 0.0;
75 
76  // Now compute orthogonal matrix
77  lapack.ORGQR(pce_sz+1, pce_sz+1, pce_sz-1, A.values(), A.stride(), &tau[0],
78  &ws_size_query, -1, &info);
79  TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error,
80  "ORGQR returned value " << info);
81  ws_size = static_cast<ordinal_type>(ws_size_query);
82  work.resize(ws_size);
83  lapack.ORGQR(pce_sz+1, pce_sz+1, pce_sz-1, A.values(), A.stride(), &tau[0],
84  &work[0], ws_size, &info);
85  TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error,
86  "ORGQR returned value " << info);
87 
88  // Get basis vectors
89  for (ordinal_type j=0; j<p+1; j++)
90  for (ordinal_type i=0; i<pce_sz; i++)
91  basis_vecs(i,j) = A(i+1,j+1);
92 
93  // Setup of rest of recurrence basis
94  this->setup();
95 
96  // Project original PCE into the new basis
97  vector_type u(pce_sz);
98  for (ordinal_type i=0; i<pce_sz; i++)
99  u[i] = pce[i]*std::sqrt(pce_norms[i]);
101  0.0);
102  for (ordinal_type i=0; i<=p; i++)
103  new_pce[i] /= this->norms[i];
104 
105  std::cout << new_pce << std::endl;
106 
107  // Test orthogonality of basis vectors
108  matrix_type prod(p+1,p+1);
110  0.0);
111  for (ordinal_type j=0; j<p+1; j++)
112  prod(j,j) -= 1.0;
113  std::cout << "orthogonalization error = " << prod.normInf() << std::endl;
114  //std::cout << prod << std::endl;
115 }
116 
117 template <typename ordinal_type, typename value_type>
120 {
121 }
122 
123 template <typename ordinal_type, typename value_type>
124 void
127  Teuchos::Array<value_type>& quad_points,
128  Teuchos::Array<value_type>& quad_weights,
129  Teuchos::Array< Teuchos::Array<value_type> >& quad_values) const
130 {
131 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
132  TEUCHOS_FUNC_TIME_MONITOR("Stokhos::LanczosPCEBasis -- compute Gauss points");
133 #endif
134 
135  // Call base class
136  ordinal_type num_points =
137  static_cast<ordinal_type>(std::ceil((quad_order+1)/2.0));
138 
139  // We can't always reliably generate quadrature points of order > 2*p
140  // when using sparse grids for the underlying quadrature
141  if (limit_integration_order && quad_order > 2*this->p)
142  quad_order = 2*this->p;
144  quad_points,
145  quad_weights,
146  quad_values);
147 
148  // Fill in the rest of the points with zero weight
149  if (quad_weights.size() < num_points) {
150  ordinal_type old_size = quad_weights.size();
151  quad_weights.resize(num_points);
152  quad_points.resize(num_points);
153  quad_values.resize(num_points);
154  for (ordinal_type i=old_size; i<num_points; i++) {
155  quad_weights[i] = value_type(0);
156  quad_points[i] = quad_points[0];
157  quad_values[i].resize(this->p+1);
158  evaluateBases(quad_points[i], quad_values[i]);
159  }
160  }
161 }
162 
163 template <typename ordinal_type, typename value_type>
167 {
168  return
170  p,*this));
171 }
172 
173 template <typename ordinal_type, typename value_type>
177 {
178  return new_pce[i];
179 }
180 
181 template <typename ordinal_type, typename value_type>
182 void
185 {
186  blas.GEMV(Teuchos::NO_TRANS, pce_sz, this->p+1,
187  value_type(1.0), basis_vecs.values(), pce_sz,
188  in, ordinal_type(1), value_type(0.0), out, ordinal_type(1));
189  for (ordinal_type i=0; i<pce_sz; i++)
190  out[i] /= pce_norms[i];
191 }
192 
193 template <typename ordinal_type, typename value_type>
194 bool
200  Teuchos::Array<value_type>& gamma) const
201 {
202  // Get recurrence coefficients from the full set we already computed
203  for (ordinal_type i=0; i<n; i++) {
204  alpha[i] = a[i];
205  beta[i] = b[i];
206  delta[i] = value_type(1.0);
207  gamma[i] = b[i];
208 
209  std::cout << "i = " << i << " alpha = " << alpha[i] << " beta = " << beta[i]
210  << " gamma = " << gamma[i] << std::endl;
211  }
212 
213  return true;
214 }
215 
216 template <typename ordinal_type, typename value_type>
219  RecurrenceBasis<ordinal_type, value_type>("Householder Tridiagonalization PCE", p, false),
220  limit_integration_order(basis.limit_integration_order),
221  pce_sz(basis.pce_sz),
222  a(basis.a),
223  b(basis.b),
224  basis_vecs(basis.basis_vecs),
225  new_pce(basis.new_pce)
226 {
227  this->setup();
228 }
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
ordinal_type pce_sz
Size of PC expansion.
#define TEUCHOS_FUNC_TIME_MONITOR(FUNCNAME)
void SYTRD(const char &UPLO, const OrdinalType &n, ScalarType *A, const OrdinalType &lda, ScalarType *D, ScalarType *E, ScalarType *TAU, ScalarType *WORK, const OrdinalType &lwork, OrdinalType *info) const
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.
Data structure storing a sparse 3-tensor C(i,j,k) in a a compressed format.
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)
value_type getNewCoeffs(ordinal_type i) const
Get new coefficients in this new basis.
Teuchos::Array< value_type > pce_norms
Basis norms.
HouseTriDiagPCEBasis(ordinal_type p, const Stokhos::OrthogPolyApprox< ordinal_type, value_type > &pce, const Stokhos::Sparse3Tensor< ordinal_type, value_type > &Cijk, bool limit_integration_order=false)
Constructor.
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 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.
kj_iterator j_end(const k_iterator &k) const
Iterator pointing to last j entry for given k.
vector_type new_pce
Projection of pce in new basis.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
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.
KOKKOS_INLINE_FUNCTION PCE< Storage > ceil(const PCE< Storage > &a)
Generates three-term recurrence using the Lanczos procedure applied to a polynomial chaos expansion i...
Teuchos::LAPACK< ordinal_type, value_type > lapack
LAPACK routines.
Teuchos::RCP< const Stokhos::OrthogPolyBasis< ordinal_type, value_type > > basis() const
Return basis.
void resize(size_type new_size, const value_type &x=value_type())
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.
ScalarTraits< ScalarType >::magnitudeType normInf() const
expr val()
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.
void transformCoeffsFromHouse(const value_type *in, value_type *out) const
Map expansion coefficients from this basis to original.
kji_iterator i_begin(const kj_iterator &j) const
Iterator pointing to first i entry for given j and k.
kji_iterator i_end(const kj_iterator &j) const
Iterator pointing to last i entry for given j and k.
OrdinalType stride() const