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

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