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 //
4 // Stokhos Package
5 // Copyright (2009) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Eric T. Phipps (etphipp@sandia.gov).
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #include "Stokhos.hpp"
44 
46 #include "Teuchos_Array.hpp"
47 #include "Teuchos_RCP.hpp"
48 
49 #include <fstream>
50 #include <iostream>
51 
52 using Teuchos::Array;
53 using Teuchos::RCP;
54 using Teuchos::rcp;
55 
56 
57 int main(int argc, char **argv)
58 {
59  try {
60 
61  // Setup command line options
63  CLP.setDocString(
64  "This example generates partitions the Cijk tensor for a lexicographic tree basis.\n");
65  int d = 3;
66  CLP.setOption("dimension", &d, "Stochastic dimension");
67  int p = 5;
68  CLP.setOption("order", &p, "Polynomial order");
69  double drop = 1.0e-12;
70  CLP.setOption("drop", &drop, "Drop tolerance");
71  bool symmetric = true;
72  CLP.setOption("symmetric", "asymmetric", &symmetric, "Use basis polynomials with symmetric PDF");
73  int a_size = 100;
74  CLP.setOption("a_size", &a_size, "Size of a (matrix) partition");
75  int x_size = 100;
76  CLP.setOption("x_size", &x_size, "Size of x (input vector) partition");
77  int y_size = 100;
78  CLP.setOption("y_size", &y_size, "Size of y (output vector) partition");
79  bool save_3tensor = false;
80  CLP.setOption("save_3tensor", "no-save_3tensor", &save_3tensor,
81  "Save full 3tensor to file");
82  std::string file_3tensor = "Cijk.dat";
83  CLP.setOption("filename_3tensor", &file_3tensor,
84  "Filename to store full 3-tensor");
85 
86  // Parse arguments
87  CLP.parse( argc, argv );
88 
89  // Basis
91  const double alpha = 1.0;
92  const double beta = symmetric ? 1.0 : 2.0 ;
93  for (int i=0; i<d; i++) {
95  p, alpha, beta, true));
96  }
99  RCP<const basis_type> basis = Teuchos::rcp(new basis_type(bases, drop));
100 
101  // Build LTB Cijk
102  typedef Stokhos::LTBSparse3Tensor<int,double> Cijk_LTB_type;
103  typedef Cijk_LTB_type::CijkNode node_type;
105  computeTripleProductTensorLTB(*basis, symmetric);
106 
107  int sz = basis->size();
108  std::cout << "basis size = " << sz
109  << " num nonzero Cijk entries = " << Cijk->num_entries()
110  << std::endl;
111 
112  // Setup partitions
113  if (a_size > sz) a_size = sz;
114  if (x_size > sz) x_size = sz;
115  if (y_size > sz) y_size = sz;
116 
118  Teuchos::Array< int > index_stack;
119  node_stack.push_back(Cijk->getHeadNode());
120  index_stack.push_back(0);
122  int child_index;
124  while (node_stack.size() > 0) {
125  node = node_stack.back();
126  child_index = index_stack.back();
127 
128  // Leaf -- If we got here, just push this node into the partitions
129  if (node->is_leaf) {
130  partition_stack.push_back(node);
131  node_stack.pop_back();
132  index_stack.pop_back();
133  }
134 
135  // Once sizes are small enough, push node onto partition stack
136  else if (node->i_size <= y_size &&
137  node->j_size <= a_size &&
138  node->k_size <= x_size) {
139  partition_stack.push_back(node);
140  node_stack.pop_back();
141  index_stack.pop_back();
142  }
143 
144  // More children to process -- process them first
145  else if (child_index < node->children.size()) {
146  ++index_stack.back();
147  node = node->children[child_index];
148  node_stack.push_back(node);
149  index_stack.push_back(0);
150  }
151 
152  // No more children
153  else {
154  node_stack.pop_back();
155  index_stack.pop_back();
156  }
157 
158  }
159 
160  std::cout << "num partitions = " << partition_stack.size() << std::endl;
161  /*
162  for (int part=0; part<partition_stack.size(); ++part) {
163  node = partition_stack[part];
164  std::cout << "partition " << part << ":" << std::endl
165  << "\ti-range: [" << node->i_begin << ","
166  << node->i_begin+node->i_size << ")" << std::endl
167  << "\tj-range: [" << node->j_begin << ","
168  << node->j_begin+node->j_size << ")" << std::endl
169  << "\tk-range: [" << node->k_begin << ","
170  << node->k_begin+node->k_size << ")" << std::endl
171  << "\tnum_non_zeros = " << node->total_num_entries << std::endl;
172  }
173  */
174 
175  // Build flat list of (i,j,k,part) tuples
178  for (int part=0; part<partition_stack.size(); ++part) {
179  node = partition_stack[part];
180  node_stack.push_back(node);
181  index_stack.push_back(0);
182  while (node_stack.size() > 0) {
183  node = node_stack.back();
184  child_index = index_stack.back();
185 
186  // Leaf -- store (i,j,k,part) tuples
187  if (node->is_leaf) {
188  Cijk_Iterator cijk_iterator(node->p_i,
189  node->p_j,
190  node->p_k,
191  symmetric);
192  bool more = true;
193  while (more) {
194  Teuchos::Array<int> t(4);
195  int I = node->i_begin + cijk_iterator.i;
196  int J = node->j_begin + cijk_iterator.j;
197  int K = node->k_begin + cijk_iterator.k;
198  t[0] = I;
199  t[1] = J;
200  t[2] = K;
201  t[3] = part;
202  tuples.push_back(t);
203  more = cijk_iterator.increment();
204  }
205  node_stack.pop_back();
206  index_stack.pop_back();
207  }
208 
209  // More children to process -- process them first
210  else if (child_index < node->children.size()) {
211  ++index_stack.back();
212  node = node->children[child_index];
213  node_stack.push_back(node);
214  index_stack.push_back(0);
215  }
216 
217  // No more children
218  else {
219  node_stack.pop_back();
220  index_stack.pop_back();
221  }
222 
223  }
224  }
225 
226  // Print full 3-tensor to file
227  if (save_3tensor) {
228  std::ofstream cijk_file(file_3tensor.c_str());
229  cijk_file.precision(14);
230  cijk_file.setf(std::ios::scientific);
231  cijk_file << "i, j, k, part" << std::endl;
232  for (int i=0; i<tuples.size(); ++i) {
233  cijk_file << tuples[i][0] << ", "
234  << tuples[i][1] << ", "
235  << tuples[i][2] << ", "
236  << tuples[i][3] << std::endl;
237  }
238  cijk_file.close();
239  }
240 
241  }
242  catch (std::exception& e) {
243  std::cout << e.what() << std::endl;
244  }
245 
246  return 0;
247 }
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).