SciML / diffeqpy

Solving differential equations in Python using DifferentialEquations.jl and the SciML Scientific Machine Learning organization
MIT License
531 stars 39 forks source link

Using `de.eval` leads to "ArgumentError: reducing over an empty collection is not allowed" #71

Closed valentinsulzer closed 4 years ago

valentinsulzer commented 4 years ago

Working through the examples in the Jupyter post, one of the examples fails TLDR: de.eval doesn't work but using Main.eval instead does

Doesn't work

from diffeqpy import de
jul_f = de.eval("""
function f(du,u,p,t)
  x, y, z = u
  sigma, rho, beta = p
  du[1] = sigma * (y - x)
  du[2] = x * (rho - z) - y
  du[3] = x * y - beta * z
end""")
u0 = [1.0,0.0,0.0]
tspan = (0., 100.)
p = [10.0,28.0,2.66]
prob = de.ODEProblem(jul_f, u0, tspan, p)
sol = de.solve(prob,abstol=1e-8,reltol=1e-8)

error:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-1-c01f82d1aa9d> in <module>
     11 tspan = (0., 100.)
     12 p = [10.0,28.0,2.66]
---> 13 prob = de.ODEProblem(jul_f, u0, tspan, p)
     14 sol = de.solve(prob,abstol=1e-8,reltol=1e-8)
     15 sol.u

ValueError: Julia exception: ArgumentError: reducing over an empty collection is not allowed
Stacktrace:
 [1] _empty_reduce_error() at ./reduce.jl:299
 [2] reduce_empty(::Function, ::Type{Any}) at ./reduce.jl:309
 [3] mapreduce_empty(::typeof(identity), ::Function, ::Type{T} where T) at ./reduce.jl:343
 [4] reduce_empty(::Base.MappingRF{typeof(identity),typeof(max)}, ::Type{Any}) at ./reduce.jl:329
 [5] reduce_empty_iter at ./reduce.jl:355 [inlined]
 [6] mapreduce_empty_iter(::Function, ::Function, ::Array{Any,1}, ::Base.HasEltype) at ./reduce.jl:351
 [7] _mapreduce(::typeof(identity), ::typeof(max), ::IndexLinear, ::Array{Any,1}) at ./reduce.jl:400
 [8] _mapreduce_dim at ./reducedim.jl:318 [inlined]
 [9] #mapreduce#620 at ./reducedim.jl:310 [inlined]
 [10] mapreduce at ./reducedim.jl:310 [inlined]
 [11] _maximum at ./reducedim.jl:724 [inlined]
 [12] _maximum(::Array{Any,1}, ::Colon) at ./reducedim.jl:723
 [13] #maximum#631 at ./reducedim.jl:719 [inlined]
 [14] maximum at ./reducedim.jl:719 [inlined]
 [15] numargs(::String) at /Users/vsulzer/.julia/packages/DiffEqBase/T5smF/src/utils.jl:13
 [16] isinplace(::String, ::Int64) at /Users/vsulzer/.julia/packages/DiffEqBase/T5smF/src/utils.jl:42
 [17] DiffEqBase.ODEFunction(::String; kwargs::Base.Iterators.Pairs{Symbol,Nothing,NTuple{10,Symbol},NamedTuple{(:analytic, :tgrad, :jac, :jvp, :vjp, :Wfact, :Wfact_t, :paramjac, :syms, :colorvec),NTuple{10,Nothing}}}) at /Users/vsulzer/.julia/packages/DiffEqBase/T5smF/src/diffeqfunction.jl:391
 [18] convert at /Users/vsulzer/.julia/packages/DiffEqBase/T5smF/src/diffeqfunction.jl:1083 [inlined]
 [19] DiffEqBase.ODEProblem(::String, ::Array{Float64,1}, ::Tuple{Float64,Float64}, ::Array{Float64,1}; kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /Users/vsulzer/.julia/packages/DiffEqBase/T5smF/src/problems/ode_problems.jl:76
 [20] DiffEqBase.ODEProblem(::String, ::Array{Float64,1}, ::Tuple{Float64,Float64}, ::Array{Float64,1}) at /Users/vsulzer/.julia/packages/DiffEqBase/T5smF/src/problems/ode_problems.jl:76
 [21] invokelatest(::Any, ::Any, ::Vararg{Any,N} where N; kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at ./essentials.jl:710
 [22] invokelatest(::Any, ::Any, ::Vararg{Any,N} where N) at ./essentials.jl:709
 [23] _pyjlwrap_call(::Type{T} where T, ::Ptr{PyCall.PyObject_struct}, ::Ptr{PyCall.PyObject_struct}) at /Users/vsulzer/.julia/packages/PyCall/zqDXB/src/callback.jl:28
 [24] pyjlwrap_call(::Ptr{PyCall.PyObject_struct}, ::Ptr{PyCall.PyObject_struct}, ::Ptr{PyCall.PyObject_struct}) at /Users/vsulzer/.julia/packages/PyCall/zqDXB/src/callback.jl:49

Does work

from diffeqpy import de
from julia import Main
jul_f = Main.eval("""
function f(du,u,p,t)
  x, y, z = u
  sigma, rho, beta = p
  du[1] = sigma * (y - x)
  du[2] = x * (rho - z) - y
  du[3] = x * y - beta * z
end""")
u0 = [1.0,0.0,0.0]
tspan = (0., 100.)
p = [10.0,28.0,2.66]
prob = de.ODEProblem(jul_f, u0, tspan, p)
sol = de.solve(prob,abstol=1e-8,reltol=1e-8)
valentinsulzer commented 4 years ago

Nevermind, have just seen this is fine in the README.md šŸ¤¦

ChrisRackauckas commented 4 years ago

Yeah that blog post is a few years old so it's probably not up to date.