Dear Stan-Community,
I am working on my first ODE translation from R (using package deSolve) to Stan as a Stan newbie. So, far, the model works with a constant input, but generally I want to input a signal as a time-series into the model. Here is the working example in R first (with some truncations for better readability):
Mader <- function(t, y, parms, input){
with(as.list(c(parms, y)), {
# input
watt <- input(t) / mm
# ...
#return
list(c(dgp, dvo2, dlam, dlab),
atp = atp, # ...
)
})
}
# ...
signal <- crossing(
watt = seq(150, 350, 50),
dt = 1,
tstage = 5,
tphase = seq(0, tstage*60, dt)
) %>%
mutate(
times = cumsum(dt) - dt,
tmin = times/60
)
times <- signal$times
sigimp <- approxfun(signal$times, signal$watt, rule = 2)
## Solve model
out <- ode(
y = yini,
times = times,
func = Mader,
parms = parms,
method = "rk4",
input = sigimp)
I guess I adopted everything but the sigimp-function. Here is my attempt for implementation in Stan:
functions {
real sigimp(real t_out, real[] ts, real[] watt) {
int left = 1;
int right = 1;
real w = 1.0;
int N_in = size(ts);
int N_out = size(t_out);
real watt_out;
while (ts[right] < t_out) {
right = right + 1;
}
while (ts[left + 1] < t_out) {
left = left + 1;
}
w = (ts[right] - t_out) / (ts[right] - ts[left]);
watt_out = w * watt[left] + (1 - w) * watt[right];
return watt_out;
}
real[] mader(real t, real[] y, real[] parms, real[] x_r, int[] x_i) {
// variables
int T = x_i[1];
real ts[T] = x_r[1];
real watt[T] = x_r[2];
real w = sigimp(t, ts, watt);
// [...]
}
}
data {
int<lower = 0> T;
real t0;
real<lower = t0> ts[T];
real y0[5];
real parms[23];
real watt[T];
}
transformed data {
real x_r[1] = ts;
real x_r[2] = watt;
int x_i[1] = T;
}
parameters {
real<lower = 0, upper = 1> p;
}
model {
}
generated quantities {
real y[T, 5] = integrate_ode_rk45(mader, y0, t0, ts, parms, x_r, x_i);
}
When compiling the code within R using cmdstanR I get the following error message:
Semantic error in line 26, column 4 to column 24:
-------------------------------------------------
24: // variables
25: int T = x_i[1];
26: real ts[T] = x_r[1];
^
27: real watt[T] = x_r[2];
28: real w = sigimp(t, ts, watt);
-------------------------------------------------
My questions:
-
Do you have any generic examples how to write and implement such a function in Stan as in the provided example with the deSolve package?
-
If my attempt is close before working, any hints to resolve remaining issues?
Any feedback/criticism regarding the code itself or tips to improve are welcome! =)
Regards
Rob