eta_adapt_mock_models_test.cpp
Go to the documentation of this file.
1 #include <ostream>
3 #include <stan/io/dump.hpp>
6 #include <boost/math/special_functions/fpclassify.hpp>
7 #include <gtest/gtest.h>
8 #include <test/unit/util.hpp>
10 #include <boost/random/additive_combine.hpp> // L'Ecuyer RNG
11 
12 typedef boost::ecuyer1988 rng_t;
13 
14 // Mock Model
16 public:
17 
19  stan::model::prob_grad(num_params_r),
23  log_prob_return_value(0.0) { }
24 
25  void reset() {
30  }
31 
32  template <bool propto, bool jacobian_adjust_transforms, typename T>
33  T log_prob(Eigen::Matrix<T,Eigen::Dynamic,1>& params_r,
34  std::ostream* output_stream = 0) const {
36  return log_prob_return_value;
37  }
38 
39  void transform_inits(const stan::io::var_context& context__,
40  Eigen::VectorXd& params_r__,
41  std::ostream* out) const {
43  for (int n = 0; n < params_r__.size(); n++) {
44  params_r__[n] = n;
45  }
46  }
47 
48  void get_dims(std::vector<std::vector<size_t> >& dimss__) const {
49  dimss__.resize(0);
50  std::vector<size_t> scalar_dim;
51  dimss__.push_back(scalar_dim);
52  dimss__.push_back(scalar_dim);
53  dimss__.push_back(scalar_dim);
54  }
55 
56  void constrained_param_names(std::vector<std::string>& param_names__,
57  bool include_tparams__ = true,
58  bool include_gqs__ = true) const {
59  param_names__.push_back("a");
60  param_names__.push_back("b");
61  param_names__.push_back("c");
62  }
63 
64  void get_param_names(std::vector<std::string>& names) const {
66  }
67 
68  void unconstrained_param_names(std::vector<std::string>& param_names__,
69  bool include_tparams__ = true,
70  bool include_gqs__ = true) const {
71  param_names__.clear();
72  for (size_t n = 0; n < num_params_r__; n++) {
73  std::stringstream param_name;
74  param_name << "param_" << n;
75  param_names__.push_back(param_name.str());
76  }
77  }
78 
79  template <typename RNG>
80  void write_array(RNG& base_rng__,
81  std::vector<double>& params_r__,
82  std::vector<int>& params_i__,
83  std::vector<double>& vars__,
84  bool include_tparams__ = true,
85  bool include_gqs__ = true,
86  std::ostream* pstream__ = 0) const {
88  vars__.resize(0);
89  for (size_t i = 0; i < params_r__.size(); i++)
90  vars__.push_back(params_r__[i]);
91  }
92 
94  mutable int transform_inits_calls;
95  mutable int write_array_calls;
97 };
98 
99 // Mock Throwing Model throws exception
101 public:
102 
104  stan::model::prob_grad(num_params_r),
108  log_prob_return_value(0.0) { }
109 
110  void reset() {
113  write_array_calls = 0;
114  log_prob_return_value = 0.0;
115  }
116 
117  template <bool propto, bool jacobian_adjust_transforms, typename T>
118  T log_prob(Eigen::Matrix<T,Eigen::Dynamic,1>& params_r,
119  std::ostream* output_stream = 0) const {
121  throw std::domain_error("throwing within log_prob");
122  return log_prob_return_value;
123  }
124 
125  void transform_inits(const stan::io::var_context& context__,
126  Eigen::VectorXd& params_r__,
127  std::ostream* out) const {
129  for (int n = 0; n < params_r__.size(); n++) {
130  params_r__[n] = n;
131  }
132  }
133 
134  void get_dims(std::vector<std::vector<size_t> >& dimss__) const {
135  dimss__.resize(0);
136  std::vector<size_t> scalar_dim;
137  dimss__.push_back(scalar_dim);
138  dimss__.push_back(scalar_dim);
139  dimss__.push_back(scalar_dim);
140  }
141 
142  void constrained_param_names(std::vector<std::string>& param_names__,
143  bool include_tparams__ = true,
144  bool include_gqs__ = true) const {
145  param_names__.push_back("a");
146  param_names__.push_back("b");
147  param_names__.push_back("c");
148  }
149 
150  void get_param_names(std::vector<std::string>& names) const {
152  }
153 
154  void unconstrained_param_names(std::vector<std::string>& param_names__,
155  bool include_tparams__ = true,
156  bool include_gqs__ = true) const {
157  param_names__.clear();
158  for (size_t n = 0; n < num_params_r__; n++) {
159  std::stringstream param_name;
160  param_name << "param_" << n;
161  param_names__.push_back(param_name.str());
162  }
163  }
164 
165  template <typename RNG>
166  void write_array(RNG& base_rng__,
167  std::vector<double>& params_r__,
168  std::vector<int>& params_i__,
169  std::vector<double>& vars__,
170  bool include_tparams__ = true,
171  bool include_gqs__ = true,
172  std::ostream* pstream__ = 0) const {
174  vars__.resize(0);
175  for (size_t i = 0; i < params_r__.size(); i++)
176  vars__.push_back(params_r__[i]);
177  }
178 
181  mutable int write_array_calls;
183 };
184 
185 class mock_rng {
186 public:
187  typedef double result_type;
188 
190  calls(0) { }
191 
192  void reset() {
193  calls = 0;
194  }
195 
196  result_type operator()() {
197  calls++;
198  return calls / 10000.0;
199  }
200 
201  static result_type max() {
202  return 1.0;
203  }
204 
205  static result_type min() {
206  return -1.0;
207  }
208 
209  int calls;
210 };
211 
212 class eta_adapt_test : public testing::Test {
213 public:
215  model(3),
216  throwing_model(3),
217  logger(log_stream_, log_stream_, log_stream_, log_stream_, log_stream_) {}
218 
219  void SetUp() {
220  cont_params = Eigen::VectorXd::Zero(3);
221  model.reset();
222  rng.reset();
223  log_stream_.clear();
224  }
225 
227  Eigen::VectorXd cont_params;
231  std::stringstream log_stream_;
233 };
234 
235 TEST_F(eta_adapt_test, initialize_state_zero_negative_infinity) {
236  model.log_prob_return_value =
237  -std::numeric_limits<double>::infinity();
238 
241  mock_rng> *advi_meanfield =
243  stan::variational::normal_meanfield,
244  mock_rng>
245  (model,
246  cont_params, rng,
247  1, 100,
248  100, 1);
249 
252  mock_rng> *advi_fullrank =
254  stan::variational::normal_fullrank,
255  mock_rng>
256  (model,
257  cont_params, rng,
258  1, 100,
259  100, 1);
260 
261  stan::variational::normal_meanfield meanfield_init =
262  stan::variational::normal_meanfield(cont_params);
263  stan::variational::normal_fullrank fullrank_init =
264  stan::variational::normal_fullrank(cont_params);
265 
266  std::string error = "stan::variational::advi::adapt_eta: "
267  "Cannot compute ELBO using the initial "
268  "variational distribution. "
269  "Your model may be either "
270  "severely ill-conditioned or misspecified.";
271 
272  EXPECT_THROW_MSG(advi_meanfield->adapt_eta(meanfield_init, 10, logger),
274  EXPECT_THROW_MSG(advi_fullrank->adapt_eta(fullrank_init, 10, logger),
276 
277  delete advi_meanfield;
278  delete advi_fullrank;
279 }
280 
281 TEST_F(eta_adapt_test, initialize_state_zero_grad_error) {
282  throwing_model.log_prob_return_value =
283  -std::numeric_limits<double>::infinity();
284 
287  mock_rng> *advi_meanfield =
288  new stan::variational::advi<mock_throwing_model,
289  stan::variational::normal_meanfield,
290  mock_rng>
291  (throwing_model,
292  cont_params, rng,
293  1, 100,
294  100, 1);
295 
296  stan::variational::advi<mock_throwing_model,
298  mock_rng> *advi_fullrank =
299  new stan::variational::advi<mock_throwing_model,
300  stan::variational::normal_fullrank,
301  mock_rng>
302  (throwing_model,
303  cont_params, rng,
304  1, 100,
305  100, 1);
306 
307  stan::variational::normal_meanfield meanfield_init =
308  stan::variational::normal_meanfield(cont_params);
309  stan::variational::normal_fullrank fullrank_init =
310  stan::variational::normal_fullrank(cont_params);
311 
312  std::string error = "stan::variational::advi::adapt_eta: "
313  "Cannot compute ELBO using the initial "
314  "variational distribution. "
315  "Your model may be either "
316  "severely ill-conditioned or misspecified.";
317 
318  EXPECT_THROW_MSG(advi_meanfield->adapt_eta(meanfield_init, 10, logger),
320  EXPECT_THROW_MSG(advi_fullrank->adapt_eta(fullrank_init, 10, logger),
322 
323  delete advi_meanfield;
324  delete advi_fullrank;
325 }
326 
327 
328 
329 
330 
331 
332 
333 // TEST_F(eta_adapt_test, gradient_warn_meanfield) {
334 // EXPECT_EQ(0, advi_meanfield_->run(0.1, false, 50, 0.01, 10000));
335 // SUCCEED() << "expecting it to compile and run without problems";
336 // }
337 
338 // TEST_F(eta_adapt_test, gradient_warn_fullrank) {
339 // EXPECT_EQ(0, advi_fullrank_->run(0.1, false, 50, 0.01, 10000));
340 // SUCCEED() << "expecting it to compile and run without problems";
341 // }
void get_param_names(std::vector< std::string > &names) const
stan::callbacks::stream_logger logger
void unconstrained_param_names(std::vector< std::string > &param_names__, bool include_tparams__=true, bool include_gqs__=true) const
#define EXPECT_THROW_MSG(expr, T_e, msg)
Definition: util.hpp:6
void get_dims(std::vector< std::vector< size_t > > &dimss__) const
void unconstrained_param_names(std::vector< std::string > &param_names__, bool include_tparams__=true, bool include_gqs__=true) const
prob_grad(size_t num_params_r)
Definition: prob_grad.hpp:23
mock_throwing_model(size_t num_params_r)
T log_prob(Eigen::Matrix< T, Eigen::Dynamic, 1 > &params_r, std::ostream *output_stream=0) const
result_type operator()()
TEST_F(eta_adapt_test, initialize_state_zero_negative_infinity)
void constrained_param_names(std::vector< std::string > &param_names__, bool include_tparams__=true, bool include_gqs__=true) const
boost::ecuyer1988 rng_t
void write_array(RNG &base_rng__, std::vector< double > &params_r__, std::vector< int > &params_i__, std::vector< double > &vars__, bool include_tparams__=true, bool include_gqs__=true, std::ostream *pstream__=0) const
mock_throwing_model throwing_model
std::stringstream log_stream_
void transform_inits(const stan::io::var_context &context__, Eigen::VectorXd &params_r__, std::ostream *out) const
void domain_error(const char *function, const char *name, const T &y, const char *msg1, const char *msg2)
mock_model(size_t num_params_r)
void get_dims(std::vector< std::vector< size_t > > &dimss__) const
T log_prob(Eigen::Matrix< T, Eigen::Dynamic, 1 > &params_r, std::ostream *output_stream=0) const
void transform_inits(const stan::io::var_context &context__, Eigen::VectorXd &params_r__, std::ostream *out) const
void Zero()
static result_type max()
size_t num_params_r() const
Definition: prob_grad.hpp:36
double T
Definition: Xdiff_gwt.C:5
void get_param_names(std::vector< std::string > &names) const
static result_type min()
void constrained_param_names(std::vector< std::string > &param_names__, bool include_tparams__=true, bool include_gqs__=true) const
const XML_Char XML_Content * model
Definition: expat.h:151
void write_array(RNG &base_rng__, std::vector< double > &params_r__, std::vector< int > &params_i__, std::vector< double > &vars__, bool include_tparams__=true, bool include_gqs__=true, std::ostream *pstream__=0) const
enum BeamMode string