Skip to content

[WIP] nonlocal stability measure estimator #165

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 87 commits into from
Apr 24, 2025
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
31ff74e
Implemented all functionality of the StabilityMeasuresAccumulator int…
andreasmorr Jan 10, 2025
6d31bd0
Made the plotting function compatible with the wider plotting framewo…
andreasmorr Jan 10, 2025
f0f675f
Adjusted the stability measure plotting functions and included docume…
andreasmorr Jan 14, 2025
4d94d80
improve the docstring a bit
Datseris Feb 2, 2025
2e1eafc
more docstring and comments
Datseris Feb 2, 2025
33bc5bf
some typos in functions
Datseris Feb 2, 2025
1bdb6cc
small error corrections in stability measure accumulation
andreasmorr Feb 3, 2025
c6d838d
Merge remote-tracking branch 'origin/stability_measures' into stabili…
andreasmorr Feb 3, 2025
165fd11
comments on type stability
Datseris Feb 13, 2025
9f97270
more todos regarding distributions and other type stability
Datseris Feb 13, 2025
492f76f
comment on outside grid
Datseris Feb 13, 2025
ee738ff
another comment for outside grid
Datseris Feb 13, 2025
1dfe651
WIP on stability_measures
andreasmorr Feb 13, 2025
405dca4
WIP on stability_measures
andreasmorr Mar 7, 2025
9b943a8
WIP on stability_measures
andreasmorr Mar 13, 2025
e308495
Merge branch 'main' into stability_measures
Datseris Mar 16, 2025
1e90f29
add new stuff to the docs
Datseris Mar 16, 2025
493f7ea
Fixed corrupted ipynbs
andreasmorr Mar 16, 2025
b862a41
Adopted new name for finalize_accumulator
andreasmorr Mar 16, 2025
b58a302
Removed persistence from accumulator
andreasmorr Mar 16, 2025
63bc01d
Started adjusting stability measure continuation for Proximity mapper
andreasmorr Mar 16, 2025
42a4e34
rework API for global continuation: now jsut use existing ACAM
Datseris Mar 16, 2025
be02c5f
Merge remote-tracking branch 'origin/stability_measures' into stabili…
andreasmorr Mar 17, 2025
3afcdb7
Continuation with Proximity mapper and d depending on p
andreasmorr Mar 17, 2025
6b6d685
Comment on Proximity problem
andreasmorr Mar 17, 2025
e332ea2
draft of new nonlocal stability continaution
Datseris Mar 18, 2025
48eb03b
add a test draft
Datseris Mar 18, 2025
e7b10fb
WIP on stability_measures
andreasmorr Mar 19, 2025
3ce9d1d
WIP on stability_measures
andreasmorr Mar 19, 2025
a7d32f7
WIP on stability_measures
andreasmorr Mar 30, 2025
bac8c9c
Merge branch 'main' into stability_measures
Datseris Apr 2, 2025
8ec1914
allow filler value for basins plot
Datseris Apr 2, 2025
e275d6c
also record basin fractions in accumulator
Datseris Apr 2, 2025
1493be8
better keyword names? TODO: We have to decide this!
Datseris Apr 2, 2025
0102f7a
rename keywords for clarity
Datseris Apr 3, 2025
7fc90d9
set Ttr to 0 for proximity
Datseris Apr 3, 2025
ca4c568
WIP on stability_measures
andreasmorr Apr 6, 2025
71de74f
Make ε a keyword argument for proximity mapper
Datseris Apr 8, 2025
533e6ce
Change the order of pcurve, ics to match that of global continuation
Datseris Apr 8, 2025
3c1f37e
propagate this keyword cahnge also to the nonlocal continuation
Datseris Apr 8, 2025
2c15b87
harmonize keyword `N` to `samples_per_parameter`
Datseris Apr 8, 2025
a6e6576
Partially corrected formatting of long code lines
andreasmorr Apr 9, 2025
6bea6ae
List comprehension changes
andreasmorr Apr 9, 2025
00c11e9
Update docs/src/examples.md
andreasmorr Apr 9, 2025
2166b14
Update docs/src/examples.md
andreasmorr Apr 9, 2025
d858936
More formatting of long lines
andreasmorr Apr 9, 2025
63b17d9
Comment formatting
andreasmorr Apr 9, 2025
46bd803
Update src/mapping/stability_measures_accumulator.jl
andreasmorr Apr 9, 2025
f01b078
Case distinction for discrete systems and linear measures
andreasmorr Apr 10, 2025
31388d3
reverted line break formatting
andreasmorr Apr 10, 2025
6bee085
Merge remote-tracking branch 'origin/stability_measures' into stabili…
andreasmorr Apr 10, 2025
0392780
Fixed calculation of mean convergence time and pace
andreasmorr Apr 10, 2025
98f75ac
critical fix in convergence time of recurrences mapper
Datseris Apr 11, 2025
479fe81
Merge remote-tracking branch 'origin/conv_time_fix' into stability_me…
andreasmorr Apr 11, 2025
f7a997b
WIP on stability_measures
andreasmorr Apr 13, 2025
f47fdf1
enable tests in test suite
Datseris Apr 13, 2025
66cdf93
add 3 TODOs for @andreasmorr
Datseris Apr 13, 2025
d391b5c
add docs to general stability continuation
Datseris Apr 13, 2025
ba443aa
add one more TODO for andreasmorr
Datseris Apr 13, 2025
26bf17a
Merge branch 'main' into stability_measures
Datseris Apr 15, 2025
e18b529
mention Inf value for single attractopr and fatal shocks
Datseris Apr 15, 2025
3eda211
re-write tutorial: dedicated enhancement of continuation with new stuff
Datseris Apr 15, 2025
8c12072
remove recomputation in the example for nonlocal continuation
Datseris Apr 15, 2025
ac99b07
WIP on stability_measures
andreasmorr Apr 15, 2025
b7dfa31
Changed term "fatal" to "critical"
andreasmorr Apr 15, 2025
42869a3
Small fix in the tests of stability measures accumulator
andreasmorr Apr 15, 2025
daf1fd6
improve logic in `edgetracking` to avoid duplicate point storage
Datseris Apr 15, 2025
3d37d87
fix edgetracking tests
Datseris Apr 15, 2025
a944ae0
make edgetracking give Ttr = 100 by default
Datseris Apr 15, 2025
3b870bc
also fix the MFS test failure
Datseris Apr 15, 2025
6cbb72d
add changelog entry for proximity
Datseris Apr 15, 2025
bce7688
Merge remote-tracking branch 'origin/stability_measures' into stabili…
andreasmorr Apr 16, 2025
b463479
allow seed option in Brute Force MCS
Datseris Apr 16, 2025
5d7ad49
clarify and explain tests of MCS
Datseris Apr 16, 2025
cd7a321
clarify explain and fix tests
Datseris Apr 16, 2025
89bd196
provide instructions on how to typeset epsilon
Datseris Apr 16, 2025
65f9a4b
fix tests and doc failures
Datseris Apr 16, 2025
19d617b
deprecate all "fatal" to "critical"
Datseris Apr 16, 2025
428e9f1
fix test checking ε in proximity
Datseris Apr 16, 2025
745dfdb
fatal to critical in exmples
Datseris Apr 16, 2025
ef67388
changelog and citation
Datseris Apr 18, 2025
dc8e201
changelog and citation
Datseris Apr 18, 2025
d986624
add a (failing) test for linear stability measures of a map
Datseris Apr 18, 2025
5bab765
Merge branch 'main' into stability_measures
Datseris Apr 24, 2025
53556dc
add changelog entry
Datseris Apr 24, 2025
74cdefa
Merge remote-tracking branch 'origin/stability_measures' into stabili…
Datseris Apr 24, 2025
abe132b
add a test for discrete time system
Datseris Apr 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ subdivision_based_grid
```

### Proximity

```@docs
AttractorsViaProximity
```

### Featurizing

```@docs
AttractorsViaFeaturizing
```
Expand Down Expand Up @@ -122,6 +124,13 @@ MFSBlackBoxOptim
MFSBruteForce
```

