1 #ifndef __STAN__GM__GENERATOR_HPP__
2 #define __STAN__GM__GENERATOR_HPP__
4 #include <boost/variant/apply_visitor.hpp>
20 const std::string
EOL(
"\n");
21 const std::string
EOL2(
"\n\n");
22 const std::string
INDENT(
" ");
28 return !
is_nil(x.range_.low_.expr_) && !
is_nil(x.range_.high_.expr_);
32 return is_nil(x.range_.low_.expr_) && !
is_nil(x.range_.high_.expr_);
36 return !
is_nil(x.range_.low_.expr_) &&
is_nil(x.range_.high_.expr_);
47 for (
size_t k = 0; k < indent; ++k)
60 o <<
"namespace " << name <<
"_namespace {" <<
EOL2;
64 o <<
"} // namespace" <<
EOL2;
70 o <<
"// " << msg <<
EOL;
75 const std::vector<expression> indexes,
81 size_t ai_size = indexes.size();
87 if (ai_size <= (e_num_dims + 1) || base_type !=
MATRIX_T) {
88 for (
size_t n = 0; n < ai_size; ++n)
91 for (
size_t n = 0; n < ai_size; ++n) {
94 o <<
',' <<
'"' << expr <<
'"' <<
',' << (n+1) <<
')';
97 for (
size_t n = 0; n < ai_size - 1; ++n)
100 for (
size_t n = 0; n < ai_size - 2; ++n) {
103 o <<
',' <<
'"' << expr <<
'"' <<
',' << (n+1) <<
')';
109 o <<
',' <<
'"' << expr <<
'"' <<
',' << (ai_size-1U) <<
')';
125 std::stringstream expr_o;
127 std::string expr_string = expr_o.str();
128 std::vector<expression> indexes;
131 for (
size_t i = 0; i < x.
dimss_.size(); ++i)
132 for (
size_t j = 0; j < x.
dimss_[i].size(); ++j)
133 indexes.push_back(x.
dimss_[i][j]);
138 for (
size_t i = 0; i < fx.
args_.size(); ++i) {
139 if (i > 0)
o_ <<
',';
140 boost::apply_visitor(*
this, fx.
args_[i].expr_);
146 boost::apply_visitor(*
this, expr.
left.
expr_);
147 o_ <<
' ' << expr.
op <<
' ';
148 boost::apply_visitor(*
this, expr.
right.
expr_);
152 o_ << expr.
op <<
'(';
160 boost::apply_visitor(vis, e.
expr_);
166 o_ <<
'"' << s <<
'"';
179 o <<
"using " << type <<
";" <<
EOL;
183 o <<
"using namespace " << ns <<
";" <<
EOL;
204 const std::string& abbrev,
206 o <<
"typedef" <<
" " << type <<
" " << abbrev <<
";" <<
EOL;
211 generate_typedef(
"Eigen::Matrix<double,1,Eigen::Dynamic>",
"row_vector_d",o);
212 generate_typedef(
"Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>",
"matrix_d",o);
214 generate_typedef(
"Eigen::Matrix<stan::agrad::var,Eigen::Dynamic,1>",
"vector_v",o);
215 generate_typedef(
"Eigen::Matrix<stan::agrad::var,1,Eigen::Dynamic>",
"row_vector_v",o);
216 generate_typedef(
"Eigen::Matrix<stan::agrad::var,Eigen::Dynamic,Eigen::Dynamic>",
"matrix_v",o);
222 o <<
"#include" <<
" " <<
"<" << lib_name <<
">" <<
EOL;
231 o <<
"// Code generated by Stan version "
237 o <<
"class " << model_name <<
" : public prob_grad_ad {" <<
EOL;
241 o <<
"}; // model" <<
EOL2;
245 const std::vector<expression>& dims,
248 for (
size_t i = 0; i < end; ++i) o <<
"std::vector<";
250 for (
size_t i = 0; i < end; ++i) {
256 void generate_initializer(std::ostream& o,
257 const std::string& base_type,
258 const std::vector<expression>& dims,
259 const expression& type_arg1 = expression(),
260 const expression& type_arg2 = expression()) {
261 for (size_t i = 0; i < dims.size(); ++i) {
263 generate_expression(dims[i].expr_,o);
265 generate_type(base_type,dims,dims.size()- i - 1,o);
269 if (!is_nil(type_arg1)) {
270 generate_expression(type_arg1.expr_,o);
271 if (!is_nil(type_arg2)) {
273 generate_expression(type_arg2.expr_,o);
275 } else if (!is_nil(type_arg2.expr_)) {
276 generate_expression(type_arg2.expr_,o);
282 for (size_t i = 0; i < dims.size(); ++i)
287 void generate_initialization(std::ostream& o,
289 const std::string& var_name,
290 const std::string& base_type,
291 const std::vector<expression>& dims,
292 const expression& type_arg1 = expression(),
293 const expression& type_arg2 = expression()) {
294 generate_indent(indent,o);
295 o << var_name << " = ";
296 generate_type(base_type,dims,dims.size(),o);
297 generate_initializer(o,base_type,dims,type_arg1,type_arg2);
301 struct var_resizing_visgen : public visgen {
302 var_resizing_visgen(std::ostream& o)
305 void operator()(nil const& x) const { } // dummy
306 void operator()(int_var_decl const& x) const {
307 generate_initialization(o_,2U,x.name_,"int",x.dims_);
309 void operator()(double_var_decl const& x) const {
310 generate_initialization(o_,2U,x.name_,"double",x.dims_);
312 void operator()(vector_var_decl const& x) const {
313 generate_initialization(o_,2U,x.name_,"vector_d",x.dims_,x.M_);
315 void operator()(row_vector_var_decl const& x) const {
316 generate_initialization(o_,2U,x.name_,"row_vector_d",x.dims_,x.N_);
318 void operator()(simplex_var_decl const& x) const {
319 generate_initialization(o_,2U,x.name_,"vector_d",x.dims_,x.K_);
321 void operator()(ordered_var_decl const& x) const {
322 generate_initialization(o_,2U,x.name_,"vector_d",x.dims_,x.K_);
324 void operator()(positive_ordered_var_decl const& x) const {
325 generate_initialization(o_,2U,x.name_,"vector_d",x.dims_,x.K_);
327 void operator()(matrix_var_decl const& x) const {
328 generate_initialization(o_,2U,x.name_,"matrix_d",x.dims_,x.M_,x.N_);
330 void operator()(cov_matrix_var_decl const& x) const {
331 generate_initialization(o_,2U,x.name_,"matrix_d",x.dims_,x.K_,x.K_);
333 void operator()(corr_matrix_var_decl const& x) const {
334 generate_initialization(o_,2U,x.name_,"matrix_d",x.dims_,x.K_,x.K_);
338 void generate_var_resizing(const std::vector<var_decl>& vs,
340 var_resizing_visgen vis(o);
341 for (size_t i = 0; i < vs.size(); ++i)
342 boost::apply_visitor(vis, vs[i].decl_);
345 const std::vector<expression> EMPTY_EXP_VECTOR(0);
347 struct init_local_var_visgen : public visgen {
348 const bool declare_vars_;
349 init_local_var_visgen(bool declare_vars,
352 declare_vars_(declare_vars) {
354 template <typename D>
355 void generate_initialize_array_bounded(const D& x, const std::string& base_type,
356 const std::string& read_fun_prefix,
357 const std::vector<expression>& dim_args) const {
358 std::vector<expression> read_args;
359 std::string read_fun(read_fun_prefix);
362 read_args.push_back(x.range_.low_);
363 read_args.push_back(x.range_.high_);
364 } else if (has_lb(x)) {
366 read_args.push_back(x.range_.low_);
367 } else if (has_ub(x)) {
369 read_args.push_back(x.range_.high_);
371 for (size_t i = 0; i < dim_args.size(); ++i)
372 read_args.push_back(dim_args[i]);
373 generate_initialize_array(base_type,read_fun,read_args,x.name_,x.dims_);
375 void operator()(const nil& x) const { }
376 void operator()(const int_var_decl& x) const {
377 generate_initialize_array("int","integer",EMPTY_EXP_VECTOR,x.name_,x.dims_);
379 void operator()(const double_var_decl& x) const {
380 std::vector<expression> read_args;
381 generate_initialize_array_bounded(x,"var","scalar",read_args);
383 void operator()(const vector_var_decl& x) const {
384 std::vector<expression> read_args;
385 read_args.push_back(x.M_);
386 generate_initialize_array_bounded(x,"vector_v","vector",read_args);
388 void operator()(const row_vector_var_decl& x) const {
389 std::vector<expression> read_args;
390 read_args.push_back(x.N_);
391 generate_initialize_array_bounded(x,"row_vector_v","row_vector",read_args);
393 void operator()(const matrix_var_decl& x) const {
394 std::vector<expression> read_args;
395 read_args.push_back(x.M_);
396 read_args.push_back(x.N_);
397 generate_initialize_array_bounded(x,"matrix_v","matrix",read_args);
399 void operator()(const simplex_var_decl& x) const {
400 std::vector<expression> read_args;
401 read_args.push_back(x.K_);
402 generate_initialize_array("vector_v","simplex",read_args,x.name_,x.dims_);
404 void operator()(const ordered_var_decl& x) const {
405 std::vector<expression> read_args;
406 read_args.push_back(x.K_);
407 generate_initialize_array("vector_v","ordered",read_args,x.name_,x.dims_);
409 void operator()(const positive_ordered_var_decl& x) const {
410 std::vector<expression> read_args;
411 read_args.push_back(x.K_);
412 generate_initialize_array("vector_v","positive_ordered",read_args,x.name_,x.dims_);
414 void operator()(const cov_matrix_var_decl& x) const {
415 std::vector<expression> read_args;
416 read_args.push_back(x.K_);
417 generate_initialize_array("matrix_v","cov_matrix",read_args,x.name_,x.dims_);
419 void operator()(const corr_matrix_var_decl& x) const {
420 std::vector<expression> read_args;
421 read_args.push_back(x.K_);
422 generate_initialize_array("matrix_v","corr_matrix",read_args,x.name_,x.dims_);
424 void generate_initialize_array(const std::string& var_type,
425 const std::string& read_type,
426 const std::vector<expression>& read_args,
427 const std::string& name,
428 const std::vector<expression>& dims)
431 if (dims.size() == 0) {
432 generate_indent(2,o_);
433 if (declare_vars_) o_ << var_type << " ";
434 o_ << name << " = in__." << read_type << "_constrain(";
435 for (size_t j = 0; j < read_args.size(); ++j) {
436 if (j > 0) o_ << ",";
437 generate_expression(read_args[j],o_);
439 if (read_args.size() > 0)
447 for (size_t i = 0; i < dims.size(); ++i) o_ << "vector<";
449 for (size_t i = 0; i < dims.size(); ++i) o_ << "> ";
450 o_ << name << ";" << EOL;
452 std::string name_dims(name);
453 for (size_t i = 0; i < dims.size(); ++i) {
454 generate_indent(i + 2, o_);
455 o_ << "size_t dim_" << name << "_" << i << "__ = ";
456 generate_expression(dims[i],o_);
458 if (i < dims.size() - 1) {
459 generate_indent(i + 2, o_);
460 o_ << name_dims << ".resize(dim" << "_" << name << "_" << i << "__);"
462 name_dims.append("[k_").append(to_string(i)).append("__]");
464 generate_indent(i + 2, o_);
465 if (i == dims.size() - 1) {
466 o_ << name_dims << ".reserve(dim_" << name << "_" << i << "__);" << EOL;
467 generate_indent(i + 2, o_);
469 o_ << "for (size_t k_" << i << "__ = 0;"
470 << " k_" << i << "__ < dim_" << name << "_" << i << "__;"
471 << " ++k_" << i << "__) {" << EOL;
472 if (i == dims.size() - 1) {
473 generate_indent(i + 3, o_);
474 o_ << name_dims << ".push_back(in__." << read_type << "_constrain(";
475 for (size_t j = 0; j < read_args.size(); ++j) {
476 if (j > 0) o_ << ",";
477 generate_expression(read_args[j],o_);
479 if (read_args.size() > 0)
485 for (size_t i = dims.size(); i > 0; --i) {
486 generate_indent(i + 1, o_);
492 void generate_local_var_inits(std::vector<var_decl> vs,
495 o << INDENT2 << "stan::io::reader<var> in__(params_r__,params_i__);" << EOL2;
496 init_local_var_visgen vis(declare_vars,o);
497 for (size_t i = 0; i < vs.size(); ++i)
498 boost::apply_visitor(vis, vs[i].decl_);
504 void generate_public_decl(std::ostream& o) {
505 o << "public:" << EOL;
508 void generate_private_decl(std::ostream& o) {
509 o << "private:" << EOL;
513 struct validate_var_decl_visgen : public visgen {
515 validate_var_decl_visgen(int indents,
520 void generate_begin_for_dims(const std::vector<expression>& dims)
523 for (size_t i = 0; i < dims.size(); ++i) {
524 generate_indent(indents_+i,o_);
525 o_ << "for (int k" << i << "__ = 0;"
526 << " k" << i << "__ < ";
527 generate_expression(dims[i].expr_,o_);
529 o_ << " ++k" << i << "__) {" << EOL;
532 void generate_end_for_dims(size_t dims_size) const {
533 for (size_t i = 0; i < dims_size; ++i) {
534 generate_indent(indents_ + dims_size - i - 1, o_);
539 void generate_loop_var(const std::string& name,
540 size_t dims_size) const {
542 for (size_t i = 0; i < dims_size; ++i)
543 o_ << "[k" << i << "__]";
545 void operator()(nil const& x) const { }
546 template <typename T>
547 void basic_validate(T const& x) const {
548 if (!(x.range_.has_low() || x.range_.has_high()))
549 return; // unconstrained
550 generate_begin_for_dims(x.dims_);
551 generate_indent(indents_ + x.dims_.size(),o_);
552 o_ << "try { " << EOL;
553 if (x.range_.has_low()) {
554 generate_indent(indents_ + 1 + x.dims_.size(),o_);
555 o_ << "check_greater_or_equal(function__,";
556 generate_loop_var(x.name_,x.dims_.size());
558 generate_expression(x.range_.low_.expr_,o_);
560 generate_loop_var(x.name_,x.dims_.size());
563 if (x.range_.has_high()) {
564 generate_indent(indents_ + 1 + x.dims_.size(),o_);
565 o_ << "check_less_or_equal(function__,";
566 generate_loop_var(x.name_,x.dims_.size());
568 generate_expression(x.range_.high_.expr_,o_);
570 generate_loop_var(x.name_,x.dims_.size());
573 generate_indent(indents_ + x.dims_.size(),o_);
574 o_ << "} catch (std::domain_error e) { throw std::domain_error(std::string(\"Invalid value of " << x.name_ << ": \") + std::string(e.what())); };" << EOL;
575 generate_end_for_dims(x.dims_.size());
577 void operator()(int_var_decl const& x) const {
580 void operator()(double_var_decl const& x) const {
583 void operator()(vector_var_decl const& x) const {
586 void operator()(row_vector_var_decl const& x) const {
589 void operator()(matrix_var_decl const& x) const {
592 template <typename T>
593 void nonbasic_validate(const T& x,
594 const std::string& type_name) const {
595 generate_begin_for_dims(x.dims_);
596 generate_indent(indents_ + x.dims_.size(),o_);
597 o_ << "try { stan::math::check_" << type_name << "(function__,";
598 generate_loop_var(x.name_,x.dims_.size());
600 generate_loop_var(x.name_,x.dims_.size());
601 o_ << "\"); } catch (std::domain_error e) { throw std::domain_error(std::string(\"Invalid value of " << x.name_ << ": \") + std::string(e.what())); };" << EOL;
602 generate_end_for_dims(x.dims_.size());
604 void operator()(simplex_var_decl const& x) const {
605 nonbasic_validate(x,"simplex");
607 void operator()(ordered_var_decl const& x) const {
608 nonbasic_validate(x,"ordered");
610 void operator()(positive_ordered_var_decl const& x) const {
611 nonbasic_validate(x,"positive_ordered");
613 void operator()(corr_matrix_var_decl const& x) const {
614 nonbasic_validate(x,"corr_matrix");
616 void operator()(cov_matrix_var_decl const& x) const {
617 nonbasic_validate(x,"cov_matrix");
622 void generate_validate_var_decl(const var_decl& decl,
625 validate_var_decl_visgen vis(indent,o);
626 boost::apply_visitor(vis,decl.decl_);
629 void generate_validate_var_decls(const std::vector<var_decl> decls,
632 for (size_t i = 0; i < decls.size(); ++i)
633 generate_validate_var_decl(decls[i],indent,o);
636 // see _var_decl_visgen cut & paste
637 struct member_var_decl_visgen : public visgen {
639 member_var_decl_visgen(int indents,
644 void operator()(nil const& x) const { }
645 void operator()(int_var_decl const& x) const {
646 declare_array("int",x.name_,x.dims_.size());
648 void operator()(double_var_decl const& x) const {
649 declare_array("double",x.name_,x.dims_.size());
651 void operator()(simplex_var_decl const& x) const {
652 declare_array(("vector_d"), x.name_, x.dims_.size());
654 void operator()(ordered_var_decl const& x) const {
655 declare_array(("vector_d"), x.name_, x.dims_.size());
657 void operator()(positive_ordered_var_decl const& x) const {
658 declare_array(("vector_d"), x.name_, x.dims_.size());
660 void operator()(cov_matrix_var_decl const& x) const {
661 declare_array(("matrix_d"), x.name_, x.dims_.size());
663 void operator()(corr_matrix_var_decl const& x) const {
664 declare_array(("matrix_d"), x.name_, x.dims_.size());
666 void operator()(vector_var_decl const& x) const {
667 declare_array(("vector_d"), x.name_, x.dims_.size());
669 void operator()(row_vector_var_decl const& x) const {
670 declare_array(("row_vector_d"), x.name_, x.dims_.size());
672 void operator()(matrix_var_decl const& x) const {
673 declare_array(("matrix_d"), x.name_, x.dims_.size());
675 void declare_array(std::string const& type, std::string const& name,
677 for (int i = 0; i < indents_; ++i)
679 for (size_t i = 0; i < size; ++i) {
686 for (size_t i = 1; i < size; ++i) {
689 o_ << " " << name << ";" << EOL;
693 void generate_member_var_decls(const std::vector<var_decl>& vs,
696 member_var_decl_visgen vis(indent,o);
697 for (size_t i = 0; i < vs.size(); ++i)
698 boost::apply_visitor(vis,vs[i].decl_);
701 // see member_var_decl_visgen cut & paste
702 struct local_var_decl_visgen : public visgen {
705 local_var_decl_visgen(int indents,
712 void operator()(nil const& x) const { }
713 void operator()(int_var_decl const& x) const {
714 std::vector<expression> ctor_args;
715 declare_array("int",ctor_args,x.name_,x.dims_);
717 void operator()(double_var_decl const& x) const {
718 std::vector<expression> ctor_args;
719 declare_array(is_var_ ? "var" : "double",
720 ctor_args,x.name_,x.dims_);
722 void operator()(vector_var_decl const& x) const {
723 std::vector<expression> ctor_args;
724 ctor_args.push_back(x.M_);
725 declare_array(is_var_ ? "vector_v" : "vector_d",
726 ctor_args, x.name_, x.dims_);
728 void operator()(row_vector_var_decl const& x) const {
729 std::vector<expression> ctor_args;
730 ctor_args.push_back(x.N_);
731 declare_array(is_var_ ? "row_vector_v" : "row_vector_d",
732 ctor_args, x.name_, x.dims_);
734 void operator()(matrix_var_decl const& x) const {
735 std::vector<expression> ctor_args;
736 ctor_args.push_back(x.M_);
737 ctor_args.push_back(x.N_);
738 declare_array(is_var_ ? "matrix_v" : "matrix_d",
739 ctor_args, x.name_, x.dims_);
741 void operator()(simplex_var_decl const& x) const {
742 std::vector<expression> ctor_args;
743 ctor_args.push_back(x.K_);
744 declare_array(is_var_ ? "vector_v" : "vector_d",
745 ctor_args, x.name_, x.dims_);
747 void operator()(ordered_var_decl const& x) const {
748 std::vector<expression> ctor_args;
749 ctor_args.push_back(x.K_);
750 declare_array(is_var_ ? "vector_v" : "vector_d",
751 ctor_args, x.name_, x.dims_);
753 void operator()(positive_ordered_var_decl const& x) const {
754 std::vector<expression> ctor_args;
755 ctor_args.push_back(x.K_);
756 declare_array(is_var_ ? "vector_v" : "vector_d",
757 ctor_args, x.name_, x.dims_);
759 void operator()(cov_matrix_var_decl const& x) const {
760 std::vector<expression> ctor_args;
761 ctor_args.push_back(x.K_);
762 ctor_args.push_back(x.K_);
763 declare_array(is_var_ ? "matrix_v" : "matrix_d",
764 ctor_args, x.name_, x.dims_);
766 void operator()(corr_matrix_var_decl const& x) const {
767 std::vector<expression> ctor_args;
768 ctor_args.push_back(x.K_);
769 ctor_args.push_back(x.K_);
770 declare_array(is_var_ ? "matrix_v" : "matrix_d",
771 ctor_args, x.name_, x.dims_);
773 void generate_type(const std::string& type,
774 size_t num_dims) const {
775 for (size_t i = 0; i < num_dims; ++i)
778 for (size_t i = 0; i < num_dims; ++i) {
779 if (i > 0) o_ << " ";
783 // var_decl -> type[0] name init_args[0] ;
784 // init_args[k] -> ctor_args if no dims left
785 // init_args[k] -> ( dim[k] , ( type[k+1] init_args[k+1] ) )
786 void generate_init_args(const std::string& type,
787 const std::vector<expression>& ctor_args,
788 const std::vector<expression>& dims,
790 if (dim < dims.size()) { // more dims left
791 o_ << '(
'; // open(1)
792 generate_expression(dims[dim],o_);
793 if ((dim + 1 < dims.size()) || ctor_args.size() > 0) {
794 o_ << ", ("; // open(2)
795 generate_type(type,dims.size() - dim - 1);
796 generate_init_args(type,ctor_args,dims,dim + 1);
797 o_ << ')
'; // close(2)
799 o_ << ')
'; // close(1)
801 if (ctor_args.size() == 1) {// vector
803 generate_expression(ctor_args[0],o_);
806 if (ctor_args.size() > 1) { // matrix
808 generate_expression(ctor_args[0],o_);
810 generate_expression(ctor_args[1],o_);
815 void declare_array(const std::string& type,
816 const std::vector<expression>& ctor_args,
817 const std::string& name,
818 const std::vector<expression>& dims) const {
820 // require double parens to counter "most vexing parse" problem
822 generate_indent(indents_,o_);
823 generate_type(type,dims.size());
825 generate_init_args(type,ctor_args,dims,0);
830 void generate_local_var_decls(const std::vector<var_decl>& vs,
834 local_var_decl_visgen vis(indent,is_var,o);
835 for (size_t i = 0; i < vs.size(); ++i)
836 boost::apply_visitor(vis,vs[i].decl_);
839 // see member_var_decl_visgen cut & paste
840 struct generate_init_vars_visgen : public visgen {
842 generate_init_vars_visgen(int indent,
847 void operator()(nil const& x) const { }
848 void operator()(int_var_decl const& x) const {
849 generate_indent(indent_,o_);
850 o_ << "initialize_variable(" << x.name_ << ",INIT_DUMMY__);" << EOL;
852 void operator()(double_var_decl const& x) const {
853 generate_indent(indent_,o_);
854 o_ << "initialize_variable(" << x.name_ << ",INIT_DUMMY__);" << EOL;
856 void operator()(vector_var_decl const& x) const {
857 generate_indent(indent_,o_);
858 o_ << "initialize_variable(" << x.name_ << ",INIT_DUMMY__);" << EOL;
860 void operator()(row_vector_var_decl const& x) const {
861 generate_indent(indent_,o_);
862 o_ << "initialize_variable(" << x.name_ << ",INIT_DUMMY__);" << EOL;
864 void operator()(matrix_var_decl const& x) const {
865 generate_indent(indent_,o_);
866 o_ << "initialize_variable(" << x.name_ << ",INIT_DUMMY__);" << EOL;
868 void operator()(simplex_var_decl const& x) const {
869 generate_indent(indent_,o_);
870 o_ << "initialize_variable(" << x.name_ << ",INIT_DUMMY__);" << EOL;
872 void operator()(ordered_var_decl const& x) const {
873 generate_indent(indent_,o_);
874 o_ << "initialize_variable(" << x.name_ << ",INIT_DUMMY__);" << EOL;
876 void operator()(positive_ordered_var_decl const& x) const {
877 generate_indent(indent_,o_);
878 o_ << "initialize_variable(" << x.name_ << ",INIT_DUMMY__);" << EOL;
880 void operator()(cov_matrix_var_decl const& x) const {
881 generate_indent(indent_,o_);
882 o_ << "initialize_variable(" << x.name_ << ",INIT_DUMMY__);" << EOL;
884 void operator()(corr_matrix_var_decl const& x) const {
885 generate_indent(indent_,o_);
886 o_ << "initialize_variable(" << x.name_ << ",INIT_DUMMY__);" << EOL;
890 void generate_init_vars(const std::vector<var_decl>& vs,
893 generate_init_vars_visgen vis(indent,o);
895 generate_comment("initialized transformed params to avoid seg fault on val access",
897 generate_indent(indent,o);
898 o << "var INIT_DUMMY__(std::numeric_limits<double>::quiet_NaN());" << EOL;
899 for (size_t i = 0; i < vs.size(); ++i)
900 boost::apply_visitor(vis,vs[i].decl_);
904 struct validate_transformed_params_visgen : public visgen {
906 validate_transformed_params_visgen(int indents,
911 void operator()(nil const& x) const { }
912 void operator()(int_var_decl const& x) const {
913 std::vector<expression> dims(x.dims_);
914 validate_array(x.name_,dims,0);
916 void operator()(double_var_decl const& x) const {
917 std::vector<expression> dims(x.dims_);
918 validate_array(x.name_,dims,0);
920 void operator()(vector_var_decl const& x) const {
921 std::vector<expression> dims(x.dims_);
922 dims.push_back(x.M_);
923 validate_array(x.name_,dims,1);
925 void operator()(simplex_var_decl const& x) const {
926 std::vector<expression> dims(x.dims_);
927 dims.push_back(x.K_);
928 validate_array(x.name_,dims,1);
930 void operator()(ordered_var_decl const& x) const {
931 std::vector<expression> dims(x.dims_);
932 dims.push_back(x.K_);
933 validate_array(x.name_,dims,1);
935 void operator()(positive_ordered_var_decl const& x) const {
936 std::vector<expression> dims(x.dims_);
937 dims.push_back(x.K_);
938 validate_array(x.name_,dims,1);
940 void operator()(row_vector_var_decl const& x) const {
941 std::vector<expression> dims(x.dims_);
942 dims.push_back(x.N_);
943 validate_array(x.name_,dims,1);
945 void operator()(matrix_var_decl const& x) const {
946 std::vector<expression> dims(x.dims_);
947 dims.push_back(x.M_);
948 dims.push_back(x.N_);
949 validate_array(x.name_,dims,2);
951 void operator()(cov_matrix_var_decl const& x) const {
952 std::vector<expression> dims(x.dims_);
953 dims.push_back(x.K_);
954 dims.push_back(x.K_);
955 validate_array(x.name_,dims,2);
957 void operator()(corr_matrix_var_decl const& x) const {
958 std::vector<expression> dims(x.dims_);
959 dims.push_back(x.K_);
960 dims.push_back(x.K_);
961 validate_array(x.name_,dims,2);
963 void validate_array(const std::string& name,
964 const std::vector<expression>& dims,
965 size_t matrix_dims) const {
967 size_t non_matrix_dims = dims.size() - matrix_dims;
969 for (size_t k = 0; k < dims.size(); ++k) {
970 generate_indent(indents_ + k,o_);
971 o_ << "for (int i" << k << "__ = 0; i" << k << "__ < ";
972 generate_expression(dims[k],o_);
973 o_ << "; ++i" << k << "__) {" << EOL;
976 generate_indent(indents_ + dims.size(), o_);
977 o_ << "if (" << name;
978 for (size_t k = 0; k < non_matrix_dims; ++k)
979 o_ << "[i" << k << "__]";
980 if (matrix_dims > 0) {
981 o_ << "(i" << non_matrix_dims << "__";
983 o_ << ",i" << (non_matrix_dims + 1) << "__";
986 o_ << ".is_uninitialized()) {" << EOL;
987 generate_indent(indents_ + dims.size() + 1, o_);
988 o_ << "std::stringstream msg__;" << EOL;
989 generate_indent(indents_ + dims.size() + 1, o_);
990 o_ << "msg__ << \"Undefined transformed parameter: "
992 for (size_t k = 0; k < dims.size(); ++k) {
994 o_ << " << i" << k << "__";
998 generate_indent(indents_ + dims.size() + 1, o_);
999 o_ << "throw std::runtime_error(msg__.str());" << EOL;
1001 generate_indent(indents_ + dims.size(), o_);
1003 for (size_t k = 0; k < dims.size(); ++k) {
1004 generate_indent(indents_ + dims.size() - k - 1, o_);
1010 void generate_validate_transformed_params(const std::vector<var_decl>& vs,
1013 generate_comment("validate transformed parameters",indent,o);
1014 validate_transformed_params_visgen vis(indent,o);
1015 for (size_t i = 0; i < vs.size(); ++i)
1016 boost::apply_visitor(vis,vs[i].decl_);
1020 void generate_statement(statement const& s, int indent, std::ostream& o,
1021 bool include_sampling, bool is_var);
1023 struct statement_visgen : public visgen {
1025 bool include_sampling_;
1027 statement_visgen(size_t indent,
1028 bool include_sampling,
1033 include_sampling_(include_sampling),
1036 void operator()(nil const& x) const {
1038 void operator()(assignment const& x) const {
1039 generate_indent(indent_,o_);
1041 generate_indexed_expr(x.var_dims_.name_,
1043 x.var_type_.base_type_,
1044 x.var_type_.dims_.size(),
1047 generate_expression(x.expr_,o_);
1050 void operator()(sample const& x) const {
1051 if (!include_sampling_) return;
1052 generate_indent(indent_,o_);
1053 // FOO_log<true> is the log FOO distribution up to a proportion
1054 o_ << "lp__ += stan::prob::" << x.dist_.family_ << "_log<true>(";
1055 generate_expression(x.expr_,o_);
1056 for (size_t i = 0; i < x.dist_.args_.size(); ++i) {
1058 generate_expression(x.dist_.args_[i],o_);
1061 // generate bounds test
1062 if (x.truncation_.has_low()) {
1063 generate_indent(indent_,o_);
1065 generate_expression(x.expr_,o_);
1067 generate_expression(x.truncation_.low_.expr_,o_); // low
1069 o_ << ") lp__ -= std::numeric_limits<double>::infinity();" << EOL;
1071 if (x.truncation_.has_high()) {
1072 generate_indent(indent_,o_);
1073 if (x.truncation_.has_low()) o_ << "else ";
1075 generate_expression(x.expr_,o_);
1077 generate_expression(x.truncation_.high_.expr_,o_); // low
1079 o_ << ") lp__ -= std::numeric_limits<double>::infinity();" << EOL;
1081 if (x.truncation_.has_low() || x.truncation_.has_high()) {
1082 generate_indent(indent_,o_);
1085 // generate log denominator
1086 if (x.truncation_.has_low() && x.truncation_.has_high()) {
1087 o_ << "lp__ -= log(";
1088 o_ << x.dist_.family_ << "_cdf(";
1089 generate_expression(x.truncation_.high_.expr_,o_);
1090 for (size_t i = 0; i < x.dist_.args_.size(); ++i) {
1092 generate_expression(x.dist_.args_[i],o_);
1094 o_ << ") - " << x.dist_.family_ << "_cdf(";
1095 generate_expression(x.truncation_.low_.expr_,o_);
1096 for (size_t i = 0; i < x.dist_.args_.size(); ++i) {
1098 generate_expression(x.dist_.args_[i],o_);
1101 } else if (!x.truncation_.has_low() && x.truncation_.has_high()) {
1102 o_ << "lp__ -= log(";
1103 o_ << x.dist_.family_ << "_cdf(";
1104 generate_expression(x.truncation_.high_.expr_,o_);
1105 for (size_t i = 0; i < x.dist_.args_.size(); ++i) {
1107 generate_expression(x.dist_.args_[i],o_);
1110 } else if (x.truncation_.has_low() && !x.truncation_.has_high()) {
1111 o_ << "lp__ -= log1m(";
1112 o_ << x.dist_.family_ << "_cdf(";
1113 generate_expression(x.truncation_.low_.expr_,o_);
1114 for (size_t i = 0; i < x.dist_.args_.size(); ++i) {
1116 generate_expression(x.dist_.args_[i],o_);
1121 void operator()(const statements& x) const {
1122 bool has_local_vars = x.local_decl_.size() > 0;
1123 size_t indent = has_local_vars ? (indent_ + 1) : indent_;
1124 if (has_local_vars) {
1125 generate_indent(indent_,o_);
1126 o_ << "{" << EOL; // need brackets for scope
1127 generate_local_var_decls(x.local_decl_,indent,o_,is_var_);
1130 for (size_t i = 0; i < x.statements_.size(); ++i)
1131 generate_statement(x.statements_[i],indent,o_,include_sampling_,is_var_);
1133 if (has_local_vars) {
1134 generate_indent(indent_,o_);
1138 void operator()(const print_statement& ps) const {
1139 generate_indent(indent_,o_);
1140 o_ << "if (pstream__) {" << EOL;
1141 for (size_t i = 0; i < ps.printables_.size(); ++i) {
1142 generate_indent(indent_ + 1,o_);
1143 o_ << "stan_print(pstream__,";
1144 generate_printable(ps.printables_[i],o_);
1147 generate_indent(indent_ + 1,o_);
1148 o_ << "*pstream__ << std::endl;" << EOL;
1149 generate_indent(indent_,o_);
1152 void operator()(const for_statement& x) const {
1153 generate_indent(indent_,o_);
1154 o_ << "for (int " << x.variable_ << " = ";
1155 generate_expression(x.range_.low_,o_);
1156 o_ << "; " << x.variable_ << " <= ";
1157 generate_expression(x.range_.high_,o_);
1158 o_ << "; ++" << x.variable_ << ") {" << EOL;
1159 generate_statement(x.statement_, indent_ + 1, o_, include_sampling_,is_var_);
1160 generate_indent(indent_,o_);
1163 void operator()(const no_op_statement& x) const {
1164 // called no_op for a reason
1168 void generate_statement(const statement& s,
1171 bool include_sampling,
1173 statement_visgen vis(indent,include_sampling,is_var,o);
1174 boost::apply_visitor(vis,s.statement_);
1177 void generate_statements(const std::vector<statement>& ss,
1180 bool include_sampling,
1182 statement_visgen vis(indent,include_sampling,is_var,o);
1183 for (size_t i = 0; i < ss.size(); ++i)
1184 boost::apply_visitor(vis,ss[i].statement_);
1188 void generate_log_prob(program const& p,
1191 o << INDENT << "var log_prob(vector<var>& params_r__," << EOL;
1192 o << INDENT << " vector<int>& params_i__," << EOL;
1193 o << INDENT << " std::ostream* pstream__ = 0) {" << EOL2;
1194 o << INDENT2 << "var lp__(0.0);" << EOL;
1196 generate_comment("model parameters",2,o);
1197 generate_local_var_inits(p.parameter_decl_,true,o);
1200 static bool is_var = true;
1201 generate_comment("transformed parameters",2,o);
1202 generate_local_var_decls(p.derived_decl_.first,2,o,is_var);
1203 generate_init_vars(p.derived_decl_.first,2,o);
1206 static bool include_sampling = true;
1207 generate_statements(p.derived_decl_.second,2,o,include_sampling,is_var);
1210 generate_validate_transformed_params(p.derived_decl_.first,2,o);
1212 generate_comment("model body",2,o);
1213 generate_statement(p.statement_,2,o,include_sampling,is_var);
1215 o << INDENT2 << "return lp__;" << EOL2;
1216 o << INDENT << "} // log_prob()" << EOL2;
1219 struct dump_member_var_visgen : public visgen {
1220 var_resizing_visgen var_resizer_;
1221 dump_member_var_visgen(std::ostream& o)
1223 var_resizer_(var_resizing_visgen(o)) {
1225 void operator()(nil const& x) const { } // dummy
1226 void operator()(int_var_decl const& x) const {
1227 std::vector<expression> dims = x.dims_;
1229 o_ << INDENT2 << "if (!context__.contains_i(\"" << x.name_ << "\"))" << EOL;
1230 o_ << INDENT3 << "throw std::runtime_error(\"variable " << x.name_ <<" not found.\");" << EOL;
1231 o_ << INDENT2 << "vals_i__ = context__.vals_i(\"" << x.name_ << "\");" << EOL;
1232 o_ << INDENT2 << "pos__ = 0;" << EOL;
1233 size_t indentation = 1;
1234 for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1235 size_t dim = dims.size() - dim_up - 1U;
1237 generate_indent(indentation,o_);
1238 o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1239 generate_expression(dims[dim],o_);
1241 generate_indent(indentation,o_);
1242 o_ << "for (size_t i_" << dim << "__ = 0; i_"
1243 << dim << "__ < " << x.name_ << "_limit_" << dim
1244 << "__; ++i_" << dim << "__) {" << EOL;
1246 generate_indent(indentation+1,o_);
1248 for (size_t dim = 0; dim < dims.size(); ++dim)
1249 o_ << "[i_" << dim << "__]";
1250 o_ << " = vals_i__[pos__++];" << EOL;
1251 for (size_t dim = 0; dim < dims.size(); ++dim) {
1252 generate_indent(dims.size() + 1 - dim,o_);
1256 // minor changes to int_var_decl
1257 void operator()(double_var_decl const& x) const {
1258 std::vector<expression> dims = x.dims_;
1260 o_ << INDENT2 << "if (!context__.contains_r(\"" << x.name_ << "\"))" << EOL;
1261 o_ << INDENT3 << "throw std::runtime_error(\"variable " << x.name_ <<" not found.\");" << EOL;
1262 o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1263 o_ << INDENT2 << "pos__ = 0;" << EOL;
1264 size_t indentation = 1;
1265 for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1266 size_t dim = dims.size() - dim_up - 1U;
1268 generate_indent(indentation,o_);
1269 o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1270 generate_expression(dims[dim],o_);
1272 generate_indent(indentation,o_);
1273 o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1275 generate_indent(indentation+1,o_);
1277 for (size_t dim = 0; dim < dims.size(); ++dim)
1278 o_ << "[i_" << dim << "__]";
1279 o_ << " = vals_r__[pos__++];" << EOL;
1280 for (size_t dim = 0; dim < dims.size(); ++dim) {
1281 generate_indent(dims.size() + 1 - dim,o_);
1285 // extra outer loop around double_var_decl
1286 void operator()(vector_var_decl const& x) const {
1287 std::vector<expression> dims = x.dims_;
1289 o_ << INDENT2 << "if (!context__.contains_r(\"" << x.name_ << "\"))" << EOL;
1290 o_ << INDENT3 << "throw std::runtime_error(\"variable " << x.name_ <<" not found.\");" << EOL;
1291 o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1292 o_ << INDENT2 << "pos__ = 0;" << EOL;
1293 o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
1294 generate_expression(x.M_,o_);
1296 o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
1297 size_t indentation = 2;
1298 for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1299 size_t dim = dims.size() - dim_up - 1U;
1301 generate_indent(indentation,o_);
1302 o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1303 generate_expression(dims[dim],o_);
1305 generate_indent(indentation,o_);
1306 o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1308 generate_indent(indentation+1,o_);
1310 for (size_t dim = 0; dim < dims.size(); ++dim)
1311 o_ << "[i_" << dim << "__]";
1313 o_ << " = vals_r__[pos__++];" << EOL;
1314 for (size_t dim = 0; dim < dims.size(); ++dim) {
1315 generate_indent(dims.size() + 2 - dim,o_);
1318 o_ << INDENT2 << "}" << EOL;
1320 // change variable name from vector_var_decl
1321 void operator()(row_vector_var_decl const& x) const {
1322 std::vector<expression> dims = x.dims_;
1324 o_ << INDENT2 << "if (!context__.contains_r(\"" << x.name_ << "\"))" << EOL;
1325 o_ << INDENT3 << "throw std::runtime_error(\"variable " << x.name_ <<" not found.\");" << EOL;
1326 o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1327 o_ << INDENT2 << "pos__ = 0;" << EOL;
1328 o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
1329 generate_expression(x.N_,o_);
1331 o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
1332 size_t indentation = 2;
1333 for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1334 size_t dim = dims.size() - dim_up - 1U;
1336 generate_indent(indentation,o_);
1337 o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1338 generate_expression(dims[dim],o_);
1340 generate_indent(indentation,o_);
1341 o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1343 generate_indent(indentation+1,o_);
1345 for (size_t dim = 0; dim < dims.size(); ++dim)
1346 o_ << "[i_" << dim << "__]";
1348 o_ << " = vals_r__[pos__++];" << EOL;
1349 for (size_t dim = 0; dim < dims.size(); ++dim) {
1350 generate_indent(dims.size() + 2 - dim,o_);
1353 o_ << INDENT2 << "}" << EOL;
1355 // diff name of dims from vector
1356 void operator()(simplex_var_decl const& x) const {
1357 std::vector<expression> dims = x.dims_;
1359 o_ << INDENT2 << "if (!context__.contains_r(\"" << x.name_ << "\"))" << EOL;
1360 o_ << INDENT3 << "throw std::runtime_error(\"variable " << x.name_ <<" not found.\");" << EOL;
1361 o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1362 o_ << INDENT2 << "pos__ = 0;" << EOL;
1363 o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
1364 generate_expression(x.K_,o_);
1366 o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
1367 size_t indentation = 2;
1368 for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1369 size_t dim = dims.size() - dim_up - 1U;
1371 generate_indent(indentation,o_);
1372 o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1373 generate_expression(dims[dim],o_);
1375 generate_indent(indentation,o_);
1376 o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1378 generate_indent(indentation+1,o_);
1380 for (size_t dim = 0; dim < dims.size(); ++dim)
1381 o_ << "[i_" << dim << "__]";
1383 o_ << " = vals_r__[pos__++];" << EOL;
1384 for (size_t dim = 0; dim < dims.size(); ++dim) {
1385 generate_indent(dims.size() + 2 - dim,o_);
1388 o_ << INDENT2 << "}" << EOL;
1391 void operator()(ordered_var_decl const& x) const {
1392 std::vector<expression> dims = x.dims_;
1394 o_ << INDENT2 << "if (!context__.contains_r(\"" << x.name_ << "\"))" << EOL;
1395 o_ << INDENT3 << "throw std::runtime_error(\"variable " << x.name_ <<" not found.\");" << EOL;
1396 o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1397 o_ << INDENT2 << "pos__ = 0;" << EOL;
1398 o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
1399 generate_expression(x.K_,o_);
1401 o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
1402 size_t indentation = 2;
1403 for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1404 size_t dim = dims.size() - dim_up - 1U;
1406 generate_indent(indentation,o_);
1407 o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1408 generate_expression(dims[dim],o_);
1410 generate_indent(indentation,o_);
1411 o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1413 generate_indent(indentation+1,o_);
1415 for (size_t dim = 0; dim < dims.size(); ++dim)
1416 o_ << "[i_" << dim << "__]";
1418 o_ << " = vals_r__[pos__++];" << EOL;
1419 for (size_t dim = 0; dim < dims.size(); ++dim) {
1420 generate_indent(dims.size() + 2 - dim,o_);
1423 o_ << INDENT2 << "}" << EOL;
1426 void operator()(positive_ordered_var_decl const& x) const {
1427 std::vector<expression> dims = x.dims_;
1429 o_ << INDENT2 << "if (!context__.contains_r(\"" << x.name_ << "\"))" << EOL;
1430 o_ << INDENT3 << "throw std::runtime_error(\"variable " << x.name_ <<" not found.\");" << EOL;
1431 o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1432 o_ << INDENT2 << "pos__ = 0;" << EOL;
1433 o_ << INDENT2 << "size_t " << x.name_ << "_i_vec_lim__ = ";
1434 generate_expression(x.K_,o_);
1436 o_ << INDENT2 << "for (size_t " << "i_vec__ = 0; " << "i_vec__ < " << x.name_ << "_i_vec_lim__; ++i_vec__) {" << EOL;
1437 size_t indentation = 2;
1438 for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1439 size_t dim = dims.size() - dim_up - 1U;
1441 generate_indent(indentation,o_);
1442 o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1443 generate_expression(dims[dim],o_);
1445 generate_indent(indentation,o_);
1446 o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1448 generate_indent(indentation+1,o_);
1450 for (size_t dim = 0; dim < dims.size(); ++dim)
1451 o_ << "[i_" << dim << "__]";
1453 o_ << " = vals_r__[pos__++];" << EOL;
1454 for (size_t dim = 0; dim < dims.size(); ++dim) {
1455 generate_indent(dims.size() + 2 - dim,o_);
1458 o_ << INDENT2 << "}" << EOL;
1460 // extra loop and different accessor vs. vector
1461 void operator()(matrix_var_decl const& x) const {
1462 std::vector<expression> dims = x.dims_;
1464 o_ << INDENT2 << "if (!context__.contains_r(\"" << x.name_ << "\"))" << EOL;
1465 o_ << INDENT3 << "throw std::runtime_error(\"variable " << x.name_ <<" not found.\");" << EOL;
1466 o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1467 o_ << INDENT2 << "pos__ = 0;" << EOL;
1468 o_ << INDENT2 << "size_t " << x.name_ << "_m_mat_lim__ = ";
1469 generate_expression(x.M_,o_);
1471 o_ << INDENT2 << "size_t " << x.name_ << "_n_mat_lim__ = ";
1472 generate_expression(x.N_,o_);
1474 o_ << INDENT2 << "for (size_t " << "n_mat__ = 0; " << "n_mat__ < " << x.name_ << "_n_mat_lim__; ++n_mat__) {" << EOL;
1475 o_ << INDENT3 << "for (size_t " << "m_mat__ = 0; " << "m_mat__ < " << x.name_ << "_m_mat_lim__; ++m_mat__) {" << EOL;
1476 size_t indentation = 3;
1477 for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1478 size_t dim = dims.size() - dim_up - 1U;
1480 generate_indent(indentation,o_);
1481 o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1482 generate_expression(dims[dim],o_);
1484 generate_indent(indentation,o_);
1485 o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1487 generate_indent(indentation+1,o_);
1489 for (size_t dim = 0; dim < dims.size(); ++dim)
1490 o_ << "[i_" << dim << "__]";
1491 o_ << "(m_mat__,n_mat__)";
1492 o_ << " = vals_r__[pos__++];" << EOL;
1493 for (size_t dim = 0; dim < dims.size(); ++dim) {
1494 generate_indent(dims.size() + 2 - dim,o_);
1497 o_ << INDENT3 << "}" << EOL;
1498 o_ << INDENT2 << "}" << EOL;
1500 void operator()(corr_matrix_var_decl const& x) const {
1501 std::vector<expression> dims = x.dims_;
1503 o_ << INDENT2 << "if (!context__.contains_r(\"" << x.name_ << "\"))" << EOL;
1504 o_ << INDENT3 << "throw std::runtime_error(\"variable " << x.name_ <<" not found.\");" << EOL;
1505 o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1506 o_ << INDENT2 << "pos__ = 0;" << EOL;
1507 o_ << INDENT2 << "size_t " << x.name_ << "_k_mat_lim__ = ";
1508 generate_expression(x.K_,o_);
1510 o_ << INDENT2 << "for (size_t " << "n_mat__ = 0; " << "n_mat__ < " << x.name_ << "_k_mat_lim__; ++n_mat__) {" << EOL;
1511 o_ << INDENT3 << "for (size_t " << "m_mat__ = 0; " << "m_mat__ < " << x.name_ << "_k_mat_lim__; ++m_mat__) {" << EOL;
1512 size_t indentation = 3;
1513 for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1514 size_t dim = dims.size() - dim_up - 1U;
1516 generate_indent(indentation,o_);
1517 o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1518 generate_expression(dims[dim],o_);
1520 generate_indent(indentation,o_);
1521 o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1523 generate_indent(indentation+1,o_);
1525 for (size_t dim = 0; dim < dims.size(); ++dim)
1526 o_ << "[i_" << dim << "__]";
1527 o_ << "(m_mat__,n_mat__)";
1528 o_ << " = vals_r__[pos__++];" << EOL;
1529 for (size_t dim = 0; dim < dims.size(); ++dim) {
1530 generate_indent(dims.size() + 2 - dim,o_);
1533 o_ << INDENT3 << "}" << EOL;
1534 o_ << INDENT2 << "}" << EOL;
1536 void operator()(cov_matrix_var_decl const& x) const {
1537 std::vector<expression> dims = x.dims_;
1539 o_ << INDENT2 << "if (!context__.contains_r(\"" << x.name_ << "\"))" << EOL;
1540 o_ << INDENT3 << "throw std::runtime_error(\"variable " << x.name_ <<" not found.\");" << EOL;
1541 o_ << INDENT2 << "vals_r__ = context__.vals_r(\"" << x.name_ << "\");" << EOL;
1542 o_ << INDENT2 << "pos__ = 0;" << EOL;
1543 o_ << INDENT2 << "size_t " << x.name_ << "_k_mat_lim__ = ";
1544 generate_expression(x.K_,o_);
1546 o_ << INDENT2 << "for (size_t " << "n_mat__ = 0; " << "n_mat__ < " << x.name_ << "_k_mat_lim__; ++n_mat__) {" << EOL;
1547 o_ << INDENT3 << "for (size_t " << "m_mat__ = 0; " << "m_mat__ < " << x.name_ << "_k_mat_lim__; ++m_mat__) {" << EOL;
1548 size_t indentation = 3;
1549 for (size_t dim_up = 0U; dim_up < dims.size(); ++dim_up) {
1550 size_t dim = dims.size() - dim_up - 1U;
1552 generate_indent(indentation,o_);
1553 o_ << "size_t " << x.name_ << "_limit_" << dim << "__ = ";
1554 generate_expression(dims[dim],o_);
1556 generate_indent(indentation,o_);
1557 o_ << "for (size_t i_" << dim << "__ = 0; i_" << dim << "__ < " << x.name_ << "_limit_" << dim << "__; ++i_" << dim << "__) {" << EOL;
1559 generate_indent(indentation+1,o_);
1561 for (size_t dim = 0; dim < dims.size(); ++dim)
1562 o_ << "[i_" << dim << "__]";
1563 o_ << "(m_mat__,n_mat__)";
1564 o_ << " = vals_r__[pos__++];" << EOL;
1565 for (size_t dim = 0; dim < dims.size(); ++dim) {
1566 generate_indent(dims.size() + 2 - dim,o_);
1569 o_ << INDENT3 << "}" << EOL;
1570 o_ << INDENT2 << "}" << EOL;
1574 void suppress_warning(const std::string& indent,
1575 const std::string& var_name,
1577 o << indent << "(void) "
1579 << " // dummy call to supress warning"
1583 void generate_member_var_inits(const std::vector<var_decl>& vs,
1585 dump_member_var_visgen vis(o);
1586 for (size_t i = 0; i < vs.size(); ++i)
1587 boost::apply_visitor(vis, vs[i].decl_);
1590 void generate_constructor(const program& prog,
1591 const std::string& model_name,
1593 o << INDENT << model_name << "(stan::io::var_context& context__,";
1594 o << INDENT << " std::ostream* pstream__ = 0)"
1596 o << INDENT2 << ": prob_grad_ad::prob_grad_ad(0) {"
1597 << EOL; // resize 0 with var_resizing
1598 o << INDENT2 << "static const char* function__ = \""
1599 << model_name << "_namespace::" << model_name << "(%1%)\";" << EOL;
1600 suppress_warning(INDENT2, "function__", o);
1601 o << INDENT2 << "size_t pos__;" << EOL;
1602 suppress_warning(INDENT2, "pos__", o);
1603 o << INDENT2 << "std::vector<int> vals_i__;" << EOL;
1604 o << INDENT2 << "std::vector<double> vals_r__;" << EOL;
1606 generate_member_var_inits(prog.data_decl_,o);
1608 generate_comment("validate data",2,o);
1609 generate_validate_var_decls(prog.data_decl_,2,o);
1611 generate_var_resizing(prog.derived_data_decl_.first, o);
1613 static bool include_sampling = false;
1614 static bool is_var = false;
1615 for (size_t i = 0; i < prog.derived_data_decl_.second.size(); ++i)
1616 generate_statement(prog.derived_data_decl_.second[i],
1617 2,o,include_sampling,is_var);
1619 generate_comment("validate transformed data",2,o);
1620 generate_validate_var_decls(prog.derived_data_decl_.first,2,o);
1622 o << EOL << INDENT2 << "set_param_ranges();" << EOL;
1623 o << INDENT << "} // dump ctor" << EOL;
1626 struct generate_init_visgen : public visgen {
1627 generate_init_visgen(std::ostream& o)
1630 void operator()(nil const& x) const { } // dummy
1631 void operator()(int_var_decl const& x) const {
1632 generate_check_int(x.name_,x.dims_.size());
1633 generate_declaration(x.name_,"int",x.dims_);
1634 generate_buffer_loop("i",x.name_, x.dims_);
1635 generate_write_loop("integer(",x.name_,x.dims_);
1637 template <typename D>
1638 std::string function_args(const std::string& fun_prefix,
1640 std::stringstream ss;
1643 ss << "_lub_unconstrain(";
1644 generate_expression(x.range_.low_.expr_,ss);
1646 generate_expression(x.range_.high_.expr_,ss);
1648 } else if (has_lb(x)) {
1649 ss << "_lb_unconstrain(";
1650 generate_expression(x.range_.low_.expr_,ss);
1652 } else if (has_ub(x)) {
1653 ss << "_ub_unconstrain(";
1654 generate_expression(x.range_.high_.expr_,ss);
1657 ss << "_unconstrain(";
1662 void operator()(double_var_decl const& x) const {
1663 generate_check_double(x.name_,x.dims_.size());
1664 generate_declaration(x.name_,"double",x.dims_);
1665 generate_buffer_loop("r",x.name_,x.dims_);
1666 generate_write_loop(function_args("scalar",x),
1669 void operator()(vector_var_decl const& x) const {
1670 generate_check_double(x.name_,x.dims_.size() + 1);
1671 generate_declaration(x.name_,"vector_d",x.dims_,x.M_);
1672 generate_buffer_loop("r",x.name_,x.dims_,x.M_);
1673 generate_write_loop(function_args("vector",x),
1676 void operator()(row_vector_var_decl const& x) const {
1677 generate_check_double(x.name_,x.dims_.size() + 1);
1678 generate_declaration(x.name_,"row_vector_d",x.dims_,x.N_);
1679 generate_buffer_loop("r",x.name_,x.dims_,x.N_);
1680 generate_write_loop(function_args("row_vector",x),
1683 void operator()(matrix_var_decl const& x) const {
1684 generate_check_double(x.name_,x.dims_.size() + 2);
1685 generate_declaration(x.name_,"matrix_d",x.dims_,x.M_,x.N_);
1686 generate_buffer_loop("r",x.name_,x.dims_,x.M_,x.N_);
1687 generate_write_loop(function_args("matrix",x),
1690 void operator()(simplex_var_decl const& x) const {
1691 generate_check_double(x.name_,x.dims_.size() + 1);
1692 generate_declaration(x.name_,"vector_d",x.dims_,x.K_);
1693 generate_buffer_loop("r",x.name_,x.dims_,x.K_);
1694 generate_write_loop("simplex_unconstrain(",x.name_,x.dims_);
1696 void operator()(ordered_var_decl const& x) const {
1697 generate_check_double(x.name_,x.dims_.size() + 1);
1698 generate_declaration(x.name_,"vector_d",x.dims_,x.K_);
1699 generate_buffer_loop("r",x.name_,x.dims_,x.K_);
1700 generate_write_loop("ordered_unconstrain(",x.name_,x.dims_);
1702 void operator()(positive_ordered_var_decl const& x) const {
1703 generate_check_double(x.name_,x.dims_.size() + 1);
1704 generate_declaration(x.name_,"vector_d",x.dims_,x.K_);
1705 generate_buffer_loop("r",x.name_,x.dims_,x.K_);
1706 generate_write_loop("positive_ordered_unconstrain(",x.name_,x.dims_);
1708 void operator()(cov_matrix_var_decl const& x) const {
1709 generate_check_double(x.name_,x.dims_.size() + 2);
1710 generate_declaration(x.name_,"matrix_d",x.dims_,x.K_,x.K_);
1711 generate_buffer_loop("r",x.name_,x.dims_,x.K_,x.K_);
1712 generate_write_loop("cov_matrix_unconstrain(",x.name_,x.dims_);
1714 void operator()(corr_matrix_var_decl const& x) const {
1715 generate_check_double(x.name_,x.dims_.size() + 2);
1716 generate_declaration(x.name_,"matrix_d",x.dims_,x.K_,x.K_);
1717 generate_buffer_loop("r",x.name_,x.dims_,x.K_,x.K_);
1718 generate_write_loop("corr_matrix_unconstrain(",x.name_,x.dims_);
1720 void generate_write_loop(const std::string& write_method_name,
1721 const std::string& var_name,
1722 const std::vector<expression>& dims) const {
1723 generate_dims_loop_fwd(dims);
1724 o_ << "writer__." << write_method_name;
1725 generate_name_dims(var_name,dims.size());
1728 void generate_name_dims(const std::string name,
1729 size_t num_dims) const {
1731 for (size_t i = 0; i < num_dims; ++i)
1732 o_ << "[i" << i << "__]";
1734 void generate_declaration(const std::string& name,
1735 const std::string& base_type,
1736 const std::vector<expression>& dims,
1737 const expression& type_arg1 = expression(),
1738 const expression& type_arg2 = expression()) const {
1740 generate_type(base_type,dims,dims.size(),o_);
1743 generate_initializer(o_,base_type,dims,type_arg1,type_arg2);
1745 void generate_indent_num_dims(size_t base_indent,
1746 const std::vector<expression>& dims,
1747 const expression& dim1,
1748 const expression& dim2) const {
1749 generate_indent(dims.size() + base_indent,o_);
1750 if (!is_nil(dim1)) o_ << INDENT;
1751 if (!is_nil(dim2)) o_ << INDENT;
1753 void generate_buffer_loop(const std::string& base_type,
1754 const std::string& name,
1755 const std::vector<expression>& dims,
1756 const expression& dim1 = expression(),
1757 const expression& dim2 = expression(),
1758 int indent = 2U) const {
1759 size_t size = dims.size();
1760 bool is_matrix = !is_nil(dim1) && !is_nil(dim2);
1761 bool is_vector = !is_nil(dim1) && is_nil(dim2);
1762 int extra_indent = is_matrix ? 2U : is_vector ? 1U : 0U;
1764 generate_indent(indent,o_);
1765 o_ << "for (int j2__ = 0U; j2__ < ";
1766 generate_expression(dim2.expr_,o_);
1767 o_ << "; ++j2__)" << EOL;
1769 generate_indent(indent+1,o_);
1770 o_ << "for (int j1__ = 0U; j1__ < ";
1771 generate_expression(dim1.expr_,o_);
1772 o_ << "; ++j1__)" << EOL;
1773 } else if (is_vector) {
1774 generate_indent(indent,o_);
1775 o_ << "for (int j1__ = 0U; j1__ < ";
1776 generate_expression(dim1.expr_,o_);
1777 o_ << "; ++j1__)" << EOL;
1779 for (size_t i = 0; i < size; ++i) {
1780 size_t idx = size - i - 1;
1781 generate_indent(i + indent + extra_indent, o_);
1782 o_ << "for (int i" << idx << "__ = 0U; i" << idx << "__ < ";
1783 generate_expression(dims[idx].expr_,o_);
1784 o_ << "; ++i" << idx << "__)" << EOL;
1786 generate_indent_num_dims(2U,dims,dim1,dim2);
1788 for (size_t i = 0; i < dims.size(); ++i)
1789 o_ << "[i" << i << "__]";
1791 o_ << "(j1__,j2__)";
1794 o_ << " = vals_" << base_type << "__[pos__++];" << EOL;
1796 void generate_dims_loop_fwd(const std::vector<expression>& dims,
1797 int indent = 2U) const {
1798 size_t size = dims.size();
1799 for (size_t i = 0; i < size; ++i) {
1800 generate_indent(i + indent, o_);
1801 o_ << "for (int i" << i << "__ = 0U; i" << i << "__ < ";
1802 generate_expression(dims[i].expr_,o_);
1803 o_ << "; ++i" << i << "__)" << EOL;
1805 generate_indent(2U + dims.size(),o_);
1807 void generate_check_int(const std::string& name, size_t n) const {
1808 o_ << EOL << INDENT2
1809 << "if (!(var_context__.contains_i(\"" << name << "\")))"
1811 << "throw std::runtime_error(\"variable " << name << " missing\");" << EOL;
1813 << "if (var_context__.dims_i(\"" << name << "\").size() != " << n << ")"
1815 << "throw std::runtime_error(\"require "
1816 << n << " dimensionss for variable "
1817 << name << "\");" << EOL;
1818 o_ << INDENT2 << "vals_i__ = var_context__.vals_i(\"" << name << "\");" << EOL;
1819 o_ << INDENT2 << "pos__ = 0U;" << EOL;
1821 void generate_check_double(const std::string& name, size_t n) const {
1822 o_ << EOL << INDENT2
1823 << "if (!(var_context__.contains_r(\"" << name << "\")))"
1825 << "throw std::runtime_error(\"variable " << name << " missing\");" << EOL;
1827 << "if (var_context__.dims_r(\"" << name << "\").size() != " << n << ")"
1829 << "throw std::runtime_error(\"require "
1830 << n << " dimensions for variable "
1831 << name << "\");" << EOL;
1832 o_ << INDENT2 << "vals_r__ = var_context__.vals_r(\"" << name << "\");" << EOL;
1833 o_ << INDENT2 << "pos__ = 0U;" << EOL;
1838 void generate_init_method(const std::vector<var_decl>& vs,
1841 o << INDENT << "void transform_inits(const stan::io::var_context& var_context__," << EOL;
1842 o << INDENT << " std::vector<int>& params_i__," << EOL;
1843 o << INDENT << " std::vector<double>& params_r__) {" << EOL;
1844 o << INDENT2 << "params_r__.clear();" << EOL;
1845 o << INDENT2 << "params_i__.clear();" << EOL;
1846 o << INDENT2 << "stan::io::writer<double> writer__(params_r__,params_i__);" << EOL;
1847 o << INDENT2 << "size_t pos__;" << EOL;
1848 o << INDENT2 << "std::vector<double> vals_r__;" << EOL;
1849 o << INDENT2 << "std::vector<int> vals_i__;" << EOL;
1851 generate_init_visgen vis(o);
1852 for (size_t i = 0; i < vs.size(); ++i)
1853 boost::apply_visitor(vis, vs[i].decl_);
1855 o << INDENT2 << "params_r__ = writer__.data_r();" << EOL;
1856 o << INDENT2 << "params_i__ = writer__.data_i();" << EOL;
1857 o << INDENT << "}" << EOL;
1860 // see write_csv_visgen for similar structure
1861 struct write_dims_visgen : public visgen {
1862 write_dims_visgen(std::ostream& o)
1865 void operator()(const nil& x) const { }
1866 void operator()(const int_var_decl& x) const {
1867 generate_dims_array(EMPTY_EXP_VECTOR,x.dims_);
1869 void operator()(const double_var_decl& x) const {
1870 generate_dims_array(EMPTY_EXP_VECTOR,x.dims_);
1872 void operator()(const vector_var_decl& x) const {
1873 std::vector<expression> matrix_args;
1874 matrix_args.push_back(x.M_);
1875 generate_dims_array(matrix_args,x.dims_);
1877 void operator()(const row_vector_var_decl& x) const {
1878 std::vector<expression> matrix_args;
1879 matrix_args.push_back(x.N_);
1880 generate_dims_array(matrix_args,x.dims_);
1882 void operator()(const matrix_var_decl& x) const {
1883 std::vector<expression> matrix_args;
1884 matrix_args.push_back(x.M_);
1885 matrix_args.push_back(x.N_);
1886 generate_dims_array(matrix_args,x.dims_);
1888 void operator()(const simplex_var_decl& x) const {
1889 std::vector<expression> matrix_args;
1890 matrix_args.push_back(x.K_);
1891 generate_dims_array(matrix_args,x.dims_);
1893 void operator()(const ordered_var_decl& x) const {
1894 std::vector<expression> matrix_args;
1895 matrix_args.push_back(x.K_);
1896 generate_dims_array(matrix_args,x.dims_);
1898 void operator()(const positive_ordered_var_decl& x) const {
1899 std::vector<expression> matrix_args;
1900 matrix_args.push_back(x.K_);
1901 generate_dims_array(matrix_args,x.dims_);
1903 void operator()(const cov_matrix_var_decl& x) const {
1904 std::vector<expression> matrix_args;
1905 matrix_args.push_back(x.K_);
1906 matrix_args.push_back(x.K_);
1907 generate_dims_array(matrix_args,x.dims_);
1909 void operator()(const corr_matrix_var_decl& x) const {
1910 std::vector<expression> matrix_args;
1911 matrix_args.push_back(x.K_);
1912 matrix_args.push_back(x.K_);
1913 generate_dims_array(matrix_args,x.dims_);
1916 generate_dims_array(const std::vector<expression>& matrix_dims_exprs,
1917 const std::vector<expression>& array_dims_exprs)
1920 o_ << INDENT2 << "dims__.resize(0);" << EOL;
1921 for (size_t i = 0; i < array_dims_exprs.size(); ++i) {
1922 o_ << INDENT2 << "dims__.push_back(";
1923 generate_expression(array_dims_exprs[i].expr_, o_);
1926 // cut and paste above with matrix_dims_exprs
1927 for (size_t i = 0; i < matrix_dims_exprs.size(); ++i) {
1928 o_ << INDENT2 << "dims__.push_back(";
1929 generate_expression(matrix_dims_exprs[i].expr_, o_);
1932 o_ << INDENT2 << "dimss__.push_back(dims__);" << EOL;
1937 void generate_dims_method(const program& prog,
1939 write_dims_visgen vis(o);
1941 << "void get_dims(std::vector<std::vector<size_t> >& dimss__) {"
1944 o << INDENT2 << "dimss__.resize(0);" << EOL;
1945 o << INDENT2 << "std::vector<size_t> dims__;" << EOL;
1948 for (size_t i = 0; i < prog.parameter_decl_.size(); ++i) {
1949 boost::apply_visitor(vis,prog.parameter_decl_[i].decl_);
1951 // transformed parameters
1952 for (size_t i = 0; i < prog.derived_decl_.first.size(); ++i) {
1953 boost::apply_visitor(vis,prog.derived_decl_.first[i].decl_);
1955 // generated quantities
1956 for (size_t i = 0; i < prog.generated_decl_.first.size(); ++i) {
1957 boost::apply_visitor(vis,prog.generated_decl_.first[i].decl_);
1959 o << INDENT << "}" << EOL2;
1964 // see write_csv_visgen for similar structure
1965 struct write_param_names_visgen : public visgen {
1966 write_param_names_visgen(std::ostream& o)
1969 void operator()(const nil& x) const { }
1970 void operator()(const int_var_decl& x) const {
1971 generate_param_names(x.name_);
1973 void operator()(const double_var_decl& x) const {
1974 generate_param_names(x.name_);
1976 void operator()(const vector_var_decl& x) const {
1977 generate_param_names(x.name_);
1979 void operator()(const row_vector_var_decl& x) const {
1980 generate_param_names(x.name_);
1982 void operator()(const matrix_var_decl& x) const {
1983 generate_param_names(x.name_);
1985 void operator()(const simplex_var_decl& x) const {
1986 generate_param_names(x.name_);
1988 void operator()(const ordered_var_decl& x) const {
1989 generate_param_names(x.name_);
1991 void operator()(const positive_ordered_var_decl& x) const {
1992 generate_param_names(x.name_);
1994 void operator()(const cov_matrix_var_decl& x) const {
1995 generate_param_names(x.name_);
1997 void operator()(const corr_matrix_var_decl& x) const {
1998 generate_param_names(x.name_);
2001 generate_param_names(const std::string& name) const {
2003 << "names__.push_back(\"" << name << "\");"
2009 void generate_param_names_method(const program& prog,
2011 write_param_names_visgen vis(o);
2013 << "void get_param_names(std::vector<std::string>& names__) {"
2017 << "names__.resize(0);"
2021 for (size_t i = 0; i < prog.parameter_decl_.size(); ++i) {
2022 boost::apply_visitor(vis,prog.parameter_decl_[i].decl_);
2024 // transformed parameters
2025 for (size_t i = 0; i < prog.derived_decl_.first.size(); ++i) {
2026 boost::apply_visitor(vis,prog.derived_decl_.first[i].decl_);
2028 // generated quantities
2029 for (size_t i = 0; i < prog.generated_decl_.first.size(); ++i) {
2030 boost::apply_visitor(vis,prog.generated_decl_.first[i].decl_);
2033 o << INDENT << "}" << EOL2;
2038 // see write_csv_visgen for similar structure
2039 struct write_csv_header_visgen : public visgen {
2040 write_csv_header_visgen(std::ostream& o)
2043 void operator()(const nil& x) const { }
2044 void operator()(const int_var_decl& x) const {
2045 generate_csv_header_array(EMPTY_EXP_VECTOR,x.name_,x.dims_);
2047 void operator()(const double_var_decl& x) const {
2048 generate_csv_header_array(EMPTY_EXP_VECTOR,x.name_,x.dims_);
2050 void operator()(const vector_var_decl& x) const {
2051 std::vector<expression> matrix_args;
2052 matrix_args.push_back(x.M_);
2053 generate_csv_header_array(matrix_args,x.name_,x.dims_);
2055 void operator()(const row_vector_var_decl& x) const {
2056 std::vector<expression> matrix_args;
2057 matrix_args.push_back(x.N_);
2058 generate_csv_header_array(matrix_args,x.name_,x.dims_);
2060 void operator()(const matrix_var_decl& x) const {
2061 std::vector<expression> matrix_args;
2062 matrix_args.push_back(x.M_);
2063 matrix_args.push_back(x.N_);
2064 generate_csv_header_array(matrix_args,x.name_,x.dims_);
2066 void operator()(const simplex_var_decl& x) const {
2067 std::vector<expression> matrix_args;
2068 matrix_args.push_back(x.K_);
2069 generate_csv_header_array(matrix_args,x.name_,x.dims_);
2071 void operator()(const ordered_var_decl& x) const {
2072 std::vector<expression> matrix_args;
2073 matrix_args.push_back(x.K_);
2074 generate_csv_header_array(matrix_args,x.name_,x.dims_);
2076 void operator()(const positive_ordered_var_decl& x) const {
2077 std::vector<expression> matrix_args;
2078 matrix_args.push_back(x.K_);
2079 generate_csv_header_array(matrix_args,x.name_,x.dims_);
2081 void operator()(const cov_matrix_var_decl& x) const {
2082 std::vector<expression> matrix_args;
2083 matrix_args.push_back(x.K_);
2084 matrix_args.push_back(x.K_);
2085 generate_csv_header_array(matrix_args,x.name_,x.dims_);
2087 void operator()(const corr_matrix_var_decl& x) const {
2088 std::vector<expression> matrix_args;
2089 matrix_args.push_back(x.K_);
2090 matrix_args.push_back(x.K_);
2091 generate_csv_header_array(matrix_args,x.name_,x.dims_);
2094 generate_csv_header_array(const std::vector<expression>& matrix_dims,
2095 const std::string& name,
2096 const std::vector<expression>& dims) const {
2098 // begin for loop dims
2099 std::vector<expression> combo_dims(dims);
2100 for (size_t i = 0; i < matrix_dims.size(); ++i)
2101 combo_dims.push_back(matrix_dims[i]);
2103 for (size_t i = 0; i < combo_dims.size(); ++i) {
2104 generate_indent(2 + i,o_);
2105 o_ << "for (int k_" << i << "__ = 1;"
2106 << " k_" << i << "__ <= ";
2107 generate_expression(combo_dims[i].expr_,o_);
2108 o_ << "; ++k_" << i << "__) {" << EOL; // begin (1)
2111 // variable + indices
2112 generate_indent(2 + combo_dims.size(),o_);
2113 o_ << "writer__.comma();" << EOL; // only writes comma after first call
2115 generate_indent(2 + combo_dims.size(),o_);
2116 o_ << "o__ << \"" << name << '"';
2117 for (size_t i = 0; i < combo_dims.size(); ++i)
2118 o_ << " <<
'.' << k_
" << i << "__
";
2121 // end for loop dims
2122 for (size_t i = 0; i < combo_dims.size(); ++i) {
2123 generate_indent(1 + combo_dims.size() - i,o_);
2124 o_ << "}
" << EOL; // end (1)
2130 void generate_write_csv_header_method(const program& prog,
2132 write_csv_header_visgen vis(o);
2133 o << EOL << INDENT << "void write_csv_header(std::ostream& o__) {
" << EOL;
2137 for (size_t i = 0; i < prog.parameter_decl_.size(); ++i) {
2138 boost::apply_visitor(vis,prog.parameter_decl_[i].decl_);
2140 // transformed parameters
2141 for (size_t i = 0; i < prog.derived_decl_.first.size(); ++i) {
2142 boost::apply_visitor(vis,prog.derived_decl_.first[i].decl_);
2144 // generated quantities
2145 for (size_t i = 0; i < prog.generated_decl_.first.size(); ++i) {
2146 boost::apply_visitor(vis,prog.generated_decl_.first[i].decl_);
2148 o << INDENT2 << "writer__.
newline();
" << EOL;
2149 o << INDENT << "}
" << EOL2;
2152 // see init_member_var_visgen for cut & paste
2153 struct write_csv_visgen : public visgen {
2154 write_csv_visgen(std::ostream& o)
2157 template <typename D>
2158 void generate_initialize_array_bounded(const D& x, const std::string& base_type,
2159 const std::string& read_fun_prefix,
2160 const std::vector<expression>& dim_args) const {
2161 std::vector<expression> read_args;
2162 std::string read_fun(read_fun_prefix);
2165 read_args.push_back(x.range_.low_);
2166 read_args.push_back(x.range_.high_);
2167 } else if (has_lb(x)) {
2169 read_args.push_back(x.range_.low_);
2170 } else if (has_ub(x)) {
2172 read_args.push_back(x.range_.high_);
2174 for (size_t i = 0; i < dim_args.size(); ++i)
2175 read_args.push_back(dim_args[i]);
2176 generate_initialize_array(base_type,read_fun,read_args,x.name_,x.dims_);
2178 void operator()(const nil& x) const { }
2179 void operator()(const int_var_decl& x) const {
2180 generate_initialize_array("int","integer
",EMPTY_EXP_VECTOR,
2183 void operator()(const double_var_decl& x) const {
2184 std::vector<expression> read_args;
2185 generate_initialize_array_bounded(x,"double","scalar
",read_args);
2187 void operator()(const vector_var_decl& x) const {
2188 std::vector<expression> read_args;
2189 read_args.push_back(x.M_);
2190 generate_initialize_array_bounded(x,"vector_d","vector
",read_args);
2192 void operator()(const row_vector_var_decl& x) const {
2193 std::vector<expression> read_args;
2194 read_args.push_back(x.N_);
2195 generate_initialize_array_bounded(x,"row_vector_d","row_vector
",read_args);
2197 void operator()(const matrix_var_decl& x) const {
2198 std::vector<expression> read_args;
2199 read_args.push_back(x.M_);
2200 read_args.push_back(x.N_);
2201 generate_initialize_array_bounded(x,"matrix_d","matrix
",read_args);
2203 void operator()(const simplex_var_decl& x) const {
2204 std::vector<expression> read_args;
2205 read_args.push_back(x.K_);
2206 generate_initialize_array("vector_d","simplex
",read_args,x.name_,x.dims_);
2208 void operator()(const ordered_var_decl& x) const {
2209 std::vector<expression> read_args;
2210 read_args.push_back(x.K_);
2211 generate_initialize_array("vector_d","ordered
",read_args,x.name_,x.dims_);
2213 void operator()(const positive_ordered_var_decl& x) const {
2214 std::vector<expression> read_args;
2215 read_args.push_back(x.K_);
2216 generate_initialize_array("vector_d","positive_ordered
",read_args,x.name_,x.dims_);
2218 void operator()(const cov_matrix_var_decl& x) const {
2219 std::vector<expression> read_args;
2220 read_args.push_back(x.K_);
2221 generate_initialize_array("matrix_d","cov_matrix
",read_args,x.name_,x.dims_);
2223 void operator()(const corr_matrix_var_decl& x) const {
2224 std::vector<expression> read_args;
2225 read_args.push_back(x.K_);
2226 generate_initialize_array("matrix_d","corr_matrix
",read_args,x.name_,x.dims_);
2228 void generate_initialize_array(const std::string& var_type,
2229 const std::string& read_type,
2230 const std::vector<expression>& read_args,
2231 const std::string& name,
2232 const std::vector<expression>& dims) const {
2233 if (dims.size() == 0) {
2234 generate_indent(2,o_);
2235 o_ << var_type << " ";
2236 o_ << name << " = in__.
" << read_type << "_constrain(
";
2237 for (size_t j = 0; j < read_args.size(); ++j) {
2238 if (j > 0) o_ << ",
";
2239 generate_expression(read_args[j],o_);
2242 o_ << INDENT2 << "writer__.write(
" << name << ");
" << EOL;
2246 for (size_t i = 0; i < dims.size(); ++i) o_ << "vector<
";
2248 for (size_t i = 0; i < dims.size(); ++i) o_ << ">
";
2249 o_ << name << ";
" << EOL;
2250 std::string name_dims(name);
2251 for (size_t i = 0; i < dims.size(); ++i) {
2252 generate_indent(i + 2, o_);
2253 o_ << "size_t dim_
" << name << "_
" << i << "__ =
";
2254 generate_expression(dims[i],o_);
2256 if (i < dims.size() - 1) {
2257 generate_indent(i + 2, o_);
2258 o_ << name_dims << ".resize(dim_
" << name << "_
" << i << "__);
"
2260 name_dims.append("[k_
").append(to_string(i)).append("__]
");
2262 generate_indent(i + 2, o_);
2263 o_ << "for (
size_t k_
" << i << "__ = 0;
"
2264 << " k_
" << i << "__ < dim_
" << name << "_
" << i << "__;
"
2265 << " ++k_
" << i << "__) {
" << EOL;
2266 if (i == dims.size() - 1) {
2267 generate_indent(i + 3, o_);
2268 o_ << name_dims << ".push_back(in__.
" << read_type << "_constrain(
";
2269 for (size_t j = 0; j < read_args.size(); ++j) {
2270 if (j > 0) o_ << ",
";
2271 generate_expression(read_args[j],o_);
2276 generate_indent(dims.size() + 2, o_);
2277 o_ << "writer__.write(
" << name;
2278 if (dims.size() > 0) {
2280 for (size_t i = 0; i < dims.size(); ++i) {
2281 if (i > 0) o_ << "][
";
2282 o_ << "k_
" << i << "__
";
2288 for (size_t i = dims.size(); i > 0; --i) {
2289 generate_indent(i + 1, o_);
2298 struct write_csv_vars_visgen : public visgen {
2299 write_csv_vars_visgen(std::ostream& o)
2302 void operator()(const nil& x) const { }
2303 // FIXME: template these out
2304 void operator()(const int_var_decl& x) const {
2305 write_array(x.name_,x.dims_);
2307 void operator()(const double_var_decl& x) const {
2308 write_array(x.name_,x.dims_);
2310 void operator()(const vector_var_decl& x) const {
2311 write_array(x.name_,x.dims_);
2313 void operator()(const row_vector_var_decl& x) const {
2314 write_array(x.name_,x.dims_);
2316 void operator()(const matrix_var_decl& x) const {
2317 write_array(x.name_,x.dims_);
2319 void operator()(const simplex_var_decl& x) const {
2320 write_array(x.name_,x.dims_);
2322 void operator()(const ordered_var_decl& x) const {
2323 write_array(x.name_,x.dims_);
2325 void operator()(const positive_ordered_var_decl& x) const {
2326 write_array(x.name_,x.dims_);
2328 void operator()(const cov_matrix_var_decl& x) const {
2329 write_array(x.name_,x.dims_);
2331 void operator()(const corr_matrix_var_decl& x) const {
2332 write_array(x.name_,x.dims_);
2334 void write_array(const std::string& name,
2335 const std::vector<expression>& dims) const {
2336 if (dims.size() == 0) {
2337 o_ << INDENT2 << "writer__.write(
" << name << ");
" << EOL;
2340 for (size_t i = 0; i < dims.size(); ++i) {
2341 generate_indent(i + 2, o_);
2342 o_ << "for (
int k_
" << i << "__ = 0;
"
2343 << " k_
" << i << "__ <
";
2344 generate_expression(dims[i],o_);
2345 o_ << "; ++k_
" << i << "__) {
" << EOL;
2348 generate_indent(dims.size() + 2, o_);
2349 o_ << "writer__.write(
" << name;
2350 if (dims.size() > 0) {
2352 for (size_t i = 0; i < dims.size(); ++i) {
2353 if (i > 0) o_ << "][
";
2354 o_ << "k_
" << i << "__
";
2360 for (size_t i = dims.size(); i > 0; --i) {
2361 generate_indent(i + 1, o_);
2368 void generate_write_csv_method(const program& prog,
2369 const std::string& model_name,
2371 o << INDENT << "void write_csv(std::vector<double>& params_r__,
" << EOL;
2372 o << INDENT << " std::vector<int>& params_i__,
" << EOL;
2373 o << INDENT << " std::ostream& o__,
" << EOL;
2374 o << INDENT << " std::ostream* pstream__ = 0) {
" << EOL;
2378 o << INDENT2 << "static const char* function__ = \
""
2379 << model_name <<
"_namespace::write_csv(%1%)\";" <<
EOL;
2385 for (
size_t i = 0; i < prog.parameter_decl_.size(); ++i)
2386 boost::apply_visitor(vis,prog.parameter_decl_[i].decl_);
2398 static bool is_var =
false;
2401 static bool include_sampling =
false;
2409 for (
size_t i = 0; i < prog.derived_decl_.first.size(); ++i)
2410 boost::apply_visitor(vis_writer, prog.derived_decl_.first[i].decl_);
2424 for (
size_t i = 0; i < prog.generated_decl_.first.size(); ++i)
2425 boost::apply_visitor(vis_writer, prog.generated_decl_.first[i].decl_);
2426 if (prog.generated_decl_.first.size() > 0)
2429 o <<
INDENT2 <<
"writer__.newline();" <<
EOL;
2445 template <
typename D>
2447 const std::string& read_fun_prefix,
2448 const std::vector<expression>& dim_args)
const {
2449 std::vector<expression> read_args;
2450 std::string read_fun(read_fun_prefix);
2453 read_args.push_back(x.range_.low_);
2454 read_args.push_back(x.range_.high_);
2457 read_args.push_back(x.range_.low_);
2460 read_args.push_back(x.range_.high_);
2462 for (
size_t i = 0; i < dim_args.size(); ++i)
2463 read_args.push_back(dim_args[i]);
2468 std::vector<expression> read_args;
2472 std::vector<expression> read_args;
2473 read_args.push_back(x.
M_);
2477 std::vector<expression> read_args;
2478 read_args.push_back(x.
N_);
2482 std::vector<expression> read_args;
2483 read_args.push_back(x.
M_);
2484 read_args.push_back(x.
N_);
2488 std::vector<expression> read_args;
2489 read_args.push_back(x.
K_);
2493 std::vector<expression> read_args;
2494 read_args.push_back(x.
K_);
2498 std::vector<expression> read_args;
2499 read_args.push_back(x.
K_);
2503 std::vector<expression> read_args;
2504 read_args.push_back(x.
K_);
2508 std::vector<expression> read_args;
2509 read_args.push_back(x.
K_);
2513 const std::string& read_type,
2514 const std::vector<expression>& read_args,
2515 const std::string& name,
2516 const std::vector<expression>& dims)
const {
2517 if (dims.size() == 0) {
2519 o_ << var_type <<
" ";
2520 o_ << name <<
" = in__." << read_type <<
"_constrain(";
2521 for (
size_t j = 0; j < read_args.size(); ++j) {
2522 if (j > 0)
o_ <<
",";
2529 for (
size_t i = 0; i < dims.size(); ++i)
o_ <<
"vector<";
2531 for (
size_t i = 0; i < dims.size(); ++i)
o_ <<
"> ";
2532 o_ << name <<
";" <<
EOL;
2533 std::string name_dims(name);
2534 for (
size_t i = 0; i < dims.size(); ++i) {
2536 o_ <<
"size_t dim_" << name <<
"_" << i <<
"__ = ";
2539 if (i < dims.size() - 1) {
2541 o_ << name_dims <<
".resize(dim_" << name <<
"_" << i <<
"__);"
2543 name_dims.append(
"[k_").append(
to_string(i)).append(
"__]");
2546 o_ <<
"for (size_t k_" << i <<
"__ = 0;"
2547 <<
" k_" << i <<
"__ < dim_" << name <<
"_" << i <<
"__;"
2548 <<
" ++k_" << i <<
"__) {" <<
EOL;
2549 if (i == dims.size() - 1) {
2551 o_ << name_dims <<
".push_back(in__." << read_type <<
"_constrain(";
2552 for (
size_t j = 0; j < read_args.size(); ++j) {
2553 if (j > 0)
o_ <<
",";
2573 for (
size_t i = dims.size(); i > 0; --i) {
2598 std::vector<expression> dims(x.
dims_);
2599 dims.push_back(x.
M_);
2603 std::vector<expression> dims(x.
dims_);
2604 dims.push_back(x.
N_);
2608 std::vector<expression> matdims;
2609 matdims.push_back(x.
M_);
2610 matdims.push_back(x.
N_);
2614 std::vector<expression> dims(x.
dims_);
2615 dims.push_back(x.
K_);
2619 std::vector<expression> dims(x.
dims_);
2620 dims.push_back(x.
K_);
2624 std::vector<expression> dims(x.
dims_);
2625 dims.push_back(x.
K_);
2629 std::vector<expression> matdims;
2630 matdims.push_back(x.
K_);
2631 matdims.push_back(x.
K_);
2635 std::vector<expression> matdims;
2636 matdims.push_back(x.
K_);
2637 matdims.push_back(x.
K_);
2641 const std::vector<expression>& arraydims,
2642 const std::vector<expression>& matdims)
const {
2644 std::vector<expression> dims(arraydims);
2645 for (
size_t i = 0; i < matdims.size(); ++i)
2646 dims.push_back(matdims[i]);
2648 if (dims.size() == 0) {
2649 o_ <<
INDENT2 <<
"vars__.push_back(" << name <<
");" <<
EOL;
2654 for (
size_t i = dims.size(); i > 0; ) {
2657 o_ <<
"for (int k_" << i <<
"__ = 0;"
2658 <<
" k_" << i <<
"__ < ";
2660 o_ <<
"; ++k_" << i <<
"__) {" <<
EOL;
2664 o_ <<
"vars__.push_back(" << name;
2665 if (arraydims.size() > 0) {
2667 for (
size_t i = 0; i < arraydims.size(); ++i) {
2668 if (i > 0)
o_ <<
"][";
2669 o_ <<
"k_" << i <<
"__";
2673 if (matdims.size() > 0) {
2674 o_ <<
"(k_" << arraydims.size() <<
"__";
2675 if (matdims.size() > 1)
2676 o_ <<
", k_" << (arraydims.size() + 1) <<
"__";
2681 for (
size_t i = dims.size(); i > 0; --i) {
2690 const std::string& model_name,
2692 o <<
INDENT <<
"void write_array(std::vector<double>& params_r__," <<
EOL;
2693 o <<
INDENT <<
" std::vector<int>& params_i__," <<
EOL;
2694 o <<
INDENT <<
" std::vector<double>& vars__," <<
EOL;
2695 o <<
INDENT <<
" std::ostream* pstream__ = 0) {" <<
EOL;
2697 o <<
INDENT2 <<
"stan::io::reader<double> in__(params_r__,params_i__);" <<
EOL;
2698 o <<
INDENT2 <<
"static const char* function__ = \""
2699 << model_name <<
"_namespace::write_array(%1%)\";" <<
EOL;
2720 static bool is_var =
false;
2723 static bool include_sampling =
false;
2732 for (
size_t i = 0; i < prog.
derived_decl_.first.size(); ++i)
2733 boost::apply_visitor(vis_writer, prog.
derived_decl_.first[i].decl_);
2748 boost::apply_visitor(vis_writer, prog.
generated_decl_.first[i].decl_);
2765 for (
size_t i = 0; i < x.
dims_.size(); ++i) {
2767 o_ <<
"for (size_t i_" << i <<
"__ = 0; ";
2768 o_ <<
"i_" << i <<
"__ < ";
2770 o_ <<
"; ++i_" << i <<
"__) {" <<
EOL;
2774 o_ <<
"param_ranges_i__.push_back(std::pair<int,int>(";
2780 for (
size_t i = 0; i < x.
dims_.size(); ++i) {
2802 for (
size_t i = 0; i < x.
dims_.size(); ++i) {
2816 o_ <<
INDENT2 <<
"num_params_r__ += ((";
2820 o_ <<
" - 1)) / 2 + ";
2823 for (
size_t i = 0; i < x.
dims_.size(); ++i) {
2830 o_ <<
INDENT2 <<
"num_params_r__ += ((";
2834 o_ <<
" - 1)) / 2)";
2835 for (
size_t i = 0; i < x.
dims_.size(); ++i) {
2843 if (dims.size() == 0) {
2848 for (
size_t i = 0; i < dims.size(); ++i) {
2849 if (i > 0)
o_ <<
" * ";
2855 if (dims.size() == 0) {
2860 for (
size_t i = 0; i < dims.size(); ++i) {
2861 if (i > 0)
o_ <<
" * ";
2867 std::vector<expression> dims)
const {
2870 for (
size_t i = 0; i < dims.size(); ++i) {
2878 std::vector<expression> dims)
const {
2883 for (
size_t i = 0; i < dims.size(); ++i) {
2894 o <<
INDENT <<
"void set_param_ranges() {" <<
EOL;
2895 o <<
INDENT2 <<
"num_params_r__ = 0U;" <<
EOL;
2896 o <<
INDENT2 <<
"param_ranges_i__.clear();" <<
EOL;
2898 for (
size_t i = 0; i < var_decls.size(); ++i)
2899 boost::apply_visitor(vis,var_decls[i].decl_);
2904 std::ostream& out) {
2905 out <<
"int main(int argc, const char* argv[]) {" <<
EOL;
2907 out <<
INDENT2 <<
"stan::gm::nuts_command<" << model_name
2908 <<
"_namespace::" << model_name <<
">(argc,argv);" <<
EOL;
2909 out <<
INDENT <<
"} catch (std::exception& e) {" <<
EOL;
2911 <<
"std::cerr << std::endl << \"Exception: \" << e.what() << std::endl;"
2914 <<
"std::cerr << \"Diagnostic information: \" << std::endl << boost::diagnostic_information(e) << std::endl;"
2923 const std::string& model_name,
2925 bool include_main =
true) {