I have now managed to get my code to compile. As @syclik and @bbbales2 pointed out I needed to template my functions.
@syclik suggested using template specialization (a C++ feature that I was not previously aware of). This is nice because I don’t have to modify my source code.
The link that @bbbales2 posted was an example where all the templating is done in the source code. The text in the relevant section starts “if we have some fancy templated C++ code that solves part of our problem”.
I don’t think my code needs to be fancy or templated so I prefer @syclik’s solution of creating a fancy templated wrapper around my basic code.
In @syclik’s post there is no fancy type-checking of return arguments, which I think is an error (at least my compiler said it was). For completeness, here are my (working) function definitions,
namespace fhn_model_namespace{
template<typename T1, typename T2>
typename boost::math::tools::promote_args<T1, T2>::type
spec_fun(const T1& p, const Eigen::Matrix<T2,-1,1>& x, std::ostream* pstream__) {
throw std::logic_error("not implemented"); // this should never be called
}
// this is a template specialization for <double, double>
template<>
double spec_fun<double, double>(const double& p, const Eigen::Matrix<double,-1,1>& x, std::ostream* pstream__) {
return linear_sde::spec_fun(p, x);
}
// this is a template specialization for <double, var>
template<>
var spec_fun<double, var>(const double& p, const Eigen::Matrix<var,-1,1>& x, std::ostream* pstream__) {
Eigen::Matrix<double,-1,1> a = value_of(x);
double fa = linear_sde::spec_fun(p, a);
vector<double> grad_fa = linear_sde::grad_spec_fun(p, a);
vector<var> x_std(x.data(), x.data() + x.rows() * x.cols());
return precomputed_gradients(fa, x_std, grad_fa);
}
}