I have a Lotka-Voltera model on which i want to perform parameter estimation by calculating the gradients of the parameters using an extended ODE system. I know there are different methods for doing that but i choose to ignore those.
is a Lotka-Voltera model
For it derived the Forward sensivity equations using: $$\dot{s}_{i,j} = \frac{df_j}{dy_i} s_{i,j} + \frac{df_j}{p_i} \text{ where } \dot{y}=f(y,p_1, \ ..., p_I ,t), \ i \in \{1,...,I\}, y \in \mathbb{R}^J, j \in \{1,...,J\} $$
So $s_{i,j}$ would be the sensitivity of the $j$-th component of solution on parameter $i$. This gave me the following extension of the system of differential equations:
I can solve the Lotka-Voltera equations for intital conditions using:
function lotka_voltera(u,p,t)
N₁, N₂ = u
ϵ₁, ϵ₂, γ₁, γ₂ = p # p_1 ... p_4
return [N₁*ϵ₁ - γ₁*N₁*N₂, -N₂*ϵ₂ + γ₂*N₁*N₂]
end
u₀ = [1.,1.];
p = [3.,1.,0.5,0.4];
t =(0., 3.);
prob = ODEProblem(lotka_voltera, u₀, t, p)
solution = solve(prob);
plot(solution)
and get a plot like this:
However when implemented the extension of the system of equations in Julia:
function lotka_sensitivity(du, u, p, t)
du[:,1] = lotka_voltera(u[:,1],p,t)
N₁, N₂ = u[:,1] # ; s₁ₚ₁ s₂ₚ₁; s₁ₚ₂ s₂ₚ₂; s₁ₚ₃ s₂ₚ₃; s₁ₚ₄ s₂ₚ₄
p₁, p₂, p₃, p₄ = p
J = [(p₁-p₂*N₂) (-p₂*N₁); (p₄*N₁) (p₄*N₂-p₃)]
du[:,2] = (J*u[:,2]) .+ [N₁, 0.]
du[:,3] = (J*u[:,3]) .+ [-N₂*N₁, 0.]
du[:,4] = (J*u[:,4]) .+ [0., -N₂]
du[:,5] = (J*u[:,5]) .+ [0., N₂*N₁]
end
u₀ₚ = hcat(u₀, zeros(2,4)) # the 2nd to fith coulouns are for the sensitivities. Those are 0 as the inital conditions u_0 are fixed and independent of p
prob_sensitivity = ODEProblem(lotka_sensitivity, u₀ₚ, t, p)
solution_sensitivity = solve(prob_sensitivity);
plot(solution_sensitivity; vars=[(1),(2),(3),#=(4),=#(5),#=(6),=#(7),#=(8),(9),(10)=#])
Then the solutions i commented out from plotting grow exponentially with time. This shouldn't be in my understanding.
What did i do wrong? Possible sources of error are:
- Did i use the right formula for the sensitivity i want?
- Is my extended system correct?
- Is it correct that i let the sensitivities start at 0?
- Did i implement the ODE correctly?
The complete code in a Pluto notebook which also is a standalone file for reference and also includes what dependencies are necessary. In vorschlag3 i try to calculate the integrated square error in the first component of solution compared to one with different parameters and attempt to do a gradient descent to minimize it. This also fails.




At some point, you tried to make the code more readable with the Greek letters, and in the course of that change switched the order of parameters, but did not carry through to all places or corrected the order.
In the Volterra-Lotka equations, the first two parameters are birth (B) and death (R) rates and the second pair are the interaction rates. In the sensitivity formulas, you treat the parameters as if the first pair belongs to the first (B) equation and the second pair to the second (R). So in one place you have to switch the roles of the second and third parameter, I think the least change is from
to
along with the same switch in the definition of the parameter array.