10 #ifndef STOKHOS_PRODUCT_BASIS_UTILS_HPP
11 #define STOKHOS_PRODUCT_BASIS_UTILS_HPP
27 template <
typename ordinal_type>
46 template <
typename ordinal_t>
123 std::ostream&
print(std::ostream& os)
const {
126 os <<
index[i] <<
" ";
166 template <
typename ordinal_type>
182 template <
typename ordinal_t>
231 index[dim-1] =
upper+1;
249 class Iterator :
public std::iterator<std::input_iterator_tag,
253 typedef std::iterator<std::input_iterator_tag,multiindex_type>
base_type;
345 template <
typename ordinal_t>
420 class Iterator :
public std::iterator<std::input_iterator_tag,
424 typedef std::iterator<std::input_iterator_tag,multiindex_type>
base_type;
525 template <
typename ordinal_t>
545 dim(dim_),
lower(dim_,lower_),
upper(dim_,upper_) {}
589 index[dim-1] =
upper[dim-1]+1;
607 class Iterator :
public std::iterator<std::input_iterator_tag,
611 typedef std::iterator<std::input_iterator_tag,multiindex_type>
base_type;
684 template <
typename ordinal_t,
typename element_t>
734 std::ostream&
print(std::ostream& os)
const {
737 os <<
term[i] <<
" ";
749 template <
typename ordinal_type,
typename element_type>
765 template <
typename term_type,
766 typename compare_type = std::less<typename term_type::element_type> >
778 bool operator()(
const term_type& a,
const term_type& b)
const {
780 while(i < a.dimension() && i < b.dimension() &&
equal(a[i],b[i])) i++;
784 if (i == a.dimension())
return i != b.dimension();
788 if (i == b.dimension())
return false;
791 return cmp(a[i],b[i]);
801 return !(
cmp(a,b) ||
cmp(b,a));
815 template <
typename term_type,
816 typename compare_type = std::less<typename term_type::element_type> >
827 bool operator()(
const term_type& a,
const term_type& b)
const {
831 while (i < a.dimension() && i < b.dimension() &&
equal(a_order,b_order)) {
836 return cmp(a_order,b_order);
846 return !(
cmp(a,b) ||
cmp(b,a));
869 template <
typename term_type>
880 bool operator()(
const term_type& a,
const term_type& b)
const {
887 if ( (x < y) && (x < (x^y)) ) {
902 template <
typename value_type>
925 template <
typename ordinal_type>
939 template <
typename ordinal_type>
967 template <
typename ordinal_type>
998 template <
typename ordinal_type>
1031 template <
typename index_set_type,
1032 typename growth_rule_type,
1033 typename basis_set_type,
1034 typename basis_map_type>
1037 const growth_rule_type& growth_rule,
1038 basis_set_type& basis_set,
1039 basis_map_type& basis_map) {
1042 typedef typename index_set_type::iterator index_iterator_type;
1043 typedef typename basis_set_type::iterator basis_iterator_type;
1044 typedef typename basis_set_type::key_type coeff_type;
1046 ordinal_type dim = index_set.dimension();
1049 index_iterator_type index_iterator = index_set.begin();
1050 index_iterator_type index_iterator_end = index_set.end();
1051 for (; index_iterator != index_iterator_end; ++index_iterator) {
1054 coeff_type coeff(dim);
1055 for (ordinal_type i=0; i<dim; i++)
1056 coeff[i] = growth_rule[i]((*index_iterator)[i]);
1063 basis_map.resize(basis_set.size());
1064 ordinal_type idx = 0;
1065 basis_iterator_type basis_iterator = basis_set.begin();
1066 basis_iterator_type basis_iterator_end = basis_set.end();
1067 for (; basis_iterator != basis_iterator_end; ++basis_iterator) {
1068 basis_iterator->second = idx;
1069 basis_map[idx] = basis_iterator->first;
1078 template <
typename index_set_type,
1079 typename basis_set_type,
1080 typename basis_map_type>
1083 basis_set_type& basis_set,
1084 basis_map_type& basis_map) {
1086 ordinal_type dim = index_set.dimension();
1093 typename basis_set_type,
1094 typename basis_map_type,
1095 typename coeff_predicate_type,
1096 typename k_coeff_predicate_type>
1100 const basis_set_type& basis_set,
1101 const basis_map_type& basis_map,
1102 const coeff_predicate_type& coeff_pred,
1103 const k_coeff_predicate_type& k_coeff_pred,
1106 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
1129 bases[i]->computeSparseTripleProductTensor(bases[i]->order()+1);
1136 typedef typename Cijk_type::k_iterator k_iterator;
1137 typedef typename Cijk_type::kj_iterator kj_iterator;
1138 typedef typename Cijk_type::kji_iterator kji_iterator;
1142 coeff_type terms_i(d), terms_j(d), terms_k(d);
1144 k_iterators[dim] = Cijk_1d[dim]->k_begin();
1145 j_iterators[dim] = Cijk_1d[dim]->j_begin(k_iterators[dim]);
1146 i_iterators[dim] = Cijk_1d[dim]->i_begin(j_iterators[dim]);
1147 terms_i[dim] = index(i_iterators[dim]);
1148 terms_j[dim] = index(j_iterators[dim]);
1149 terms_k[dim] = index(k_iterators[dim]);
1155 bool valid_i = coeff_pred(terms_i);
1156 bool valid_j = coeff_pred(terms_j);
1157 bool valid_k = k_coeff_pred(terms_k);
1166 if (valid_i && valid_j && valid_k) {
1168 typename basis_set_type::const_iterator k =
1169 basis_set.find(terms_k);
1173 typename basis_set_type::const_iterator i =
1174 basis_set.find(terms_i);
1178 typename basis_set_type::const_iterator
j =
1179 basis_set.find(terms_j);
1185 c *= value(i_iterators[dim]);
1186 nrm *= bases[dim]->norm_squared(terms_i[dim]);
1189 Cijk->add_term(I,J,K,c);
1198 while (inc && cdim < d) {
1200 ++i_iterators[cdim];
1202 if (i_iterators[cdim] != Cijk_1d[cdim]->i_end(j_iterators[cdim])) {
1203 terms_i[cdim] = index(i_iterators[cdim]);
1204 valid_i = coeff_pred(terms_i);
1206 if (i_iterators[cdim] == Cijk_1d[cdim]->i_end(j_iterators[cdim]) ||
1208 ++j_iterators[cdim];
1210 if (j_iterators[cdim] != Cijk_1d[cdim]->j_end(k_iterators[cdim])) {
1211 terms_j[cdim] = index(j_iterators[cdim]);
1212 valid_j = coeff_pred(terms_j);
1214 if (j_iterators[cdim] == Cijk_1d[cdim]->j_end(k_iterators[cdim]) ||
1216 ++k_iterators[cdim];
1218 if (k_iterators[cdim] != Cijk_1d[cdim]->k_end()) {
1219 terms_k[cdim] = index(k_iterators[cdim]);
1220 valid_k = k_coeff_pred(terms_k);
1222 if (k_iterators[cdim] == Cijk_1d[cdim]->k_end() || !valid_k) {
1223 k_iterators[cdim] = Cijk_1d[cdim]->k_begin();
1225 terms_k[cur_dim] = index(k_iterators[cur_dim]);
1226 valid_k = k_coeff_pred(terms_k);
1230 j_iterators[cur_dim] =
1231 Cijk_1d[cur_dim]->j_begin(k_iterators[cur_dim]);
1232 terms_j[cur_dim] = index(j_iterators[cur_dim]);
1233 valid_j = coeff_pred(terms_j);
1237 i_iterators[cur_dim] =
1238 Cijk_1d[cur_dim]->i_begin(j_iterators[cur_dim]);
1239 terms_i[cur_dim] = index(i_iterators[cur_dim]);
1240 valid_i = coeff_pred(terms_i);
1245 if (!valid_i || !valid_j || !valid_k)
1255 Cijk->fillComplete();
1260 template <
typename ordinal_type>
1288 if (!more)
return false;
1307 while (more && zero) {
1348 if (
k+
j <
i ||
i+
j <
k ||
i+
k <
j)
return true;
1356 typename basis_set_type,
1357 typename basis_map_type,
1358 typename coeff_predicate_type,
1359 typename k_coeff_predicate_type>
1363 const basis_set_type& basis_set,
1364 const basis_map_type& basis_map,
1365 const coeff_predicate_type& coeff_pred,
1366 const k_coeff_predicate_type& k_coeff_pred,
1367 bool symmetric =
false,
1369 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
1392 bases[i]->computeSparseTripleProductTensor(bases[i]->order()+1);
1398 coeff_type terms_i(d), terms_j(d), terms_k(d);
1400 Cijk_1d_iterators[dim] = Cijk_Iterator(bases[dim]->order(), symmetric);
1409 bool valid_i = coeff_pred(terms_i);
1410 bool valid_j = coeff_pred(terms_j);
1411 bool valid_k = k_coeff_pred(terms_k);
1412 bool stop = !valid_i || !valid_j || !valid_k;
1416 typename basis_set_type::const_iterator k = basis_set.find(terms_k);
1417 typename basis_set_type::const_iterator i = basis_set.find(terms_i);
1418 typename basis_set_type::const_iterator
j = basis_set.find(terms_j);
1425 c *= Cijk_1d[dim]->getValue(terms_i[dim], terms_j[dim], terms_k[dim]);
1428 Cijk->add_term(I,J,K,c);
1440 while (inc && cdim < d) {
1441 bool more = Cijk_1d_iterators[cdim].increment();
1442 terms_i[cdim] = Cijk_1d_iterators[cdim].i;
1443 terms_j[cdim] = Cijk_1d_iterators[cdim].j;
1444 terms_k[cdim] = Cijk_1d_iterators[cdim].k;
1449 valid_i = coeff_pred(terms_i);
1450 valid_j = coeff_pred(terms_j);
1451 valid_k = k_coeff_pred(terms_k);
1453 if (valid_i && valid_j && valid_k)
1464 Cijk->fillComplete();
1473 template <
typename ordinal_type,
typename value_type>
1521 template <
typename ordinal_type,
typename value_type>
1530 return compute_terms(basis_orders, sz, terms, num_terms);
1533 template <
typename ordinal_type,
typename value_type>
1578 if (basis_orders[i] > p)
1579 p = basis_orders[i];
1589 terms_order[0].
resize(1);
1598 if (basis_orders[
j] >= 1)
1609 num_terms[k] = num_terms[k-1];
1619 if (terms_order[k-1][prev+i][
j] < basis_orders[
j]) {
1620 term = terms_order[k-1][prev+i];
1632 prev += cnt[
j] - cnt[
j+1];
1638 cnt[
j] = cnt_next[
j];
1644 num_terms[p+1] = sz;
1652 terms[i++] = terms_order[k][
j];
1658 template <
typename ordinal_type,
typename value_type>
1676 "Stokhos::CompletePolynomialBasis::compute_index(): " <<
1677 "Term has invalid order " << ord);
1684 k = num_terms[ord-1];
1687 while (k < k_max && !found) {
1688 bool found_term =
true;
1690 found_term = found_term && (term[
j] == terms[k][
j]);
1698 "Stokhos::CompletePolynomialBasis::compute_index(): " <<
1699 "Could not find specified term.");
static ordinal_type compute_index(const MultiIndex< ordinal_type > &term, const Teuchos::Array< MultiIndex< ordinal_type > > &terms, const Teuchos::Array< ordinal_type > &num_terms, ordinal_type max_p)
Compute basis index given the orders for each basis dimension.
std::iterator< std::input_iterator_tag, multiindex_type > base_type
multiindex_type upper
Component-wise upper bounds.
A functor for comparing floating-point numbers to some tolerance.
Iterator(ordinal_type max_order_, const multiindex_type &component_max_order_, const multiindex_type &index_)
Constructor.
multiindex_type lower
Component-wise lower bounds.
const multiindex_type * const_pointer
#define TEUCHOS_FUNC_TIME_MONITOR(FUNCNAME)
bool termWiseLEQ(const MultiIndex &idx) const
Compare term-wise less-than or equal-to.
const_pointer operator->() const
Dereference.
base_type::iterator_category iterator_category
ordinal_type upper_order
Upper order of index set.
bool operator==(const Iterator &it) const
Compare equality of iterators.
Iterator(const multiindex_type &upper_, const multiindex_type &index_)
Constructor.
multiindex_type max_orders() const
Return maximum order for each dimension.
ordinal_type n_choose_k(const ordinal_type &n, const ordinal_type &k)
Compute bionomial coefficient (n ; k) = n!/( k! (n-k)! )
const_reference operator*() const
Dereference.
MultiIndex< ordinal_type > multiindex_type
MultiIndex< ordinal_type > multiindex_type
base_type::pointer pointer
MortonZLess()
Constructor.
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.
Teuchos::Array< ordinal_type > orders
Maximum orders for each term to determine how to increment.
TensorProductIndexSet(ordinal_type dim_, ordinal_type lower_, ordinal_type upper_)
Constructor.
Utilities for indexing a multi-variate complete polynomial basis.
base_type::value_type value_type
ordinal_type dim
Dimension.
term_type::ordinal_type ordinal_type
bool increment(ordinal_type &delta_i, ordinal_type &delta_j, ordinal_type &delta_k)
std::ostream & print(std::ostream &os) const
Print multiindex.
MultiIndex< ordinal_type > coeff_type
ordinal_type dimension() const
Return dimension.
std::iterator< std::input_iterator_tag, multiindex_type > base_type
const_iterator end() const
Return iterator for end of the index set.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
ordinal_type size() const
Size.
AnisotropicTotalOrderIndexSet(ordinal_type upper_order_, const multiindex_type &lower_, const multiindex_type &upper_)
Constructor.
ordinal_type dimension() const
Dimension.
MultiIndex & termWiseMin(const MultiIndex &idx)
Replace multiindex with min of this and other multiindex.
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)
term_type::element_type element_type
base_type::value_type value_type
Iterator & operator++()
Prefix increment, i.e., ++iterator.
ordinal_type dim
Dimension.
term_type::ordinal_type ordinal_type
base_type::difference_type difference_type
Teuchos::Array< element_type > term
Array storing term elements.
bool operator!=(const Iterator &it) const
Compare inequality of iterators.
Teuchos::Array< ordinal_type > index
index terms
term_type::ordinal_type ordinal_type
TensorProductPredicate(const coeff_type &orders_)
base_type::pointer pointer
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.
Teuchos::Array< element_type > & getTerm()
Term access.
TotalOrderPredicate(ordinal_type max_order_, const coeff_type &orders_)
base_type::value_type value_type
multiindex_type index
Current value of iterator.
const Teuchos::Array< element_type > & getTerm() const
Term access.
TotalOrderIndexSet(ordinal_type dim_, ordinal_type lower_, ordinal_type upper_)
Constructor.
ordinal_type dim
Dimension.
Iterator & operator++()
Prefix increment, i.e., ++iterator.
ordinal_type dimension() const
Return dimension.
bool operator!=(const Iterator &it) const
Compare inequality of iterators.
A comparison functor implementing a strict weak ordering based total-order ordering, recursive on the dimension.
Iterator class for iterating over elements of the index set.
base_type::reference reference
ordinal_type size() const
Return dimension.
Utilities for indexing a multi-variate complete polynomial basis.
KOKKOS_INLINE_FUNCTION PCE< Storage > min(const typename PCE< Storage >::value_type &a, const PCE< Storage > &b)
TensorProductElement(ordinal_type dim, const element_type &val=element_type(0))
Constructor.
Cijk_1D_Iterator(ordinal_type p=0, bool sym=false)
Iterator & operator++()
Prefix increment, i.e., ++iterator.
ordinal_type upper
Upper order of index set.
multiindex_type max_orders() const
Return maximum order for each dimension.
base_type::pointer pointer
A multidimensional index.
Iterator & operator++(int)
Postfix increment, i.e., iterator++.
Cijk_1D_Iterator(ordinal_type p_i, ordinal_type p_j, ordinal_type p_k, bool sym)
base_type::difference_type difference_type
Teuchos::Array< ordinal_type > orders
Maximum orders for each term to determine how to increment.
const ordinal_type & operator[](ordinal_type i) const
Term access.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
const_reference operator*() const
Dereference.
Iterator(ordinal_type max_order_, const multiindex_type &index_)
Constructor.
std::ostream & operator<<(std::ostream &os, const ProductContainer< coeff_type > &vec)
multiindex_type index
Current value of iterator.
MultiIndex & termWiseMax(const ordinal_type idx)
Replace multiindex with max of this and given value.
TotalOrderLess(const compare_type &cmp_=compare_type())
Constructor.
base_type::reference reference
bool operator()(const term_type &a, const term_type &b) const
bool operator()(const coeff_type &term) const
const multiindex_type & const_reference
ordinal_type max_order
Maximum order of iterator.
Teuchos::Array< element_type > & getTerm()
Term access.
MultiIndex(ordinal_type dim, ordinal_type v=ordinal_type(0))
Constructor.
MultiIndex< ordinal_type > coeff_type
base_type::reference reference
std::iterator< std::input_iterator_tag, multiindex_type > base_type
bool operator!=(const MultiIndex &idx) const
Compare equality.
compare_type cmp
Element comparison functor.
multiindex_type upper
Upper bound of iterator.
KOKKOS_INLINE_FUNCTION PCE< Storage > abs(const PCE< Storage > &a)
Iterator & operator++(int)
Postfix increment, i.e., iterator++.
void resize(ordinal_type d, ordinal_type v=ordinal_type(0))
Resize.
TensorProductIndexSet(ordinal_type dim_, ordinal_type upper_)
Constructor.
term_type::element_type element_type
const element_type & operator[](ordinal_type i) const
Term access.
void resize(size_type new_size, const value_type &x=value_type())
const_iterator begin() const
Return iterator for first element in the set.
ordinal_type max_order
Maximum order of iterator.
MultiIndex & termWiseMax(const MultiIndex &idx)
Replace multiindex with max of this and other multiindex.
term_type product_element_type
An anisotropic total order index set.
bool equal(const element_type &a, const element_type &b) const
Determine if two elements a and b are equal.
base_type::iterator_category iterator_category
Predicate functor for building sparse triple products based on total order.
const_iterator end() const
Return iterator for end of the index set.
TensorProductIndexSet(const multiindex_type &upper_)
Constructor.
element_type order() const
Compute total order of tensor product element.
ordinal_type dim
Dimension.
bool operator==(const Iterator &it) const
Compare equality of iterators.
Iterator class for iterating over elements of the index set.
multiindex_type upper
Upper bound of index set.
Stokhos::Sparse3Tensor< int, double > Cijk_type
ordinal_type dim
Dimension.
base_type::iterator_category iterator_category
bool operator==(const MultiIndex &idx) const
Compare equality.
multiindex_type index
Current value of iterator.
LexographicLess(const compare_type &cmp_=compare_type())
Constructor.
void push_back(const value_type &x)
const multiindex_type & const_reference
An isotropic total order index set.
Abstract base class for 1-D orthogonal polynomials.
std::ostream & print(std::ostream &os) const
Print multiindex.
const_reference operator*() const
Dereference.
void init(ordinal_type v)
Initialize.
FloatingPointLess(const value_type &tol_=1.0e-12)
Constructor.
A comparison functor implementing a strict weak ordering based Morton Z-ordering. ...
TensorProductElement()
Default constructor.
const Teuchos::Array< element_type > & getTerm() const
Term access.
multiindex_type lower
Lower bound of index set.
A comparison functor implementing a strict weak ordering based lexographic ordering.
Iterator class for iterating over elements of the index set.
const multiindex_type * const_pointer
MultiIndex & termWiseMin(const ordinal_type idx)
Replace multiindex with min of this and given value.
~TensorProductElement()
Destructor.
static void buildProductBasis(const index_set_type &index_set, basis_set_type &basis_set, basis_map_type &basis_map)
Generate a product basis from an index set.
ordinal_type order() const
Compute total order of index.
Iterator & operator++(int)
Postfix increment, i.e., iterator++.
TensorProductIndexSet(const multiindex_type &lower_, const multiindex_type &upper_)
Constructor.
AnisotropicTotalOrderIndexSet(ordinal_type upper_order_, const multiindex_type &upper_)
Constructor.
multiindex_type max_orders() const
Return maximum order for each dimension.
~FloatingPointLess()
Destructor.
ordinal_type dimension() const
Return dimension.
ordinal_type dim
Dimension.
const multiindex_type & const_reference
const_pointer operator->() const
Dereference.
const_iterator begin() const
Return iterator for first element in the set.
static Teuchos::RCP< Stokhos::Sparse3Tensor< ordinal_type, value_type > > computeTripleProductTensorNew(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, bool symmetric=false, const value_type sparse_tol=1.0e-12)
ordinal_type lower_order
Lower order of index set.
const_pointer operator->() const
Dereference.
base_type::difference_type difference_type
ordinal_type lower
Lower order of index set.
bool operator()(const term_type &a, const term_type &b) const
Determine if a is less than b.
ordinal_type dimension() const
Return dimension.
ordinal_type lexicographicMapping(const Stokhos::MultiIndex< ordinal_type > &index, ordinal_type max_order)
A tensor product index set.
bool equal(const element_type &a, const element_type &b) const
Determine if two elements a and b are equal.
const_iterator end() const
Return iterator for end of the index set.
bool operator()(const coeff_type &term) const
bool operator()(const value_type &a, const value_type &b) const
Compare if a < b.
Predicate functor for building sparse triple products.
bool operator!=(const Iterator &it) const
Compare inequality of iterators.
bool operator==(const Iterator &it) const
Compare equality of iterators.
const multiindex_type * const_pointer
bool operator()(const term_type &a, const term_type &b) const
term_type product_element_type
const_iterator begin() const
Return iterator for first element in the set.
term_type::element_type element_type
term_type product_element_type
TotalOrderIndexSet(ordinal_type dim_, ordinal_type upper_)
Constructor.
multiindex_type component_max_order
Maximum order for each component.
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...
MultiIndex< ordinal_type > multiindex_type
ordinal_type totalOrderMapping(const Stokhos::MultiIndex< ordinal_type > &index)
compare_type cmp
Element comparison functor.