Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Stokhos_ProductBasisUtilsUnitTest.cpp
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 
14 #include "Teuchos_ArrayView.hpp"
15 
16 #include "Stokhos.hpp"
18 
19 #include <iterator>
20 #include <set>
21 
22 namespace ProductBasisUtilsUnitTest {
23 
24  // Common setup for unit tests
25  template <typename OrdinalType, typename ValueType>
26  struct UnitTestSetup {
27  ValueType rtol, atol;
28  OrdinalType sz,p,d;
29 
31  rtol = 1e-12;
32  atol = 1e-12;
33  d = 3;
34  p = 5;
35  }
36 
37  };
38 
39  typedef int ordinal_type;
40  typedef double value_type;
42 
43  // Utility function for computing factorials
44  template <typename ordinal_type>
46  ordinal_type res = 1;
47  for (ordinal_type i=1; i<=n; ++i)
48  res *= i;
49  return res;
50  }
51 
52  // Function for testing quadratures
53  template <typename scalar_type>
55  scalar_type val = 0.0;
56  for (int i=0; i<x.size(); i++)
57  val += x[i];
58  return std::exp(val);
59  }
60 
61  // Function for testing quadratures
62  template <typename scalar_type>
64  scalar_type val = 0.0;
65  for (int i=0; i<x.size(); i++)
66  val += x[i];
67  return std::sin(val);
68  }
69 
70  TEUCHOS_UNIT_TEST( Stokhos_ProductBasisUtils, NChooseK ) {
71  ordinal_type n, k, v1, v2;
72 
73  success = true;
74 
75  n = 7; k = 3; // n-k > k
76  v1 = Stokhos::n_choose_k(n,k);
77  v2 = factorial(n)/(factorial(k)*factorial(n-k));
78  if (v1 != v2) {
79  out << "For n =" << n << ", k = " << k << ", n_choose_k = " << v1
80  << " != " << v2 << std::endl;
81  success = false;
82  }
83 
84  n = 7; k = 4; // n-k < k
85  v1 = Stokhos::n_choose_k(n,k);
86  v2 = factorial(n)/(factorial(k)*factorial(n-k));
87  if (v1 != v2) {
88  out << "For n =" << n << ", k = " << k << ", n_choose_k = " << v1
89  << " != " << v2 << std::endl;
90  success = false;
91  }
92 
93  }
94 
95  TEUCHOS_UNIT_TEST( Stokhos_ProductBasisUtils, TotalOrderLess ) {
96  success = true;
97 
98  // Build sorted index set of dimension d and order p
99  typedef Stokhos::TotalOrderIndexSet<ordinal_type> index_set_type;
100  typedef index_set_type::multiindex_type multiindex_type;
102  typedef std::set<multiindex_type, less_type> multiindex_set;
103  typedef multiindex_set::iterator iterator;
104  index_set_type indexSet(setup.d, 0, setup.p);
105  multiindex_set sortedIndexSet(indexSet.begin(), indexSet.end());
106 
107  // Print sorted index set
108  std::ostream_iterator<multiindex_type> out_iterator(out, "\n");
109  out << std::endl << "Sorted total order index set (dimension = " << setup.d
110  << ", order = " << setup.p << "):" << std::endl;
111  std::copy(sortedIndexSet.begin(), sortedIndexSet.end(), out_iterator);
112 
113  // Ensure orders of each index are increasing
114  iterator prev = sortedIndexSet.begin();
115  iterator curr = prev; ++curr;
116  while (curr != sortedIndexSet.end()) {
117  ordinal_type order_prev = prev->order();
118  ordinal_type order_curr = curr->order();
119  ordinal_type i = 0;
120  while (i < setup.d && order_prev == order_curr) {
121  order_prev -= (*prev)[i];
122  order_curr -= (*curr)[i];
123  ++i;
124  }
125  if (order_prev >= order_curr) {
126  out << "previous index " << *prev << " and current index "
127  << *curr << " are out of order" << std::endl;
128  success = false;
129  }
130  prev = curr;
131  ++curr;
132  }
133  }
134 
135  TEUCHOS_UNIT_TEST( Stokhos_ProductBasisUtils, LexographicLess ) {
136  success = true;
137 
138  // Build sorted index set of dimension d and order p
139  typedef Stokhos::TotalOrderIndexSet<ordinal_type> index_set_type;
140  typedef index_set_type::multiindex_type multiindex_type;
142  typedef std::set<multiindex_type, less_type> multiindex_set;
143  typedef multiindex_set::iterator iterator;
144  index_set_type indexSet(setup.d, 0, setup.p);
145  multiindex_set sortedIndexSet(indexSet.begin(), indexSet.end());
146 
147  // Print sorted index set
148  std::ostream_iterator<multiindex_type> out_iterator(out, "\n");
149  out << std::endl << "Sorted lexicographic index set (dimension = "
150  << setup.d << ", order = " << setup.p << "):" << std::endl;
151  std::copy(sortedIndexSet.begin(), sortedIndexSet.end(), out_iterator);
152 
153  // Ensure orders of each index are increasing
154  iterator prev = sortedIndexSet.begin();
155  iterator curr = prev; ++curr;
156  while (curr != sortedIndexSet.end()) {
157  ordinal_type i = 0;
158  while (i < setup.d && (*prev)[i] == (*curr)[i]) ++i;
159  if (i == setup.d || (*prev)[i] >= (*curr)[i]) {
160  out << "previous index " << *prev << " and current index "
161  << *curr << " are out of order" << std::endl;
162  success = false;
163  }
164  prev = curr;
165  ++curr;
166  }
167  }
168 
169  TEUCHOS_UNIT_TEST( Stokhos_ProductBasisUtils, FloatingPointLess ) {
170  success = true;
171 
172  value_type tol=1e-12;
174 
175  TEUCHOS_TEST_EQUALITY(less(-0.774597,-0.774597), false, out, success);
176  TEUCHOS_TEST_EQUALITY(less(-0.774597+tol/2.0,-0.774597), false, out, success);
177  TEUCHOS_TEST_EQUALITY(less(-0.774597-tol/2.0,-0.774597), false, out, success);
178  TEUCHOS_TEST_EQUALITY(less(-0.774597,-0.774597+tol/2.0), false, out, success);
179  TEUCHOS_TEST_EQUALITY(less(-0.774597,-0.774597-tol/2.0), false, out, success);
180  TEUCHOS_TEST_EQUALITY(less(-0.774597,0.0), true, out, success);
181  TEUCHOS_TEST_EQUALITY(less(0.0,-0.774597), false, out, success);
182  }
183 
184  TEUCHOS_UNIT_TEST( Stokhos_ProductBasisUtils, LexographicFloatingPointLess ) {
185  success = true;
186 
188  typedef Stokhos::FloatingPointLess<value_type> comp_type;
189  term_type a(2), b(2);
191  a[0] = -0.774597; a[1] = -0.774597;
192  b[0] = -0.774597; b[1] = 0.0;
193 
194  TEUCHOS_TEST_EQUALITY(less(a,b), true, out, success);
195  TEUCHOS_TEST_EQUALITY(less(b,a), false, out, success);
196  }
197 
198  TEUCHOS_UNIT_TEST( Stokhos_ProductBasisUtils, TotalOrderIndexSet ) {
199  success = true;
200 
201  // Build index set of dimension d and order p
202  typedef Stokhos::TotalOrderIndexSet<ordinal_type> index_set_type;
203  typedef index_set_type::multiindex_type multiindex_type;
204  typedef index_set_type::iterator iterator;
205  index_set_type indexSet(setup.d, 0, setup.p);
206 
207  // Print index set
208  out << std::endl << "Total order index set (dimension = " << setup.d
209  << ", order = " << setup.p << "):" << std::endl;
210  std::ostream_iterator<multiindex_type> out_iterator(out, "\n");
211  std::copy(indexSet.begin(), indexSet.end(), out_iterator);
212 
213  // Verify each index lies appropriatly in the set
214  for (iterator i=indexSet.begin(); i!=indexSet.end(); ++i) {
215  if (i->order() < 0 || i->order() > setup.p) {
216  out << "index " << *i << " does not lie in total order set! "
217  << std::endl;
218  success = false;
219  }
220  }
221 
222  // Put indices in sorted container -- this will ensure there are no
223  // duplicates, if we get the right size
225  typedef std::set<multiindex_type, less_type> multiindex_set;
226  multiindex_set sortedIndexSet(indexSet.begin(), indexSet.end());
227 
228  out << "sorted index set size = " << sortedIndexSet.size() << std::endl;
229  out << "expected index set size = "
230  << Stokhos::n_choose_k(setup.p+setup.d,setup.d) << std::endl;
231  if (static_cast<ordinal_type>(sortedIndexSet.size()) !=
233  success = false;
234  }
235 
236  TEUCHOS_UNIT_TEST( Stokhos_ProductBasisUtils,
237  AnisotropicTotalOrderIndexSet ) {
238  success = true;
239 
240  // Build index set of dimension d and order p
242  typedef index_set_type::multiindex_type multiindex_type;
243  typedef index_set_type::iterator iterator;
244  multiindex_type upper(setup.d);
245  for (ordinal_type i=0; i<setup.d; ++i)
246  upper[i] = i+1;
247  index_set_type indexSet(setup.p, upper);
248 
249  // Print index set
250  out << std::endl << "Anisotropic total order index set (dimension = "
251  << setup.d << ", order = " << setup.p << ", and component orders = "
252  << upper << "):" << std::endl;
253  std::ostream_iterator<multiindex_type> out_iterator(out, "\n");
254  std::copy(indexSet.begin(), indexSet.end(), out_iterator);
255 
256  // Verify each index lies appropriatly in the set
257  for (iterator i=indexSet.begin(); i!=indexSet.end(); ++i) {
258  if (i->order() < 0 || i->order() > setup.p || !i->termWiseLEQ(upper)) {
259  out << "index " << *i << " does not lie in total order set! "
260  << std::endl;
261  success = false;
262  }
263  }
264 
265  // Need to figure out how to compute the size of such an index set
266  /*
267  // Put indices in sorted container -- this will ensure there are no
268  // duplicates, if we get the right size
269  typedef Stokhos::TotalOrderLess<multiindex_type> less_type;
270  typedef std::set<multiindex_type, less_type> multiindex_set;
271  multiindex_set sortedIndexSet(indexSet.begin(), indexSet.end());
272 
273  out << "sorted index set size = " << sortedIndexSet.size() << std::endl;
274  out << "expected index set size = "
275  << Stokhos::n_choose_k(setup.p+setup.d,setup.d) << std::endl;
276  if (static_cast<ordinal_type>(sortedIndexSet.size()) !=
277  Stokhos::n_choose_k(setup.p+setup.d,setup.d))
278  success = false;
279  */
280  }
281 
282  TEUCHOS_UNIT_TEST( Stokhos_ProductBasisUtils, TotalOrderBasis ) {
283  success = true;
284 
285  // Build index set of dimension d and order p
286  typedef Stokhos::TotalOrderIndexSet<ordinal_type> index_set_type;
287  index_set_type indexSet(setup.d, 0, setup.p);
288 
289  // Build total-order basis from index set
291  typedef Stokhos::TotalOrderLess<coeff_type> less_type;
292  typedef std::map<coeff_type, ordinal_type, less_type> basis_set_type;
293  typedef Teuchos::Array<coeff_type> basis_map_type;
294  basis_set_type basis_set;
295  basis_map_type basis_map;
297  indexSet, basis_set, basis_map);
298 
299  // Build total-order basis directly
300  ordinal_type sz;
304  compute_terms(setup.p, setup.d, sz, terms, num_terms);
305 
306  // Check sizes
307  TEUCHOS_TEST_EQUALITY(static_cast<ordinal_type>(basis_set.size()),
308  static_cast<ordinal_type>(basis_map.size()),
309  out, success);
310  TEUCHOS_TEST_EQUALITY(static_cast<ordinal_type>(basis_set.size()),
311  static_cast<ordinal_type>(terms.size()),
312  out, success);
313  TEUCHOS_TEST_EQUALITY(sz, static_cast<ordinal_type>(terms.size()),
314  out, success);
315 
316  std::ostream_iterator<ordinal_type> out_iterator(out, " ");
317  for (ordinal_type i=0; i<sz; i++) {
318 
319  // Verify terms match
320  out << "term " << basis_map[i] << " == " << terms[i] << " : ";
321  bool is_equal = true;
322  for (ordinal_type j=0; j<setup.d; j++)
323  is_equal = is_equal && terms[i][j] == basis_map[i][j];
324  if (is_equal)
325  out << "passed" << std::endl;
326  else {
327  out << "failed" << std::endl;
328  success = false;
329  }
330 
331  // Verify global index mapping matches
332  TEUCHOS_TEST_EQUALITY(basis_set[basis_map[i]], i, out, success);
333  }
334 
335  }
336 
337  TEUCHOS_UNIT_TEST( Stokhos_ProductBasisUtils, TensorProductBasis ) {
338  success = true;
339 
340  // Build index set of dimension d and order p
341  typedef Stokhos::TensorProductIndexSet<ordinal_type> index_set_type;
342  index_set_type indexSet(setup.d, 0, setup.p);
343 
344  // Build total-order basis from index set
346  typedef Stokhos::TotalOrderLess<coeff_type> less_type;
347  typedef std::map<coeff_type, ordinal_type, less_type> basis_set_type;
348  typedef Teuchos::Array<coeff_type> basis_map_type;
349  basis_set_type basis_set;
350  basis_map_type basis_map;
352  indexSet, basis_set, basis_map);
353 
354  // Compute expected size
355  ordinal_type sz = 1;
356  for (ordinal_type i=0; i<setup.d; ++i)
357  sz *= setup.p+1;
358 
359  // Check sizes
360  TEUCHOS_TEST_EQUALITY(static_cast<ordinal_type>(basis_set.size()),
361  static_cast<ordinal_type>(basis_map.size()),
362  out, success);
363  TEUCHOS_TEST_EQUALITY(sz, static_cast<ordinal_type>(basis_set.size()),
364  out, success);
365 
366  std::ostream_iterator<ordinal_type> out_iterator(out, " ");
367  for (ordinal_type i=0; i<sz; i++) {
368 
369  // Verify terms match
370  out << "term " << basis_map[i] << " <= " << setup.p << " : ";
371  bool is_less = true;
372  for (ordinal_type j=0; j<setup.d; j++)
373  is_less = is_less && basis_map[i][j] <= setup.p;
374  if (is_less)
375  out << "passed" << std::endl;
376  else {
377  out << "failed" << std::endl;
378  success = false;
379  }
380 
381  // Verify global index mapping matches
382  TEUCHOS_TEST_EQUALITY(basis_set[basis_map[i]], i, out, success);
383  }
384 
385  }
386 
387  template <typename ordinal_type>
390 
392  dim(dim_), order(order_) {}
393 
394  template <typename term_type>
395  bool operator() (const term_type& term) const {
396  ordinal_type sum = 0;
397  for (ordinal_type i=0; i<dim; ++i)
398  sum += term[i];
399  return sum <= order;
400  }
401 
402  };
403 
404  template <typename basis_set_type>
406  const basis_set_type& basis_set;
407 
408  general_predicate(const basis_set_type& basis_set_) :
409  basis_set(basis_set_) {}
410 
411  template <typename term_type>
412  bool operator() (const term_type& term) const {
413  return basis_set.find(term) != basis_set.end();
414  }
415 
416  };
417 
418 
419  TEUCHOS_UNIT_TEST( Stokhos_ProductBasisUtils, TotalOrderSparse3Tensor ) {
420  success = true;
421  ordinal_type dim = setup.d;
422  ordinal_type order = setup.p;
423 
424  // Build index set of dimension d and order p
425  typedef Stokhos::TotalOrderIndexSet<ordinal_type> index_set_type;
426  index_set_type indexSet(dim, 0, order);
427 
428  // Build total-order basis from index set
430  typedef Stokhos::TotalOrderLess<coeff_type> less_type;
431  typedef std::map<coeff_type, ordinal_type, less_type> basis_set_type;
432  typedef Teuchos::Array<coeff_type> basis_map_type;
433  basis_set_type basis_set;
434  basis_map_type basis_map;
436  indexSet, basis_set, basis_map);
437 
438  // 1-D bases
440  for (ordinal_type i=0; i<dim; i++)
442 
443  // Build Cijk tensor
445  total_order_predicate<ordinal_type> pred(dim, order);
446  //general_predicate<basis_set_type> pred(basis_set);
448  Stokhos::ProductBasisUtils::computeTripleProductTensor<ordinal_type,value_type>(bases, basis_set, basis_map, pred, pred);
449 
450  // Build Cijk tensor using original approach
453  basis->computeTripleProductTensor();
454 
455  // Check sizes
456  TEUCHOS_TEST_EQUALITY(Cijk->num_k(), Cijk2->num_k(), out, success);
457  TEUCHOS_TEST_EQUALITY(Cijk->num_entries(), Cijk2->num_entries(), out, success);
458 
459  // Check tensors match
460  for (Cijk_type::k_iterator k_it=Cijk2->k_begin();
461  k_it!=Cijk2->k_end(); ++k_it) {
462  int k = Stokhos::index(k_it);
463  for (Cijk_type::kj_iterator j_it = Cijk2->j_begin(k_it);
464  j_it != Cijk2->j_end(k_it); ++j_it) {
465  int j = Stokhos::index(j_it);
466  for (Cijk_type::kji_iterator i_it = Cijk2->i_begin(j_it);
467  i_it != Cijk2->i_end(j_it); ++i_it) {
468  int i = Stokhos::index(i_it);
469  double c = Cijk->getValue(i,j,k);
470  double c2 = Stokhos::value(i_it);
471  double tol = setup.atol + c2*setup.rtol;
472  double err = std::abs(c-c2);
473  bool s = err < tol;
474  if (!s) {
475  out << std::endl
476  << "Check: rel_err( C(" << i << "," << j << "," << k << ") )"
477  << " = " << "rel_err( " << c << ", " << c2 << " ) = " << err
478  << " <= " << tol << " : ";
479  if (s) out << "Passed.";
480  else out << "Failed!";
481  out << std::endl;
482  }
483  success = success && s;
484  }
485  }
486  }
487  }
488 
489  TEUCHOS_UNIT_TEST( Stokhos_ProductBasisUtils, TotalOrderSparse3TensorNew ) {
490  success = true;
491  // ordinal_type dim = setup.d;
492  // ordinal_type order = setup.p;
493  ordinal_type dim = 2;
494  ordinal_type order = 3;
495 
496  // Build index set of dimension d and order p
497  typedef Stokhos::TotalOrderIndexSet<ordinal_type> index_set_type;
498  index_set_type indexSet(dim, 0, order);
499 
500  // Build total-order basis from index set
502  typedef Stokhos::TotalOrderLess<coeff_type> less_type;
503  typedef std::map<coeff_type, ordinal_type, less_type> basis_set_type;
504  typedef Teuchos::Array<coeff_type> basis_map_type;
505  basis_set_type basis_set;
506  basis_map_type basis_map;
508  indexSet, basis_set, basis_map);
509 
510  // 1-D bases
512  for (ordinal_type i=0; i<dim; i++)
514 
515  // Build Cijk tensor
517  total_order_predicate<ordinal_type> pred(dim, order);
518  //general_predicate<basis_set_type> pred(basis_set);
520  Stokhos::ProductBasisUtils::computeTripleProductTensorNew<ordinal_type,value_type>(bases, basis_set, basis_map, pred, pred, false);
521 
522  // Build Cijk tensor using original approach
525  basis->computeTripleProductTensor();
526 
527  // Check sizes
528  TEUCHOS_TEST_EQUALITY(Cijk->num_k(), Cijk2->num_k(), out, success);
529  TEUCHOS_TEST_EQUALITY(Cijk->num_entries(), Cijk2->num_entries(), out, success);
530 
531  // Check tensors match
532  for (Cijk_type::k_iterator k_it=Cijk2->k_begin();
533  k_it!=Cijk2->k_end(); ++k_it) {
534  int k = Stokhos::index(k_it);
535  for (Cijk_type::kj_iterator j_it = Cijk2->j_begin(k_it);
536  j_it != Cijk2->j_end(k_it); ++j_it) {
537  int j = Stokhos::index(j_it);
538  for (Cijk_type::kji_iterator i_it = Cijk2->i_begin(j_it);
539  i_it != Cijk2->i_end(j_it); ++i_it) {
540  int i = Stokhos::index(i_it);
541  double c = Cijk->getValue(i,j,k);
542  double c2 = Stokhos::value(i_it);
543  double tol = setup.atol + c2*setup.rtol;
544  double err = std::abs(c-c2);
545  bool s = err < tol;
546  if (!s) {
547  out << std::endl
548  << "Check: rel_err( C(" << i << "," << j << "," << k << ") )"
549  << " = " << "rel_err( " << c << ", " << c2 << " ) = " << err
550  << " <= " << tol << " : ";
551  if (s) out << "Passed.";
552  else out << "Failed!";
553  out << std::endl;
554  }
555  success = success && s;
556  }
557  }
558  }
559  }
560 
561  TEUCHOS_UNIT_TEST( Stokhos_ProductBasisUtils, TotalOrderSparse3LTO ) {
562  success = true;
563  ordinal_type dim = setup.d;
564  ordinal_type order = setup.p;
565  // ordinal_type dim = 2;
566  // ordinal_type order = 3;
567 
568  // 1-D bases
570  for (ordinal_type i=0; i<dim; i++)
572 
573  // Product basis
574  typedef Stokhos::MultiIndex<ordinal_type> coeff_type;
575  typedef Stokhos::LexographicLess<coeff_type> less_type;
577  bases);
578 
579  // Build Cijk tensor
583 
584  // Build Cijk tensor using original approach
587 
588  // Check sizes
589  TEUCHOS_TEST_EQUALITY(Cijk->num_k(), Cijk2->num_k(), out, success);
590  TEUCHOS_TEST_EQUALITY(Cijk->num_entries(), Cijk2->num_entries(), out, success);
591 
592  // Check tensors match
593  for (Cijk_type::k_iterator k_it=Cijk2->k_begin();
594  k_it!=Cijk2->k_end(); ++k_it) {
595  int k = Stokhos::index(k_it);
596  for (Cijk_type::kj_iterator j_it = Cijk2->j_begin(k_it);
597  j_it != Cijk2->j_end(k_it); ++j_it) {
598  int j = Stokhos::index(j_it);
599  for (Cijk_type::kji_iterator i_it = Cijk2->i_begin(j_it);
600  i_it != Cijk2->i_end(j_it); ++i_it) {
601  int i = Stokhos::index(i_it);
602  double c = Cijk->getValue(i,j,k);
603  double c2 = Stokhos::value(i_it);
604  double tol = setup.atol + c2*setup.rtol;
605  double err = std::abs(c-c2);
606  bool s = err < tol;
607  if (!s) {
608  out << std::endl
609  << "Check: rel_err( C(" << i << "," << j << "," << k << ") )"
610  << " = " << "rel_err( " << c << ", " << c2 << " ) = " << err
611  << " <= " << tol << " : ";
612  if (s) out << "Passed.";
613  else out << "Failed!";
614  out << std::endl;
615  }
616  success = success && s;
617  }
618  }
619  }
620  }
621 
622  TEUCHOS_UNIT_TEST( Stokhos_ProductBasisUtils, TotalOrderMapping ) {
623  success = true;
624 
625  // Build sorted index set of dimension d and order p
626  typedef Stokhos::TotalOrderIndexSet<ordinal_type> index_set_type;
627  typedef index_set_type::multiindex_type multiindex_type;
629  typedef std::set<multiindex_type, less_type> multiindex_set;
630  typedef multiindex_set::iterator iterator;
631  index_set_type indexSet(setup.d, 0, setup.p);
632  multiindex_set sortedIndexSet(indexSet.begin(), indexSet.end());
633 
634  // Loop over each index set element and test if mapping
635  // computes proper global index
636  iterator i = sortedIndexSet.begin();
637  ordinal_type idx = 0;
638  while (i != sortedIndexSet.end()) {
639  ordinal_type idx_mapping = totalOrderMapping(*i);
640  out << *i << ": index = " << idx << " mapped index = " << idx_mapping
641  << ": ";
642  if (idx == idx_mapping)
643  out << "passed";
644  else {
645  out << "failed";
646  success = false;
647  }
648  out << std::endl;
649  ++i;
650  ++idx;
651  }
652  }
653 
654  TEUCHOS_UNIT_TEST( Stokhos_ProductBasisUtils, LexographicMapping ) {
655  success = true;
656 
657  // Build sorted index set of dimension d and order p
658  typedef Stokhos::TotalOrderIndexSet<ordinal_type> index_set_type;
659  typedef index_set_type::multiindex_type multiindex_type;
661  typedef std::set<multiindex_type, less_type> multiindex_set;
662  typedef multiindex_set::iterator iterator;
663  index_set_type indexSet(setup.d, 0, setup.p);
664  multiindex_set sortedIndexSet(indexSet.begin(), indexSet.end());
665 
666  // Loop over each index set element and test if mapping
667  // computes proper global index
668  iterator i = sortedIndexSet.begin();
669  ordinal_type idx = 0;
670  while (i != sortedIndexSet.end()) {
671  ordinal_type idx_mapping = lexicographicMapping(*i,setup.p);
672  out << *i << ": index = " << idx << " mapped index = " << idx_mapping
673  << ": ";
674  if (idx == idx_mapping)
675  out << "passed";
676  else {
677  out << "failed";
678  success = false;
679  }
680  out << std::endl;
681  ++i;
682  ++idx;
683  }
684  }
685 
686  TEUCHOS_UNIT_TEST( Stokhos_ProductBasisUtils, LexographicMapping2 ) {
687  success = true;
688 
689  // Build sorted index set of dimension d and order p
690  ordinal_type d = setup.d;
691  ordinal_type p = setup.p;
692  typedef Stokhos::TotalOrderIndexSet<ordinal_type> index_set_type;
693  typedef index_set_type::multiindex_type multiindex_type;
695  typedef std::set<multiindex_type, less_type> multiindex_set;
696  index_set_type indexSet(d, 0, p);
697  multiindex_set sortedIndexSet(indexSet.begin(), indexSet.end());
698 
699  // Loop over lexicographically sorted multi-indices, compute global index
700  // using combinatorial number system, and test if it is correct
701  multiindex_type index(d), num_terms(d), orders(d,p);
702  bool stop = false;
703  ordinal_type idx = 0;
704  index[d-1] = -1;
705  num_terms[d-1] = -1;
706  while (!stop) {
707  // Increment index to next lexicographic term
708  ordinal_type dim = d-1;
709  ++index[dim];
710  while (dim > 0 && index[dim] > orders[dim]) {
711  index[dim] = 0;
712  --dim;
713  ++index[dim];
714  }
715  for (ordinal_type i=dim+1; i<d; ++i)
716  orders[i] = orders[i-1] - index[i-1];
717 
718  if (index[dim] > orders[dim])
719  stop = true;
720  else {
721  // Update num_terms: num_terms[dim] = number of terms with
722  // order < index[dim] and dimension d-dim-1
723  num_terms[dim] += Stokhos::n_choose_k(orders[dim]-index[dim]+d-dim,
724  d-dim-1);
725  for (ordinal_type i=dim+1; i<d; ++i)
726  num_terms[i] = 0;
727 
728  // Compute global index
729  ordinal_type I = num_terms.order();
730  //ordinal_type I = lexicographicMapping(index, p);
731 
732  out << index << ": index = " << idx << " mapped index = " << I
733  << ": ";
734  if (idx == I)
735  out << "passed";
736  else {
737  out << "failed";
738  success = false;
739  }
740  out << std::endl;
741  }
742 
743  ++idx;
744  }
745  }
746 }
747 
748 int main( int argc, char* argv[] ) {
749  Teuchos::GlobalMPISession mpiSession(&argc, &argv);
752  return res;
753 }
A functor for comparing floating-point numbers to some tolerance.
ordinal_type factorial(const ordinal_type &n)
ordinal_type n_choose_k(const ordinal_type &n, const ordinal_type &k)
Compute bionomial coefficient (n ; k) = n!/( k! (n-k)! )
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...
Container storing a term in a generalized tensor product.
Data structure storing a sparse 3-tensor C(i,j,k) in a a compressed format.
virtual Teuchos::RCP< Stokhos::Sparse3Tensor< ordinal_type, value_type > > computeTripleProductTensor() const
Compute triple product tensor.
TEUCHOS_UNIT_TEST(Stokhos_ProductBasisUtils, NChooseK)
static void buildProductBasis(const index_set_type &index_set, const growth_rule_type &growth_rule, basis_set_type &basis_set, basis_map_type &basis_map)
Generate a product basis from an index set.
A comparison functor implementing a strict weak ordering based total-order ordering, recursive on the dimension.
UnitTestSetup< ordinal_type, value_type > setup
static int runUnitTestsFromMain(int argc, char *argv[])
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
static void summarize(Ptr< const Comm< int > > comm, std::ostream &out=std::cout, const bool alwaysWriteLocal=false, const bool writeGlobalStats=true, const bool writeZeroTimers=true, const ECounterSetOp setOp=Intersection, const std::string &filter="", const bool ignoreZeroTimers=false)
scalar_type quad_func2(const Teuchos::Array< scalar_type > &x)
KOKKOS_INLINE_FUNCTION PCE< Storage > abs(const PCE< Storage > &a)
An anisotropic total order index set.
Multivariate orthogonal polynomial basis generated from a total-order complete-polynomial tensor prod...
KOKKOS_INLINE_FUNCTION PCE< Storage > exp(const PCE< Storage > &a)
Legendre polynomial basis.
Stokhos::Sparse3Tensor< int, double > Cijk_type
scalar_type quad_func1(const Teuchos::Array< scalar_type > &x)
int main(int argc, char **argv)
expr val()
#define TEUCHOS_TEST_EQUALITY(v1, v2, out, success)
An isotropic total order index set.
size_type size() const
A comparison functor implementing a strict weak ordering based lexographic ordering.
KOKKOS_INLINE_FUNCTION PCE< Storage > sin(const PCE< Storage > &a)
ordinal_type lexicographicMapping(const Stokhos::MultiIndex< ordinal_type > &index, ordinal_type max_order)
int n
std::enable_if< Kokkos::is_view_uq_pce< Kokkos::View< RD, RP...> >::value &&Kokkos::is_view_uq_pce< Kokkos::View< XD, XP...> >::value >::type sum(const Kokkos::View< RD, RP...> &r, const Kokkos::View< XD, XP...> &x)
static ordinal_type compute_terms(ordinal_type p, ordinal_type d, ordinal_type &sz, Teuchos::Array< MultiIndex< ordinal_type > > &terms, Teuchos::Array< ordinal_type > &num_terms)
Compute the 2-D array of basis terms which maps a basis index into the orders for each basis dimensio...
ordinal_type totalOrderMapping(const Stokhos::MultiIndex< ordinal_type > &index)