Stokhos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cijk_ltb_partition_level.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 
10 #include "Stokhos.hpp"
12 
14 #include "Teuchos_Array.hpp"
15 #include "Teuchos_RCP.hpp"
16 
17 #include <fstream>
18 #include <iostream>
19 
20 using Teuchos::Array;
21 using Teuchos::RCP;
22 using Teuchos::rcp;
23 
24 int main(int argc, char **argv)
25 {
26  try {
27 
28  // Setup command line options
30  CLP.setDocString(
31  "This example generates partitions the Cijk tensor for a lexicographic tree basis.\n");
32  int d = 3;
33  CLP.setOption("dimension", &d, "Stochastic dimension");
34  int p = 5;
35  CLP.setOption("order", &p, "Polynomial order");
36  double drop = 1.0e-12;
37  CLP.setOption("drop", &drop, "Drop tolerance");
38  bool symmetric = true;
39  CLP.setOption("symmetric", "asymmetric", &symmetric, "Use basis polynomials with symmetric PDF");
40  int level = 1;
41  CLP.setOption("level", &level, "Level to partition");
42  bool save_3tensor = false;
43  CLP.setOption("save_3tensor", "no-save_3tensor", &save_3tensor,
44  "Save full 3tensor to file");
45  std::string file_3tensor = "Cijk.dat";
46  CLP.setOption("filename_3tensor", &file_3tensor,
47  "Filename to store full 3-tensor");
48 
49  // Parse arguments
50  CLP.parse( argc, argv );
51 
52  // Basis
54  const double alpha = 1.0;
55  const double beta = symmetric ? 1.0 : 2.0 ;
56  for (int i=0; i<d; i++) {
58  p, alpha, beta, true));
59  }
62  RCP<const basis_type> basis = Teuchos::rcp(new basis_type(bases, drop));
63 
64  // Build LTB Cijk
65  typedef Stokhos::LTBSparse3Tensor<int,double> Cijk_LTB_type;
66  typedef Cijk_LTB_type::CijkNode node_type;
68  computeTripleProductTensorLTB(*basis, symmetric);
69 
70  int sz = basis->size();
71  std::cout << "basis size = " << sz
72  << " num nonzero Cijk entries = " << Cijk->num_entries()
73  << std::endl;
74 
75  // Setup partitions
77  Teuchos::Array< int > index_stack;
78  node_stack.push_back(Cijk->getHeadNode());
79  index_stack.push_back(0);
81  int child_index;
83  int my_level = 0;
84  while (node_stack.size() > 0) {
85  node = node_stack.back();
86  child_index = index_stack.back();
87 
88  // Leaf -- If we got here, just push this node into the partitions
89  if (node->is_leaf) {
90  partition_stack.push_back(node);
91  node_stack.pop_back();
92  index_stack.pop_back();
93  --my_level;
94  }
95 
96  // Put nodes into partition if level matches
97  else if (my_level == level) {
98  partition_stack.push_back(node);
99  node_stack.pop_back();
100  index_stack.pop_back();
101  --my_level;
102  }
103 
104  // More children to process -- process them first
105  else if (child_index < node->children.size()) {
106  ++index_stack.back();
107  node = node->children[child_index];
108  node_stack.push_back(node);
109  index_stack.push_back(0);
110  ++my_level;
111  }
112 
113  // No more children
114  else {
115  node_stack.pop_back();
116  index_stack.pop_back();
117  --my_level;
118  }
119 
120  }
121 
122  // Print statistics
123  int max_i_size = 0, max_j_size = 0, max_k_size = 0;
124  for (int part=0; part<partition_stack.size(); ++part) {
125  node = partition_stack[part];
126  if (node->i_size > max_i_size) max_i_size = node->i_size;
127  if (node->j_size > max_j_size) max_j_size = node->j_size;
128  if (node->k_size > max_k_size) max_k_size = node->k_size;
129  }
130  std::cout << "num partitions = " << partition_stack.size() << std::endl
131  << "max i size = " << max_i_size << std::endl
132  << "max j size = " << max_j_size << std::endl
133  << "max k size = " << max_k_size << std::endl;
134 
135  // Build flat list of (i,j,k,part) tuples
138  for (int part=0; part<partition_stack.size(); ++part) {
139  node = partition_stack[part];
140  node_stack.push_back(node);
141  index_stack.push_back(0);
142  while (node_stack.size() > 0) {
143  node = node_stack.back();
144  child_index = index_stack.back();
145 
146  // Leaf -- store (i,j,k,part) tuples
147  if (node->is_leaf) {
148  Cijk_Iterator cijk_iterator(node->p_i,
149  node->p_j,
150  node->p_k,
151  symmetric);
152  bool more = true;
153  while (more) {
154  Teuchos::Array<int> t(4);
155  int I = node->i_begin + cijk_iterator.i;
156  int J = node->j_begin + cijk_iterator.j;
157  int K = node->k_begin + cijk_iterator.k;
158  t[0] = I;
159  t[1] = J;
160  t[2] = K;
161  t[3] = part;
162  tuples.push_back(t);
163  more = cijk_iterator.increment();
164  }
165  node_stack.pop_back();
166  index_stack.pop_back();
167  }
168 
169  // More children to process -- process them first
170  else if (child_index < node->children.size()) {
171  ++index_stack.back();
172  node = node->children[child_index];
173  node_stack.push_back(node);
174  index_stack.push_back(0);
175  }
176 
177  // No more children
178  else {
179  node_stack.pop_back();
180  index_stack.pop_back();
181  }
182 
183  }
184  }
185 
186  // Print full 3-tensor to file
187  if (save_3tensor) {
188  std::ofstream cijk_file(file_3tensor.c_str());
189  cijk_file.precision(14);
190  cijk_file.setf(std::ios::scientific);
191  cijk_file << "i, j, k, part" << std::endl;
192  for (int i=0; i<tuples.size(); ++i) {
193  cijk_file << tuples[i][0] << ", "
194  << tuples[i][1] << ", "
195  << tuples[i][2] << ", "
196  << tuples[i][3] << std::endl;
197  }
198  cijk_file.close();
199  }
200 
201  }
202  catch (std::exception& e) {
203  std::cout << e.what() << std::endl;
204  }
205 
206  return 0;
207 }
Teuchos::RCP< LTBSparse3Tensor< ordinal_type, value_type > > computeTripleProductTensorLTB(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...
Stokhos::LegendreBasis< int, double > basis_type
Kokkos::Serial node_type
Data structure storing a sparse 3-tensor C(i,j,k) in a a tree-based format for lexicographically orde...
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
Jacobi polynomial basis.
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
int main(int argc, char **argv)
reference back()
void push_back(const value_type &x)
void setDocString(const char doc_string[])
size_type size() const
A comparison functor implementing a strict weak ordering based lexographic ordering.
virtual ordinal_type size() const
Return total size of basis (given by order() + 1).