# ODE with parameters as vectors

**URL:** <https://discourse.mc-stan.org/t/ode-with-parameters-as-vectors/26762>\
**Category:** Modeling\
**Created:** [March 11, 2022, 2:49pm UTC](https://discourse.mc-stan.org/t/ode-with-parameters-as-vectors/26762 "2022-03-11T14:49:46Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![irenegfsr](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/irenegfsr/32/15802_2.png) [@irenegfsr](https://discourse.mc-stan.org/u/irenegfsr)\
**Post date:** [March 11, 2022, 2:49pm UTC](https://discourse.mc-stan.org/t/ode-with-parameters-as-vectors/26762/1 "2022-03-11T14:49:46Z")

</div>

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?

```stan
functions {
  real [] model3(real t, real[] y, real[] theta,
  real[] x_r, int[] x_i) {
    
    real AB= y[1];
    real ASC = y[2];
    
    real pAB = theta[1];
    real uAB = theta[2]; 
    real uASC = theta[3];
    
    
    real dAB_dt = pAB*ASC - uAB*AB;
    real dASC_dt = -uASC*ASC;
    
   return {dAB_dt, dASC_dt};
  }
}

```

---

<div class="post-metadata">

**Author:** ![yizhang](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/yizhang/32/15673_2.png) [@yizhang](https://discourse.mc-stan.org/u/yizhang)\
**Post date:** [March 11, 2022, 5:04pm UTC](https://discourse.mc-stan.org/t/ode-with-parameters-as-vectors/26762/2 "2022-03-11T17:04:59Z")

</div>

use `to_vector`, see [8 Mixed Operations | Stan Functions Reference](https://mc-stan.org/docs/2_29/functions-reference/mixed-operations.html)

---

<div class="post-metadata">

**Author:** ![irenegfsr](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/irenegfsr/32/15802_2.png) [@irenegfsr](https://discourse.mc-stan.org/u/irenegfsr)\
**Post date:** [March 14, 2022, 1:06pm UTC](https://discourse.mc-stan.org/t/ode-with-parameters-as-vectors/26762/3 "2022-03-14T13:06:54Z")

</div>

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

```stan
functions {
  vector model3(real t, vector y, vector pAB, 
  real uAB, vector uASC) {
    
    vector[2] dydt;
    
    dydt[1] = pAB*y[2]-uAB*y[1];
    dydt[2] = -uASC*y[2];
    
   return dydt;
  }
}
data {
  int <lower=1> nobs;
  real t0;
  vector[2] 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[2] 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?

---

<div class="post-metadata">

**Author:** ![caesoma](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/caesoma/32/19767_2.png) [@caesoma](https://discourse.mc-stan.org/u/caesoma)\
**Post date:** [March 14, 2022, 1:52pm UTC](https://discourse.mc-stan.org/t/ode-with-parameters-as-vectors/26762/4 "2022-03-14T13:52:41Z")

</div>

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](https://mc-stan.org/users/documentation/case-studies/convert_odes.html) 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).

---

<div class="post-metadata">

**Author:** ![jsocolar](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/jsocolar/32/2486_2.png) [@jsocolar](https://discourse.mc-stan.org/u/jsocolar)\
**Post date:** [March 14, 2022, 1:56pm UTC](https://discourse.mc-stan.org/t/ode-with-parameters-as-vectors/26762/5 "2022-03-14T13:56:38Z")

</div>

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

Thus, we see the error

```nohighlight
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.

---

<div class="post-metadata">

**Author:** ![irenegfsr](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/irenegfsr/32/15802_2.png) [@irenegfsr](https://discourse.mc-stan.org/u/irenegfsr)\
**Post date:** [March 14, 2022, 2:58pm UTC](https://discourse.mc-stan.org/t/ode-with-parameters-as-vectors/26762/6 "2022-03-14T14:58:46Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![irenegfsr](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/irenegfsr/32/15802_2.png) [@irenegfsr](https://discourse.mc-stan.org/u/irenegfsr)\
**Post date:** [March 14, 2022, 3:19pm UTC](https://discourse.mc-stan.org/t/ode-with-parameters-as-vectors/26762/7 "2022-03-14T15:19:33Z")

</div>

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:

```stan
functions {
  vector model3(real t, vector y, vector pAB, 
  vector uAB, vector uASC) {
    
    vector[2] dydt;
    
    dydt[1] = pAB*y[2]-uAB*y[1];
    dydt[2] = -uASC*y[2];
    
   return dydt;
  }
}
data {
  int <lower=1> nobs;
  real t0;
  vector[2] 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[2] 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); 
  }
}
´´´
```

---

<div class="post-metadata">

**Author:** ![jsocolar](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/jsocolar/32/2486_2.png) [@jsocolar](https://discourse.mc-stan.org/u/jsocolar)\
**Post date:** [March 14, 2022, 4:11pm UTC](https://discourse.mc-stan.org/t/ode-with-parameters-as-vectors/26762/8 "2022-03-14T16:11:45Z")

</div>

> [@irenegfsr](#):
>
> ```no-highlight
> functions {
> vector model3(real t, vector y, vector pAB, 
> vector uAB, vector uASC) {
>     
> vector[2] dydt;
>     
> dydt[1] = pAB*y[2]-uAB*y[1];
> dydt[2] = -uASC*y[2];
>     
> return dydt;
> }
> }
> 
> ```

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

---

<div class="post-metadata">

**Author:** ![irenegfsr](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.mc-stan.org/irenegfsr/32/15802_2.png) [@irenegfsr](https://discourse.mc-stan.org/u/irenegfsr)\
**Post date:** [March 15, 2022, 2:18pm UTC](https://discourse.mc-stan.org/t/ode-with-parameters-as-vectors/26762/9 "2022-03-15T14:18:59Z")

</div>

Thanks, this helped
