I’m trying use Stan’s numerical integrator and replicating the stochastic differential equation model from http://ctsm.info/ (example building 2). Here’s the Stan code:
functions {
// the TiTe state space model
real[] TiTe_ODE(real t, real[] X, real[] parms, real[] rdata, int[] idata) {
// the state variables:
// X[1]: internal temperature
// X[2]: envelope (the thermal mass) temperature
real Ci = parms[1]; // capacitance internal
real Ce = parms[2]; // capacitance envelope
real Rie = parms[3]; // resistance internal-envelope
real Rea = parms[4]; // resistance envelope-ambient
real Aw = parms[5]; // effective glazing area (aka gA)
real Ta = rdata[1]; // ambient air temperature
real Ps = rdata[2]; // thermal power from solar
real Ph = rdata[3]; // thermal power from heaters
real dXdt[2];
// the differential equations
dXdt[1] = 1/(Ci*Rie)*(X[2]-X[1]) + Aw/Ci*Ps + 1/Ci*Ph;
dXdt[2] = 1/(Ce*Rie)*(X[1]-X[2]) + 1/(Ce*Rea)*(Ta-X[2]);
return dXdt;
}
// needed to not get syntax error on inital time for integrate_ode_rk45, some referencing/data issue
real[] TiTe_integrate(real[] init, real t0, real[] time, real[] parms, real[] rdata,int[] idummy) {
real temp[1, 2] = integrate_ode_rk45(TiTe_ODE, init, t0, time, parms, rdata, idummy);
real res[2] = to_array_1d(temp);
return res;
}
matrix TiTe(real[] time, real[] Ta, real[] Ps, real[] Ph,
real Ci, real Ce, real Rie, real Rea, real Aw) {
int nX = 2; // number of state variables
int nt = size(time); // number of time steps
matrix[nt, nX] result;
real parms[5] = to_array_1d([Ci, Ce, Rie, Rea, Aw]); // parameters have to be in array
int idata[0]; // integer data, not used
//init = rep_array(0, nT);
real t0 = time[1];
real init[nX];
init[1] = 15; // init internal temperature
init[2] = 10; // init same as CTSM-model
// init[2] = (init[1] + Ta[1]) / 2; // envelope temp as average of internal & ambient
for(i in 2:nt){
real rdata[3] = to_array_1d([Ta[i], Ps[i], Ph[i]]); // real data, have to be in array
init = TiTe_integrate(init, t0, time[i:i], parms, rdata, idata);
for(j in 1:nX) result[i, j] = init[j];
t0 = time[i];
}
return result;
}
}
data {
int nt;
real time[nt];
real Ta[nt];
real Ps[nt];
real Ph[nt];
// observation
real yTi[nt];
}
parameters {
// R-C network parameters
real<lower=0.0, upper=20> Ci;
real<lower=0.0, upper=20> Ce;
real<lower=0.0, upper=50> Rie;
real<lower=0.0, upper=50> Rea;
real<lower=0.0, upper=40> Aw;
real<lower=0> sigmaTi;
//real<lower=0> sigmaTe;
}
transformed parameters {
// the state variables
matrix[nt, 2] X; // X[, 1]: Ti (internal temperature), X[, 2]: Te (envelope temperature)
X = TiTe(time, Ta, Ps, Ph, Ci, Ce, Rie, Rea, Aw);
}
model {
// observed data likelihood
yTi ~ normal(X[, 1], sigmaTi);
}
Exposing the functions with rstan::expose_stan_functions
works fine and calling the TiTe
-function from R with data and parameters return expected results.
But, trying to compile with stan_model
returns following error: Compilation ERROR, function(s)/method(s) not created!
Any suggestions on what is going wrong are welcome!
Regards,
Lukas Lundström