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

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