Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Stokhos_TotalOrderBasis.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Stokhos Package
5 // Copyright (2009) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Eric T. Phipps (etphipp@sandia.gov).
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #ifndef STOKHOS_TOTAL_ORDER_BASIS_HPP
43 #define STOKHOS_TOTAL_ORDER_BASIS_HPP
44 
45 #include "Teuchos_RCP.hpp"
46 
47 #include "Stokhos_ProductBasis.hpp"
50 
51 namespace Stokhos {
52 
65  template <typename ordinal_type, typename value_type,
66  typename coeff_compare_type =
67  TotalOrderLess<MultiIndex<ordinal_type> > >
68  class TotalOrderBasis :
69  public ProductBasis<ordinal_type,value_type> {
70  public:
71 
73 
80  value_type> > >& bases,
81  const value_type& sparse_tol = 1.0e-12,
82  const coeff_compare_type& coeff_compare = coeff_compare_type());
83 
85  virtual ~TotalOrderBasis();
86 
88 
89 
91  ordinal_type order() const;
92 
94  ordinal_type dimension() const;
95 
97  virtual ordinal_type size() const;
98 
100 
104  virtual const Teuchos::Array<value_type>& norm_squared() const;
105 
107  virtual const value_type& norm_squared(ordinal_type i) const;
108 
110 
116  virtual
119 
121  virtual
124 
126  virtual value_type evaluateZero(ordinal_type i) const;
127 
129 
133  virtual void evaluateBases(
135  Teuchos::Array<value_type>& basis_vals) const;
136 
138  virtual void print(std::ostream& os) const;
139 
141  virtual const std::string& getName() const;
142 
144 
146 
147 
149 
154  virtual const MultiIndex<ordinal_type>& term(ordinal_type i) const;
155 
157 
161  virtual ordinal_type index(const MultiIndex<ordinal_type>& term) const;
162 
164 
168  value_type> > >
169  getCoordinateBases() const;
170 
172  virtual MultiIndex<ordinal_type> getMaxOrders() const;
173 
175 
176  private:
177 
178  // Prohibit copying
180 
181  // Prohibit Assignment
183 
184  protected:
185 
187  typedef std::map<coeff_type,ordinal_type,coeff_compare_type> coeff_set_type;
189 
191  std::string name;
192 
195 
198 
201 
204 
207 
210 
213 
216 
219 
222 
223  }; // class TotalOrderBasis
224 
225  // An approach for building a sparse 3-tensor only for lexicographically
226  // ordered total order basis
227  // To-do:
228  // * Remove the n_choose_k() calls
229  // * Remove the loops in the Cijk_1D_Iterator::increment() functions
230  // * Store the 1-D Cijk tensors in a compressed format and eliminate
231  // the implicit searches with getValue()
232  // * Instead of looping over (i,j,k) multi-indices we could just store
233  // the 1-D Cijk tensors as an array of (i,j,k,c) tuples.
234  template <typename ordinal_type,
235  typename value_type>
239  bool symmetric = false) {
240 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
241  TEUCHOS_FUNC_TIME_MONITOR("Stokhos: Total Triple-Product Tensor Time");
242 #endif
243  using Teuchos::RCP;
244  using Teuchos::rcp;
245  using Teuchos::Array;
246 
247  typedef MultiIndex<ordinal_type> coeff_type;
248  const Array< RCP<const OneDOrthogPolyBasis<ordinal_type, value_type> > >& bases = product_basis.getCoordinateBases();
249  ordinal_type d = bases.size();
250  //ordinal_type p = product_basis.order();
251  Array<ordinal_type> basis_orders(d);
252  for (int i=0; i<d; ++i)
253  basis_orders[i] = bases[i]->order();
254 
255  // Create 1-D triple products
257  for (ordinal_type i=0; i<d; i++) {
258  Cijk_1d[i] =
259  bases[i]->computeSparseTripleProductTensor(bases[i]->order()+1);
260  }
261 
264 
265  // Create i, j, k iterators for each dimension
267  Array<Cijk_Iterator> Cijk_1d_iterators(d);
268  coeff_type terms_i(d,0), terms_j(d,0), terms_k(d,0);
269  Array<ordinal_type> sum_i(d,0), sum_j(d,0), sum_k(d,0);
270  for (ordinal_type dim=0; dim<d; dim++) {
271  Cijk_1d_iterators[dim] = Cijk_Iterator(bases[dim]->order(), symmetric);
272  }
273 
274  ordinal_type I = 0;
275  ordinal_type J = 0;
276  ordinal_type K = 0;
277  ordinal_type cnt = 0;
278  bool stop = false;
279  while (!stop) {
280 
281  // Fill out terms from 1-D iterators
282  for (ordinal_type dim=0; dim<d; ++dim) {
283  terms_i[dim] = Cijk_1d_iterators[dim].i;
284  terms_j[dim] = Cijk_1d_iterators[dim].j;
285  terms_k[dim] = Cijk_1d_iterators[dim].k;
286  }
287 
288  // Compute global I,J,K
289  /*
290  ordinal_type II = lexicographicMapping(terms_i, p);
291  ordinal_type JJ = lexicographicMapping(terms_j, p);
292  ordinal_type KK = lexicographicMapping(terms_k, p);
293  if (I != II || J != JJ || K != KK) {
294  std::cout << "DIFF!!!" << std::endl;
295  std::cout << terms_i << ": I = " << I << ", II = " << II << std::endl;
296  std::cout << terms_j << ": J = " << J << ", JJ = " << JJ << std::endl;
297  std::cout << terms_k << ": K = " << K << ", KK = " << KK << std::endl;
298  }
299  */
300 
301  // Compute triple-product value
302  value_type c = value_type(1.0);
303  for (ordinal_type dim=0; dim<d; dim++) {
304  c *= Cijk_1d[dim]->getValue(Cijk_1d_iterators[dim].i,
305  Cijk_1d_iterators[dim].j,
306  Cijk_1d_iterators[dim].k);
307  }
308 
310  std::abs(c) <= 1.0e-12,
311  std::logic_error,
312  "Got 0 triple product value " << c
313  << ", I = " << I << " = " << terms_i
314  << ", J = " << J << " = " << terms_j
315  << ", K = " << K << " = " << terms_k
316  << std::endl);
317 
318  // Add term to global Cijk
319  Cijk->add_term(I,J,K,c);
320  // Cijk->add_term(I,K,J,c);
321  // Cijk->add_term(J,I,K,c);
322  // Cijk->add_term(J,K,I,c);
323  // Cijk->add_term(K,I,J,c);
324  // Cijk->add_term(K,J,I,c);
325 
326  // Increment iterators to the next valid term
327  ordinal_type cdim = d-1;
328  bool inc = true;
329  while (inc && cdim >= 0) {
330  ordinal_type delta_i, delta_j, delta_k;
331  bool more =
332  Cijk_1d_iterators[cdim].increment(delta_i, delta_j, delta_k);
333 
334  // Update number of terms used for computing global index
335  if (cdim == d-1) {
336  I += delta_i;
337  J += delta_j;
338  K += delta_k;
339  }
340  else {
341  if (delta_i > 0) {
342  for (ordinal_type ii=0; ii<delta_i; ++ii)
343  I +=
345  basis_orders[cdim+1]-sum_i[cdim] -
346  (Cijk_1d_iterators[cdim].i-ii)+d-cdim,
347  d-cdim-1);
348  }
349  else {
350  for (ordinal_type ii=0; ii<-delta_i; ++ii)
351  I -=
353  basis_orders[cdim+1]-sum_i[cdim] -
354  (Cijk_1d_iterators[cdim].i+ii)+d-cdim-1,
355  d-cdim-1);
356  }
357 
358  if (delta_j > 0) {
359  for (ordinal_type jj=0; jj<delta_j; ++jj)
360  J +=
362  basis_orders[cdim+1]-sum_j[cdim] -
363  (Cijk_1d_iterators[cdim].j-jj)+d-cdim,
364  d-cdim-1);
365  }
366  else {
367  for (ordinal_type jj=0; jj<-delta_j; ++jj)
368  J -=
370  basis_orders[cdim+1]-sum_j[cdim] -
371  (Cijk_1d_iterators[cdim].j+jj)+d-cdim-1,
372  d-cdim-1);
373  }
374 
375  if (delta_k > 0) {
376  for (ordinal_type kk=0; kk<delta_k; ++kk)
377  K +=
379  basis_orders[cdim+1]-sum_k[cdim] -
380  (Cijk_1d_iterators[cdim].k-kk)+d-cdim,
381  d-cdim-1);
382  }
383  else {
384  for (ordinal_type kk=0; kk<-delta_k; ++kk)
385  K -=
387  basis_orders[cdim+1]-sum_k[cdim] -
388  (Cijk_1d_iterators[cdim].k+kk)+d-cdim-1,
389  d-cdim-1);
390  }
391  }
392 
393  if (!more) {
394  // If no more terms in this dimension, go to previous one
395  --cdim;
396  }
397  else {
398  // cdim has more terms, so reset iterators for all dimensions > cdim
399  // adjusting max order based on sum of i,j,k for previous dims
400  inc = false;
401 
402  for (ordinal_type dim=cdim+1; dim<d; ++dim) {
403 
404  // Update sums of orders for previous dimension
405  sum_i[dim] = sum_i[dim-1] + Cijk_1d_iterators[dim-1].i;
406  sum_j[dim] = sum_j[dim-1] + Cijk_1d_iterators[dim-1].j;
407  sum_k[dim] = sum_k[dim-1] + Cijk_1d_iterators[dim-1].k;
408 
409  // Reset iterator for this dimension
410  Cijk_1d_iterators[dim] =
411  Cijk_Iterator(basis_orders[dim]-sum_i[dim],
412  basis_orders[dim]-sum_j[dim],
413  basis_orders[dim]-sum_k[dim],
414  symmetric);
415  }
416  }
417  }
418 
419  if (cdim < 0)
420  stop = true;
421 
422  cnt++;
423  }
424 
425  Cijk->fillComplete();
426 
427  return Cijk;
428  }
429 
430 } // Namespace Stokhos
431 
432 // Include template definitions
434 
435 #endif
Teuchos::Array< value_type > norms
Norms.
coeff_map_type basis_map
Basis map.
virtual ordinal_type size() const
Return total size of basis.
#define TEUCHOS_FUNC_TIME_MONITOR(FUNCNAME)
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::Array< Teuchos::Array< value_type > > basis_eval_tmp
Temporary array used in basis evaluation.
ordinal_type n_choose_k(const ordinal_type &n, const ordinal_type &k)
Compute bionomial coefficient (n ; k) = n!/( k! (n-k)! )
virtual const MultiIndex< ordinal_type > & term(ordinal_type i) const
Get orders of each coordinate polynomial given an index i.
Teuchos::RCP< Sparse3Tensor< ordinal_type, value_type > > computeTripleProductTensorLTO(const TotalOrderBasis< ordinal_type, value_type, LexographicLess< MultiIndex< ordinal_type > > > &product_basis, bool symmetric=false)
Multivariate orthogonal polynomial basis generated from a total order tensor product of univariate po...
Data structure storing a sparse 3-tensor C(i,j,k) in a a compressed format.
ordinal_type sz
Total size of basis.
ordinal_type dimension() const
Return dimension of basis.
TotalOrderBasis & operator=(const TotalOrderBasis &b)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
virtual Teuchos::RCP< Stokhos::Sparse3Tensor< ordinal_type, value_type > > computeTripleProductTensor() const
Compute triple product tensor.
coeff_type max_orders
Maximum orders for each dimension.
virtual Teuchos::RCP< Stokhos::Sparse3Tensor< ordinal_type, value_type > > computeLinearTripleProductTensor() const
Compute linear triple product tensor where k = 0,1,..,d.
TotalOrderBasis(const Teuchos::Array< Teuchos::RCP< const OneDOrthogPolyBasis< ordinal_type, value_type > > > &bases, const value_type &sparse_tol=1.0e-12, const coeff_compare_type &coeff_compare=coeff_compare_type())
Constructor.
virtual value_type evaluateZero(ordinal_type i) const
Evaluate basis polynomial i at zero.
virtual MultiIndex< ordinal_type > getMaxOrders() const
Return maximum order allowable for each coordinate basis.
ordinal_type d
Total dimension of basis.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
MultiIndex< ordinal_type > coeff_type
value_type sparse_tol
Tolerance for computing sparse Cijk.
Teuchos::Array< coeff_type > coeff_map_type
coeff_set_type basis_set
Basis set.
std::string name
Name of basis.
KOKKOS_INLINE_FUNCTION PCE< Storage > abs(const PCE< Storage > &a)
Abstract base class for multivariate orthogonal polynomials generated from tensor products of univari...
std::map< coeff_type, ordinal_type, coeff_compare_type > coeff_set_type
Abstract base class for 1-D orthogonal polynomials.
Teuchos::Array< Teuchos::RCP< const OneDOrthogPolyBasis< ordinal_type, value_type > > > bases
Array of bases.
size_type size() const
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.
ordinal_type order() const
Return order of basis.
virtual void print(std::ostream &os) const
Print basis to stream os.
virtual ~TotalOrderBasis()
Destructor.
virtual const Teuchos::Array< value_type > & norm_squared() const
Return array storing norm-squared of each basis polynomial.
Teuchos::Array< Teuchos::RCP< const OneDOrthogPolyBasis< ordinal_type, value_type > > > getCoordinateBases() const
Return coordinate bases.
virtual const std::string & getName() const
Return string name of basis.
ordinal_type p
Total order of basis.