Skip to content

Commit 60b8a6f

Browse files
Edgetracking algorithm (#61)
* added OrdinaryDiffEq to deps (for tests) * implemented edge tracking algorithm * cleaned up code and docstrings * added edgetracking test * revised docstrings * removed unneeded dependency * changed file locations and renamed kwargs eps1, eps2 * added testfile for intermediate testing * worked on requested changes * changed edgetracking based on PR review * changed how and when 'track1', 'track2' and 'edge' are saved * 'track1' and 'track2' now include all points of parallel trajectories * 'edge' is computed at the very end * renamed local variable 'T' to 't' * added cubic map test * updated docstring according to PR review * changed formatting of citations * added references to .bib file * removed outdated warning * changed output type of 'edgetracking' to EdgeTrackingResults * added edgetracking section to docs * made input/output changes to 'edgetracking' * added kwarg 'T_transient' * refined error messages if AttractorMapper returns -1 * modified and expanded testsets * changed testsets to match new output type of 'edgetracking' * started adding Thomas' rule example (WIP) * updated edgetracking and bisect_to_edge functions * added `success` field to `EdgeTrackingResults` * changed behavior from error to warning with `EdgeTrackingResults.success = false` when both states belong to the same basin * added `T_transient` kwarg to `edgetracking` * changed output arguments of `bisect_to_edge` * completed Thomas' rule testset * cleaned up code and tested locally * removed unneeded dependency * updated docs and package version number * applied suggestions from Datseris' code review Co-authored-by: George Datseris <[email protected]> * implemented further changes based on code review * silenced print output in testset * fix docs failing * added edgetracking documentation example * also changed EdgeTrackingResults.bisect_idx to include first bisection point * remove warnonly --------- Co-authored-by: Datseris <[email protected]>
1 parent b049d3a commit 60b8a6f

21 files changed

+594
-37
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ Manifest.toml
33
*.scss
44
*.css
55
.vscode
6-
*style.jl
6+
*style.jl
7+
.DS_Store

Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name = "Attractors"
22
uuid = "f3fd9213-ca85-4dba-9dfd-7fc91308fec7"
33
authors = ["George Datseris <[email protected]>", "Kalel Rossi", "Alexandre Wagemakers"]
44
repo = "https://github.com/JuliaDynamics/Attractors.jl.git"
5-
version = "1.13.6"
5+
version = "1.14.0"
66

77
[deps]
88
BlackBoxOptim = "a134a8b2-14d6-55f6-9291-3336d3ab0209"

docs/make.jl

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ pages = [
1515
"references.md",
1616
]
1717

18-
1918
import Downloads
2019
Downloads.download(
2120
"https://raw.githubusercontent.com/JuliaDynamics/doctheme/master/build_docs_with_style.jl",
@@ -31,5 +30,5 @@ bib = CitationBibliography(
3130
)
3231

3332
build_docs_with_style(pages, Attractors, DynamicalSystemsBase, StateSpaceSets;
34-
expandfirst = ["index.md"], bib,
33+
expandfirst = ["index.md"], bib
3534
)

docs/refs.bib

+61
Original file line numberDiff line numberDiff line change
@@ -158,4 +158,65 @@ @article{Halekotte2020
158158
author = {Lukas Halekotte and Ulrike Feudel},
159159
title = {Minimal fatal shocks in multistable complex networks},
160160
journal = {Scientific Reports}
161+
}
162+
163+
@article{Battelino1988,
164+
title={Multiple coexisting attractors, basin boundaries and basic sets},
165+
author={Battelino, Peter M and Grebogi, Celso and Ott, Edward and Yorke, James A and Yorke, Ellen D},
166+
journal={Physica D: Nonlinear Phenomena},
167+
volume={32},
168+
number={2},
169+
pages={296--305},
170+
year={1988},
171+
publisher={Elsevier}
172+
}
173+
174+
@article{Skufca2006,
175+
title={Edge of chaos in a parallel shear flow},
176+
author={Skufca, Joseph D and Yorke, James A and Eckhardt, Bruno},
177+
journal={Physical review letters},
178+
volume={96},
179+
number={17},
180+
pages={174101},
181+
year={2006},
182+
publisher={APS}
183+
}
184+
185+
@article{Schneider2008,
186+
title={Laminar-turbulent boundary in plane Couette flow},
187+
author={Schneider, Tobias M and Gibson, John F and Lagha, Maher and De Lillo, Filippo and Eckhardt, Bruno},
188+
journal={Physical Review E},
189+
volume={78},
190+
number={3},
191+
pages={037301},
192+
year={2008},
193+
publisher={APS}
194+
}
195+
196+
@article{Wagemakers2020,
197+
title={The saddle-straddle method to test for Wada basins},
198+
author={Wagemakers, Alexandre and Daza, Alvar and Sanju{\'a}n, Miguel AF},
199+
journal={Communications in Nonlinear Science and Numerical Simulation},
200+
volume={84},
201+
pages={105167},
202+
year={2020},
203+
publisher={Elsevier}
204+
}
205+
206+
@article{Lucarini2017,
207+
title={Edge states in the climate system: exploring global instabilities and critical transitions},
208+
author={Lucarini, Valerio and B{\'o}dai, Tam{\'a}s},
209+
journal={Nonlinearity},
210+
volume={30},
211+
number={7},
212+
pages={R32},
213+
year={2017},
214+
publisher={IOP Publishing}
215+
}
216+
217+
@article{Mehling2023,
218+
title={Limits to predictability of the asymptotic state of the Atlantic Meridional Overturning Circulation in a conceptual climate model},
219+
author={Mehling, Oliver and B{\"o}rner, Reyk and Lucarini, Valerio},
220+
journal={arXiv preprint arXiv:2308.16251},
221+
year={2023}
161222
}

docs/src/basins.md

+9
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ basins_fractal_test
2929
uncertainty_exponent
3030
```
3131

32+
## Edge tracking and edge states
33+
The edge tracking algorithm allows to locate and construct so-called edge states (also referred to as *Melancholia states*) embedded in the basin boundary separating different basins of attraction. These could be saddle points, unstable periodic orbits or chaotic saddles. The general idea is that these sets can be found because they act as attractors when restricting to the basin boundary.
34+
35+
```@docs
36+
edgetracking
37+
EdgeTrackingResults
38+
bisect_to_edge
39+
```
40+
3241
## Tipping points
3342
This page discusses functionality related with tipping points in dynamical systems with known rule. If instead you are interested in identifying tipping points in measured timeseries, have a look at [TransitionIndicators.jl](https://github.com/JuliaDynamics/TransitionIndicators.jl).
3443

docs/src/continuation.md

+3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ RecurrencesFindAndMatch
2424

2525
```@docs
2626
match_statespacesets!
27+
Centroid
28+
Hausdorff
29+
StrictlyMinimumDistance
2730
replacement_map
2831
set_distance
2932
setsofsets_distances

docs/src/examples.md

+91-2
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ fig
321321

322322
To achieve even better results for this kind of problematic systems than with previuosly introduced `Irregular Grids` we provide a functionality to construct `Subdivision Based Grids` in which
323323
one can obtain more coarse or dense structure not only along some axis but for a specific regions where the state space flow has
324-
significantly different speed. [`subdivided_based_grid`](@ref) enables automatic evaluation of velocity vectors for regions of originally user specified
324+
significantly different speed. [`subdivision_based_grid`](@ref) enables automatic evaluation of velocity vectors for regions of originally user specified
325325
grid to further treat those areas as having more dense or coarse structure than others.
326326

327327
```@example MAIN
@@ -536,7 +536,7 @@ plot_basins_curves(aggregated_fractions, prange;
536536

537537
## Trivial featurizing and grouping for basins fractions
538538

539-
This is a rather trivial example showcasing the usage of [`AttractorsViaFeaturizing`](@ref). Let us use once again the magnetic pendulum example. For it, we have a really good idea of what features will uniquely describe each attractor: the last points of a trajectory (which should be very close to the magnetic the trajectory converged to). To provide this information to the [`AttractorsviaFeaturizing`](@ref) we just create a julia function that returns this last point
539+
This is a rather trivial example showcasing the usage of [`AttractorsViaFeaturizing`](@ref). Let us use once again the magnetic pendulum example. For it, we have a really good idea of what features will uniquely describe each attractor: the last points of a trajectory (which should be very close to the magnetic the trajectory converged to). To provide this information to the [`AttractorsViaFeaturizing`](@ref) we just create a julia function that returns this last point
540540

541541
```@example MAIN
542542
using Attractors
@@ -871,3 +871,92 @@ animate_attractors_via_recurrences(mapper, u0s)
871871
<source src="https://raw.githubusercontent.com/JuliaDynamics/JuliaDynamics/master/videos/attractors/recurrence_algorithm.mp4?raw=true" type="video/mp4">
872872
</video>
873873
```
874+
875+
## Edge tracking
876+
877+
To showcase how to run the [`edgetracking`](@ref) algorithm, let us use it to find the
878+
saddle point of the bistable FitzHugh-Nagumo (FHN) model, a two-dimensional ODE system
879+
originally conceived to represent a spiking neuron.
880+
We define the system in the following form:
881+
882+
```@example MAIN
883+
function fitzhugh_nagumo(u,p,t)
884+
x, y = u
885+
eps, beta = p
886+
dx = (x - x^3 - y)/eps
887+
dy = -beta*y + x
888+
return SVector{2}([dx, dy])
889+
end
890+
891+
params = [0.1, 3.0]
892+
ds = CoupledODEs(fitzhugh_nagumo, ones(2), params, diffeq=(;alg = Vern9(), reltol=1e-11))
893+
```
894+
895+
Now, we can use Attractors.jl to compute the fixed points and basins of attraction of the
896+
FHN model.
897+
898+
```@example MAIN
899+
xg = yg = range(-1.5, 1.5; length = 201)
900+
grid = (xg, yg)
901+
mapper = AttractorsViaRecurrences(ds, grid; sparse=false)
902+
basins, attractors = basins_of_attraction(mapper)
903+
904+
for i in 1:length(attractors)
905+
println(attractors[i][1])
906+
end
907+
```
908+
909+
The `basins_of_attraction` function found three fixed points: the two stable nodes of the
910+
system (labeled A and B) and the saddle point at the origin. The saddle is an unstable
911+
equilibrium and can therefore not be found by simulation, but we can find it using the
912+
[`edgetracking`](@ref) algorithm. For illustration, let us initialize the algorithm from
913+
two initial conditions `init1` and `init2` (which must belong to different basins
914+
of attraction, see figure below).
915+
916+
```julia
917+
attractors_AB = Dict(1 => attractors[1], 2 => attractors[2])
918+
init1, init2 = [-1.0, -1.0], [-1.0, 0.2]
919+
```
920+
921+
Now, we run the edge tracking algorithm:
922+
923+
```@example MAIN
924+
bisect_thresh, diverge_thresh, Δt, abstol = 1e-3, 2e-3, 1e-5, 1e-3
925+
et = edgetracking(ds, attractors_AB; u1=init1, u2=init2,
926+
bisect_thresh, diverge_thresh, Δt, abstol)
927+
928+
et.edge[end]
929+
```
930+
931+
The algorithm has converged to the origin (up to the specified accuracy) where the saddle
932+
is located. The figure below shows how the algorithm has iteratively tracked along the basin
933+
boundary from the two initial conditions (red points) to the saddle (green square). Points
934+
of the edge track (orange) at which a re-bisection occured are marked with a white border.
935+
The figure also depicts two trajectories (blue) intialized on either side of the basin
936+
boundary at the first bisection point. We see that these trajectories follow the basin
937+
boundary for a while but then relax to either attractor before reaching the saddle. By
938+
counteracting the instability of the saddle, the edge tracking algorithm instead allows to
939+
track the basin boundary all the way to the saddle, or edge state.
940+
941+
```@example MAIN
942+
traj1 = trajectory(ds, 2, et.track1[et.bisect_idx[1]], Δt=1e-5)
943+
traj2 = trajectory(ds, 2, et.track2[et.bisect_idx[1]], Δt=1e-5)
944+
945+
fig = Figure()
946+
ax = Axis(fig[1,1], xlabel="x", ylabel="y")
947+
heatmap_basins_attractors!(ax, grid, basins, attractors, add_legend=false, labels=Dict(1=>"Attractor A", 2=>"Attractor B", 3=>"Saddle"))
948+
lines!(ax, traj1[1][:,1], traj1[1][:,2], color=:dodgerblue, linewidth=2, label="Trajectories")
949+
lines!(ax, traj2[1][:,1], traj2[1][:,2], color=:dodgerblue, linewidth=2)
950+
lines!(ax, et.edge[:,1], et.edge[:,2], color=:orange, linestyle=:dash)
951+
scatter!(ax, et.edge[et.bisect_idx,1], et.edge[et.bisect_idx,2], color=:white, markersize=15, marker=:circle, zorder=10)
952+
scatter!(ax, et.edge[:,1], et.edge[:,2], color=:orange, markersize=11, marker=:circle, zorder=10, label="Edge track")
953+
scatter!(ax, [-1.0,-1.0], [-1.0, 0.2], color=:red, markersize=15, label="Initial conditions")
954+
xlims!(ax, -1.2, 1.1); ylims!(ax, -1.3, 0.8)
955+
axislegend(ax, position=:rb)
956+
fig
957+
```
958+
959+
In this simple two-dimensional model, we could of course have found the saddle directly by
960+
computing the zeroes of the ODE system. However, the edge tracking algorithm allows finding
961+
edge states also in high-dimensional and chaotic systems where a simple computation of
962+
unstable equilibria becomes infeasible.

docs/src/index.md

+1-3
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ using CairoMakie, Attractors
1010

1111
## Latest news
1212

13-
- Our paper on the global stability analysis framework offered by Attractors.jl ([`continuation`](@ref)) and the novel continuation offered by [`RecurrencesFindAndMatch`](@ref) is published as a _Featured Article_ in Chaos (https://pubs.aip.org/aip/cha/article/33/7/073151/2904709/Framework-for-global-stability-analysis-of) and has been featured in the AIP publishing showcase (https://www.growkudos.com/publications/10.1063%25252F5.0159675/reader)
14-
- New function [`minimal_fatal_shock`](@ref)
15-
- New function [`match_continuation!`](@ref) which improves the matching during a continuation process where attractors disappear and reappear.
13+
- New functions [`edgetracking`](@ref) and [`bisect_to_edge`](@ref) added that implement an **edge tracking algorithm** to find saddles or *edge states* in dynamical systems, also when they are unstable chaotic sets.
1614

1715
## Outline of Attractors.jl
1816

docs/src/visualization.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ heatmap_basins_attractors(grid, basins, attractors; kwargs...)
1111
heatmap_basins_attractors!(ax, grid, basins, attractors; kwargs...)
1212
```
1313

14-
## Common plotting keywords
14+
## [Common plotting keywords](@id common_plot_kwargs)
1515
Common keywords for plotting functions in Attractors.jl are:
1616

1717
- `ukeys`: the basin ids (unique keys, vector of integers) to use. By default all existing keys are used.

src/Attractors.jl

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ include("dict_utils.jl")
1818
include("mapping/attractor_mapping.jl")
1919
include("basins/basins.jl")
2020
include("continuation/basins_fractions_continuation_api.jl")
21+
include("boundaries/edgetracking.jl")
2122
include("deprecated.jl")
2223
include("tipping/tipping.jl")
2324

0 commit comments

Comments
 (0)