Reducir la asignación de memoria en DifferentialEquations.jl

Dec 08 2020

Estoy usando DifferentialEquations.jl para resolver un sistema ODE como se muestra a continuación. El resultado no es realmente relevante ya que psolo contiene parámetros de prueba con el fin de producir un MWE, pero la clave es que estoy viendo una gran cantidad de asignación de memoria a pesar de usar una función ODE en el lugar.

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

Como necesito resolver este sistema ODE repetidamente, me gustaría reducir las asignaciones tanto como sea posible y me pregunto si hay algo que se pueda hacer al respecto. Me he estado preguntando si el problema radica en Xy Yhe intentado preasignar estos fuera de la función ODE, pero desafortunadamente no he logrado reducir las asignaciones de esa manera.

Respuestas

2 OscarSmith Dec 08 2020 at 12:51

Estoy bastante seguro de que esto debería ser más rápido y la mitad de las asignaciones

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

Probablemente haya una forma de deshacerse de todos ellos, pero no soy un DifferentialEquationsexperto.