Model Concept

Bob Carpenter edited this page Jul 23, 2014 · 12 revisions
Clone this wiki locally

C++ Model

The C++ model generated by translating a Stan model using Stan's command-line function bin/stanc implements the following C++ "concept." Functions working with models must declare the model's class as a template parameter (for examples, see the next section of static utility functions).

A Stan model implements an object that stores data and transformed data in member variables and provides functions to compute log probabilities. Data is provided at construction time and is immutable after construction. Thus a particular instance of a Stan model is tied to data.

Utility functions, described in the next section, can be used to calculate derivatives, Hessians, etc.

Stan models themselves are thread safe after construction. Operations on models involving auto-diff may not be thread safe.

The Stan model depends heavily on the Stan math and probability library, but not on auto-diff.

For a model class M, the following public constructors, destructors, and methods are available. Most of the functions are constant member functions because they depend on the data, but the name of the model is static.

Model Name

Returns name of model.

static 
std::string 
model_name();

Constructor and Destructor

The following constructor reads data from context, writes errors/warnings to msgs, and throws exceptions if there are errors. After construction, a model is immutable.

M(stan::io::var_context& data_context,
  std::ostream* msgs = 0);

There is a destructor which cleans up all of the data allocated for memory; typically it won't be called explicitly.

~M();

Initialization

Transform constrained initial values represented in a context to an unconstrained parameter vector suitable for use in HMC; throws exceptions if errors.

void 
transform_inits(const stan::io::var_context& inits_context,
                std::vector<int>& params_i__,
                std::vector<double>& params_r__) 
const;

Log Probability

Log prob function for unconstrained parameters, with or without Jacobian and computed with or without proportionality; error msgs written to msgs, may also throw exceptions

template <bool propto, bool jacobian_adjust_transforms, typename T>
T 
log_prob(std::vector<T>& params_r,
         std::vector<int>& params_i,
         std::ostream* msgs = 0) 
const;

Parameter Names and Dimensions

Copy constrained param names into vector (just variable names, once per variable, no dimensions)

void 
get_param_names(std::vector<std::string>& names) 
const;

Write out dimensions of params corresponding to get_param_names (in constrained space)

void 
get_dims(std::vector<std::vector<size_t> >& dimss) 
const;

Copy constrained params with dimensions encoded into specified string vector, optionally included transformed parameters, generated quantities.

void 
constrained_param_names(std::vector<std::string>& param_names,
                        bool include_tparams = true,
                        bool include_gqs = true) 
const;

Copy unconstrained params with dimensions encoded; indexing based on transform.

void 
unconstrained_param_names(std::vector<std::string>& param_names__,
                          bool include_tparams__ = true,
                          bool include_gqs__ = true) 
const;

Transform Parameters, Calculate Transformed Parameters, Execute Generated Quantities

Given unconstrained parameters, write their constrained versions into the specified output variable vector. Transformed parameters and generated quantities may be optionally included. If the generated quantities are included, the random-number generator is used to execute the generated quantities block.

template <typename RNG>
void 
write_array(RNG& base_rng__,
            std::vector<double>& params_r,
            std::vector<int>& params_i,
            std::vector<double>& vars,
            bool include_transformed_param = true,
            bool include_generated_quantities = true,
            std::ostream* msgs = 0) 
const;

Comma-Separated Value Output

May eventually move these to static helper functions.

Write CSV output header with encoded parameter, trans param, gen quants.

void 
write_csv_header(std::ostream& out) 
const;

Write values in a line of CSV format using specified RNG, includes params, transformed parameters, and generated quantities.

template <typename RNG>
void 
write_csv(RNG& base_rng,
          std::vector<double>& params_r,
          std::vector<int>& params_i,
          std::ostream& o,
          std::ostream* msgs = 0) const;

Number of Parameters

Return the number of unconstrained real parameters

size_t 
num_params_r() 
const;

Return the number of integer parameters

size_t 
num_params_i()
const;

Integer Parameter Ranges

Return ranges of integer parameter with specified index

const pair<int,int>& 
param_range_i(size_t idx) 
const;

Utility functions

These are in: src/stan/model/util.hpp

Replace the eliminated base class functions and some of the generated functions by static model utility functions.

Gradients

Gradient and log probabilty via auto-diff.

template <class M, bool propto, bool jacobian_adjust_transform>
double 
log_prob_grad(const M& model,
              vector<double>& params_r, vector<int>& params_i,
              vector<double>& gradient,
              ostream* msgs = 0);

Gradient via finite differences.

template <bool propto, bool jacobian_adjust_transform, class M>
void 
finite_diff_grad(const M& model,
                 std::vector<double>& params_r,
                 std::vector<int>& params_i,
                 std::vector<double>& grad,
                 double epsilon = 1e-6,
                 std::ostream* msgs = 0); 

Gradient testing.

template <bool propto, bool jacobian_adjust_transform, class M>
int 
test_gradients(const M& model,
               std::vector<double>& params_r,
               std::vector<int>& params_i,
               double epsilon = 1e-6,
               double error = 1e-6,
               std::ostream& o = std::cout,
               std::ostream* msgs = 0);

Hessians

Hessians via finite differences with gradients using auto-diff.

template <class M, bool propto, bool jacobian_adjust_transform>
double 
grad_hess_log_prob(const M& model,
                   vector<double>& params_r, vector<int>& params_i,
                   vector<double>& gradient,
                   vector<double>& hessian,
                   ostream* msgs = 0);

Log Probability

Log probability with propto=true for double-valued parameters. It calls the auto-diff version by converting parameters to var, so it'll be relatively slow, but it'll give answers that match those computed using log_prob with var inputs.

template <bool jacobian_adjust_transform, class M>
double 
log_prob_propto(const M& model,
                std::vector<double>& params_r,
                std::vector<int>& params_i,
                std::ostream* msgs = 0);