Closed schillic closed 5 years ago
The problem is caused by MappedArrays
: They call zero(eltype(A))
for array A
if it is empty. In the case here, A::Vector(Int)
, so zero(eltype(A)) == 0
. Then the edge_object
function crashes because a location with index 0 does not exist. I am working on a fix, but I only see an unpleasent way how to make it type stable using MappedArrays
.
We can give the type to MappedArrays
so that it does not need to infer it (last time I checked it was not possible, I am glad they added it):
julia> mappedarray(x -> sqrt(-1 + x), 1:0)
ERROR: DomainError with -1.0:
sqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).
Stacktrace:
[1] sqrt at ./math.jl:492 [inlined]
[2] sqrt at ./math.jl:518 [inlined]
[3] #15 at ./REPL[17]:1 [inlined]
[4] mappedarray(::getfield(Main, Symbol("##15#16")), ::UnitRange{Int64}) at /home/blegat/.julia/packages/MappedArrays/kV0sK/src/MappedArrays.jl:61
[5] top-level scope at none:0
julia> mappedarray(Float64, x -> sqrt(-1 + x), 1:0)
0-element mappedarray(Float64, getfield(Main, Symbol("##17#18"))(), ::UnitRange{Int64}) with eltype Float64
Wouldn't it resolve the issue ?
Perfect! Should I update my PR or do you want to send a fix?
You can update the PR, I am on my phone at the moment
I failed to do it (see #30).
My example doesn't work, the sqrt function is taken as the inverse function.
julia> mappedarray(Float64, x -> sqrt(-1 + x), 1:2)
2-element mappedarray(Float64, getfield(Main, Symbol("##7#8"))(), ::UnitRange{Int64}) with eltype Float64:
1.0
2.0
This is very embarrassing, but my "fix" did not actually fix the example in the inital post :disappointed:
what do you mean that it didn't fix it? i get no error so far:
julia> using HybridSystems
julia> automaton = LightAutomaton(2)
LightAutomaton{LightGraphs.SimpleGraphs.SimpleDiGraph{Int64},LightGraphs.SimpleGraphs.SimpleEdge{Int64}}({2, 0} directed simple Int64 graph, Dict{LightGraphs.SimpleGraphs.SimpleEdge{Int64},Dict{Int64,Int64}}(), 0, 0)
julia> add_transition!(automaton, 1, 1, 1)
HybridSystems.LightTransition{LightGraphs.SimpleGraphs.SimpleEdge{Int64}}(Edge 1 => 1, 1)
julia> add_transition!(automaton, 1, 2, 2)
HybridSystems.LightTransition{LightGraphs.SimpleGraphs.SimpleEdge{Int64}}(Edge 1 => 2, 2)
julia> m1 = "mode1"
"mode1"
julia> m2 = "mode2"
"mode2"
julia> modes = [m1, m2]
2-element Array{String,1}:
"mode1"
"mode2"
julia> resetmaps = ["transition1", "transition2"]
2-element Array{String,1}:
"transition1"
"transition2"
julia> switchings = [AutonomousSwitching() for _ in 1:2]
2-element Array{AutonomousSwitching,1}:
AutonomousSwitching()
AutonomousSwitching()
julia> H = HybridSystem(automaton, modes, resetmaps, switchings)
Hybrid System with automaton LightAutomaton{LightGraphs.SimpleGraphs.SimpleDiGraph{Int64},LightGraphs.SimpleGraphs.SimpleEdge{Int64}}({2, 2} directed simple Int64 graph, Dict(Edge 1 => 2=>Dict(2=>2),Edge 1 => 1=>Dict(1=>1)), 2, 2)
julia>
julia> out_transitions(H, 1)
HybridSystems.LightTransitionIterator{LightGraphs.SimpleGraphs.SimpleDiGraph{Int64},LightGraphs.SimpleGraphs.SimpleEdge{Int64},MappedArrays.ReadonlyMappedArray{LightGraphs.SimpleGraphs.SimpleEdge{Int64},1,Array{Int64,1},getfield(HybridSystems, Symbol("#f#4")){LightAutomaton{LightGraphs.SimpleGraphs.SimpleDiGraph{Int64},LightGraphs.SimpleGraphs.SimpleEdge{Int64}},Int64}}}(LightAutomaton{LightGraphs.SimpleGraphs.SimpleDiGraph{Int64},LightGraphs.SimpleGraphs.SimpleEdge{Int64}}({2, 2} directed simple Int64 graph, Dict(Edge 1 => 2=>Dict(2=>2),Edge 1 => 1=>Dict(1=>1)), 2, 2), LightGraphs.SimpleGraphs.SimpleEdge{Int64}[Edge 1 => 1, Edge 1 => 2])
julia>
julia> out_transitions(H, 2)
HybridSystems.LightTransitionIterator{LightGraphs.SimpleGraphs.SimpleDiGraph{Int64},LightGraphs.SimpleGraphs.SimpleEdge{Int64},MappedArrays.ReadonlyMappedArray{LightGraphs.SimpleGraphs.SimpleEdge{Int64},1,Array{Int64,1},getfield(HybridSystems, Symbol("#f#4")){LightAutomaton{LightGraphs.SimpleGraphs.SimpleDiGraph{Int64},LightGraphs.SimpleGraphs.SimpleEdge{Int64}},Int64}}}(LightAutomaton{LightGraphs.SimpleGraphs.SimpleDiGraph{Int64},LightGraphs.SimpleGraphs.SimpleEdge{Int64}}({2, 2} directed simple Int64 graph, Dict(Edge 1 => 2=>Dict(2=>2),Edge 1 => 1=>Dict(1=>1)), 2, 2), LightGraphs.SimpleGraphs.SimpleEdge{Int64}[])
julia> collect(ans)
0-element Array{HybridSystems.LightTransition{LightGraphs.SimpleGraphs.SimpleEdge{Int64}},1}
julia> isempty(ans)
true
Okay, this is even more embarrassing :smile:
Apparently I used the release version of HybridSystems
.
@blegat: Do you mind sending a new release?
Here is a small example of an automaton where the second location has no outgoing transition.
This script breaks in the last line with the following message:
After adding
println("q = $q, r = $r")
to this line I get this output:It seems that the graph method here returns
0
if there is no outgoing edge, which is apparently not expected by the other function.