Zmniejszenie alokacji pamięci w DifferentialEquations.jl

Dec 08 2020

Używam DifferentialEquations.jl do rozwiązywania systemu ODE, jak pokazano poniżej. Wynik nie jest tak naprawdę istotny, ponieważ pzawiera tylko parametry testowe w celu wytworzenia MWE, ale kluczem jest to, że widzę dużo alokacji pamięci pomimo używania funkcji ODE w miejscu.

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

Ponieważ muszę wielokrotnie rozwiązywać ten system ODE, chciałbym maksymalnie zredukować przydziały i zastanawiam się, czy można coś z nimi zrobić. Zastanawiałem się, czy problem tkwi w Xi Yi próbowali przydzielenia Te poza funkcją ODE, ale niestety nie udało się obniżyć alokacje w ten sposób.

Odpowiedzi

2 OscarSmith Dec 08 2020 at 12:51

Jestem prawie pewien, że powinno to być szybsze i połowę alokacji

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

Prawdopodobnie jest sposób na pozbycie się ich wszystkich, ale nie jestem DifferentialEquationsekspertem.