Stan  1.3
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
generator.hpp
Go to the documentation of this file.
1 #ifndef __STAN__GM__GENERATOR_HPP__
2 #define __STAN__GM__GENERATOR_HPP__
3 
4 #include <boost/variant/apply_visitor.hpp>
5 #include <boost/lexical_cast.hpp>
6 
7 #include <cstddef>
8 #include <ostream>
9 #include <sstream>
10 #include <stdexcept>
11 #include <string>
12 #include <vector>
13 
14 #include <stan/version.hpp>
15 #include <stan/gm/ast.hpp>
16 
17 namespace stan {
18 
19  namespace gm {
20 
21  const std::string EOL("\n");
22  const std::string EOL2("\n\n");
23  const std::string INDENT(" ");
24  const std::string INDENT2(" ");
25  const std::string INDENT3(" ");
26 
27  template <typename D>
28  bool has_lub(const D& x) {
29  return !is_nil(x.range_.low_.expr_) && !is_nil(x.range_.high_.expr_);
30  }
31  template <typename D>
32  bool has_ub(const D& x) {
33  return is_nil(x.range_.low_.expr_) && !is_nil(x.range_.high_.expr_);
34  }
35  template <typename D>
36  bool has_lb(const D& x) {
37  return !is_nil(x.range_.low_.expr_) && is_nil(x.range_.high_.expr_);
38  }
39 
40  template <typename T>
41  std::string to_string(T i) {
42  std::stringstream ss;
43  ss << i;
44  return ss.str();
45  }
46 
47  void generate_indent(size_t indent, std::ostream& o) {
48  for (size_t k = 0; k < indent; ++k)
49  o << INDENT;
50  }
51 
53  struct visgen {
54  typedef void result_type;
55  std::ostream& o_;
56  visgen(std::ostream& o) : o_(o) { }
57  };
58 
59  void generate_start_namespace(std::string name,
60  std::ostream& o) {
61  o << "namespace " << name << "_namespace {" << EOL2;
62  }
63 
64  void generate_end_namespace(std::ostream& o) {
65  o << "} // namespace" << EOL2;
66  }
67 
68  void generate_comment(std::string const& msg, int indent,
69  std::ostream& o) {
70  generate_indent(indent,o);
71  o << "// " << msg << EOL;
72  }
73 
74 
75  template <bool isLHS>
76  void generate_indexed_expr(const std::string& expr,
77  const std::vector<expression> indexes,
78  base_expr_type base_type, // may have more dims
79  size_t e_num_dims, // array dims
80  std::ostream& o) {
81  // FIXME: add more get_base1 functions and fold nested calls into API
82  // up to a given size, then default to this behavior
83  size_t ai_size = indexes.size();
84  if (ai_size == 0) {
85  // no indexes
86  o << expr;
87  return;
88  }
89  if (ai_size <= (e_num_dims + 1) || base_type != MATRIX_T) {
90  for (size_t n = 0; n < ai_size; ++n)
91  o << (isLHS ? "get_base1_lhs(" : "get_base1(");
92  o << expr;
93  for (size_t n = 0; n < ai_size; ++n) {
94  o << ',';
95  generate_expression(indexes[n],o);
96  o << ',' << '"' << expr << '"' << ',' << (n+1) << ')';
97  }
98  } else {
99  for (size_t n = 0; n < ai_size - 1; ++n)
100  o << (isLHS ? "get_base1_lhs(" : "get_base1(");
101  o << expr;
102  for (size_t n = 0; n < ai_size - 2; ++n) {
103  o << ',';
104  generate_expression(indexes[n],o);
105  o << ',' << '"' << expr << '"' << ',' << (n+1) << ')';
106  }
107  o << ',';
108  generate_expression(indexes[ai_size - 2U],o);
109  o << ',';
110  generate_expression(indexes[ai_size - 1U],o);
111  o << ',' << '"' << expr << '"' << ',' << (ai_size-1U) << ')';
112  }
113  }
114 
115  void generate_type(const std::string& base_type,
116  const std::vector<expression>& /*dims*/,
117  size_t end,
118  std::ostream& o) {
119  for (size_t i = 0; i < end; ++i) o << "std::vector<";
120  o << base_type;
121  for (size_t i = 0; i < end; ++i) {
122  if (i > 0) o << ' ';
123  o << '>';
124  }
125  }
126 
127  std::string base_type_to_string(const base_expr_type& bt) {
128  std::stringstream s;
129  s << bt;
130  return s.str();
131  }
132 
133 
134  struct expression_visgen : public visgen {
135  expression_visgen(std::ostream& o) : visgen(o) { }
136  void operator()(nil const& /*x*/) const {
137  o_ << "nil";
138  }
139  void operator()(const int_literal& n) const { o_ << n.val_; }
140  void operator()(const double_literal& x) const {
141  std::string num_str = boost::lexical_cast<std::string>(x.val_);
142  o_ << num_str;
143  if (num_str.find_first_of("eE.") == std::string::npos)
144  o_ << ".0"; // trailing 0 to ensure C++ makes it a double
145  }
146  void operator()(const array_literal& x) const {
147  o_ << "stan::math::new_array<";
148  generate_type("foobar", // not enough to use: base_type_to_string(x.type_.base_type_),
149  x.args_,
150  x.args_.size(),
151  o_);
152  o_ << ">()";
153  for (size_t i = 0; i < x.args_.size(); ++i) {
154  o_ << ".add(";
155  generate_expression(x.args_[i],o_);
156  o_ << ")";
157  }
158  o_ << ".array()";
159  }
160  void operator()(const variable& v) const { o_ << v.name_; }
161  void operator()(int n) const { o_ << static_cast<long>(n); }
162  void operator()(double x) const { o_ << x; }
163  void operator()(const std::string& x) const { o_ << x; } // identifiers
164  void operator()(const index_op& x) const {
165  std::stringstream expr_o;
166  generate_expression(x.expr_,expr_o);
167  std::string expr_string = expr_o.str();
168  std::vector<expression> indexes;
169  size_t e_num_dims = x.expr_.expression_type().num_dims_;
170  base_expr_type base_type = x.expr_.expression_type().base_type_;
171  for (size_t i = 0; i < x.dimss_.size(); ++i)
172  for (size_t j = 0; j < x.dimss_[i].size(); ++j)
173  indexes.push_back(x.dimss_[i][j]); // wasteful copy, could use refs
174  generate_indexed_expr<false>(expr_string,indexes,base_type,e_num_dims,o_);
175  }
176  void operator()(const fun& fx) const {
177  o_ << fx.name_ << '(';
178  for (size_t i = 0; i < fx.args_.size(); ++i) {
179  if (i > 0) o_ << ',';
180  boost::apply_visitor(*this, fx.args_[i].expr_);
181  }
182  if (has_rng_suffix(fx.name_))
183  o_ << ", base_rng__";
184  o_ << ')';
185  }
186  void operator()(const binary_op& expr) const {
187  o_ << '(';
188  boost::apply_visitor(*this, expr.left.expr_);
189  o_ << ' ' << expr.op << ' ';
190  boost::apply_visitor(*this, expr.right.expr_);
191  o_ << ')';
192  }
193  void operator()(const unary_op& expr) const {
194  o_ << expr.op << '(';
195  boost::apply_visitor(*this, expr.subject.expr_);
196  o_ << ')';
197  }
198  };
199 
200  void generate_expression(const expression& e, std::ostream& o) {
201  expression_visgen vis(o);
202  boost::apply_visitor(vis, e.expr_);
203  }
204 
205  struct printable_visgen : public visgen {
206  printable_visgen(std::ostream& o) : visgen(o) { }
207  void operator()(const std::string& s) const {
208  o_ << '"' << s << '"';
209  }
210  void operator()(const expression& e) const {
211  generate_expression(e,o_);
212  }
213  };
214 
215  void generate_printable(const printable& p, std::ostream& o) {
216  printable_visgen vis(o);
217  boost::apply_visitor(vis, p.printable_);
218  }
219 
220  void generate_using(const std::string& type, std::ostream& o) {
221  o << "using " << type << ";" << EOL;
222  }
223 
224  void generate_using_namespace(const std::string& ns, std::ostream& o) {
225  o << "using namespace " << ns << ";" << EOL;
226  }
227 
228 
229  void generate_usings(std::ostream& o) {
230  generate_using("std::vector",o);
231  generate_using("std::string",o);
232  generate_using("std::stringstream",o);
233  generate_using("stan::agrad::var",o);
234  generate_using("stan::model::prob_grad_ad",o);
235  generate_using("stan::math::get_base1",o);
236  generate_using("stan::math::stan_print",o);
237  generate_using("stan::io::dump",o);
238  generate_using("std::istream",o);
239  generate_using_namespace("stan::math",o);
240  generate_using_namespace("stan::prob",o);
241  generate_using_namespace("stan::agrad",o);
242  o << EOL;
243  }
244 
245  void generate_typedef(const std::string& type,
246  const std::string& abbrev,
247  std::ostream& o) {
248  o << "typedef" << " " << type << " " << abbrev << ";" << EOL;
249  }
250 
251  void generate_typedefs(std::ostream& o) {
252  generate_typedef("Eigen::Matrix<double,Eigen::Dynamic,1>","vector_d",o);
253  generate_typedef("Eigen::Matrix<double,1,Eigen::Dynamic>","row_vector_d",o);
254  generate_typedef("Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>","matrix_d",o);
255  o << EOL;
256  }
257 
258  void generate_include(const std::string& lib_name, std::ostream& o) {
259  o << "#include" << " " << "<" << lib_name << ">" << EOL;
260  }
261 
262  void generate_includes(std::ostream& o) {
263  generate_include("stan/model/model_header.hpp",o);
264  o << EOL;
265  }
266 
267  void generate_version_comment(std::ostream& o) {
268  o << "// Code generated by Stan version "
269  << stan::MAJOR_VERSION << "." << stan::MINOR_VERSION << EOL2;
270  }
271 
272  void generate_class_decl(const std::string& model_name,
273  std::ostream& o) {
274  o << "class " << model_name << " : public prob_grad_ad {" << EOL;
275  }
276 
277  void generate_end_class_decl(std::ostream& o) {
278  o << "}; // model" << EOL2;
279  }
280 
281  void generate_initializer(std::ostream& o,
282  const std::string& base_type,
283  const std::vector<expression>& dims,
284  const expression& type_arg1 = expression(),
285  const expression& type_arg2 = expression()) {
286  for (size_t i = 0; i < dims.size(); ++i) {
287  o << '(';
288  generate_expression(dims[i].expr_,o);
289  o << ',';
290  generate_type(base_type,dims,dims.size()- i - 1,o);
291  }
292 
293  o << '(';
294  if (!is_nil(type_arg1)) {
295  generate_expression(type_arg1.expr_,o);
296  if (!is_nil(type_arg2)) {
297  o << ',';
298  generate_expression(type_arg2.expr_,o);
299  }
300  } else if (!is_nil(type_arg2.expr_)) {
301  generate_expression(type_arg2.expr_,o);
302  } else {
303  o << '0';
304  }
305  o << ')';
306 
307  for (size_t i = 0; i < dims.size(); ++i)
308  o << ')';
309  o << ';' << EOL;
310  }
311 
312  // only generates the test
313  void generate_validate_context_size(std::ostream& o,
314  const std::string& stage,
315  const std::string& var_name,
316  const std::string& base_type,
317  const std::vector<expression>& dims,
318  const expression& type_arg1 = expression(),
319  const expression& type_arg2 = expression()) {
320  o << INDENT2
321  << "context__.validate_dims("
322  << '"' << stage << '"'
323  << ", " << '"' << var_name << '"'
324  << ", " << '"' << base_type << '"'
325  << ", context__.to_vec(";
326  for (size_t i = 0; i < dims.size(); ++i) {
327  if (i > 0) o << ",";
328  generate_expression(dims[i].expr_,o);
329  }
330  if (!is_nil(type_arg1)) {
331  if (dims.size() > 0) o << ",";
332  generate_expression(type_arg1.expr_,o);
333  if (!is_nil(type_arg2)) {
334  o << ",";
335  generate_expression(type_arg2.expr_,o);
336  }
337  }
338  o << "));"
339  << EOL;
340  }
341 
342  struct var_size_validating_visgen : public visgen {
343  const std::string stage_;
344  var_size_validating_visgen(std::ostream& o, const std::string& stage)
345  : visgen(o),
346  stage_(stage) {
347  }
348  void operator()(nil const& /*x*/) const { } // dummy
349  void operator()(int_var_decl const& x) const {
350  generate_validate_context_size(o_,stage_,x.name_,"int",x.dims_);
351  }
352  void operator()(double_var_decl const& x) const {
353  generate_validate_context_size(o_,stage_,x.name_,"double",x.dims_);
354  }
355  void operator()(vector_var_decl const& x) const {
356  generate_validate_context_size(o_,stage_,x.name_,"vector_d",x.dims_,x.M_);
357  }
358  void operator()(row_vector_var_decl const& x) const {
359  generate_validate_context_size(o_,stage_,x.name_,"row_vector_d",x.dims_,x.N_);
360  }
361  void operator()(unit_vector_var_decl const& x) const {
362  generate_validate_context_size(o_,stage_,x.name_,"vector_d",x.dims_,x.K_);
363  }
364  void operator()(simplex_var_decl const& x) const {
365  generate_validate_context_size(o_,stage_,x.name_,"vector_d",x.dims_,x.K_);
366  }
367  void operator()(ordered_var_decl const& x) const {
368  generate_validate_context_size(o_,stage_,x.name_,"vector_d",x.dims_,x.K_);
369  }
370  void operator()(positive_ordered_var_decl const& x) const {
371  generate_validate_context_size(o_,stage_,x.name_,"vector_d",x.dims_,x.K_);
372  }
373  void operator()(matrix_var_decl const& x) const {
374  generate_validate_context_size(o_,stage_,x.name_,"matrix_d",x.dims_,x.M_,x.N_);
375  }
376  void operator()(cov_matrix_var_decl const& x) const {
377  generate_validate_context_size(o_,stage_,x.name_,"matrix_d",x.dims_,x.K_,x.K_);
378  }
379  void operator()(corr_matrix_var_decl const& x) const {
380  generate_validate_context_size(o_,stage_,x.name_,"matrix_d",x.dims_,x.K_,x.K_);
381  }
382  };
383 
384 
385  void generate_validate_positive(const std::string& var_name,
386  const expression& expr,
387  std::ostream& o) {
388  o << INDENT2;
389  o << "stan::math::validate_non_negative_index(\"" << var_name << "\", \"";
390  generate_expression(expr,o);
391  o << "\", ";
392  generate_expression(expr,o);
393  o << ");" << EOL;
394 
395  // o << "if (0 > ";
396  // generate_expression(expr,o);
397  // o << ") {" << EOL;
398  // o << INDENT3 << "std::stringstream s__;" << EOL;
399  // o << INDENT3 << "s__ << \"Found negative index for variable declaration.\";" << EOL;
400  // o << INDENT3 << "s__ << \"; declared variable=" << var_name << "\";" << EOL;
401  // o << INDENT3 << "s__ << \"; dimension expression=";
402  // generate_expression(expr,o);
403  // o << "\";" << EOL;
404  // o << INDENT3 << "s__ << \"; expression value=\" << ";
405  // generate_expression(expr,o);
406  // o << ";" << EOL;
407  // o << INDENT3 << "throw std::invalid_argument(s__.str());" << EOL;
408  // o << INDENT2 << "}" << EOL;
409  }
410 
411  void generate_initialization(std::ostream& o,
412  const std::string& var_name,
413  const std::string& base_type,
414  const std::vector<expression>& dims,
415  const expression& type_arg1 = expression(),
416  const expression& type_arg2 = expression()) {
417  // validate all dims are positive
418  for (size_t i = 0; i < dims.size(); ++i)
419  generate_validate_positive(var_name,dims[i],o);
420  if (!is_nil(type_arg1))
421  generate_validate_positive(var_name,type_arg1,o);
422  if (!is_nil(type_arg2))
423  generate_validate_positive(var_name,type_arg2,o);
424 
425  // define variable with initializer
426  o << INDENT2
427  << var_name << " = ";
428  generate_type(base_type,dims,dims.size(),o);
429  generate_initializer(o,base_type,dims,type_arg1,type_arg2);
430 
431  }
432 
433  struct var_resizing_visgen : public visgen {
434  var_resizing_visgen(std::ostream& o)
435  : visgen(o) {
436  }
437  void operator()(nil const& /*x*/) const { } // dummy
438  void operator()(int_var_decl const& x) const {
439  generate_initialization(o_,x.name_,"int",x.dims_);
440  }
441  void operator()(double_var_decl const& x) const {
442  generate_initialization(o_,x.name_,"double",x.dims_);
443  }
444  void operator()(vector_var_decl const& x) const {
445  generate_initialization(o_,x.name_,"vector_d",x.dims_,x.M_);
446  }
447  void operator()(row_vector_var_decl const& x) const {
448  generate_initialization(o_,x.name_,"row_vector_d",x.dims_,x.N_);
449  }
450  void operator()(unit_vector_var_decl const& x) const {
451  generate_initialization(o_,x.name_,"vector_d",x.dims_,x.K_);
452  }
453  void operator()(simplex_var_decl const& x) const {
454  generate_initialization(o_,x.name_,"vector_d",x.dims_,x.K_);
455  }
456  void operator()(ordered_var_decl const& x) const {
457  generate_initialization(o_,x.name_,"vector_d",x.dims_,x.K_);
458  }
459  void operator()(positive_ordered_var_decl const& x) const {
460  generate_initialization(o_,x.name_,"vector_d",x.dims_,x.K_);
461  }
462  void operator()(matrix_var_decl const& x) const {
463  generate_initialization(o_,x.name_,"matrix_d",x.dims_,x.M_,x.N_);
464  }
465  void operator()(cov_matrix_var_decl const& x) const {
466  generate_initialization(o_,x.name_,"matrix_d",x.dims_,x.K_,x.K_);
467  }
468  void operator()(corr_matrix_var_decl const& x) const {
469  generate_initialization(o_,x.name_,"matrix_d",x.dims_,x.K_,x.K_);
470  }
471  };
472 
473  void generate_var_resizing(const std::vector<var_decl>& vs,
474  std::ostream& o) {
475  var_resizing_visgen vis(o);
476  for (size_t i = 0; i < vs.size(); ++i)
477  boost::apply_visitor(vis, vs[i].decl_);
478  }
479 
480  const std::vector<expression> EMPTY_EXP_VECTOR(0);
481 
482  struct init_local_var_visgen : public visgen {
483  const bool declare_vars_;
484  const bool is_var_;
485  init_local_var_visgen(bool declare_vars,
486  bool is_var,
487  std::ostream& o)
488  : visgen(o),
489  declare_vars_(declare_vars),
490  is_var_(is_var) {
491  }
492  template <typename D>
493  void generate_initialize_array_bounded(const D& x, const std::string& base_type,
494  const std::string& read_fun_prefix,
495  const std::vector<expression>& dim_args) const {
496  std::vector<expression> read_args;
497  std::string read_fun(read_fun_prefix);
498  if (has_lub(x)) {
499  read_fun += "_lub";
500  read_args.push_back(x.range_.low_);
501  read_args.push_back(x.range_.high_);
502  } else if (has_lb(x)) {
503  read_fun += "_lb";
504  read_args.push_back(x.range_.low_);
505  } else if (has_ub(x)) {
506  read_fun += "_ub";
507  read_args.push_back(x.range_.high_);
508  }
509  for (size_t i = 0; i < dim_args.size(); ++i)
510  read_args.push_back(dim_args[i]);
511  generate_initialize_array(base_type,read_fun,read_args,x.name_,x.dims_);
512  }
513  void operator()(const nil& /*x*/) const { }
514  void operator()(const int_var_decl& x) const {
515  generate_initialize_array("int","integer",EMPTY_EXP_VECTOR,x.name_,x.dims_);
516  }
517  void operator()(const double_var_decl& x) const {
518  std::vector<expression> read_args;
519  generate_initialize_array_bounded(x,is_var_?"T__":"double","scalar",read_args);
520  }
521  void operator()(const vector_var_decl& x) const {
522  std::vector<expression> read_args;
523  read_args.push_back(x.M_);
524  generate_initialize_array_bounded(x,is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,1> ":"vector_d","vector",read_args);
525  }
526  void operator()(const row_vector_var_decl& x) const {
527  std::vector<expression> read_args;
528  read_args.push_back(x.N_);
529  generate_initialize_array_bounded(x,is_var_?"Eigen::Matrix<T__,1,Eigen::Dynamic> ":"row_vector_d","row_vector",read_args);
530  }
531  void operator()(const matrix_var_decl& x) const {
532  std::vector<expression> read_args;
533  read_args.push_back(x.M_);
534  read_args.push_back(x.N_);
535  generate_initialize_array_bounded(x,is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> ":"matrix_d","matrix",read_args);
536  }
537  void operator()(const unit_vector_var_decl& x) const {
538  std::vector<expression> read_args;
539  read_args.push_back(x.K_);
540  generate_initialize_array(is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,1> ":"vector_d","unit_vector",read_args,x.name_,x.dims_);
541  }
542  void operator()(const simplex_var_decl& x) const {
543  std::vector<expression> read_args;
544  read_args.push_back(x.K_);
545  generate_initialize_array(is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,1> ":"vector_d","simplex",read_args,x.name_,x.dims_);
546  }
547  void operator()(const ordered_var_decl& x) const {
548  std::vector<expression> read_args;
549  read_args.push_back(x.K_);
550  generate_initialize_array(is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,1> ":"vector_d","ordered",read_args,x.name_,x.dims_);
551  }
552  void operator()(const positive_ordered_var_decl& x) const {
553  std::vector<expression> read_args;
554  read_args.push_back(x.K_);
555  generate_initialize_array(is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,1> ":"vector_d","positive_ordered",read_args,x.name_,x.dims_);
556  }
557  void operator()(const cov_matrix_var_decl& x) const {
558  std::vector<expression> read_args;
559  read_args.push_back(x.K_);
560  generate_initialize_array(is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> ":"matrix_d","cov_matrix",read_args,x.name_,x.dims_);
561  }
562  void operator()(const corr_matrix_var_decl& x) const {
563  std::vector<expression> read_args;
564  read_args.push_back(x.K_);
565  generate_initialize_array(is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> ":"matrix_d","corr_matrix",read_args,x.name_,x.dims_);
566  }
567  void generate_initialize_array(const std::string& var_type,
568  const std::string& read_type,
569  const std::vector<expression>& read_args,
570  const std::string& name,
571  const std::vector<expression>& dims)
572  const {
573 
574  if (dims.size() == 0) {
575  generate_indent(2,o_);
576  if (declare_vars_) o_ << var_type << " ";
577  o_ << name << " = in__." << read_type << "_constrain(";
578  for (size_t j = 0; j < read_args.size(); ++j) {
579  if (j > 0) o_ << ",";
580  generate_expression(read_args[j],o_);
581  }
582  if (read_args.size() > 0)
583  o_ << ",";
584  o_ << "lp__";
585  o_ << ");" << EOL;
586  generate_indent(2,o_);
587  o_ << "(void) " << name << "; // supress unused variable warning" << EOL;
588  return;
589  }
590  if (declare_vars_) {
591  o_ << INDENT2;
592  for (size_t i = 0; i < dims.size(); ++i) o_ << "vector<";
593  o_ << var_type;
594  for (size_t i = 0; i < dims.size(); ++i) o_ << "> ";
595  o_ << name << ";" << EOL;
596  }
597  std::string name_dims(name);
598  for (size_t i = 0; i < dims.size(); ++i) {
599  generate_indent(i + 2, o_);
600  o_ << "size_t dim_" << name << "_" << i << "__ = ";
601  generate_expression(dims[i],o_);
602  o_ << ";" << EOL;
603  if (i < dims.size() - 1) {
604  generate_indent(i + 2, o_);
605  o_ << name_dims << ".resize(dim" << "_" << name << "_" << i << "__);"
606  << EOL;
607  name_dims.append("[k_").append(to_string(i)).append("__]");
608  }
609  generate_indent(i + 2, o_);
610  if (i == dims.size() - 1) {
611  o_ << name_dims << ".reserve(dim_" << name << "_" << i << "__);" << EOL;
612  generate_indent(i + 2, o_);
613  }
614  o_ << "for (size_t k_" << i << "__ = 0;"
615  << " k_" << i << "__ < dim_" << name << "_" << i << "__;"
616  << " ++k_" << i << "__) {" << EOL;
617  if (i == dims.size() - 1) {
618  generate_indent(i + 3, o_);
619  o_ << name_dims << ".push_back(in__." << read_type << "_constrain(";
620  for (size_t j = 0; j < read_args.size(); ++j) {
621  if (j > 0) o_ << ",";
622  generate_expression(read_args[j],o_);
623  }
624  if (read_args.size() > 0)
625  o_ << ",";
626  o_ << "lp__";
627  o_ << "));" << EOL;
628  }
629  }
630  for (size_t i = dims.size(); i > 0; --i) {
631  generate_indent(i + 1, o_);
632  o_ << "}" << EOL;
633  }
634  }
635  };
636 
637  void generate_local_var_inits(std::vector<var_decl> vs,
638  bool is_var,
639  bool declare_vars,
640  std::ostream& o) {
641  o << INDENT2
642  << "stan::io::reader<"
643  << (is_var ? "T__" : "double")
644  << "> in__(params_r__,params_i__);" << EOL2;
645  init_local_var_visgen vis(declare_vars,is_var,o);
646  for (size_t i = 0; i < vs.size(); ++i)
647  boost::apply_visitor(vis, vs[i].decl_);
648  }
649 
650 
651 
652 
653  void generate_public_decl(std::ostream& o) {
654  o << "public:" << EOL;
655  }
656 
657  void generate_private_decl(std::ostream& o) {
658  o << "private:" << EOL;
659  }
660 
661 
662  struct validate_var_decl_visgen : public visgen {
663  int indents_;
664  validate_var_decl_visgen(int indents,
665  std::ostream& o)
666  : visgen(o),
667  indents_(indents) {
668  }
669  void generate_begin_for_dims(const std::vector<expression>& dims)
670  const {
671 
672  for (size_t i = 0; i < dims.size(); ++i) {
673  generate_indent(indents_+i,o_);
674  o_ << "for (int k" << i << "__ = 0;"
675  << " k" << i << "__ < ";
676  generate_expression(dims[i].expr_,o_);
677  o_ << ";";
678  o_ << " ++k" << i << "__) {" << EOL;
679  }
680  }
681  void generate_end_for_dims(size_t dims_size) const {
682  for (size_t i = 0; i < dims_size; ++i) {
683  generate_indent(indents_ + dims_size - i - 1, o_);
684  o_ << "}" << EOL;
685  }
686  }
687 
688  void generate_loop_var(const std::string& name,
689  size_t dims_size) const {
690  o_ << name;
691  for (size_t i = 0; i < dims_size; ++i)
692  o_ << "[k" << i << "__]";
693  }
694  void operator()(nil const& /*x*/) const { }
695  template <typename T>
696  void basic_validate(T const& x) const {
697  if (!(x.range_.has_low() || x.range_.has_high()))
698  return; // unconstrained
699  generate_begin_for_dims(x.dims_);
700  generate_indent(indents_ + x.dims_.size(),o_);
701  o_ << "try { " << EOL;
702  if (x.range_.has_low()) {
703  generate_indent(indents_ + 1 + x.dims_.size(),o_);
704  o_ << "check_greater_or_equal(function__,";
705  generate_loop_var(x.name_,x.dims_.size());
706  o_ << ",";
707  generate_expression(x.range_.low_.expr_,o_);
708  o_ << ",\"";
709  generate_loop_var(x.name_,x.dims_.size());
710  o_ << "\");" << EOL;
711  }
712  if (x.range_.has_high()) {
713  generate_indent(indents_ + 1 + x.dims_.size(),o_);
714  o_ << "check_less_or_equal(function__,";
715  generate_loop_var(x.name_,x.dims_.size());
716  o_ << ",";
717  generate_expression(x.range_.high_.expr_,o_);
718  o_ << ",\"";
719  generate_loop_var(x.name_,x.dims_.size());
720  o_ << "\");" << EOL;
721  }
722  generate_indent(indents_ + x.dims_.size(),o_);
723  o_ << "} catch (std::domain_error& e) { throw std::domain_error(std::string(\"Invalid value of " << x.name_ << ": \") + std::string(e.what())); };" << EOL;
724  generate_end_for_dims(x.dims_.size());
725  }
726  void operator()(int_var_decl const& x) const {
727  basic_validate(x);
728  }
729  void operator()(double_var_decl const& x) const {
730  basic_validate(x);
731  }
732  void operator()(vector_var_decl const& x) const {
733  basic_validate(x);
734  }
735  void operator()(row_vector_var_decl const& x) const {
736  basic_validate(x);
737  }
738  void operator()(matrix_var_decl const& x) const {
739  basic_validate(x);
740  }
741  template <typename T>
742  void nonbasic_validate(const T& x,
743  const std::string& type_name) const {
744  generate_begin_for_dims(x.dims_);
745  generate_indent(indents_ + x.dims_.size(),o_);
746  o_ << "try { stan::math::check_" << type_name << "(function__,";
747  generate_loop_var(x.name_,x.dims_.size());
748  o_ << ",\"";
749  generate_loop_var(x.name_,x.dims_.size());
750  o_ << "\"); } catch (std::domain_error& e) { throw std::domain_error(std::string(\"Invalid value of " << x.name_ << ": \") + std::string(e.what())); };" << EOL;
751  generate_end_for_dims(x.dims_.size());
752  }
753  void operator()(unit_vector_var_decl const& x) const {
754  nonbasic_validate(x,"unit_vector");
755  }
756  void operator()(simplex_var_decl const& x) const {
757  nonbasic_validate(x,"simplex");
758  }
759  void operator()(ordered_var_decl const& x) const {
760  nonbasic_validate(x,"ordered");
761  }
762  void operator()(positive_ordered_var_decl const& x) const {
763  nonbasic_validate(x,"positive_ordered");
764  }
765  void operator()(corr_matrix_var_decl const& x) const {
766  nonbasic_validate(x,"corr_matrix");
767  }
768  void operator()(cov_matrix_var_decl const& x) const {
769  nonbasic_validate(x,"cov_matrix");
770  }
771  };
772 
773 
774  void generate_validate_var_decl(const var_decl& decl,
775  int indent,
776  std::ostream& o) {
777  validate_var_decl_visgen vis(indent,o);
778  boost::apply_visitor(vis,decl.decl_);
779  }
780 
781  void generate_validate_var_decls(const std::vector<var_decl> decls,
782  int indent,
783  std::ostream& o) {
784  for (size_t i = 0; i < decls.size(); ++i)
785  generate_validate_var_decl(decls[i],indent,o);
786  }
787 
788  // see _var_decl_visgen cut & paste
789  struct member_var_decl_visgen : public visgen {
790  int indents_;
791  member_var_decl_visgen(int indents,
792  std::ostream& o)
793  : visgen(o),
794  indents_(indents) {
795  }
796  void operator()(nil const& /*x*/) const { }
797  void operator()(int_var_decl const& x) const {
798  declare_array("int",x.name_,x.dims_.size());
799  }
800  void operator()(double_var_decl const& x) const {
801  declare_array("double",x.name_,x.dims_.size());
802  }
803  void operator()(unit_vector_var_decl const& x) const {
804  declare_array(("vector_d"), x.name_, x.dims_.size());
805  }
806  void operator()(simplex_var_decl const& x) const {
807  declare_array(("vector_d"), x.name_, x.dims_.size());
808  }
809  void operator()(ordered_var_decl const& x) const {
810  declare_array(("vector_d"), x.name_, x.dims_.size());
811  }
812  void operator()(positive_ordered_var_decl const& x) const {
813  declare_array(("vector_d"), x.name_, x.dims_.size());
814  }
815  void operator()(cov_matrix_var_decl const& x) const {
816  declare_array(("matrix_d"), x.name_, x.dims_.size());
817  }
818  void operator()(corr_matrix_var_decl const& x) const {
819  declare_array(("matrix_d"), x.name_, x.dims_.size());
820  }
821  void operator()(vector_var_decl const& x) const {
822  declare_array(("vector_d"), x.name_, x.dims_.size());
823  }
824  void operator()(row_vector_var_decl const& x) const {
825  declare_array(("row_vector_d"), x.name_, x.dims_.size());
826  }
827  void operator()(matrix_var_decl const& x) const {
828  declare_array(("matrix_d"), x.name_, x.dims_.size());
829  }
830  void declare_array(std::string const& type, std::string const& name,
831  size_t size) const {
832  for (int i = 0; i < indents_; ++i)
833  o_ << INDENT;
834  for (size_t i = 0; i < size; ++i) {
835  o_ << "vector<";
836  }
837  o_ << type;
838  if (size > 0) {
839  o_ << ">";
840  }
841  for (size_t i = 1; i < size; ++i) {
842  o_ << " >";
843  }
844  o_ << " " << name << ";" << EOL;
845  }
846  };
847 
848  void generate_member_var_decls(const std::vector<var_decl>& vs,
849  int indent,
850  std::ostream& o) {
851  member_var_decl_visgen vis(indent,o);
852  for (size_t i = 0; i < vs.size(); ++i)
853  boost::apply_visitor(vis,vs[i].decl_);
854  }
855 
856  // see member_var_decl_visgen cut & paste
857  struct local_var_decl_visgen : public visgen {
858  int indents_;
859  bool is_var_;
860  local_var_decl_visgen(int indents,
861  bool is_var,
862  std::ostream& o)
863  : visgen(o),
864  indents_(indents),
865  is_var_(is_var) {
866  }
867  void operator()(nil const& /*x*/) const { }
868  void operator()(int_var_decl const& x) const {
869  std::vector<expression> ctor_args;
870  declare_array("int",ctor_args,x.name_,x.dims_);
871  }
872  void operator()(double_var_decl const& x) const {
873  std::vector<expression> ctor_args;
874  declare_array(is_var_ ? "T__" : "double",
875  ctor_args,x.name_,x.dims_);
876  }
877  void operator()(vector_var_decl const& x) const {
878  std::vector<expression> ctor_args;
879  ctor_args.push_back(x.M_);
880  declare_array(is_var_ ? "Eigen::Matrix<T__,Eigen::Dynamic,1> " : "vector_d",
881  ctor_args, x.name_, x.dims_);
882  }
883  void operator()(row_vector_var_decl const& x) const {
884  std::vector<expression> ctor_args;
885  ctor_args.push_back(x.N_);
886  declare_array(is_var_ ? "Eigen::Matrix<T__,1,Eigen::Dynamic> " : "row_vector_d",
887  ctor_args, x.name_, x.dims_);
888  }
889  void operator()(matrix_var_decl const& x) const {
890  std::vector<expression> ctor_args;
891  ctor_args.push_back(x.M_);
892  ctor_args.push_back(x.N_);
893  declare_array(is_var_ ? "Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> " : "matrix_d",
894  ctor_args, x.name_, x.dims_);
895  }
896  void operator()(unit_vector_var_decl const& x) const {
897  std::vector<expression> ctor_args;
898  ctor_args.push_back(x.K_);
899  declare_array(is_var_ ? "Eigen::Matrix<T__,Eigen::Dynamic,1> " : "vector_d",
900  ctor_args, x.name_, x.dims_);
901  }
902  void operator()(simplex_var_decl const& x) const {
903  std::vector<expression> ctor_args;
904  ctor_args.push_back(x.K_);
905  declare_array(is_var_ ? "Eigen::Matrix<T__,Eigen::Dynamic,1> " : "vector_d",
906  ctor_args, x.name_, x.dims_);
907  }
908  void operator()(ordered_var_decl const& x) const {
909  std::vector<expression> ctor_args;
910  ctor_args.push_back(x.K_);
911  declare_array(is_var_ ? "Eigen::Matrix<T__,Eigen::Dynamic,1> " : "vector_d",
912  ctor_args, x.name_, x.dims_);
913  }
914  void operator()(positive_ordered_var_decl const& x) const {
915  std::vector<expression> ctor_args;
916  ctor_args.push_back(x.K_);
917  declare_array(is_var_ ? "Eigen::Matrix<T__,Eigen::Dynamic,1> " : "vector_d",
918  ctor_args, x.name_, x.dims_);
919  }
920  void operator()(cov_matrix_var_decl const& x) const {
921  std::vector<expression> ctor_args;
922  ctor_args.push_back(x.K_);
923  ctor_args.push_back(x.K_);
924  declare_array(is_var_ ? "Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> " : "matrix_d",
925  ctor_args, x.name_, x.dims_);
926  }
927  void operator()(corr_matrix_var_decl const& x) const {
928  std::vector<expression> ctor_args;
929  ctor_args.push_back(x.K_);
930  ctor_args.push_back(x.K_);
931  declare_array(is_var_ ? "Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> " : "matrix_d",
932  ctor_args, x.name_, x.dims_);
933  }
934  void generate_type(const std::string& type,
935  size_t num_dims) const {
936  for (size_t i = 0; i < num_dims; ++i)
937  o_ << "vector<";
938  o_ << type;
939  for (size_t i = 0; i < num_dims; ++i) {
940  if (i > 0) o_ << " ";
941  o_ << ">";
942  }
943  }
944  // var_decl -> type[0] name init_args[0] ;
945  // init_args[k] -> ctor_args if no dims left
946  // init_args[k] -> ( dim[k] , ( type[k+1] init_args[k+1] ) )
947  void generate_init_args(const std::string& type,
948  const std::vector<expression>& ctor_args,
949  const std::vector<expression>& dims,
950  size_t dim) const {
951  if (dim < dims.size()) { // more dims left
952  o_ << '('; // open(1)
953  generate_expression(dims[dim],o_);
954  if ((dim + 1 < dims.size()) || ctor_args.size() > 0) {
955  o_ << ", ("; // open(2)
956  generate_type(type,dims.size() - dim - 1);
957  generate_init_args(type,ctor_args,dims,dim + 1);
958  o_ << ')'; // close(2)
959  } else if (type == "var") {
960  o_ << ", DUMMY_VAR__";
961  } else if (type == "int") {
962  o_ << ", 0";
963  } else if (type == "double") {
964  o_ << ", 0.0";
965  } else {
966  // shouldn't hit this
967  }
968  o_ << ')'; // close(1)
969  } else {
970  if (ctor_args.size() == 0) { // scalar int or real
971  if (type == "int") {
972  o_ << "(0)";
973  } else if (type == "double") {
974  o_ << "(0.0)";
975  } else if (type == "var") {
976  o_ << "(DUMMY_VAR__)";
977  } else {
978  // shouldn't hit this, either
979  }
980  }
981  else if (ctor_args.size() == 1) {// vector
982  o_ << '(';
983  generate_expression(ctor_args[0],o_);
984  o_ << ')';
985  } else if (ctor_args.size() > 1) { // matrix
986  o_ << '(';
987  generate_expression(ctor_args[0],o_);
988  o_ << ',';
989  generate_expression(ctor_args[1],o_);
990  o_ << ')';
991  }
992  }
993  }
994  void declare_array(const std::string& type,
995  const std::vector<expression>& ctor_args,
996  const std::string& name,
997  const std::vector<expression>& dims) const {
998 
999  // require double parens to counter "most vexing parse" problem
1000 
1001  generate_indent(indents_,o_);
1002  generate_type(type,dims.size());
1003  o_ << ' ' << name;
1004  generate_init_args(type,ctor_args,dims,0);
1005  o_ << ';' << EOL;
1006  if (type == "Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> "
1007  || type == "Eigen::Matrix<T__,1,Eigen::Dynamic> "
1008  || type == "Eigen::Matrix<T__,Eigen::Dynamic,1> ") {
1009  generate_indent(indents_,o_);
1010  o_ << "stan::agrad::fill(" << name << ",DUMMY_VAR__);" << EOL;
1011  }
1012  }
1013  };
1014 
1015  void generate_local_var_decls(const std::vector<var_decl>& vs,
1016  int indent,
1017  std::ostream& o,
1018  bool is_var) {
1019  local_var_decl_visgen vis(indent,is_var,o);
1020  for (size_t i = 0; i < vs.size(); ++i)
1021  boost::apply_visitor(vis,vs[i].decl_);
1022  }
1023 
1024  // see member_var_decl_visgen cut & paste
1026  int indent_;
1028  std::ostream& o)
1029  : visgen(o),
1030  indent_(indent) {
1031  }
1032  void operator()(nil const& /*x*/) const { }
1033  void operator()(int_var_decl const& x) const {
1034  generate_indent(indent_,o_);
1035  o_ << "stan::agrad::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1036  }
1037  void operator()(double_var_decl const& x) const {
1038  generate_indent(indent_,o_);
1039  o_ << "stan::agrad::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1040  }
1041  void operator()(vector_var_decl const& x) const {
1042  generate_indent(indent_,o_);
1043  o_ << "stan::agrad::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1044  }
1045  void operator()(row_vector_var_decl const& x) const {
1046  generate_indent(indent_,o_);
1047  o_ << "stan::agrad::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1048  }
1049  void operator()(matrix_var_decl const& x) const {
1050  generate_indent(indent_,o_);
1051  o_ << "stan::agrad::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1052  }
1053  void operator()(unit_vector_var_decl const& x) const {
1054  generate_indent(indent_,o_);
1055  o_ << "stan::agrad::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1056  }
1057  void operator()(simplex_var_decl const& x) const {
1058  generate_indent(indent_,o_);
1059  o_ << "stan::agrad::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1060  }
1061  void operator()(ordered_var_decl const& x) const {
1062  generate_indent(indent_,o_);
1063  o_ << "stan::agrad::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1064  }
1065  void operator()(positive_ordered_var_decl const& x) const {
1066  generate_indent(indent_,o_);
1067  o_ << "stan::agrad::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1068  }
1069  void operator()(cov_matrix_var_decl const& x) const {
1070  generate_indent(indent_,o_);
1071  o_ << "stan::agrad::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1072  }
1073  void operator()(corr_matrix_var_decl const& x) const {
1074  generate_indent(indent_,o_);
1075  o_ << "stan::agrad::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1076  }
1077  };
1078 
1079  void generate_init_vars(const std::vector<var_decl>& vs,
1080  int indent,
1081  std::ostream& o) {
1082  generate_init_vars_visgen vis(indent,o);
1083  o << EOL;
1084  generate_comment("initialized transformed params to avoid seg fault on val access",
1085  indent,o);
1086  generate_indent(indent,o);
1087  for (size_t i = 0; i < vs.size(); ++i)
1088  boost::apply_visitor(vis,vs[i].decl_);
1089  }
1090 
1091 
1095  std::ostream& o)
1096  : visgen(o),
1097  indents_(indents)
1098  { }
1099  void operator()(nil const& /*x*/) const { }
1100  void operator()(int_var_decl const& x) const {
1101  std::vector<expression> dims(x.dims_);
1102  validate_array(x.name_,dims,0);
1103  }
1104  void operator()(double_var_decl const& x) const {
1105  std::vector<expression> dims(x.dims_);
1106  validate_array(x.name_,dims,0);
1107  }
1108  void operator()(vector_var_decl const& x) const {
1109  std::vector<expression> dims(x.dims_);
1110  dims.push_back(x.M_);
1111  validate_array(x.name_,dims,1);
1112  }
1113  void operator()(unit_vector_var_decl const& x) const {
1114  std::vector<expression> dims(x.dims_);
1115  dims.push_back(x.K_);
1116  validate_array(x.name_,dims,1);
1117  }
1118  void operator()(simplex_var_decl const& x) const {
1119  std::vector<expression> dims(x.dims_);
1120  dims.push_back(x.K_);
1121  validate_array(x.name_,dims,1);
1122  }
1123  void operator()(ordered_var_decl const& x) const {
1124  std::vector<expression> dims(x.dims_);
1125  dims.push_back(x.K_);
1126  validate_array(x.name_,dims,1);
1127  }
1128  void operator()(positive_ordered_var_decl const& x) const {
1129  std::vector<expression> dims(x.dims_);
1130  dims.push_back(x.K_);
1131  validate_array(x.name_,dims,1);
1132  }
1133  void operator()(row_vector_var_decl const& x) const {
1134  std::vector<expression> dims(x.dims_);
1135  dims.push_back(x.N_);
1136  validate_array(x.name_,dims,1);
1137  }
1138  void operator()(matrix_var_decl const& x) const {
1139  std::vector<expression> dims(x.dims_);
1140  dims.push_back(x.M_);
1141  dims.push_back(x.N_);
1142  validate_array(x.name_,dims,2);
1143  }
1144  void operator()(cov_matrix_var_decl const& x) const {
1145  std::vector<expression> dims(x.dims_);
1146  dims.push_back(x.K_);
1147  dims.push_back(x.K_);
1148  validate_array(x.name_,dims,2);
1149  }
1150  void operator()(corr_matrix_var_decl const& x) const {
1151  std::vector<expression> dims(x.dims_);
1152  dims.push_back(x.K_);
1153  dims.push_back(x.K_);
1154  validate_array(x.name_,dims,2);
1155  }
1156  void validate_array(const std::string& name,
1157  const std::vector<expression>& dims,
1158  size_t matrix_dims) const {
1159 
1160  size_t non_matrix_dims = dims.size() - matrix_dims;
1161 
1162  for (size_t k = 0; k < dims.size(); ++k) {
1163  generate_indent(indents_ + k,o_);
1164  o_ << "for (int i" << k << "__ = 0; i" << k << "__ < ";
1165  generate_expression(dims[k],o_);
1166  o_ << "; ++i" << k << "__) {" << EOL;
1167  }
1168 
1169  generate_indent(indents_ + dims.size(), o_);
1170  o_ << "if (stan::agrad::is_uninitialized(" << name;
1171  for (size_t k = 0; k < non_matrix_dims; ++k)
1172  o_ << "[i" << k << "__]";
1173  if (matrix_dims > 0) {
1174  o_ << "(i" << non_matrix_dims << "__";
1175  if (matrix_dims > 1)
1176  o_ << ",i" << (non_matrix_dims + 1) << "__";
1177  o_ << ')';
1178  }
1179  o_ << ")) {" << EOL;
1180  generate_indent(indents_ + dims.size() + 1, o_);
1181  o_ << "std::stringstream msg__;" << EOL;
1182  generate_indent(indents_ + dims.size() + 1, o_);
1183  o_ << "msg__ << \"Undefined transformed parameter: "
1184  << name << "\"";
1185  for (size_t k = 0; k < dims.size(); ++k) {
1186  o_ << " << '['";
1187  o_ << " << i" << k << "__";
1188  o_ << " << ']'";
1189  }
1190  o_ << ';' << EOL;
1191  generate_indent(indents_ + dims.size() + 1, o_);
1192  o_ << "throw std::runtime_error(msg__.str());" << EOL;
1193 
1194  generate_indent(indents_ + dims.size(), o_);
1195  o_ << "}" << EOL;
1196  for (size_t k = 0; k < dims.size(); ++k) {
1197  generate_indent(indents_ + dims.size() - k - 1, o_);
1198  o_ << "}" << EOL;
1199  }
1200  }
1201  };
1202 
1203  void generate_validate_transformed_params(const std::vector<var_decl>& vs,
1204  int indent,
1205  std::ostream& o) {
1206  generate_comment("validate transformed parameters",indent,o);
1207  validate_transformed_params_visgen vis(indent,o);
1208  for (size_t i = 0; i < vs.size(); ++i)
1209  boost::apply_visitor(vis,vs[i].decl_);
1210  o << EOL;
1211  }
1212 
1213  void generate_statement(statement const& s, int indent, std::ostream& o,
1214  bool include_sampling, bool is_var);
1215 
1216  struct statement_visgen : public visgen {
1217  size_t indent_;
1219  bool is_var_;
1220  statement_visgen(size_t indent,
1221  bool include_sampling,
1222  bool is_var,
1223  std::ostream& o)
1224  : visgen(o),
1225  indent_(indent),
1226  include_sampling_(include_sampling),
1227  is_var_(is_var) {
1228  }
1229  void operator()(nil const& /*x*/) const {
1230  }
1231  void operator()(assignment const& x) const {
1232  generate_indent(indent_,o_);
1233  o_ << "assign(";
1234  generate_indexed_expr<true>(x.var_dims_.name_,
1235  x.var_dims_.dims_,
1237  x.var_type_.dims_.size(),
1238  o_);
1239  o_ << ", ";
1240  generate_expression(x.expr_,o_);
1241  o_ << ");" << EOL;
1242  }
1243  void operator()(sample const& x) const {
1244  if (!include_sampling_) return;
1245  generate_indent(indent_,o_);
1246  o_ << "lp__ += stan::prob::" << x.dist_.family_ << "_log<true>(";
1247  generate_expression(x.expr_,o_);
1248  for (size_t i = 0; i < x.dist_.args_.size(); ++i) {
1249  o_ << ", ";
1250  generate_expression(x.dist_.args_[i],o_);
1251  }
1252  o_ << ");" << EOL;
1253  // generate bounds test
1254  if (x.truncation_.has_low()) {
1255  generate_indent(indent_,o_);
1256  o_ << "if (";
1257  generate_expression(x.expr_,o_);
1258  o_ << " < ";
1260  // bound
1261  o_ << ") lp__ -= std::numeric_limits<double>::infinity();" << EOL;
1262  }
1263  if (x.truncation_.has_high()) {
1264  generate_indent(indent_,o_);
1265  if (x.truncation_.has_low()) o_ << "else ";
1266  o_ << "if (";
1267  generate_expression(x.expr_,o_);
1268  o_ << " > ";
1270  // bound
1271  o_ << ") lp__ -= std::numeric_limits<double>::infinity();" << EOL;
1272  }
1273  if (x.truncation_.has_low() || x.truncation_.has_high()) {
1274  generate_indent(indent_,o_);
1275  o_ << "else ";
1276  }
1277  // generate log denominator
1278  if (x.truncation_.has_low() && x.truncation_.has_high()) {
1279  o_ << "lp__ -= log(";
1280  o_ << x.dist_.family_ << "_cdf(";
1282  for (size_t i = 0; i < x.dist_.args_.size(); ++i) {
1283  o_ << ", ";
1284  generate_expression(x.dist_.args_[i],o_);
1285  }
1286  o_ << ") - " << x.dist_.family_ << "_cdf(";
1288  for (size_t i = 0; i < x.dist_.args_.size(); ++i) {
1289  o_ << ", ";
1290  generate_expression(x.dist_.args_[i],o_);
1291  }
1292  o_ << "));" << EOL;
1293  } else if (!x.truncation_.has_low() && x.truncation_.has_high()) {
1294  o_ << "lp__ -= log(";
1295  o_ << x.dist_.family_ << "_cdf(";
1297  for (size_t i = 0; i < x.dist_.args_.size(); ++i) {
1298  o_ << ", ";
1299  generate_expression(x.dist_.args_[i],o_);
1300  }
1301  o_ << "));" << EOL;
1302  } else if (x.truncation_.has_low() && !x.truncation_.has_high()) {
1303  o_ << "lp__ -= log1m(";
1304  o_ << x.dist_.family_ << "_cdf(";
1306  for (size_t i = 0; i < x.dist_.args_.size(); ++i) {
1307  o_ << ", ";
1308  generate_expression(x.dist_.args_[i],o_);
1309  }
1310  o_ << "));" << EOL;
1311  }
1312  }
1313  void operator()(const statements& x) const {
1314  bool has_local_vars = x.local_decl_.size() > 0;
1315  size_t indent = has_local_vars ? (indent_ + 1) : indent_;
1316  if (has_local_vars) {
1317  generate_indent(indent_,o_);
1318  o_ << "{" << EOL; // need brackets for scope
1319  generate_local_var_decls(x.local_decl_,indent,o_,is_var_);
1320  }
1321 
1322  for (size_t i = 0; i < x.statements_.size(); ++i)
1323  generate_statement(x.statements_[i],indent,o_,include_sampling_,is_var_);
1324 
1325  if (has_local_vars) {
1326  generate_indent(indent_,o_);
1327  o_ << "}" << EOL;
1328  }
1329  }
1330  void operator()(const print_statement& ps) const {
1331  generate_indent(indent_,o_);
1332  o_ << "if (pstream__) {" << EOL;
1333  for (size_t i = 0; i < ps.printables_.size(); ++i) {
1334  generate_indent(indent_ + 1,o_);
1335  o_ << "stan_print(pstream__,";
1336  generate_printable(ps.printables_[i],o_);
1337  o_ << ");" << EOL;
1338  }
1339  generate_indent(indent_ + 1,o_);
1340  o_ << "*pstream__ << std::endl;" << EOL;
1341  generate_indent(indent_,o_);
1342  o_ << '}' << EOL;
1343  }
1344  void operator()(const for_statement& x) const {
1345  generate_indent(indent_,o_);
1346  o_ << "for (int " << x.variable_ << " = ";
1348  o_ << "; " << x.variable_ << " <= ";
1350  o_ << "; ++" << x.variable_ << ") {" << EOL;
1351  generate_statement(x.statement_, indent_ + 1, o_, include_sampling_,is_var_);
1352  generate_indent(indent_,o_);
1353  o_ << "}" << EOL;
1354  }
1355  void operator()(const while_statement& x) const {
1356  generate_indent(indent_,o_);
1357  o_ << "while (as_bool(";
1359  o_ << ")) {" << EOL;
1360  generate_statement(x.body_, indent_+1, o_, include_sampling_,is_var_);
1361  generate_indent(indent_,o_);
1362  o_ << "}" << EOL;
1363  }
1364  void operator()(const conditional_statement& x) const {
1365  for (size_t i = 0; i < x.conditions_.size(); ++i) {
1366  if (i == 0)
1367  generate_indent(indent_,o_);
1368  else
1369  o_ << " else ";
1370  o_ << "if (as_bool(";
1372  o_ << ")) {" << EOL;
1373  generate_statement(x.bodies_[i], indent_ + 1,
1374  o_, include_sampling_,is_var_);
1375  generate_indent(indent_,o_);
1376  o_ << '}';
1377  }
1378  if (x.bodies_.size() > x.conditions_.size()) {
1379  o_ << " else {" << EOL;
1380  generate_statement(x.bodies_[x.bodies_.size()-1], indent_ + 1,
1381  o_, include_sampling_, is_var_);
1382  generate_indent(indent_,o_);
1383  o_ << '}';
1384  }
1385  o_ << EOL;
1386  }
1387  void operator()(const no_op_statement& /*x*/) const {
1388  }
1389  };
1390 
1392  int indent,
1393  std::ostream& o,
1394  bool include_sampling,
1395  bool is_var) {
1396  statement_visgen vis(indent,include_sampling,is_var,o);
1397  boost::apply_visitor(vis,s.statement_);
1398  }
1399 
1400  void generate_statements(const std::vector<statement>& ss,
1401  int indent,
1402  std::ostream& o,
1403  bool include_sampling,
1404  bool is_var) {
1405  statement_visgen vis(indent,include_sampling,is_var,o);
1406  for (size_t i = 0; i < ss.size(); ++i)
1407  boost::apply_visitor(vis,ss[i].statement_);
1408  }
1409 
1410 
1412  std::ostream& o) {
1413  o << EOL;
1414  o << INDENT << "var log_prob(vector<var>& params_r__," << EOL;
1415  o << INDENT << " vector<int>& params_i__," << EOL;
1416  o << INDENT << " std::ostream* pstream__ = 0) {" << EOL;
1417  o << INDENT << " return log_prob_poly<true,var>(params_r__,params_i__,pstream__);" << EOL;
1418  o << INDENT << "}" << EOL;
1419  o << EOL;
1420  o << INDENT << "template <bool propto__, typename T__>" << EOL;
1421  o << INDENT << "T__ log_prob_poly(vector<T__>& params_r__," << EOL;
1422  o << INDENT << " vector<int>& params_i__," << EOL;
1423  o << INDENT << " std::ostream* pstream__ = 0) {" << EOL2;
1424 
1425  // use this dummy for inits
1426  o << INDENT2 << "T__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());" << EOL;
1427  o << INDENT2 << "(void) DUMMY_VAR__; // suppress unused var warning" << EOL2;
1428 
1429  o << INDENT2 << "T__ lp__(0.0);" << EOL2;
1430 
1431  bool is_var = true;
1432 
1433  generate_comment("model parameters",2,o);
1434  generate_local_var_inits(p.parameter_decl_,is_var,true,o);
1435  o << EOL;
1436 
1437  generate_comment("transformed parameters",2,o);
1438  generate_local_var_decls(p.derived_decl_.first,2,o,is_var);
1439  generate_init_vars(p.derived_decl_.first,2,o);
1440 
1441  o << EOL;
1442  bool include_sampling = true;
1443  generate_statements(p.derived_decl_.second,2,o,include_sampling,is_var);
1444  o << EOL;
1445 
1447  o << INDENT2
1448  << "const char* function__ = \"validate transformed params %1%\";"
1449  << EOL;
1450  o << INDENT2
1451  << "(void) function__; // dummy to suppress unused var warning"
1452  << EOL;
1453 
1455 
1456  generate_comment("model body",2,o);
1457  generate_statement(p.statement_,2,o,include_sampling,is_var);
1458  o << EOL;
1459  o << INDENT2 << "return lp__;" << EOL2;
1460  o << INDENT << "} // log_prob(...var...)" << EOL2;
1461  }
1462 
1463  struct dump_member_var_visgen : public visgen {
1466  dump_member_var_visgen(std::ostream& o)
1467  : visgen(o),
1468  var_resizer_(var_resizing_visgen(o)),
1469  var_size_validator_(var_size_validating_visgen(o,"data initialization")) {
1470  }
1471  void operator()(nil const& /*x*/) const { } // dummy
1472  void operator()(int_var_decl const& x) const {
1473  std::vector<expression> dims = x.dims_;
1474  var_size_validator_(x);
1475  var_resizer_(x);
1476  o_ << INDENT2 << "vals_i__ = context__.vals_i(\"" << x.name_ << "\");" << EOL;
1477  o_ << INDENT2 << "pos__ = 0;" << EOL;
1478  size_t indentation = 1;
1479  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1480  size_t dim = dims.size() - dim_up - 1U;
1481  ++indentation;
1482  generate_indent(indentation,o_);
1483  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1484  generate_expression(dims[dim],o_);
1485  o_ << ";" << EOL;
1486  generate_indent(indentation,o_);
1487  o_ << "for (size_t i_" << dim << "__ = 0; i_"
1488  << dim << "__ < " << x.name_ << "_limit_" << dim
1489  << "__; ++i_" << dim << "__) {" << EOL;
1490  }
1491  generate_indent(indentation+1,o_);
1492  o_ << x.name_;
1493  for (size_t dim = 0; dim < dims.size(); ++dim)
1494  o_ << "[i_" << dim << "__]";
1495  o_ << " = vals_i__[pos__++];" << EOL;
1496  for (size_t dim = 0; dim < dims.size(); ++dim) {
1497  generate_indent(dims.size() + 1 - dim,o_);
1498  o_ << "}" << EOL;
1499  }
1500  }
1501  // minor changes to int_var_decl
1502  void operator()(double_var_decl const& x) const {
1503  std::vector<expression> dims = x.dims_;
1504  var_size_validator_(x);
1505  var_resizer_(x);
1506  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1507  o_ << INDENT2 << "pos__ = 0;" << EOL;
1508  size_t indentation = 1;
1509  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1510  size_t dim = dims.size() - dim_up - 1U;
1511  ++indentation;
1512  generate_indent(indentation,o_);
1513  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1514  generate_expression(dims[dim],o_);
1515  o_ << ";" << EOL;
1516  generate_indent(indentation,o_);
1517  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1518  }
1519  generate_indent(indentation+1,o_);
1520  o_ << x.name_;
1521  for (size_t dim = 0; dim < dims.size(); ++dim)
1522  o_ << "[i_" << dim << "__]";
1523  o_ << " = vals_r__[pos__++];" << EOL;
1524  for (size_t dim = 0; dim < dims.size(); ++dim) {
1525  generate_indent(dims.size() + 1 - dim,o_);
1526  o_ << "}" << EOL;
1527  }
1528  }
1529  // extra outer loop around double_var_decl
1530  void operator()(vector_var_decl const& x) const {
1531  std::vector<expression> dims = x.dims_;
1532  var_resizer_(x);
1533  var_size_validator_(x);
1534  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1535  o_ << INDENT2 << "pos__ = 0;" << EOL;
1536  o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
1537  generate_expression(x.M_,o_);
1538  o_ << ";" << EOL;
1539  o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
1540  size_t indentation = 2;
1541  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1542  size_t dim = dims.size() - dim_up - 1U;
1543  ++indentation;
1544  generate_indent(indentation,o_);
1545  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1546  generate_expression(dims[dim],o_);
1547  o_ << ";" << EOL;
1548  generate_indent(indentation,o_);
1549  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1550  }
1551  generate_indent(indentation+1,o_);
1552  o_ << x.name_;
1553  for (size_t dim = 0; dim < dims.size(); ++dim)
1554  o_ << "[i_" << dim << "__]";
1555  o_ << "[i_vec__]";
1556  o_ << " = vals_r__[pos__++];" << EOL;
1557  for (size_t dim = 0; dim < dims.size(); ++dim) {
1558  generate_indent(dims.size() + 2 - dim,o_);
1559  o_ << "}" << EOL;
1560  }
1561  o_ << INDENT2 << "}" << EOL;
1562  }
1563  // change variable name from vector_var_decl
1564  void operator()(row_vector_var_decl const& x) const {
1565  std::vector<expression> dims = x.dims_;
1566  var_size_validator_(x);
1567  var_resizer_(x);
1568  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1569  o_ << INDENT2 << "pos__ = 0;" << EOL;
1570  o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
1571  generate_expression(x.N_,o_);
1572  o_ << ";" << EOL;
1573  o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
1574  size_t indentation = 2;
1575  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1576  size_t dim = dims.size() - dim_up - 1U;
1577  ++indentation;
1578  generate_indent(indentation,o_);
1579  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1580  generate_expression(dims[dim],o_);
1581  o_ << ";" << EOL;
1582  generate_indent(indentation,o_);
1583  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1584  }
1585  generate_indent(indentation+1,o_);
1586  o_ << x.name_;
1587  for (size_t dim = 0; dim < dims.size(); ++dim)
1588  o_ << "[i_" << dim << "__]";
1589  o_ << "[i_vec__]";
1590  o_ << " = vals_r__[pos__++];" << EOL;
1591  for (size_t dim = 0; dim < dims.size(); ++dim) {
1592  generate_indent(dims.size() + 2 - dim,o_);
1593  o_ << "}" << EOL;
1594  }
1595  o_ << INDENT2 << "}" << EOL;
1596  }
1597  // same as simplex
1598  void operator()(unit_vector_var_decl const& x) const {
1599  std::vector<expression> dims = x.dims_;
1600  var_size_validator_(x);
1601  var_resizer_(x);
1602  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1603  o_ << INDENT2 << "pos__ = 0;" << EOL;
1604  o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
1605  generate_expression(x.K_,o_);
1606  o_ << ";" << EOL;
1607  o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
1608  size_t indentation = 2;
1609  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1610  size_t dim = dims.size() - dim_up - 1U;
1611  ++indentation;
1612  generate_indent(indentation,o_);
1613  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1614  generate_expression(dims[dim],o_);
1615  o_ << ";" << EOL;
1616  generate_indent(indentation,o_);
1617  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1618  }
1619  generate_indent(indentation+1,o_);
1620  o_ << x.name_;
1621  for (size_t dim = 0; dim < dims.size(); ++dim)
1622  o_ << "[i_" << dim << "__]";
1623  o_ << "[i_vec__]";
1624  o_ << " = vals_r__[pos__++];" << EOL;
1625  for (size_t dim = 0; dim < dims.size(); ++dim) {
1626  generate_indent(dims.size() + 2 - dim,o_);
1627  o_ << "}" << EOL;
1628  }
1629  o_ << INDENT2 << "}" << EOL;
1630  }
1631  // diff name of dims from vector
1632  void operator()(simplex_var_decl const& x) const {
1633  std::vector<expression> dims = x.dims_;
1634  var_size_validator_(x);
1635  var_resizer_(x);
1636  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1637  o_ << INDENT2 << "pos__ = 0;" << EOL;
1638  o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
1639  generate_expression(x.K_,o_);
1640  o_ << ";" << EOL;
1641  o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
1642  size_t indentation = 2;
1643  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1644  size_t dim = dims.size() - dim_up - 1U;
1645  ++indentation;
1646  generate_indent(indentation,o_);
1647  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1648  generate_expression(dims[dim],o_);
1649  o_ << ";" << EOL;
1650  generate_indent(indentation,o_);
1651  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1652  }
1653  generate_indent(indentation+1,o_);
1654  o_ << x.name_;
1655  for (size_t dim = 0; dim < dims.size(); ++dim)
1656  o_ << "[i_" << dim << "__]";
1657  o_ << "[i_vec__]";
1658  o_ << " = vals_r__[pos__++];" << EOL;
1659  for (size_t dim = 0; dim < dims.size(); ++dim) {
1660  generate_indent(dims.size() + 2 - dim,o_);
1661  o_ << "}" << EOL;
1662  }
1663  o_ << INDENT2 << "}" << EOL;
1664  }
1665  // same as simplex
1666  void operator()(ordered_var_decl const& x) const {
1667  std::vector<expression> dims = x.dims_;
1668  var_size_validator_(x);
1669  var_resizer_(x);
1670  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1671  o_ << INDENT2 << "pos__ = 0;" << EOL;
1672  o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
1673  generate_expression(x.K_,o_);
1674  o_ << ";" << EOL;
1675  o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
1676  size_t indentation = 2;
1677  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1678  size_t dim = dims.size() - dim_up - 1U;
1679  ++indentation;
1680  generate_indent(indentation,o_);
1681  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1682  generate_expression(dims[dim],o_);
1683  o_ << ";" << EOL;
1684  generate_indent(indentation,o_);
1685  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1686  }
1687  generate_indent(indentation+1,o_);
1688  o_ << x.name_;
1689  for (size_t dim = 0; dim < dims.size(); ++dim)
1690  o_ << "[i_" << dim << "__]";
1691  o_ << "[i_vec__]";
1692  o_ << " = vals_r__[pos__++];" << EOL;
1693  for (size_t dim = 0; dim < dims.size(); ++dim) {
1694  generate_indent(dims.size() + 2 - dim,o_);
1695  o_ << "}" << EOL;
1696  }
1697  o_ << INDENT2 << "}" << EOL;
1698  }
1699  // same as simplex
1700  void operator()(positive_ordered_var_decl const& x) const {
1701  std::vector<expression> dims = x.dims_;
1702  var_size_validator_(x);
1703  var_resizer_(x);
1704  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1705  o_ << INDENT2 << "pos__ = 0;" << EOL;
1706  o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
1707  generate_expression(x.K_,o_);
1708  o_ << ";" << EOL;
1709  o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
1710  size_t indentation = 2;
1711  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1712  size_t dim = dims.size() - dim_up - 1U;
1713  ++indentation;
1714  generate_indent(indentation,o_);
1715  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1716  generate_expression(dims[dim],o_);
1717  o_ << ";" << EOL;
1718  generate_indent(indentation,o_);
1719  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1720  }
1721  generate_indent(indentation+1,o_);
1722  o_ << x.name_;
1723  for (size_t dim = 0; dim < dims.size(); ++dim)
1724  o_ << "[i_" << dim << "__]";
1725  o_ << "[i_vec__]";
1726  o_ << " = vals_r__[pos__++];" << EOL;
1727  for (size_t dim = 0; dim < dims.size(); ++dim) {
1728  generate_indent(dims.size() + 2 - dim,o_);
1729  o_ << "}" << EOL;
1730  }
1731  o_ << INDENT2 << "}" << EOL;
1732  }
1733  // extra loop and different accessor vs. vector
1734  void operator()(matrix_var_decl const& x) const {
1735  std::vector<expression> dims = x.dims_;
1736  var_size_validator_(x);
1737  var_resizer_(x);
1738  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1739  o_ << INDENT2 << "pos__ = 0;" << EOL;
1740  o_ << INDENT2 << "size_t " << x.name_ << "_m_mat_lim__ = ";
1741  generate_expression(x.M_,o_);
1742  o_ << ";" << EOL;
1743  o_ << INDENT2 << "size_t " << x.name_ << "_n_mat_lim__ = ";
1744  generate_expression(x.N_,o_);
1745  o_ << ";" << EOL;
1746  o_ << INDENT2 << "for (size_t " << "n_mat__ = 0; " << "n_mat__ < " << x.name_ << "_n_mat_lim__; ++n_mat__) {" << EOL;
1747  o_ << INDENT3 << "for (size_t " << "m_mat__ = 0; " << "m_mat__ < " << x.name_ << "_m_mat_lim__; ++m_mat__) {" << EOL;
1748  size_t indentation = 3;
1749  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1750  size_t dim = dims.size() - dim_up - 1U;
1751  ++indentation;
1752  generate_indent(indentation,o_);
1753  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1754  generate_expression(dims[dim],o_);
1755  o_ << ";" << EOL;
1756  generate_indent(indentation,o_);
1757  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1758  }
1759  generate_indent(indentation+1,o_);
1760  o_ << x.name_;
1761  for (size_t dim = 0; dim < dims.size(); ++dim)
1762  o_ << "[i_" << dim << "__]";
1763  o_ << "(m_mat__,n_mat__)";
1764  o_ << " = vals_r__[pos__++];" << EOL;
1765  for (size_t dim = 0; dim < dims.size(); ++dim) {
1766  generate_indent(dims.size() + 2 - dim,o_);
1767  o_ << "}" << EOL;
1768  }
1769  o_ << INDENT3 << "}" << EOL;
1770  o_ << INDENT2 << "}" << EOL;
1771  }
1772  void operator()(corr_matrix_var_decl const& x) const {
1773  std::vector<expression> dims = x.dims_;
1774  var_size_validator_(x);
1775  var_resizer_(x);
1776  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1777  o_ << INDENT2 << "pos__ = 0;" << EOL;
1778  o_ << INDENT2 << "size_t " << x.name_ << "_k_mat_lim__ = ";
1779  generate_expression(x.K_,o_);
1780  o_ << ";" << EOL;
1781  o_ << INDENT2 << "for (size_t " << "n_mat__ = 0; " << "n_mat__ < " << x.name_ << "_k_mat_lim__; ++n_mat__) {" << EOL;
1782  o_ << INDENT3 << "for (size_t " << "m_mat__ = 0; " << "m_mat__ < " << x.name_ << "_k_mat_lim__; ++m_mat__) {" << EOL;
1783  size_t indentation = 3;
1784  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1785  size_t dim = dims.size() - dim_up - 1U;
1786  ++indentation;
1787  generate_indent(indentation,o_);
1788  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1789  generate_expression(dims[dim],o_);
1790  o_ << ";" << EOL;
1791  generate_indent(indentation,o_);
1792  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1793  }
1794  generate_indent(indentation+1,o_);
1795  o_ << x.name_;
1796  for (size_t dim = 0; dim < dims.size(); ++dim)
1797  o_ << "[i_" << dim << "__]";
1798  o_ << "(m_mat__,n_mat__)";
1799  o_ << " = vals_r__[pos__++];" << EOL;
1800  for (size_t dim = 0; dim < dims.size(); ++dim) {
1801  generate_indent(dims.size() + 2 - dim,o_);
1802  o_ << "}" << EOL;
1803  }
1804  o_ << INDENT3 << "}" << EOL;
1805  o_ << INDENT2 << "}" << EOL;
1806  }
1807  void operator()(cov_matrix_var_decl const& x) const {
1808  std::vector<expression> dims = x.dims_;
1809  var_size_validator_(x);
1810  var_resizer_(x);
1811  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1812  o_ << INDENT2 << "pos__ = 0;" << EOL;
1813  o_ << INDENT2 << "size_t " << x.name_ << "_k_mat_lim__ = ";
1814  generate_expression(x.K_,o_);
1815  o_ << ";" << EOL;
1816  o_ << INDENT2 << "for (size_t " << "n_mat__ = 0; " << "n_mat__ < " << x.name_ << "_k_mat_lim__; ++n_mat__) {" << EOL;
1817  o_ << INDENT3 << "for (size_t " << "m_mat__ = 0; " << "m_mat__ < " << x.name_ << "_k_mat_lim__; ++m_mat__) {" << EOL;
1818  size_t indentation = 3;
1819  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1820  size_t dim = dims.size() - dim_up - 1U;
1821  ++indentation;
1822  generate_indent(indentation,o_);
1823  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1824  generate_expression(dims[dim],o_);
1825  o_ << ";" << EOL;
1826  generate_indent(indentation,o_);
1827  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1828  }
1829  generate_indent(indentation+1,o_);
1830  o_ << x.name_;
1831  for (size_t dim = 0; dim < dims.size(); ++dim)
1832  o_ << "[i_" << dim << "__]";
1833  o_ << "(m_mat__,n_mat__)";
1834  o_ << " = vals_r__[pos__++];" << EOL;
1835  for (size_t dim = 0; dim < dims.size(); ++dim) {
1836  generate_indent(dims.size() + 2 - dim,o_);
1837  o_ << "}" << EOL;
1838  }
1839  o_ << INDENT3 << "}" << EOL;
1840  o_ << INDENT2 << "}" << EOL;
1841  }
1842  };
1843 
1844  void suppress_warning(const std::string& indent,
1845  const std::string& var_name,
1846  std::ostream& o) {
1847  o << indent << "(void) "
1848  << var_name << ";"
1849  << " // dummy call to supress warning"
1850  << EOL;
1851  }
1852 
1853  void generate_member_var_inits(const std::vector<var_decl>& vs,
1854  std::ostream& o) {
1855  dump_member_var_visgen vis(o);
1856  for (size_t i = 0; i < vs.size(); ++i)
1857  boost::apply_visitor(vis, vs[i].decl_);
1858  }
1859 
1860  void generate_constructor(const program& prog,
1861  const std::string& model_name,
1862  std::ostream& o) {
1863  o << INDENT << model_name << "(stan::io::var_context& context__," << EOL;
1864  o << INDENT << " std::ostream* pstream__ = 0)"
1865  << EOL;
1866  o << INDENT2 << ": prob_grad_ad::prob_grad_ad(0) {"
1867  << EOL; // resize 0 with var_resizing
1868  o << INDENT2 << "static const char* function__ = \""
1869  << model_name << "_namespace::" << model_name << "(%1%)\";" << EOL;
1870  suppress_warning(INDENT2, "function__", o);
1871  o << INDENT2 << "size_t pos__;" << EOL;
1872  suppress_warning(INDENT2, "pos__", o);
1873  o << INDENT2 << "std::vector<int> vals_i__;" << EOL;
1874  o << INDENT2 << "std::vector<double> vals_r__;" << EOL;
1875 
1877 
1878  generate_comment("validate data",2,o);
1880 
1882  o << EOL;
1883  bool include_sampling = false;
1884  bool is_var = false;
1885  for (size_t i = 0; i < prog.derived_data_decl_.second.size(); ++i)
1886  generate_statement(prog.derived_data_decl_.second[i],
1887  2,o,include_sampling,is_var);
1888 
1889  generate_comment("validate transformed data",2,o);
1891 
1892  o << EOL << INDENT2 << "set_param_ranges();" << EOL;
1893  o << INDENT << "} // dump ctor" << EOL;
1894  }
1895 
1896  struct generate_init_visgen : public visgen {
1898  generate_init_visgen(std::ostream& o)
1899  : visgen(o),
1900  var_size_validator_(o,"initialization") {
1901  }
1902  void operator()(nil const& /*x*/) const { } // dummy
1903  void operator()(int_var_decl const& x) const {
1904  generate_check_int(x.name_,x.dims_.size());
1905  var_size_validator_(x);
1906  generate_declaration(x.name_,"int",x.dims_);
1907  generate_buffer_loop("i",x.name_, x.dims_);
1908  generate_write_loop("integer(",x.name_,x.dims_);
1909  }
1910  template <typename D>
1911  std::string function_args(const std::string& fun_prefix,
1912  const D& x) const {
1913  std::stringstream ss;
1914  ss << fun_prefix;
1915  if (has_lub(x)) {
1916  ss << "_lub_unconstrain(";
1917  generate_expression(x.range_.low_.expr_,ss);
1918  ss << ',';
1919  generate_expression(x.range_.high_.expr_,ss);
1920  ss << ',';
1921  } else if (has_lb(x)) {
1922  ss << "_lb_unconstrain(";
1923  generate_expression(x.range_.low_.expr_,ss);
1924  ss << ',';
1925  } else if (has_ub(x)) {
1926  ss << "_ub_unconstrain(";
1927  generate_expression(x.range_.high_.expr_,ss);
1928  ss << ',';
1929  } else {
1930  ss << "_unconstrain(";
1931  }
1932  return ss.str();
1933  }
1934 
1935  void operator()(double_var_decl const& x) const {
1936  generate_check_double(x.name_,x.dims_.size());
1937  var_size_validator_(x);
1938  generate_declaration(x.name_,"double",x.dims_);
1939  generate_buffer_loop("r",x.name_,x.dims_);
1940  generate_write_loop(function_args("scalar",x),
1941  x.name_, x.dims_);
1942  }
1943  void operator()(vector_var_decl const& x) const {
1944  generate_check_double(x.name_,x.dims_.size() + 1);
1945  var_size_validator_(x);
1946  generate_declaration(x.name_,"vector_d",x.dims_,x.M_);
1947  generate_buffer_loop("r",x.name_,x.dims_,x.M_);
1948  generate_write_loop(function_args("vector",x),
1949  x.name_,x.dims_);
1950  }
1951  void operator()(row_vector_var_decl const& x) const {
1952  generate_check_double(x.name_,x.dims_.size() + 1);
1953  var_size_validator_(x);
1954  generate_declaration(x.name_,"row_vector_d",x.dims_,x.N_);
1955  generate_buffer_loop("r",x.name_,x.dims_,x.N_);
1956  generate_write_loop(function_args("row_vector",x),
1957  x.name_,x.dims_);
1958  }
1959  void operator()(matrix_var_decl const& x) const {
1960  generate_check_double(x.name_,x.dims_.size() + 2);
1961  var_size_validator_(x);
1962  generate_declaration(x.name_,"matrix_d",x.dims_,x.M_,x.N_);
1963  generate_buffer_loop("r",x.name_,x.dims_,x.M_,x.N_);
1964  generate_write_loop(function_args("matrix",x),
1965  x.name_,x.dims_);
1966  }
1967  void operator()(unit_vector_var_decl const& x) const {
1968  generate_check_double(x.name_,x.dims_.size() + 1);
1969  var_size_validator_(x);
1970  generate_declaration(x.name_,"vector_d",x.dims_,x.K_);
1971  generate_buffer_loop("r",x.name_,x.dims_,x.K_);
1972  generate_write_loop("unit_vector_unconstrain(",x.name_,x.dims_);
1973  }
1974  void operator()(simplex_var_decl const& x) const {
1975  generate_check_double(x.name_,x.dims_.size() + 1);
1976  var_size_validator_(x);
1977  generate_declaration(x.name_,"vector_d",x.dims_,x.K_);
1978  generate_buffer_loop("r",x.name_,x.dims_,x.K_);
1979  generate_write_loop("simplex_unconstrain(",x.name_,x.dims_);
1980  }
1981  void operator()(ordered_var_decl const& x) const {
1982  generate_check_double(x.name_,x.dims_.size() + 1);
1983  var_size_validator_(x);
1984  generate_declaration(x.name_,"vector_d",x.dims_,x.K_);
1985  generate_buffer_loop("r",x.name_,x.dims_,x.K_);
1986  generate_write_loop("ordered_unconstrain(",x.name_,x.dims_);
1987  }
1988  void operator()(positive_ordered_var_decl const& x) const {
1989  generate_check_double(x.name_,x.dims_.size() + 1);
1990  var_size_validator_(x);
1991  generate_declaration(x.name_,"vector_d",x.dims_,x.K_);
1992  generate_buffer_loop("r",x.name_,x.dims_,x.K_);
1993  generate_write_loop("positive_ordered_unconstrain(",x.name_,x.dims_);
1994  }
1995  void operator()(cov_matrix_var_decl const& x) const {
1996  generate_check_double(x.name_,x.dims_.size() + 2);
1997  var_size_validator_(x);
1998  generate_declaration(x.name_,"matrix_d",x.dims_,x.K_,x.K_);
1999  generate_buffer_loop("r",x.name_,x.dims_,x.K_,x.K_);
2000  generate_write_loop("cov_matrix_unconstrain(",x.name_,x.dims_);
2001  }
2002  void operator()(corr_matrix_var_decl const& x) const {
2003  generate_check_double(x.name_,x.dims_.size() + 2);
2004  var_size_validator_(x);
2005  generate_declaration(x.name_,"matrix_d",x.dims_,x.K_,x.K_);
2006  generate_buffer_loop("r",x.name_,x.dims_,x.K_,x.K_);
2007  generate_write_loop("corr_matrix_unconstrain(",x.name_,x.dims_);
2008  }
2009  void generate_write_loop(const std::string& write_method_name,
2010  const std::string& var_name,
2011  const std::vector<expression>& dims) const {
2012  generate_dims_loop_fwd(dims);
2013  o_ << "writer__." << write_method_name;
2014  generate_name_dims(var_name,dims.size());
2015  o_ << ");" << EOL;
2016  }
2017  void generate_name_dims(const std::string name,
2018  size_t num_dims) const {
2019  o_ << name;
2020  for (size_t i = 0; i < num_dims; ++i)
2021  o_ << "[i" << i << "__]";
2022  }
2023  void generate_declaration(const std::string& name,
2024  const std::string& base_type,
2025  const std::vector<expression>& dims,
2026  const expression& type_arg1 = expression(),
2027  const expression& type_arg2 = expression()) const {
2028  o_ << INDENT2;
2029  generate_type(base_type,dims,dims.size(),o_);
2030  o_ << ' ' << name;
2031 
2032  generate_initializer(o_,base_type,dims,type_arg1,type_arg2);
2033  }
2034  void generate_indent_num_dims(size_t base_indent,
2035  const std::vector<expression>& dims,
2036  const expression& dim1,
2037  const expression& dim2) const {
2038  generate_indent(dims.size() + base_indent,o_);
2039  if (!is_nil(dim1)) o_ << INDENT;
2040  if (!is_nil(dim2)) o_ << INDENT;
2041  }
2042  void generate_buffer_loop(const std::string& base_type,
2043  const std::string& name,
2044  const std::vector<expression>& dims,
2045  const expression& dim1 = expression(),
2046  const expression& dim2 = expression(),
2047  int indent = 2U) const {
2048  size_t size = dims.size();
2049  bool is_matrix = !is_nil(dim1) && !is_nil(dim2);
2050  bool is_vector = !is_nil(dim1) && is_nil(dim2);
2051  int extra_indent = is_matrix ? 2U : is_vector ? 1U : 0U;
2052  if (is_matrix) {
2053  generate_indent(indent,o_);
2054  o_ << "for (int j2__ = 0U; j2__ < ";
2055  generate_expression(dim2.expr_,o_);
2056  o_ << "; ++j2__)" << EOL;
2057 
2058  generate_indent(indent+1,o_);
2059  o_ << "for (int j1__ = 0U; j1__ < ";
2060  generate_expression(dim1.expr_,o_);
2061  o_ << "; ++j1__)" << EOL;
2062  } else if (is_vector) {
2063  generate_indent(indent,o_);
2064  o_ << "for (int j1__ = 0U; j1__ < ";
2065  generate_expression(dim1.expr_,o_);
2066  o_ << "; ++j1__)" << EOL;
2067  }
2068  for (size_t i = 0; i < size; ++i) {
2069  size_t idx = size - i - 1;
2070  generate_indent(i + indent + extra_indent, o_);
2071  o_ << "for (int i" << idx << "__ = 0U; i" << idx << "__ < ";
2072  generate_expression(dims[idx].expr_,o_);
2073  o_ << "; ++i" << idx << "__)" << EOL;
2074  }
2075  generate_indent_num_dims(2U,dims,dim1,dim2);
2076  o_ << name;
2077  for (size_t i = 0; i < dims.size(); ++i)
2078  o_ << "[i" << i << "__]";
2079  if (is_matrix)
2080  o_ << "(j1__,j2__)";
2081  else if (is_vector)
2082  o_ << "(j1__)";
2083  o_ << " = vals_" << base_type << "__[pos__++];" << EOL;
2084  }
2085  void generate_dims_loop_fwd(const std::vector<expression>& dims,
2086  int indent = 2U) const {
2087  size_t size = dims.size();
2088  for (size_t i = 0; i < size; ++i) {
2089  generate_indent(i + indent, o_);
2090  o_ << "for (int i" << i << "__ = 0U; i" << i << "__ < ";
2091  generate_expression(dims[i].expr_,o_);
2092  o_ << "; ++i" << i << "__)" << EOL;
2093  }
2094  generate_indent(2U + dims.size(),o_);
2095  }
2096  void generate_check_int(const std::string& name, size_t /*n*/) const {
2097  o_ << EOL << INDENT2
2098  << "if (!(context__.contains_i(\"" << name << "\")))"
2099  << EOL << INDENT3
2100  << "throw std::runtime_error(\"variable " << name << " missing\");" << EOL;
2101  o_ << INDENT2 << "vals_i__ = context__.vals_i(\"" << name << "\");" << EOL;
2102  o_ << INDENT2 << "pos__ = 0U;" << EOL;
2103  }
2104  void generate_check_double(const std::string& name, size_t /*n*/) const {
2105  o_ << EOL << INDENT2
2106  << "if (!(context__.contains_r(\"" << name << "\")))"
2107  << EOL << INDENT3
2108  << "throw std::runtime_error(\"variable " << name << " missing\");" << EOL;
2109  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << name << "\");" << EOL;
2110  o_ << INDENT2 << "pos__ = 0U;" << EOL;
2111  }
2112  };
2113 
2114 
2115  void generate_init_method(const std::vector<var_decl>& vs,
2116  std::ostream& o) {
2117  o << EOL;
2118  o << INDENT << "void transform_inits(const stan::io::var_context& context__," << EOL;
2119  o << INDENT << " std::vector<int>& params_i__," << EOL;
2120  o << INDENT << " std::vector<double>& params_r__) {" << EOL;
2121  o << INDENT2 << "stan::io::writer<double> writer__(params_r__,params_i__);" << EOL;
2122  o << INDENT2 << "size_t pos__;" << EOL;
2123  o << INDENT2 << "std::vector<double> vals_r__;" << EOL;
2124  o << INDENT2 << "std::vector<int> vals_i__;" << EOL;
2125  o << EOL;
2126  generate_init_visgen vis(o);
2127  for (size_t i = 0; i < vs.size(); ++i)
2128  boost::apply_visitor(vis, vs[i].decl_);
2129 
2130  o << INDENT2 << "params_r__ = writer__.data_r();" << EOL;
2131  o << INDENT2 << "params_i__ = writer__.data_i();" << EOL;
2132  o << INDENT << "}" << EOL;
2133  }
2134 
2135  // see write_csv_visgen for similar structure
2136  struct write_dims_visgen : public visgen {
2137  write_dims_visgen(std::ostream& o)
2138  : visgen(o) {
2139  }
2140  void operator()(const nil& /*x*/) const { }
2141  void operator()(const int_var_decl& x) const {
2142  generate_dims_array(EMPTY_EXP_VECTOR,x.dims_);
2143  }
2144  void operator()(const double_var_decl& x) const {
2145  generate_dims_array(EMPTY_EXP_VECTOR,x.dims_);
2146  }
2147  void operator()(const vector_var_decl& x) const {
2148  std::vector<expression> matrix_args;
2149  matrix_args.push_back(x.M_);
2150  generate_dims_array(matrix_args,x.dims_);
2151  }
2152  void operator()(const row_vector_var_decl& x) const {
2153  std::vector<expression> matrix_args;
2154  matrix_args.push_back(x.N_);
2155  generate_dims_array(matrix_args,x.dims_);
2156  }
2157  void operator()(const matrix_var_decl& x) const {
2158  std::vector<expression> matrix_args;
2159  matrix_args.push_back(x.M_);
2160  matrix_args.push_back(x.N_);
2161  generate_dims_array(matrix_args,x.dims_);
2162  }
2163  void operator()(const unit_vector_var_decl& x) const {
2164  std::vector<expression> matrix_args;
2165  matrix_args.push_back(x.K_);
2166  generate_dims_array(matrix_args,x.dims_);
2167  }
2168  void operator()(const simplex_var_decl& x) const {
2169  std::vector<expression> matrix_args;
2170  matrix_args.push_back(x.K_);
2171  generate_dims_array(matrix_args,x.dims_);
2172  }
2173  void operator()(const ordered_var_decl& x) const {
2174  std::vector<expression> matrix_args;
2175  matrix_args.push_back(x.K_);
2176  generate_dims_array(matrix_args,x.dims_);
2177  }
2178  void operator()(const positive_ordered_var_decl& x) const {
2179  std::vector<expression> matrix_args;
2180  matrix_args.push_back(x.K_);
2181  generate_dims_array(matrix_args,x.dims_);
2182  }
2183  void operator()(const cov_matrix_var_decl& x) const {
2184  std::vector<expression> matrix_args;
2185  matrix_args.push_back(x.K_);
2186  matrix_args.push_back(x.K_);
2187  generate_dims_array(matrix_args,x.dims_);
2188  }
2189  void operator()(const corr_matrix_var_decl& x) const {
2190  std::vector<expression> matrix_args;
2191  matrix_args.push_back(x.K_);
2192  matrix_args.push_back(x.K_);
2193  generate_dims_array(matrix_args,x.dims_);
2194  }
2195  void
2196  generate_dims_array(const std::vector<expression>& matrix_dims_exprs,
2197  const std::vector<expression>& array_dims_exprs)
2198  const {
2199 
2200  o_ << INDENT2 << "dims__.resize(0);" << EOL;
2201  for (size_t i = 0; i < array_dims_exprs.size(); ++i) {
2202  o_ << INDENT2 << "dims__.push_back(";
2203  generate_expression(array_dims_exprs[i].expr_, o_);
2204  o_ << ");" << EOL;
2205  }
2206  // cut and paste above with matrix_dims_exprs
2207  for (size_t i = 0; i < matrix_dims_exprs.size(); ++i) {
2208  o_ << INDENT2 << "dims__.push_back(";
2209  generate_expression(matrix_dims_exprs[i].expr_, o_);
2210  o_ << ");" << EOL;
2211  }
2212  o_ << INDENT2 << "dimss__.push_back(dims__);" << EOL;
2213  }
2214 
2215  };
2216 
2217  void generate_dims_method(const program& prog,
2218  std::ostream& o) {
2219  write_dims_visgen vis(o);
2220  o << EOL << INDENT
2221  << "void get_dims(std::vector<std::vector<size_t> >& dimss__) {"
2222  << EOL;
2223 
2224  o << INDENT2 << "dimss__.resize(0);" << EOL;
2225  o << INDENT2 << "std::vector<size_t> dims__;" << EOL;
2226 
2227  // parameters
2228  for (size_t i = 0; i < prog.parameter_decl_.size(); ++i) {
2229  boost::apply_visitor(vis,prog.parameter_decl_[i].decl_);
2230  }
2231  // transformed parameters
2232  for (size_t i = 0; i < prog.derived_decl_.first.size(); ++i) {
2233  boost::apply_visitor(vis,prog.derived_decl_.first[i].decl_);
2234  }
2235  // generated quantities
2236  for (size_t i = 0; i < prog.generated_decl_.first.size(); ++i) {
2237  boost::apply_visitor(vis,prog.generated_decl_.first[i].decl_);
2238  }
2239  o << INDENT << "}" << EOL2;
2240  }
2241 
2242 
2243 
2244  // see write_csv_visgen for similar structure
2246  write_param_names_visgen(std::ostream& o)
2247  : visgen(o) {
2248  }
2249  void operator()(const nil& /*x*/) const { }
2250  void operator()(const int_var_decl& x) const {
2251  generate_param_names(x.name_);
2252  }
2253  void operator()(const double_var_decl& x) const {
2254  generate_param_names(x.name_);
2255  }
2256  void operator()(const vector_var_decl& x) const {
2257  generate_param_names(x.name_);
2258  }
2259  void operator()(const row_vector_var_decl& x) const {
2260  generate_param_names(x.name_);
2261  }
2262  void operator()(const matrix_var_decl& x) const {
2263  generate_param_names(x.name_);
2264  }
2265  void operator()(const unit_vector_var_decl& x) const {
2266  generate_param_names(x.name_);
2267  }
2268  void operator()(const simplex_var_decl& x) const {
2269  generate_param_names(x.name_);
2270  }
2271  void operator()(const ordered_var_decl& x) const {
2272  generate_param_names(x.name_);
2273  }
2274  void operator()(const positive_ordered_var_decl& x) const {
2275  generate_param_names(x.name_);
2276  }
2277  void operator()(const cov_matrix_var_decl& x) const {
2278  generate_param_names(x.name_);
2279  }
2280  void operator()(const corr_matrix_var_decl& x) const {
2281  generate_param_names(x.name_);
2282  }
2283  void
2284  generate_param_names(const std::string& name) const {
2285  o_ << INDENT2
2286  << "names__.push_back(\"" << name << "\");"
2287  << EOL;
2288  }
2289  };
2290 
2291 
2293  std::ostream& o) {
2294  write_param_names_visgen vis(o);
2295  o << EOL << INDENT
2296  << "void get_param_names(std::vector<std::string>& names__) {"
2297  << EOL;
2298 
2299  o << INDENT2
2300  << "names__.resize(0);"
2301  << EOL;
2302 
2303  // parameters
2304  for (size_t i = 0; i < prog.parameter_decl_.size(); ++i) {
2305  boost::apply_visitor(vis,prog.parameter_decl_[i].decl_);
2306  }
2307  // transformed parameters
2308  for (size_t i = 0; i < prog.derived_decl_.first.size(); ++i) {
2309  boost::apply_visitor(vis,prog.derived_decl_.first[i].decl_);
2310  }
2311  // generated quantities
2312  for (size_t i = 0; i < prog.generated_decl_.first.size(); ++i) {
2313  boost::apply_visitor(vis,prog.generated_decl_.first[i].decl_);
2314  }
2315 
2316  o << INDENT << "}" << EOL2;
2317  }
2318 
2319 
2320 
2321  // see write_csv_visgen for similar structure
2323  write_csv_header_visgen(std::ostream& o)
2324  : visgen(o) {
2325  }
2326  void operator()(const nil& /*x*/) const { }
2327  void operator()(const int_var_decl& x) const {
2328  generate_csv_header_array(EMPTY_EXP_VECTOR,x.name_,x.dims_);
2329  }
2330  void operator()(const double_var_decl& x) const {
2331  generate_csv_header_array(EMPTY_EXP_VECTOR,x.name_,x.dims_);
2332  }
2333  void operator()(const vector_var_decl& x) const {
2334  std::vector<expression> matrix_args;
2335  matrix_args.push_back(x.M_);
2336  generate_csv_header_array(matrix_args,x.name_,x.dims_);
2337  }
2338  void operator()(const row_vector_var_decl& x) const {
2339  std::vector<expression> matrix_args;
2340  matrix_args.push_back(x.N_);
2341  generate_csv_header_array(matrix_args,x.name_,x.dims_);
2342  }
2343  void operator()(const matrix_var_decl& x) const {
2344  std::vector<expression> matrix_args;
2345  matrix_args.push_back(x.M_);
2346  matrix_args.push_back(x.N_);
2347  generate_csv_header_array(matrix_args,x.name_,x.dims_);
2348  }
2349  void operator()(const unit_vector_var_decl& x) const {
2350  std::vector<expression> matrix_args;
2351  matrix_args.push_back(x.K_);
2352  generate_csv_header_array(matrix_args,x.name_,x.dims_);
2353  }
2354  void operator()(const simplex_var_decl& x) const {
2355  std::vector<expression> matrix_args;
2356  matrix_args.push_back(x.K_);
2357  generate_csv_header_array(matrix_args,x.name_,x.dims_);
2358  }
2359  void operator()(const ordered_var_decl& x) const {
2360  std::vector<expression> matrix_args;
2361  matrix_args.push_back(x.K_);
2362  generate_csv_header_array(matrix_args,x.name_,x.dims_);
2363  }
2364  void operator()(const positive_ordered_var_decl& x) const {
2365  std::vector<expression> matrix_args;
2366  matrix_args.push_back(x.K_);
2367  generate_csv_header_array(matrix_args,x.name_,x.dims_);
2368  }
2369  void operator()(const cov_matrix_var_decl& x) const {
2370  std::vector<expression> matrix_args;
2371  matrix_args.push_back(x.K_);
2372  matrix_args.push_back(x.K_);
2373  generate_csv_header_array(matrix_args,x.name_,x.dims_);
2374  }
2375  void operator()(const corr_matrix_var_decl& x) const {
2376  std::vector<expression> matrix_args;
2377  matrix_args.push_back(x.K_);
2378  matrix_args.push_back(x.K_);
2379  generate_csv_header_array(matrix_args,x.name_,x.dims_);
2380  }
2381  void
2382  generate_csv_header_array(const std::vector<expression>& matrix_dims,
2383  const std::string& name,
2384  const std::vector<expression>& dims) const {
2385 
2386  // begin for loop dims
2387  std::vector<expression> combo_dims(dims);
2388  for (size_t i = 0; i < matrix_dims.size(); ++i)
2389  combo_dims.push_back(matrix_dims[i]);
2390 
2391  for (size_t i = 0; i < combo_dims.size(); ++i) {
2392  generate_indent(2 + i,o_);
2393  o_ << "for (int k_" << i << "__ = 1;"
2394  << " k_" << i << "__ <= ";
2395  generate_expression(combo_dims[i].expr_,o_);
2396  o_ << "; ++k_" << i << "__) {" << EOL; // begin (1)
2397  }
2398 
2399  // variable + indices
2400  generate_indent(2 + combo_dims.size(),o_);
2401  o_ << "writer__.comma();" << EOL; // only writes comma after first call
2402 
2403  generate_indent(2 + combo_dims.size(),o_);
2404  o_ << "o__ << \"" << name << '"';
2405  for (size_t i = 0; i < combo_dims.size(); ++i)
2406  o_ << " << '.' << k_" << i << "__";
2407  o_ << ';' << EOL;
2408 
2409  // end for loop dims
2410  for (size_t i = 0; i < combo_dims.size(); ++i) {
2411  generate_indent(1 + combo_dims.size() - i,o_);
2412  o_ << "}" << EOL; // end (1)
2413  }
2414  }
2415  };
2416 
2417 
2419  std::ostream& o) {
2420  write_csv_header_visgen vis(o);
2421  o << EOL << INDENT << "void write_csv_header(std::ostream& o__) {" << EOL;
2422  o << INDENT2 << "stan::io::csv_writer writer__(o__);" << EOL;
2423 
2424  // parameters
2425  for (size_t i = 0; i < prog.parameter_decl_.size(); ++i) {
2426  boost::apply_visitor(vis,prog.parameter_decl_[i].decl_);
2427  }
2428  // transformed parameters
2429  for (size_t i = 0; i < prog.derived_decl_.first.size(); ++i) {
2430  boost::apply_visitor(vis,prog.derived_decl_.first[i].decl_);
2431  }
2432  // generated quantities
2433  for (size_t i = 0; i < prog.generated_decl_.first.size(); ++i) {
2434  boost::apply_visitor(vis,prog.generated_decl_.first[i].decl_);
2435  }
2436  o << INDENT2 << "writer__.newline();" << EOL;
2437  o << INDENT << "}" << EOL2;
2438  }
2439 
2440  // see init_member_var_visgen for cut & paste
2441  struct write_csv_visgen : public visgen {
2442  write_csv_visgen(std::ostream& o)
2443  : visgen(o) {
2444  }
2445  template <typename D>
2446  void generate_initialize_array_bounded(const D& x, const std::string& base_type,
2447  const std::string& read_fun_prefix,
2448  const std::vector<expression>& dim_args) const {
2449  std::vector<expression> read_args;
2450  std::string read_fun(read_fun_prefix);
2451  if (has_lub(x)) {
2452  read_fun += "_lub";
2453  read_args.push_back(x.range_.low_);
2454  read_args.push_back(x.range_.high_);
2455  } else if (has_lb(x)) {
2456  read_fun += "_lb";
2457  read_args.push_back(x.range_.low_);
2458  } else if (has_ub(x)) {
2459  read_fun += "_ub";
2460  read_args.push_back(x.range_.high_);
2461  }
2462  for (size_t i = 0; i < dim_args.size(); ++i)
2463  read_args.push_back(dim_args[i]);
2464  generate_initialize_array(base_type,read_fun,read_args,x.name_,x.dims_);
2465  }
2466  void operator()(const nil& /*x*/) const { }
2467  void operator()(const int_var_decl& x) const {
2468  generate_initialize_array("int","integer",EMPTY_EXP_VECTOR,
2469  x.name_,x.dims_);
2470  }
2471  void operator()(const double_var_decl& x) const {
2472  std::vector<expression> read_args;
2473  generate_initialize_array_bounded(x,"double","scalar",read_args);
2474  }
2475  void operator()(const vector_var_decl& x) const {
2476  std::vector<expression> read_args;
2477  read_args.push_back(x.M_);
2478  generate_initialize_array_bounded(x,"vector_d","vector",read_args);
2479  }
2480  void operator()(const row_vector_var_decl& x) const {
2481  std::vector<expression> read_args;
2482  read_args.push_back(x.N_);
2483  generate_initialize_array_bounded(x,"row_vector_d","row_vector",read_args);
2484  }
2485  void operator()(const matrix_var_decl& x) const {
2486  std::vector<expression> read_args;
2487  read_args.push_back(x.M_);
2488  read_args.push_back(x.N_);
2489  generate_initialize_array_bounded(x,"matrix_d","matrix",read_args);
2490  }
2491  void operator()(const unit_vector_var_decl& x) const {
2492  std::vector<expression> read_args;
2493  read_args.push_back(x.K_);
2494  generate_initialize_array("vector_d","unit_vector",read_args,x.name_,x.dims_);
2495  }
2496  void operator()(const simplex_var_decl& x) const {
2497  std::vector<expression> read_args;
2498  read_args.push_back(x.K_);
2499  generate_initialize_array("vector_d","simplex",read_args,x.name_,x.dims_);
2500  }
2501  void operator()(const ordered_var_decl& x) const {
2502  std::vector<expression> read_args;
2503  read_args.push_back(x.K_);
2504  generate_initialize_array("vector_d","ordered",read_args,x.name_,x.dims_);
2505  }
2506  void operator()(const positive_ordered_var_decl& x) const {
2507  std::vector<expression> read_args;
2508  read_args.push_back(x.K_);
2509  generate_initialize_array("vector_d","positive_ordered",read_args,x.name_,x.dims_);
2510  }
2511  void operator()(const cov_matrix_var_decl& x) const {
2512  std::vector<expression> read_args;
2513  read_args.push_back(x.K_);
2514  generate_initialize_array("matrix_d","cov_matrix",read_args,x.name_,x.dims_);
2515  }
2516  void operator()(const corr_matrix_var_decl& x) const {
2517  std::vector<expression> read_args;
2518  read_args.push_back(x.K_);
2519  generate_initialize_array("matrix_d","corr_matrix",read_args,x.name_,x.dims_);
2520  }
2521  void generate_initialize_array(const std::string& var_type,
2522  const std::string& read_type,
2523  const std::vector<expression>& read_args,
2524  const std::string& name,
2525  const std::vector<expression>& dims) const {
2526  if (dims.size() == 0) {
2527  generate_indent(2,o_);
2528  o_ << var_type << " ";
2529  o_ << name << " = in__." << read_type << "_constrain(";
2530  for (size_t j = 0; j < read_args.size(); ++j) {
2531  if (j > 0) o_ << ",";
2532  generate_expression(read_args[j],o_);
2533  }
2534  o_ << ");" << EOL;
2535  o_ << INDENT2 << "writer__.write(" << name << ");" << EOL;
2536  return;
2537  }
2538  o_ << INDENT2;
2539  for (size_t i = 0; i < dims.size(); ++i) o_ << "vector<";
2540  o_ << var_type;
2541  for (size_t i = 0; i < dims.size(); ++i) o_ << "> ";
2542  o_ << name << ";" << EOL;
2543  std::string name_dims(name);
2544  for (size_t i = 0; i < dims.size(); ++i) {
2545  generate_indent(i + 2, o_);
2546  o_ << "size_t dim_" << name << "_" << i << "__ = ";
2547  generate_expression(dims[i],o_);
2548  o_ << ";" << EOL;
2549  if (i < dims.size() - 1) {
2550  generate_indent(i + 2, o_);
2551  o_ << name_dims << ".resize(dim_" << name << "_" << i << "__);"
2552  << EOL;
2553  name_dims.append("[k_").append(to_string(i)).append("__]");
2554  }
2555  generate_indent(i + 2, o_);
2556  o_ << "for (size_t k_" << i << "__ = 0;"
2557  << " k_" << i << "__ < dim_" << name << "_" << i << "__;"
2558  << " ++k_" << i << "__) {" << EOL;
2559  if (i == dims.size() - 1) {
2560  generate_indent(i + 3, o_);
2561  o_ << name_dims << ".push_back(in__." << read_type << "_constrain(";
2562  for (size_t j = 0; j < read_args.size(); ++j) {
2563  if (j > 0) o_ << ",";
2564  generate_expression(read_args[j],o_);
2565  }
2566  o_ << "));" << EOL;
2567  }
2568  }
2569  generate_indent(dims.size() + 2, o_);
2570  o_ << "writer__.write(" << name;
2571  if (dims.size() > 0) {
2572  o_ << '[';
2573  for (size_t i = 0; i < dims.size(); ++i) {
2574  if (i > 0) o_ << "][";
2575  o_ << "k_" << i << "__";
2576  }
2577  o_ << ']';
2578  }
2579  o_ << ");" << EOL;
2580 
2581  for (size_t i = dims.size(); i > 0; --i) {
2582  generate_indent(i + 1, o_);
2583  o_ << "}" << EOL;
2584  }
2585  }
2586  };
2587 
2588 
2589 
2590 
2591  struct write_csv_vars_visgen : public visgen {
2592  write_csv_vars_visgen(std::ostream& o)
2593  : visgen(o) {
2594  }
2595  void operator()(const nil& /*x*/) const { }
2596  // FIXME: template these out
2597  void operator()(const int_var_decl& x) const {
2598  write_array(x.name_,x.dims_);
2599  }
2600  void operator()(const double_var_decl& x) const {
2601  write_array(x.name_,x.dims_);
2602  }
2603  void operator()(const vector_var_decl& x) const {
2604  write_array(x.name_,x.dims_);
2605  }
2606  void operator()(const row_vector_var_decl& x) const {
2607  write_array(x.name_,x.dims_);
2608  }
2609  void operator()(const matrix_var_decl& x) const {
2610  write_array(x.name_,x.dims_);
2611  }
2612  void operator()(const unit_vector_var_decl& x) const {
2613  write_array(x.name_,x.dims_);
2614  }
2615  void operator()(const simplex_var_decl& x) const {
2616  write_array(x.name_,x.dims_);
2617  }
2618  void operator()(const ordered_var_decl& x) const {
2619  write_array(x.name_,x.dims_);
2620  }
2621  void operator()(const positive_ordered_var_decl& x) const {
2622  write_array(x.name_,x.dims_);
2623  }
2624  void operator()(const cov_matrix_var_decl& x) const {
2625  write_array(x.name_,x.dims_);
2626  }
2627  void operator()(const corr_matrix_var_decl& x) const {
2628  write_array(x.name_,x.dims_);
2629  }
2630  void write_array(const std::string& name,
2631  const std::vector<expression>& dims) const {
2632  if (dims.size() == 0) {
2633  o_ << INDENT2 << "writer__.write(" << name << ");" << EOL;
2634  return;
2635  }
2636  for (size_t i = 0; i < dims.size(); ++i) {
2637  generate_indent(i + 2, o_);
2638  o_ << "for (int k_" << i << "__ = 0;"
2639  << " k_" << i << "__ < ";
2640  generate_expression(dims[i],o_);
2641  o_ << "; ++k_" << i << "__) {" << EOL;
2642  }
2643 
2644  generate_indent(dims.size() + 2, o_);
2645  o_ << "writer__.write(" << name;
2646  if (dims.size() > 0) {
2647  o_ << '[';
2648  for (size_t i = 0; i < dims.size(); ++i) {
2649  if (i > 0) o_ << "][";
2650  o_ << "k_" << i << "__";
2651  }
2652  o_ << ']';
2653  }
2654  o_ << ");" << EOL;
2655 
2656  for (size_t i = dims.size(); i > 0; --i) {
2657  generate_indent(i + 1, o_);
2658  o_ << "}" << EOL;
2659  }
2660  }
2661  };
2662 
2663 
2665  const std::string& model_name,
2666  std::ostream& o) {
2667  o << INDENT << "template <typename RNG>" << EOL;
2668  o << INDENT << "void write_csv(RNG& base_rng__," << EOL;
2669  o << INDENT << " std::vector<double>& params_r__," << EOL;
2670  o << INDENT << " std::vector<int>& params_i__," << EOL;
2671  o << INDENT << " std::ostream& o__," << EOL;
2672  o << INDENT << " std::ostream* pstream__ = 0) {" << EOL;
2673  o << INDENT2 << "stan::io::reader<double> in__(params_r__,params_i__);"
2674  << EOL;
2675  o << INDENT2 << "stan::io::csv_writer writer__(o__);" << EOL;
2676  o << INDENT2 << "static const char* function__ = \""
2677  << model_name << "_namespace::write_csv(%1%)\";" << EOL;
2678  suppress_warning(INDENT2, "function__", o);
2679 
2680  // declares, reads, and writes parameters
2681  generate_comment("read-transform, write parameters",2,o);
2682  write_csv_visgen vis(o);
2683  for (size_t i = 0; i < prog.parameter_decl_.size(); ++i)
2684  boost::apply_visitor(vis,prog.parameter_decl_[i].decl_);
2685 
2686  // this is for all other values
2687  write_csv_vars_visgen vis_writer(o);
2688 
2689  // parameters are guaranteed to satisfy constraints
2690 
2691  o << EOL;
2692  generate_comment("declare, define and validate transformed parameters",
2693  2,o);
2694  o << INDENT2 << "double lp__ = 0.0;" << EOL;
2695  suppress_warning(INDENT2, "lp__", o);
2696  bool is_var = false;
2697  generate_local_var_decls(prog.derived_decl_.first,2,o,is_var);
2698  o << EOL;
2699  bool include_sampling = false;
2700  generate_statements(prog.derived_decl_.second,2,o,include_sampling,is_var);
2701  o << EOL;
2702 
2704  o << EOL;
2705 
2706  generate_comment("write transformed parameters",2,o);
2707  for (size_t i = 0; i < prog.derived_decl_.first.size(); ++i)
2708  boost::apply_visitor(vis_writer, prog.derived_decl_.first[i].decl_);
2709  o << EOL;
2710 
2711  generate_comment("declare and define generated quantities",2,o);
2712  generate_local_var_decls(prog.generated_decl_.first,2,o,is_var);
2713  o << EOL;
2714  generate_statements(prog.generated_decl_.second,2,o,include_sampling,is_var);
2715  o << EOL;
2716 
2717  generate_comment("validate generated quantities",2,o);
2719  o << EOL;
2720 
2721  generate_comment("write generated quantities",2,o);
2722  for (size_t i = 0; i < prog.generated_decl_.first.size(); ++i)
2723  boost::apply_visitor(vis_writer, prog.generated_decl_.first[i].decl_);
2724  if (prog.generated_decl_.first.size() > 0)
2725  o << EOL;
2726 
2727  o << INDENT2 << "writer__.newline();" << EOL;
2728  o << INDENT << "}" << EOL2;
2729  }
2730 
2731 
2732  // see init_member_var_visgen for cut & paste
2733  struct write_array_visgen : public visgen {
2734  write_array_visgen(std::ostream& o)
2735  : visgen(o) {
2736  }
2737  void operator()(const nil& /*x*/) const { }
2738  void operator()(const int_var_decl& x) const {
2739  generate_initialize_array("int","integer",EMPTY_EXP_VECTOR,
2740  x.name_,x.dims_);
2741  }
2742  // fixme -- reuse cut-and-pasted from other lub reader case
2743  template <typename D>
2744  void generate_initialize_array_bounded(const D& x, const std::string& base_type,
2745  const std::string& read_fun_prefix,
2746  const std::vector<expression>& dim_args) const {
2747  std::vector<expression> read_args;
2748  std::string read_fun(read_fun_prefix);
2749  if (has_lub(x)) {
2750  read_fun += "_lub";
2751  read_args.push_back(x.range_.low_);
2752  read_args.push_back(x.range_.high_);
2753  } else if (has_lb(x)) {
2754  read_fun += "_lb";
2755  read_args.push_back(x.range_.low_);
2756  } else if (has_ub(x)) {
2757  read_fun += "_ub";
2758  read_args.push_back(x.range_.high_);
2759  }
2760  for (size_t i = 0; i < dim_args.size(); ++i)
2761  read_args.push_back(dim_args[i]);
2762  generate_initialize_array(base_type,read_fun,read_args,x.name_,x.dims_);
2763  }
2764 
2765  void operator()(const double_var_decl& x) const {
2766  std::vector<expression> read_args;
2767  generate_initialize_array_bounded(x,"double","scalar",read_args);
2768  }
2769  void operator()(const vector_var_decl& x) const {
2770  std::vector<expression> read_args;
2771  read_args.push_back(x.M_);
2772  generate_initialize_array_bounded(x,"vector_d","vector",read_args);
2773  }
2774  void operator()(const row_vector_var_decl& x) const {
2775  std::vector<expression> read_args;
2776  read_args.push_back(x.N_);
2777  generate_initialize_array_bounded(x,"row_vector_d","row_vector",read_args);
2778  }
2779  void operator()(const matrix_var_decl& x) const {
2780  std::vector<expression> read_args;
2781  read_args.push_back(x.M_);
2782  read_args.push_back(x.N_);
2783  generate_initialize_array_bounded(x,"matrix_d","matrix",read_args);
2784  }
2785  void operator()(const unit_vector_var_decl& x) const {
2786  std::vector<expression> read_args;
2787  read_args.push_back(x.K_);
2788  generate_initialize_array("vector_d","unit_vector",read_args,x.name_,x.dims_);
2789  }
2790  void operator()(const simplex_var_decl& x) const {
2791  std::vector<expression> read_args;
2792  read_args.push_back(x.K_);
2793  generate_initialize_array("vector_d","simplex",read_args,x.name_,x.dims_);
2794  }
2795  void operator()(const ordered_var_decl& x) const {
2796  std::vector<expression> read_args;
2797  read_args.push_back(x.K_);
2798  generate_initialize_array("vector_d","ordered",read_args,x.name_,x.dims_);
2799  }
2800  void operator()(const positive_ordered_var_decl& x) const {
2801  std::vector<expression> read_args;
2802  read_args.push_back(x.K_);
2803  generate_initialize_array("vector_d","positive_ordered",read_args,x.name_,x.dims_);
2804  }
2805  void operator()(const cov_matrix_var_decl& x) const {
2806  std::vector<expression> read_args;
2807  read_args.push_back(x.K_);
2808  generate_initialize_array("matrix_d","cov_matrix",read_args,x.name_,x.dims_);
2809  }
2810  void operator()(const corr_matrix_var_decl& x) const {
2811  std::vector<expression> read_args;
2812  read_args.push_back(x.K_);
2813  generate_initialize_array("matrix_d","corr_matrix",read_args,x.name_,x.dims_);
2814  }
2815  void generate_initialize_array(const std::string& var_type,
2816  const std::string& read_type,
2817  const std::vector<expression>& read_args,
2818  const std::string& name,
2819  const std::vector<expression>& dims) const {
2820  if (dims.size() == 0) {
2821  generate_indent(2,o_);
2822  o_ << var_type << " ";
2823  o_ << name << " = in__." << read_type << "_constrain(";
2824  for (size_t j = 0; j < read_args.size(); ++j) {
2825  if (j > 0) o_ << ",";
2826  generate_expression(read_args[j],o_);
2827  }
2828  o_ << ");" << EOL;
2829  return;
2830  }
2831  o_ << INDENT2;
2832  for (size_t i = 0; i < dims.size(); ++i) o_ << "vector<";
2833  o_ << var_type;
2834  for (size_t i = 0; i < dims.size(); ++i) o_ << "> ";
2835  o_ << name << ";" << EOL;
2836  std::string name_dims(name);
2837  for (size_t i = 0; i < dims.size(); ++i) {
2838  generate_indent(i + 2, o_);
2839  o_ << "size_t dim_" << name << "_" << i << "__ = ";
2840  generate_expression(dims[i],o_);
2841  o_ << ";" << EOL;
2842  if (i < dims.size() - 1) {
2843  generate_indent(i + 2, o_);
2844  o_ << name_dims << ".resize(dim_" << name << "_" << i << "__);"
2845  << EOL;
2846  name_dims.append("[k_").append(to_string(i)).append("__]");
2847  }
2848  generate_indent(i + 2, o_);
2849  o_ << "for (size_t k_" << i << "__ = 0;"
2850  << " k_" << i << "__ < dim_" << name << "_" << i << "__;"
2851  << " ++k_" << i << "__) {" << EOL;
2852  if (i == dims.size() - 1) {
2853  generate_indent(i + 3, o_);
2854  o_ << name_dims << ".push_back(in__." << read_type << "_constrain(";
2855  for (size_t j = 0; j < read_args.size(); ++j) {
2856  if (j > 0) o_ << ",";
2857  generate_expression(read_args[j],o_);
2858  }
2859  o_ << "));" << EOL;
2860  }
2861  }
2862 
2863  for (size_t i = dims.size(); i > 0; --i) {
2864  generate_indent(i + 1, o_);
2865  o_ << "}" << EOL;
2866  }
2867 
2868 
2869  }
2870  };
2871 
2872 
2873 
2874 
2876  write_array_vars_visgen(std::ostream& o)
2877  : visgen(o) {
2878  }
2879  void operator()(const nil& /*x*/) const { }
2880  // FIXME: template these out
2881  void operator()(const int_var_decl& x) const {
2882  write_array(x.name_,x.dims_,EMPTY_EXP_VECTOR);
2883  }
2884  void operator()(const double_var_decl& x) const {
2885  write_array(x.name_,x.dims_,EMPTY_EXP_VECTOR);
2886  }
2887  void operator()(const vector_var_decl& x) const {
2888  std::vector<expression> dims(x.dims_);
2889  dims.push_back(x.M_);
2890  write_array(x.name_,dims, EMPTY_EXP_VECTOR);
2891  }
2892  void operator()(const row_vector_var_decl& x) const {
2893  std::vector<expression> dims(x.dims_);
2894  dims.push_back(x.N_);
2895  write_array(x.name_,dims, EMPTY_EXP_VECTOR);
2896  }
2897  void operator()(const matrix_var_decl& x) const {
2898  std::vector<expression> matdims;
2899  matdims.push_back(x.M_);
2900  matdims.push_back(x.N_);
2901  write_array(x.name_,x.dims_,matdims);
2902  }
2903  void operator()(const unit_vector_var_decl& x) const {
2904  std::vector<expression> dims(x.dims_);
2905  dims.push_back(x.K_);
2906  write_array(x.name_,dims,EMPTY_EXP_VECTOR);
2907  }
2908  void operator()(const simplex_var_decl& x) const {
2909  std::vector<expression> dims(x.dims_);
2910  dims.push_back(x.K_);
2911  write_array(x.name_,dims,EMPTY_EXP_VECTOR);
2912  }
2913  void operator()(const ordered_var_decl& x) const {
2914  std::vector<expression> dims(x.dims_);
2915  dims.push_back(x.K_);
2916  write_array(x.name_,dims,EMPTY_EXP_VECTOR);
2917  }
2918  void operator()(const positive_ordered_var_decl& x) const {
2919  std::vector<expression> dims(x.dims_);
2920  dims.push_back(x.K_);
2921  write_array(x.name_,dims,EMPTY_EXP_VECTOR);
2922  }
2923  void operator()(const cov_matrix_var_decl& x) const {
2924  std::vector<expression> matdims;
2925  matdims.push_back(x.K_);
2926  matdims.push_back(x.K_);
2927  write_array(x.name_,x.dims_,matdims);
2928  }
2929  void operator()(const corr_matrix_var_decl& x) const {
2930  std::vector<expression> matdims;
2931  matdims.push_back(x.K_);
2932  matdims.push_back(x.K_);
2933  write_array(x.name_,x.dims_,matdims);
2934  }
2935  void write_array(const std::string& name,
2936  const std::vector<expression>& arraydims,
2937  const std::vector<expression>& matdims) const {
2938 
2939  std::vector<expression> dims(arraydims);
2940  for (size_t i = 0; i < matdims.size(); ++i)
2941  dims.push_back(matdims[i]);
2942 
2943  if (dims.size() == 0) {
2944  o_ << INDENT2 << "vars__.push_back(" << name << ");" << EOL;
2945  return;
2946  }
2947 
2948  // for (size_t i = 0; i < dims.size(); ++i) {
2949  for (size_t i = dims.size(); i > 0; ) {
2950  --i;
2951  generate_indent((dims.size() - i) + 1, o_);
2952  o_ << "for (int k_" << i << "__ = 0;"
2953  << " k_" << i << "__ < ";
2954  generate_expression(dims[i],o_);
2955  o_ << "; ++k_" << i << "__) {" << EOL;
2956  }
2957 
2958  generate_indent(dims.size() + 2, o_);
2959  o_ << "vars__.push_back(" << name;
2960  if (arraydims.size() > 0) {
2961  o_ << '[';
2962  for (size_t i = 0; i < arraydims.size(); ++i) {
2963  if (i > 0) o_ << "][";
2964  o_ << "k_" << i << "__";
2965  }
2966  o_ << ']';
2967  }
2968  if (matdims.size() > 0) {
2969  o_ << "(k_" << arraydims.size() << "__";
2970  if (matdims.size() > 1)
2971  o_ << ", k_" << (arraydims.size() + 1) << "__";
2972  o_ << ")";
2973  }
2974  o_ << ");" << EOL;
2975 
2976  for (size_t i = dims.size(); i > 0; --i) {
2977  generate_indent(i + 1, o_);
2978  o_ << "}" << EOL;
2979  }
2980  }
2981  };
2982 
2983 
2985  const std::string& model_name,
2986  std::ostream& o) {
2987  o << INDENT << "template <typename RNG>" << EOL;
2988  o << INDENT << "void write_array(RNG& base_rng__," << EOL;
2989  o << INDENT << " std::vector<double>& params_r__," << EOL;
2990  o << INDENT << " std::vector<int>& params_i__," << EOL;
2991  o << INDENT << " std::vector<double>& vars__," << EOL;
2992  o << INDENT << " std::ostream* pstream__ = 0) {" << EOL;
2993  o << INDENT2 << "vars__.resize(0);" << EOL;
2994  o << INDENT2 << "stan::io::reader<double> in__(params_r__,params_i__);" << EOL;
2995  o << INDENT2 << "static const char* function__ = \""
2996  << model_name << "_namespace::write_array(%1%)\";" << EOL;
2997  suppress_warning(INDENT2, "function__", o);
2998 
2999  // declares, reads, and sets parameters
3000  generate_comment("read-transform, write parameters",2,o);
3001  write_array_visgen vis(o);
3002  for (size_t i = 0; i < prog.parameter_decl_.size(); ++i)
3003  boost::apply_visitor(vis,prog.parameter_decl_[i].decl_);
3004 
3005  // this is for all other values
3006  write_array_vars_visgen vis_writer(o);
3007 
3008  // writes parameters
3009  for (size_t i = 0; i < prog.parameter_decl_.size(); ++i)
3010  boost::apply_visitor(vis_writer,prog.parameter_decl_[i].decl_);
3011 
3012 
3013  o << EOL;
3014  generate_comment("declare and define transformed parameters",2,o);
3015  o << INDENT2 << "double lp__ = 0.0;" << EOL;
3016  suppress_warning(INDENT2, "lp__", o);
3017  bool is_var = false;
3018  generate_local_var_decls(prog.derived_decl_.first,2,o,is_var);
3019  o << EOL;
3020  bool include_sampling = false;
3021  generate_statements(prog.derived_decl_.second,2,o,include_sampling,is_var);
3022  o << EOL;
3023 
3024  generate_comment("validate transformed parameters",2,o);
3026  o << EOL;
3027 
3028  generate_comment("write transformed parameters",2,o);
3029  for (size_t i = 0; i < prog.derived_decl_.first.size(); ++i)
3030  boost::apply_visitor(vis_writer, prog.derived_decl_.first[i].decl_);
3031  o << EOL;
3032 
3033  generate_comment("declare and define generated quantities",2,o);
3034  generate_local_var_decls(prog.generated_decl_.first,2,o,is_var);
3035  o << EOL;
3036  generate_statements(prog.generated_decl_.second,2,o,include_sampling,is_var);
3037  o << EOL;
3038 
3039  generate_comment("validate generated quantities",2,o);
3041  o << EOL;
3042 
3043  generate_comment("write generated quantities",2,o);
3044  for (size_t i = 0; i < prog.generated_decl_.first.size(); ++i)
3045  boost::apply_visitor(vis_writer, prog.generated_decl_.first[i].decl_);
3046  if (prog.generated_decl_.first.size() > 0)
3047  o << EOL;
3048 
3049  o << INDENT << "}" << EOL2;
3050  }
3051 
3052 
3053  // know all data is set and range expressions only depend on data
3055  set_param_ranges_visgen(std::ostream& o)
3056  : visgen(o) {
3057  }
3058  void operator()(const nil& /*x*/) const { }
3059  void operator()(const int_var_decl& x) const {
3060  generate_increment_i(x.dims_);
3061  // for loop for ranges
3062  for (size_t i = 0; i < x.dims_.size(); ++i) {
3063  generate_indent(i + 2, o_);
3064  o_ << "for (size_t i_" << i << "__ = 0; ";
3065  o_ << "i_" << i << "__ < ";
3066  generate_expression(x.dims_[i],o_);
3067  o_ << "; ++i_" << i << "__) {" << EOL;
3068  }
3069  // add range
3070  generate_indent(x.dims_.size() + 2,o_);
3071  o_ << "param_ranges_i__.push_back(std::pair<int,int>(";
3073  o_ << ", ";
3075  o_ << "));" << EOL;
3076  // close for loop
3077  for (size_t i = 0; i < x.dims_.size(); ++i) {
3078  generate_indent(x.dims_.size() + 1 - i, o_);
3079  o_ << "}" << EOL;
3080  }
3081  }
3082  void operator()(const double_var_decl& x) const {
3083  generate_increment(x.dims_);
3084  }
3085  void operator()(const vector_var_decl& x) const {
3086  generate_increment(x.M_,x.dims_);
3087  }
3088  void operator()(const row_vector_var_decl& x) const {
3089  generate_increment(x.N_,x.dims_);
3090  }
3091  void operator()(const matrix_var_decl& x) const {
3092  generate_increment(x.M_,x.N_,x.dims_);
3093  }
3094  void operator()(const unit_vector_var_decl& x) const {
3095  // only K-1 vals
3096  o_ << INDENT2 << "num_params_r__ += (";
3097  generate_expression(x.K_,o_);
3098  o_ << " - 1)";
3099  for (size_t i = 0; i < x.dims_.size(); ++i) {
3100  o_ << " * ";
3101  generate_expression(x.dims_[i],o_);
3102  }
3103  o_ << ";" << EOL;
3104  }
3105  void operator()(const simplex_var_decl& x) const {
3106  // only K-1 vals
3107  o_ << INDENT2 << "num_params_r__ += (";
3108  generate_expression(x.K_,o_);
3109  o_ << " - 1)";
3110  for (size_t i = 0; i < x.dims_.size(); ++i) {
3111  o_ << " * ";
3112  generate_expression(x.dims_[i],o_);
3113  }
3114  o_ << ";" << EOL;
3115  }
3116  void operator()(const ordered_var_decl& x) const {
3117  generate_increment(x.K_,x.dims_);
3118  }
3119  void operator()(const positive_ordered_var_decl& x) const {
3120  generate_increment(x.K_,x.dims_);
3121  }
3122  void operator()(const cov_matrix_var_decl& x) const {
3123  // (K * (K - 1))/2 + K ?? define fun(K) = ??
3124  o_ << INDENT2 << "num_params_r__ += ((";
3125  generate_expression(x.K_,o_);
3126  o_ << " * (";
3127  generate_expression(x.K_,o_);
3128  o_ << " - 1)) / 2 + ";
3129  generate_expression(x.K_,o_);
3130  o_ << ")";
3131  for (size_t i = 0; i < x.dims_.size(); ++i) {
3132  o_ << " * ";
3133  generate_expression(x.dims_[i],o_);
3134  }
3135  o_ << ";" << EOL;
3136  }
3137  void operator()(const corr_matrix_var_decl& x) const {
3138  o_ << INDENT2 << "num_params_r__ += ((";
3139  generate_expression(x.K_,o_);
3140  o_ << " * (";
3141  generate_expression(x.K_,o_);
3142  o_ << " - 1)) / 2)";
3143  for (size_t i = 0; i < x.dims_.size(); ++i) {
3144  o_ << " * ";
3145  generate_expression(x.dims_[i],o_);
3146  }
3147  o_ << ";" << EOL;
3148  }
3149  // cut-and-paste from next for r
3150  void generate_increment_i(std::vector<expression> dims) const {
3151  if (dims.size() == 0) {
3152  o_ << INDENT2 << "++num_params_i__;" << EOL;
3153  return;
3154  }
3155  o_ << INDENT2 << "num_params_r__ += ";
3156  for (size_t i = 0; i < dims.size(); ++i) {
3157  if (i > 0) o_ << " * ";
3158  generate_expression(dims[i],o_);
3159  }
3160  o_ << ";" << EOL;
3161  }
3162  void generate_increment(std::vector<expression> dims) const {
3163  if (dims.size() == 0) {
3164  o_ << INDENT2 << "++num_params_r__;" << EOL;
3165  return;
3166  }
3167  o_ << INDENT2 << "num_params_r__ += ";
3168  for (size_t i = 0; i < dims.size(); ++i) {
3169  if (i > 0) o_ << " * ";
3170  generate_expression(dims[i],o_);
3171  }
3172  o_ << ";" << EOL;
3173  }
3174  void generate_increment(expression K,
3175  std::vector<expression> dims) const {
3176  o_ << INDENT2 << "num_params_r__ += ";
3177  generate_expression(K,o_);
3178  for (size_t i = 0; i < dims.size(); ++i) {
3179  o_ << " * ";
3180  generate_expression(dims[i],o_);
3181  }
3182  o_ << ";" << EOL;
3183 
3184  }
3185  void generate_increment(expression M, expression N,
3186  std::vector<expression> dims) const {
3187  o_ << INDENT2 << "num_params_r__ += ";
3188  generate_expression(M,o_);
3189  o_ << " * ";
3190  generate_expression(N,o_);
3191  for (size_t i = 0; i < dims.size(); ++i) {
3192  o_ << " * ";
3193  generate_expression(dims[i],o_);
3194  }
3195  o_ << ";" << EOL;
3196  }
3197  };
3198 
3199  void generate_set_param_ranges(const std::vector<var_decl>& var_decls,
3200  std::ostream& o) {
3201  o << EOL;
3202  o << INDENT << "void set_param_ranges() {" << EOL;
3203  o << INDENT2 << "num_params_r__ = 0U;" << EOL;
3204  o << INDENT2 << "param_ranges_i__.clear();" << EOL;
3205  set_param_ranges_visgen vis(o);
3206  for (size_t i = 0; i < var_decls.size(); ++i)
3207  boost::apply_visitor(vis,var_decls[i].decl_);
3208  o << INDENT << "}" << EOL;
3209  }
3210 
3211  void generate_main(const std::string& model_name,
3212  std::ostream& out) {
3213  out << "int main(int argc, const char* argv[]) {" << EOL;
3214  out << INDENT << "try {" << EOL;
3215  out << INDENT2 << "stan::gm::nuts_command<" << model_name
3216  << "_namespace::" << model_name << ">(argc,argv);" << EOL;
3217  out << INDENT << "} catch (std::exception& e) {" << EOL;
3218  out << INDENT2
3219  << "std::cerr << std::endl << \"Exception: \" << e.what() << std::endl;"
3220  << EOL;
3221  out << INDENT2
3222  << "std::cerr << \"Diagnostic information: \" << std::endl << boost::diagnostic_information(e) << std::endl;"
3223  << EOL;
3224  out << INDENT2 << "return -1;" << EOL;
3225  out << INDENT << "}" << EOL;
3226 
3227  out << "}" << EOL2;
3228  }
3229 
3230  void generate_cpp(const program& prog,
3231  const std::string& model_name,
3232  std::ostream& out,
3233  bool include_main = true) {
3235  generate_includes(out);
3236  generate_start_namespace(model_name,out);
3237  generate_usings(out);
3238  generate_typedefs(out);
3239  generate_class_decl(model_name,out);
3240  generate_private_decl(out);
3243  generate_public_decl(out);
3244  generate_constructor(prog,model_name,out);
3247  generate_log_prob(prog,out);
3248  generate_param_names_method(prog,out);
3249  generate_dims_method(prog,out);
3250  generate_write_array_method(prog,model_name,out);
3252  generate_write_csv_method(prog,model_name,out);
3255  if (include_main)
3256  generate_main(model_name,out);
3257  }
3258 
3259  }
3260 
3261 }
3262 
3263 #endif

     [ Stan Home Page ] © 2011–2013, Stan Development Team.