Stan's ODE solver has a fixed signature. The state, parameters and data has to be given as arrays. This can get confusing during development of a model, since parameters can change to constants (i.e. data), the number of parameters can change and even the state variables could change. Errors can easily creep in since the user has to correctly change all indices in the ODE function, and in (e.g.) the
model
block.
A nice way to solve this is using constant functions. Constants in Stan are functions without an argument that
return the constant value. For instance pi()
returns 3.14159265... The user can define such constants
in the functions
block. Suppose that we want to fit the Lotka-Volterra model to data. The system of ODEs is given by
\[ \frac{dx}{dt} = ax - bxy\,,\quad \frac{dy}{dt} = cbxy - dy \]
and so we have a 2-dimenional state, and we need a parameter vector of length 4.
In the function
block, we will define a function int idx_a() { return 1; }
that returns the index of the parameter \(a\) in the parameter vector, and we define similar functions
for the other parameters. The full model can be implemented in Stan as shown below. The data Preys
and Predators
is assumed to be Poisson-distributed with mean \(Kx\) and \(Ky\), respectively,
for some large constant \(K\).
I fitted the model to some randomly generated data, which resulted in figure above.
Of course, this is still a low-dimensional model with a small number of parameters, but I found that even in a simple model, defining parameter indices in this way keeps everything concise.
I used the following Python script to generate the data and interface with Stan.
The following Figure show the parameter estimates together with the "real" parameter values
No comments:
Post a Comment