One dimensional system fails with incomprehensible error message
AWildSugar opened this issue · 8 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.