test_gradients.hpp
Go to the documentation of this file.
1 #ifndef STAN_MODEL_TEST_GRADIENTS_HPP
2 #define STAN_MODEL_TEST_GRADIENTS_HPP
3 
8 #include <cmath>
9 #include <sstream>
10 #include <vector>
11 
12 namespace stan {
13  namespace model {
14 
15  /**
16  * Test the log_prob_grad() function's ability to produce
17  * accurate gradients using finite differences. This shouldn't
18  * be necessary when using autodiff, but is useful for finding
19  * bugs in hand-written code (or var).
20  *
21  * @tparam propto True if calculation is up to proportion
22  * (double-only terms dropped).
23  * @tparam jacobian_adjust_transform True if the log absolute
24  * Jacobian determinant of inverse parameter transforms is added to the
25  * log probability.
26  * @tparam Model Class of model.
27  * @param[in] model Model.
28  * @param[in] params_r Real-valued parameter vector.
29  * @param[in] params_i Integer-valued parameter vector.
30  * @param[in] epsilon Real-valued scalar saying how much to perturb.
31  * Reasonable value is 1e-6.
32  * @param[in] error Real-valued scalar saying how much error to allow.
33  * Reasonable value is 1e-6.
34  * @param[in,out] interrupt callback to be called at every iteration
35  * @param[in,out] logger Logger for messages
36  * @param[in,out] parameter_writer Writer callback for file output
37  * @return number of failed gradient comparisons versus allowed
38  * error, so 0 if all gradients pass
39  */
40  template <bool propto, bool jacobian_adjust_transform, class Model>
42  std::vector<double>& params_r,
43  std::vector<int>& params_i,
44  double epsilon,
45  double error,
46  stan::callbacks::interrupt& interrupt,
48  stan::callbacks::writer& parameter_writer) {
49  std::stringstream msg;
50  std::vector<double> grad;
51  double lp = log_prob_grad<propto, jacobian_adjust_transform>(model,
52  params_r,
53  params_i,
54  grad,
55  &msg);
56  if (msg.str().length() > 0) {
57  logger.info(msg);
58  parameter_writer(msg.str());
59  }
60 
61  std::vector<double> grad_fd;
62  finite_diff_grad<false, true, Model>(model, interrupt, params_r, params_i,
63  grad_fd, epsilon, &msg);
64  if (msg.str().length() > 0) {
65  logger.info(msg);
66  parameter_writer(msg.str());
67  }
68 
69  int num_failed = 0;
70 
71  std::stringstream lp_msg;
72  lp_msg << " Log probability=" << lp;
73 
74  parameter_writer();
75  parameter_writer(lp_msg.str());
76  parameter_writer();
77 
78  logger.info("");
79  logger.info(lp_msg);
80  logger.info("");
81 
82  std::stringstream header;
83  header << std::setw(10) << "param idx"
84  << std::setw(16) << "value"
85  << std::setw(16) << "model"
86  << std::setw(16) << "finite diff"
87  << std::setw(16) << "error";
88 
89  parameter_writer(header.str());
90  logger.info(header);
91 
92  for (size_t k = 0; k < params_r.size(); k++) {
93  std::stringstream line;
94  line << std::setw(10) << k
95  << std::setw(16) << params_r[k]
96  << std::setw(16) << grad[k]
97  << std::setw(16) << grad_fd[k]
98  << std::setw(16) << (grad[k] - grad_fd[k]);
99  parameter_writer(line.str());
100  logger.info(line);
101  if (std::fabs(grad[k] - grad_fd[k]) > error)
102  num_failed++;
103  }
104  return num_failed;
105  }
106 
107  }
108 }
109 #endif
fvar< T > fabs(const fvar< T > &x)
Definition: fabs.hpp:15
rosenbrock_model_namespace::rosenbrock_model Model
static void grad(vari *vi)
Definition: grad.hpp:30
virtual void info(const std::string &message)
Definition: logger.hpp:47
double epsilon
int test_gradients(const Model &model, std::vector< double > &params_r, std::vector< int > &params_i, double epsilon, double error, stan::callbacks::interrupt &interrupt, stan::callbacks::logger &logger, stan::callbacks::writer &parameter_writer)
const XML_Char XML_Content * model
Definition: expat.h:151