Compilation error in another forced ODE example

I am having compiler issues with trying to compile the below model in rstan. (I also have the same issue in pystan.) Any ideas as to what is causing the issue? I also get an error for the 4th order Runga Kutta integrator…

functions {
  real[] derivative_HH(real t,real[] y,real[] theta,real[] x_r,int[] x_i) {
    real dndt[1];
    real a0 = theta[1];
    real b0 = theta[2];
    real V1 = x_r[1];
    real V2 = x_r[2];
    real tThreshold = x_r[3];
    real n = y[0];
    real aV;
    real a;
    real b;
    
    
    if (t <= tThreshold)
        aV = V1;
    else
        aV = V2;
    a = a0 * (-aV - 65) / (exp((-aV - 65) / 10) - 1);
    b = b0 * exp((-aV - 75) / 80);
    dndt[1] = a * (1 - n) - b * n;
    
    return dndt;
  }
  
  vector solve_HH(real[] ts, real t0, real a0, real b0, real[] vV, real n0, real g, real E, real tThreshold){
    real n[size(ts),1];
    real theta[2];
    vector[size(ts)] I;
    int x_i[1];
    real aV;
    theta[1] = a0;
    theta[2] = b0;
    x_i[1] = 0;
    
    n = integrate_ode_bdf(derivative_HH, rep_array(n0, 1), t0, ts, theta, to_array_1d({vV[1],vV[2],tThreshold}), x_i);
    
    for(t in 1:size(ts)){
      if (t <= tThreshold)
        aV = vV[1];
      else
        aV = vV[2];
      I[t] = g * (n[t, 1] ^ 4) * (aV - E);
    }
    return(I);
  }
}

data {
  int<lower=1> T;
  real t0;
  real ts[T];
  real vV[2];
  real n0;
  real g;
  real E;
  vector[T] I;
  real tThreshold;
}

parameters {
  real<lower=0> theta[2];
  real<lower=0> a0;
  real<lower=0> b0;
  real<lower=0> sigma;
}

model {
  // solve HH equation
  vector[T] I_hat;
  I_hat = solve_HH(ts, t0, a0, b0, vV, n0, g, E, tThreshold);
  
  // likelihood
  for(t in 1:T){
    I[t] ~ normal(I_hat[t], sigma);
  }
  
  // priors
  a0 ~ normal(0,1);
  b0 ~ normal(0,1);
  sigma ~ normal(0,1);
}

The error:

In file included from file2f0405bce70.cpp:8:
In file included from /Library/Frameworks/R.framework/Versions/3.3/Resources/library/StanHeaders/include/src/stan/model/model_header.hpp:4:
In file included from /Library/Frameworks/R.framework/Versions/3.3/Resources/library/StanHeaders/include/stan/math.hpp:4:
In file included from /Library/Frameworks/R.framework/Versions/3.3/Resources/library/StanHeaders/include/stan/math/rev/mat.hpp:4:
In file included from /Library/Frameworks/R.framework/Versions/3.3/Resources/library/StanHeaders/include/stan/math/rev/core.hpp:12:
In file included from /Library/Frameworks/R.framework/Versions/3.3/Resources/library/StanHeaders/include/stan/math/rev/core/gevv_vvv_vari.hpp:5:
In file included from /Library/Frameworks/R.framework/Versions/3.3/Resources/library/StanHeaders/include/stan/math/rev/core/var.hpp:7:
In file included from /Library/Frameworks/R.framework/Versions/3.3/Resources/library/BH/include/boost/math/tools/config.hpp:13:
In file included from /Library/Frameworks/R.framework/Versions/3.3/Resources/library/BH/include/boost/config.hpp:39:
/Library/Frameworks/R.framework/Versions/3.3/Resources/library/BH/include/boost/config/compiler/clang.hpp:200:11: warning: 'BOOST_NO_CXX11_RVALUE_REFERENCES' macro redefined [-Wmacro-redefined]
#  define BOOST_NO_CXX11_RVALUE_REFERENCES
          ^
<command line>:6:9: note: previous definition is here
#define BOOST_NO_CXX11_RVALUE_REFERENCES 1
        ^