## Nonlocal Stability

```@docs
StabilityMeasuresAccumulator
finalize_accumulator
```

## Global continuation

```@docs
Expand Down
5 changes: 2 additions & 3 deletions ext/plotting.jl
Original file line number Diff line number Diff line change
Expand Up @@ -295,15 +295,15 @@ function Attractors.plot_continuation_curves!(ax, continuation_info, prange = 1:
labels = Dict(ukeys .=> ukeys),
add_legend = length(ukeys) < 7,
markers = markers_from_keys(ukeys),
slines_kwargs = (;linewidth = 3,),
series_kwargs = NamedTuple(),
axislegend_kwargs = (position = :lt,)
)

series = continuation_series(continuation_info, NaN, ukeys)
for k in ukeys
scatterlines!(ax, prange, series[k];
color = colors[k], label = "$(labels[k])", marker = markers[k],
markersize = 10, linewidth = 3, slines_kwargs...
markersize = 10, linewidth = 3, series_kwargs...
)
end
xlims!(ax, minimum(prange), maximum(prange))
Expand Down Expand Up @@ -381,7 +381,6 @@ function Attractors.plot_basins_attractors_curves!(axb, axa, fractions_cont, att
return
end


##########################################################################################
# Videos
##########################################################################################
Expand Down
2 changes: 1 addition & 1 deletion src/continuation/continuation_ascm_generic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ without having to recompute the whole global continuation!

### Step 5 - Finish

After matching the parameter is incremented.
After matching the parameter(s) is incremented.
Steps 1-4 repeat until all parameter values are exhausted.

### Further note
Expand Down
113 changes: 113 additions & 0 deletions src/continuation/continuation_stability_measures.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# TODO: Can we make this function not duplicate the source code
# of the original `ASCM` implementation?

function global_continuation(
acam::AttractorSeedContinueMatch{<:StabilityMeasuresAccumulator}, pcurve, ics;
samples_per_parameter = 100, show_progress = true,
)
N = samples_per_parameter
progress = ProgressMeter.Progress(length(pcurve); desc = "Continuing attractors and stability:", enabled=show_progress)
mapper = acam.mapper
reset_mapper!(mapper)

set_parameters!(referenced_dynamical_system(mapper), pcurve[1])
if ics isa Function
fs = basins_fractions(mapper, ics; show_progress = false, N = samples_per_parameter)
else # we ignore labels in this continuation algorithm
fs, = basins_fractions(mapper, ics; show_progress = false)
end

# this is the first difference with the standard continuation: we have to call finalize.
measures = finalize_accumulator(mapper)
measures_cont = [measures]

prev_attractors = deepcopy(extract_attractors(mapper))
attractors_cont = [deepcopy(prev_attractors)] # we need the copy
ProgressMeter.next!(progress)

# Continue loop over all remaining parameters
### For @Datseris: Is this what you had in mind when we emailed about
### the global continuation algorithm with AttractorsViaProximity?
### Currently, line 44 has an error because we cant pass ics to the AttractorsViaRecurrences.
for p in @view(pcurve[2:end])
set_parameters!(referenced_dynamical_system(mapper), p)
reset_mapper!(mapper)
if typeof(mapper.mapper) <: AttractorsViaRecurrences
fs = if allows_mapper_u0(mapper)
seed_attractors_to_fractions_individual(mapper, prev_attractors, ics, N, acam.seeding)
else
seed_attractors_to_fractions_grouped(mapper, prev_attractors, ics, N, acam.seeding)
end
current_attractors = deepcopy(extract_attractors(mapper))
else
error("Unsupported mapper type: $(typeof(mapper.mapper))")
end
push!(attractors_cont, current_attractors)
overwrite_dict!(prev_attractors, current_attractors)
ProgressMeter.next!(progress)

# this is the second difference in global continuation
measures = finalize_accumulator(mapper)
push!(measures_cont, measures)
end

rmaps = match_sequentially!(attractors_cont, acam.matcher; pcurve, ds = referenced_dynamical_system(mapper))

# This is the third difference in global continuation
for i in 2:length(pcurve)
for dict in values(measures_cont[i])
swap_dict_keys!(dict, rmaps[i-1])
end
end
transposed = Dict{String, Vector{Dict{Int64, Float64}}}()
for measure in measures_cont[1]
measure_name = measure[1]
transposed[measure_name] = Vector{Dict{Int64, Float64}}()
end

for measures in measures_cont
for (measure_name, measure_dict) in measures
push!(transposed[measure_name], measure_dict)
end
end
measures_cont = transposed

return measures_cont, attractors_cont
end



# make sure to allow the possiblity that the proximity options can also be
# vectors of same length as `pcurve`; Same for the distributions
function stability_measures_along_continuation(ds::DynamicalSystem, attractors_cont, ics, pcurve, εs, distributions, Ts; metric=Euclidean(), proximity_mapper_options=[])
measures_cont = []
for (i, p) in enumerate(pcurve)
ε = εs isa AbstractVector ? εs[i] : εs # if its a vector, get i-th entry
d = distributions isa AbstractVector ? distributions[i] : distributions # if its a vector, get i-th entry
T = Ts isa AbstractVector ? Ts[i] : Ts # if its a vector, get i-th entry
set_parameters!(ds, p)
attractors = attractors_cont[i]
accumulator = StabilityMeasuresAccumulator(
AttractorsViaProximity(ds, attractors, ε, proximity_mapper_options...),
d=d, T=T, metric=metric
)
for u0 in ics
id = accumulator(u0)
end
push!(measures_cont, finalize_accumulator(accumulator))
end

transposed = Dict{String, Vector{Dict{Int64, Float64}}}()
for measure in measures_cont[1]
measure_name = measure[1]
transposed[measure_name] = Vector{Dict{Int64, Float64}}()
end

for measures in measures_cont
for (measure_name, measure_dict) in measures
push!(transposed[measure_name], measure_dict)
end
end
measures_cont = transposed
return measures_cont
end
8 changes: 6 additions & 2 deletions src/continuation/global_continuation_api.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export global_continuation, GlobalContinuationAlgorithm, continuation_series
export global_continuation, GlobalContinuationAlgorithm, continuation_series, stability_measures_along_continuation

"""
GlobalContinuationAlgorithm
Expand All @@ -25,6 +25,9 @@ Return:
1. `fractions_cont::Vector{Dict{Int, Float64}}`. The fractions of basins of attraction.
`fractions_cont[i]` is a dictionary mapping attractor IDs to their basin fraction
at the `i`-th parameter combination.
- This output is different if you are using [`StabilityMeasuresAccumulator`](@ref)
in combination with [`AttractorSeedContinueMatch`](@ref). See the docstring
of [`StabilityMeasuresAccumulator`](@ref) for more details.
2. `attractors_cont::Vector{Dict{Int, <:Any}}`. The continued attractors.
`attractors_cont[i]` is a dictionary mapping attractor ID to the
attractor set at the `i`-th parameter combination.
Expand Down Expand Up @@ -98,4 +101,5 @@ end
include("continuation_ascm_generic.jl")
include("continuation_recurrences.jl")
include("continuation_grouping.jl")
include("aggregate_attractor_fractions.jl")
include("aggregate_attractor_fractions.jl")
include("continuation_stability_measures.jl")
8 changes: 7 additions & 1 deletion src/mapping/attractor_mapping.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ export AttractorMapper,
extract_attractors,
subdivision_based_grid,
SubdivisionBasedGrid,
reset_mapper!
reset_mapper!,
StabilityMeasuresAccumulator,
finalize_accumulator

ValidICS = Union{AbstractVector, Function}

Expand Down Expand Up @@ -48,6 +50,9 @@ The mappers that can do this are:
* [`AttractorsViaRecurrences`](@ref)
* [`AttractorsViaFeaturizing`](@ref) with the [`GroupViaHistogram`](@ref) configuration.

See also [`StabilityMeasuresAccumulator`](@ref) that extends this interface
to accelerate estimation of stability measures.

## For developers

`AttractorMapper` defines an extendable interface. A new type needs to subtype
Expand Down Expand Up @@ -183,3 +188,4 @@ function convergence_time end
include("attractor_mapping_proximity.jl")
include("recurrences/attractor_mapping_recurrences.jl")
include("grouping/attractor_mapping_featurizing.jl")
include("stability_measures_accumulator.jl")
2 changes: 2 additions & 0 deletions src/mapping/attractor_mapping_proximity.jl
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ function AttractorsViaProximity(ds::DynamicalSystem, attractors::Dict, ε = noth
return mapper
end

reset_mapper!(mapper::AttractorsViaProximity) = nothing # AM can we add this for consistency?

function _deduce_ε_from_attractors(attractors, search_trees, verbose = false)
if length(attractors) != 1
verbose && @info("Computing minimum distance between attractors to deduce `ε`...")
Expand Down
Loading
Loading