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

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