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.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 
25 int main(int argc, char **argv)
26 {
27  try {
28 
29  // Setup command line options
31  CLP.setDocString(
32  "This example generates partitions the Cijk tensor for a lexicographic tree basis.\n");
33  int d = 3;
34  CLP.setOption("dimension", &d, "Stochastic dimension");
35  int p = 5;
36  CLP.setOption("order", &p, "Polynomial order");
37  double drop = 1.0e-12;
38  CLP.setOption("drop", &drop, "Drop tolerance");
39  bool symmetric = true;
40  CLP.setOption("symmetric", "asymmetric", &symmetric, "Use basis polynomials with symmetric PDF");
41  int a_size = 100;
42  CLP.setOption("a_size", &a_size, "Size of a (matrix) partition");
43  int x_size = 100;
44  CLP.setOption("x_size", &x_size, "Size of x (input vector) partition");
45  int y_size = 100;
46  CLP.setOption("y_size", &y_size, "Size of y (output vector) partition");
47  bool save_3tensor = false;
48  CLP.setOption("save_3tensor", "no-save_3tensor", &save_3tensor,
49  "Save full 3tensor to file");
50  std::string file_3tensor = "Cijk.dat";
51  CLP.setOption("filename_3tensor", &file_3tensor,
52  "Filename to store full 3-tensor");
53 
54  // Parse arguments
55  CLP.parse( argc, argv );
56 
57  // Basis
59  const double alpha = 1.0;
60  const double beta = symmetric ? 1.0 : 2.0 ;
61  for (int i=0; i<d; i++) {
63  p, alpha, beta, true));
64  }
67  RCP<const basis_type> basis = Teuchos::rcp(new basis_type(bases, drop));
68 
69  // Build LTB Cijk
70  typedef Stokhos::LTBSparse3Tensor<int,double> Cijk_LTB_type;
71  typedef Cijk_LTB_type::CijkNode node_type;
73  computeTripleProductTensorLTB(*basis, symmetric);
74 
75  int sz = basis->size();
76  std::cout << "basis size = " << sz
77  << " num nonzero Cijk entries = " << Cijk->num_entries()
78  << std::endl;
79 
80  // Setup partitions
81  if (a_size > sz) a_size = sz;
82  if (x_size > sz) x_size = sz;
83  if (y_size > sz) y_size = sz;
84 
86  Teuchos::Array< int > index_stack;
87  node_stack.push_back(Cijk->getHeadNode());
88  index_stack.push_back(0);
90  int child_index;
92  while (node_stack.size() > 0) {
93  node = node_stack.back();
94  child_index = index_stack.back();
95 
96  // Leaf -- If we got here, just push this node into the partitions
97  if (node->is_leaf) {
98  partition_stack.push_back(node);
99  node_stack.pop_back();
100  index_stack.pop_back();
101  }
102 
103  // Once sizes are small enough, push node onto partition stack
104  else if (node->i_size <= y_size &&
105  node->j_size <= a_size &&
106  node->k_size <= x_size) {
107  partition_stack.push_back(node);
108  node_stack.pop_back();
109  index_stack.pop_back();
110  }
111 
112  // More children to process -- process them first
113  else if (child_index < node->children.size()) {
114  ++index_stack.back();
115  node = node->children[child_index];
116  node_stack.push_back(node);
117  index_stack.push_back(0);
118  }
119 
120  // No more children
121  else {
122  node_stack.pop_back();
123  index_stack.pop_back();
124  }
125 
126  }
127 
128  std::cout << "num partitions = " << partition_stack.size() << std::endl;
129  /*
130  for (int part=0; part<partition_stack.size(); ++part) {
131  node = partition_stack[part];
132  std::cout << "partition " << part << ":" << std::endl
133  << "\ti-range: [" << node->i_begin << ","
134  << node->i_begin+node->i_size << ")" << std::endl
135  << "\tj-range: [" << node->j_begin << ","
136  << node->j_begin+node->j_size << ")" << std::endl
137  << "\tk-range: [" << node->k_begin << ","
138  << node->k_begin+node->k_size << ")" << std::endl
139  << "\tnum_non_zeros = " << node->total_num_entries << std::endl;
140  }
141  */
142 
143  // Build flat list of (i,j,k,part) tuples
146  for (int part=0; part<partition_stack.size(); ++part) {
147  node = partition_stack[part];
148  node_stack.push_back(node);
149  index_stack.push_back(0);
150  while (node_stack.size() > 0) {
151  node = node_stack.back();
152  child_index = index_stack.back();
153 
154  // Leaf -- store (i,j,k,part) tuples
155  if (node->is_leaf) {
156  Cijk_Iterator cijk_iterator(node->p_i,
157  node->p_j,
158  node->p_k,
159  symmetric);
160  bool more = true;
161  while (more) {
162  Teuchos::Array<int> t(4);
163  int I = node->i_begin + cijk_iterator.i;
164  int J = node->j_begin + cijk_iterator.j;
165  int K = node->k_begin + cijk_iterator.k;
166  t[0] = I;
167  t[1] = J;
168  t[2] = K;
169  t[3] = part;
170  tuples.push_back(t);
171  more = cijk_iterator.increment();
172  }
173  node_stack.pop_back();
174  index_stack.pop_back();
175  }
176 
177  // More children to process -- process them first
178  else if (child_index < node->children.size()) {
179  ++index_stack.back();
180  node = node->children[child_index];
181  node_stack.push_back(node);
182  index_stack.push_back(0);
183  }
184 
185  // No more children
186  else {
187  node_stack.pop_back();
188  index_stack.pop_back();
189  }
190 
191  }
192  }
193 
194  // Print full 3-tensor to file
195  if (save_3tensor) {
196  std::ofstream cijk_file(file_3tensor.c_str());
197  cijk_file.precision(14);
198  cijk_file.setf(std::ios::scientific);
199  cijk_file << "i, j, k, part" << std::endl;
200  for (int i=0; i<tuples.size(); ++i) {
201  cijk_file << tuples[i][0] << ", "
202  << tuples[i][1] << ", "
203  << tuples[i][2] << ", "
204  << tuples[i][3] << std::endl;
205  }
206  cijk_file.close();
207  }
208 
209  }
210  catch (std::exception& e) {
211  std::cout << e.what() << std::endl;
212  }
213 
214  return 0;
215 }
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).