Problems while calling an external C++ function

Hello everyone. I’d like to kindly share with you a problem that I’m trying to solve while compiling my code. This code calls an external C++ function.

I have recently started using Stan (CmdStan), and I also don’t have a lot of experience with C++. I successfully implemented the Bernoulli example, as shown in the CmdStan User’s Guide. I also managed to compile the code that calls the external C++ function “make_odds”. My next step was then to finally run my own code, but unfortunately it failed. This is my Stan code:

functions {
  vector my_function(int n, real k);
}

data {
  int n;
  vector[n] y;
}

parameters {
  real k;
}

transformed parameters {
  vector[n] f;
  f = my_function(n, k);
}

model {
  k ~ normal(1.5, 0.1);
  y ~ normal(f, 0.01);
}

And this is my C++ function:

#include <ostream>
#include <cmath>
#include <Eigen/Dense>

using namespace std;
using namespace Eigen;

template <typename T1, typename T2, typename T3>

T1 my_function(const T2 &n, const T3 &k, std::ostream *pstream__)
{
  VectorXd f;

  //  Do some calculation to find "f"

  return f;
}

Then, I try to compile as follows:

make STANCFLAGS=--allow-undefined USER_HEADER=./examples/my_example/my_function.hpp ./examples/my_example/my_stan

Finally, I get this error:

error: no matching function for call to 'my_function'
      stan::model::assign(f, my_function(n, k, pstream__),
                              ^~~~~~
././examples/my_example/my_function.hpp:10:4: note: candidate template ignored: couldn't infer template argument 'T1'
T1 my_function(const T2 &n, const T3 &k, std::ostream *pstream__)
   ^
^Cmake: *** [examples/my_example/my_stan.o] Interrupt: 2
make: *** Deleting intermediate file `examples/my_example/my_stan.hpp'

Does anyone have an idea about what is causing this error? Any help would be very appreciated.

Best regards,
Rodrigo

The error says

candidate template ignored: couldn’t infer template argument ‘T1’

C++ templates can be inferred only if they’re used in function arguments but you have T1 as the return type. If you need to infer the return type you can use auto.

template <typename T2, typename T3>
auto my_function(const T2 &n, const T3 &k, std::ostream *pstream__)
{

If you want to see what Stan expects the function to look like, compile a model like this

functions {
  vector my_function(int n, real k) {
    reject("not implemented yet");
  }
}

and inspect the .hpp file. There, you’ll find a declaration along the lines of

template <typename T1__,
          stan::require_all_t<stan::is_stan_scalar<T1__>>* = nullptr>
Eigen::Matrix<stan::promote_args_t<T1__>,-1,1>
my_function(const int& n, const T1__& k, std::ostream* pstream__);

I believe that require_all_t part is needed only if you declare multiple Stan functions with the same name.

I should also warn you that returning a VectorXd may compile but is not going to sample correctly.
You need to compute the derivates of your function as well.
You may want to write two C++ functions, one for the plain value and one that propagates gradients.

Eigen::Matrix<double,-1,1>
my_function(const int& n, const double& k, std::ostream* pstream__);

Eigen::Matrix<stan::math::var,-1,1>
my_function(const int& n, const stan::math::var& k, std::ostream* pstream__);

Hi nhuurre,

Many thanks for your reply. Your suggestion of using “auto” indeed worked, although now I receive another error message.
The main reason for me to think about using an external C++ function is the fact that I need to solve a sparse linear system. As far as I understand, Stan does not provide any sparse solver. Nevertheless, I am starting to believe it can be faster to write a solver in Stan than trying to implement the C++ function.

Once again, I really appreciate your help.

Best,
Rodrigo