Reduzieren der Speicherzuordnung in DifferentialEquations.jl

Dec 08 2020

Ich verwende DifferentialEquations.jl, um ein ODE-System wie unten gezeigt zu lösen. Das Ergebnis ist nicht wirklich relevant, da es pnur Testparameter zum Erstellen eines MWE enthält. Der Schlüssel ist jedoch, dass ich trotz Verwendung einer vorhandenen ODE-Funktion viel Speicherzuweisung sehe.

using DifferentialEquations

function ode_fun!(du,u,p,t)
    a,b,c,d,e = p

    X = @. u[1] * a * ((b-c)/b)
    Y = @. u[2] * d * ((b-e)/b)

    du[1] = -sum(X) + sum(Y) - u[1]*u[2]
    du[2] = sum(X) - sum(Y) - u[1]*u[2]
end

#exemplary parameters 
a = collect(10:-0.1:0.1)
b = a.^2
c = b*0.7
d = collect(0.01:0.01:1)
e = b*0.3

u0 = [1.0, 0.5]
p = [a,b,c,d,e]
tspan = [0.0, 100.0]
t = collect(0:0.01:100) 

prob = ODEProblem(ode_fun!,u0,tspan,p,saveat=t) 
@time sol = solve(prob)

1.837609 seconds (5.17 M allocations: 240.331 MiB, 2.31% gc time) #Julia 1.5.2

Da ich dieses ODE-System wiederholt lösen muss, möchte ich die Zuweisungen so weit wie möglich reduzieren und frage mich, ob etwas dagegen unternommen werden kann. Ich habe mich gefragt, ob das Problem bei Xund liegt, Yund habe versucht, diese außerhalb der ODE-Funktion vorzuordnen, aber es ist mir leider nicht gelungen, die Zuweisungen auf diese Weise zu reduzieren.

Antworten

2 OscarSmith Dec 08 2020 at 12:51

Ich bin mir ziemlich sicher, dass dies schneller sein sollte und die Hälfte der Zuweisungen

function ode_fun!(du,u,p,t)
    a,b,c,d,e = p
    XmY = @. u[1] * a * (1-c/b) - u[2] * d * (1-e/b)
    sXmY = sum(XmY)
    du[1] = -sXmY - u[1]*u[2]
    du[2] = sXmY - u[1]*u[2]
end

Es gibt wahrscheinlich einen Weg, sie alle loszuwerden, aber ich bin kein DifferentialEquationsExperte.