Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Stokhos_SmolyakBasisImp.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_TimeMonitor.hpp"
12 
13 template <typename ordinal_type, typename value_type, typename ordering_type>
14 template <typename index_set_type>
18  const index_set_type& index_set,
19  const value_type& sparse_tol_,
20  const ordering_type& coeff_compare) :
21  p(0),
22  d(bases_.size()),
23  sz(0),
24  bases(bases_),
25  sparse_tol(sparse_tol_),
26  max_orders(d),
27  basis_set(coeff_compare),
28  norms()
29 {
30 
31  // Generate index set for the final Smolyak coefficients
32  //
33  // The Smolyak operator is given by the formula
34  //
35  // A = \sum_{k\in\K} \bigotimes_{i=1}^d \Delta^i_{k_i}
36  //
37  // where \Delta^i_0 = 0, \Delta^i_{k_i} = L^i_{k_i} - L^i_{k_i-1},
38  // and K is the supplied index set. This becomes
39  //
40  // A = \sum_{k\in\tilde{K}} c(k) \bigotimes_{i=1}^d L^i_{k_i}
41  //
42  // for some new index set \tilde{K} and coefficient c(k). Using the
43  // formula (cf. G W Wasilkowski and H Wozniakowski, "Explicit cost bounds
44  // of algorithms for multivariate tensor product problems,"
45  // Journal of Complexity (11), 1995)
46  //
47  // \bigotimes_{i=1}^d \Delta^i_{k_i} =
48  // \sum_{\alpha\in\Alpha} (-1)^{|\alpha|}
49  // \bigotimes_{i=1}^d L^i_{k_i-\alpha_i}
50  //
51  // where \Alpha = {0,1}^d and |\alpha| = \alpha_1 + ... + \alpha_d, we
52  // iterate over K and \Alpha, compute k-\alpha and the corresponding
53  // coefficient contribution (-1)^{|\alpha|} and store these in a map.
54  // The keys of of this map with non-zero coefficients define
55  // \tilde{K} and c(k).
56  typedef Stokhos::TensorProductIndexSet<ordinal_type> alpha_set_type;
57  typedef Stokhos::LexographicLess<multiindex_type> index_compare;
58  typedef std::map<multiindex_type,ordinal_type,index_compare> index_map_type;
59  ordinal_type dim = index_set.dimension();
60  alpha_set_type alpha_set(dim, 1);
61  typename alpha_set_type::iterator alpha_begin = alpha_set.begin();
62  typename alpha_set_type::iterator alpha_end = alpha_set.end();
63  typename index_set_type::iterator index_iterator = index_set.begin();
64  typename index_set_type::iterator index_end = index_set.end();
65  multiindex_type diff(dim);
66  index_map_type index_map;
67  for (; index_iterator != index_end; ++index_iterator) {
68  for (typename alpha_set_type::iterator alpha = alpha_begin;
69  alpha != alpha_end; ++alpha) {
70  bool valid_index = true;
71  for (ordinal_type i=0; i<dim; ++i) {
72  diff[i] = (*index_iterator)[i] - (*alpha)[i];
73  if (diff[i] < 0) {
74  valid_index = false;
75  break;
76  }
77  }
78  if (valid_index) {
79  ordinal_type alpha_order = alpha->order();
81  if (alpha_order % 2 == 0)
82  val = 1;
83  else
84  val = -1;
85  typename index_map_type::iterator index_map_iterator =
86  index_map.find(diff);
87  if (index_map_iterator == index_map.end())
88  index_map[diff] = val;
89  else
90  index_map_iterator->second += val;
91  }
92  }
93  }
94 
95  // Generate tensor product bases
96  typename index_map_type::iterator index_map_iterator = index_map.begin();
97  typename index_map_type::iterator index_map_end = index_map.end();
98  for (; index_map_iterator != index_map_end; ++index_map_iterator) {
99 
100  // Skip indices with zero coefficient
101  if (index_map_iterator->second == 0)
102  continue;
103 
104  // Apply growth rule to cofficient multi-index
105  multiindex_type coeff_growth_index(dim);
106  for (ordinal_type i=0; i<dim; ++i) {
107  coeff_growth_index[i] =
108  bases[i]->coefficientGrowth(index_map_iterator->first[i]);
109  }
110 
111  // Build tensor product basis for given index
114  bases, sparse_tol, coeff_growth_index));
115 
116  // Include coefficients in union over all sets
117  for (ordinal_type i=0; i<tp->size(); ++i)
118  basis_set[tp->term(i)] = ordinal_type(0);
119 
120  tp_bases.push_back(tp);
121  sm_pred.tp_preds.push_back(
122  TensorProductPredicate<ordinal_type>(coeff_growth_index) );
123  smolyak_coeffs.push_back(index_map_iterator->second);
124  }
125  sz = basis_set.size();
126 
127  // Generate linear odering of coefficients
128  ordinal_type idx = 0;
130  for (typename coeff_set_type::iterator i = basis_set.begin();
131  i != basis_set.end();
132  ++i) {
133  i->second = idx;
134  basis_map[idx] = i->first;
135  ++idx;
136  }
137 
138  // Compute max coefficient orders
139  for (ordinal_type i=0; i<sz; ++i) {
140  for (ordinal_type j=0; j<dim; ++j)
141  if (basis_map[i][j] > max_orders[j])
142  max_orders[j] = basis_map[i][j];
143  }
144 
145  // Resize bases to make sure they are high enough order
146  for (ordinal_type i=0; i<dim; i++)
147  if (bases[i]->order() < max_orders[i])
148  bases[i] = bases[i]->cloneWithOrder(max_orders[i]);
149 
150  // Compute largest order
151  p = 0;
152  for (ordinal_type i=0; i<d; i++) {
153  if (max_orders[i] > p)
154  p = max_orders[i];
155  }
156 
157  // Compute norms
158  norms.resize(sz);
159  value_type nrm;
160  for (ordinal_type k=0; k<sz; k++) {
161  nrm = value_type(1.0);
162  for (ordinal_type i=0; i<d; i++)
163  nrm = nrm * bases[i]->norm_squared(basis_map[k][i]);
164  norms[k] = nrm;
165  }
166 
167  // Create name
168  name = "Smolyak basis (";
169  for (ordinal_type i=0; i<d-1; i++)
170  name += bases[i]->getName() + ", ";
171  name += bases[d-1]->getName() + ")";
172 
173  // Allocate array for basis evaluation
174  basis_eval_tmp.resize(d);
175  for (ordinal_type j=0; j<d; j++)
176  basis_eval_tmp[j].resize(max_orders[j]+1);
177 }
178 
179 template <typename ordinal_type, typename value_type, typename ordering_type>
182 {
183 }
184 
185 template <typename ordinal_type, typename value_type, typename ordering_type>
188 order() const
189 {
190  return p;
191 }
192 
193 template <typename ordinal_type, typename value_type, typename ordering_type>
196 dimension() const
197 {
198  return d;
199 }
200 
201 template <typename ordinal_type, typename value_type, typename ordering_type>
204 size() const
205 {
206  return sz;
207 }
208 
209 template <typename ordinal_type, typename value_type, typename ordering_type>
213 {
214  return norms;
215 }
216 
217 template <typename ordinal_type, typename value_type, typename ordering_type>
218 const value_type&
221 {
222  return norms[i];
223 }
224 
225 template <typename ordinal_type, typename value_type, typename ordering_type>
229 {
230 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
231  TEUCHOS_FUNC_TIME_MONITOR("Stokhos: Total Triple-Product Tensor Fill Time");
232 #endif
233 
235  bases, basis_set, basis_map, sm_pred, sm_pred, sparse_tol);
236 }
237 
238 template <typename ordinal_type, typename value_type, typename ordering_type>
242 {
243 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
244  TEUCHOS_FUNC_TIME_MONITOR("Stokhos: Total Triple-Product Tensor Fill Time");
245 #endif
246 
248  for (ordinal_type i=0; i<sm_pred.tp_preds.size(); ++i) {
249  k_pred.tp_preds.push_back(
250  TotalOrderPredicate<ordinal_type>(1, sm_pred.tp_preds[i].orders) );
251  }
252 
254  bases, basis_set, basis_map, sm_pred, k_pred, sparse_tol);
255 }
256 
257 template <typename ordinal_type, typename value_type, typename ordering_type>
261 {
262  // z = psi_{i_1}(0) * ... * psi_{i_d}(0) where i_1,...,i_d are the basis
263  // terms for coefficient i
264  value_type z = value_type(1.0);
265  for (ordinal_type j=0; j<d; j++)
266  z = z * bases[j]->evaluate(value_type(0.0), basis_map[i][j]);
267 
268  return z;
269 }
270 
271 template <typename ordinal_type, typename value_type, typename ordering_type>
272 void
275  Teuchos::Array<value_type>& basis_vals) const
276 {
277  for (ordinal_type j=0; j<d; j++)
278  bases[j]->evaluateBases(point[j], basis_eval_tmp[j]);
279 
280  // Only evaluate basis upto number of terms included in basis_pts
281  for (ordinal_type i=0; i<sz; i++) {
282  value_type t = value_type(1.0);
283  for (ordinal_type j=0; j<d; j++)
284  t *= basis_eval_tmp[j][basis_map[i][j]];
285  basis_vals[i] = t;
286  }
287 }
288 
289 template <typename ordinal_type, typename value_type, typename ordering_type>
290 void
292 print(std::ostream& os) const
293 {
294  os << "Smolyak basis of order " << p << ", dimension " << d
295  << ", and size " << sz << ". Component bases:\n";
296  for (ordinal_type i=0; i<d; i++)
297  os << *bases[i];
298  os << "Basis vector norms (squared):\n\t";
299  for (ordinal_type i=0; i<static_cast<ordinal_type>(norms.size()); i++)
300  os << norms[i] << " ";
301  os << "\n";
302 }
303 
304 template <typename ordinal_type, typename value_type, typename ordering_type>
308 {
309  return basis_map[i];
310 }
311 
312 template <typename ordinal_type, typename value_type, typename ordering_type>
316 {
317  typename coeff_set_type::const_iterator it = basis_set.find(term);
318  TEUCHOS_TEST_FOR_EXCEPTION(it == basis_set.end(), std::logic_error,
319  "Invalid term " << term);
320  return it->second;
321 }
322 
323 template <typename ordinal_type, typename value_type, typename ordering_type>
324 const std::string&
326 getName() const
327 {
328  return name;
329 }
330 
331 template <typename ordinal_type, typename value_type, typename ordering_type>
335 {
336  return bases;
337 }
338 
339 template <typename ordinal_type, typename value_type, typename ordering_type>
343 {
344  return max_orders;
345 }
virtual Teuchos::RCP< Stokhos::Sparse3Tensor< ordinal_type, value_type > > computeTripleProductTensor() const
Compute triple product tensor.
#define TEUCHOS_FUNC_TIME_MONITOR(FUNCNAME)
virtual value_type evaluateZero(ordinal_type i) const
Evaluate basis polynomial i at zero.
coeff_type max_orders
Maximum orders for each dimension.
Teuchos::Array< Teuchos::RCP< const OneDOrthogPolyBasis< ordinal_type, value_type > > > getCoordinateBases() const
Return coordinate bases.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
static Teuchos::RCP< Stokhos::Sparse3Tensor< ordinal_type, value_type > > computeTripleProductTensor(const Teuchos::Array< Teuchos::RCP< const OneDOrthogPolyBasis< ordinal_type, value_type > > > &bases, const basis_set_type &basis_set, const basis_map_type &basis_map, const coeff_predicate_type &coeff_pred, const k_coeff_predicate_type &k_coeff_pred, const value_type sparse_tol=1.0e-12)
coeff_set_type basis_set
Basis set.
ordinal_type sz
Total size of basis.
SmolyakPredicate< TensorProductPredicate< ordinal_type > > sm_pred
Predicate for building sparse triple products.
ordinal_type p
Total order of basis.
virtual const MultiIndex< ordinal_type > & term(ordinal_type i) const
Get orders of each coordinate polynomial given an index i.
std::string name
Name of basis.
Teuchos::Array< value_type > norms
Norms.
virtual MultiIndex< ordinal_type > getMaxOrders() const
Return maximum order allowable for each coordinate basis.
virtual Teuchos::RCP< Stokhos::Sparse3Tensor< ordinal_type, value_type > > computeLinearTripleProductTensor() const
Compute linear triple product tensor where k = 0,1,..,d.
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)
Teuchos::Array< Teuchos::RCP< tensor_product_basis_type > > tp_bases
Tensor product bases comprising Smolyak set.
virtual ~SmolyakBasis()
Destructor.
Teuchos::Array< ordinal_type > smolyak_coeffs
Smolyak coefficients.
SmolyakBasis(const Teuchos::Array< Teuchos::RCP< const OneDOrthogPolyBasis< ordinal_type, value_type > > > &bases, const index_set_type &index_set, const value_type &sparse_tol=1.0e-12, const coeff_compare_type &coeff_compare=coeff_compare_type())
Constructor.
void resize(size_type new_size, const value_type &x=value_type())
virtual const std::string & getName() const
Return string name of basis.
Predicate functor for building sparse triple products.
Predicate functor for building sparse triple products based on total order.
ordinal_type dimension() const
Return dimension of basis.
virtual const MultiIndex< ordinal_type > & term(ordinal_type i) const
Get orders of each coordinate polynomial given an index i.
expr val()
ordinal_type d
Total dimension of basis.
void push_back(const value_type &x)
Abstract base class for 1-D orthogonal polynomials.
virtual ordinal_type size() const
Return total size of basis.
virtual ordinal_type size() const
Return total size of basis.
Teuchos::Array< Teuchos::RCP< const OneDOrthogPolyBasis< ordinal_type, value_type > > > bases
Array of bases.
A comparison functor implementing a strict weak ordering based lexographic ordering.
virtual ordinal_type index(const MultiIndex< ordinal_type > &term) const
Get index of the multivariate polynomial given orders of each coordinate.
coeff_map_type basis_map
Basis map.
Teuchos::Array< Teuchos::Array< value_type > > basis_eval_tmp
Temporary array used in basis evaluation.
ordinal_type order() const
Return order of basis.
TensorProductBasis< ordinal_type, value_type, LexographicLess< coeff_type > > tensor_product_basis_type
Predicate functor for building sparse triple products.
virtual const Teuchos::Array< value_type > & norm_squared() const
Return array storing norm-squared of each basis polynomial.
virtual void print(std::ostream &os) const
Print basis to stream os.
Teuchos::Array< tp_predicate_type > tp_preds
value_type sparse_tol
Tolerance for computing sparse Cijk.