Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Stokhos_GramSchmidtBasisImp.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_BLAS.hpp"
11 
12 template <typename ordinal_type, typename value_type>
15  const Teuchos::RCP<const OrthogPolyBasis<ordinal_type,value_type> >& basis_,
17  const Teuchos::Array<value_type>& weights_,
18  const value_type& sparse_tol_) :
19  name("Gram Schmidt Basis"),
20  basis(basis_),
21  weights(weights_),
22  sparse_tol(sparse_tol_),
23  p(basis->order()),
24  d(basis->dimension()),
25  sz(basis->size()),
26  norms(sz),
27  gs_mat(sz,sz),
28  basis_vals_tmp(sz)
29 {
30  // Get quadrature data
31  ordinal_type nqp = weights.size();
33  for (ordinal_type k=0; k<nqp; k++) {
34  values[k].resize(sz);
35  basis->evaluateBases(points[k], values[k]);
36  }
37 
38  // Compute all inner products
40  inner_product.putScalar(0.0);
41  for (ordinal_type i=0; i<sz; i++) {
42  for (ordinal_type j=0; j<=i; j++) {
43  value_type t = 0.0;
44  for (ordinal_type k=0; k<nqp; k++)
45  t += weights[k]*values[k][i]*values[k][j];
46  inner_product(i,j) = t;
47  }
48  }
49 
50  // Classical Gram-Schmidt algorithm:
51  // u_i = v_i - \sum_{j<i} (v_i,u_j)/(u_j,u_j) u_j
52  // u_j = \sum_{k<=i} a_{jk} v_k
53  // => u_i = v_i - \sum_{j<i}\sum_{k<=j} (v_i,u_j)/(u_j,u_j)*a_{jk}*v_k
54  for (ordinal_type i=0; i<sz; i++) {
55 
56  // a_{ii} = 1.0
57  gs_mat(i,i) = 1.0;
58 
59  for (ordinal_type j=0; j<i; j++) {
60 
61  // compute t = (v_i,u_j)/(u_j,u_j)
62  value_type t = 0.0;
63  for (ordinal_type k=0; k<=j; k++)
64  t += gs_mat(j,k)*inner_product(i,k);
65  t /= norms[j];
66 
67  // substract contribution to a_{ik}: t*a_{jk}
68  for (ordinal_type k=0; k<=j; k++)
69  gs_mat(i,k) -= t*gs_mat(j,k);
70  }
71 
72  // compute (u_i,u_i) = \sum_{j,k<=i} a_{ij}*a_{ik}*(v_j,v_k)
73  value_type nrm = 0.0;
74  for (ordinal_type j=0; j<=i; j++) {
75  for (ordinal_type k=0; k<=j; k++)
76  nrm += gs_mat(i,j)*gs_mat(i,k)*inner_product(j,k);
77  for (ordinal_type k=j+1; k<=i; k++)
78  nrm += gs_mat(i,j)*gs_mat(i,k)*inner_product(k,j);
79  }
80  norms[i] = nrm;
81 
82  }
83 
84  basis_values.resize(nqp);
85  for (ordinal_type k=0; k<nqp; k++) {
86  basis_values[k].resize(sz);
87  for (ordinal_type i=0; i<sz; i++) {
88  value_type t = 0.0;
89  for (ordinal_type j=0; j<=i; j++)
90  t += gs_mat(i,j)*values[k][j];
91  basis_values[k][i] = t;
92  }
93  }
94 }
95 
96 template <typename ordinal_type, typename value_type>
99 {
100 }
101 
102 template <typename ordinal_type, typename value_type>
105 order() const
106 {
107  return p;
108 }
109 
110 template <typename ordinal_type, typename value_type>
113 dimension() const
114 {
115  return d;
116 }
117 
118 template <typename ordinal_type, typename value_type>
121 size() const
122 {
123  return sz;
124 }
125 
126 template <typename ordinal_type, typename value_type>
129 norm_squared() const
130 {
131  return norms;
132 }
133 
134 template <typename ordinal_type, typename value_type>
135 const value_type&
137 norm_squared(ordinal_type i) const
138 {
139  return norms[i];
140 }
141 
142 template <typename ordinal_type, typename value_type>
146 {
148  Teuchos::rcp(new Sparse3Tensor<ordinal_type, value_type>);
149  ordinal_type nqp = weights.size();
150  for (ordinal_type j=0; j<sz; j++) {
151  for (ordinal_type i=0; i<sz; i++) {
152  for (ordinal_type k=0; k<sz; k++) {
153  value_type t = 0.0;
154  for (ordinal_type l=0; l<nqp; l++)
155  t +=
156  weights[l]*basis_values[l][i]*basis_values[l][j]*basis_values[l][k];
157  if (std::abs(t) > sparse_tol)
158  Cijk->add_term(i,j,k,t);
159  }
160  }
161  }
162 
163  Cijk->fillComplete();
164 
165  return Cijk;
166 }
167 
168 template <typename ordinal_type, typename value_type>
172 {
174  Teuchos::rcp(new Sparse3Tensor<ordinal_type, value_type>);
175  ordinal_type nqp = weights.size();
176  for (ordinal_type j=0; j<sz; j++) {
177  for (ordinal_type i=0; i<sz; i++) {
178  for (ordinal_type k=0; k<d+1; k++) {
179  value_type t = 0.0;
180  for (ordinal_type l=0; l<nqp; l++)
181  t +=
182  weights[l]*basis_values[l][i]*basis_values[l][j]*basis_values[l][k];
183  if (std::abs(t) > sparse_tol)
184  Cijk->add_term(i,j,k,t);
185  }
186  }
187  }
188 
189  Cijk->fillComplete();
190 
191  return Cijk;
192 }
193 
194 template <typename ordinal_type, typename value_type>
197 evaluateZero(ordinal_type i) const
198 {
199  value_type z = 0.0;
200  for (ordinal_type j=0; j<sz; j++)
201  z += gs_mat(i,j)*basis->evaluateZero(j);
202 
203  return z;
204 }
205 
206 template <typename ordinal_type, typename value_type>
207 void
210  Teuchos::Array<value_type>& basis_vals) const
211 {
212  basis->evaluateBases(point, basis_vals_tmp);
213  for (ordinal_type i=0; i<sz; i++) {
214  value_type t = 0.0;
215  for (ordinal_type j=0; j<sz; j++)
216  t += gs_mat(i,j)*basis_vals_tmp[j];
217  basis_vals[i] = t;
218  }
219 }
220 
221 template <typename ordinal_type, typename value_type>
222 void
224 print(std::ostream& os) const
225 {
226  os << "Gram-Schmidt basis of order " << p << ", dimension " << d
227  << ", and size " << sz << ". Matrix coefficients:\n";
228  os << printMat(gs_mat) << std::endl;
229  os << "Basis vector norms (squared):\n\t";
230  for (ordinal_type i=0; i<sz; i++)
231  os << norms[i] << " ";
232  os << "\n";
233  os << "Underlying basis:\n";
234  os << *basis;
235 }
236 
237 template <typename ordinal_type, typename value_type>
238 const std::string&
240 getName() const
241 {
242  return name;
243 }
244 
245 template <typename ordinal_type, typename value_type>
246 void
248 transformCoeffs(const value_type *in, value_type *out) const
249 {
251  for (ordinal_type i=0; i<sz; i++)
252  out[i] = in[i];
254  Teuchos::UNIT_DIAG, sz, 1, 1.0, gs_mat.values(), sz, out, sz);
255 }
void TRSM(ESide side, EUplo uplo, ETransp transa, EDiag diag, const OrdinalType &m, const OrdinalType &n, const alpha_type alpha, const A_type *A, const OrdinalType &lda, ScalarType *B, const OrdinalType &ldb) const
SerialBandDenseMatrixPrinter< OrdinalType, ScalarType > printMat(const SerialBandDenseMatrix< OrdinalType, ScalarType > &obj)
virtual Teuchos::RCP< Stokhos::Sparse3Tensor< ordinal_type, value_type > > computeTripleProductTensor() const =0
Compute triple product tensor.
virtual ordinal_type order() const =0
Return order of basis.
virtual void evaluateBases(const Teuchos::ArrayView< const value_type > &point, Teuchos::Array< value_type > &basis_vals) const =0
Evaluate basis polynomials at given point point.
virtual ordinal_type dimension() const =0
Return dimension of basis.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual value_type evaluateZero(ordinal_type i) const =0
Evaluate basis polynomial i at zero.
Transforms a non-orthogonal multivariate basis to an orthogonal one using the Gram-Schmit procedure...
KOKKOS_INLINE_FUNCTION PCE< Storage > abs(const PCE< Storage > &a)
virtual const Teuchos::Array< value_type > & norm_squared() const =0
Return array storing norm-squared of each basis polynomial.
virtual void print(std::ostream &os) const =0
Print basis to stream os.
virtual Teuchos::RCP< Stokhos::Sparse3Tensor< ordinal_type, value_type > > computeLinearTripleProductTensor() const =0
Compute linear triple product tensor where k = 0,1.
virtual ordinal_type size() const =0
Return total size of basis.
virtual const std::string & getName() const =0
Return string name of basis.