JuliaDynamics / DynamicalSystems.jl

Award winning software library for nonlinear dynamics and nonlinear timeseries analysis

Home Page:https://juliadynamics.github.io/DynamicalSystemsDocs.jl/dynamicalsystems/dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

One dimensional system fails with incomprehensible error message

AWildSugar opened this issue · comments

Hey, I was playing around with getting a simple dynamical system working, and I couldn't get it to work without sticking the 0.0's in as the second dimension of the system. The error message/trace is super unhelpful too, and I'm still not sure why it didn't work.
Maybe you can improve the message (before it goes into the ForwardDiff library?)

function one_dim_neuron()                             
    hodg_hux(x, p, t) = SVector{2}((x[1] - p[1]) - p[2]*(x[1] - p[3]), 0.0)
    state = SVector{2}(-80.0, 0.0)             
    p = SVector{3}(-70.0, 1.0, 40.0)   
                           
    hh = ContinuousDynamicalSystem(hodg_hux, state, p)
end

ERROR: MethodError: no method matching derivative(::DynamicalSystemsBase.var"#11#18"{StaticArrays.SArray{Tuple{3},Float64,1,3},Float64,var"#hodg_hux#15"}, ::StaticArrays.SArray{Tuple{1},Float64,1,1})
Closest candidates are:
derivative(::Any, ::AbstractArray, ::Real) at /home/alex/.julia/packages/ForwardDiff/sdToQ/src/derivative.jl:27
derivative(::Any, ::AbstractArray, ::Real, ::ForwardDiff.DerivativeConfig{T,D} where D) where T at /home/alex/.julia/packages/ForwardDiff/sdToQ/src/derivative.jl:27
derivative(::Any, ::AbstractArray, ::Real, ::ForwardDiff.DerivativeConfig{T,D} where D, ::Val{CHK}) where {T, CHK} at /home/alex/.julia/packages/ForwardDiff/sdToQ/src/derivative.jl:27
...
Stacktrace:
[1] (::DynamicalSystemsBase.var"#10#17"{var"#hodg_hux#15"})(::StaticArrays.SArray{Tuple{1},Float64,1,1}, ::StaticArrays.SArray{Tuple{3},Float64,1,3}, ::Float64) at /home/alex/.julia/packages/DynamicalSystemsBase/BT13p/src/dynamicalsystem.jl:302
[2] get_J(::DynamicalSystemsBase.var"#10#17"{var"#hodg_hux#15"}, ::StaticArrays.SArray{Tuple{1},Float64,1,1}, ::StaticArrays.SArray{Tuple{3},Float64,1,3}, ::Float64, ::Bool) at /home/alex/.julia/packages/DynamicalSystemsBase/BT13p/src/dynamicalsystem.jl:319

Hi, can you please help me help you: when I run the code you paste I don't get any errors... Where is the error happening?

I guess you mean this:

julia> state = SVector{1}(-80.0)
1-element StaticArrays.SArray{Tuple{1},Float64,1,1} with indices SOneTo(1):
 -80.0

julia> hh = ContinuousDynamicalSystem(hodg_hux, state, p)
ERROR: MethodError: no method matching derivative(::DynamicalSystemsBase.var"#11#18"{StaticArrays.SArray{Tuple{3},Float64,1,3},Float64,typeof(hodg_hux)}, ::StaticArrays.SArray{Tuple{1},Float64,1,1})
Closest candidates are:
  derivative(::Any, ::AbstractArray, ::Real) at C:\Users\datse\.julia\packages\ForwardDiff\sdToQ\src\derivative.jl:25
  derivative(::Any, ::AbstractArray, ::Real, ::ForwardDiff.DerivativeConfig{T,D} where D) where T at C:\Users\datse\.julia\packages\ForwardDiff\sdToQ\src\derivative.jl:25
  derivative(::Any, ::AbstractArray, ::Real, ::ForwardDiff.DerivativeConfig{T,D} where D, ::Val{CHK}) where {T, CHK} at C:\Users\datse\.julia\packages\ForwardDiff\sdToQ\src\derivative.jl:25
  ...