file2f0405bce70.cpp:191:35: error: no matching function for call to 'integrate_ode_bdf'
            stan::math::assign(n, integrate_ode_bdf(derivative_HH_functor__(), rep_array(n0,1), t0, ts, theta, to_array_1d(static_cast<std::vector<fun_scalar_t__> >(stan::math::array_builder<fun_scalar_t__ >().add(get_base1(vV,1,"vV",1)).add(get_base1(vV,2,"vV",1)).add(tThreshold).array())), x_i, pstream__));
                                  ^~~~~~~~~~~~~~~~~
file2f0405bce70.cpp:522:43: note: in instantiation of function template specialization 'model2f03cffd681_HH_model_namespace::solve_HH<double, double, stan::math::var, stan::math::var, double, double, double, double, double>' requested here
                stan::math::assign(I_hat, solve_HH(ts,t0,a0,b0,vV,n0,g,E,tThreshold, pstream__));
                                          ^
/Library/Frameworks/R.framework/Versions/3.3/Resources/library/StanHeaders/include/src/stan/model/log_prob_grad.hpp:44:28: note: in instantiation of function template specialization 'model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model::log_prob<true, true, stan::math::var>' requested here
          = model.template log_prob<propto, jacobian_adjust_transform>
                           ^
/Library/Frameworks/R.framework/Versions/3.3/Resources/library/StanHeaders/include/src/stan/services/util/initialize.hpp:126:35: note: in instantiation of function template specialization 'stan::model::log_prob_grad<true, true, model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model>' requested here
          log_prob = stan::model::log_prob_grad<true, true>
                                  ^
