What is the best way to add a user function that is used in likelihood calculation?

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);
  }

}

3 Likes