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

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