42 #ifndef STOKHOS_PRODUCT_BASIS_UTILS_HPP
43 #define STOKHOS_PRODUCT_BASIS_UTILS_HPP
59 template <
typename ordinal_type>
78 template <
typename ordinal_t>
155 std::ostream&
print(std::ostream& os)
const {
158 os <<
index[i] <<
" ";
198 template <
typename ordinal_type>
214 template <
typename ordinal_t>
263 index[dim-1] =
upper+1;
281 class Iterator :
public std::iterator<std::input_iterator_tag,
285 typedef std::iterator<std::input_iterator_tag,multiindex_type>
base_type;
377 template <
typename ordinal_t>
452 class Iterator :
public std::iterator<std::input_iterator_tag,
456 typedef std::iterator<std::input_iterator_tag,multiindex_type>
base_type;
557 template <
typename ordinal_t>
577 dim(dim_),
lower(dim_,lower_),
upper(dim_,upper_) {}
621 index[dim-1] =
upper[dim-1]+1;
639 class Iterator :
public std::iterator<std::input_iterator_tag,
643 typedef std::iterator<std::input_iterator_tag,multiindex_type>
base_type;
716 template <
typename ordinal_t,
typename element_t>
766 std::ostream&
print(std::ostream& os)
const {
769 os <<
term[i] <<
" ";
781 template <
typename ordinal_type,
typename element_type>
797 template <
typename term_type,
798 typename compare_type = std::less<typename term_type::element_type> >
810 bool operator()(
const term_type& a,
const term_type& b)
const {
812 while(i < a.dimension() && i < b.dimension() &&
equal(a[i],b[i])) i++;
816 if (i == a.dimension())
return i != b.dimension();
820 if (i == b.dimension())
return false;
823 return cmp(a[i],b[i]);
833 return !(
cmp(a,b) ||
cmp(b,a));
847 template <
typename term_type,
848 typename compare_type = std::less<typename term_type::element_type> >
859 bool operator()(
const term_type& a,
const term_type& b)
const {
863 while (i < a.dimension() && i < b.dimension() &&
equal(a_order,b_order)) {
868 return cmp(a_order,b_order);
878 return !(
cmp(a,b) ||
cmp(b,a));
901 template <
typename term_type>
912 bool operator()(
const term_type& a,
const term_type& b)
const {
919 if ( (x < y) && (x < (x^y)) ) {
934 template <
typename value_type>
957 template <
typename ordinal_type>
971 template <
typename ordinal_type>
999 template <
typename ordinal_type>
1030 template <
typename ordinal_type>
1063 template <
typename index_set_type,
1064 typename growth_rule_type,
1065 typename basis_set_type,
1066 typename basis_map_type>
1069 const growth_rule_type& growth_rule,
1070 basis_set_type& basis_set,
1071 basis_map_type& basis_map) {
1074 typedef typename index_set_type::iterator index_iterator_type;
1075 typedef typename basis_set_type::iterator basis_iterator_type;
1076 typedef typename basis_set_type::key_type coeff_type;
1078 ordinal_type dim = index_set.dimension();
1081 index_iterator_type index_iterator = index_set.begin();
1082 index_iterator_type index_iterator_end = index_set.end();
1083 for (; index_iterator != index_iterator_end; ++index_iterator) {
1086 coeff_type coeff(dim);
1087 for (ordinal_type i=0; i<dim; i++)
1088 coeff[i] = growth_rule[i]((*index_iterator)[i]);
1095 basis_map.resize(basis_set.size());
1096 ordinal_type idx = 0;
1097 basis_iterator_type basis_iterator = basis_set.begin();
1098 basis_iterator_type basis_iterator_end = basis_set.end();
1099 for (; basis_iterator != basis_iterator_end; ++basis_iterator) {
1100 basis_iterator->second = idx;
1101 basis_map[idx] = basis_iterator->first;
1110 template <
typename index_set_type,
1111 typename basis_set_type,
1112 typename basis_map_type>
1115 basis_set_type& basis_set,
1116 basis_map_type& basis_map) {
1118 ordinal_type dim = index_set.dimension();
1125 typename basis_set_type,
1126 typename basis_map_type,
1127 typename coeff_predicate_type,
1128 typename k_coeff_predicate_type>
1132 const basis_set_type& basis_set,
1133 const basis_map_type& basis_map,
1134 const coeff_predicate_type& coeff_pred,
1135 const k_coeff_predicate_type& k_coeff_pred,
1138 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
1161 bases[i]->computeSparseTripleProductTensor(bases[i]->order()+1);
1168 typedef typename Cijk_type::k_iterator k_iterator;
1169 typedef typename Cijk_type::kj_iterator kj_iterator;
1170 typedef typename Cijk_type::kji_iterator kji_iterator;
1174 coeff_type terms_i(d), terms_j(d), terms_k(d);
1176 k_iterators[dim] = Cijk_1d[dim]->k_begin();
1177 j_iterators[dim] = Cijk_1d[dim]->j_begin(k_iterators[dim]);
1178 i_iterators[dim] = Cijk_1d[dim]->i_begin(j_iterators[dim]);
1179 terms_i[dim] = index(i_iterators[dim]);
1180 terms_j[dim] = index(j_iterators[dim]);
1181 terms_k[dim] = index(k_iterators[dim]);
1187 bool valid_i = coeff_pred(terms_i);
1188 bool valid_j = coeff_pred(terms_j);
1189 bool valid_k = k_coeff_pred(terms_k);
1198 if (valid_i && valid_j && valid_k) {
1200 typename basis_set_type::const_iterator k =
1201 basis_set.find(terms_k);
1205 typename basis_set_type::const_iterator i =
1206 basis_set.find(terms_i);
1210 typename basis_set_type::const_iterator
j =
1211 basis_set.find(terms_j);
1217 c *= value(i_iterators[dim]);
1218 nrm *= bases[dim]->norm_squared(terms_i[dim]);
1221 Cijk->add_term(I,J,K,c);
1230 while (inc && cdim < d) {
1232 ++i_iterators[cdim];
1234 if (i_iterators[cdim] != Cijk_1d[cdim]->i_end(j_iterators[cdim])) {
1235 terms_i[cdim] = index(i_iterators[cdim]);
1236 valid_i = coeff_pred(terms_i);
1238 if (i_iterators[cdim] == Cijk_1d[cdim]->i_end(j_iterators[cdim]) ||
1240 ++j_iterators[cdim];
1242 if (j_iterators[cdim] != Cijk_1d[cdim]->j_end(k_iterators[cdim])) {
1243 terms_j[cdim] = index(j_iterators[cdim]);
1244 valid_j = coeff_pred(terms_j);
1246 if (j_iterators[cdim] == Cijk_1d[cdim]->j_end(k_iterators[cdim]) ||
1248 ++k_iterators[cdim];
1250 if (k_iterators[cdim] != Cijk_1d[cdim]->k_end()) {
1251 terms_k[cdim] = index(k_iterators[cdim]);
1252 valid_k = k_coeff_pred(terms_k);
1254 if (k_iterators[cdim] == Cijk_1d[cdim]->k_end() || !valid_k) {
1255 k_iterators[cdim] = Cijk_1d[cdim]->k_begin();
1257 terms_k[cur_dim] = index(k_iterators[cur_dim]);
1258 valid_k = k_coeff_pred(terms_k);
1262 j_iterators[cur_dim] =
1263 Cijk_1d[cur_dim]->j_begin(k_iterators[cur_dim]);
1264 terms_j[cur_dim] = index(j_iterators[cur_dim]);
1265 valid_j = coeff_pred(terms_j);
1269 i_iterators[cur_dim] =
1270 Cijk_1d[cur_dim]->i_begin(j_iterators[cur_dim]);
1271 terms_i[cur_dim] = index(i_iterators[cur_dim]);
1272 valid_i = coeff_pred(terms_i);
1277 if (!valid_i || !valid_j || !valid_k)
1287 Cijk->fillComplete();
1292 template <
typename ordinal_type>
1320 if (!more)
return false;
1339 while (more && zero) {
1380 if (
k+
j <
i ||
i+
j <
k ||
i+
k <
j)
return true;
1388 typename basis_set_type,
1389 typename basis_map_type,
1390 typename coeff_predicate_type,
1391 typename k_coeff_predicate_type>
1395 const basis_set_type& basis_set,
1396 const basis_map_type& basis_map,
1397 const coeff_predicate_type& coeff_pred,
1398 const k_coeff_predicate_type& k_coeff_pred,
1399 bool symmetric =
false,
1401 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
1424 bases[i]->computeSparseTripleProductTensor(bases[i]->order()+1);
1430 coeff_type terms_i(d), terms_j(d), terms_k(d);
1432 Cijk_1d_iterators[dim] = Cijk_Iterator(bases[dim]->order(), symmetric);
1441 bool valid_i = coeff_pred(terms_i);
1442 bool valid_j = coeff_pred(terms_j);
1443 bool valid_k = k_coeff_pred(terms_k);
1444 bool stop = !valid_i || !valid_j || !valid_k;
1448 typename basis_set_type::const_iterator k = basis_set.find(terms_k);
1449 typename basis_set_type::const_iterator i = basis_set.find(terms_i);
1450 typename basis_set_type::const_iterator
j = basis_set.find(terms_j);
1457 c *= Cijk_1d[dim]->getValue(terms_i[dim], terms_j[dim], terms_k[dim]);
1460 Cijk->add_term(I,J,K,c);
1472 while (inc && cdim < d) {
1473 bool more = Cijk_1d_iterators[cdim].increment();
1474 terms_i[cdim] = Cijk_1d_iterators[cdim].i;
1475 terms_j[cdim] = Cijk_1d_iterators[cdim].j;
1476 terms_k[cdim] = Cijk_1d_iterators[cdim].k;
1481 valid_i = coeff_pred(terms_i);
1482 valid_j = coeff_pred(terms_j);
1483 valid_k = k_coeff_pred(terms_k);
1485 if (valid_i && valid_j && valid_k)
1496 Cijk->fillComplete();
1505 template <
typename ordinal_type,
typename value_type>
1553 template <
typename ordinal_type,
typename value_type>
1562 return compute_terms(basis_orders, sz, terms, num_terms);
1565 template <
typename ordinal_type,
typename value_type>
1610 if (basis_orders[i] > p)
1611 p = basis_orders[i];
1621 terms_order[0].
resize(1);
1630 if (basis_orders[
j] >= 1)
1641 num_terms[k] = num_terms[k-1];
1651 if (terms_order[k-1][prev+i][
j] < basis_orders[
j]) {
1652 term = terms_order[k-1][prev+i];
1664 prev += cnt[
j] - cnt[
j+1];
1670 cnt[
j] = cnt_next[
j];
1676 num_terms[p+1] = sz;
1684 terms[i++] = terms_order[k][
j];
1690 template <
typename ordinal_type,
typename value_type>
1708 "Stokhos::CompletePolynomialBasis::compute_index(): " <<
1709 "Term has invalid order " << ord);
1716 k = num_terms[ord-1];
1719 while (k < k_max && !found) {
1720 bool found_term =
true;
1722 found_term = found_term && (term[
j] == terms[k][
j]);
1730 "Stokhos::CompletePolynomialBasis::compute_index(): " <<
1731 "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.