# ODE with parameters as vectors

Hi all,

I was wondering to use a function like mentioned below, but instead of using theta as a real[] to use instead vector theta? I would like to transform later on in the code these parameters of theta, and in order to transform them they need to be a vector type, but the problem is that I have already define this a real. Would that be possible?
Do I also need then to change the type real model3 to vector model3 as well?

``````functions {
real [] model3(real t, real[] y, real[] theta,
real[] x_r, int[] x_i) {

real AB= y;
real ASC = y;

real pAB = theta;
real uAB = theta;
real uASC = theta;

real dAB_dt = pAB*ASC - uAB*AB;
real dASC_dt = -uASC*ASC;

return {dAB_dt, dASC_dt};
}
}
``````

use `to_vector`, see 8 Mixed Operations | Stan Functions Reference

1 Like

Thanks!
However, I have tried this but since I defined in the function these parameters as reals it did not work; I have changed the code with the following code, with the following error message:
Error in stanc(filename, allow_undefined = TRUE) : 0

Semantic error in ‘string’, line 7, column 4 to column 32:

Ill-typed arguments supplied to assignment operator =: lhs has type real and rhs has type vector

``````functions {
vector model3(real t, vector y, vector pAB,
real uAB, vector uASC) {

vector dydt;

dydt = pAB*y-uAB*y;
dydt = -uASC*y;

return dydt;
}
}
data {
int <lower=1> nobs;
real t0;
vector y0;
array[nobs] real ts;
int <lower=1> indivs;
array[nobs] real antib;
real <lower=1, upper=indivs> subj[nobs];
}
parameters {
//real <lower=0> AB0;
real <lower=0> pAB0;
real <lower=0> uAB;
real <lower=0> uASC0;
//real <lower=0> sigmaAB0;
real <lower=0> sigma;
vector[indivs] rpAB;
vector[indivs] ruASC;
}
transformed parameters {
vector[indivs] pAB;
pAB = pAB0*rpAB;
vector[indivs] uASC;
uASC = uASC0*ruASC;
array[nobs] vector yhat = ode_bdf_tol(model3, y0, t0, ts, 1e-8, 1e-8, 1000, pAB, uAB, uASC);
}
model {
rpAB ~ lognormal(-2, sqrt(4));
uAB ~ lognormal(-1, sqrt(2));
ruASC ~ lognormal(-0.1, 0.44);
//AB0 ~ lognormal(-2, 4);
//sigmaAB0 ~ gamma(0.001, 0.001);
sigma ~ normal(0, 1);

//for (i in 1:nobs) {
//antib[i] ~ lognormal(yhat[i,1], sigma);
//}
antib ~ lognormal(log(yhat[ : , 2]), sigma);
}
generated quantities {
array[nobs] real z_pred;
for (j in 1:nobs) {
z_pred[j] = lognormal_rng(log(yhat[j,2]), sigma);
}
}
``````

Do you know why I could not use this vector type in the function denoted as pAB and uASC?

If a function takes a `real []` argument and you for some reason have the parameters as `vector` (or others like `row_vector` or a 1D matrix) you should use `to_array_1d` to convert them to the right type.

This will not change the type of the function itself, which will remain `real []`; however, note that for ODEs this is the old interface, the new interface has output type `vector` and takes parameters as separate `real` arguments (and I guess can also take a packed real array just like the old one).

1 Like

The error arises because at line 7 `dydt` has type real. (`dydt` is a vector; its elements are reals). `pAB*y-uAB*y;` has type vector, because `pAB` is a vector and a vector times a scalar is also a vector.

Thus, we see the error

``````Semantic error in ‘string’, line 7, column 4 to column 32:

Ill-typed arguments supplied to assignment operator =: lhs has type real and rhs has type vector
``````

It’s telling us that the left hand side is a real, and the right hand side is a vector.

1 Like

Where do you mean that I should use the argument to_array_1d?
I have tried also the following in the transformed parameters, defining in the function everything as real (for the parameters) instead of vectors:

to_vector(pAB) = pAB0*rpAB

However, this did not worked either

Thanks! However, when I change uAB to a vector type, and I also do the same transformation for uAB in the transformed parameters I do still get the same error message, please find the code:

``````functions {
vector model3(real t, vector y, vector pAB,
vector uAB, vector uASC) {

vector dydt;

dydt = pAB*y-uAB*y;
dydt = -uASC*y;

return dydt;
}
}
data {
int <lower=1> nobs;
real t0;
vector y0;
array[nobs] real ts;
int <lower=1> indivs;
array[nobs] real antib;
real <lower=1, upper=indivs> subj[nobs];
}
parameters {
//real <lower=0> AB0;
real <lower=0> pAB0;
real <lower=0> uAB0;
real <lower=0> uASC0;
//real <lower=0> sigmaAB0;
real <lower=0> sigma;
vector[indivs] rpAB;
vector[indivs] ruAB;
vector[indivs] ruASC;
}
transformed parameters {
vector[indivs] pAB;
pAB = pAB0*rpAB;
vector[indivs] uAB;
uAB = uAB0*ruAB;
vector[indivs] uASC;
uASC = uASC0*ruASC;
array[nobs] vector yhat = ode_bdf_tol(model3, y0, t0, ts, 1e-8, 1e-8, 1000, pAB, uAB, uASC);
}
model {
rpAB ~ lognormal(-2, sqrt(4));
ruAB ~ lognormal(-1, sqrt(2));
ruASC ~ lognormal(-0.1, 0.44);
//AB0 ~ lognormal(-2, 4);
//sigmaAB0 ~ gamma(0.001, 0.001);
sigma ~ normal(0, 1);

//for (i in 1:nobs) {
//antib[i] ~ lognormal(yhat[i,1], sigma);
//}
antib ~ lognormal(log(yhat[ : , 2]), sigma);
}
generated quantities {
array[nobs] real z_pred;
for (j in 1:nobs) {
z_pred[j] = lognormal_rng(log(yhat[j,2]), sigma);
}
}
´´´``````

The function arguments tell us that `pAB` is a vector, and `uAB` is a vector. At line 7, `pAB*y-uAB*y` is therefore a vector. But at line 7 `dydt` is not a vector; it is a real.

1 Like

Thanks, this helped

1 Like