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

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