Stan  2.5.0
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
initialize_state.hpp
Go to the documentation of this file.
1 #ifndef STAN__COMMON__INITIALIZE_STATE_HPP
2 #define STAN__COMMON__INITIALIZE_STATE_HPP
3 
4 #include <string>
5 #include <iostream>
6 #include <math.h>
7 
9 
10 #include <boost/lexical_cast.hpp>
11 #include <boost/random/additive_combine.hpp> // L'Ecuyer RNG
12 #include <boost/random/uniform_real_distribution.hpp>
13 #include <boost/random/variate_generator.hpp>
14 
15 #include <stan/model/util.hpp>
16 #include <stan/gm/error_codes.hpp>
19 
20 namespace stan {
21  namespace common {
22 
32  template <class Model>
33  bool initialize_state_zero(Eigen::VectorXd& cont_params,
34  Model& model,
35  std::ostream* output) {
36  cont_params.setZero();
37 
38  double init_log_prob;
39  Eigen::VectorXd init_grad = Eigen::VectorXd::Zero(model.num_params_r());
40 
41  try {
42  stan::model::gradient(model, cont_params, init_log_prob, init_grad, output);
43  } catch (const std::exception& e) {
44  if (output)
45  *output << "Rejecting initialization at zero because of gradient failure."
46  << std::endl << e.what() << std::endl;
47  return false;
48  }
49 
50  if (!boost::math::isfinite(init_log_prob)) {
51  if (output)
52  *output << "Rejecting initialization at zero because of vanishing density."
53  << std::endl;
54  return false;
55  }
56 
57  for (int i = 0; i < init_grad.size(); ++i) {
58  if (!boost::math::isfinite(init_grad[i])) {
59  if (output)
60  *output << "Rejecting initialization at zero because of divergent gradient."
61  << std::endl;
62  return false;
63  }
64  }
65  return true;
66  }
67 
68 
81  template <class Model, class RNG>
82  bool initialize_state_random(const double R,
83  Eigen::VectorXd& cont_params,
84  Model& model,
85  RNG& base_rng,
86  std::ostream* output) {
87  int num_init_tries = -1;
88 
89  boost::random::uniform_real_distribution<double>
90  init_range_distribution(-R, R);
91 
92  boost::variate_generator<RNG&, boost::random::uniform_real_distribution<double> >
93  init_rng(base_rng, init_range_distribution);
94 
95  cont_params.setZero();
96 
97  // Random initializations until log_prob is finite
98  Eigen::VectorXd init_grad = Eigen::VectorXd::Zero(model.num_params_r());
99  static int MAX_INIT_TRIES = 100;
100 
101  for (num_init_tries = 1; num_init_tries <= MAX_INIT_TRIES; ++num_init_tries) {
102  for (int i = 0; i < cont_params.size(); ++i)
103  cont_params(i) = init_rng();
104 
105  double init_log_prob;
106  try {
107  stan::model::gradient(model, cont_params, init_log_prob, init_grad, &std::cout);
108  } catch (const std::exception& e) {
109  write_error_msg(output, e);
110  if (output)
111  *output << "Rejecting proposed initial value with zero density." << std::endl;
112  init_log_prob = -std::numeric_limits<double>::infinity();
113  }
114  if (!boost::math::isfinite(init_log_prob))
115  continue;
116  for (int i = 0; i < init_grad.size(); ++i)
117  if (!boost::math::isfinite(init_grad(i)))
118  continue;
119  break;
120 
121  }
122 
123  if (num_init_tries > MAX_INIT_TRIES) {
124  if (output)
125  *output << std::endl << std::endl
126  << "Initialization between (" << -R << ", " << R << ") failed after "
127  << MAX_INIT_TRIES << " attempts. " << std::endl
128  << " Try specifying initial values,"
129  << " reducing ranges of constrained values,"
130  << " or reparameterizing the model."
131  << std::endl;
132  return false;
133  }
134  return true;
135  }
136 
137 
153  template <class ContextFactory, class Model, class RNG>
154  bool initialize_state_source(const std::string source,
155  Eigen::VectorXd& cont_params,
156  Model& model,
157  RNG& base_rng,
158  std::ostream* output,
159  ContextFactory& context_factory) {
160  try {
161  typename ContextFactory::var_context_t context = context_factory(source);
162  model.transform_inits(context, cont_params);
163  } catch(const std::exception& e) {
164  if (output)
165  *output << "Initialization from source failed."
166  << std::endl << e.what() << std::endl;
167  return false;
168  }
169 
170  double init_log_prob;
171  Eigen::VectorXd init_grad = Eigen::VectorXd::Zero(model.num_params_r());
172 
173  try {
174  stan::model::gradient(model, cont_params, init_log_prob, init_grad, &std::cout);
175  } catch (const std::exception& e) {
176  if (output)
177  *output << "Rejecting user-specified initialization because of gradient failure."
178  << std::endl << e.what() << std::endl;
179  return false;
180  }
181 
182  if (!boost::math::isfinite(init_log_prob)) {
183  if (output)
184  *output << "Rejecting user-specified initialization because of vanishing density."
185  << std::endl;
186  return false;
187  }
188 
189  for (int i = 0; i < init_grad.size(); ++i) {
190  if (!boost::math::isfinite(init_grad[i])) {
191  if (output)
192  *output << "Rejecting user-specified initialization because of divergent gradient."
193  << std::endl;
194  return false;
195  }
196  }
197  return true;
198  }
199 
208  bool get_double_from_string(const std::string& s, double& val) {
209  try {
210  val = boost::lexical_cast<double>(s);
211  } catch (const boost::bad_lexical_cast& e) {
212  val = std::numeric_limits<double>::quiet_NaN();
213  return false;
214  }
215  return true;
216  }
217 
233  template <class ContextFactory, class Model, class RNG>
234  bool initialize_state(const std::string init,
235  Eigen::VectorXd& cont_params,
236  Model& model,
237  RNG& base_rng,
238  std::ostream* output,
239  ContextFactory& context_factory) {
240  double R;
241  if (get_double_from_string(init, R)) {
242  if (R == 0) {
243  return initialize_state_zero(cont_params, model, output);
244  } else {
245  return initialize_state_random(R, cont_params, model,
246  base_rng, output);
247  }
248  } else {
249  return initialize_state_source(init, cont_params, model,
250  base_rng, output,
251  context_factory);
252  }
253  return false;
254  }
255  } // common
256 } // stan
257 
258 #endif
bool get_double_from_string(const std::string &s, double &val)
Converts string to double.
bool initialize_state_source(const std::string source, Eigen::VectorXd &cont_params, Model &model, RNG &base_rng, std::ostream *output, ContextFactory &context_factory)
Creates the initial state using the source parameter.
bool isfinite(const stan::agrad::var &v)
Checks if the given number has finite value.
bool initialize_state_random(const double R, Eigen::VectorXd &cont_params, Model &model, RNG &base_rng, std::ostream *output)
Initializes state to random uniform values within range.
void gradient(const M &model, const Eigen::Matrix< double, Eigen::Dynamic, 1 > &x, double &f, Eigen::Matrix< double, Eigen::Dynamic, 1 > &grad_f, std::ostream *msgs=0)
Definition: util.hpp:405
void write_error_msg(std::ostream *error_stream, const std::exception &e)
bool initialize_state_zero(Eigen::VectorXd &cont_params, Model &model, std::ostream *output)
Sets initial state to zero.
bool initialize_state(const std::string init, Eigen::VectorXd &cont_params, Model &model, RNG &base_rng, std::ostream *output, ContextFactory &context_factory)
Creates the initial state.
double e()
Return the base of the natural logarithm.
Definition: constants.hpp:86

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