Stacktrace:
 [1] (::DynamicalSystemsBase.var"#10#17"{typeof(hodg_hux)})(::StaticArrays.SArray{Tuple{1},Float64,1,1}, ::StaticArrays.SArray{Tuple{3},Float64,1,3}, ::Float64) at C:\Users\datse\.julia\dev\DynamicalSystemsBase\src\dynamicalsystem.jl:302
 [2] get_J(::DynamicalSystemsBase.var"#10#17"{typeof(hodg_hux)}, ::StaticArrays.SArray{Tuple{1},Float64,1,1}, ::StaticArrays.SArray{Tuple{3},Float64,1,3}, ::Float64, ::Bool) at C:\Users\datse\.julia\dev\DynamicalSystemsBase\src\dynamicalsystem.jl:319
 [3] ContinuousDynamicalSystem(::Function, ::StaticArrays.SArray{Tuple{1},Float64,1,1}, ::StaticArrays.SArray{Tuple{3},Float64,1,3}; t0::Float64) at C:\Users\datse\.julia\dev\DynamicalSystemsBase\src\dynamicalsystem.jl:238
 [4] ContinuousDynamicalSystem(::Function, ::StaticArrays.SArray{Tuple{1},Float64,1,1}, ::StaticArrays.SArray{Tuple{3},Float64,1,3}) at C:\Users\datse\.julia\dev\DynamicalSystemsBase\src\dynamicalsystem.jl:227
 [5] top-level scope at none:1

Hey sorry, like I said it works like that but I had to put the zeros in as a 'dummy' dimension.

function one_dim_neuron()                             
    hodg_hux(x, p, t) = SVector{1}((x[1] - p[1]) - p[2]*(x[1] - p[3]))
    state = SVector{1}(-80.0)             
    p = SVector{3}(-70.0, 1.0, 40.0)   
                           
    hh = ContinuousDynamicalSystem(hodg_hux, state, p)
end

Damn, I have forgotten about this... Actually 1D continuous systems were never supported I now realize :( You need some special handling for automatic differentiation in the case of 1 dimension, which I never wrote code for. For discrete systems 1D is supported. I'll see if there is some quick fix, but I'll first write an error message about it.

At the moment your workaround is the best we can do (unfortunately I don't have much time at the moment). Or, you create a derivative explicitly yourself.

Ah ok, I figured it was something weird like that. But yeah maybe an error message so the next guy doesn't spend an hour looking at three line of code ;).

julia> hodg_hux(x, p, t) = SVector((x[1] - p[1]) - p[2]*(x[1] - p[3]))
hodg_hux (generic function with 1 method)

julia> hodg_hux_der(x, p, t) = SVector(- p[2])
hodg_hux_der (generic function with 1 method)

# state = SVector(0.8)

julia> hh = ContinuousDynamicalSystem(hodg_hux, state, p, hodg_hux_der)
1-dimensional continuous dynamical system
 state:       [0.8]
 e.o.m.:      hodg_hux
 in-place?    false
 jacobian:    hodg_hux_der
 parameters:  [-70.0, 1.0, 40.0]

julia> trajectory(hh, 10)
1-dimensional Dataset{Float64} with 1001 points
    0.8
    1.8999999999999944
    2.9999999999999987
    4.099999999999998
    5.200000000000003
    6.299999999999994
    7.399999999999989
    8.499999999999993
    9.599999999999987
   10.699999999999964
    
 1091.9999999999968
 1093.1
 1094.1999999999944
 1095.2999999999972
 1096.3999999999946
 1097.4999999999986
 1098.5999999999972
 1099.7000000000012
 1100.8000000000002

Though, I checked (because I thought I tried this), and DiscreteDynamicalSystem doesn't seem to work either.


function one_dim_neuron()                             
    hodg_hux(x, p, t) = SVector{1}((x[1] - p[1]) - p[2]*(x[1] - p[3]))     
    state = SVector{1}(-80.0)                  
    p = SVector{3}(-70.0, 1.0, 40.0)   
                           
    hh = DiscreteDynamicalSystem(hodg_hux, state, p)  
end                                    

one_dim_neuron()
ERROR: MethodError: no method matching derivative(::DynamicalSystemsBase.var"#11#18"{StaticArrays.SArray{Tuple{3},Float64,1,3},Int64,var"#hodg_hux#21"}, ::StaticArrays.SArray{Tuple{1},Float64,1,1})
Closest candidates are:
derivative(::Any, ::AbstractArray, ::Real) at /home/alex/.julia/packages/ForwardDiff/sdToQ/src/derivative.jl:27
derivative(::Any, ::AbstractArray, ::Real, ::ForwardDiff.DerivativeConfig{T,D} where D) where T at /home/alex/.julia/packages/ForwardDiff/sdToQ/src/derivative.jl:27
derivative(::Any, ::AbstractArray, ::Real, ::ForwardDiff.DerivativeConfig{T,D} where D, ::Val{CHK}) where {T, CHK} at /home/alex/.julia/packages/ForwardDiff/sdToQ/src/derivative.jl:27
...
Stacktrace:

Yeah, because discrete dynamical systems have full analytic support for 1D throughout the ecosystem, including stuff like Lyapunov exponents, and expect the state as a pure number, e.g. 0.8 instead of SVector(0.8). See the commit that I just referenced.