22 Using external C++ code
The --allow_undefined flag can be passed to the call to stanc,
which will allow undefined functions in the Stan language to be parsed
without an error. We can then include a definition of the function in
a C++ header file.
This requires specifying two makefile variables:
- STANCFLAGS=--allow_undedefined
- USER_HEADER=<header_file.hpp>, where <header_file.hpp> is the name of a header file that
defines a function with the same name and signature in a namespace
that is formed by concatenating the class_name argument to
stanc documented above to the string _namespace
As an example, consider the following variant of the Bernoulli example
functions {
  real make_odds(real theta);
}
data {
  int<lower=0> N;
  array[N] int<lower=0, upper=1> y;
}
parameters {
  real<lower=0, upper=1> theta;
}
model {
  theta ~ beta(1, 1); // uniform prior on interval 0, 1
  y ~ bernoulli(theta);
}
generated quantities {
  real odds;
  odds = make_odds(theta);
}Here the make_odds function is declared but not defined, which
would ordinarily result in a parser error. However, if you put
STANCFLAGS = --allow_undefined into the make/local file
or into the stanc call, then the stanc compiler will translate
this program to C++, but the generated C++ code will not compile
unless you write a file
such as examples/bernoulli/make_odds.hpp with the following lines
#include <boost/math/tools/promotion.hpp>
#include <ostream>
namespace bernoulli_model_namespace {
          template <typename T0__>  inline  typename
          boost::math::tools::promote_args<T0__>::type  make_odds(const T0__&
theta, std::ostream* pstream__) {
       return theta / (1 - theta);  }
       }Given the above, the following make invocation should work
> make STANCFLAGS=--allow_undefined USER_HEADER=examples/bernoulli/make_odds.hpp examples/bernoulli/bernoulli # on Windows add .exeAlternatively, you could put STANCFLAGS and USER_HEADER into the
make/local file instead of specifying them on the command-line.
If the function were more complicated and involved functions in the
Stan Math Library, then you would need to prefix the function calls
with stan::math:: The pstream__ argument is mandatory
in the signature but need not be used if your function does not print
any output. To see the necessary boilerplate look at the corresponding
lines in the generated C++ file.
For more details about how to write C++ code using the Stan Math Library, see https://arxiv.org/abs/1509.07164.