How to use DifferentialEquations with complicated equations

Hello Everyone, I am back with a functioning code that generates differential equations. Wooo! :relieved:

Apologies if any of this seems obvious, but the things I learned along the way (in case anyone else struggling is reading this):

Making something a constant (const) even if the value changes, is okay (and recommended). The const only keeps the type the same e.g. zxcv = 12.45 can change to zxcv = 15.23 but it cannot change to zxcv = 12 (this is a different data type).

zeros(size(qwer)) is used when it is an array
zeros(asdf) is used when it is a tuple

for i in length(qwer) is faster when it is an array
for i in 1:asdf is faster when it is a tuple

So if you have formulas like this;

image

that feed into differential formulas like this;

image

First you need to make a function that calculates Fij. I had difficulty with making a sum function (image ) because I thought it would be

sumF = 0.0
sumF = sumF + b[(pred), k]*bioS[k]^(1+q)

where pred is either i or j depending on the formula (because sometimes the predator becomes the prey) and bioS is the biomass of a species,

The feeding function then looks like

function FF(pred, prey, bioS, bm, b, h, Ο‰, q)
    sumF = 0.0

    for k in 1:bm
        if foodWeb[(pred), k] != 0.0
            sumF = sumF + b[(pred), k]*bioS[k]^(1+q)
        end
    end
    return (((Ο‰[pred]*b[pred,prey]*bioS[prey]*bioS[prey]^(1+q))/(1+c*bioS[pred]+Ο‰[pred]*h[pred]*sumF))/bm[pred])
end

This then gets put into another function (exactly how EIOceanografo showed here, so apologies for being slow on the uptake)

The dAdT equation (second formula) then looks something like:

function dAdT(dA, foodWeb, e, bioS, X, num_plant, num_animal, num_nutrient, bm, b, h, Ο‰, q)
    dA = zeros(num_animal)
    for i in 1:num_animal
        into = 0.0
        out = 0.0
        for j in num_nutrient+1:arr_size
            if foodWeb[i,j-num_nutrient] !=0.0
                into = into+e[j-num_nutrient]*FF(pred, prey, bioS, bm, b, h, Ο‰, q) #here you put all the parameters needed to run FF
            end
            if foodWeb[j-num_nutrient, i+num_plant] !=0.0
                out = out+FF(pred, prey, bioS, bm, b, h, Ο‰, q)*bioS[j]  #here you put all the parameters needed to run FF
            end
        end
        into = into*bioS[num_nutrient+num_plant+i]
        met = X[num_plant+i]*bioS[num_nutrient+num_plant+i]
        dA[i] = into-out-met
    end
    return dA
end

And then you need to create the function to run the differential equation, which looks something like

function dBdT(dB, bioS, p, t) #the change in biomass (bioS) is what we are interested in

    dA = dB

    dB = dAdT(dA, foodWeb, e, bioS, X, num_plant, num_animal, num_nutrient, bm, b, h, Ο‰, q) #put all the parameters needed to produce dAdT here
    return dB
end

tspan = (0.0,500.0)
p = (foodWeb, num_plant, num_animal, num_nutrient, bm, b, h, Ο‰, q) #do not put the variable that is being changed (e.g.  bioS) in here, only parameters

prob = ODEProblem(dBdT,bioS,tspan,p)
sol=solve(prob)

The code snippets I post won’t work by themselves, and they are also edited because I have two more differential functions that go into dBdT, but I hope this is enough for whoever is also trying to figure out nested functions.

My next task is how to put a callback into this :rofl: But I will make a new topic for it.

3 Likes