Stan  2.5.0
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations 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 <iostream>
9 #include <ostream>
10 #include <sstream>
11 #include <stdexcept>
12 #include <string>
13 #include <vector>
14 
15 #include <stan/version.hpp>
16 #include <stan/gm/ast.hpp>
17 
18 namespace stan {
19 
20  namespace gm {
21 
22  void generate_expression(const expression& e, std::ostream& o);
23 
24  const std::string EOL("\n");
25  const std::string EOL2("\n\n");
26  const std::string INDENT(" ");
27  const std::string INDENT2(" ");
28  const std::string INDENT3(" ");
29 
30  template <typename D>
31  bool has_lub(const D& x) {
32  return !is_nil(x.range_.low_.expr_) && !is_nil(x.range_.high_.expr_);
33  }
34  template <typename D>
35  bool has_ub(const D& x) {
36  return is_nil(x.range_.low_.expr_) && !is_nil(x.range_.high_.expr_);
37  }
38  template <typename D>
39  bool has_lb(const D& x) {
40  return !is_nil(x.range_.low_.expr_) && is_nil(x.range_.high_.expr_);
41  }
42 
43  template <typename T>
44  std::string to_string(T i) {
45  std::stringstream ss;
46  ss << i;
47  return ss.str();
48  }
49 
50  void generate_indent(size_t indent, std::ostream& o) {
51  for (size_t k = 0; k < indent; ++k)
52  o << INDENT;
53  }
54 
55  void generate_void_statement(const std::string& name,
56  const size_t indent,
57  std::ostream& o) {
58  generate_indent(indent, o);
59  o << "(void) " << name << "; // dummy to suppress unused var warning";
60  o << EOL;
61  }
62 
64  struct visgen {
65  typedef void result_type;
66  std::ostream& o_;
67  visgen(std::ostream& o) : o_(o) { }
68  };
69 
70  void generate_start_namespace(std::string name,
71  std::ostream& o) {
72  o << "namespace " << name << "_namespace {" << EOL2;
73  }
74 
75  void generate_end_namespace(std::ostream& o) {
76  o << "} // namespace" << EOL2;
77  }
78 
79  void generate_comment(std::string const& msg, int indent,
80  std::ostream& o) {
81  generate_indent(indent,o);
82  o << "// " << msg << EOL;
83  }
84 
85 
86  template <bool isLHS>
87  void generate_indexed_expr(const std::string& expr,
88  const std::vector<expression> indexes,
89  base_expr_type base_type, // may have more dims
90  size_t e_num_dims, // array dims
91  std::ostream& o) {
92  // FIXME: add more get_base1 functions and fold nested calls into API
93  // up to a given size, then default to this behavior
94  size_t ai_size = indexes.size();
95  if (ai_size == 0) {
96  // no indexes
97  o << expr;
98  return;
99  }
100  if (ai_size <= (e_num_dims + 1) || base_type != MATRIX_T) {
101  for (size_t n = 0; n < ai_size; ++n)
102  o << (isLHS ? "get_base1_lhs(" : "get_base1(");
103  o << expr;
104  for (size_t n = 0; n < ai_size; ++n) {
105  o << ',';
106  generate_expression(indexes[n],o);
107  o << ',' << '"' << expr << '"' << ',' << (n+1) << ')';
108  }
109  } else {
110  for (size_t n = 0; n < ai_size - 1; ++n)
111  o << (isLHS ? "get_base1_lhs(" : "get_base1(");
112  o << expr;
113  for (size_t n = 0; n < ai_size - 2; ++n) {
114  o << ',';
115  generate_expression(indexes[n],o);
116  o << ',' << '"' << expr << '"' << ',' << (n+1) << ')';
117  }
118  o << ',';
119  generate_expression(indexes[ai_size - 2U],o);
120  o << ',';
121  generate_expression(indexes[ai_size - 1U],o);
122  o << ',' << '"' << expr << '"' << ',' << (ai_size-1U) << ')';
123  }
124  }
125 
126  void generate_type(const std::string& base_type,
127  const std::vector<expression>& /*dims*/,
128  size_t end,
129  std::ostream& o) {
130  for (size_t i = 0; i < end; ++i) o << "std::vector<";
131  o << base_type;
132  for (size_t i = 0; i < end; ++i) {
133  if (i > 0) o << ' ';
134  o << '>';
135  }
136  }
137 
138  struct expression_visgen : public visgen {
139  expression_visgen(std::ostream& o) : visgen(o) { }
140  void operator()(nil const& /*x*/) const {
141  o_ << "nil";
142  }
143  void operator()(const int_literal& n) const { o_ << n.val_; }
144  void operator()(const double_literal& x) const {
145  std::string num_str = boost::lexical_cast<std::string>(x.val_);
146  o_ << num_str;
147  if (num_str.find_first_of("eE.") == std::string::npos)
148  o_ << ".0"; // trailing 0 to ensure C++ makes it a double
149  }
150  void operator()(const array_literal& x) const {
151  o_ << "stan::math::new_array<";
152  generate_type("foobar",
153  x.args_,
154  x.args_.size(),
155  o_);
156  o_ << ">()";
157  for (size_t i = 0; i < x.args_.size(); ++i) {
158  o_ << ".add(";
159  generate_expression(x.args_[i],o_);
160  o_ << ")";
161  }
162  o_ << ".array()";
163  }
164  void operator()(const variable& v) const { o_ << v.name_; }
165  void operator()(int n) const { o_ << static_cast<long>(n); }
166  void operator()(double x) const { o_ << x; }
167  void operator()(const std::string& x) const { o_ << x; } // identifiers
168  void operator()(const index_op& x) const {
169  std::stringstream expr_o;
170  generate_expression(x.expr_,expr_o);
171  std::string expr_string = expr_o.str();
172  std::vector<expression> indexes;
173  size_t e_num_dims = x.expr_.expression_type().num_dims_;
174  base_expr_type base_type = x.expr_.expression_type().base_type_;
175  for (size_t i = 0; i < x.dimss_.size(); ++i)
176  for (size_t j = 0; j < x.dimss_[i].size(); ++j)
177  indexes.push_back(x.dimss_[i][j]); // wasteful copy, could use refs
178  generate_indexed_expr<false>(expr_string,indexes,base_type,e_num_dims,o_);
179  }
180  void operator()(const integrate_ode& fx) const {
181  o_ << "integrate_ode("
182  << fx.system_function_name_
183  << "_functor__(), ";
184 
185  generate_expression(fx.y0_, o_);
186  o_ << ", ";
187 
188  generate_expression(fx.t0_, o_);
189  o_ << ", ";
190 
191  generate_expression(fx.ts_, o_);
192  o_ << ", ";
193 
194  generate_expression(fx.theta_, o_);
195  o_ << ", ";
196 
197  generate_expression(fx.x_, o_);
198  o_ << ", ";
199 
200  generate_expression(fx.x_int_, o_);
201  o_ << ", pstream__)";
202  }
203  void operator()(const fun& fx) const {
204  // first test if short-circuit op (binary && and || applied to
205  // primitives; overloads are eager, not short-circuiting)
206  if (fx.name_ == "logical_or" || fx.name_ == "logical_and") {
207  o_ << "(primitive_value(";
208  boost::apply_visitor(*this, fx.args_[0].expr_);
209  o_ << ") " << ((fx.name_ == "logical_or") ? "||" : "&&") << " primitive_value(";
210  boost::apply_visitor(*this, fx.args_[1].expr_);
211  o_ << "))";
212  return;
213  }
214  o_ << fx.name_ << '(';
215  for (size_t i = 0; i < fx.args_.size(); ++i) {
216  if (i > 0) o_ << ',';
217  boost::apply_visitor(*this, fx.args_[i].expr_);
218  }
219  if (fx.args_.size() > 0
220  && (has_rng_suffix(fx.name_) || has_lp_suffix(fx.name_)))
221  o_ << ", ";
222  if (has_rng_suffix(fx.name_))
223  o_ << "base_rng__";
224  if (has_lp_suffix(fx.name_))
225  o_ << "lp__, lp_accum__";
226  if (is_user_defined(fx)) {
227  if (fx.args_.size() > 0
228  || has_rng_suffix(fx.name_)
229  || has_lp_suffix(fx.name_))
230  o_ << ", ";
231  o_ << "pstream__";
232  }
233  o_ << ')';
234  }
235  void operator()(const binary_op& expr) const {
236  o_ << '(';
237  boost::apply_visitor(*this, expr.left.expr_);
238  o_ << ' ' << expr.op << ' ';
239  boost::apply_visitor(*this, expr.right.expr_);
240  o_ << ')';
241  }
242  void operator()(const unary_op& expr) const {
243  o_ << expr.op << '(';
244  boost::apply_visitor(*this, expr.subject.expr_);
245  o_ << ')';
246  }
247  };
248 
249  void generate_expression(const expression& e, std::ostream& o) {
250  expression_visgen vis(o);
251  boost::apply_visitor(vis, e.expr_);
252  }
253 
254  static void print_string_literal(std::ostream& o,
255  const std::string& s) {
256  o << '"';
257  for (size_t i = 0; i < s.size(); ++i) {
258  if (s[i] == '"' || s[i] == '\\' || s[i] == '\'' )
259  o << '\\'; // escape
260  o << s[i];
261  }
262  o << '"';
263  }
264 
265  static void print_quoted_expression(std::ostream& o,
266  const expression& e) {
267  std::stringstream ss;
268  generate_expression(e,ss);
269  print_string_literal(o,ss.str());
270  }
271 
272  struct printable_visgen : public visgen {
273  printable_visgen(std::ostream& o) : visgen(o) { }
274  void operator()(const std::string& s) const {
276  }
277  void operator()(const expression& e) const {
279  // print_quoted_expression(o_,e);
280  }
281  };
282 
283  void generate_printable(const printable& p, std::ostream& o) {
284  printable_visgen vis(o);
285  boost::apply_visitor(vis, p.printable_);
286  }
287 
288  void generate_using(const std::string& type, std::ostream& o) {
289  o << "using " << type << ";" << EOL;
290  }
291 
292  void generate_using_namespace(const std::string& ns, std::ostream& o) {
293  o << "using namespace " << ns << ";" << EOL;
294  }
295 
296 
297  void generate_usings(std::ostream& o) {
298  generate_using("std::istream",o);
299  generate_using("std::string",o);
300  generate_using("std::stringstream",o);
301  generate_using("std::vector",o);
302  generate_using("stan::io::dump",o);
303  generate_using("stan::math::lgamma",o);
304  generate_using("stan::model::prob_grad",o);
305  generate_using_namespace("stan::math",o);
306  generate_using_namespace("stan::prob",o);
307  o << EOL;
308  }
309 
310  void generate_typedef(const std::string& type,
311  const std::string& abbrev,
312  std::ostream& o) {
313  o << "typedef" << " " << type << " " << abbrev << ";" << EOL;
314  }
315 
316  void generate_typedefs(std::ostream& o) {
317  generate_typedef("Eigen::Matrix<double,Eigen::Dynamic,1>","vector_d",o);
318  generate_typedef("Eigen::Matrix<double,1,Eigen::Dynamic>","row_vector_d",o);
319  generate_typedef("Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>","matrix_d",o);
320  o << EOL;
321  }
322 
323  void generate_include(const std::string& lib_name, std::ostream& o) {
324  o << "#include" << " " << "<" << lib_name << ">" << EOL;
325  }
326 
327  void generate_includes(std::ostream& o) {
328  generate_include("stan/model/model_header.hpp",o);
329  generate_include("stan/common/command.hpp",o);
330  // generate_include("boost/random/linear_congruential.hpp",o);
331  o << EOL;
332  }
333 
334  void generate_version_comment(std::ostream& o) {
335  o << "// Code generated by Stan version "
337  }
338 
339  void generate_class_decl(const std::string& model_name,
340  std::ostream& o) {
341  o << "class " << model_name << " : public prob_grad {" << EOL;
342  }
343 
344  void generate_end_class_decl(std::ostream& o) {
345  o << "}; // model" << EOL2;
346  }
347 
348  void generate_initializer(std::ostream& o,
349  const std::string& base_type,
350  const std::vector<expression>& dims,
351  const expression& type_arg1 = expression(),
352  const expression& type_arg2 = expression()) {
353  for (size_t i = 0; i < dims.size(); ++i) {
354  o << '(';
355  generate_expression(dims[i].expr_,o);
356  o << ',';
357  generate_type(base_type,dims,dims.size()- i - 1,o);
358  }
359 
360  o << '(';
361  if (!is_nil(type_arg1)) {
362  generate_expression(type_arg1.expr_,o);
363  if (!is_nil(type_arg2)) {
364  o << ',';
365  generate_expression(type_arg2.expr_,o);
366  }
367  } else if (!is_nil(type_arg2.expr_)) {
368  generate_expression(type_arg2.expr_,o);
369  } else {
370  o << '0';
371  }
372  o << ')';
373 
374  for (size_t i = 0; i < dims.size(); ++i)
375  o << ')';
376  o << ';' << EOL;
377  }
378 
379  // only generates the test
380  void generate_validate_context_size(std::ostream& o,
381  const std::string& stage,
382  const std::string& var_name,
383  const std::string& base_type,
384  const std::vector<expression>& dims,
385  const expression& type_arg1 = expression(),
386  const expression& type_arg2 = expression()) {
387  o << INDENT2
388  << "context__.validate_dims("
389  << '"' << stage << '"'
390  << ", " << '"' << var_name << '"'
391  << ", " << '"' << base_type << '"'
392  << ", context__.to_vec(";
393  for (size_t i = 0; i < dims.size(); ++i) {
394  if (i > 0) o << ",";
395  generate_expression(dims[i].expr_,o);
396  }
397  if (!is_nil(type_arg1)) {
398  if (dims.size() > 0) o << ",";
399  generate_expression(type_arg1.expr_,o);
400  if (!is_nil(type_arg2)) {
401  o << ",";
402  generate_expression(type_arg2.expr_,o);
403  }
404  }
405  o << "));"
406  << EOL;
407  }
408 
410  const std::string stage_;
411  var_size_validating_visgen(std::ostream& o, const std::string& stage)
412  : visgen(o),
413  stage_(stage) {
414  }
415  void operator()(nil const& /*x*/) const { } // dummy
416  void operator()(int_var_decl const& x) const {
418  }
419  void operator()(double_var_decl const& x) const {
421  }
422  void operator()(vector_var_decl const& x) const {
424  }
425  void operator()(row_vector_var_decl const& x) const {
426  generate_validate_context_size(o_,stage_,x.name_,"row_vector_d",x.dims_,x.N_);
427  }
428  void operator()(unit_vector_var_decl const& x) const {
430  }
431  void operator()(simplex_var_decl const& x) const {
433  }
434  void operator()(ordered_var_decl const& x) const {
436  }
437  void operator()(positive_ordered_var_decl const& x) const {
439  }
440  void operator()(matrix_var_decl const& x) const {
442  }
443  void operator()(cholesky_factor_var_decl const& x) const {
445  }
446  void operator()(cholesky_corr_var_decl const& x) const {
448  }
449  void operator()(cov_matrix_var_decl const& x) const {
451  }
452  void operator()(corr_matrix_var_decl const& x) const {
454  }
455  };
456 
457 
458  void generate_validate_positive(const std::string& var_name,
459  const expression& expr,
460  std::ostream& o) {
461  o << INDENT2;
462  o << "stan::math::validate_non_negative_index(\"" << var_name << "\", ";
463  print_quoted_expression(o,expr);
464  o << ", ";
465  generate_expression(expr,o);
466  o << ");" << EOL;
467  }
468 
469  void generate_initialization(std::ostream& o,
470  const std::string& var_name,
471  const std::string& base_type,
472  const std::vector<expression>& dims,
473  const expression& type_arg1 = expression(),
474  const expression& type_arg2 = expression()) {
475  // validate all dims are positive
476  for (size_t i = 0; i < dims.size(); ++i)
477  generate_validate_positive(var_name,dims[i],o);
478  if (!is_nil(type_arg1))
479  generate_validate_positive(var_name,type_arg1,o);
480  if (!is_nil(type_arg2))
481  generate_validate_positive(var_name,type_arg2,o);
482 
483  // define variable with initializer
484  o << INDENT2
485  << var_name << " = ";
486  generate_type(base_type,dims,dims.size(),o);
487  generate_initializer(o,base_type,dims,type_arg1,type_arg2);
488 
489  }
490 
491  struct var_resizing_visgen : public visgen {
492  var_resizing_visgen(std::ostream& o)
493  : visgen(o) {
494  }
495  void operator()(nil const& /*x*/) const { } // dummy
496  void operator()(int_var_decl const& x) const {
498  }
499  void operator()(double_var_decl const& x) const {
500  generate_initialization(o_,x.name_,"double",x.dims_);
501  }
502  void operator()(vector_var_decl const& x) const {
503  generate_initialization(o_,x.name_,"vector_d",x.dims_,x.M_);
504  }
505  void operator()(row_vector_var_decl const& x) const {
506  generate_initialization(o_,x.name_,"row_vector_d",x.dims_,x.N_);
507  }
508  void operator()(unit_vector_var_decl const& x) const {
509  generate_initialization(o_,x.name_,"vector_d",x.dims_,x.K_);
510  }
511  void operator()(simplex_var_decl const& x) const {
512  generate_initialization(o_,x.name_,"vector_d",x.dims_,x.K_);
513  }
514  void operator()(ordered_var_decl const& x) const {
515  generate_initialization(o_,x.name_,"vector_d",x.dims_,x.K_);
516  }
517  void operator()(positive_ordered_var_decl const& x) const {
518  generate_initialization(o_,x.name_,"vector_d",x.dims_,x.K_);
519  }
520  void operator()(matrix_var_decl const& x) const {
521  generate_initialization(o_,x.name_,"matrix_d",x.dims_,x.M_,x.N_);
522  }
523  void operator()(cholesky_factor_var_decl const& x) const {
524  generate_initialization(o_,x.name_,"matrix_d",x.dims_,x.M_,x.N_);
525  }
526  void operator()(cholesky_corr_var_decl const& x) const {
527  generate_initialization(o_,x.name_,"matrix_d",x.dims_,x.K_,x.K_);
528  }
529  void operator()(cov_matrix_var_decl const& x) const {
530  generate_initialization(o_,x.name_,"matrix_d",x.dims_,x.K_,x.K_);
531  }
532  void operator()(corr_matrix_var_decl const& x) const {
533  generate_initialization(o_,x.name_,"matrix_d",x.dims_,x.K_,x.K_);
534  }
535  };
536 
537  void generate_var_resizing(const std::vector<var_decl>& vs,
538  std::ostream& o) {
539  var_resizing_visgen vis(o);
540  for (size_t i = 0; i < vs.size(); ++i)
541  boost::apply_visitor(vis, vs[i].decl_);
542  }
543 
544  const std::vector<expression> EMPTY_EXP_VECTOR(0);
545 
546  struct init_local_var_visgen : public visgen {
547  const bool declare_vars_;
548  const bool is_var_;
549  init_local_var_visgen(bool declare_vars,
550  bool is_var,
551  std::ostream& o)
552  : visgen(o),
553  declare_vars_(declare_vars),
554  is_var_(is_var) {
555  }
556  template <typename D>
557  void generate_initialize_array_bounded(const D& x, const std::string& base_type,
558  const std::string& read_fun_prefix,
559  const std::vector<expression>& dim_args) const {
560  std::vector<expression> read_args;
561  std::string read_fun(read_fun_prefix);
562  if (has_lub(x)) {
563  read_fun += "_lub";
564  read_args.push_back(x.range_.low_);
565  read_args.push_back(x.range_.high_);
566  } else if (has_lb(x)) {
567  read_fun += "_lb";
568  read_args.push_back(x.range_.low_);
569  } else if (has_ub(x)) {
570  read_fun += "_ub";
571  read_args.push_back(x.range_.high_);
572  }
573  for (size_t i = 0; i < dim_args.size(); ++i)
574  read_args.push_back(dim_args[i]);
575  generate_initialize_array(base_type,read_fun,read_args,x.name_,x.dims_);
576  }
577  void operator()(const nil& /*x*/) const { }
578  void operator()(const int_var_decl& x) const {
580  }
581  void operator()(const double_var_decl& x) const {
582  std::vector<expression> read_args;
583  generate_initialize_array_bounded(x,is_var_?"T__":"double","scalar",read_args);
584  }
585  void operator()(const vector_var_decl& x) const {
586  std::vector<expression> read_args;
587  read_args.push_back(x.M_);
588  generate_initialize_array_bounded(x,is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,1> ":"vector_d","vector",read_args);
589  }
590  void operator()(const row_vector_var_decl& x) const {
591  std::vector<expression> read_args;
592  read_args.push_back(x.N_);
593  generate_initialize_array_bounded(x,is_var_?"Eigen::Matrix<T__,1,Eigen::Dynamic> ":"row_vector_d","row_vector",read_args);
594  }
595  void operator()(const matrix_var_decl& x) const {
596  std::vector<expression> read_args;
597  read_args.push_back(x.M_);
598  read_args.push_back(x.N_);
599  generate_initialize_array_bounded(x,is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> ":"matrix_d","matrix",read_args);
600  }
601  void operator()(const unit_vector_var_decl& x) const {
602  std::vector<expression> read_args;
603  read_args.push_back(x.K_);
604  generate_initialize_array(is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,1> ":"vector_d","unit_vector",read_args,x.name_,x.dims_);
605  }
606  void operator()(const simplex_var_decl& x) const {
607  std::vector<expression> read_args;
608  read_args.push_back(x.K_);
609  generate_initialize_array(is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,1> ":"vector_d","simplex",read_args,x.name_,x.dims_);
610  }
611  void operator()(const ordered_var_decl& x) const {
612  std::vector<expression> read_args;
613  read_args.push_back(x.K_);
614  generate_initialize_array(is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,1> ":"vector_d","ordered",read_args,x.name_,x.dims_);
615  }
616  void operator()(const positive_ordered_var_decl& x) const {
617  std::vector<expression> read_args;
618  read_args.push_back(x.K_);
619  generate_initialize_array(is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,1> ":"vector_d","positive_ordered",read_args,x.name_,x.dims_);
620  }
621  void operator()(const cholesky_factor_var_decl& x) const {
622  std::vector<expression> read_args;
623  read_args.push_back(x.M_);
624  read_args.push_back(x.N_);
625  generate_initialize_array(is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> ":"matrix_d",
626  "cholesky_factor",read_args,x.name_,x.dims_);
627  }
628  void operator()(const cholesky_corr_var_decl& x) const {
629  std::vector<expression> read_args;
630  read_args.push_back(x.K_);
632  ? "Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> "
633  : "matrix_d",
634  "cholesky_corr",read_args,x.name_,x.dims_);
635  }
636 
637  void operator()(const cov_matrix_var_decl& x) const {
638  std::vector<expression> read_args;
639  read_args.push_back(x.K_);
640  generate_initialize_array(is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> ":"matrix_d",
641  "cov_matrix",read_args,x.name_,x.dims_);
642  }
643  void operator()(const corr_matrix_var_decl& x) const {
644  std::vector<expression> read_args;
645  read_args.push_back(x.K_);
646  generate_initialize_array(is_var_?"Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> ":"matrix_d",
647  "corr_matrix",read_args,x.name_,x.dims_);
648  }
649  void generate_initialize_array(const std::string& var_type,
650  const std::string& read_type,
651  const std::vector<expression>& read_args,
652  const std::string& name,
653  const std::vector<expression>& dims) const {
654  if (declare_vars_) {
655  o_ << INDENT2;
656  for (size_t i = 0; i < dims.size(); ++i) o_ << "vector<";
657  o_ << var_type;
658  for (size_t i = 0; i < dims.size(); ++i) o_ << "> ";
659  if (dims.size() == 0) o_ << " ";
660  o_ << name << ";" << EOL;
661  }
662 
663  if (dims.size() == 0) {
664  generate_void_statement(name, 2, o_);
665  o_ << INDENT2 << "if (jacobian__)" << EOL;
666 
667  // w Jacobian
668  generate_indent(3,o_);
669  o_ << name << " = in__." << read_type << "_constrain(";
670  for (size_t j = 0; j < read_args.size(); ++j) {
671  if (j > 0) o_ << ",";
672  generate_expression(read_args[j],o_);
673  }
674  if (read_args.size() > 0)
675  o_ << ",";
676  o_ << "lp__";
677  o_ << ");" << EOL;
678 
679  o_ << INDENT2 << "else" << EOL;
680 
681  // w/o Jacobian
682  generate_indent(3,o_);
683  o_ << name << " = in__." << read_type << "_constrain(";
684  for (size_t j = 0; j < read_args.size(); ++j) {
685  if (j > 0) o_ << ",";
686  generate_expression(read_args[j],o_);
687  }
688  o_ << ");" << EOL;
689 
690  } else {
691  // dims > 0
692  std::string name_dims(name);
693  for (size_t i = 0; i < dims.size(); ++i) {
694  generate_indent(i + 2, o_);
695  o_ << "size_t dim_" << name << "_" << i << "__ = ";
696  generate_expression(dims[i],o_);
697  o_ << ";" << EOL;
698 
699  if (i < dims.size() - 1) {
700  generate_indent(i + 2, o_);
701  o_ << name_dims << ".resize(dim" << "_" << name << "_" << i << "__);"
702  << EOL;
703  name_dims.append("[k_").append(to_string(i)).append("__]");
704  }
705 
706  generate_indent(i + 2, o_);
707  if (i == dims.size() - 1) {
708  o_ << name_dims << ".reserve(dim_" << name << "_" << i << "__);" << EOL;
709  generate_indent(i + 2, o_);
710  }
711 
712  o_ << "for (size_t k_" << i << "__ = 0;"
713  << " k_" << i << "__ < dim_" << name << "_" << i << "__;"
714  << " ++k_" << i << "__) {" << EOL;
715 
716  // if on the last loop, push read element into array
717  if (i == dims.size() - 1) {
718  generate_indent(i + 3, o_);
719  o_ << "if (jacobian__)" << EOL;
720 
721  // w Jacobian
722 
723  generate_indent(i + 4, o_);
724  o_ << name_dims << ".push_back(in__." << read_type << "_constrain(";
725  for (size_t j = 0; j < read_args.size(); ++j) {
726  if (j > 0) o_ << ",";
727  generate_expression(read_args[j],o_);
728  }
729  if (read_args.size() > 0)
730  o_ << ",";
731  o_ << "lp__";
732  o_ << "));" << EOL;
733 
734  generate_indent(i + 3, o_);
735  o_ << "else" << EOL;
736 
737  // w/o Jacobian
738 
739  generate_indent(i + 4, o_);
740  o_ << name_dims << ".push_back(in__." << read_type << "_constrain(";
741  for (size_t j = 0; j < read_args.size(); ++j) {
742  if (j > 0) o_ << ",";
743  generate_expression(read_args[j],o_);
744  }
745  o_ << "));" << EOL;
746  }
747  }
748 
749  for (size_t i = dims.size(); i > 0; --i) {
750  generate_indent(i + 1, o_);
751  o_ << "}" << EOL;
752  }
753  }
754  o_ << EOL;
755  }
756  };
757 
758  void generate_local_var_inits(std::vector<var_decl> vs,
759  bool is_var,
760  bool declare_vars,
761  std::ostream& o) {
762  o << INDENT2
763  << "stan::io::reader<"
764  << (is_var ? "T__" : "double")
765  << "> in__(params_r__,params_i__);" << EOL2;
766  init_local_var_visgen vis(declare_vars,is_var,o);
767  for (size_t i = 0; i < vs.size(); ++i)
768  boost::apply_visitor(vis, vs[i].decl_);
769  }
770 
771 
772 
773 
774  void generate_public_decl(std::ostream& o) {
775  o << "public:" << EOL;
776  }
777 
778  void generate_private_decl(std::ostream& o) {
779  o << "private:" << EOL;
780  }
781 
782 
784  int indents_;
786  std::ostream& o)
787  : visgen(o),
788  indents_(indents) {
789  }
790  void generate_begin_for_dims(const std::vector<expression>& dims)
791  const {
792 
793  for (size_t i = 0; i < dims.size(); ++i) {
795  o_ << "for (int k" << i << "__ = 0;"
796  << " k" << i << "__ < ";
797  generate_expression(dims[i].expr_,o_);
798  o_ << ";";
799  o_ << " ++k" << i << "__) {" << EOL;
800  }
801  }
802  void generate_end_for_dims(size_t dims_size) const {
803  for (size_t i = 0; i < dims_size; ++i) {
804  generate_indent(indents_ + dims_size - i - 1, o_);
805  o_ << "}" << EOL;
806  }
807  }
808 
809  void generate_loop_var(const std::string& name,
810  size_t dims_size) const {
811  o_ << name;
812  for (size_t i = 0; i < dims_size; ++i)
813  o_ << "[k" << i << "__]";
814  }
815  void operator()(nil const& /*x*/) const { }
816  template <typename T>
817  void basic_validate(T const& x) const {
818  if (!(x.range_.has_low() || x.range_.has_high()))
819  return; // unconstrained
820  generate_begin_for_dims(x.dims_);
821  generate_indent(indents_ + x.dims_.size(),o_);
822  o_ << "try { " << EOL;
823  if (x.range_.has_low()) {
824  generate_indent(indents_ + 1 + x.dims_.size(),o_);
825  o_ << "check_greater_or_equal(function__,";
826  generate_loop_var(x.name_,x.dims_.size());
827  o_ << ",";
828  generate_expression(x.range_.low_.expr_,o_);
829  o_ << ",\"";
830  generate_loop_var(x.name_,x.dims_.size());
831  o_ << "\", (double *)0);" << EOL;
832  }
833  if (x.range_.has_high()) {
834  generate_indent(indents_ + 1 + x.dims_.size(),o_);
835  o_ << "check_less_or_equal(function__,";
836  generate_loop_var(x.name_,x.dims_.size());
837  o_ << ",";
838  generate_expression(x.range_.high_.expr_,o_);
839  o_ << ",\"";
840  generate_loop_var(x.name_,x.dims_.size());
841  o_ << "\", (double *)0);" << EOL;
842  }
843  generate_indent(indents_ + x.dims_.size(),o_);
844  o_ << "} catch (const std::exception& e) { "
845  << EOL;
846  generate_indent(indents_ + x.dims_.size() + 1, o_);
847  o_ << "throw std::domain_error(std::string(\"Invalid value of " << x.name_ << ": \") + std::string(e.what()));"
848  << EOL;
849  generate_indent(indents_ + x.dims_.size(), o_);
850  o_ << "};" << EOL;
851  generate_end_for_dims(x.dims_.size());
852  }
853  void operator()(int_var_decl const& x) const {
854  basic_validate(x);
855  }
856  void operator()(double_var_decl const& x) const {
857  basic_validate(x);
858  }
859  void operator()(vector_var_decl const& x) const {
860  basic_validate(x);
861  }
862  void operator()(row_vector_var_decl const& x) const {
863  basic_validate(x);
864  }
865  void operator()(matrix_var_decl const& x) const {
866  basic_validate(x);
867  }
868  template <typename T>
869  void nonbasic_validate(const T& x,
870  const std::string& type_name) const {
871  generate_begin_for_dims(x.dims_);
872  generate_indent(indents_ + x.dims_.size(),o_);
873  o_ << "try { stan::math::check_" << type_name << "(function__,";
874  generate_loop_var(x.name_,x.dims_.size());
875  o_ << ",\"";
876  generate_loop_var(x.name_,x.dims_.size());
877  o_ << "\", (double *)0); } catch (const std::exception& e) { throw std::domain_error(std::string(\"Invalid value of " << x.name_ << ": \") + std::string(e.what())); };" << EOL;
878  generate_end_for_dims(x.dims_.size());
879  }
880  void operator()(unit_vector_var_decl const& x) const {
881  nonbasic_validate(x,"unit_vector");
882  }
883  void operator()(simplex_var_decl const& x) const {
884  nonbasic_validate(x,"simplex");
885  }
886  void operator()(ordered_var_decl const& x) const {
887  nonbasic_validate(x,"ordered");
888  }
889  void operator()(positive_ordered_var_decl const& x) const {
890  nonbasic_validate(x,"positive_ordered");
891  }
892  void operator()(cholesky_factor_var_decl const& x) const {
893  nonbasic_validate(x,"cholesky_factor");
894  }
895  void operator()(cholesky_corr_var_decl const& x) const {
896  nonbasic_validate(x,"cholesky_factor_corr");
897  }
898  void operator()(cov_matrix_var_decl const& x) const {
899  nonbasic_validate(x,"cov_matrix");
900  }
901  void operator()(corr_matrix_var_decl const& x) const {
902  nonbasic_validate(x,"corr_matrix");
903  }
904  };
905 
906 
908  int indent,
909  std::ostream& o) {
910  validate_var_decl_visgen vis(indent,o);
911  boost::apply_visitor(vis,decl.decl_);
912  }
913 
914  void generate_validate_var_decls(const std::vector<var_decl> decls,
915  int indent,
916  std::ostream& o) {
917  for (size_t i = 0; i < decls.size(); ++i)
918  generate_validate_var_decl(decls[i],indent,o);
919  }
920 
921  // see _var_decl_visgen cut & paste
922  struct member_var_decl_visgen : public visgen {
923  int indents_;
925  std::ostream& o)
926  : visgen(o),
927  indents_(indents) {
928  }
929  void operator()(nil const& /*x*/) const { }
930  void operator()(int_var_decl const& x) const {
931  declare_array("int",x.name_,x.dims_.size());
932  }
933  void operator()(double_var_decl const& x) const {
934  declare_array("double",x.name_,x.dims_.size());
935  }
936  void operator()(unit_vector_var_decl const& x) const {
937  declare_array(("vector_d"), x.name_, x.dims_.size());
938  }
939  void operator()(simplex_var_decl const& x) const {
940  declare_array(("vector_d"), x.name_, x.dims_.size());
941  }
942  void operator()(ordered_var_decl const& x) const {
943  declare_array(("vector_d"), x.name_, x.dims_.size());
944  }
945  void operator()(positive_ordered_var_decl const& x) const {
946  declare_array(("vector_d"), x.name_, x.dims_.size());
947  }
948  void operator()(cholesky_factor_var_decl const& x) const {
949  declare_array(("matrix_d"), x.name_, x.dims_.size());
950  }
951  void operator()(const cholesky_corr_var_decl& x) const {
952  declare_array(("matrix_d"), x.name_, x.dims_.size());
953  }
954  void operator()(cov_matrix_var_decl const& x) const {
955  declare_array(("matrix_d"), x.name_, x.dims_.size());
956  }
957  void operator()(corr_matrix_var_decl const& x) const {
958  declare_array(("matrix_d"), x.name_, x.dims_.size());
959  }
960  void operator()(vector_var_decl const& x) const {
961  declare_array(("vector_d"), x.name_, x.dims_.size());
962  }
963  void operator()(row_vector_var_decl const& x) const {
964  declare_array(("row_vector_d"), x.name_, x.dims_.size());
965  }
966  void operator()(matrix_var_decl const& x) const {
967  declare_array(("matrix_d"), x.name_, x.dims_.size());
968  }
969  void declare_array(std::string const& type, std::string const& name,
970  size_t size) const {
971  for (int i = 0; i < indents_; ++i)
972  o_ << INDENT;
973  for (size_t i = 0; i < size; ++i) {
974  o_ << "vector<";
975  }
976  o_ << type;
977  if (size > 0) {
978  o_ << ">";
979  }
980  for (size_t i = 1; i < size; ++i) {
981  o_ << " >";
982  }
983  o_ << " " << name << ";" << EOL;
984  }
985  };
986 
987  void generate_member_var_decls(const std::vector<var_decl>& vs,
988  int indent,
989  std::ostream& o) {
990  member_var_decl_visgen vis(indent,o);
991  for (size_t i = 0; i < vs.size(); ++i)
992  boost::apply_visitor(vis,vs[i].decl_);
993  }
994 
995  // see member_var_decl_visgen cut & paste
996  struct local_var_decl_visgen : public visgen {
997  int indents_;
998  bool is_var_;
1001  bool is_var,
1002  bool is_fun_return,
1003  std::ostream& o)
1004  : visgen(o),
1005  indents_(indents),
1006  is_var_(is_var),
1007  is_fun_return_(is_fun_return) {
1008  }
1009  void operator()(nil const& /*x*/) const { }
1010  void operator()(int_var_decl const& x) const {
1011  std::vector<expression> ctor_args;
1012  declare_array("int",ctor_args,x.name_,x.dims_);
1013  }
1014  void operator()(double_var_decl const& x) const {
1015  std::vector<expression> ctor_args;
1017  ? "fun_scalar_t__"
1018  : ( is_var_ ? "T__" : "double" ),
1019  ctor_args,x.name_,x.dims_);
1020  }
1021  void operator()(vector_var_decl const& x) const {
1022  std::vector<expression> ctor_args;
1023  ctor_args.push_back(x.M_);
1025  ? "Eigen::Matrix<fun_scalar_t__,Eigen::Dynamic,1> "
1026  : ( is_var_ ? "Eigen::Matrix<T__,Eigen::Dynamic,1> " : "vector_d" ),
1027  ctor_args, x.name_, x.dims_);
1028  }
1029  void operator()(row_vector_var_decl const& x) const {
1030  std::vector<expression> ctor_args;
1031  ctor_args.push_back(x.N_);
1033  ? "Eigen::Matrix<fun_scalar_t__,1,Eigen::Dynamic> "
1034  : ( is_var_
1035  ? "Eigen::Matrix<T__,1,Eigen::Dynamic> "
1036  : "row_vector_d" ),
1037  ctor_args, x.name_, x.dims_);
1038  }
1039  void operator()(matrix_var_decl const& x) const {
1040  std::vector<expression> ctor_args;
1041  ctor_args.push_back(x.M_);
1042  ctor_args.push_back(x.N_);
1044  ? "Eigen::Matrix<fun_scalar_t__,Eigen::Dynamic,Eigen::Dynamic> "
1045  : ( is_var_
1046  ? "Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> "
1047  : "matrix_d" ),
1048  ctor_args, x.name_, x.dims_);
1049  }
1050  void operator()(unit_vector_var_decl const& x) const {
1051  std::vector<expression> ctor_args;
1052  ctor_args.push_back(x.K_);
1054  ? "Eigen::Matrix<fun_scalar_t__,Eigen::Dynamic,1> "
1055  : ( is_var_ ? "Eigen::Matrix<T__,Eigen::Dynamic,1> " : "vector_d" ),
1056  ctor_args, x.name_, x.dims_);
1057  }
1058  void operator()(simplex_var_decl const& x) const {
1059  std::vector<expression> ctor_args;
1060  ctor_args.push_back(x.K_);
1062  ? "Eigen::Matrix<fun_scalar_t__,Eigen::Dynamic,1> "
1063  : ( is_var_ ? "Eigen::Matrix<T__,Eigen::Dynamic,1> " : "vector_d"),
1064  ctor_args, x.name_, x.dims_);
1065  }
1066  void operator()(ordered_var_decl const& x) const {
1067  std::vector<expression> ctor_args;
1068  ctor_args.push_back(x.K_);
1070  ? "Eigen::Matrix<fun_scalar_t__,Eigen::Dynamic,1> "
1071  : ( is_var_ ? "Eigen::Matrix<T__,Eigen::Dynamic,1> " : "vector_d" ),
1072  ctor_args, x.name_, x.dims_);
1073  }
1074  void operator()(positive_ordered_var_decl const& x) const {
1075  std::vector<expression> ctor_args;
1076  ctor_args.push_back(x.K_);
1078  ? "Eigen::Matrix<fun_scalar_t__,Eigen::Dynamic,1> "
1079  : ( is_var_ ? "Eigen::Matrix<T__,Eigen::Dynamic,1> " : "vector_d" ),
1080  ctor_args, x.name_, x.dims_);
1081  }
1082  void operator()(cholesky_factor_var_decl const& x) const {
1083  std::vector<expression> ctor_args;
1084  ctor_args.push_back(x.M_);
1085  ctor_args.push_back(x.N_);
1087  ? "Eigen::Matrix<fun_scalar_t__,Eigen::Dynamic,Eigen::Dynamic> "
1088  : ( is_var_
1089  ? "Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> "
1090  : "matrix_d" ),
1091  ctor_args, x.name_, x.dims_);
1092  }
1093  void operator()(const cholesky_corr_var_decl& x) const {
1094  std::vector<expression> ctor_args;
1095  ctor_args.push_back(x.K_);
1096  ctor_args.push_back(x.K_);
1098  ? "Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> "
1099  : "matrix_d",
1100  ctor_args, x.name_, x.dims_);
1101  }
1102  void operator()(cov_matrix_var_decl const& x) const {
1103  std::vector<expression> ctor_args;
1104  ctor_args.push_back(x.K_);
1105  ctor_args.push_back(x.K_);
1107  ? "Eigen::Matrix<fun_scalar_t__,Eigen::Dynamic,Eigen::Dynamic> "
1108  : ( is_var_
1109  ? "Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> "
1110  : "matrix_d" ),
1111  ctor_args, x.name_, x.dims_);
1112  }
1113  void operator()(corr_matrix_var_decl const& x) const {
1114  std::vector<expression> ctor_args;
1115  ctor_args.push_back(x.K_);
1116  ctor_args.push_back(x.K_);
1118  ? "Eigen::Matrix<fun_scalar_t__,Eigen::Dynamic,Eigen::Dynamic> "
1119  : ( is_var_
1120  ? "Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> "
1121  : "matrix_d" ),
1122  ctor_args, x.name_, x.dims_);
1123  }
1124  void generate_type(const std::string& type,
1125  size_t num_dims) const {
1126  for (size_t i = 0; i < num_dims; ++i)
1127  o_ << "vector<";
1128  o_ << type;
1129  for (size_t i = 0; i < num_dims; ++i) {
1130  if (i > 0) o_ << " ";
1131  o_ << ">";
1132  }
1133  }
1134 
1135  void generate_void_statement(const std::string& name) const {
1136  o_ << "(void) " << name << "; // dummy to suppress unused var warning";
1137  }
1138 
1139  // var_decl -> type[0] name init_args[0] ;
1140  // init_args[k] -> ctor_args if no dims left
1141  // init_args[k] -> ( dim[k] , ( type[k+1] init_args[k+1] ) )
1142  void generate_init_args(const std::string& type,
1143  const std::vector<expression>& ctor_args,
1144  const std::vector<expression>& dims,
1145  size_t dim) const {
1146  if (dim < dims.size()) { // more dims left
1147  o_ << '('; // open(1)
1148  generate_expression(dims[dim],o_);
1149  if ((dim + 1 < dims.size()) || ctor_args.size() > 0) {
1150  o_ << ", ("; // open(2)
1151  generate_type(type,dims.size() - dim - 1);
1152  generate_init_args(type,ctor_args,dims,dim + 1);
1153  o_ << ')'; // close(2)
1154  } else if (type == "var") {
1155  o_ << ", DUMMY_VAR__";
1156  } else if (type == "int") {
1157  o_ << ", 0";
1158  } else if (type == "double") {
1159  o_ << ", 0.0";
1160  } else {
1161  // shouldn't hit this
1162  }
1163  o_ << ')'; // close(1)
1164  } else {
1165  if (ctor_args.size() == 0) { // scalar int or real
1166  if (type == "int") {
1167  o_ << "(0)";
1168  } else if (type == "double") {
1169  o_ << "(0.0)";
1170  } else if (type == "var") {
1171  o_ << "(DUMMY_VAR__)";
1172  } else {
1173  // shouldn't hit this, either
1174  }
1175  }
1176  else if (ctor_args.size() == 1) {// vector
1177  o_ << '(';
1178  generate_expression(ctor_args[0],o_);
1179  o_ << ')';
1180  } else if (ctor_args.size() > 1) { // matrix
1181  o_ << '(';
1182  generate_expression(ctor_args[0],o_);
1183  o_ << ',';
1184  generate_expression(ctor_args[1],o_);
1185  o_ << ')';
1186  }
1187  }
1188  }
1189  void declare_array(const std::string& type,
1190  const std::vector<expression>& ctor_args,
1191  const std::string& name,
1192  const std::vector<expression>& dims) const {
1193 
1194  // require double parens to counter "most vexing parse" problem
1195 
1197  generate_type(type,dims.size());
1198  o_ << ' ' << name;
1199  generate_init_args(type,ctor_args,dims,0);
1200  o_ << ';' << EOL;
1201  if (dims.size() == 0) {
1204  o_ << EOL;
1205  }
1206  if (type == "Eigen::Matrix<T__,Eigen::Dynamic,Eigen::Dynamic> "
1207  || type == "Eigen::Matrix<T__,1,Eigen::Dynamic> "
1208  || type == "Eigen::Matrix<T__,Eigen::Dynamic,1> ") {
1210  o_ << "stan::math::fill(" << name << ",DUMMY_VAR__);" << EOL;
1211  }
1212  }
1213  };
1214 
1215  void generate_local_var_decls(const std::vector<var_decl>& vs,
1216  int indent,
1217  std::ostream& o,
1218  bool is_var,
1219  bool is_fun_return) {
1220  local_var_decl_visgen vis(indent,is_var,is_fun_return,o);
1221  for (size_t i = 0; i < vs.size(); ++i)
1222  boost::apply_visitor(vis,vs[i].decl_);
1223  }
1224 
1225 
1226 
1228  const bool declare_vars_;
1229  const bool is_var_;
1230  const bool is_fun_return_;
1231  const int indent_;
1233  bool is_var,
1234  bool is_fun_return,
1235  int indent,
1236  std::ostream& o)
1237  : visgen(o),
1238  declare_vars_(declare_vars),
1239  is_var_(is_var),
1240  is_fun_return_(is_fun_return),
1241  indent_(indent) {
1242  }
1243  void operator()(const nil& /*x*/) const {
1244  // no-op
1245  }
1246  void operator()(const int_var_decl& x) const {
1247  // no-op; ints need no init to prevent crashes and no NaN available
1248  }
1249  void operator()(const double_var_decl& x) const {
1250  generate_init(x);
1251  }
1252  void operator()(const vector_var_decl& x) const {
1253  generate_init(x);
1254  }
1255  void operator()(const row_vector_var_decl& x) const {
1256  generate_init(x);
1257  }
1258  void operator()(const matrix_var_decl& x) const {
1259  generate_init(x);
1260  }
1261  void operator()(const unit_vector_var_decl& x) const {
1262  generate_init(x);
1263  }
1264  void operator()(const simplex_var_decl& x) const {
1265  generate_init(x);
1266  }
1267  void operator()(const ordered_var_decl& x) const {
1268  generate_init(x);
1269  }
1270  void operator()(const positive_ordered_var_decl& x) const {
1271  generate_init(x);
1272  }
1273  void operator()(const cholesky_factor_var_decl& x) const {
1274  generate_init(x);
1275  }
1276  void operator()(const cholesky_corr_var_decl& x) const {
1277  generate_init(x);
1278  }
1279  void operator()(const cov_matrix_var_decl& x) const {
1280  generate_init(x);
1281  }
1282  void operator()(const corr_matrix_var_decl& x) const {
1283  generate_init(x);
1284  }
1285  template <typename T>
1286  void generate_init(const T& x) const {
1288  o_ << "stan::math::initialize(" << x.name_ << ", "
1289  << (is_var_ ? "DUMMY_VAR__" : "std::numeric_limits<double>::quiet_NaN()")
1290  << ");"
1291  << EOL;
1292  }
1293  };
1294 
1295  void generate_local_var_init_nan(const std::vector<var_decl>& vs,
1296  int indent,
1297  std::ostream& o,
1298  bool is_var,
1299  bool is_fun_return) {
1300  generate_local_var_init_nan_visgen vis(indent,is_var,is_fun_return,indent,o);
1301  for (size_t i = 0; i < vs.size(); ++i)
1302  boost::apply_visitor(vis,vs[i].decl_);
1303  }
1304 
1305 
1306  // see member_var_decl_visgen cut & paste
1308  int indent_;
1310  std::ostream& o)
1311  : visgen(o),
1312  indent_(indent) {
1313  }
1314  void operator()(nil const& /*x*/) const { }
1315  void operator()(int_var_decl const& x) const {
1317  o_ << "stan::math::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1318  }
1319  void operator()(double_var_decl const& x) const {
1321  o_ << "stan::math::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1322  }
1323  void operator()(vector_var_decl const& x) const {
1325  o_ << "stan::math::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1326  }
1327  void operator()(row_vector_var_decl const& x) const {
1329  o_ << "stan::math::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1330  }
1331  void operator()(matrix_var_decl const& x) const {
1333  o_ << "stan::math::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1334  }
1335  void operator()(unit_vector_var_decl const& x) const {
1337  o_ << "stan::math::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1338  }
1339  void operator()(simplex_var_decl const& x) const {
1341  o_ << "stan::math::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1342  }
1343  void operator()(ordered_var_decl const& x) const {
1345  o_ << "stan::math::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1346  }
1347  void operator()(positive_ordered_var_decl const& x) const {
1349  o_ << "stan::math::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1350  }
1351  void operator()(cholesky_factor_var_decl const& x) const {
1353  o_ << "stan::math::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1354  }
1355  void operator()(cholesky_corr_var_decl const& x) const {
1357  o_ << "stan::math::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1358  }
1359  void operator()(cov_matrix_var_decl const& x) const {
1361  o_ << "stan::math::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1362  }
1363  void operator()(corr_matrix_var_decl const& x) const {
1365  o_ << "stan::math::fill(" << x.name_ << ",DUMMY_VAR__);" << EOL;
1366  }
1367  };
1368 
1369  void generate_init_vars(const std::vector<var_decl>& vs,
1370  int indent,
1371  std::ostream& o) {
1372  generate_init_vars_visgen vis(indent,o);
1373  o << EOL;
1374  generate_comment("initialized transformed params to avoid seg fault on val access",
1375  indent,o);
1376  for (size_t i = 0; i < vs.size(); ++i)
1377  boost::apply_visitor(vis,vs[i].decl_);
1378  }
1379 
1380 
1384  std::ostream& o)
1385  : visgen(o),
1386  indents_(indents)
1387  { }
1388  void operator()(nil const& /*x*/) const { }
1389  void operator()(int_var_decl const& x) const {
1390  std::vector<expression> dims(x.dims_);
1391  validate_array(x.name_,dims,0);
1392  }
1393  void operator()(double_var_decl const& x) const {
1394  std::vector<expression> dims(x.dims_);
1395  validate_array(x.name_,dims,0);
1396  }
1397  void operator()(vector_var_decl const& x) const {
1398  std::vector<expression> dims(x.dims_);
1399  dims.push_back(x.M_);
1400  validate_array(x.name_,dims,1);
1401  }
1402  void operator()(unit_vector_var_decl const& x) const {
1403  std::vector<expression> dims(x.dims_);
1404  dims.push_back(x.K_);
1405  validate_array(x.name_,dims,1);
1406  }
1407  void operator()(simplex_var_decl const& x) const {
1408  std::vector<expression> dims(x.dims_);
1409  dims.push_back(x.K_);
1410  validate_array(x.name_,dims,1);
1411  }
1412  void operator()(ordered_var_decl const& x) const {
1413  std::vector<expression> dims(x.dims_);
1414  dims.push_back(x.K_);
1415  validate_array(x.name_,dims,1);
1416  }
1417  void operator()(positive_ordered_var_decl const& x) const {
1418  std::vector<expression> dims(x.dims_);
1419  dims.push_back(x.K_);
1420  validate_array(x.name_,dims,1);
1421  }
1422  void operator()(row_vector_var_decl const& x) const {
1423  std::vector<expression> dims(x.dims_);
1424  dims.push_back(x.N_);
1425  validate_array(x.name_,dims,1);
1426  }
1427  void operator()(matrix_var_decl const& x) const {
1428  std::vector<expression> dims(x.dims_);
1429  dims.push_back(x.M_);
1430  dims.push_back(x.N_);
1431  validate_array(x.name_,dims,2);
1432  }
1433  void operator()(cholesky_factor_var_decl const& x) const {
1434  std::vector<expression> dims(x.dims_);
1435  dims.push_back(x.M_);
1436  dims.push_back(x.N_);
1437  validate_array(x.name_,dims,2);
1438  }
1439  void operator()(cholesky_corr_var_decl const& x) const {
1440  std::vector<expression> dims(x.dims_);
1441  dims.push_back(x.K_);
1442  dims.push_back(x.K_);
1443  validate_array(x.name_,dims,2);
1444  }
1445  void operator()(cov_matrix_var_decl const& x) const {
1446  std::vector<expression> dims(x.dims_);
1447  dims.push_back(x.K_);
1448  dims.push_back(x.K_);
1449  validate_array(x.name_,dims,2);
1450  }
1451  void operator()(corr_matrix_var_decl const& x) const {
1452  std::vector<expression> dims(x.dims_);
1453  dims.push_back(x.K_);
1454  dims.push_back(x.K_);
1455  validate_array(x.name_,dims,2);
1456  }
1457  void validate_array(const std::string& name,
1458  const std::vector<expression>& dims,
1459  size_t matrix_dims) const {
1460 
1461  size_t non_matrix_dims = dims.size() - matrix_dims;
1462 
1463  for (size_t k = 0; k < dims.size(); ++k) {
1465  o_ << "for (int i" << k << "__ = 0; i" << k << "__ < ";
1466  generate_expression(dims[k],o_);
1467  o_ << "; ++i" << k << "__) {" << EOL;
1468  }
1469 
1470  generate_indent(indents_ + dims.size(), o_);
1471  o_ << "if (stan::math::is_uninitialized(" << name;
1472  for (size_t k = 0; k < non_matrix_dims; ++k)
1473  o_ << "[i" << k << "__]";
1474  if (matrix_dims > 0) {
1475  o_ << "(i" << non_matrix_dims << "__";
1476  if (matrix_dims > 1)
1477  o_ << ",i" << (non_matrix_dims + 1) << "__";
1478  o_ << ')';
1479  }
1480  o_ << ")) {" << EOL;
1481  generate_indent(indents_ + dims.size() + 1, o_);
1482  o_ << "std::stringstream msg__;" << EOL;
1483  generate_indent(indents_ + dims.size() + 1, o_);
1484  o_ << "msg__ << \"Undefined transformed parameter: "
1485  << name << "\"";
1486  for (size_t k = 0; k < dims.size(); ++k) {
1487  o_ << " << '['";
1488  o_ << " << i" << k << "__";
1489  o_ << " << ']'";
1490  }
1491  o_ << ';' << EOL;
1492  generate_indent(indents_ + dims.size() + 1, o_);
1493  o_ << "throw std::runtime_error(msg__.str());" << EOL;
1494 
1495  generate_indent(indents_ + dims.size(), o_);
1496  o_ << "}" << EOL;
1497  for (size_t k = 0; k < dims.size(); ++k) {
1498  generate_indent(indents_ + dims.size() - k - 1, o_);
1499  o_ << "}" << EOL;
1500  }
1501  }
1502  };
1503 
1504  void generate_validate_transformed_params(const std::vector<var_decl>& vs,
1505  int indent,
1506  std::ostream& o) {
1507  generate_comment("validate transformed parameters",indent,o);
1508  validate_transformed_params_visgen vis(indent,o);
1509  for (size_t i = 0; i < vs.size(); ++i)
1510  boost::apply_visitor(vis,vs[i].decl_);
1511  o << EOL;
1512  }
1513 
1514  void generate_statement(statement const& s, int indent, std::ostream& o,
1515  bool include_sampling, bool is_var,
1516  bool is_fun_return);
1517 
1518  struct statement_visgen : public visgen {
1519  size_t indent_;
1521  bool is_var_;
1523  statement_visgen(size_t indent,
1524  bool include_sampling,
1525  bool is_var,
1526  bool is_fun_return,
1527  std::ostream& o)
1528  : visgen(o),
1529  indent_(indent),
1530  include_sampling_(include_sampling),
1531  is_var_(is_var),
1532  is_fun_return_(is_fun_return) {
1533  }
1534  void operator()(nil const& /*x*/) const {
1535  }
1536  void operator()(assignment const& x) const {
1538  o_ << "stan::math::assign(";
1539  generate_indexed_expr<true>(x.var_dims_.name_,
1540  x.var_dims_.dims_,
1542  x.var_type_.dims_.size(),
1543  o_);
1544  o_ << ", ";
1545  generate_expression(x.expr_,o_);
1546  o_ << ");" << EOL;
1547  }
1548  void operator()(expression const& x) const {
1551  o_ << ";" << EOL;
1552  }
1553  void operator()(sample const& x) const {
1554  if (!include_sampling_) return;
1556  o_ << "lp_accum__.add(" << x.dist_.family_ << "_log<propto__>(";
1558  for (size_t i = 0; i < x.dist_.args_.size(); ++i) {
1559  o_ << ", ";
1561  }
1563  x.expr_,
1564  x.dist_.args_)) {
1565  o_ << ", pstream__";
1566  }
1567  o_ << "));" << EOL;
1568  // rest of impl is for truncation
1569  // generate bounds test
1570  if (x.truncation_.has_low()) {
1572  o_ << "if (";
1574  o_ << " < ";
1576  // bound
1577  o_ << ") lp_accum__.add(-std::numeric_limits<double>::infinity());" << EOL;
1578  }
1579  if (x.truncation_.has_high()) {
1581  if (x.truncation_.has_low()) o_ << "else ";
1582  o_ << "if (";
1584  o_ << " > ";
1586  // bound
1587  o_ << ") lp_accum__.add(-std::numeric_limits<double>::infinity());" << EOL;
1588  }
1589  // generate log denominator for case where bounds test pass
1590  if (x.truncation_.has_low() || x.truncation_.has_high()) {
1592  o_ << "else ";
1593  }
1594  if (x.truncation_.has_low() && x.truncation_.has_high()) {
1595  // T[L,U]: -log_diff_exp(Dist_cdf_log(U|params),Dist_cdf_log(L|Params))
1596  o_ << "lp_accum__.add(-log_diff_exp(";
1597  o_ << x.dist_.family_ << "_cdf_log(";
1599  for (size_t i = 0; i < x.dist_.args_.size(); ++i) {
1600  o_ << ", ";
1602  }
1603  o_ << "), " << x.dist_.family_ << "_cdf_log(";
1605  for (size_t i = 0; i < x.dist_.args_.size(); ++i) {
1606  o_ << ", ";
1608  }
1609  o_ << ")));" << EOL;
1610  } else if (!x.truncation_.has_low() && x.truncation_.has_high()) {
1611  // T[,U]; -Dist_cdf_log(U)
1612  o_ << "lp_accum__.add(-";
1613  o_ << x.dist_.family_ << "_cdf_log(";
1615  for (size_t i = 0; i < x.dist_.args_.size(); ++i) {
1616  o_ << ", ";
1618  }
1619  o_ << "));" << EOL;
1620  } else if (x.truncation_.has_low() && !x.truncation_.has_high()) {
1621  // T[L,]: -Dist_ccdf_log(L)
1622  o_ << "lp_accum__.add(-";
1623  o_ << x.dist_.family_ << "_ccdf_log(";
1625  for (size_t i = 0; i < x.dist_.args_.size(); ++i) {
1626  o_ << ", ";
1628  }
1629  o_ << "));" << EOL;
1630  }
1631  }
1634  o_ << "lp_accum__.add(";
1636  o_ << ");" << EOL;
1637  }
1638  void operator()(const statements& x) const {
1639  bool has_local_vars = x.local_decl_.size() > 0;
1640  size_t indent = has_local_vars ? (indent_ + 1) : indent_;
1641  if (has_local_vars) {
1643  o_ << "{" << EOL;
1648  }
1649 
1650  for (size_t i = 0; i < x.statements_.size(); ++i)
1652  is_fun_return_);
1653 
1654  if (has_local_vars) {
1656  o_ << "}" << EOL;
1657  }
1658  }
1659  void operator()(const print_statement& ps) const {
1661  o_ << "if (pstream__) {" << EOL;
1662  for (size_t i = 0; i < ps.printables_.size(); ++i) {
1663  generate_indent(indent_ + 1,o_);
1664  o_ << "stan_print(pstream__,";
1666  o_ << ");" << EOL;
1667  }
1668  generate_indent(indent_ + 1,o_);
1669  o_ << "*pstream__ << std::endl;" << EOL;
1671  o_ << '}' << EOL;
1672  }
1673  void operator()(const reject_statement& ps) const {
1675  o_ << "std::stringstream errmsg_stream__;" << EOL;
1676  for (size_t i = 0; i < ps.printables_.size(); ++i) {
1678  o_ << "errmsg_stream__ << ";
1680  o_ << ";" << EOL;
1681  }
1683  o_ << "throw std::domain_error(errmsg_stream__.str());" << EOL;
1684  }
1685  void operator()(const return_statement& rs) const {
1687  o_ << "return ";
1689  && !rs.return_value_.expression_type().is_void()) {
1690  o_ << "stan::math::promote_scalar<fun_return_scalar_t__>(";
1692  o_ << ")";
1693  }
1694  o_ << ";" << EOL;
1695  }
1696  void operator()(const for_statement& x) const {
1698  o_ << "for (int " << x.variable_ << " = ";
1700  o_ << "; " << x.variable_ << " <= ";
1702  o_ << "; ++" << x.variable_ << ") {" << EOL;
1706  o_ << "}" << EOL;
1707  }
1708  void operator()(const while_statement& x) const {
1710  o_ << "while (as_bool(";
1712  o_ << ")) {" << EOL;
1716  o_ << "}" << EOL;
1717  }
1718  void operator()(const conditional_statement& x) const {
1719  for (size_t i = 0; i < x.conditions_.size(); ++i) {
1720  if (i == 0)
1722  else
1723  o_ << " else ";
1724  o_ << "if (as_bool(";
1726  o_ << ")) {" << EOL;
1730  o_ << '}';
1731  }
1732  if (x.bodies_.size() > x.conditions_.size()) {
1733  o_ << " else {" << EOL;
1734  generate_statement(x.bodies_[x.bodies_.size()-1], indent_ + 1,
1737  generate_indent(indent_,o_);
1738  o_ << '}';
1739  }
1740  o_ << EOL;
1741  }
1742  void operator()(const no_op_statement& /*x*/) const {
1743  }
1744  };
1745 
1747  int indent,
1748  std::ostream& o,
1749  bool include_sampling,
1750  bool is_var,
1751  bool is_fun_return) {
1752  statement_visgen vis(indent,include_sampling,is_var,is_fun_return, o);
1753  boost::apply_visitor(vis,s.statement_);
1754  }
1755 
1756  void generate_statements(const std::vector<statement>& ss,
1757  int indent,
1758  std::ostream& o,
1759  bool include_sampling,
1760  bool is_var,
1761  bool is_fun_return) {
1762  statement_visgen vis(indent,include_sampling,is_var,is_fun_return,o);
1763  for (size_t i = 0; i < ss.size(); ++i)
1764  boost::apply_visitor(vis,ss[i].statement_);
1765  }
1766 
1767 
1769  std::ostream& o) {
1770 
1771 
1772  o << EOL;
1773  o << INDENT << "template <bool propto__, bool jacobian__, typename T__>" << EOL;
1774  o << INDENT << "T__ log_prob(vector<T__>& params_r__," << EOL;
1775  o << INDENT << " vector<int>& params_i__," << EOL;
1776  o << INDENT << " std::ostream* pstream__ = 0) const {" << EOL2;
1777 
1778  // use this dummy for inits
1779  o << INDENT2 << "T__ DUMMY_VAR__(std::numeric_limits<double>::quiet_NaN());" << EOL;
1780  o << INDENT2 << "(void) DUMMY_VAR__; // suppress unused var warning" << EOL2;
1781 
1782  o << INDENT2 << "T__ lp__(0.0);" << EOL;
1783  o << INDENT2 << "stan::math::accumulator<T__> lp_accum__;" << EOL2;
1784 
1785  bool is_var = true;
1786  bool is_fun_return = false;
1787 
1788  generate_comment("model parameters",2,o);
1789  generate_local_var_inits(p.parameter_decl_,is_var,true,o);
1790  o << EOL;
1791 
1792  generate_comment("transformed parameters",2,o);
1793  generate_local_var_decls(p.derived_decl_.first,2,o,is_var,is_fun_return);
1794  generate_init_vars(p.derived_decl_.first,2,o);
1795 
1796  o << EOL;
1797  bool include_sampling = true;
1798  generate_statements(p.derived_decl_.second,2,o,include_sampling,
1799  is_var,is_fun_return);
1800  o << EOL;
1801 
1803  o << INDENT2
1804  << "const char* function__ = \"validate transformed params %1%\";"
1805  << EOL;
1806  o << INDENT2
1807  << "(void) function__; // dummy to suppress unused var warning"
1808  << EOL;
1809 
1811 
1812  generate_comment("model body",2,o);
1813  generate_statement(p.statement_,2,o,include_sampling,
1814  is_var,is_fun_return);
1815  o << EOL;
1816  o << INDENT2 << "lp_accum__.add(lp__);" << EOL;
1817  o << INDENT2 << "return lp_accum__.sum();" << EOL2;
1818  o << INDENT << "} // log_prob()" << EOL2;
1819 
1820  o << INDENT << "template <bool propto, bool jacobian, typename T_>" << EOL;
1821  o << INDENT << "T_ log_prob(Eigen::Matrix<T_,Eigen::Dynamic,1>& params_r," << EOL;
1822  o << INDENT << " std::ostream* pstream = 0) const {" << EOL;
1823  o << INDENT << " std::vector<T_> vec_params_r;" << EOL;
1824  o << INDENT << " vec_params_r.reserve(params_r.size());" << EOL;
1825  o << INDENT << " for (int i = 0; i < params_r.size(); ++i)" << EOL;
1826  o << INDENT << " vec_params_r.push_back(params_r(i));" << EOL;
1827  o << INDENT << " std::vector<int> vec_params_i;" << EOL;
1828  o << INDENT << " return log_prob<propto,jacobian,T_>(vec_params_r, vec_params_i, pstream);" << EOL;
1829  o << INDENT << "}" << EOL2;
1830  }
1831 
1832  struct dump_member_var_visgen : public visgen {
1835  dump_member_var_visgen(std::ostream& o)
1836  : visgen(o),
1838  var_size_validator_(var_size_validating_visgen(o,"data initialization")) {
1839  }
1840  void operator()(nil const& /*x*/) const { } // dummy
1841  void operator()(int_var_decl const& x) const {
1842  std::vector<expression> dims = x.dims_;
1844  var_resizer_(x);
1845  o_ << INDENT2 << "vals_i__ = context__.vals_i(\"" << x.name_ << "\");" << EOL;
1846  o_ << INDENT2 << "pos__ = 0;" << EOL;
1847  size_t indentation = 1;
1848  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1849  size_t dim = dims.size() - dim_up - 1U;
1850  ++indentation;
1851  generate_indent(indentation,o_);
1852  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1853  generate_expression(dims[dim],o_);
1854  o_ << ";" << EOL;
1855  generate_indent(indentation,o_);
1856  o_ << "for (size_t i_" << dim << "__ = 0; i_"
1857  << dim << "__ < " << x.name_ << "_limit_" << dim
1858  << "__; ++i_" << dim << "__) {" << EOL;
1859  }
1860  generate_indent(indentation+1,o_);
1861  o_ << x.name_;
1862  for (size_t dim = 0; dim < dims.size(); ++dim)
1863  o_ << "[i_" << dim << "__]";
1864  o_ << " = vals_i__[pos__++];" << EOL;
1865  for (size_t dim = 0; dim < dims.size(); ++dim) {
1866  generate_indent(dims.size() + 1 - dim,o_);
1867  o_ << "}" << EOL;
1868  }
1869  }
1870  // minor changes to int_var_decl
1871  void operator()(double_var_decl const& x) const {
1872  std::vector<expression> dims = x.dims_;
1874  var_resizer_(x);
1875  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1876  o_ << INDENT2 << "pos__ = 0;" << EOL;
1877  size_t indentation = 1;
1878  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1879  size_t dim = dims.size() - dim_up - 1U;
1880  ++indentation;
1881  generate_indent(indentation,o_);
1882  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1883  generate_expression(dims[dim],o_);
1884  o_ << ";" << EOL;
1885  generate_indent(indentation,o_);
1886  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1887  }
1888  generate_indent(indentation+1,o_);
1889  o_ << x.name_;
1890  for (size_t dim = 0; dim < dims.size(); ++dim)
1891  o_ << "[i_" << dim << "__]";
1892  o_ << " = vals_r__[pos__++];" << EOL;
1893  for (size_t dim = 0; dim < dims.size(); ++dim) {
1894  generate_indent(dims.size() + 1 - dim,o_);
1895  o_ << "}" << EOL;
1896  }
1897  }
1898  // extra outer loop around double_var_decl
1899  void operator()(vector_var_decl const& x) const {
1900  std::vector<expression> dims = x.dims_;
1901  var_resizer_(x);
1903  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1904  o_ << INDENT2 << "pos__ = 0;" << EOL;
1905  o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
1907  o_ << ";" << EOL;
1908  o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
1909  size_t indentation = 2;
1910  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1911  size_t dim = dims.size() - dim_up - 1U;
1912  ++indentation;
1913  generate_indent(indentation,o_);
1914  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1915  generate_expression(dims[dim],o_);
1916  o_ << ";" << EOL;
1917  generate_indent(indentation,o_);
1918  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1919  }
1920  generate_indent(indentation+1,o_);
1921  o_ << x.name_;
1922  for (size_t dim = 0; dim < dims.size(); ++dim)
1923  o_ << "[i_" << dim << "__]";
1924  o_ << "[i_vec__]";
1925  o_ << " = vals_r__[pos__++];" << EOL;
1926  for (size_t dim = 0; dim < dims.size(); ++dim) {
1927  generate_indent(dims.size() + 2 - dim,o_);
1928  o_ << "}" << EOL;
1929  }
1930  o_ << INDENT2 << "}" << EOL;
1931  }
1932  // change variable name from vector_var_decl
1933  void operator()(row_vector_var_decl const& x) const {
1934  std::vector<expression> dims = x.dims_;
1936  var_resizer_(x);
1937  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1938  o_ << INDENT2 << "pos__ = 0;" << EOL;
1939  o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
1941  o_ << ";" << EOL;
1942  o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
1943  size_t indentation = 2;
1944  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1945  size_t dim = dims.size() - dim_up - 1U;
1946  ++indentation;
1947  generate_indent(indentation,o_);
1948  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1949  generate_expression(dims[dim],o_);
1950  o_ << ";" << EOL;
1951  generate_indent(indentation,o_);
1952  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1953  }
1954  generate_indent(indentation+1,o_);
1955  o_ << x.name_;
1956  for (size_t dim = 0; dim < dims.size(); ++dim)
1957  o_ << "[i_" << dim << "__]";
1958  o_ << "[i_vec__]";
1959  o_ << " = vals_r__[pos__++];" << EOL;
1960  for (size_t dim = 0; dim < dims.size(); ++dim) {
1961  generate_indent(dims.size() + 2 - dim,o_);
1962  o_ << "}" << EOL;
1963  }
1964  o_ << INDENT2 << "}" << EOL;
1965  }
1966  // same as simplex
1967  void operator()(unit_vector_var_decl const& x) const {
1968  std::vector<expression> dims = x.dims_;
1970  var_resizer_(x);
1971  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1972  o_ << INDENT2 << "pos__ = 0;" << EOL;
1973  o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
1975  o_ << ";" << EOL;
1976  o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
1977  size_t indentation = 2;
1978  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1979  size_t dim = dims.size() - dim_up - 1U;
1980  ++indentation;
1981  generate_indent(indentation,o_);
1982  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1983  generate_expression(dims[dim],o_);
1984  o_ << ";" << EOL;
1985  generate_indent(indentation,o_);
1986  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1987  }
1988  generate_indent(indentation+1,o_);
1989  o_ << x.name_;
1990  for (size_t dim = 0; dim < dims.size(); ++dim)
1991  o_ << "[i_" << dim << "__]";
1992  o_ << "[i_vec__]";
1993  o_ << " = vals_r__[pos__++];" << EOL;
1994  for (size_t dim = 0; dim < dims.size(); ++dim) {
1995  generate_indent(dims.size() + 2 - dim,o_);
1996  o_ << "}" << EOL;
1997  }
1998  o_ << INDENT2 << "}" << EOL;
1999  }
2000  // diff name of dims from vector
2001  void operator()(simplex_var_decl const& x) const {
2002  std::vector<expression> dims = x.dims_;
2004  var_resizer_(x);
2005  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
2006  o_ << INDENT2 << "pos__ = 0;" << EOL;
2007  o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
2009  o_ << ";" << EOL;
2010  o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
2011  size_t indentation = 2;
2012  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
2013  size_t dim = dims.size() - dim_up - 1U;
2014  ++indentation;
2015  generate_indent(indentation,o_);
2016  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
2017  generate_expression(dims[dim],o_);
2018  o_ << ";" << EOL;
2019  generate_indent(indentation,o_);
2020  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
2021  }
2022  generate_indent(indentation+1,o_);
2023  o_ << x.name_;
2024  for (size_t dim = 0; dim < dims.size(); ++dim)
2025  o_ << "[i_" << dim << "__]";
2026  o_ << "[i_vec__]";
2027  o_ << " = vals_r__[pos__++];" << EOL;
2028  for (size_t dim = 0; dim < dims.size(); ++dim) {
2029  generate_indent(dims.size() + 2 - dim,o_);
2030  o_ << "}" << EOL;
2031  }
2032  o_ << INDENT2 << "}" << EOL;
2033  }
2034  // same as simplex
2035  void operator()(ordered_var_decl const& x) const {
2036  std::vector<expression> dims = x.dims_;
2038  var_resizer_(x);
2039  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
2040  o_ << INDENT2 << "pos__ = 0;" << EOL;
2041  o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
2043  o_ << ";" << EOL;
2044  o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
2045  size_t indentation = 2;
2046  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
2047  size_t dim = dims.size() - dim_up - 1U;
2048  ++indentation;
2049  generate_indent(indentation,o_);
2050  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
2051  generate_expression(dims[dim],o_);
2052  o_ << ";" << EOL;
2053  generate_indent(indentation,o_);
2054  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
2055  }
2056  generate_indent(indentation+1,o_);
2057  o_ << x.name_;
2058  for (size_t dim = 0; dim < dims.size(); ++dim)
2059  o_ << "[i_" << dim << "__]";
2060  o_ << "[i_vec__]";
2061  o_ << " = vals_r__[pos__++];" << EOL;
2062  for (size_t dim = 0; dim < dims.size(); ++dim) {
2063  generate_indent(dims.size() + 2 - dim,o_);
2064  o_ << "}" << EOL;
2065  }
2066  o_ << INDENT2 << "}" << EOL;
2067  }
2068  // same as simplex
2069  void operator()(positive_ordered_var_decl const& x) const {
2070  std::vector<expression> dims = x.dims_;
2072  var_resizer_(x);
2073  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
2074  o_ << INDENT2 << "pos__ = 0;" << EOL;
2075  o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
2077  o_ << ";" << EOL;
2078  o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
2079  size_t indentation = 2;
2080  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
2081  size_t dim = dims.size() - dim_up - 1U;
2082  ++indentation;
2083  generate_indent(indentation,o_);
2084  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
2085  generate_expression(dims[dim],o_);
2086  o_ << ";" << EOL;
2087  generate_indent(indentation,o_);
2088  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
2089  }
2090  generate_indent(indentation+1,o_);
2091  o_ << x.name_;
2092  for (size_t dim = 0; dim < dims.size(); ++dim)
2093  o_ << "[i_" << dim << "__]";
2094  o_ << "[i_vec__]";
2095  o_ << " = vals_r__[pos__++];" << EOL;
2096  for (size_t dim = 0; dim < dims.size(); ++dim) {
2097  generate_indent(dims.size() + 2 - dim,o_);
2098  o_ << "}" << EOL;
2099  }
2100  o_ << INDENT2 << "}" << EOL;
2101  }
2102  // extra loop and different accessor vs. vector
2103  void operator()(matrix_var_decl const& x) const {
2104  std::vector<expression> dims = x.dims_;
2106  var_resizer_(x);
2107  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
2108  o_ << INDENT2 << "pos__ = 0;" << EOL;
2109  o_ << INDENT2 << "size_t " << x.name_ << "_m_mat_lim__ = ";
2111  o_ << ";" << EOL;
2112  o_ << INDENT2 << "size_t " << x.name_ << "_n_mat_lim__ = ";
2114  o_ << ";" << EOL;
2115  o_ << INDENT2 << "for (size_t " << "n_mat__ = 0; " << "n_mat__ < " << x.name_ << "_n_mat_lim__; ++n_mat__) {" << EOL;
2116  o_ << INDENT3 << "for (size_t " << "m_mat__ = 0; " << "m_mat__ < " << x.name_ << "_m_mat_lim__; ++m_mat__) {" << EOL;
2117  size_t indentation = 3;
2118  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
2119  size_t dim = dims.size() - dim_up - 1U;
2120  ++indentation;
2121  generate_indent(indentation,o_);
2122  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
2123  generate_expression(dims[dim],o_);
2124  o_ << ";" << EOL;
2125  generate_indent(indentation,o_);
2126  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
2127  }
2128  generate_indent(indentation+1,o_);
2129  o_ << x.name_;
2130  for (size_t dim = 0; dim < dims.size(); ++dim)
2131  o_ << "[i_" << dim << "__]";
2132  o_ << "(m_mat__,n_mat__)";
2133  o_ << " = vals_r__[pos__++];" << EOL;
2134  for (size_t dim = 0; dim < dims.size(); ++dim) {
2135  generate_indent(dims.size() + 2 - dim,o_);
2136  o_ << "}" << EOL;
2137  }
2138  o_ << INDENT3 << "}" << EOL;
2139  o_ << INDENT2 << "}" << EOL;
2140  }
2141  void operator()(corr_matrix_var_decl const& x) const {
2142  // FIXME: cut-and-paste of cov_matrix, very slightly different from matrix
2143  std::vector<expression> dims = x.dims_;
2145  var_resizer_(x);
2146  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
2147  o_ << INDENT2 << "pos__ = 0;" << EOL;
2148  o_ << INDENT2 << "size_t " << x.name_ << "_k_mat_lim__ = ";
2150  o_ << ";" << EOL;
2151  o_ << INDENT2 << "for (size_t " << "n_mat__ = 0; " << "n_mat__ < " << x.name_ << "_k_mat_lim__; ++n_mat__) {" << EOL;
2152  o_ << INDENT3 << "for (size_t " << "m_mat__ = 0; " << "m_mat__ < " << x.name_ << "_k_mat_lim__; ++m_mat__) {" << EOL;
2153  size_t indentation = 3;
2154  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
2155  size_t dim = dims.size() - dim_up - 1U;
2156  ++indentation;
2157  generate_indent(indentation,o_);
2158  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
2159  generate_expression(dims[dim],o_);
2160  o_ << ";" << EOL;
2161  generate_indent(indentation,o_);
2162  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
2163  }
2164  generate_indent(indentation+1,o_);
2165  o_ << x.name_;
2166  for (size_t dim = 0; dim < dims.size(); ++dim)
2167  o_ << "[i_" << dim << "__]";
2168  o_ << "(m_mat__,n_mat__)";
2169  o_ << " = vals_r__[pos__++];" << EOL;
2170  for (size_t dim = 0; dim < dims.size(); ++dim) {
2171  generate_indent(dims.size() + 2 - dim,o_);
2172  o_ << "}" << EOL;
2173  }
2174  o_ << INDENT3 << "}" << EOL;
2175  o_ << INDENT2 << "}" << EOL;
2176  }
2177  void operator()(cholesky_factor_var_decl const& x) const {
2178  // FIXME: cut and paste of cov_matrix
2179  std::vector<expression> dims = x.dims_;
2181  var_resizer_(x);
2182  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
2183  o_ << INDENT2 << "pos__ = 0;" << EOL;
2184 
2185  o_ << INDENT2 << "size_t " << x.name_ << "_m_mat_lim__ = ";
2187  o_ << ";" << EOL;
2188 
2189  o_ << INDENT2 << "size_t " << x.name_ << "_n_mat_lim__ = ";
2191  o_ << ";" << EOL;
2192 
2193  o_ << INDENT2 << "for (size_t " << "n_mat__ = 0; " << "n_mat__ < " << x.name_ << "_n_mat_lim__; ++n_mat__) {" << EOL;
2194  o_ << INDENT3 << "for (size_t " << "m_mat__ = 0; " << "m_mat__ < " << x.name_ << "_m_mat_lim__; ++m_mat__) {" << EOL;
2195 
2196  size_t indentation = 3;
2197  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
2198  size_t dim = dims.size() - dim_up - 1U;
2199  ++indentation;
2200  generate_indent(indentation,o_);
2201  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
2202  generate_expression(dims[dim],o_);
2203  o_ << ";" << EOL;
2204  generate_indent(indentation,o_);
2205  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {"
2206  << EOL;
2207  }
2208  generate_indent(indentation+1,o_);
2209  o_ << x.name_;
2210  for (size_t dim = 0; dim < dims.size(); ++dim)
2211  o_ << "[i_" << dim << "__]";
2212  o_ << "(m_mat__,n_mat__)";
2213  o_ << " = vals_r__[pos__++];" << EOL;
2214  for (size_t dim = 0; dim < dims.size(); ++dim) {
2215  generate_indent(dims.size() + 2 - dim,o_);
2216  o_ << "}" << EOL;
2217  }
2218 
2219  o_ << INDENT3 << "}" << EOL;
2220  o_ << INDENT2 << "}" << EOL;
2221  }
2222  void operator()(cholesky_corr_var_decl const& x) const {
2223  // FIXME: cut and paste of cholesky_factor_var_decl
2224  std::vector<expression> dims = x.dims_;
2226  var_resizer_(x);
2227  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
2228  o_ << INDENT2 << "pos__ = 0;" << EOL;
2229 
2230  o_ << INDENT2 << "size_t " << x.name_ << "_m_mat_lim__ = ";
2232  o_ << ";" << EOL;
2233 
2234  o_ << INDENT2 << "size_t " << x.name_ << "_n_mat_lim__ = ";
2236  o_ << ";" << EOL;
2237 
2238  o_ << INDENT2 << "for (size_t " << "n_mat__ = 0; " << "n_mat__ < " << x.name_ << "_n_mat_lim__; ++n_mat__) {" << EOL;
2239  o_ << INDENT3 << "for (size_t " << "m_mat__ = 0; " << "m_mat__ < " << x.name_ << "_m_mat_lim__; ++m_mat__) {" << EOL;
2240 
2241  size_t indentation = 3;
2242  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
2243  size_t dim = dims.size() - dim_up - 1U;
2244  ++indentation;
2245  generate_indent(indentation,o_);
2246  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
2247  generate_expression(dims[dim],o_);
2248  o_ << ";" << EOL;
2249  generate_indent(indentation,o_);
2250  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {"
2251  << EOL;
2252  }
2253  generate_indent(indentation+1,o_);
2254  o_ << x.name_;
2255  for (size_t dim = 0; dim < dims.size(); ++dim)
2256  o_ << "[i_" << dim << "__]";
2257  o_ << "(m_mat__,n_mat__)";
2258  o_ << " = vals_r__[pos__++];" << EOL;
2259  for (size_t dim = 0; dim < dims.size(); ++dim) {
2260  generate_indent(dims.size() + 2 - dim,o_);
2261  o_ << "}" << EOL;
2262  }
2263 
2264  o_ << INDENT3 << "}" << EOL;
2265  o_ << INDENT2 << "}" << EOL;
2266  }
2267  void operator()(cov_matrix_var_decl const& x) const {
2268  std::vector<expression> dims = x.dims_;
2270  var_resizer_(x);
2271  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
2272  o_ << INDENT2 << "pos__ = 0;" << EOL;
2273  o_ << INDENT2 << "size_t " << x.name_ << "_k_mat_lim__ = ";
2275  o_ << ";" << EOL;
2276  o_ << INDENT2 << "for (size_t " << "n_mat__ = 0; " << "n_mat__ < " << x.name_ << "_k_mat_lim__; ++n_mat__) {" << EOL;
2277  o_ << INDENT3 << "for (size_t " << "m_mat__ = 0; " << "m_mat__ < " << x.name_ << "_k_mat_lim__; ++m_mat__) {" << EOL;
2278  size_t indentation = 3;
2279  for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
2280  size_t dim = dims.size() - dim_up - 1U;
2281  ++indentation;
2282  generate_indent(indentation,o_);
2283  o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
2284  generate_expression(dims[dim],o_);
2285  o_ << ";" << EOL;
2286  generate_indent(indentation,o_);
2287  o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
2288  }
2289  generate_indent(indentation+1,o_);
2290  o_ << x.name_;
2291  for (size_t dim = 0; dim < dims.size(); ++dim)
2292  o_ << "[i_" << dim << "__]";
2293  o_ << "(m_mat__,n_mat__)";
2294  o_ << " = vals_r__[pos__++];" << EOL;
2295  for (size_t dim = 0; dim < dims.size(); ++dim) {
2296  generate_indent(dims.size() + 2 - dim,o_);
2297  o_ << "}" << EOL;
2298  }
2299  o_ << INDENT3 << "}" << EOL;
2300  o_ << INDENT2 << "}" << EOL;
2301  }
2302  };
2303 
2304  void suppress_warning(const std::string& indent,
2305  const std::string& var_name,
2306  std::ostream& o) {
2307  o << indent << "(void) "
2308  << var_name << ";"
2309  << " // dummy call to supress warning"
2310  << EOL;
2311  }
2312 
2313  void generate_member_var_inits(const std::vector<var_decl>& vs,
2314  std::ostream& o) {
2315  dump_member_var_visgen vis(o);
2316  for (size_t i = 0; i < vs.size(); ++i)
2317  boost::apply_visitor(vis, vs[i].decl_);
2318  }
2319 
2320  void generate_destructor(const std::string& model_name,
2321  std::ostream& o) {
2322  o << EOL
2323  << INDENT << "~" << model_name << "() { }"
2324  << EOL2;
2325  }
2326 
2327  // know all data is set and range expressions only depend on data
2329  set_param_ranges_visgen(std::ostream& o)
2330  : visgen(o) {
2331  }
2332  void operator()(const nil& /*x*/) const { }
2333  void operator()(const int_var_decl& x) const {
2335  // for loop for ranges
2336  for (size_t i = 0; i < x.dims_.size(); ++i) {
2337  generate_indent(i + 2, o_);
2338  o_ << "for (size_t i_" << i << "__ = 0; ";
2339  o_ << "i_" << i << "__ < ";
2341  o_ << "; ++i_" << i << "__) {" << EOL;
2342  }
2343  // add range
2344  generate_indent(x.dims_.size() + 2,o_);
2345  o_ << "param_ranges_i__.push_back(std::pair<int,int>(";
2347  o_ << ", ";
2349  o_ << "));" << EOL;
2350  // close for loop
2351  for (size_t i = 0; i < x.dims_.size(); ++i) {
2352  generate_indent(x.dims_.size() + 1 - i, o_);
2353  o_ << "}" << EOL;
2354  }
2355  }
2356  void operator()(const double_var_decl& x) const {
2358  }
2359  void operator()(const vector_var_decl& x) const {
2361  }
2362  void operator()(const row_vector_var_decl& x) const {
2364  }
2365  void operator()(const matrix_var_decl& x) const {
2366  generate_increment(x.M_,x.N_,x.dims_);
2367  }
2368  void operator()(const unit_vector_var_decl& x) const {
2369  // only K-1 vals
2370  o_ << INDENT2 << "num_params_r__ += (";
2372  o_ << " - 1)";
2373  for (size_t i = 0; i < x.dims_.size(); ++i) {
2374  o_ << " * ";
2376  }
2377  o_ << ";" << EOL;
2378  }
2379  void operator()(const simplex_var_decl& x) const {
2380  // only K-1 vals
2381  o_ << INDENT2 << "num_params_r__ += (";
2383  o_ << " - 1)";
2384  for (size_t i = 0; i < x.dims_.size(); ++i) {
2385  o_ << " * ";
2387  }
2388  o_ << ";" << EOL;
2389  }
2390  void operator()(const ordered_var_decl& x) const {
2392  }
2393  void operator()(const positive_ordered_var_decl& x) const {
2395  }
2396  void operator()(const cholesky_factor_var_decl& x) const {
2397  o_ << INDENT2 << "num_params_r__ += ((";
2398  // N * (N + 1) / 2 + (M - N) * M
2400  o_ << " * (";
2402  o_ << " + 1)) / 2 + (";
2404  o_ << " - ";
2406  o_ << ") * ";
2408  o_ << ")";
2409  for (size_t i = 0; i < x.dims_.size(); ++i) {
2410  o_ << " * ";
2412  }
2413  o_ << ";" << EOL;
2414  }
2415  void operator()(const cholesky_corr_var_decl& x) const {
2416  // FIXME: cut and paste ofcorr_matrix_var_decl
2417  o_ << INDENT2 << "num_params_r__ += ((";
2419  o_ << " * (";
2421  o_ << " - 1)) / 2)";
2422  for (size_t i = 0; i < x.dims_.size(); ++i) {
2423  o_ << " * ";
2425  }
2426  o_ << ";" << EOL;
2427  }
2428  void operator()(const cov_matrix_var_decl& x) const {
2429  // (K * (K - 1))/2 + K ?? define fun(K) = ??
2430  o_ << INDENT2 << "num_params_r__ += ((";
2432  o_ << " * (";
2434  o_ << " - 1)) / 2 + ";
2436  o_ << ")";
2437  for (size_t i = 0; i < x.dims_.size(); ++i) {
2438  o_ << " * ";
2440  }
2441  o_ << ";" << EOL;
2442  }
2443  void operator()(const corr_matrix_var_decl& x) const {
2444  o_ << INDENT2 << "num_params_r__ += ((";
2446  o_ << " * (";
2448  o_ << " - 1)) / 2)";
2449  for (size_t i = 0; i < x.dims_.size(); ++i) {
2450  o_ << " * ";
2452  }
2453  o_ << ";" << EOL;
2454  }
2455  // cut-and-paste from next for r
2456  void generate_increment_i(std::vector<expression> dims) const {
2457  if (dims.size() == 0) {
2458  o_ << INDENT2 << "++num_params_i__;" << EOL;
2459  return;
2460  }
2461  o_ << INDENT2 << "num_params_r__ += ";
2462  for (size_t i = 0; i < dims.size(); ++i) {
2463  if (i > 0) o_ << " * ";
2464  generate_expression(dims[i],o_);
2465  }
2466  o_ << ";" << EOL;
2467  }
2468  void generate_increment(std::vector<expression> dims) const {
2469  if (dims.size() == 0) {
2470  o_ << INDENT2 << "++num_params_r__;" << EOL;
2471  return;
2472  }
2473  o_ << INDENT2 << "num_params_r__ += ";
2474  for (size_t i = 0; i < dims.size(); ++i) {
2475  if (i > 0) o_ << " * ";
2476  generate_expression(dims[i],o_);
2477  }
2478  o_ << ";" << EOL;
2479  }
2481  std::vector<expression> dims) const {
2482  o_ << INDENT2 << "num_params_r__ += ";
2484  for (size_t i = 0; i < dims.size(); ++i) {
2485  o_ << " * ";
2486  generate_expression(dims[i],o_);
2487  }
2488  o_ << ";" << EOL;
2489 
2490  }
2492  std::vector<expression> dims) const {
2493  o_ << INDENT2 << "num_params_r__ += ";
2495  o_ << " * ";
2497  for (size_t i = 0; i < dims.size(); ++i) {
2498  o_ << " * ";
2499  generate_expression(dims[i],o_);
2500  }
2501  o_ << ";" << EOL;
2502  }
2503  };
2504 
2505  void generate_set_param_ranges(const std::vector<var_decl>& var_decls,
2506  std::ostream& o) {
2507  // o << EOL;
2508  // o << INDENT << "void set_param_ranges() {" << EOL;
2509  o << INDENT2 << "num_params_r__ = 0U;" << EOL;
2510  o << INDENT2 << "param_ranges_i__.clear();" << EOL;
2511  set_param_ranges_visgen vis(o);
2512  for (size_t i = 0; i < var_decls.size(); ++i)
2513  boost::apply_visitor(vis,var_decls[i].decl_);
2514  // o << INDENT << "}" << EOL;
2515  }
2516 
2517  void generate_constructor(const program& prog,
2518  const std::string& model_name,
2519  std::ostream& o) {
2520  o << INDENT << model_name << "(stan::io::var_context& context__," << EOL;
2521  o << INDENT << " std::ostream* pstream__ = 0)"
2522  << EOL;
2523  o << INDENT2 << ": prob_grad(0) {"
2524  << EOL; // resize 0 with var_resizing
2525  o << INDENT2 << "static const char* function__ = \""
2526  << model_name << "_namespace::" << model_name << "(%1%)\";" << EOL;
2527  suppress_warning(INDENT2, "function__", o);
2528  o << INDENT2 << "size_t pos__;" << EOL;
2529  suppress_warning(INDENT2, "pos__", o);
2530  o << INDENT2 << "std::vector<int> vals_i__;" << EOL;
2531  o << INDENT2 << "std::vector<double> vals_r__;" << EOL;
2532 
2534 
2535  o << EOL;
2536  generate_comment("validate data",2,o);
2538 
2540  o << EOL;
2541  bool include_sampling = false;
2542  bool is_var = false;
2543  bool is_fun_return = false;
2544  for (size_t i = 0; i < prog.derived_data_decl_.second.size(); ++i)
2545  generate_statement(prog.derived_data_decl_.second[i],
2546  2,o,include_sampling,is_var,is_fun_return);
2547 
2548  o << EOL;
2549  generate_comment("validate transformed data",2,o);
2551 
2552  o << EOL;
2553  generate_comment("set parameter ranges",2,o);
2555  // o << EOL << INDENT2 << "set_param_ranges();" << EOL;
2556 
2557  o << INDENT << "}" << EOL;
2558  }
2559 
2560  struct generate_init_visgen : public visgen {
2562  generate_init_visgen(std::ostream& o)
2563  : visgen(o),
2564  var_size_validator_(o,"initialization") {
2565  }
2566  void operator()(nil const& /*x*/) const { } // dummy
2567  void operator()(int_var_decl const& x) const {
2568  generate_check_int(x.name_,x.dims_.size());
2570  generate_declaration(x.name_,"int",x.dims_);
2571  generate_buffer_loop("i",x.name_, x.dims_);
2572  generate_write_loop("integer(",x.name_,x.dims_);
2573  }
2574  template <typename D>
2575  std::string function_args(const std::string& fun_prefix,
2576  const D& x) const {
2577  std::stringstream ss;
2578  ss << fun_prefix;
2579  if (has_lub(x)) {
2580  ss << "_lub_unconstrain(";
2581  generate_expression(x.range_.low_.expr_,ss);
2582  ss << ',';
2583  generate_expression(x.range_.high_.expr_,ss);
2584  ss << ',';
2585  } else if (has_lb(x)) {
2586  ss << "_lb_unconstrain(";
2587  generate_expression(x.range_.low_.expr_,ss);
2588  ss << ',';
2589  } else if (has_ub(x)) {
2590  ss << "_ub_unconstrain(";
2591  generate_expression(x.range_.high_.expr_,ss);
2592  ss << ',';
2593  } else {
2594  ss << "_unconstrain(";
2595  }
2596  return ss.str();
2597  }
2598 
2599  void operator()(double_var_decl const& x) const {
2600  generate_check_double(x.name_,x.dims_.size());
2602  generate_declaration(x.name_,"double",x.dims_);
2603  generate_buffer_loop("r",x.name_,x.dims_);
2604  generate_write_loop(function_args("scalar",x),
2605  x.name_, x.dims_);
2606  }
2607  void operator()(vector_var_decl const& x) const {
2608  generate_check_double(x.name_,x.dims_.size() + 1);
2610  generate_declaration(x.name_,"vector_d",x.dims_,x.M_);
2611  generate_buffer_loop("r",x.name_,x.dims_,x.M_);
2612  generate_write_loop(function_args("vector",x),
2613  x.name_,x.dims_);
2614  }
2615  void operator()(row_vector_var_decl const& x) const {
2616  generate_check_double(x.name_,x.dims_.size() + 1);
2618  generate_declaration(x.name_,"row_vector_d",x.dims_,x.N_);
2619  generate_buffer_loop("r",x.name_,x.dims_,x.N_);
2620  generate_write_loop(function_args("row_vector",x),
2621  x.name_,x.dims_);
2622  }
2623  void operator()(matrix_var_decl const& x) const {
2624  generate_check_double(x.name_,x.dims_.size() + 2);
2626  generate_declaration(x.name_,"matrix_d",x.dims_,x.M_,x.N_);
2627  generate_buffer_loop("r",x.name_,x.dims_,x.M_,x.N_);
2628  generate_write_loop(function_args("matrix",x),
2629  x.name_,x.dims_);
2630  }
2631  void operator()(unit_vector_var_decl const& x) const {
2632  generate_check_double(x.name_,x.dims_.size() + 1);
2634  generate_declaration(x.name_,"vector_d",x.dims_,x.K_);
2635  generate_buffer_loop("r",x.name_,x.dims_,x.K_);
2636  generate_write_loop("unit_vector_unconstrain(",x.name_,x.dims_);
2637  }
2638  void operator()(simplex_var_decl const& x) const {
2639  generate_check_double(x.name_,x.dims_.size() + 1);
2641  generate_declaration(x.name_,"vector_d",x.dims_,x.K_);
2642  generate_buffer_loop("r",x.name_,x.dims_,x.K_);
2643  generate_write_loop("simplex_unconstrain(",x.name_,x.dims_);
2644  }
2645  void operator()(ordered_var_decl const& x) const {
2646  generate_check_double(x.name_,x.dims_.size() + 1);
2648  generate_declaration(x.name_,"vector_d",x.dims_,x.K_);
2649  generate_buffer_loop("r",x.name_,x.dims_,x.K_);
2650  generate_write_loop("ordered_unconstrain(",x.name_,x.dims_);
2651  }
2652  void operator()(positive_ordered_var_decl const& x) const {
2653  generate_check_double(x.name_,x.dims_.size() + 1);
2655  generate_declaration(x.name_,"vector_d",x.dims_,x.K_);
2656  generate_buffer_loop("r",x.name_,x.dims_,x.K_);
2657  generate_write_loop("positive_ordered_unconstrain(",x.name_,x.dims_);
2658  }
2659  void operator()(cholesky_factor_var_decl const& x) const {
2660  generate_check_double(x.name_,x.dims_.size() + 2);
2662  generate_declaration(x.name_,"matrix_d",x.dims_,x.M_,x.N_);
2663  generate_buffer_loop("r",x.name_,x.dims_,x.M_,x.N_);
2664  generate_write_loop("cholesky_factor_unconstrain(",x.name_,x.dims_);
2665  }
2666  void operator()(cholesky_corr_var_decl const& x) const {
2667  generate_check_double(x.name_,x.dims_.size() + 2);
2669  generate_declaration(x.name_,"matrix_d",x.dims_,x.K_,x.K_);
2670  generate_buffer_loop("r",x.name_,x.dims_,x.K_,x.K_);
2671  generate_write_loop("cholesky_corr_unconstrain(",x.name_,x.dims_);
2672  }
2673  void operator()(cov_matrix_var_decl const& x) const {
2674  generate_check_double(x.name_,x.dims_.size() + 2);
2676  generate_declaration(x.name_,"matrix_d",x.dims_,x.K_,x.K_);
2677  generate_buffer_loop("r",x.name_,x.dims_,x.K_,x.K_);
2678  generate_write_loop("cov_matrix_unconstrain(",x.name_,x.dims_);
2679  }
2680  void operator()(corr_matrix_var_decl const& x) const {
2681  generate_check_double(x.name_,x.dims_.size() + 2);
2683  generate_declaration(x.name_,"matrix_d",x.dims_,x.K_,x.K_);
2684  generate_buffer_loop("r",x.name_,x.dims_,x.K_,x.K_);
2685  generate_write_loop("corr_matrix_unconstrain(",x.name_,x.dims_);
2686  }
2687  void generate_write_loop(const std::string& write_method_name,
2688  const std::string& var_name,
2689  const std::vector<expression>& dims) const {
2690  generate_dims_loop_fwd(dims);
2691  o_ << "try { writer__." << write_method_name;
2692  generate_name_dims(var_name,dims.size());
2693  o_ << "); } catch (const std::exception& e) { "
2694  " throw std::runtime_error(std::string(\"Error transforming variable "
2695  << var_name << ": \") + e.what()); }" << EOL;
2696  }
2697  void generate_name_dims(const std::string name,
2698  size_t num_dims) const {
2699  o_ << name;
2700  for (size_t i = 0; i < num_dims; ++i)
2701  o_ << "[i" << i << "__]";
2702  }
2703  void generate_declaration(const std::string& name,
2704  const std::string& base_type,
2705  const std::vector<expression>& dims,
2706  const expression& type_arg1 = expression(),
2707  const expression& type_arg2 = expression()) const {
2708  o_ << INDENT2;
2709  generate_type(base_type,dims,dims.size(),o_);
2710  o_ << ' ' << name;
2711 
2712  generate_initializer(o_,base_type,dims,type_arg1,type_arg2);
2713  }
2714  void generate_indent_num_dims(size_t base_indent,
2715  const std::vector<expression>& dims,
2716  const expression& dim1,
2717  const expression& dim2) const {
2718  generate_indent(dims.size() + base_indent,o_);
2719  if (!is_nil(dim1)) o_ << INDENT;
2720  if (!is_nil(dim2)) o_ << INDENT;
2721  }
2722  void generate_buffer_loop(const std::string& base_type,
2723  const std::string& name,
2724  const std::vector<expression>& dims,
2725  const expression& dim1 = expression(),
2726  const expression& dim2 = expression(),
2727  int indent = 2U) const {
2728  size_t size = dims.size();
2729  bool is_matrix = !is_nil(dim1) && !is_nil(dim2);
2730  bool is_vector = !is_nil(dim1) && is_nil(dim2);
2731  int extra_indent = is_matrix ? 2U : is_vector ? 1U : 0U;
2732  if (is_matrix) {
2733  generate_indent(indent,o_);
2734  o_ << "for (int j2__ = 0U; j2__ < ";
2735  generate_expression(dim2.expr_,o_);
2736  o_ << "; ++j2__)" << EOL;
2737 
2738  generate_indent(indent+1,o_);
2739  o_ << "for (int j1__ = 0U; j1__ < ";
2740  generate_expression(dim1.expr_,o_);
2741  o_ << "; ++j1__)" << EOL;
2742  } else if (is_vector) {
2743  generate_indent(indent,o_);
2744  o_ << "for (int j1__ = 0U; j1__ < ";
2745  generate_expression(dim1.expr_,o_);
2746  o_ << "; ++j1__)" << EOL;
2747  }
2748  for (size_t i = 0; i < size; ++i) {
2749  size_t idx = size - i - 1;
2750  generate_indent(i + indent + extra_indent, o_);
2751  o_ << "for (int i" << idx << "__ = 0U; i" << idx << "__ < ";
2752  generate_expression(dims[idx].expr_,o_);
2753  o_ << "; ++i" << idx << "__)" << EOL;
2754  }
2755  generate_indent_num_dims(2U,dims,dim1,dim2);
2756  o_ << name;
2757  for (size_t i = 0; i < dims.size(); ++i)
2758  o_ << "[i" << i << "__]";
2759  if (is_matrix)
2760  o_ << "(j1__,j2__)";
2761  else if (is_vector)
2762  o_ << "(j1__)";
2763  o_ << " = vals_" << base_type << "__[pos__++];" << EOL;
2764  }
2765  void generate_dims_loop_fwd(const std::vector<expression>& dims,
2766  int indent = 2U) const {
2767  size_t size = dims.size();
2768  for (size_t i = 0; i < size; ++i) {
2769  generate_indent(i + indent, o_);
2770  o_ << "for (int i" << i << "__ = 0U; i" << i << "__ < ";
2771  generate_expression(dims[i].expr_,o_);
2772  o_ << "; ++i" << i << "__)" << EOL;
2773  }
2774  generate_indent(2U + dims.size(),o_);
2775  }
2776  void generate_check_int(const std::string& name, size_t /*n*/) const {
2777  o_ << EOL << INDENT2
2778  << "if (!(context__.contains_i(\"" << name << "\")))"
2779  << EOL << INDENT3
2780  << "throw std::runtime_error(\"variable " << name << " missing\");" << EOL;
2781  o_ << INDENT2 << "vals_i__ = context__.vals_i(\"" << name << "\");" << EOL;
2782  o_ << INDENT2 << "pos__ = 0U;" << EOL;
2783  }
2784  void generate_check_double(const std::string& name, size_t /*n*/) const {
2785  o_ << EOL << INDENT2
2786  << "if (!(context__.contains_r(\"" << name << "\")))"
2787  << EOL << INDENT3
2788  << "throw std::runtime_error(\"variable " << name << " missing\");" << EOL;
2789  o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << name << "\");" << EOL;
2790  o_ << INDENT2 << "pos__ = 0U;" << EOL;
2791  }
2792  };
2793 
2794 
2795  void generate_init_method(const std::vector<var_decl>& vs,
2796  std::ostream& o) {
2797  o << EOL;
2798  o << INDENT << "void transform_inits(const stan::io::var_context& context__," << EOL;
2799  o << INDENT << " std::vector<int>& params_i__," << EOL;
2800  o << INDENT << " std::vector<double>& params_r__) const {" << EOL;
2801  o << INDENT2 << "stan::io::writer<double> writer__(params_r__,params_i__);" << EOL;
2802  o << INDENT2 << "size_t pos__;" << EOL;
2803  o << INDENT2 << "(void) pos__; // dummy call to supress warning" << EOL;
2804  o << INDENT2 << "std::vector<double> vals_r__;" << EOL;
2805  o << INDENT2 << "std::vector<int> vals_i__;" << EOL;
2806  o << EOL;
2807  generate_init_visgen vis(o);
2808  for (size_t i = 0; i < vs.size(); ++i)
2809  boost::apply_visitor(vis, vs[i].decl_);
2810 
2811  o << INDENT2 << "params_r__ = writer__.data_r();" << EOL;
2812  o << INDENT2 << "params_i__ = writer__.data_i();" << EOL;
2813  o << INDENT << "}" << EOL2;
2814 
2815  o << INDENT << "void transform_inits(const stan::io::var_context& context," << EOL;
2816  o << INDENT << " Eigen::Matrix<double,Eigen::Dynamic,1>& params_r) const {" << EOL;
2817  o << INDENT << " std::vector<double> params_r_vec;" << EOL;
2818  o << INDENT << " std::vector<int> params_i_vec;" << EOL;
2819  o << INDENT << " transform_inits(context, params_i_vec, params_r_vec);" << EOL;
2820  o << INDENT << " params_r.resize(params_r_vec.size());" << EOL;
2821  o << INDENT << " for (int i = 0; i < params_r.size(); ++i)" << EOL;
2822  o << INDENT << " params_r(i) = params_r_vec[i];" << EOL;
2823  o << INDENT << "}" << EOL2;
2824  }
2825 
2826  // see write_csv_visgen for similar structure
2827  struct write_dims_visgen : public visgen {
2828  write_dims_visgen(std::ostream& o)
2829  : visgen(o) {
2830  }
2831  void operator()(const nil& /*x*/) const { }
2832  void operator()(const int_var_decl& x) const {
2834  }
2835  void operator()(const double_var_decl& x) const {
2837  }
2838  void operator()(const vector_var_decl& x) const {
2839  std::vector<expression> matrix_args;
2840  matrix_args.push_back(x.M_);
2841  generate_dims_array(matrix_args,x.dims_);
2842  }
2843  void operator()(const row_vector_var_decl& x) const {
2844  std::vector<expression> matrix_args;
2845  matrix_args.push_back(x.N_);
2846  generate_dims_array(matrix_args,x.dims_);
2847  }
2848  void operator()(const matrix_var_decl& x) const {
2849  std::vector<expression> matrix_args;
2850  matrix_args.push_back(x.M_);
2851  matrix_args.push_back(x.N_);
2852  generate_dims_array(matrix_args,x.dims_);
2853  }
2854  void operator()(const unit_vector_var_decl& x) const {
2855  std::vector<expression> matrix_args;
2856  matrix_args.push_back(x.K_);
2857  generate_dims_array(matrix_args,x.dims_);
2858  }
2859  void operator()(const simplex_var_decl& x) const {
2860  std::vector<expression> matrix_args;
2861  matrix_args.push_back(x.K_);
2862  generate_dims_array(matrix_args,x.dims_);
2863  }
2864  void operator()(const ordered_var_decl& x) const {
2865  std::vector<expression> matrix_args;
2866  matrix_args.push_back(x.K_);
2867  generate_dims_array(matrix_args,x.dims_);
2868  }
2869  void operator()(const positive_ordered_var_decl& x) const {
2870  std::vector<expression> matrix_args;
2871  matrix_args.push_back(x.K_);
2872  generate_dims_array(matrix_args,x.dims_);
2873  }
2874  void operator()(const cholesky_factor_var_decl& x) const {
2875  std::vector<expression> matrix_args;
2876  matrix_args.push_back(x.M_);
2877  matrix_args.push_back(x.N_);
2878  generate_dims_array(matrix_args,x.dims_);
2879  }
2880  void operator()(const cholesky_corr_var_decl& x) const {
2881  std::vector<expression> matrix_args;
2882  matrix_args.push_back(x.K_);
2883  matrix_args.push_back(x.K_);
2884  generate_dims_array(matrix_args,x.dims_);
2885  }
2886  void operator()(const cov_matrix_var_decl& x) const {
2887  std::vector<expression> matrix_args;
2888  matrix_args.push_back(x.K_);
2889  matrix_args.push_back(x.K_);
2890  generate_dims_array(matrix_args,x.dims_);
2891  }
2892  void operator()(const corr_matrix_var_decl& x) const {
2893  std::vector<expression> matrix_args;
2894  matrix_args.push_back(x.K_);
2895  matrix_args.push_back(x.K_);
2896  generate_dims_array(matrix_args,x.dims_);
2897  }
2898  void
2899  generate_dims_array(const std::vector<expression>& matrix_dims_exprs,
2900  const std::vector<expression>& array_dims_exprs)
2901  const {
2902 
2903  o_ << INDENT2 << "dims__.resize(0);" << EOL;
2904  for (size_t i = 0; i < array_dims_exprs.size(); ++i) {
2905  o_ << INDENT2 << "dims__.push_back(";
2906  generate_expression(array_dims_exprs[i].expr_, o_);
2907  o_ << ");" << EOL;
2908  }
2909  // cut and paste above with matrix_dims_exprs
2910  for (size_t i = 0; i < matrix_dims_exprs.size(); ++i) {
2911  o_ << INDENT2 << "dims__.push_back(";
2912  generate_expression(matrix_dims_exprs[i].expr_, o_);
2913  o_ << ");" << EOL;
2914  }
2915  o_ << INDENT2 << "dimss__.push_back(dims__);" << EOL;
2916  }
2917 
2918  };
2919 
2920  void generate_dims_method(const program& prog,
2921  std::ostream& o) {
2922  write_dims_visgen vis(o);
2923  o << EOL << INDENT
2924  << "void get_dims(std::vector<std::vector<size_t> >& dimss__) const {"
2925  << EOL;
2926 
2927  o << INDENT2 << "dimss__.resize(0);" << EOL;
2928  o << INDENT2 << "std::vector<size_t> dims__;" << EOL;
2929 
2930  // parameters
2931  for (size_t i = 0; i < prog.parameter_decl_.size(); ++i) {
2932  boost::apply_visitor(vis,prog.parameter_decl_[i].decl_);
2933  }
2934  // transformed parameters
2935  for (size_t i = 0; i < prog.derived_decl_.first.size(); ++i) {
2936  boost::apply_visitor(vis,prog.derived_decl_.first[i].decl_);
2937  }
2938  // generated quantities
2939  for (size_t i = 0; i < prog.generated_decl_.first.size(); ++i) {
2940  boost::apply_visitor(vis,prog.generated_decl_.first[i].decl_);
2941  }
2942  o << INDENT << "}" << EOL2;
2943  }
2944 
2945 
2946 
2947  // see write_csv_visgen for similar structure
2949  write_param_names_visgen(std::ostream& o)
2950  : visgen(o) {
2951  }
2952  void operator()(const nil& /*x*/) const { }
2953  void operator()(const int_var_decl& x) const {
2955  }
2956  void operator()(const double_var_decl& x) const {
2958  }
2959  void operator()(const vector_var_decl& x) const {
2961  }
2962  void operator()(const row_vector_var_decl& x) const {
2964  }
2965  void operator()(const matrix_var_decl& x) const {
2967  }
2968  void operator()(const unit_vector_var_decl& x) const {
2970  }
2971  void operator()(const simplex_var_decl& x) const {
2973  }
2974  void operator()(const ordered_var_decl& x) const {
2976  }
2977  void operator()(const positive_ordered_var_decl& x) const {
2979  }
2980  void operator()(const cholesky_factor_var_decl& x) const {
2982  }
2983  void operator()(const cholesky_corr_var_decl& x) const {
2985  }
2986  void operator()(const cov_matrix_var_decl& x) const {
2988  }
2989  void operator()(const corr_matrix_var_decl& x) const {
2991  }
2992  void
2993  generate_param_names(const std::string& name) const {
2994  o_ << INDENT2
2995  << "names__.push_back(\"" << name << "\");"
2996  << EOL;
2997  }
2998  };
2999 
3000 
3002  std::ostream& o) {
3003  write_param_names_visgen vis(o);
3004  o << EOL << INDENT
3005  << "void get_param_names(std::vector<std::string>& names__) const {"
3006  << EOL;
3007 
3008  o << INDENT2
3009  << "names__.resize(0);"
3010  << EOL;
3011 
3012  // parameters
3013  for (size_t i = 0; i < prog.parameter_decl_.size(); ++i) {
3014  boost::apply_visitor(vis,prog.parameter_decl_[i].decl_);
3015  }
3016  // transformed parameters
3017  for (size_t i = 0; i < prog.derived_decl_.first.size(); ++i) {
3018  boost::apply_visitor(vis,prog.derived_decl_.first[i].decl_);
3019  }
3020  // generated quantities
3021  for (size_t i = 0; i < prog.generated_decl_.first.size(); ++i) {
3022  boost::apply_visitor(vis,prog.generated_decl_.first[i].decl_);
3023  }
3024 
3025  o << INDENT << "}" << EOL2;
3026  }
3027 
3028 
3029 
3030  // see write_csv_visgen for similar structure
3032  write_csv_header_visgen(std::ostream& o)
3033  : visgen(o) {
3034  }
3035  void operator()(const nil& /*x*/) const { }
3036  void operator()(const int_var_decl& x) const {
3038  }
3039  void operator()(const double_var_decl& x) const {
3041  }
3042  void operator()(const vector_var_decl& x) const {
3043  std::vector<expression> matrix_args;
3044  matrix_args.push_back(x.M_);
3045  generate_csv_header_array(matrix_args,x.name_,x.dims_);
3046  }
3047  void operator()(const row_vector_var_decl& x) const {
3048  std::vector<expression> matrix_args;
3049  matrix_args.push_back(x.N_);
3050  generate_csv_header_array(matrix_args,x.name_,x.dims_);
3051  }
3052  void operator()(const matrix_var_decl& x) const {
3053  std::vector<expression> matrix_args;
3054  matrix_args.push_back(x.M_);
3055  matrix_args.push_back(x.N_);
3056  generate_csv_header_array(matrix_args,x.name_,x.dims_);
3057  }
3058  void operator()(const unit_vector_var_decl& x) const {
3059  std::vector<expression> matrix_args;
3060  matrix_args.push_back(x.K_);
3061  generate_csv_header_array(matrix_args,x.name_,x.dims_);
3062  }
3063  void operator()(const simplex_var_decl& x) const {
3064  std::vector<expression> matrix_args;
3065  matrix_args.push_back(x.K_);
3066  generate_csv_header_array(matrix_args,x.name_,x.dims_);
3067  }
3068  void operator()(const ordered_var_decl& x) const {
3069  std::vector<expression> matrix_args;
3070  matrix_args.push_back(x.K_);
3071  generate_csv_header_array(matrix_args,x.name_,x.dims_);
3072  }
3073  void operator()(const positive_ordered_var_decl& x) const {
3074  std::vector<expression> matrix_args;
3075  matrix_args.push_back(x.K_);
3076  generate_csv_header_array(matrix_args,x.name_,x.dims_);
3077  }
3078  void operator()(const cholesky_factor_var_decl& x) const {
3079  std::vector<expression> matrix_args;
3080  matrix_args.push_back(x.M_);
3081  matrix_args.push_back(x.N_);
3082  generate_csv_header_array(matrix_args,x.name_,x.dims_);
3083  }
3084  void operator()(const cholesky_corr_var_decl& x) const {
3085  std::vector<expression> matrix_args;
3086  matrix_args.push_back(x.K_);
3087  matrix_args.push_back(x.K_);
3088  generate_csv_header_array(matrix_args,x.name_,x.dims_);
3089  }
3090  void operator()(const cov_matrix_var_decl& x) const {
3091  std::vector<expression> matrix_args;
3092  matrix_args.push_back(x.K_);
3093  matrix_args.push_back(x.K_);
3094  generate_csv_header_array(matrix_args,x.name_,x.dims_);
3095  }
3096  void operator()(const corr_matrix_var_decl& x) const {
3097  std::vector<expression> matrix_args;
3098  matrix_args.push_back(x.K_);
3099  matrix_args.push_back(x.K_);
3100  generate_csv_header_array(matrix_args,x.name_,x.dims_);
3101  }
3102  void
3103  generate_csv_header_array(const std::vector<expression>& matrix_dims,
3104  const std::string& name,
3105  const std::vector<expression>& dims) const {
3106 
3107  // begin for loop dims
3108  std::vector<expression> combo_dims(dims);
3109  for (size_t i = 0; i < matrix_dims.size(); ++i)
3110  combo_dims.push_back(matrix_dims[i]);
3111 
3112  for (size_t i = combo_dims.size(); i-- > 0; ) {
3113  generate_indent(1 + combo_dims.size() - i,o_);
3114  o_ << "for (int k_" << i << "__ = 1;"
3115  << " k_" << i << "__ <= ";
3116  generate_expression(combo_dims[i].expr_,o_);
3117  o_ << "; ++k_" << i << "__) {" << EOL; // begin (1)
3118  }
3119 
3120  // variable + indices
3121  generate_indent(2 + combo_dims.size(),o_);
3122  o_ << "writer__.comma();" << EOL; // only writes comma after first call
3123 
3124  generate_indent(2 + combo_dims.size(),o_);
3125  o_ << "o__ << \"" << name << '"';
3126  for (size_t i = 0; i < combo_dims.size(); ++i)
3127  o_ << " << '.' << k_" << i << "__";
3128  o_ << ';' << EOL;
3129 
3130  // end for loop dims
3131  for (size_t i = 0; i < combo_dims.size(); ++i) {
3132  generate_indent(1 + combo_dims.size() - i,o_);
3133  o_ << "}" << EOL; // end (1)
3134  }
3135  }
3136  // void
3137  // generate_csv_header_array(const std::vector<expression>& matrix_dims,
3138  // const std::string& name,
3139  // const std::vector<expression>& dims) const {
3140 
3141  // // begin for loop dims
3142  // std::vector<expression> combo_dims(dims);
3143  // for (size_t i = 0; i < matrix_dims.size(); ++i)
3144  // combo_dims.push_back(matrix_dims[i]);
3145 
3146  // for (size_t i = 0; i < combo_dims.size(); ++i) {
3147  // generate_indent(2 + i,o_);
3148  // o_ << "for (int k_" << i << "__ = 1;"
3149  // << " k_" << i << "__ <= ";
3150  // generate_expression(combo_dims[i].expr_,o_);
3151  // o_ << "; ++k_" << i << "__) {" << EOL; // begin (1)
3152  // }
3153 
3154  // // variable + indices
3155  // generate_indent(2 + combo_dims.size(),o_);
3156  // o_ << "writer__.comma();" << EOL; // only writes comma after first call
3157 
3158  // generate_indent(2 + combo_dims.size(),o_);
3159  // o_ << "o__ << \"" << name << '"';
3160  // for (size_t i = 0; i < combo_dims.size(); ++i)
3161  // o_ << " << '.' << k_" << i << "__";
3162  // o_ << ';' << EOL;
3163 
3164  // // end for loop dims
3165  // for (size_t i = 0; i < combo_dims.size(); ++i) {
3166  // generate_indent(1 + combo_dims.size() - i,o_);
3167  // o_ << "}" << EOL; // end (1)
3168  // }
3169  // }
3170  };
3171 
3172 
3174  std::ostream& o) {
3175  write_csv_header_visgen vis(o);
3176  o << EOL << INDENT << "void write_csv_header(std::ostream& o__) const {" << EOL;
3177  o << INDENT2 << "stan::io::csv_writer writer__(o__);" << EOL;
3178 
3179  // parameters
3180  for (size_t i = 0; i < prog.parameter_decl_.size(); ++i) {
3181  boost::apply_visitor(vis,prog.parameter_decl_[i].decl_);
3182  }
3183  // transformed parameters
3184  for (size_t i = 0; i < prog.derived_decl_.first.size(); ++i) {
3185  boost::apply_visitor(vis,prog.derived_decl_.first[i].decl_);
3186  }
3187  // generated quantities
3188  for (size_t i = 0; i < prog.generated_decl_.first.size(); ++i) {
3189  boost::apply_visitor(vis,prog.generated_decl_.first[i].decl_);
3190  }
3191  o << INDENT2 << "writer__.newline();" << EOL;
3192  o << INDENT << "}" << EOL2;
3193  }
3194 
3195  // see write_csv_visgen for similar structure
3198  : visgen(o) {
3199  }
3200  void operator()(const nil& /*x*/) const { }
3201  void operator()(const int_var_decl& x) const {
3203  }
3204  void operator()(const double_var_decl& x) const {
3206  }
3207  void operator()(const vector_var_decl& x) const {
3208  std::vector<expression> matrix_args;
3209  matrix_args.push_back(x.M_);
3210  generate_param_names_array(matrix_args,x.name_,x.dims_);
3211  }
3212  void operator()(const row_vector_var_decl& x) const {
3213  std::vector<expression> matrix_args;
3214  matrix_args.push_back(x.N_);
3215  generate_param_names_array(matrix_args,x.name_,x.dims_);
3216  }
3217  void operator()(const matrix_var_decl& x) const {
3218  std::vector<expression> matrix_args;
3219  matrix_args.push_back(x.M_);
3220  matrix_args.push_back(x.N_);
3221  generate_param_names_array(matrix_args,x.name_,x.dims_);
3222  }
3223  void operator()(const unit_vector_var_decl& x) const {
3224  std::vector<expression> matrix_args;
3225  matrix_args.push_back(x.K_);
3226  generate_param_names_array(matrix_args,x.name_,x.dims_);
3227  }
3228  void operator()(const simplex_var_decl& x) const {
3229  std::vector<expression> matrix_args;
3230  matrix_args.push_back(x.K_);
3231  generate_param_names_array(matrix_args,x.name_,x.dims_);
3232  }
3233  void operator()(const ordered_var_decl& x) const {
3234  std::vector<expression> matrix_args;
3235  matrix_args.push_back(x.K_);
3236  generate_param_names_array(matrix_args,x.name_,x.dims_);
3237  }
3238  void operator()(const positive_ordered_var_decl& x) const {
3239  std::vector<expression> matrix_args;
3240  matrix_args.push_back(x.K_);
3241  generate_param_names_array(matrix_args,x.name_,x.dims_);
3242  }
3243  void operator()(const cholesky_factor_var_decl& x) const {
3244  std::vector<expression> matrix_args;
3245  matrix_args.push_back(x.M_);
3246  matrix_args.push_back(x.N_);
3247  generate_param_names_array(matrix_args,x.name_,x.dims_);
3248  }
3249  void operator()(const cholesky_corr_var_decl& x) const {
3250  std::vector<expression> matrix_args;
3251  matrix_args.push_back(x.K_);
3252  matrix_args.push_back(x.K_);
3253  generate_param_names_array(matrix_args,x.name_,x.dims_);
3254  }
3255  void operator()(const cov_matrix_var_decl& x) const {
3256  std::vector<expression> matrix_args;
3257  matrix_args.push_back(x.K_);
3258  matrix_args.push_back(x.K_);
3259  generate_param_names_array(matrix_args,x.name_,x.dims_);
3260  }
3261  void operator()(const corr_matrix_var_decl& x) const {
3262  std::vector<expression> matrix_args;
3263  matrix_args.push_back(x.K_);
3264  matrix_args.push_back(x.K_);
3265  generate_param_names_array(matrix_args,x.name_,x.dims_);
3266  }
3267  void
3268  generate_param_names_array(const std::vector<expression>& matrix_dims,
3269  const std::string& name,
3270  const std::vector<expression>& dims) const {
3271 
3272  // begin for loop dims
3273  std::vector<expression> combo_dims(dims);
3274  for (size_t i = 0; i < matrix_dims.size(); ++i)
3275  combo_dims.push_back(matrix_dims[i]);
3276 
3277  for (size_t i = combo_dims.size(); i-- > 0; ) {
3278  generate_indent(1 + combo_dims.size() - i,o_);
3279  o_ << "for (int k_" << i << "__ = 1;"
3280  << " k_" << i << "__ <= ";
3281  generate_expression(combo_dims[i].expr_,o_);
3282  o_ << "; ++k_" << i << "__) {" << EOL; // begin (1)
3283  }
3284 
3285  generate_indent(2 + combo_dims.size(),o_);
3286  o_ << "param_name_stream__.str(std::string());" << EOL;
3287 
3288  generate_indent(2 + combo_dims.size(),o_);
3289  o_ << "param_name_stream__ << \"" << name << '"';
3290 
3291  for (size_t i = 0; i < combo_dims.size(); ++i)
3292  o_ << " << '.' << k_" << i << "__";
3293  o_ << ';' << EOL;
3294 
3295  generate_indent(2 + combo_dims.size(),o_);
3296  o_ << "param_names__.push_back(param_name_stream__.str());" << EOL;
3297 
3298  // end for loop dims
3299  for (size_t i = 0; i < combo_dims.size(); ++i) {
3300  generate_indent(1 + combo_dims.size() - i,o_);
3301  o_ << "}" << EOL; // end (1)
3302  }
3303  }
3304 
3305  };
3306 
3307 
3309  std::ostream& o) {
3310  o << EOL << INDENT
3311  << "void constrained_param_names(std::vector<std::string>& param_names__,"
3312  << EOL << INDENT
3313  << " bool include_tparams__ = true,"
3314  << EOL << INDENT
3315  << " bool include_gqs__ = true) const {"
3316  << EOL << INDENT2
3317  << "std::stringstream param_name_stream__;" << EOL;
3318 
3320  // parameters
3321  for (size_t i = 0; i < prog.parameter_decl_.size(); ++i) {
3322  boost::apply_visitor(vis,prog.parameter_decl_[i].decl_);
3323  }
3324 
3325  o << EOL << INDENT2
3326  << "if (!include_gqs__ && !include_tparams__) return;"
3327  << EOL;
3328 
3329  // transformed parameters
3330  for (size_t i = 0; i < prog.derived_decl_.first.size(); ++i) {
3331  boost::apply_visitor(vis,prog.derived_decl_.first[i].decl_);
3332  }
3333 
3334  o << EOL << INDENT2
3335  << "if (!include_gqs__) return;"
3336  << EOL;
3337 
3338  // generated quantities
3339  for (size_t i = 0; i < prog.generated_decl_.first.size(); ++i) {
3340  boost::apply_visitor(vis,prog.generated_decl_.first[i].decl_);
3341  }
3342 
3343  o << INDENT << "}" << EOL2;
3344  }
3345 
3346  // see write_csv_visgen for similar structure
3349  : visgen(o) {
3350  }
3351  void operator()(const nil& /*x*/) const { }
3352  void operator()(const int_var_decl& x) const {
3354  }
3355  void operator()(const double_var_decl& x) const {
3357  }
3358  void operator()(const vector_var_decl& x) const {
3359  std::vector<expression> matrix_args;
3360  matrix_args.push_back(x.M_);
3361  generate_param_names_array(matrix_args,x.name_,x.dims_);
3362  }
3363  void operator()(const row_vector_var_decl& x) const {
3364  std::vector<expression> matrix_args;
3365  matrix_args.push_back(x.N_);
3366  generate_param_names_array(matrix_args,x.name_,x.dims_);
3367  }
3368  void operator()(const matrix_var_decl& x) const {
3369  std::vector<expression> matrix_args;
3370  matrix_args.push_back(x.M_);
3371  matrix_args.push_back(x.N_);
3372  generate_param_names_array(matrix_args,x.name_,x.dims_);
3373  }
3374  void operator()(const unit_vector_var_decl& x) const {
3375  std::vector<expression> matrix_args;
3376  matrix_args.push_back(binary_op(x.K_,"-",int_literal(1)));
3377  generate_param_names_array(matrix_args,x.name_,x.dims_);
3378  }
3379  void operator()(const simplex_var_decl& x) const {
3380  std::vector<expression> matrix_args;
3381  matrix_args.push_back(binary_op(x.K_,"-",int_literal(1)));
3382  generate_param_names_array(matrix_args,x.name_,x.dims_);
3383  }
3384  void operator()(const ordered_var_decl& x) const {
3385  std::vector<expression> matrix_args;
3386  matrix_args.push_back(x.K_);
3387  generate_param_names_array(matrix_args,x.name_,x.dims_);
3388  }
3389  void operator()(const positive_ordered_var_decl& x) const {
3390  std::vector<expression> matrix_args;
3391  matrix_args.push_back(x.K_);
3392  generate_param_names_array(matrix_args,x.name_,x.dims_);
3393  }
3394  void operator()(const cholesky_factor_var_decl& x) const {
3395  // FIXME: cut-and-paste of cov_matrix
3396  std::vector<expression> matrix_args;
3397  // (N * (N + 1)) / 2 + (M - N) * N
3398  matrix_args.push_back(binary_op(binary_op(binary_op(x.N_,
3399  "*",
3400  binary_op(x.N_,
3401  "+",
3402  int_literal(1))),
3403  "/",
3404  int_literal(2)),
3405  "+",
3407  "-",
3408  x.N_),
3409  "*",
3410  x.N_)));
3411  generate_param_names_array(matrix_args,x.name_,x.dims_);
3412  }
3413  void operator()(const cholesky_corr_var_decl& x) const {
3414  // FIXME: cut-and-paste of corr_matrix
3415  std::vector<expression> matrix_args;
3416  // (K * (K - 1)) / 2
3417  matrix_args.push_back(binary_op(binary_op(x.K_,
3418  "*",
3419  binary_op(x.K_,
3420  "-",
3421  int_literal(1))),
3422  "/",
3423  int_literal(2)));
3424  generate_param_names_array(matrix_args,x.name_,x.dims_);
3425  }
3426  void operator()(const cov_matrix_var_decl& x) const {
3427  std::vector<expression> matrix_args;
3428  matrix_args.push_back(binary_op(x.K_,
3429  "+",
3431  "*",
3432  binary_op(x.K_,
3433  "-",
3434  int_literal(1))),
3435  "/",
3436  int_literal(2))));
3437  generate_param_names_array(matrix_args,x.name_,x.dims_);
3438  }
3439  void operator()(const corr_matrix_var_decl& x) const {
3440  std::vector<expression> matrix_args;
3441  matrix_args.push_back(binary_op(binary_op(x.K_,
3442  "*",
3443  binary_op(x.K_,
3444  "-",
3445  int_literal(1))),
3446  "/",
3447  int_literal(2)));
3448  generate_param_names_array(matrix_args,x.name_,x.dims_);
3449  }
3450  // FIXME: sharing instead of cut-and-paste from constrained
3451  void
3452  generate_param_names_array(const std::vector<expression>& matrix_dims,
3453  const std::string& name,
3454  const std::vector<expression>& dims) const {
3455 
3456  // begin for loop dims
3457  std::vector<expression> combo_dims(dims);
3458  for (size_t i = 0; i < matrix_dims.size(); ++i)
3459  combo_dims.push_back(matrix_dims[i]);
3460 
3461  for (size_t i = combo_dims.size(); i-- > 0; ) {
3462  generate_indent(1 + combo_dims.size() - i,o_);
3463  o_ << "for (int k_" << i << "__ = 1;"
3464  << " k_" << i << "__ <= ";
3465  generate_expression(combo_dims[i].expr_,o_);
3466  o_ << "; ++k_" << i << "__) {" << EOL; // begin (1)
3467  }
3468 
3469  generate_indent(2 + combo_dims.size(),o_);
3470  o_ << "param_name_stream__.str(std::string());" << EOL;
3471 
3472  generate_indent(2 + combo_dims.size(),o_);
3473  o_ << "param_name_stream__ << \"" << name << '"';
3474 
3475  for (size_t i = 0; i < combo_dims.size(); ++i)
3476  o_ << " << '.' << k_" << i << "__";
3477  o_ << ';' << EOL;
3478 
3479  generate_indent(2 + combo_dims.size(),o_);
3480  o_ << "param_names__.push_back(param_name_stream__.str());" << EOL;
3481 
3482  // end for loop dims
3483  for (size_t i = 0; i < combo_dims.size(); ++i) {
3484  generate_indent(1 + combo_dims.size() - i,o_);
3485  o_ << "}" << EOL; // end (1)
3486  }
3487  }
3488  };
3489 
3490 
3492  std::ostream& o) {
3493  o << EOL << INDENT
3494  << "void unconstrained_param_names(std::vector<std::string>& param_names__,"
3495  << EOL << INDENT
3496  << " bool include_tparams__ = true,"
3497  << EOL << INDENT
3498  << " bool include_gqs__ = true) const {"
3499  << EOL << INDENT2
3500  << "std::stringstream param_name_stream__;" << EOL;
3501 
3503  // parameters
3504  for (size_t i = 0; i < prog.parameter_decl_.size(); ++i) {
3505  boost::apply_visitor(vis,prog.parameter_decl_[i].decl_);
3506  }
3507 
3508  o << EOL << INDENT2
3509  << "if (!include_gqs__ && !include_tparams__) return;"
3510  << EOL;
3511 
3512  // transformed parameters
3513  for (size_t i = 0; i < prog.derived_decl_.first.size(); ++i) {
3514  boost::apply_visitor(vis,prog.derived_decl_.first[i].decl_);
3515  }
3516 
3517  o << EOL << INDENT2
3518  << "if (!include_gqs__) return;"
3519  << EOL;
3520 
3521  // generated quantities
3522  for (size_t i = 0; i < prog.generated_decl_.first.size(); ++i) {
3523  boost::apply_visitor(vis,prog.generated_decl_.first[i].decl_);
3524  }
3525 
3526  o << INDENT << "}" << EOL2;
3527  }
3528 
3529 
3530  // see init_member_var_visgen for cut & paste
3531  struct write_csv_visgen : public visgen {
3532  write_csv_visgen(std::ostream& o)
3533  : visgen(o) {
3534  }
3535  template <typename D>
3536  void generate_initialize_array_bounded(const D& x, const std::string& base_type,
3537  const std::string& read_fun_prefix,
3538  const std::vector<expression>& dim_args) const {
3539  std::vector<expression> read_args;
3540  std::string read_fun(read_fun_prefix);
3541  if (has_lub(x)) {
3542  read_fun += "_lub";
3543  read_args.push_back(x.range_.low_);
3544  read_args.push_back(x.range_.high_);
3545  } else if (has_lb(x)) {
3546  read_fun += "_lb";
3547  read_args.push_back(x.range_.low_);
3548  } else if (has_ub(x)) {
3549  read_fun += "_ub";
3550  read_args.push_back(x.range_.high_);
3551  }
3552  for (size_t i = 0; i < dim_args.size(); ++i)
3553  read_args.push_back(dim_args[i]);
3554  generate_initialize_array(base_type,read_fun,read_args,x.name_,x.dims_);
3555  }
3556  void operator()(const nil& /*x*/) const { }
3557  void operator()(const int_var_decl& x) const {
3559  x.name_,x.dims_);
3560  }
3561  void operator()(const double_var_decl& x) const {
3562  std::vector<expression> read_args;
3563  generate_initialize_array_bounded(x,"double","scalar",read_args);
3564  }
3565  void operator()(const vector_var_decl& x) const {
3566  std::vector<expression> read_args;
3567  read_args.push_back(x.M_);
3568  generate_initialize_array_bounded(x,"vector_d","vector",read_args);
3569  }
3570  void operator()(const row_vector_var_decl& x) const {
3571  std::vector<expression> read_args;
3572  read_args.push_back(x.N_);
3573  generate_initialize_array_bounded(x,"row_vector_d","row_vector",read_args);
3574  }
3575  void operator()(const matrix_var_decl& x) const {
3576  std::vector<expression> read_args;
3577  read_args.push_back(x.M_);
3578  read_args.push_back(x.N_);
3579  generate_initialize_array_bounded(x,"matrix_d","matrix",read_args);
3580  }
3581  void operator()(const unit_vector_var_decl& x) const {
3582  std::vector<expression> read_args;
3583  read_args.push_back(x.K_);
3584  generate_initialize_array("vector_d","unit_vector",read_args,x.name_,x.dims_);
3585  }
3586  void operator()(const simplex_var_decl& x) const {
3587  std::vector<expression> read_args;
3588  read_args.push_back(x.K_);
3589  generate_initialize_array("vector_d","simplex",read_args,x.name_,x.dims_);
3590  }
3591  void operator()(const ordered_var_decl& x) const {
3592  std::vector<expression> read_args;
3593  read_args.push_back(x.K_);
3594  generate_initialize_array("vector_d","ordered",read_args,x.name_,x.dims_);
3595  }
3596  void operator()(const positive_ordered_var_decl& x) const {
3597  std::vector<expression> read_args;
3598  read_args.push_back(x.K_);
3599  generate_initialize_array("vector_d","positive_ordered",read_args,x.name_,x.dims_);
3600  }
3601  void operator()(const cholesky_factor_var_decl& x) const {
3602  std::vector<expression> read_args;
3603  read_args.push_back(x.M_);
3604  read_args.push_back(x.N_);
3605  generate_initialize_array("matrix_d","cholesky_factor",read_args,x.name_,x.dims_);
3606  }
3607  void operator()(const cholesky_corr_var_decl& x) const {
3608  std::vector<expression> read_args;
3609  read_args.push_back(x.K_);
3610  generate_initialize_array("matrix_d","cholesky_corr",read_args,x.name_,x.dims_);
3611  }
3612  void operator()(const cov_matrix_var_decl& x) const {
3613  std::vector<expression> read_args;
3614  read_args.push_back(x.K_);
3615  generate_initialize_array("matrix_d","cov_matrix",read_args,x.name_,x.dims_);
3616  }
3617  void operator()(const corr_matrix_var_decl& x) const {
3618  std::vector<expression> read_args;
3619  read_args.push_back(x.K_);
3620  generate_initialize_array("matrix_d","corr_matrix",read_args,x.name_,x.dims_);
3621  }
3622  void generate_initialize_array(const std::string& var_type,
3623  const std::string& read_type,
3624  const std::vector<expression>& read_args,
3625  const std::string& name,
3626  const std::vector<expression>& dims) const {
3627  if (dims.size() == 0) {
3628  generate_indent(2,o_);
3629  o_ << var_type << " ";
3630  o_ << name << " = in__." << read_type << "_constrain(";
3631  for (size_t j = 0; j < read_args.size(); ++j) {
3632  if (j > 0) o_ << ",";
3633  generate_expression(read_args[j],o_);
3634  }
3635  o_ << ");" << EOL;
3636  o_ << INDENT2 << "writer__.write(" << name << ");" << EOL;
3637  return;
3638  }
3639  o_ << INDENT2;
3640  for (size_t i = 0; i < dims.size(); ++i) o_ << "vector<";
3641  o_ << var_type;
3642  for (size_t i = 0; i < dims.size(); ++i) o_ << "> ";
3643  o_ << name << ";" << EOL;
3644  std::string name_dims(name);
3645  for (size_t i = 0; i < dims.size(); ++i) {
3646  generate_indent(i + 2, o_);
3647  o_ << "size_t dim_" << name << "_" << i << "__ = ";
3648  generate_expression(dims[i],o_);
3649  o_ << ";" << EOL;
3650  if (i < dims.size() - 1) {
3651  generate_indent(i + 2, o_);
3652  o_ << name_dims << ".resize(dim_" << name << "_" << i << "__);"
3653  << EOL;
3654  name_dims.append("[k_").append(to_string(i)).append("__]");
3655  }
3656  generate_indent(i + 2, o_);
3657  o_ << "for (size_t k_" << i << "__ = 0;"
3658  << " k_" << i << "__ < dim_" << name << "_" << i << "__;"
3659  << " ++k_" << i << "__) {" << EOL;
3660  if (i == dims.size() - 1) {
3661  generate_indent(i + 3, o_);
3662  o_ << name_dims << ".push_back(in__." << read_type << "_constrain(";
3663  for (size_t j = 0; j < read_args.size(); ++j) {
3664  if (j > 0) o_ << ",";
3665  generate_expression(read_args[j],o_);
3666  }
3667  o_ << "));" << EOL;
3668  }
3669  }
3670  generate_indent(dims.size() + 2, o_);
3671  o_ << "writer__.write(" << name;
3672  if (dims.size() > 0) {
3673  o_ << '[';
3674  for (size_t i = 0; i < dims.size(); ++i) {
3675  if (i > 0) o_ << "][";
3676  o_ << "k_" << i << "__";
3677  }
3678  o_ << ']';
3679  }
3680  o_ << ");" << EOL;
3681 
3682  for (size_t i = dims.size(); i > 0; --i) {
3683  generate_indent(i + 1, o_);
3684  o_ << "}" << EOL;
3685  }
3686  }
3687  };
3688 
3689 
3690 
3691 
3692  struct write_csv_vars_visgen : public visgen {
3693  write_csv_vars_visgen(std::ostream& o)
3694  : visgen(o) {
3695  }
3696  void operator()(const nil& /*x*/) const { }
3697  // FIXME: template these out
3698  void operator()(const int_var_decl& x) const {
3699  write_array(x.name_,x.dims_);
3700  }
3701  void operator()(const double_var_decl& x) const {
3702  write_array(x.name_,x.dims_);
3703  }
3704  void operator()(const vector_var_decl& x) const {
3705  write_array(x.name_,x.dims_);
3706  }
3707  void operator()(const row_vector_var_decl& x) const {
3708  write_array(x.name_,x.dims_);
3709  }
3710  void operator()(const matrix_var_decl& x) const {
3711  write_array(x.name_,x.dims_);
3712  }
3713  void operator()(const unit_vector_var_decl& x) const {
3714  write_array(x.name_,x.dims_);
3715  }
3716  void operator()(const simplex_var_decl& x) const {
3717  write_array(x.name_,x.dims_);
3718  }
3719  void operator()(const ordered_var_decl& x) const {
3720  write_array(x.name_,x.dims_);
3721  }
3722  void operator()(const positive_ordered_var_decl& x) const {
3723  write_array(x.name_,x.dims_);
3724  }
3725  void operator()(const cholesky_factor_var_decl& x) const {
3726  write_array(x.name_,x.dims_);
3727  }
3728  void operator()(const cholesky_corr_var_decl& x) const {
3729  write_array(x.name_,x.dims_);
3730  }
3731  void operator()(const cov_matrix_var_decl& x) const {
3732  write_array(x.name_,x.dims_);
3733  }
3734  void operator()(const corr_matrix_var_decl& x) const {
3735  write_array(x.name_,x.dims_);
3736  }
3737  void write_array(const std::string& name,
3738  const std::vector<expression>& dims) const {
3739  if (dims.size() == 0) {
3740  o_ << INDENT2 << "writer__.write(" << name << ");" << EOL;
3741  return;
3742  }
3743  for (size_t i = 0; i < dims.size(); ++i) {
3744  generate_indent(i + 2, o_);
3745  o_ << "for (int k_" << i << "__ = 0;"
3746  << " k_" << i << "__ < ";
3747  generate_expression(dims[i],o_);
3748  o_ << "; ++k_" << i << "__) {" << EOL;
3749  }
3750 
3751  generate_indent(dims.size() + 2, o_);
3752  o_ << "writer__.write(" << name;
3753  if (dims.size() > 0) {
3754  o_ << '[';
3755  for (size_t i = 0; i < dims.size(); ++i) {
3756  if (i > 0) o_ << "][";
3757  o_ << "k_" << i << "__";
3758  }
3759  o_ << ']';
3760  }
3761  o_ << ");" << EOL;
3762 
3763  for (size_t i = dims.size(); i > 0; --i) {
3764  generate_indent(i + 1, o_);
3765  o_ << "}" << EOL;
3766  }
3767  }
3768  };
3769 
3770 
3772  const std::string& model_name,
3773  std::ostream& o) {
3774  o << INDENT << "template <typename RNG>" << EOL;
3775  o << INDENT << "void write_csv(RNG& base_rng__," << EOL;
3776  o << INDENT << " std::vector<double>& params_r__," << EOL;
3777  o << INDENT << " std::vector<int>& params_i__," << EOL;
3778  o << INDENT << " std::ostream& o__," << EOL;
3779  o << INDENT << " std::ostream* pstream__ = 0) const {" << EOL;
3780  o << INDENT2 << "stan::io::reader<double> in__(params_r__,params_i__);"
3781  << EOL;
3782  o << INDENT2 << "stan::io::csv_writer writer__(o__);" << EOL;
3783  o << INDENT2 << "static const char* function__ = \""
3784  << model_name << "_namespace::write_csv(%1%)\";" << EOL;
3785  suppress_warning(INDENT2, "function__", o);
3786 
3787  // declares, reads, and writes parameters
3788  generate_comment("read-transform, write parameters",2,o);
3789  write_csv_visgen vis(o);
3790  for (size_t i = 0; i < prog.parameter_decl_.size(); ++i)
3791  boost::apply_visitor(vis,prog.parameter_decl_[i].decl_);
3792 
3793  // this is for all other values
3794  write_csv_vars_visgen vis_writer(o);
3795 
3796  // parameters are guaranteed to satisfy constraints
3797 
3798  o << EOL;
3799  generate_comment("declare, define and validate transformed parameters",
3800  2,o);
3801  o << INDENT2 << "double lp__ = 0.0;" << EOL;
3802  suppress_warning(INDENT2, "lp__", o);
3803  o << INDENT2 << "stan::math::accumulator<double> lp_accum__;" << EOL2;
3804  bool is_var = false;
3805  bool is_fun_return = false;
3806  generate_local_var_decls(prog.derived_decl_.first,2,o,
3807  is_var,is_fun_return);
3808  o << EOL;
3809  bool include_sampling = false;
3810  generate_statements(prog.derived_decl_.second,2,o,include_sampling,
3811  is_var,is_fun_return);
3812  o << EOL;
3813 
3815  o << EOL;
3816 
3817  generate_comment("write transformed parameters",2,o);
3818  for (size_t i = 0; i < prog.derived_decl_.first.size(); ++i)
3819  boost::apply_visitor(vis_writer, prog.derived_decl_.first[i].decl_);
3820  o << EOL;
3821 
3822  generate_comment("declare and define generated quantities",2,o);
3823  generate_local_var_decls(prog.generated_decl_.first,2,o,is_var,is_fun_return);
3824  o << EOL;
3825  generate_statements(prog.generated_decl_.second,2,o,include_sampling,
3826  is_var,is_fun_return);
3827  o << EOL;
3828 
3829  generate_comment("validate generated quantities",2,o);
3831  o << EOL;
3832 
3833  generate_comment("write generated quantities",2,o);
3834  for (size_t i = 0; i < prog.generated_decl_.first.size(); ++i)
3835  boost::apply_visitor(vis_writer, prog.generated_decl_.first[i].decl_);
3836  if (prog.generated_decl_.first.size() > 0)
3837  o << EOL;
3838 
3839  o << INDENT2 << "writer__.newline();" << EOL;
3840  o << INDENT << "}" << EOL2;
3841 
3842  o << INDENT << "template <typename RNG>" << EOL;
3843  o << INDENT << "void write_csv(RNG& base_rng," << EOL;
3844  o << INDENT << " Eigen::Matrix<double,Eigen::Dynamic,1>& params_r," << EOL;
3845  o << INDENT << " std::ostream& o," << EOL;
3846  o << INDENT << " std::ostream* pstream = 0) const {" << EOL;
3847  o << INDENT << " std::vector<double> params_r_vec(params_r.size());" << EOL;
3848  o << INDENT << " for (int i = 0; i < params_r.size(); ++i)" << EOL;
3849  o << INDENT << " params_r_vec[i] = params_r(i);" << EOL;
3850  o << INDENT << " std::vector<int> params_i_vec; // dummy" << EOL;
3851  o << INDENT << " write_csv(base_rng, params_r_vec, params_i_vec, o, pstream);" << EOL;
3852  o << INDENT << "}" << EOL2;
3853  }
3854 
3855 
3856  // see init_member_var_visgen for cut & paste
3857  struct write_array_visgen : public visgen {
3858  write_array_visgen(std::ostream& o)
3859  : visgen(o) {
3860  }
3861  void operator()(const nil& /*x*/) const { }
3862  void operator()(const int_var_decl& x) const {
3864  x.name_,x.dims_);
3865  }
3866  // fixme -- reuse cut-and-pasted from other lub reader case
3867  template <typename D>
3868  void generate_initialize_array_bounded(const D& x, const std::string& base_type,
3869  const std::string& read_fun_prefix,
3870  const std::vector<expression>& dim_args) const {
3871  std::vector<expression> read_args;
3872  std::string read_fun(read_fun_prefix);
3873  if (has_lub(x)) {
3874  read_fun += "_lub";
3875  read_args.push_back(x.range_.low_);
3876  read_args.push_back(x.range_.high_);
3877  } else if (has_lb(x)) {
3878  read_fun += "_lb";
3879  read_args.push_back(x.range_.low_);
3880  } else if (has_ub(x)) {
3881  read_fun += "_ub";
3882  read_args.push_back(x.range_.high_);
3883  }
3884  for (size_t i = 0; i < dim_args.size(); ++i)
3885  read_args.push_back(dim_args[i]);
3886  generate_initialize_array(base_type,read_fun,read_args,x.name_,x.dims_);
3887  }
3888 
3889  void operator()(const double_var_decl& x) const {
3890  std::vector<expression> read_args;
3891  generate_initialize_array_bounded(x,"double","scalar",read_args);
3892  }
3893  void operator()(const vector_var_decl& x) const {
3894  std::vector<expression> read_args;
3895  read_args.push_back(x.M_);
3896  generate_initialize_array_bounded(x,"vector_d","vector",read_args);
3897  }
3898  void operator()(const row_vector_var_decl& x) const {
3899  std::vector<expression> read_args;
3900  read_args.push_back(x.N_);
3901  generate_initialize_array_bounded(x,"row_vector_d","row_vector",read_args);
3902  }
3903  void operator()(const matrix_var_decl& x) const {
3904  std::vector<expression> read_args;
3905  read_args.push_back(x.M_);
3906  read_args.push_back(x.N_);
3907  generate_initialize_array_bounded(x,"matrix_d","matrix",read_args);
3908  }
3909  void operator()(const unit_vector_var_decl& x) const {
3910  std::vector<expression> read_args;
3911  read_args.push_back(x.K_);
3912  generate_initialize_array("vector_d","unit_vector",read_args,x.name_,x.dims_);
3913  }
3914  void operator()(const simplex_var_decl& x) const {
3915  std::vector<expression> read_args;
3916  read_args.push_back(x.K_);
3917  generate_initialize_array("vector_d","simplex",read_args,x.name_,x.dims_);
3918  }
3919  void operator()(const ordered_var_decl& x) const {
3920  std::vector<expression> read_args;
3921  read_args.push_back(x.K_);
3922  generate_initialize_array("vector_d","ordered",read_args,x.name_,x.dims_);
3923  }
3924  void operator()(const positive_ordered_var_decl& x) const {
3925  std::vector<expression> read_args;
3926  read_args.push_back(x.K_);
3927  generate_initialize_array("vector_d","positive_ordered",read_args,x.name_,x.dims_);
3928  }
3929  void operator()(const cholesky_factor_var_decl& x) const {
3930  std::vector<expression> read_args;
3931  read_args.push_back(x.M_);
3932  read_args.push_back(x.N_);
3933  generate_initialize_array("matrix_d","cholesky_factor",read_args,x.name_,x.dims_);
3934  }
3935  void operator()(const cholesky_corr_var_decl& x) const {
3936  std::vector<expression> read_args;
3937  read_args.push_back(x.K_);
3938  generate_initialize_array("matrix_d","cholesky_corr",read_args,x.name_,x.dims_);
3939  }
3940  void operator()(const cov_matrix_var_decl& x) const {
3941  std::vector<expression> read_args;
3942  read_args.push_back(x.K_);
3943  generate_initialize_array("matrix_d","cov_matrix",read_args,x.name_,x.dims_);
3944  }
3945  void operator()(const corr_matrix_var_decl& x) const {
3946  std::vector<expression> read_args;
3947  read_args.push_back(x.K_);
3948  generate_initialize_array("matrix_d","corr_matrix",read_args,x.name_,x.dims_);
3949  }
3950  void generate_initialize_array(const std::string& var_type,
3951  const std::string& read_type,
3952  const std::vector<expression>& read_args,
3953  const std::string& name,
3954  const std::vector<expression>& dims) const {
3955  if (dims.size() == 0) {
3956  generate_indent(2,o_);
3957  o_ << var_type << " ";
3958  o_ << name << " = in__." << read_type << "_constrain(";
3959  for (size_t j = 0; j < read_args.size(); ++j) {
3960  if (j > 0) o_ << ",";
3961  generate_expression(read_args[j],o_);
3962  }
3963  o_ << ");" << EOL;
3964  return;
3965  }
3966  o_ << INDENT2;
3967  for (size_t i = 0; i < dims.size(); ++i) o_ << "vector<";
3968  o_ << var_type;
3969  for (size_t i = 0; i < dims.size(); ++i) o_ << "> ";
3970  o_ << name << ";" << EOL;
3971  std::string name_dims(name);
3972  for (size_t i = 0; i < dims.size(); ++i) {
3973  generate_indent(i + 2, o_);
3974  o_ << "size_t dim_" << name << "_" << i << "__ = ";
3975  generate_expression(dims[i],o_);
3976  o_ << ";" << EOL;
3977  if (i < dims.size() - 1) {
3978  generate_indent(i + 2, o_);
3979  o_ << name_dims << ".resize(dim_" << name << "_" << i << "__);"
3980  << EOL;
3981  name_dims.append("[k_").append(to_string(i)).append("__]");
3982  }
3983  generate_indent(i + 2, o_);
3984  o_ << "for (size_t k_" << i << "__ = 0;"
3985  << " k_" << i << "__ < dim_" << name << "_" << i << "__;"
3986  << " ++k_" << i << "__) {" << EOL;
3987  if (i == dims.size() - 1) {
3988  generate_indent(i + 3, o_);
3989  o_ << name_dims << ".push_back(in__." << read_type << "_constrain(";
3990  for (size_t j = 0; j < read_args.size(); ++j) {
3991  if (j > 0) o_ << ",";
3992  generate_expression(read_args[j],o_);
3993  }
3994  o_ << "));" << EOL;
3995  }
3996  }
3997 
3998  for (size_t i = dims.size(); i > 0; --i) {
3999  generate_indent(i + 1, o_);
4000  o_ << "}" << EOL;
4001  }
4002 
4003 
4004  }
4005  };
4006 
4007 
4008 
4009 
4011  write_array_vars_visgen(std::ostream& o)
4012  : visgen(o) {
4013  }
4014  void operator()(const nil& /*x*/) const { }
4015  // FIXME: template these out
4016  void operator()(const int_var_decl& x) const {
4018  }
4019  void operator()(const double_var_decl& x) const {
4021  }
4022  void operator()(const vector_var_decl& x) const {
4023  std::vector<expression> dims(x.dims_);
4024  dims.push_back(x.M_);
4026  }
4027  void operator()(const row_vector_var_decl& x) const {
4028  std::vector<expression> dims(x.dims_);
4029  dims.push_back(x.N_);
4031  }
4032  void operator()(const matrix_var_decl& x) const {
4033  std::vector<expression> matdims;
4034  matdims.push_back(x.M_);
4035  matdims.push_back(x.N_);
4036  write_array(x.name_,x.dims_,matdims);
4037  }
4038  void operator()(const unit_vector_var_decl& x) const {
4039  std::vector<expression> dims(x.dims_);
4040  dims.push_back(x.K_);
4042  }
4043  void operator()(const simplex_var_decl& x) const {
4044  std::vector<expression> dims(x.dims_);
4045  dims.push_back(x.K_);
4047  }
4048  void operator()(const ordered_var_decl& x) const {
4049  std::vector<expression> dims(x.dims_);
4050  dims.push_back(x.K_);
4052  }
4053  void operator()(const positive_ordered_var_decl& x) const {
4054  std::vector<expression> dims(x.dims_);
4055  dims.push_back(x.K_);
4057  }
4058  void operator()(const cholesky_factor_var_decl& x) const {
4059  std::vector<expression> matdims;
4060  matdims.push_back(x.M_);
4061  matdims.push_back(x.N_);
4062  write_array(x.name_,x.dims_,matdims);
4063  }
4064  void operator()(const cholesky_corr_var_decl& x) const {
4065  std::vector<expression> matdims;
4066  matdims.push_back(x.K_);
4067  matdims.push_back(x.K_);
4068  write_array(x.name_,x.dims_,matdims);
4069  }
4070  void operator()(const cov_matrix_var_decl& x) const {
4071  std::vector<expression> matdims;
4072  matdims.push_back(x.K_);
4073  matdims.push_back(x.K_);
4074  write_array(x.name_,x.dims_,matdims);
4075  }
4076  void operator()(const corr_matrix_var_decl& x) const {
4077  std::vector<expression> matdims;
4078  matdims.push_back(x.K_);
4079  matdims.push_back(x.K_);
4080  write_array(x.name_,x.dims_,matdims);
4081  }
4082  void write_array(const std::string& name,
4083  const std::vector<expression>& arraydims,
4084  const std::vector<expression>& matdims) const {
4085 
4086  std::vector<expression> dims(arraydims);
4087  for (size_t i = 0; i < matdims.size(); ++i)
4088  dims.push_back(matdims[i]);
4089 
4090  if (dims.size() == 0) {
4091  o_ << INDENT2 << "vars__.push_back(" << name << ");" << EOL;
4092  return;
4093  }
4094 
4095  // for (size_t i = 0; i < dims.size(); ++i) {
4096  for (size_t i = dims.size(); i > 0; ) {
4097  --i;
4098  generate_indent((dims.size() - i) + 1, o_);
4099  o_ << "for (int k_" << i << "__ = 0;"
4100  << " k_" << i << "__ < ";
4101  generate_expression(dims[i],o_);
4102  o_ << "; ++k_" << i << "__) {" << EOL;
4103  }
4104 
4105  generate_indent(dims.size() + 2, o_);
4106  o_ << "vars__.push_back(" << name;
4107  if (arraydims.size() > 0) {
4108  o_ << '[';
4109  for (size_t i = 0; i < arraydims.size(); ++i) {
4110  if (i > 0) o_ << "][";
4111  o_ << "k_" << i << "__";
4112  }
4113  o_ << ']';
4114  }
4115  if (matdims.size() > 0) {
4116  o_ << "(k_" << arraydims.size() << "__";
4117  if (matdims.size() > 1)
4118  o_ << ", k_" << (arraydims.size() + 1) << "__";
4119  o_ << ")";
4120  }
4121  o_ << ");" << EOL;
4122 
4123  for (size_t i = dims.size(); i > 0; --i) {
4124  generate_indent(i + 1, o_);
4125  o_ << "}" << EOL;
4126  }
4127  }
4128  };
4129 
4130 
4132  const std::string& model_name,
4133  std::ostream& o) {
4134  o << INDENT << "template <typename RNG>" << EOL;
4135  o << INDENT << "void write_array(RNG& base_rng__," << EOL;
4136  o << INDENT << " std::vector<double>& params_r__," << EOL;
4137  o << INDENT << " std::vector<int>& params_i__," << EOL;
4138  o << INDENT << " std::vector<double>& vars__," << EOL;
4139  o << INDENT << " bool include_tparams__ = true," << EOL;
4140  o << INDENT << " bool include_gqs__ = true," << EOL;
4141  o << INDENT << " std::ostream* pstream__ = 0) const {" << EOL;
4142  o << INDENT2 << "vars__.resize(0);" << EOL;
4143  o << INDENT2 << "stan::io::reader<double> in__(params_r__,params_i__);" << EOL;
4144  o << INDENT2 << "static const char* function__ = \""
4145  << model_name << "_namespace::write_array(%1%)\";" << EOL;
4146  suppress_warning(INDENT2, "function__", o);
4147 
4148  // declares, reads, and sets parameters
4149  generate_comment("read-transform, write parameters",2,o);
4150  write_array_visgen vis(o);
4151  for (size_t i = 0; i < prog.parameter_decl_.size(); ++i)
4152  boost::apply_visitor(vis,prog.parameter_decl_[i].decl_);
4153 
4154  // this is for all other values
4155  write_array_vars_visgen vis_writer(o);
4156 
4157  // writes parameters
4158  for (size_t i = 0; i < prog.parameter_decl_.size(); ++i)
4159  boost::apply_visitor(vis_writer,prog.parameter_decl_[i].decl_);
4160  o << EOL;
4161 
4162  o << INDENT2 << "if (!include_tparams__) return;"
4163  << EOL;
4164  generate_comment("declare and define transformed parameters",2,o);
4165  o << INDENT2 << "double lp__ = 0.0;" << EOL;
4166  suppress_warning(INDENT2, "lp__", o);
4167  o << INDENT2 << "stan::math::accumulator<double> lp_accum__;" << EOL2;
4168  bool is_var = false;
4169  bool is_fun_return = false;
4170  generate_local_var_decls(prog.derived_decl_.first,2,o,is_var,is_fun_return);
4171  o << EOL;
4172  bool include_sampling = false;
4173  generate_statements(prog.derived_decl_.second,2,o,include_sampling,
4174  is_var,is_fun_return);
4175  o << EOL;
4176 
4177  generate_comment("validate transformed parameters",2,o);
4179  o << EOL;
4180 
4181  generate_comment("write transformed parameters",2,o);
4182  for (size_t i = 0; i < prog.derived_decl_.first.size(); ++i)
4183  boost::apply_visitor(vis_writer, prog.derived_decl_.first[i].decl_);
4184  o << EOL;
4185 
4186  o << INDENT2 << "if (!include_gqs__) return;"
4187  << EOL;
4188  generate_comment("declare and define generated quantities",2,o);
4190  is_var,is_fun_return);
4191  o << EOL;
4192  generate_statements(prog.generated_decl_.second,2,o,include_sampling,
4193  is_var,is_fun_return);
4194  o << EOL;
4195 
4196  generate_comment("validate generated quantities",2,o);
4198  o << EOL;
4199 
4200  generate_comment("write generated quantities",2,o);
4201  for (size_t i = 0; i < prog.generated_decl_.first.size(); ++i)
4202  boost::apply_visitor(vis_writer, prog.generated_decl_.first[i].decl_);
4203  if (prog.generated_decl_.first.size() > 0)
4204  o << EOL;
4205 
4206  o << INDENT << "}" << EOL2;
4207 
4208  o << INDENT << "template <typename RNG>" << EOL;
4209  o << INDENT << "void write_array(RNG& base_rng," << EOL;
4210  o << INDENT << " Eigen::Matrix<double,Eigen::Dynamic,1>& params_r," << EOL;
4211  o << INDENT << " Eigen::Matrix<double,Eigen::Dynamic,1>& vars," << EOL;
4212  o << INDENT << " bool include_tparams = true," << EOL;
4213  o << INDENT << " bool include_gqs = true," << EOL;
4214  o << INDENT << " std::ostream* pstream = 0) const {" << EOL;
4215  o << INDENT << " std::vector<double> params_r_vec(params_r.size());" << EOL;
4216  o << INDENT << " for (int i = 0; i < params_r.size(); ++i)" << EOL;
4217  o << INDENT << " params_r_vec[i] = params_r(i);" << EOL;
4218  o << INDENT << " std::vector<double> vars_vec;" << EOL;
4219  o << INDENT << " std::vector<int> params_i_vec;" << EOL;
4220  o << INDENT << " write_array(base_rng,params_r_vec,params_i_vec,vars_vec,include_tparams,include_gqs,pstream);" << EOL;
4221  o << INDENT << " vars.resize(vars_vec.size());" << EOL;
4222  o << INDENT << " for (int i = 0; i < vars.size(); ++i)" << EOL;
4223  o << INDENT << " vars(i) = vars_vec[i];" << EOL;
4224  o << INDENT << "}" << EOL2;
4225 
4226  }
4227 
4228  void generate_model_name_method(const std::string& model_name,
4229  std::ostream& out) {
4230  out << INDENT << "static std::string model_name() {" << EOL
4231  << INDENT2 << "return \"" << model_name << "\";" << EOL
4232  << INDENT << "}" << EOL2;
4233  }
4234 
4235  void generate_model_typedef(const std::string& model_name,
4236  std::ostream& out) {
4237  out << "typedef " << model_name << "_namespace::" << model_name
4238  << " stan_model;" <<EOL2;
4239  }
4240 
4242  const std::string& scalar_t_name,
4243  std::ostream& out) {
4244  for (size_t d = 0; d < t.num_dims_; ++d)
4245  out << "std::vector<";
4246 
4247  bool is_template_type = false;
4248  switch (t.base_type_) {
4249  case INT_T :
4250  out << "int";
4251  is_template_type = false;
4252  break;
4253  case DOUBLE_T:
4254  out << scalar_t_name;
4255  is_template_type = false;
4256  break;
4257  case VECTOR_T:
4258  out << "Eigen::Matrix<"
4259  << scalar_t_name
4260  << ", Eigen::Dynamic,1>";
4261  is_template_type = true;
4262  break;
4263  case ROW_VECTOR_T:
4264  out << "Eigen::Matrix<"
4265  << scalar_t_name
4266  << ", 1,Eigen::Dynamic>";
4267  is_template_type = true;
4268  break;
4269  case MATRIX_T:
4270  out << "Eigen::Matrix<"
4271  << scalar_t_name
4272  << ", Eigen::Dynamic,Eigen::Dynamic>";
4273  is_template_type = true;
4274  break;
4275  case VOID_T:
4276  out << "void";
4277  break;
4278  default:
4279  out << "UNKNOWN TYPE";
4280  }
4281 
4282  for (size_t d = 0; d < t.num_dims_; ++d) {
4283  if (d > 0 || is_template_type)
4284  out << " ";
4285  out << ">";
4286  }
4287  }
4288 
4289  void generate_arg_decl(bool gen_const,
4290  bool gen_ref,
4291  const arg_decl& decl,
4292  const std::string& scalar_t_name,
4293  std::ostream& out) {
4294  if (gen_const)
4295  out << "const ";
4296  generate_bare_type(decl.arg_type_,scalar_t_name,out);
4297  if (gen_ref)
4298  out << "&";
4299  out << " " << decl.name_;
4300  }
4301 
4303  for (size_t i = 0; i < fun.arg_decls_.size(); ++i)
4304  if (fun.arg_decls_[i].arg_type_.base_type_ != INT_T)
4305  return false;
4306  return true;
4307  }
4308 
4310  bool is_lp) {
4311  size_t num_args = fun.arg_decls_.size();
4312  // nullary, non-lp
4313  if (has_only_int_args(fun) && !is_lp)
4314  return "double";
4315 
4316  // need template metaprogram to construct return
4317  std::stringstream ss;
4318  ss << "typename boost::math::tools::promote_args<";
4319  int num_open_brackets = 1;
4320  int num_generated_params = 0;
4321  for (size_t i = 0; i < num_args; ++i) {
4322  if (fun.arg_decls_[i].arg_type_.base_type_ != INT_T) {
4323  // two conditionals cut and pasted below
4324  if (num_generated_params > 0)
4325  ss << ", ";
4326  if (num_generated_params == 4) {
4327  ss << "typename boost::math::tools::promote_args<";
4328  num_generated_params = 0;
4329  ++num_open_brackets;
4330  }
4331  ss << "T" << i << "__";
4332  ++num_generated_params;
4333  }
4334  }
4335  if (is_lp) {
4336  if (num_generated_params > 0)
4337  ss << ", ";
4338  // set threshold at 4 so always room for one more param at end
4339  ss << "T_lp__";
4340  }
4341  for (int i = 0; i < num_open_brackets; ++i)
4342  ss << ">::type";
4343  return ss.str();
4344  }
4345 
4347  for (size_t i = 0; i < fun.arg_decls_.size(); ++i) {
4348  if (fun.arg_decls_[i].arg_type_.base_type_ != INT_T) {
4349  return true;
4350  }
4351  }
4352  return false;
4353  }
4354 
4355 
4357  bool is_rng,
4358  bool is_lp,
4359  bool is_log,
4360  std::ostream& out) {
4361  if (needs_template_params(fun)) {
4362  out << "template <";
4363  bool continuing_tps = false;
4364  if (is_log) {
4365  out << "bool propto";
4366  continuing_tps = true;
4367  }
4368  for (size_t i = 0; i < fun.arg_decls_.size(); ++i) {
4369  // no template parameter for int-based args
4370  if (fun.arg_decls_[i].arg_type_.base_type_ != INT_T) {
4371  if (continuing_tps)
4372  out << ", ";
4373  out << "typename T" << i << "__";
4374  continuing_tps = true;
4375  }
4376  }
4377  if (is_rng) {
4378  if (continuing_tps)
4379  out << ", ";
4380  out << "class RNG";
4381  continuing_tps = true;
4382  }
4383  else if (is_lp) {
4384  if (continuing_tps)
4385  out << ", ";
4386  out << "typename T_lp__, typename T_lp_accum__";
4387  continuing_tps = true;
4388  }
4389  out << ">" << EOL;
4390  } else { // no-arg function
4391  if (is_rng) {
4392  // nullary RNG case
4393  out << "template <class RNG>" << EOL;
4394  } else if (is_lp) {
4395  out << "template <typename T_lp__, typename T_lp_accum__>"
4396  << EOL;
4397  } else if (is_log) {
4398  out << "template <bool propto>"
4399  << EOL;
4400  }
4401  }
4402  }
4403 
4405  const std::string& scalar_t_name,
4406  std::ostream& out) {
4407  out << "inline" << EOL;
4408  generate_bare_type(fun.return_type_,scalar_t_name,out);
4409  out << EOL;
4410  }
4411 
4413  std::ostream& out) {
4414  out << fun.name_;
4415  }
4416 
4417 
4419  bool is_rng,
4420  bool is_lp,
4421  bool is_log,
4422  std::ostream& out) {
4423  // arguments
4424  out << "(";
4425  for (size_t i = 0; i < fun.arg_decls_.size(); ++i) {
4426  std::string template_type_i
4427  = "T" + boost::lexical_cast<std::string>(i) + "__";
4428  generate_arg_decl(true,true,fun.arg_decls_[i],template_type_i,out);
4429  if (i + 1 < fun.arg_decls_.size()) {
4430  out << "," << EOL << INDENT;
4431  for (size_t i = 0; i <= fun.name_.size(); ++i)
4432  out << " ";
4433  }
4434  }
4435  if ((is_rng || is_lp) && fun.arg_decls_.size() > 0)
4436  out << ", ";
4437  if (is_rng)
4438  out << "RNG& base_rng__";
4439  else if (is_lp)
4440  out << "T_lp__& lp__, T_lp_accum__& lp_accum__";
4441  if (is_rng || is_lp || fun.arg_decls_.size() > 0)
4442  out << ", ";
4443  out << "std::ostream* pstream__";
4444  out << ")";
4445  }
4446 
4448  bool is_rng,
4449  bool is_lp,
4450  bool is_log,
4451  std::ostream& out) {
4452  // arguments
4453  out << "(";
4454  for (size_t i = 0; i < fun.arg_decls_.size(); ++i) {
4455  if (i > 0)
4456  out << ", ";
4457  out << fun.arg_decls_[i].name_;
4458  }
4459  if ((is_rng || is_lp) && fun.arg_decls_.size() > 0)
4460  out << ", ";
4461  if (is_rng)
4462  out << "base_rng__";
4463  else if (is_lp)
4464  out << "lp__, lp_accum__";
4465  if (is_rng || is_lp || fun.arg_decls_.size() > 0)
4466  out << ", ";
4467  out << "pstream__";
4468  out << ")";
4469  }
4470 
4471 
4472 
4474  const std::string& scalar_t_name,
4475  std::ostream& out) {
4476  // no-op body
4477  if (fun.body_.is_no_op_statement()) {
4478  out << ";" << EOL;
4479  return;
4480  }
4481  out << " {" << EOL;
4482  out << INDENT
4483  << "typedef " << scalar_t_name << " fun_scalar_t__;"
4484  << EOL;
4485  out << INDENT
4486  << "typedef "
4487  << ((fun.return_type_.base_type_ == INT_T)
4488  ? "int" : "fun_scalar_t__")
4489  << " fun_return_scalar_t__;"
4490  << EOL;
4491  out << INDENT
4492  << "const static bool propto__ = true;"
4493  << EOL
4494  << INDENT
4495  << "(void) propto__;"
4496  << EOL;
4497  bool is_var = false;
4498  bool is_fun_return = true;
4499  bool include_sampling = true;
4500  generate_statement(fun.body_,1,out,
4501  include_sampling,is_var,is_fun_return);
4502  out << "}"
4503  << EOL;
4504  }
4506  std::ostream& out) {
4507  out << " {" << EOL;
4508  out << INDENT << "return ";
4509  out << fun.name_ << "<false>(";
4510  for (size_t i = 0; i < fun.arg_decls_.size(); ++i) {
4511  if (i > 0)
4512  out << ",";
4513  out << fun.arg_decls_[i].name_;
4514  }
4515  if (fun.arg_decls_.size() > 0)
4516  out << ", ";
4517  out << "pstream__";
4518  out << ");" << EOL;
4519  out << "}" << EOL;
4520  }
4521 
4523  const std::string& scalar_t_name,
4524  std::ostream& out) {
4525  generate_function_template_parameters(fun,false,false,false,out);
4526  generate_function_inline_return_type(fun,scalar_t_name,out);
4527  generate_function_name(fun,out);
4528  generate_function_arguments(fun,false,false,false,out);
4530  }
4531 
4544  std::ostream& out) {
4545 
4546  bool is_rng = ends_with("_rng", fun.name_);
4547  bool is_lp = ends_with("_lp", fun.name_);
4548  bool is_log = ends_with("_log", fun.name_);
4549  std::string scalar_t_name
4550  = fun_scalar_type(fun, is_lp);
4551 
4552  generate_function_template_parameters(fun,is_rng,is_lp,is_log,out);
4553  generate_function_inline_return_type(fun,scalar_t_name,out);
4554  generate_function_name(fun,out);
4555  generate_function_arguments(fun,is_rng,is_lp,is_log,out);
4556  generate_function_body(fun,scalar_t_name,out);
4557 
4558  // need a second function def for default propto=false for _log funs
4559  if (is_log)
4560  generate_propto_default_function(fun,scalar_t_name,out);
4561  out << EOL;
4562  }
4563 
4565  std::ostream& out) {
4566  if (fun.body_.is_no_op_statement())
4567  return; // forward declaration, so no functor needed
4568 
4569  bool is_rng = ends_with("_rng", fun.name_);
4570  bool is_lp = ends_with("_lp", fun.name_);
4571  bool is_log = ends_with("_log", fun.name_);
4572  std::string scalar_t_name
4573  = fun_scalar_type(fun, is_lp);
4574 
4575  out << std::endl
4576  << "struct ";
4577  generate_function_name(fun,out);
4578  out << "_functor__ {"
4579  << std::endl;
4580 
4581  generate_function_template_parameters(fun,is_rng,is_lp,is_log,out);
4582 
4583  generate_function_inline_return_type(fun,scalar_t_name,out);
4584 
4585  out << "operator()";
4586  generate_function_arguments(fun,is_rng,is_lp,is_log,out);
4587  out << " const {"
4588  << std::endl;
4589 
4590  out << INDENT
4591  << "return ";
4592  generate_function_name(fun,out);
4593  generate_functor_arguments(fun,is_rng,is_lp,is_log,out);
4594  out << ";"
4595  << std::endl;
4596 
4597  out << "}"
4598  << std::endl;
4599 
4600  out << "};"
4601  << std::endl
4602  << std::endl;
4603  }
4604 
4605 
4606  void generate_functions(const std::vector<function_decl_def>& funs,
4607  std::ostream& out) {
4608  for (size_t i = 0; i < funs.size(); ++i) {
4609  generate_function(funs[i],out);
4610  generate_function_functor(funs[i],out);
4611  }
4612  }
4613 
4614  void generate_cpp(const program& prog,
4615  const std::string& model_name,
4616  std::ostream& out) {
4618  generate_includes(out);
4619  generate_start_namespace(model_name,out);
4620  generate_usings(out);
4621  generate_typedefs(out);
4623  generate_class_decl(model_name,out);
4624  generate_private_decl(out);
4627  generate_public_decl(out);
4628  generate_constructor(prog,model_name,out);
4629  generate_destructor(model_name,out);
4630  // generate_set_param_ranges(prog.parameter_decl_,out);
4632  generate_log_prob(prog,out);
4633  generate_param_names_method(prog,out);
4634  generate_dims_method(prog,out);
4635  generate_write_array_method(prog,model_name,out);
4637  generate_write_csv_method(prog,model_name,out);
4638  generate_model_name_method(model_name,out);
4643  generate_model_typedef(model_name,out);
4644  }
4645 
4646  }
4647 
4648 }
4649 
4650 #endif
void operator()(const positive_ordered_var_decl &x) const
Definition: generator.hpp:616
generic visitor with output for extension
Definition: generator.hpp:64
void operator()(const double_var_decl &x) const
Definition: generator.hpp:1249
void operator()(const simplex_var_decl &x) const
Definition: generator.hpp:3716
void operator()(cholesky_corr_var_decl const &x) const
Definition: generator.hpp:2666
std::string family_
Definition: ast.hpp:195
Placeholder struct for boost::variant default ctors.
Definition: ast.hpp:18
void operator()(unit_vector_var_decl const &x) const
Definition: generator.hpp:880
void operator()(nil const &) const
Definition: generator.hpp:495
void generate_void_statement(const std::string &name, const size_t indent, std::ostream &o)
Definition: generator.hpp:55
void generate_function_functor(const function_decl_def &fun, std::ostream &out)
Definition: generator.hpp:4564
void operator()(corr_matrix_var_decl const &x) const
Definition: generator.hpp:532
void operator()(const row_vector_var_decl &x) const
Definition: generator.hpp:3212
void generate_initialize_array_bounded(const D &x, const std::string &base_type, const std::string &read_fun_prefix, const std::vector< expression > &dim_args) const
Definition: generator.hpp:3868
void generate_begin_for_dims(const std::vector< expression > &dims) const
Definition: generator.hpp:790
void generate_statements(const std::vector< statement > &ss, int indent, std::ostream &o, bool include_sampling, bool is_var, bool is_fun_return)
Definition: generator.hpp:1756
void operator()(vector_var_decl const &x) const
Definition: generator.hpp:1021
void generate_expression(const expression &e, std::ostream &o)
Definition: generator.hpp:249
void operator()(simplex_var_decl const &x) const
Definition: generator.hpp:883
void operator()(unit_vector_var_decl const &x) const
Definition: generator.hpp:1335
void operator()(vector_var_decl const &x) const
Definition: generator.hpp:502
void operator()(cholesky_corr_var_decl const &x) const
Definition: generator.hpp:1439
void operator()(const double_var_decl &x) const
Definition: generator.hpp:581
bool is_no_op_statement() const
Definition: ast_def.cpp:1286
void operator()(const corr_matrix_var_decl &x) const
Definition: generator.hpp:1282
void generate_initialization(std::ostream &o, const std::string &var_name, const std::string &base_type, const std::vector< expression > &dims, const expression &type_arg1=expression(), const expression &type_arg2=expression())
Definition: generator.hpp:469
void write_array(const std::string &name, const std::vector< expression > &arraydims, const std::vector< expression > &matdims) const
Definition: generator.hpp:4082
bool ends_with(const std::string &suffix, const std::string &s)
Definition: ast_def.cpp:1477
void generate_buffer_loop(const std::string &base_type, const std::string &name, const std::vector< expression > &dims, const expression &dim1=expression(), const expression &dim2=expression(), int indent=2U) const
Definition: generator.hpp:2722
void generate_dims_loop_fwd(const std::vector< expression > &dims, int indent=2U) const
Definition: generator.hpp:2765
void operator()(nil const &) const
Definition: generator.hpp:815
std::pair< std::vector< var_decl >, std::vector< statement > > derived_data_decl_
Definition: ast.hpp:799
void operator()(const cholesky_factor_var_decl &x) const
Definition: generator.hpp:3078
void suppress_warning(const std::string &indent, const std::string &var_name, std::ostream &o)
Definition: generator.hpp:2304
std::vector< expression > conditions_
Definition: ast.hpp:730
const std::vector< expression > EMPTY_EXP_VECTOR(0)
void operator()(const positive_ordered_var_decl &x) const
Definition: generator.hpp:1270
void operator()(const double_var_decl &x) const
Definition: generator.hpp:2835
void generate_type(const std::string &type, size_t num_dims) const
Definition: generator.hpp:1124
void operator()(cov_matrix_var_decl const &x) const
Definition: generator.hpp:954
static void print_string_literal(std::ostream &o, const std::string &s)
Definition: generator.hpp:254
std::vector< expression > dims_
Definition: ast.hpp:430
base_expr_type base_type_
Definition: ast.hpp:75
void generate_model_name_method(const std::string &model_name, std::ostream &out)
Definition: generator.hpp:4228
void operator()(double_var_decl const &x) const
Definition: generator.hpp:499
void generate_param_names_array(const std::vector< expression > &matrix_dims, const std::string &name, const std::vector< expression > &dims) const
Definition: generator.hpp:3268
void operator()(row_vector_var_decl const &x) const
Definition: generator.hpp:862
variable_dims var_dims_
Definition: ast.hpp:829
void operator()(const unit_vector_var_decl &x) const
Definition: generator.hpp:1261
void operator()(const cholesky_factor_var_decl &x) const
Definition: generator.hpp:3601
void generate_validate_transformed_params(const std::vector< var_decl > &vs, int indent, std::ostream &o)
Definition: generator.hpp:1504
void operator()(row_vector_var_decl const &x) const
Definition: generator.hpp:963
void generate_using(const std::string &type, std::ostream &o)
Definition: generator.hpp:288
void operator()(const int_var_decl &x) const
Definition: generator.hpp:3862
statement_visgen(size_t indent, bool include_sampling, bool is_var, bool is_fun_return, std::ostream &o)
Definition: generator.hpp:1523
bool is_user_defined_prob_function(const std::string &name, const expression &variate, const std::vector< expression > &params)
Definition: ast_def.cpp:1439
statement statement_
Definition: ast.hpp:803
void operator()(const row_vector_var_decl &x) const
Definition: generator.hpp:1255
void operator()(cholesky_corr_var_decl const &x) const
Definition: generator.hpp:1355
void operator()(double_var_decl const &x) const
Definition: generator.hpp:1393
void operator()(const nil &) const
Definition: generator.hpp:3696
void operator()(const unit_vector_var_decl &x) const
Definition: generator.hpp:2854
const int DOUBLE_T
Definition: ast.hpp:66
void operator()(nil const &) const
Definition: generator.hpp:415
void operator()(const positive_ordered_var_decl &x) const
Definition: generator.hpp:3389
std::string name_
Definition: ast.hpp:769
void generate_functions(const std::vector< function_decl_def > &funs, std::ostream &out)
Definition: generator.hpp:4606
void operator()(const row_vector_var_decl &x) const
Definition: generator.hpp:2843
const std::string INDENT3(" ")
void operator()(const cholesky_corr_var_decl &x) const
Definition: generator.hpp:3249
void operator()(row_vector_var_decl const &x) const
Definition: generator.hpp:1422
void operator()(expression const &x) const
Definition: generator.hpp:1548
void operator()(const cholesky_corr_var_decl &x) const
Definition: generator.hpp:2983
expression expr_
Definition: ast.hpp:830
void generate_var_resizing(const std::vector< var_decl > &vs, std::ostream &o)
Definition: generator.hpp:537
void generate_propto_default_function(const function_decl_def &fun, const std::string &scalar_t_name, std::ostream &out)
Definition: generator.hpp:4522
void operator()(const vector_var_decl &x) const
Definition: generator.hpp:2838
void generate_set_param_ranges(const std::vector< var_decl > &var_decls, std::ostream &o)
Definition: generator.hpp:2505
var_size_validating_visgen var_size_validator_
Definition: generator.hpp:2561
void operator()(int_var_decl const &x) const
Definition: generator.hpp:1315
void operator()(simplex_var_decl const &x) const
Definition: generator.hpp:939
void operator()(const positive_ordered_var_decl &x) const
Definition: generator.hpp:3596
void generate_init_args(const std::string &type, const std::vector< expression > &ctor_args, const std::vector< expression > &dims, size_t dim) const
Definition: generator.hpp:1142
void operator()(const unit_vector_var_decl &x) const
Definition: generator.hpp:2368
void generate_increment(expression K, std::vector< expression > dims) const
Definition: generator.hpp:2480
void operator()(simplex_var_decl const &x) const
Definition: generator.hpp:511
void operator()(const unit_vector_var_decl &x) const
Definition: generator.hpp:3374
void generate_check_double(const std::string &name, size_t) const
Definition: generator.hpp:2784
void operator()(cov_matrix_var_decl const &x) const
Definition: generator.hpp:1359
void operator()(cholesky_corr_var_decl const &x) const
Definition: generator.hpp:526
void operator()(ordered_var_decl const &x) const
Definition: generator.hpp:514
void generate_validate_context_size(std::ostream &o, const std::string &stage, const std::string &var_name, const std::string &base_type, const std::vector< expression > &dims, const expression &type_arg1=expression(), const expression &type_arg2=expression())
Definition: generator.hpp:380
void operator()(row_vector_var_decl const &x) const
Definition: generator.hpp:425
void operator()(const corr_matrix_var_decl &x) const
Definition: generator.hpp:3439
void generate_member_var_decls(const std::vector< var_decl > &vs, int indent, std::ostream &o)
Definition: generator.hpp:987
void generate_printable(const printable &p, std::ostream &o)
Definition: generator.hpp:283
bool has_low() const
Definition: ast_def.cpp:937
expression high_
Definition: ast.hpp:403
void operator()(positive_ordered_var_decl const &x) const
Definition: generator.hpp:889
write_dims_visgen(std::ostream &o)
Definition: generator.hpp:2828
void operator()(const cholesky_factor_var_decl &x) const
Definition: generator.hpp:2980
const std::string INDENT(" ")
void operator()(const unit_vector_var_decl &x) const
Definition: generator.hpp:3713
void generate_local_var_init_nan(const std::vector< var_decl > &vs, int indent, std::ostream &o, bool is_var, bool is_fun_return)
Definition: generator.hpp:1295
std::pair< std::vector< var_decl >, std::vector< statement > > generated_decl_
Definition: ast.hpp:804
void write_array(const std::string &name, const std::vector< expression > &dims) const
Definition: generator.hpp:3737
void operator()(const int_var_decl &x) const
Definition: generator.hpp:3698
void operator()(cholesky_factor_var_decl const &x) const
Definition: generator.hpp:948
void operator()(corr_matrix_var_decl const &x) const
Definition: generator.hpp:1113
const int ROW_VECTOR_T
Definition: ast.hpp:68
void operator()(ordered_var_decl const &x) const
Definition: generator.hpp:434
void operator()(nil const &) const
Definition: generator.hpp:1314
void operator()(const corr_matrix_var_decl &x) const
Definition: generator.hpp:3945
std::vector< var_decl > data_decl_
Definition: ast.hpp:797
void generate_dims_method(const program &prog, std::ostream &o)
Definition: generator.hpp:2920
generate_init_vars_visgen(int indent, std::ostream &o)
Definition: generator.hpp:1309
void operator()(const cov_matrix_var_decl &x) const
Definition: generator.hpp:1279
void operator()(const cholesky_corr_var_decl &x) const
Definition: generator.hpp:4064
void operator()(int_var_decl const &x) const
Definition: generator.hpp:1841
void operator()(cholesky_factor_var_decl const &x) const
Definition: generator.hpp:523
void operator()(const matrix_var_decl &x) const
Definition: generator.hpp:1258
void operator()(const unit_vector_var_decl &x) const
Definition: generator.hpp:3223
void generate_include(const std::string &lib_name, std::ostream &o)
Definition: generator.hpp:323
void operator()(const simplex_var_decl &x) const
Definition: generator.hpp:3586
void generate_arg_decl(bool gen_const, bool gen_ref, const arg_decl &decl, const std::string &scalar_t_name, std::ostream &out)
Definition: generator.hpp:4289
void operator()(corr_matrix_var_decl const &x) const
Definition: generator.hpp:901
write_csv_visgen(std::ostream &o)
Definition: generator.hpp:3532
void generate_check_int(const std::string &name, size_t) const
Definition: generator.hpp:2776
void operator()(const simplex_var_decl &x) const
Definition: generator.hpp:2379
void operator()(ordered_var_decl const &x) const
Definition: generator.hpp:1343
void generate_constructor(const program &prog, const std::string &model_name, std::ostream &o)
Definition: generator.hpp:2517
void operator()(simplex_var_decl const &x) const
Definition: generator.hpp:1339
void operator()(const ordered_var_decl &x) const
Definition: generator.hpp:3068
void operator()(const int_var_decl &x) const
Definition: generator.hpp:578
void operator()(matrix_var_decl const &x) const
Definition: generator.hpp:1427
void operator()(const double_var_decl &x) const
Definition: generator.hpp:3889
void operator()(cov_matrix_var_decl const &x) const
Definition: generator.hpp:449
void operator()(const nil &) const
Definition: generator.hpp:4014
void operator()(const int_var_decl &x) const
Definition: generator.hpp:2832
void operator()(const matrix_var_decl &x) const
Definition: generator.hpp:3710
void operator()(const row_vector_var_decl &x) const
Definition: generator.hpp:3570
void generate_increment(std::vector< expression > dims) const
Definition: generator.hpp:2468
void generate_name_dims(const std::string name, size_t num_dims) const
Definition: generator.hpp:2697
void operator()(const vector_var_decl &x) const
Definition: generator.hpp:2359
void operator()(const positive_ordered_var_decl &x) const
Definition: generator.hpp:3924
void generate_unconstrained_param_names_method(const program &prog, std::ostream &o)
Definition: generator.hpp:3491
void operator()(positive_ordered_var_decl const &x) const
Definition: generator.hpp:2069
void operator()(sample const &x) const
Definition: generator.hpp:1553
void generate_function_name(const function_decl_def &fun, std::ostream &out)
Definition: generator.hpp:4412
void operator()(const matrix_var_decl &x) const
Definition: generator.hpp:2365
void operator()(const row_vector_var_decl &x) const
Definition: generator.hpp:2362
void generate_initialize_array_bounded(const D &x, const std::string &base_type, const std::string &read_fun_prefix, const std::vector< expression > &dim_args) const
Definition: generator.hpp:3536
bool has_ub(const D &x)
Definition: generator.hpp:35
void operator()(const int_var_decl &x) const
Definition: generator.hpp:2953
void generate_constrained_param_names_method(const program &prog, std::ostream &o)
Definition: generator.hpp:3308
void generate_function(const function_decl_def &fun, std::ostream &out)
Generate the specified function and optionally its default for propto=false for functions ending in _...
Definition: generator.hpp:4543
void generate_function_template_parameters(const function_decl_def &fun, bool is_rng, bool is_lp, bool is_log, std::ostream &out)
Definition: generator.hpp:4356
write_csv_header_visgen(std::ostream &o)
Definition: generator.hpp:3032
void generate_local_var_inits(std::vector< var_decl > vs, bool is_var, bool declare_vars, std::ostream &o)
Definition: generator.hpp:758
void operator()(const positive_ordered_var_decl &x) const
Definition: generator.hpp:4053
expression return_value_
Definition: ast.hpp:758
void generate_validate_var_decls(const std::vector< var_decl > decls, int indent, std::ostream &o)
Definition: generator.hpp:914
void operator()(matrix_var_decl const &x) const
Definition: generator.hpp:1331
void operator()(const vector_var_decl &x) const
Definition: generator.hpp:3565
void operator()(const cov_matrix_var_decl &x) const
Definition: generator.hpp:3940
void operator()(const reject_statement &ps) const
Definition: generator.hpp:1673
generate_local_var_init_nan_visgen(bool declare_vars, bool is_var, bool is_fun_return, int indent, std::ostream &o)
Definition: generator.hpp:1232
void operator()(const unit_vector_var_decl &x) const
Definition: generator.hpp:3909
void generate_destructor(const std::string &model_name, std::ostream &o)
Definition: generator.hpp:2320
void generate_indent(size_t indent, std::ostream &o)
Definition: generator.hpp:50
void operator()(corr_matrix_var_decl const &x) const
Definition: generator.hpp:452
void operator()(const positive_ordered_var_decl &x) const
Definition: generator.hpp:2869
void operator()(const nil &) const
Definition: generator.hpp:3035
void operator()(double_var_decl const &x) const
Definition: generator.hpp:1871
void generate_initialize_array(const std::string &var_type, const std::string &read_type, const std::vector< expression > &read_args, const std::string &name, const std::vector< expression > &dims) const
Definition: generator.hpp:3950
var_size_validating_visgen(std::ostream &o, const std::string &stage)
Definition: generator.hpp:411
dump_member_var_visgen(std::ostream &o)
Definition: generator.hpp:1835
void operator()(const matrix_var_decl &x) const
Definition: generator.hpp:595
void operator()(const positive_ordered_var_decl &x) const
Definition: generator.hpp:3722
void generate_validate_var_decl(const var_decl &decl, int indent, std::ostream &o)
Definition: generator.hpp:907
void operator()(vector_var_decl const &x) const
Definition: generator.hpp:1323
std::string to_string(T i)
Definition: generator.hpp:44
void operator()(const positive_ordered_var_decl &x) const
Definition: generator.hpp:3073
void generate_dims_array(const std::vector< expression > &matrix_dims_exprs, const std::vector< expression > &array_dims_exprs) const
Definition: generator.hpp:2899
void operator()(positive_ordered_var_decl const &x) const
Definition: generator.hpp:945
void generate_param_names_array(const std::vector< expression > &matrix_dims, const std::string &name, const std::vector< expression > &dims) const
Definition: generator.hpp:3452
void operator()(const double_var_decl &x) const
Definition: generator.hpp:3355
void operator()(const simplex_var_decl &x) const
Definition: generator.hpp:3063
void operator()(const simplex_var_decl &x) const
Definition: generator.hpp:3914
void generate_bare_type(const expr_type &t, const std::string &scalar_t_name, std::ostream &out)
Definition: generator.hpp:4241
var_resizing_visgen var_resizer_
Definition: generator.hpp:1833
init_local_var_visgen(bool declare_vars, bool is_var, std::ostream &o)
Definition: generator.hpp:549
void generate_model_typedef(const std::string &model_name, std::ostream &out)
Definition: generator.hpp:4235
void operator()(unit_vector_var_decl const &x) const
Definition: generator.hpp:936
void operator()(const cholesky_factor_var_decl &x) const
Definition: generator.hpp:621
void operator()(const cholesky_corr_var_decl &x) const
Definition: generator.hpp:628
void generate_functor_arguments(const function_decl_def &fun, bool is_rng, bool is_lp, bool is_log, std::ostream &out)
Definition: generator.hpp:4447
void operator()(const matrix_var_decl &x) const
Definition: generator.hpp:4032
void operator()(const int_var_decl &x) const
Definition: generator.hpp:4016
void operator()(const increment_log_prob_statement &x) const
Definition: generator.hpp:1632
void operator()(const cov_matrix_var_decl &x) const
Definition: generator.hpp:4070
void operator()(const cholesky_corr_var_decl &x) const
Definition: generator.hpp:3084
expression expr_
Definition: ast.hpp:819
void generate_indexed_expr(const std::string &expr, const std::vector< expression > indexes, base_expr_type base_type, size_t e_num_dims, std::ostream &o)
Definition: generator.hpp:87
void generate_function_inline_return_type(const function_decl_def &fun, const std::string &scalar_t_name, std::ostream &out)
Definition: generator.hpp:4404
void operator()(unit_vector_var_decl const &x) const
Definition: generator.hpp:1050
base_expr_type base_type_
Definition: ast.hpp:431
void operator()(const cov_matrix_var_decl &x) const
Definition: generator.hpp:2428
void operator()(const cov_matrix_var_decl &x) const
Definition: generator.hpp:3255
expression_t expr_
Definition: ast.hpp:252
void operator()(simplex_var_decl const &x) const
Definition: generator.hpp:2638
void operator()(const cov_matrix_var_decl &x) const
Definition: generator.hpp:637
void operator()(positive_ordered_var_decl const &x) const
Definition: generator.hpp:1347
std::vector< var_decl > parameter_decl_
Definition: ast.hpp:800
bool needs_template_params(const function_decl_def &fun)
Definition: generator.hpp:4346
void operator()(simplex_var_decl const &x) const
Definition: generator.hpp:431
size_t num_dims_
Definition: ast.hpp:76
void generate_function_body(const function_decl_def &fun, const std::string &scalar_t_name, std::ostream &out)
Definition: generator.hpp:4473
void operator()(positive_ordered_var_decl const &x) const
Definition: generator.hpp:1074
void operator()(matrix_var_decl const &x) const
Definition: generator.hpp:440
write_array_vars_visgen(std::ostream &o)
Definition: generator.hpp:4011
void operator()(const std::string &s) const
Definition: generator.hpp:274
void operator()(const vector_var_decl &x) const
Definition: generator.hpp:3893
void operator()(const corr_matrix_var_decl &x) const
Definition: generator.hpp:3096
void operator()(const double_var_decl &x) const
Definition: generator.hpp:2956
void operator()(const ordered_var_decl &x) const
Definition: generator.hpp:3591
void generate_initialize_array(const std::string &var_type, const std::string &read_type, const std::vector< expression > &read_args, const std::string &name, const std::vector< expression > &dims) const
Definition: generator.hpp:649
void generate_propto_default_function_body(const function_decl_def &fun, std::ostream &out)
Definition: generator.hpp:4505
void operator()(const cov_matrix_var_decl &x) const
Definition: generator.hpp:2986
std::vector< statement > bodies_
Definition: ast.hpp:731
void operator()(row_vector_var_decl const &x) const
Definition: generator.hpp:1327
void operator()(const corr_matrix_var_decl &x) const
Definition: generator.hpp:643
expression condition_
Definition: ast.hpp:738
void operator()(const cov_matrix_var_decl &x) const
Definition: generator.hpp:3090
void operator()(double_var_decl const &x) const
Definition: generator.hpp:419
void operator()(const vector_var_decl &x) const
Definition: generator.hpp:585
void operator()(const ordered_var_decl &x) const
Definition: generator.hpp:2974
void generate_indent_num_dims(size_t base_indent, const std::vector< expression > &dims, const expression &dim1, const expression &dim2) const
Definition: generator.hpp:2714
void operator()(const double_var_decl &x) const
Definition: generator.hpp:2356
void generate_write_loop(const std::string &write_method_name, const std::string &var_name, const std::vector< expression > &dims) const
Definition: generator.hpp:2687
void operator()(int_var_decl const &x) const
Definition: generator.hpp:2567
write_array_visgen(std::ostream &o)
Definition: generator.hpp:3858
void operator()(const simplex_var_decl &x) const
Definition: generator.hpp:606
void operator()(const cholesky_corr_var_decl &x) const
Definition: generator.hpp:3728
void operator()(cholesky_factor_var_decl const &x) const
Definition: generator.hpp:2659
bool has_only_int_args(const function_decl_def &fun)
Definition: generator.hpp:4302
void operator()(const cov_matrix_var_decl &x) const
Definition: generator.hpp:2886
void operator()(unit_vector_var_decl const &x) const
Definition: generator.hpp:428
void generate_typedef(const std::string &type, const std::string &abbrev, std::ostream &o)
Definition: generator.hpp:310
void operator()(const ordered_var_decl &x) const
Definition: generator.hpp:3719
void operator()(cov_matrix_var_decl const &x) const
Definition: generator.hpp:2267
void operator()(row_vector_var_decl const &x) const
Definition: generator.hpp:2615
const std::string MINOR_VERSION
Minor version number for Stan package.
Definition: version.hpp:12
void operator()(double_var_decl const &x) const
Definition: generator.hpp:856
void operator()(vector_var_decl const &x) const
Definition: generator.hpp:859
const int VECTOR_T
Definition: ast.hpp:67
std::pair< std::vector< var_decl >, std::vector< statement > > derived_decl_
Definition: ast.hpp:802
std::ostream & o_
Definition: generator.hpp:66
void operator()(cov_matrix_var_decl const &x) const
Definition: generator.hpp:529
void operator()(const matrix_var_decl &x) const
Definition: generator.hpp:3052
const int MATRIX_T
Definition: ast.hpp:69
void generate_end_namespace(std::ostream &o)
Definition: generator.hpp:75
void operator()(cov_matrix_var_decl const &x) const
Definition: generator.hpp:1445
void generate_class_decl(const std::string &model_name, std::ostream &o)
Definition: generator.hpp:339
void operator()(const cholesky_corr_var_decl &x) const
Definition: generator.hpp:1276
void dims(const T &x, std::vector< int > &result)
Definition: dims.hpp:13
void operator()(const row_vector_var_decl &x) const
Definition: generator.hpp:590
void generate_includes(std::ostream &o)
Definition: generator.hpp:327
void operator()(unit_vector_var_decl const &x) const
Definition: generator.hpp:508
void operator()(cov_matrix_var_decl const &x) const
Definition: generator.hpp:1102
expression low_
Definition: ast.hpp:402
void operator()(const simplex_var_decl &x) const
Definition: generator.hpp:2859
void generate_cpp(const program &prog, const std::string &model_name, std::ostream &out)
Definition: generator.hpp:4614
void operator()(matrix_var_decl const &x) const
Definition: generator.hpp:2623
void operator()(const cov_matrix_var_decl &x) const
Definition: generator.hpp:3731
void operator()(const simplex_var_decl &x) const
Definition: generator.hpp:3379
void operator()(unit_vector_var_decl const &x) const
Definition: generator.hpp:1967
printable_t printable_
Definition: ast.hpp:267
void operator()(const row_vector_var_decl &x) const
Definition: generator.hpp:3047
std::vector< expression > dims_
Definition: ast.hpp:290
void generate_csv_header_array(const std::vector< expression > &matrix_dims, const std::string &name, const std::vector< expression > &dims) const
Definition: generator.hpp:3103
void operator()(vector_var_decl const &x) const
Definition: generator.hpp:1899
void operator()(const vector_var_decl &x) const
Definition: generator.hpp:3207
void operator()(const ordered_var_decl &x) const
Definition: generator.hpp:2390
void operator()(const positive_ordered_var_decl &x) const
Definition: generator.hpp:3238
void generate_typedefs(std::ostream &o)
Definition: generator.hpp:316
void operator()(const matrix_var_decl &x) const
Definition: generator.hpp:3368
void operator()(const unit_vector_var_decl &x) const
Definition: generator.hpp:2968
void operator()(const int_var_decl &x) const
Definition: generator.hpp:2333
void generate_local_var_decls(const std::vector< var_decl > &vs, int indent, std::ostream &o, bool is_var, bool is_fun_return)
Definition: generator.hpp:1215
statement statement_
Definition: ast.hpp:721
void operator()(const cholesky_factor_var_decl &x) const
Definition: generator.hpp:2874
void generate_function_arguments(const function_decl_def &fun, bool is_rng, bool is_lp, bool is_log, std::ostream &out)
Definition: generator.hpp:4418
std::string function_args(const std::string &fun_prefix, const D &x) const
Definition: generator.hpp:2575
std::string name_
Definition: ast.hpp:289
void validate_array(const std::string &name, const std::vector< expression > &dims, size_t matrix_dims) const
Definition: generator.hpp:1457
void operator()(const row_vector_var_decl &x) const
Definition: generator.hpp:3363
void operator()(const simplex_var_decl &x) const
Definition: generator.hpp:1264
void operator()(const cholesky_corr_var_decl &x) const
Definition: generator.hpp:2880
void operator()(ordered_var_decl const &x) const
Definition: generator.hpp:942
validate_var_decl_visgen(int indents, std::ostream &o)
Definition: generator.hpp:785
void operator()(row_vector_var_decl const &x) const
Definition: generator.hpp:505
void generate_version_comment(std::ostream &o)
Definition: generator.hpp:334
void operator()(positive_ordered_var_decl const &x) const
Definition: generator.hpp:517
void operator()(vector_var_decl const &x) const
Definition: generator.hpp:422
void operator()(matrix_var_decl const &x) const
Definition: generator.hpp:520
void operator()(const double_var_decl &x) const
Definition: generator.hpp:3039
void operator()(corr_matrix_var_decl const &x) const
Definition: generator.hpp:957
void operator()(const cholesky_factor_var_decl &x) const
Definition: generator.hpp:1273
void operator()(simplex_var_decl const &x) const
Definition: generator.hpp:1058
void operator()(const row_vector_var_decl &x) const
Definition: generator.hpp:2962
void operator()(positive_ordered_var_decl const &x) const
Definition: generator.hpp:2652
void generate_initialize_array(const std::string &var_type, const std::string &read_type, const std::vector< expression > &read_args, const std::string &name, const std::vector< expression > &dims) const
Definition: generator.hpp:3622
void operator()(ordered_var_decl const &x) const
Definition: generator.hpp:886
validate_transformed_params_visgen(int indents, std::ostream &o)
Definition: generator.hpp:1383
void operator()(const int_var_decl &x) const
Definition: generator.hpp:3352
static void print_quoted_expression(std::ostream &o, const expression &e)
Definition: generator.hpp:265
std::vector< arg_decl > arg_decls_
Definition: ast.hpp:784
write_param_names_visgen(std::ostream &o)
Definition: generator.hpp:2949
void operator()(corr_matrix_var_decl const &x) const
Definition: generator.hpp:1363
void operator()(vector_var_decl const &x) const
Definition: generator.hpp:2607
void operator()(const while_statement &x) const
Definition: generator.hpp:1708
void operator()(const cholesky_corr_var_decl &x) const
Definition: generator.hpp:1093
void operator()(cholesky_factor_var_decl const &x) const
Definition: generator.hpp:1433
void operator()(int_var_decl const &x) const
Definition: generator.hpp:496
std::string name_
Definition: ast.hpp:429
var_resizing_visgen(std::ostream &o)
Definition: generator.hpp:492
void operator()(nil const &) const
Definition: generator.hpp:1009
void operator()(const corr_matrix_var_decl &x) const
Definition: generator.hpp:3734
void operator()(positive_ordered_var_decl const &x) const
Definition: generator.hpp:437
void operator()(cholesky_factor_var_decl const &x) const
Definition: generator.hpp:892
void operator()(vector_var_decl const &x) const
Definition: generator.hpp:960
void operator()(unit_vector_var_decl const &x) const
Definition: generator.hpp:1402
set_param_ranges_visgen(std::ostream &o)
Definition: generator.hpp:2329
void generate_statement(statement const &s, int indent, std::ostream &o, bool include_sampling, bool is_var, bool is_fun_return)
Definition: generator.hpp:1746
void operator()(matrix_var_decl const &x) const
Definition: generator.hpp:1039
write_csv_vars_visgen(std::ostream &o)
Definition: generator.hpp:3693
void operator()(ordered_var_decl const &x) const
Definition: generator.hpp:1412
void generate_increment_i(std::vector< expression > dims) const
Definition: generator.hpp:2456
void operator()(const nil &) const
Definition: generator.hpp:3556
void operator()(const vector_var_decl &x) const
Definition: generator.hpp:4022
void operator()(cholesky_corr_var_decl const &x) const
Definition: generator.hpp:2222
void operator()(const positive_ordered_var_decl &x) const
Definition: generator.hpp:2977
void operator()(simplex_var_decl const &x) const
Definition: generator.hpp:2001
void operator()(cholesky_factor_var_decl const &x) const
Definition: generator.hpp:2177
void operator()(const cholesky_factor_var_decl &x) const
Definition: generator.hpp:3394
void generate_param_names_method(const program &prog, std::ostream &o)
Definition: generator.hpp:3001
void operator()(corr_matrix_var_decl const &x) const
Definition: generator.hpp:2680
void operator()(cholesky_factor_var_decl const &x) const
Definition: generator.hpp:1351
void operator()(const int_var_decl &x) const
Definition: generator.hpp:3557
void operator()(double_var_decl const &x) const
Definition: generator.hpp:1014
void operator()(const unit_vector_var_decl &x) const
Definition: generator.hpp:3058
void operator()(int_var_decl const &x) const
Definition: generator.hpp:853
void operator()(matrix_var_decl const &x) const
Definition: generator.hpp:2103
void operator()(ordered_var_decl const &x) const
Definition: generator.hpp:2035
void operator()(corr_matrix_var_decl const &x) const
Definition: generator.hpp:2141
void generate_type(const std::string &base_type, const std::vector< expression > &, size_t end, std::ostream &o)
Definition: generator.hpp:126
void operator()(const matrix_var_decl &x) const
Definition: generator.hpp:2848
void operator()(simplex_var_decl const &x) const
Definition: generator.hpp:1407
void operator()(const corr_matrix_var_decl &x) const
Definition: generator.hpp:3617
void generate_using_namespace(const std::string &ns, std::ostream &o)
Definition: generator.hpp:292
void operator()(const nil &) const
Definition: generator.hpp:2831
var_size_validating_visgen var_size_validator_
Definition: generator.hpp:1834
void operator()(const int_var_decl &x) const
Definition: generator.hpp:3201
void generate_declaration(const std::string &name, const std::string &base_type, const std::vector< expression > &dims, const expression &type_arg1=expression(), const expression &type_arg2=expression()) const
Definition: generator.hpp:2703
void generate_log_prob(program const &p, std::ostream &o)
Definition: generator.hpp:1768
void generate_member_var_inits(const std::vector< var_decl > &vs, std::ostream &o)
Definition: generator.hpp:2313
const std::string EOL2("\n\n")
void operator()(row_vector_var_decl const &x) const
Definition: generator.hpp:1029
void operator()(nil const &) const
Definition: generator.hpp:929
void operator()(int_var_decl const &x) const
Definition: generator.hpp:930
void generate_start_namespace(std::string name, std::ostream &o)
Definition: generator.hpp:70
void generate_initialize_array_bounded(const D &x, const std::string &base_type, const std::string &read_fun_prefix, const std::vector< expression > &dim_args) const
Definition: generator.hpp:557
void operator()(const cholesky_factor_var_decl &x) const
Definition: generator.hpp:4058
void declare_array(std::string const &type, std::string const &name, size_t size) const
Definition: generator.hpp:969
void basic_validate(T const &x) const
Definition: generator.hpp:817
void operator()(const corr_matrix_var_decl &x) const
Definition: generator.hpp:2443
void operator()(const no_op_statement &) const
Definition: generator.hpp:1742
void operator()(vector_var_decl const &x) const
Definition: generator.hpp:1397
visgen(std::ostream &o)
Definition: generator.hpp:67
void operator()(const corr_matrix_var_decl &x) const
Definition: generator.hpp:4076
local_var_decl_visgen(int indents, bool is_var, bool is_fun_return, std::ostream &o)
Definition: generator.hpp:1000
void operator()(const cholesky_corr_var_decl &x) const
Definition: generator.hpp:3607
void operator()(const vector_var_decl &x) const
Definition: generator.hpp:3704
void generate_comment(std::string const &msg, int indent, std::ostream &o)
Definition: generator.hpp:79
void operator()(const cholesky_factor_var_decl &x) const
Definition: generator.hpp:3929
int base_expr_type
Definition: ast.hpp:60
void generate_end_for_dims(size_t dims_size) const
Definition: generator.hpp:802
void operator()(const ordered_var_decl &x) const
Definition: generator.hpp:1267
bool is_nil(const expression &e)
Definition: ast_def.cpp:768
statement_t statement_
Definition: ast.hpp:650
void operator()(const nil &) const
Definition: generator.hpp:577
void operator()(const unit_vector_var_decl &x) const
Definition: generator.hpp:601
double e()
Return the base of the natural logarithm.
Definition: constants.hpp:86
void operator()(const int_var_decl &x) const
Definition: generator.hpp:1246
void operator()(cholesky_factor_var_decl const &x) const
Definition: generator.hpp:443
void operator()(cholesky_corr_var_decl const &x) const
Definition: generator.hpp:446
var_decl_t decl_
Definition: ast.hpp:609
void declare_array(const std::string &type, const std::vector< expression > &ctor_args, const std::string &name, const std::vector< expression > &dims) const
Definition: generator.hpp:1189
void operator()(const nil &) const
Definition: generator.hpp:3200
void operator()(const return_statement &rs) const
Definition: generator.hpp:1685
printable_visgen(std::ostream &o)
Definition: generator.hpp:273
void operator()(row_vector_var_decl const &x) const
Definition: generator.hpp:1933
std::string variable_
Definition: ast.hpp:719
void operator()(int_var_decl const &x) const
Definition: generator.hpp:1010
void operator()(const simplex_var_decl &x) const
Definition: generator.hpp:3228
void generate_write_csv_method(const program &prog, const std::string &model_name, std::ostream &o)
Definition: generator.hpp:3771
std::vector< function_decl_def > function_decl_defs_
Definition: ast.hpp:796
void operator()(cholesky_corr_var_decl const &x) const
Definition: generator.hpp:895
range truncation_
Definition: ast.hpp:821
std::vector< printable > printables_
Definition: ast.hpp:752
int size(const std::vector< T > &x)
Definition: size.hpp:11
void operator()(const nil &) const
Definition: generator.hpp:2332
bool is_ill_formed() const
Definition: ast_def.cpp:105
void generate_end_class_decl(std::ostream &o)
Definition: generator.hpp:344
void operator()(int_var_decl const &x) const
Definition: generator.hpp:416
void operator()(cov_matrix_var_decl const &x) const
Definition: generator.hpp:2673
bool has_high() const
Definition: ast_def.cpp:940
void operator()(const double_var_decl &x) const
Definition: generator.hpp:3204
void generate_initializer(std::ostream &o, const std::string &base_type, const std::vector< expression > &dims, const expression &type_arg1=expression(), const expression &type_arg2=expression())
Definition: generator.hpp:348
void generate_void_statement(const std::string &name) const
Definition: generator.hpp:1135
void operator()(const simplex_var_decl &x) const
Definition: generator.hpp:4043
void generate_increment(expression M, expression N, std::vector< expression > dims) const
Definition: generator.hpp:2491
void generate_usings(std::ostream &o)
Definition: generator.hpp:297
const int INT_T
Definition: ast.hpp:65
void operator()(assignment const &x) const
Definition: generator.hpp:1536
void operator()(ordered_var_decl const &x) const
Definition: generator.hpp:1066
base_var_decl var_type_
Definition: ast.hpp:831
void operator()(const cholesky_factor_var_decl &x) const
Definition: generator.hpp:3725
void operator()(matrix_var_decl const &x) const
Definition: generator.hpp:966
void operator()(const cov_matrix_var_decl &x) const
Definition: generator.hpp:3426
void operator()(const conditional_statement &x) const
Definition: generator.hpp:1718
void generate_loop_var(const std::string &name, size_t dims_size) const
Definition: generator.hpp:809
void operator()(nil const &) const
Definition: generator.hpp:1534
void operator()(const row_vector_var_decl &x) const
Definition: generator.hpp:3707
void operator()(const ordered_var_decl &x) const
Definition: generator.hpp:3384
generate_init_visgen(std::ostream &o)
Definition: generator.hpp:2562
void operator()(const cholesky_corr_var_decl &x) const
Definition: generator.hpp:951
std::string fun_scalar_type(const function_decl_def &fun, bool is_lp)
Definition: generator.hpp:4309
void operator()(const cholesky_corr_var_decl &x) const
Definition: generator.hpp:3935
void generate_public_decl(std::ostream &o)
Definition: generator.hpp:774
void operator()(matrix_var_decl const &x) const
Definition: generator.hpp:865
void operator()(nil const &) const
Definition: generator.hpp:2566
void operator()(const corr_matrix_var_decl &x) const
Definition: generator.hpp:3261
void operator()(const unit_vector_var_decl &x) const
Definition: generator.hpp:3581
void operator()(const cholesky_factor_var_decl &x) const
Definition: generator.hpp:3243
void operator()(cov_matrix_var_decl const &x) const
Definition: generator.hpp:898
void operator()(double_var_decl const &x) const
Definition: generator.hpp:2599
std::vector< expression > args_
Definition: ast.hpp:196
void operator()(double_var_decl const &x) const
Definition: generator.hpp:933
void operator()(const vector_var_decl &x) const
Definition: generator.hpp:3358
void operator()(const ordered_var_decl &x) const
Definition: generator.hpp:2864
const std::string MAJOR_VERSION
Major version number for Stan package.
Definition: version.hpp:9
bool has_lb(const D &x)
Definition: generator.hpp:39
void operator()(const row_vector_var_decl &x) const
Definition: generator.hpp:3898
distribution dist_
Definition: ast.hpp:820
void operator()(const cholesky_factor_var_decl &x) const
Definition: generator.hpp:2396
void generate_init_vars(const std::vector< var_decl > &vs, int indent, std::ostream &o)
Definition: generator.hpp:1369
void operator()(const matrix_var_decl &x) const
Definition: generator.hpp:2965
void operator()(const row_vector_var_decl &x) const
Definition: generator.hpp:4027
void operator()(const corr_matrix_var_decl &x) const
Definition: generator.hpp:2989
void operator()(const matrix_var_decl &x) const
Definition: generator.hpp:3903
void nonbasic_validate(const T &x, const std::string &type_name) const
Definition: generator.hpp:869
void operator()(const double_var_decl &x) const
Definition: generator.hpp:3701
void operator()(const ordered_var_decl &x) const
Definition: generator.hpp:3919
void operator()(const cov_matrix_var_decl &x) const
Definition: generator.hpp:3612
void operator()(const simplex_var_decl &x) const
Definition: generator.hpp:2971
const std::string EOL("\n")
void generate_validate_positive(const std::string &var_name, const expression &expr, std::ostream &o)
Definition: generator.hpp:458
void operator()(const double_var_decl &x) const
Definition: generator.hpp:4019
void operator()(const matrix_var_decl &x) const
Definition: generator.hpp:3217
void operator()(const positive_ordered_var_decl &x) const
Definition: generator.hpp:2393
void operator()(const unit_vector_var_decl &x) const
Definition: generator.hpp:4038
void operator()(const matrix_var_decl &x) const
Definition: generator.hpp:3575
member_var_decl_visgen(int indents, std::ostream &o)
Definition: generator.hpp:924
void operator()(const ordered_var_decl &x) const
Definition: generator.hpp:611
void operator()(const nil &) const
Definition: generator.hpp:3861
void operator()(const ordered_var_decl &x) const
Definition: generator.hpp:3233
void operator()(const cholesky_corr_var_decl &x) const
Definition: generator.hpp:3413
std::vector< var_decl > local_decl_
Definition: ast.hpp:186
std::vector< printable > printables_
Definition: ast.hpp:746
expr_type expression_type() const
Definition: ast_def.cpp:570
void operator()(positive_ordered_var_decl const &x) const
Definition: generator.hpp:1417
void operator()(const int_var_decl &x) const
Definition: generator.hpp:3036
void operator()(const expression &e) const
Definition: generator.hpp:277
void operator()(const corr_matrix_var_decl &x) const
Definition: generator.hpp:2892
void operator()(const cholesky_corr_var_decl &x) const
Definition: generator.hpp:2415
void operator()(const vector_var_decl &x) const
Definition: generator.hpp:3042
void operator()(const vector_var_decl &x) const
Definition: generator.hpp:1252
void operator()(double_var_decl const &x) const
Definition: generator.hpp:1319
void operator()(const print_statement &ps) const
Definition: generator.hpp:1659
void operator()(ordered_var_decl const &x) const
Definition: generator.hpp:2645
const std::string INDENT2(" ")
bool has_lub(const D &x)
Definition: generator.hpp:31
expr_type arg_type_
Definition: ast.hpp:768
void operator()(const for_statement &x) const
Definition: generator.hpp:1696
void operator()(unit_vector_var_decl const &x) const
Definition: generator.hpp:2631
void generate_init_method(const std::vector< var_decl > &vs, std::ostream &o)
Definition: generator.hpp:2795
std::vector< statement > statements_
Definition: ast.hpp:187
void operator()(const statements &x) const
Definition: generator.hpp:1638
void operator()(int_var_decl const &x) const
Definition: generator.hpp:1389
void operator()(const double_var_decl &x) const
Definition: generator.hpp:3561
void generate_private_decl(std::ostream &o)
Definition: generator.hpp:778
void generate_write_csv_header_method(const program &prog, std::ostream &o)
Definition: generator.hpp:3173
void operator()(const ordered_var_decl &x) const
Definition: generator.hpp:4048
void generate_write_array_method(const program &prog, const std::string &model_name, std::ostream &o)
Definition: generator.hpp:4131
void operator()(cholesky_factor_var_decl const &x) const
Definition: generator.hpp:1082
void operator()(nil const &) const
Definition: generator.hpp:1840
bool is_void() const
Definition: ast_def.cpp:108
const int VOID_T
Definition: ast.hpp:64
void generate_param_names(const std::string &name) const
Definition: generator.hpp:2993
void operator()(corr_matrix_var_decl const &x) const
Definition: generator.hpp:1451
void operator()(const vector_var_decl &x) const
Definition: generator.hpp:2959
void operator()(const nil &) const
Definition: generator.hpp:2952

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