Skip to content

Commit 56f83e2

Browse files
authored
fix infinite while loop problem in trajectory (#194)
* fix infinite while loop problem in trajectory * only reference ODEintegrator * AbstractODEIntegrator is tehe correct name
1 parent 1abe5d3 commit 56f83e2

File tree

4 files changed

+23
-10
lines changed

4 files changed

+23
-10
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "DynamicalSystemsBase"
22
uuid = "6e36e845-645a-534a-86f2-f5d4aa5a06b4"
33
repo = "https://github.com/JuliaDynamics/DynamicalSystemsBase.jl.git"
4-
version = "3.5.1"
4+
version = "3.5.2"
55

66
[deps]
77
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"

src/core/trajectory.jl

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ export trajectory
33
"""
44
trajectory(ds::DynamicalSystem, T [, u0]; kwargs...) → X, t
55
6-
Return a dataset `X` that will contain the trajectory of the system `ds`,
7-
after evolving it for total time `T`.
8-
`u0` is the state given given to [`reinit!`](@ref) prior to time evolution
9-
and defaults to [`initial_state(ds)`](@ref).
6+
Evolve `ds` for a total time of `T` and return its trajectory `X`, sampled at equal time
7+
intervals, and corresponding time vector.
8+
Optionally provide a starting state `u0` which is `current_state(ds)` by default.
109
11-
See [`StateSpaceSet`](@ref) for info on how to use `X`.
1210
The returned time vector is `t = (t0+Ttr):Δt:(t0+Ttr+T)`.
1311
12+
If time evolution diverged before `T`, the remaining of the trajectory is set
13+
to the last valid point.
14+
1415
## Keyword arguments
1516
1617
* `Δt`: Time step of value output. For discrete time systems it must be an integer.
@@ -69,6 +70,7 @@ function trajectory_continuous(ds, T; Dt = 0.1, Δt = Dt, Ttr = 0.0, accessor =
6970
for (i, t) in enumerate(tvec)
7071
while t > current_time(ds)
7172
step!(ds)
73+
successful_step(ds) || break
7274
end
7375
sol[i] = SVector{X, ET}(obtain_access(ds(t), accessor))
7476
if !successful_step(ds)

src/core_systems/continuous_time_ode.jl

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ function CoupledODEs(f, u0, p = SciMLBase.NullParameters(); t0 = 0, diffeq = DEF
8686
prob = ODEProblem{IIP}(f, s, (T(t0), T(Inf)), p)
8787
return CoupledODEs(prob, diffeq)
8888
end
89-
# This preserves the referrenced MTK system
90-
CoupledODEs(ds::CoupledODEs, diffeq) = CoupledODEs(ODEProblem(ds), diffeq)
89+
# This preserves the referrenced MTK system and the originally passed diffeq kwargs
90+
CoupledODEs(ds::CoupledODEs, diffeq) = CoupledODEs(ODEProblem(ds), merge(ds.diffeq, diffeq))
9191
# Below `special_kwargs` is undocumented internal option for passing `internalnorm`
9292
function CoupledODEs(prob::ODEProblem, diffeq = DEFAULT_DIFFEQ; special_kwargs...)
9393
if haskey(special_kwargs, :diffeq)
@@ -159,8 +159,17 @@ current_state(integ::DEIntegrator) = integ.u
159159
current_time(integ::DEIntegrator) = integ.t
160160
initial_time(integ::DEIntegrator) = integ.sol.prob.tspan[1]
161161

162-
using SciMLBase: successful_retcode, check_error
163-
successful_step(integ::DEIntegrator) = successful_retcode(check_error(integ))
162+
# For checking successful step, the `SciMLBase.step!` function checks
163+
# `integ.sol.retcode in (ReturnCode.Default, ReturnCode.Success) || break`.
164+
# But the actual API call would be `successful_retcode(check_error(integ))`.
165+
# The latter however is already used in `step!(integ)` so there is no reason to re-do it.
166+
# Besides, within DynamicalSystems.jl the integration is never expected to terminate.
167+
# Nevertheless here we extend explicitly only for ODE stuff because it may be that for
168+
# other type of DEIntegrators a different step interruption is possible.
169+
function successful_step(integ::SciMLBase.AbstractODEIntegrator)
170+
rcode = integ.sol.retcode
171+
return rcode == SciMLBase.ReturnCode.Default || rcode == SciMLBase.ReturnCode.Success
172+
end
164173

165174
function set_state!(integ::DEIntegrator, u)
166175
if integ.u isa Array{<:Real}

src/core_systems/discrete_time_map.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ function SciMLBase.step!(ds::DeterministicIteratedMap{true})
8888
return ds
8989
end
9090
function SciMLBase.step!(ds::DeterministicIteratedMap{true}, N, stop_at_tdt = true)
91+
# We do not check for errors here for performance (of not computing equals to NaN
92+
# or Inf all the time), because in the end detecting the error early doesn't help
9193
for _ in 1:N
9294
ds.dummy, ds.u = ds.u, ds.dummy
9395
ds.f(ds.u, ds.dummy, ds.p, ds.t)

0 commit comments

Comments
 (0)