ODE in PyStan: 'Failed to parse Stan model'

I am trying to use PyStan to estimate parameters for an ODE model. As an exercise I have been following the Lotka-Volterra tutorial by Bob Carpenter: https://mc-stan.org/users/documentation/case-studies/lotka-volterra-predator-prey.html

After failing to compile my own attempt at Stan code, I have copy-and-pasted the example given in the tutorial but still get the following error:

‘ValueError: Failed to parse Stan model ‘anon_model_55a47a04c3ed33f2bf08c4bd5e3a9a36’. Error message:
PARSER FAILED TO PARSE INPUT COMPLETELY’
STOPPED AT LINE 2:

This is my code in Spyder

model = """
    real[] dz_dt(real t, real[] z, real[] theta,
                 real[] x_r, int[] x_i) {
      real u = z[1];
      real v = z[2];

  real alpha = theta[1];
  real beta = theta[2];
  real gamma = theta[3];
  real delta = theta[4];

  real du_dt = (alpha - beta * v) * u;
  real dv_dt = (-gamma + delta * u) * v;
  return { du_dt, dv_dt };
}

data {
  int<lower = 0> N;           // num measurements
  real ts[N];                 // measurement times > 0
  real y_init[2];             // initial measured population
  real<lower = 0> y[N, 2];    // measured population at measurement times
}

parameters {
  real<lower = 0> theta[4];   // theta = { alpha, beta, gamma, delta }
  real<lower = 0> z_init[2];  // initial population
  real<lower = 0> sigma[2];   // error scale
}

transformed parameters {
  real z[N, 2]
    = integrate_ode_rk45(dz_dt, z_init, 0, ts, theta,
                         rep_array(0.0, 0), rep_array(0, 0),
                         1e-6, 1e-5, 1e3);
}

model {
  theta[{1, 3}] ~ normal(1, 0.5);
  theta[{2, 4}] ~ normal(0.05, 0.05);
  sigma ~ lognormal(-1, 1);
  z_init ~ lognormal(log(10), 1);
  for (k in 1:2) {
    y_init[k] ~ lognormal(log(z_init[k]), sigma[k]);
    y[ , k] ~ lognormal(log(z[, k]), sigma[k]);
  }
}
"""

sm = pystan.StanModel(model_code = model)

I am new to Stan, but cannot see any errors. Can anyone tell me what I’m doing wrong?

Your function

is not inside any block. You should have a functions block and put it inside it. So just wrap that with

functions{
 // code for dz_dt here
}
1 Like

Also notice

https://pystan.readthedocs.io/en/latest/installation_cvodes.html

The latest version

pip install git+https://github.com/stan-dev/pystan@cvodes

I think it may be a case of what the tutorial is doing wrong. I noticed that when it quotes the functions block, it leaves off the “functions {” line, as if the tutorial author had make a copy-and-paste error.

The tutorial does have a section called “Complete Stan program” which looks like it has everything that you’d need to copy and paste.