/Library/Frameworks/R.framework/Versions/3.3/Resources/library/StanHeaders/include/src/stan/services/diagnose/diagnose.hpp:54:19: note: in instantiation of function template specialization 'stan::services::util::initialize<model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model, boost::random::additive_combine_engine<boost::random::linear_congruential_engine<unsigned int, 40014, 0, 2147483563>, boost::random::linear_congruential_engine<unsigned int, 40692, 0, 2147483399> > >' requested here
          = util::initialize(model, init, rng, init_radius,
                  ^
/Library/Frameworks/R.framework/Versions/3.3/Resources/library/rstan/include/rstan/stan_fit.hpp:458:45: note: in instantiation of function template specialization 'stan::services::diagnose::diagnose<model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model>' requested here
    return_code = stan::services::diagnose::diagnose(model,
                                            ^
/Library/Frameworks/R.framework/Versions/3.3/Resources/library/rstan/include/rstan/stan_fit.hpp:1175:11: note: in instantiation of function template specialization 'rstan::(anonymous namespace)::command<model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model, boost::random::additive_combine_engine<boost::random::linear_congruential_engine<unsigned int, 40014, 0, 2147483563>, boost::random::linear_congruential_engine<unsigned int, 40692, 0, 2147483399> > >' requested here
    ret = command(args, model_, holder, names_oi_tidx_,
          ^
file2f0405bce70.cpp:737:122: note: in instantiation of member function 'rstan::stan_fit<model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model, boost::random::additive_combine_engine<boost::random::linear_congruential_engine<unsigned int, 40014, 0, 2147483563>, boost::random::linear_congruential_engine<unsigned int, 40692, 0, 2147483399> > >::call_sampler' requested here
            &rstan::stan_fit<model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model, boost::random::ecuyer1988>::call_sampler)
                                                                                                                         ^
/Library/Frameworks/R.framework/Versions/3.3/Resources/library/StanHeaders/include/stan/math/rev/mat/functor/integrate_ode_bdf.hpp:83:5: note: candidate function [with F = model2f03cffd681_HH_model_namespace::derivative_HH_functor__, T_initial = double, T_param = stan::math::var] not viable: no known conversion from 'vector<stan::math::var>' to 'const vector<double>' for 6th argument
    integrate_ode_bdf(const F& f,
    ^
file2f0405bce70.cpp:522:43: error: no matching function for call to 'solve_HH'
                stan::math::assign(I_hat, solve_HH(ts,t0,a0,b0,vV,n0,g,E,tThreshold, pstream__));
                                          ^~~~~~~~
/Library/Frameworks/R.framework/Versions/3.3/Resources/library/StanHeaders/include/src/stan/model/log_prob_grad.hpp:44:28: note: in instantiation of function template specialization 'model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model::log_prob<true, false, stan::math::var>' requested here
          = model.template log_prob<propto, jacobian_adjust_transform>
                           ^
/Library/Frameworks/R.framework/Versions/3.3/Resources/library/StanHeaders/include/src/stan/optimization/newton.hpp:66:31: note: in instantiation of function template specialization 'stan::model::log_prob_grad<true, false, model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model>' requested here
            f1 = stan::model::log_prob_grad<true, false>(model,
                              ^
/Library/Frameworks/R.framework/Versions/3.3/Resources/library/StanHeaders/include/src/stan/services/optimize/newton.hpp:101:36: note: in instantiation of function template specialization 'stan::optimization::newton_step<model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model>' requested here
          lp = stan::optimization::newton_step(model, cont_vector, disc_vector);
                                   ^
/Library/Frameworks/R.framework/Versions/3.3/Resources/library/rstan/include/rstan/stan_fit.hpp:479:35: note: in instantiation of function template specialization 'stan::services::optimize::newton<model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model>' requested here
      = stan::services::optimize::newton(model, *init_context_ptr,
                                  ^
/Library/Frameworks/R.framework/Versions/3.3/Resources/library/rstan/include/rstan/stan_fit.hpp:1175:11: note: in instantiation of function template specialization 'rstan::(anonymous namespace)::command<model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model, boost::random::additive_combine_engine<boost::random::linear_congruential_engine<unsigned int, 40014, 0, 2147483563>, boost::random::linear_congruential_engine<unsigned int, 40692, 0, 2147483399> > >' requested here
    ret = command(args, model_, holder, names_oi_tidx_,
          ^
file2f0405bce70.cpp:737:122: note: in instantiation of member function 'rstan::stan_fit<model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model, boost::random::additive_combine_engine<boost::random::linear_congruential_engine<unsigned int, 40014, 0, 2147483563>, boost::random::linear_congruential_engine<unsigned int, 40692, 0, 2147483399> > >::call_sampler' requested here
            &rstan::stan_fit<model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model, boost::random::ecuyer1988>::call_sampler)
                                                                                                                         ^
file2f0405bce70.cpp:140:1: note: candidate template ignored: substitution failure [with T0__ = double, T1__ = double, T2__ = stan::math::var, T3__ = stan::math::var, T4__ = double, T5__ = double, T6__ = double, T7__ = double, T8__ = double]
solve_HH(const std::vector<T0__>& ts,
^
In file included from file2f0405bce70.cpp:726:
In file included from /Library/Frameworks/R.framework/Versions/3.3/Resources/library/rstan/include/rstan/rstaninc.hpp:3:
In file included from /Library/Frameworks/R.framework/Versions/3.3/Resources/library/rstan/include/rstan/stan_fit.hpp:35:
In file included from /Library/Frameworks/R.framework/Versions/3.3/Resources/library/StanHeaders/include/src/stan/services/optimize/bfgs.hpp:10:
In file included from /Library/Frameworks/R.framework/Versions/3.3/Resources/library/StanHeaders/include/src/stan/optimization/bfgs.hpp:5:
/Library/Frameworks/R.framework/Versions/3.3/Resources/library/StanHeaders/include/src/stan/model/log_prob_propto.hpp:45:28: error: no matching member function for call to 'log_prob'
          = model.template log_prob<true, jacobian_adjust_transform>
            ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Frameworks/R.framework/Versions/3.3/Resources/library/rstan/include/rstan/stan_fit.hpp:1098:40: note: in instantiation of function template specialization 'stan::model::log_prob_propto<false, model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model>' requested here
        return Rcpp::wrap(stan::model::log_prob_propto<false>(model_, par_r, par_i, &rstan::io::rcout));
                                       ^
file2f0405bce70.cpp:755:122: note: in instantiation of member function 'rstan::stan_fit<model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model, boost::random::additive_combine_engine<boost::random::linear_congruential_engine<unsigned int, 40014, 0, 2147483563>, boost::random::linear_congruential_engine<unsigned int, 40692, 0, 2147483399> > >::log_prob' requested here
            &rstan::stan_fit<model2f03cffd681_HH_model_namespace::model2f03cffd681_HH_model, boost::random::ecuyer1988>::log_prob)
                                                                                                                         ^
file2f0405bce70.cpp:450:9: note: candidate template ignored: substitution failure [with propto__ = true, jacobian__ = false, T__ = stan::math::var]
    T__ log_prob(vector<T__>& params_r__,
        ^
file2f0405bce70.cpp:548:8: note: candidate function template not viable: requires at most 2 arguments, but 3 were provided
    T_ log_prob(Eigen::Matrix<T_,Eigen::Dynamic,1>& params_r,
       ^
1 warning and 3 errors generated.
make: *** [file2f0405bce70.o] Error 1

The session info is below:

R version 3.3.1 (2016-06-21)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X 10.11.3 (El Capitan)

locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8

attached base packages:
[1] stats graphics grDevices utils datasets methods base

other attached packages:
[1] rstan_2.15.1 StanHeaders_2.15.0-1 ggplot2_2.2.1

loaded via a namespace (and not attached):
[1] Rcpp_0.12.13 grid_3.3.1 plyr_1.8.4 gtable_0.2.0
[5] stats4_3.3.1 scales_0.5.0 rlang_0.1.2 lazyeval_0.2.0
[9] tools_3.3.1 munsell_0.4.3 rsconnect_0.4.3 inline_0.3.14
[13] colorspace_1.2-6 gridExtra_2.2.1 tibble_1.3.4

It seems that the error is due to calling the ODE integrator in a function. If I take the integrator and put it in the ‘model’ block, then it works. I can make do with this for now, but is a bit of a strange error. I was integrating an ODE in a Stan function in a past example and didn’t have this issue. Any ideas?

I’m now having the issue where the model compiles in R but not in Python. The model and versions of the two languages are shown below, along with the error message in Python.

Anyone got any idea?

Python error message:

---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-9-b91f020a8dde> in <module>()
     77 """
     78 
---> 79 stan_naive_model = pystan.StanModel(model_code=naive_model)

/anaconda2/lib/python2.7/site-packages/pystan/model.pyc in __init__(self, file, charset, model_name, model_code, stanc_ret, boost_lib, eigen_lib, verbose, obfuscate_model_name, extra_compile_args)
    317                 os.dup2(orig_stderr, sys.stderr.fileno())
    318 
--> 319         self.module = load_module(self.module_name, lib_dir)
    320         self.module_filename = os.path.basename(self.module.__file__)
    321         # once the module is in memory, we no longer need the file on disk

/anaconda2/lib/python2.7/site-packages/pystan/model.pyc in load_module(module_name, module_path)
     52         import imp
     53         module_info = imp.find_module(module_name, [module_path])
---> 54         return imp.load_module(module_name, *module_info)
     55 
     56 

ImportError: dlopen(/var/folders/f2/b6912q052s38c1tl7ymgk_s40000gn/T/tmprm_C4P/stanfit4anon_model_e415049eca35d70c6dddca69ca9c7922_2069256199282878047.so, 2): Symbol not found: _CVDense
  Referenced from: /var/folders/f2/b6912q052s38c1tl7ymgk_s40000gn/T/tmprm_C4P/stanfit4anon_model_e415049eca35d70c6dddca69ca9c7922_2069256199282878047.so
  Expected in: flat namespace
 in /var/folders/f2/b6912q052s38c1tl7ymgk_s40000gn/T/tmprm_C4P/stanfit4anon_model_e415049eca35d70c6dddca69ca9c7922_2069256199282878047.so

The Stan code (same across both platforms):

functions {
  real[] derivative_HH(real t,real[] y,real[] theta,real[] x_r,int[] x_i) {
    real dndt[1];
    real a0 = theta[1];
    real b0 = theta[2];
    real V1 = x_r[1];
    real V2 = x_r[2];
    real tThreshold = x_r[3];
    real n = y[1];
    real aV;
    real a;
    real b;
    
    
    if (t <= tThreshold)
        aV = V1;
    else
        aV = V2;
    a = a0 * (-aV - 65) / (exp((-aV - 65) / 10) - 1);
    b = b0 * exp((-aV - 75) / 80);
    dndt[1] = a * (1 - n) - b * n;
    
    return dndt;
  }
}

data {
  int<lower=1> T;
  real t0;
  real ts[T];
  real vV[2];
  real n0;
  real g;
  real E;
  vector[T] I;
  real tThreshold;
}

parameters {
  real<lower=0> theta[2];
  // real<lower=0> a0;
  // real<lower=0> b0;
  real<lower=0> sigma;
}

model {
  // solve HH equation
  int x_i[1];
  real aV;
  real n[size(ts),1];
  vector[T] I_hat;
  
  x_i[1] = 0;
  n = integrate_ode_bdf(derivative_HH, rep_array(n0, 1), t0, ts, theta, to_array_1d({vV[1],vV[2],tThreshold}), x_i);
  
  for(t in 1:size(ts)){
      if (t <= tThreshold)
        aV = vV[1];
      else
        aV = vV[2];
      I_hat[t] = g * (n[t, 1] ^ 4) * (aV - E);
    }
  
  // likelihood
  for(t in 1:T){
    I[t] ~ normal(I_hat[t], sigma);
  }
  
  // priors
  theta[1] ~ normal(0,1);
  theta[2] ~ normal(0,1);
  sigma ~ normal(0,1);
}

Python session info:

{'commit_hash': u'1149d1700',
 'commit_source': 'installation',
 'default_encoding': 'UTF-8',
 'ipython_path': '/anaconda2/lib/python2.7/site-packages/IPython',
 'ipython_version': '5.4.1',
 'os_name': 'posix',
 'platform': 'Darwin-15.3.0-x86_64-i386-64bit',
 'sys_executable': '/anaconda2/bin/python',
 'sys_platform': 'darwin',
 'sys_version': '2.7.14 |Anaconda, Inc.| (default, Oct  5 2017, 02:28:52) \n[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]'}

R session info:

R version 3.3.1 (2016-06-21)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
Running under: OS X 10.11.3 (El Capitan)

locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] rstan_2.16.2         StanHeaders_2.16.0-1 ggplot2_2.2.1       

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.13     grid_3.3.1       plyr_1.8.4       gtable_0.2.0    
 [5] stats4_3.3.1     scales_0.5.0     rlang_0.1.2      lazyeval_0.2.0  
 [9] tools_3.3.1      munsell_0.4.3    rsconnect_0.4.3  inline_0.3.14   
[13] colorspace_1.2-6 gridExtra_2.2.1  tibble_1.3.4

It might be the compiler you have. In python it looks like gcc 4.2, which isn’t capable of handling Stan’s C++.

These things are hard to track down without more detailed information about the tool chain you’re using and which libraries it thinks it’s using. If you’re able to provide some of that, we can help a little more. (Sorry, I’m not an R or python build expert to know how to access that info easily.)

There’s a branch which has CVODES support.
https://github.com/stan-dev/pystan/tree/feature/cvodes-support

Here’s the relevant issue: https://github.com/stan-dev/pystan/pull/293

Hi Ben,

your code looks correct to me on a first glance. Just two thoughts:

  • I think the to_array_1d({vV[1],vV[2],tThreshold}) argument is actually doing too much work. The curly braces already give you a 1D array. You should be able to drop the to_array_1d call; I would try that.

  • I know that it is a lot nicer to call the integrate_ode_bdf function inside other functions. If the above does not help, you could try to setup the data-only arguments for the integrate call already in the transformed data block and then just pass it “as-is” into the function which passes this on to the integrate_ode_bdf

The current develop branch has hopefully fixed this problem already (a dedicated data only type has been introduced as I understood). It would be great if you could try with more modern compilers (g++ 4.9.3 at least) and if possible for you also with the current dev version. I understand that this is asking for a lot from you, but in any case this should be filed as an issue (ideally after trying the two things I mentioned) with a small example to trigger this problem.

To get the python problem solved / worked around, you could switch to the rk45 integrator to check if it works then.

… calling the ODE integrator in functions already caused a lot of headache for me; it is intrinsically hard for the Stan language and the compilers.

Best,
Sebastian