Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Stokhos_SmolyakPseudoSpectralOperatorImp.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 template <typename ordinal_type, typename value_type,
11  typename point_compare_type>
12 template <typename coeff_compare_type>
16  bool use_smolyak_apply,
17  bool use_pst,
18  const point_compare_type& point_compare) :
19  use_smolyak(use_smolyak_apply),
20  points(point_compare) {
21 
23  typedef typename smolyak_basis_type::tensor_product_basis_type tensor_product_basis_type;
24 
25  // Generate sparse grid and tensor operators
26  coeff_sz = smolyak_basis.size();
27  ordinal_type dim = smolyak_basis.dimension();
28  ordinal_type num_terms = smolyak_basis.getNumSmolyakTerms();
29  for (ordinal_type i=0; i<num_terms; ++i) {
30 
31  // Get tensor product basis for given term
33  smolyak_basis.getTensorProductBasis(i);
34 
35  // Get coefficient multi-index defining basis orders
36  multiindex_type coeff_index = tp_basis->getMaxOrders();
37 
38  // Apply growth rule to cofficient multi-index
39  multiindex_type point_growth_index(dim);
40  for (ordinal_type j=0; j<dim; ++j) {
41  point_growth_index[j] =
42  smolyak_basis.getCoordinateBases()[j]->pointGrowth(coeff_index[j]);
43  }
44 
45  // Build tensor product operator for given index
47  Teuchos::rcp(new operator_type(*tp_basis, use_pst,
48  point_growth_index));
49  if (use_smolyak)
50  operators.push_back(op);
51 
52  // Get smolyak cofficient for given index
53  value_type c = smolyak_basis.getSmolyakCoefficient(i);
54  if (use_smolyak)
56 
57  // Include points in union over all sets
58  typename operator_type::set_iterator op_set_iterator = op->set_begin();
59  typename operator_type::set_iterator op_set_end = op->set_end();
60  for (; op_set_iterator != op_set_end; ++op_set_iterator) {
61  const point_type& point = op_set_iterator->first;
62  value_type w = op_set_iterator->second.first;
63  set_iterator si = points.find(point);
64  if (si == points.end())
65  points[point] = std::make_pair(c*w,ordinal_type(0));
66  else
67  si->second.first += c*w;
68  }
69 
70  }
71 
72  // Generate linear ordering of points
73  ordinal_type idx = 0;
74  point_map.resize(points.size());
75  for (set_iterator si = points.begin(); si != points.end(); ++si) {
76  si->second.second = idx;
77  point_map[idx] = si->first;
78  ++idx;
79  }
80 
81  if (use_smolyak) {
82 
83  // Build gather/scatter maps into global domain/range for each operator
84  gather_maps.resize(operators.size());
85  scatter_maps.resize(operators.size());
86  for (ordinal_type i=0; i<operators.size(); i++) {
88 
89  gather_maps[i].reserve(op->point_size());
90  typename operator_type::iterator op_iterator = op->begin();
91  typename operator_type::iterator op_end = op->end();
92  for (; op_iterator != op_end; ++op_iterator) {
93  gather_maps[i].push_back(points[*op_iterator].second);
94  }
95 
97  smolyak_basis.getTensorProductBasis(i);
98  ordinal_type op_coeff_sz = tp_basis->size();
99  scatter_maps[i].reserve(op_coeff_sz);
100  for (ordinal_type j=0; j<op_coeff_sz; ++j) {
101  scatter_maps[i].push_back(smolyak_basis.index(tp_basis->term(j)));
102  }
103  }
104  }
105 
106  //else {
107 
108  // Generate quadrature operator
109  ordinal_type nqp = points.size();
110  ordinal_type npc = coeff_sz;
111  qp2pce.reshape(npc,nqp);
112  pce2qp.reshape(nqp,npc);
113  qp2pce.putScalar(1.0);
114  pce2qp.putScalar(1.0);
115  Teuchos::Array<value_type> vals(npc);
116  for (set_iterator si = points.begin(); si != points.end(); ++si) {
117  ordinal_type j = si->second.second;
118  value_type w = si->second.first;
119  point_type point = si->first;
120  smolyak_basis.evaluateBases(point, vals);
121  for (ordinal_type i=0; i<npc; ++i) {
122  qp2pce(i,j) = w*vals[i] / smolyak_basis.norm_squared(i);
123  pce2qp(j,i) = vals[i];
124  }
125  }
126  //}
127 
128 }
129 
130 template <typename ordinal_type, typename value_type,
131  typename point_compare_type>
132 void
135  const value_type& alpha,
138  const value_type& beta,
139  bool trans) const {
140 
141  if (use_smolyak)
142  transformQP2PCE_smolyak(alpha, input, result, beta, trans);
143  else
144  apply_direct(qp2pce, alpha, input, result, beta, trans);
145 }
146 
147 template <typename ordinal_type, typename value_type,
148  typename point_compare_type>
149 void
152  const value_type& alpha,
155  const value_type& beta,
156  bool trans) const {
157 
158  // Currently we use the direct method for mapping PCE->QP because the
159  // current implementation doesn't work. Need to evaluate tensor bases
160  // on all quad points, not just the quad points associated with that
161  // basis.
162 
163  // if (use_smolyak)
164  // transformPCE2QP_smolyak(alpha, input, result, beta, trans);
165  // else
166  apply_direct(pce2qp, alpha, input, result, beta, trans);
167 }
168 
169 template <typename ordinal_type, typename value_type,
170  typename point_compare_type>
171 void
175  const value_type& alpha,
178  const value_type& beta,
179  bool trans) const {
180  if (trans) {
181  TEUCHOS_ASSERT(input.numCols() <= A.numCols());
182  TEUCHOS_ASSERT(result.numCols() == A.numRows());
183  TEUCHOS_ASSERT(result.numRows() == input.numRows());
184  blas.GEMM(Teuchos::NO_TRANS, Teuchos::TRANS, input.numRows(),
185  A.numRows(), input.numCols(), alpha, input.values(),
186  input.stride(), A.values(), A.stride(), beta,
187  result.values(), result.stride());
188  }
189  else {
190  TEUCHOS_ASSERT(input.numRows() <= A.numCols());
191  TEUCHOS_ASSERT(result.numRows() == A.numRows());
192  TEUCHOS_ASSERT(result.numCols() == input.numCols());
194  input.numCols(), input.numRows(), alpha, A.values(),
195  A.stride(), input.values(), input.stride(), beta,
196  result.values(), result.stride());
197  }
198 }
199 
200 template <typename ordinal_type, typename value_type,
201  typename point_compare_type>
202 void
205  const value_type& alpha,
208  const value_type& beta,
209  bool trans) const {
211  result.scale(beta);
212  for (ordinal_type i=0; i<operators.size(); i++) {
213  Teuchos::RCP<operator_type> op = operators[i];
214  if (trans) {
215  op_input.reshape(input.numRows(), op->point_size());
216  op_result.reshape(result.numRows(), op->coeff_size());
217  }
218  else {
219  op_input.reshape(op->point_size(), input.numCols());
220  op_result.reshape(op->coeff_size(), result.numCols());
221  }
222  gather(gather_maps[i], input, trans, op_input);
223  op->transformQP2PCE(smolyak_coeffs[i], op_input, op_result, 0.0, trans);
224  scatter(scatter_maps[i], op_result, trans, result);
225  }
226 }
227 
228 template <typename ordinal_type, typename value_type,
229  typename point_compare_type>
230 void
233  const value_type& alpha,
236  const value_type& beta,
237  bool trans) const {
239  result.scale(beta);
240 
241  for (ordinal_type i=0; i<operators.size(); i++) {
242  Teuchos::RCP<operator_type> op = operators[i];
243  if (trans) {
244  op_input.reshape(input.numRows(), op->coeff_size());
245  op_result.reshape(result.numRows(), op->point_size());
246  }
247  else {
248  op_input.reshape(op->coeff_size(), input.numCols());
249  op_result.reshape(op->point_size(), result.numCols());
250  }
251 
252  gather(scatter_maps[i], input, trans, op_input);
253  op->transformPCE2QP(smolyak_coeffs[i], op_input, op_result, 0.0, trans);
254  scatter(gather_maps[i], op_result, trans, result);
255  }
256 }
257 
258 template <typename ordinal_type, typename value_type,
259  typename point_compare_type>
260 void
265  bool trans,
267  if (trans) {
268  for (ordinal_type j=0; j<map.size(); j++)
269  for (ordinal_type i=0; i<input.numRows(); i++)
270  result(i,j) = input(i,map[j]);
271  }
272  else {
273  for (ordinal_type j=0; j<input.numCols(); j++)
274  for (ordinal_type i=0; i<map.size(); i++)
275  result(i,j) = input(map[i],j);
276  }
277 }
278 
279 template <typename ordinal_type, typename value_type,
280  typename point_compare_type>
281 void
286  bool trans,
288  if (trans) {
289  for (ordinal_type j=0; j<map.size(); j++)
290  for (ordinal_type i=0; i<input.numRows(); i++)
291  result(i,map[j]) += input(i,j);
292  }
293  else {
294  for (ordinal_type j=0; j<input.numCols(); j++)
295  for (ordinal_type i=0; i<map.size(); i++)
296  result(map[i],j) += input(i,j);
297  }
298 }
ScalarType * values() const
Teuchos::SerialDenseMatrix< ordinal_type, value_type > pce2qp
Matrix mapping coefficients to points.
void apply_direct(const Teuchos::SerialDenseMatrix< ordinal_type, value_type > &A, const value_type &alpha, const Teuchos::SerialDenseMatrix< ordinal_type, value_type > &input, Teuchos::SerialDenseMatrix< ordinal_type, value_type > &result, const value_type &beta, bool trans) const
Apply transformation operator using direct method.
point_map_type point_map
Map index to sparse grid term.
Teuchos::SerialDenseMatrix< ordinal_type, value_type > qp2pce
Matrix mapping points to coefficients.
Container storing a term in a generalized tensor product.
Teuchos::Array< Teuchos::RCP< const OneDOrthogPolyBasis< ordinal_type, value_type > > > getCoordinateBases() const
Return coordinate bases.
set_iterator set_begin()
Iterator to begining of point set.
ordinal_type getNumSmolyakTerms() const
Return number of terms in Smolyak formula.
int scale(const ScalarType alpha)
ordinal_type getSmolyakCoefficient(ordinal_type i) const
Return ith smolyak coefficient.
Teuchos::Array< Teuchos::Array< ordinal_type > > gather_maps
Gather maps for each operator for Smolyak apply.
Teuchos::Array< Teuchos::Array< ordinal_type > > scatter_maps
Scatter maps for each operator for Smolyak apply.
virtual void evaluateBases(const Teuchos::ArrayView< const value_type > &point, Teuchos::Array< value_type > &basis_vals) const
Evaluate basis polynomials at given point point.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
int putScalar(const ScalarType value=Teuchos::ScalarTraits< ScalarType >::zero())
void transformQP2PCE(const value_type &alpha, const Teuchos::SerialDenseMatrix< ordinal_type, value_type > &input, Teuchos::SerialDenseMatrix< ordinal_type, value_type > &result, const value_type &beta, bool trans=false) const
Transform values at quadrature points to PCE coefficients.
void transformPCE2QP_smolyak(const value_type &alpha, const Teuchos::SerialDenseMatrix< ordinal_type, value_type > &input, Teuchos::SerialDenseMatrix< ordinal_type, value_type > &result, const value_type &beta, bool trans) const
Transform PCE coefficients to values at quadrature points using Smolyak formula.
void scatter(const Teuchos::Array< ordinal_type > &map, const Teuchos::SerialDenseMatrix< ordinal_type, value_type > &input, bool trans, Teuchos::SerialDenseMatrix< ordinal_type, value_type > &result) const
void gather(const Teuchos::Array< ordinal_type > &map, const Teuchos::SerialDenseMatrix< ordinal_type, value_type > &input, bool trans, Teuchos::SerialDenseMatrix< ordinal_type, value_type > &result) const
Teuchos::Array< value_type > smolyak_coeffs
Smolyak coefficients.
void resize(size_type new_size, const value_type &x=value_type())
Multivariate orthogonal polynomial basis generated from a Smolyak sparse grid.
ordinal_type dimension() const
Return dimension of basis.
OrdinalType numCols() const
void push_back(const value_type &x)
virtual ordinal_type size() const
Return total size of basis.
int reshape(OrdinalType numRows, OrdinalType numCols)
size_type size() const
Teuchos::RCP< const tensor_product_basis_type > getTensorProductBasis(ordinal_type i) const
Return ith tensor product basis.
virtual ordinal_type index(const MultiIndex< ordinal_type > &term) const
Get index of the multivariate polynomial given orders of each coordinate.
void transformQP2PCE_smolyak(const value_type &alpha, const Teuchos::SerialDenseMatrix< ordinal_type, value_type > &input, Teuchos::SerialDenseMatrix< ordinal_type, value_type > &result, const value_type &beta, bool trans) const
Transform values at quadrature points to PCE coefficients using Smolyak formula.
TEUCHOSCOMM_LIB_DLL_EXPORT void scatter(const int sendBuf[], const int sendCount, int recvBuf[], const int recvCount, const int root, const Comm< int > &comm)
SmolyakPseudoSpectralOperator(const SmolyakBasis< ordinal_type, value_type, coeff_compare_type > &smolyak_basis, bool use_smolyak_apply=true, bool use_pst=true, const point_compare_type &point_compare=point_compare_type())
Constructor.
const point_type & point(ordinal_type n) const
Get point for given index.
TensorProductPseudoSpectralOperator< ordinal_type, value_type > operator_type
#define TEUCHOS_ASSERT(assertion_test)
virtual const Teuchos::Array< value_type > & norm_squared() const
Return array storing norm-squared of each basis polynomial.
OrdinalType stride() const
virtual void transformPCE2QP(const value_type &alpha, const Teuchos::SerialDenseMatrix< ordinal_type, value_type > &input, Teuchos::SerialDenseMatrix< ordinal_type, value_type > &result, const value_type &beta, bool trans=false) const
Transform PCE coefficients to quadrature values.
OrdinalType numRows() const
operator_set_type operators
Tensor pseudospectral operators.