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

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