I’m trying to model a biological system of a population, N, and a trait, X.
The rate of change of the population, \frac{dN}{dt}, depends on some nonlinear function that is governed by some dynamic trait of the population, f(X).
The rate of change of X, \frac{dX}{dt}, depends on the derivative of \frac{dN}{dt} with respect to X: \frac{dX}{dt} = \frac{\partial}{\partial X}\frac{dN}{dt}.
I am trying to do this entirely in Julia, as my actual system is a bit more complex and I want to avoid introducing human error, meaning that I’m trying to take advantage of Symbolics differentiation. However, I run into problems when using the derivative on the right-hand side of the differential equations.
A demonstration:
## Setup demonstration
using ModelingToolkit, Symbolics, Plots
# I define a demo function here that is similar but simpler than what I actually
# need - a, b, and c are parameters, X a state variable
f(X, a, b, c) = a / (1 + (b / X) ^ c);
# Usually I try it out with some test parameters to make sure I haven't done
# anything weird
p = (a = 1.0,
b = 2.0,
c = 0.5);
# And also with a test vector of X
Xvec = 0:0.01:2;
# Then I like to see how this function is behaving with X
plot(Xvec, f.(Xvec, p...), label = :none)
## Moving into ModelingToolkit stuff
# State variables and parameters
@parameters t a b c; # Including time, t
@variables N(t) X(t); # Two state variables to track,
# the 2nd depends on the derivative w.r.t. X of the 1st
# I need a symbolic version of the earlier function for ModelingToolkit
# to do its thing
F = f(X, a, b, c);
# Define derivatives
D = Differential(t); # time
Dx = Differential(X); # state variable X
# Rate of change of population
dNdt = N * F - 0.1;
# Defining the equations for the system
eqs = [D(N) ~ dNdt;
D(X) ~ Dx(dNdt)]
# Putting it into ODE
@named sys = ODESystem(eqs); # this breaks
# returning:
# ArgumentError: Cannot find the parent of a / (1 + (b / X(t))^c).
Is there something specific that I’m doing wrong here or is this whole approach wrong? I am fairly new to this and haven’t found anything in the documentation that matches this exact problem.
Any help would be hugely appreciated !