Skip to content

Commit

Permalink
move basins_of_attraction to basin utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
Datseris committed Aug 6, 2024
1 parent 3ca5203 commit 0bd6178
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 46 deletions.
43 changes: 43 additions & 0 deletions src/basins/basins_utilities.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,46 @@
# It works for all mappers that define a `basins_fractions` method.
"""
basins_of_attraction(mapper::AttractorMapper, grid::Tuple) → basins, attractors
Compute the full basins of attraction as identified by the given `mapper`,
which includes a reference to a [`DynamicalSystem`](@ref) and return them
along with (perhaps approximated) found attractors.
`grid` is a tuple of ranges defining the grid of initial conditions that partition
the state space into boxes with size the step size of each range.
For example, `grid = (xg, yg)` where `xg = yg = range(-5, 5; length = 100)`.
The grid has to be the same dimensionality as the state space expected by the
integrator/system used in `mapper`. E.g., a [`ProjectedDynamicalSystem`](@ref)
could be used for lower dimensional projections, etc. A special case here is
a [`PoincareMap`](@ref) with `plane` being `Tuple{Int, <: Real}`. In this special
scenario the grid can be one dimension smaller than the state space, in which case
the partitioning happens directly on the hyperplane the Poincaré map operates on.
`basins_of_attraction` function is a convenience 5-lines-of-code wrapper which uses the
`labels` returned by [`basins_fractions`](@ref) and simply assigns them to a full array
corresponding to the state space partitioning indicated by `grid`.
See also [`convergence_and_basins_of_attraction`](@ref).
"""
function basins_of_attraction(mapper::AttractorMapper, grid::Tuple; kwargs...)
basins = zeros(Int32, map(length, grid))
I = CartesianIndices(basins)
A = StateSpaceSet([generate_ic_on_grid(grid, i) for i in vec(I)])
fs, labels = basins_fractions(mapper, A; kwargs...)
attractors = extract_attractors(mapper)
vec(basins) .= vec(labels)
return basins, attractors
end

# Type-stable generation of an initial condition given a grid array index
@generated function generate_ic_on_grid(grid::NTuple{B, T}, ind) where {B, T}
gens = [:(grid[$k][ind[$k]]) for k=1:B]
quote
Base.@_inline_meta
@inbounds return SVector{$B, Float64}($(gens...))
end
end

"""
basins_fractions(basins::AbstractArray [,ids]) → fs::Dict
Expand Down
46 changes: 0 additions & 46 deletions src/mapping/attractor_mapping.jl
Original file line number Diff line number Diff line change
Expand Up @@ -174,52 +174,6 @@ be used instead of [`basins_fractions`](@ref).
"""
function convergence_time end

#########################################################################################
# Generic basins of attraction method structure definition
#########################################################################################
# It works for all mappers that define a `basins_fractions` method.
"""
basins_of_attraction(mapper::AttractorMapper, grid::Tuple) → basins, attractors
Compute the full basins of attraction as identified by the given `mapper`,
which includes a reference to a [`DynamicalSystem`](@ref) and return them
along with (perhaps approximated) found attractors.
`grid` is a tuple of ranges defining the grid of initial conditions that partition
the state space into boxes with size the step size of each range.
For example, `grid = (xg, yg)` where `xg = yg = range(-5, 5; length = 100)`.
The grid has to be the same dimensionality as the state space expected by the
integrator/system used in `mapper`. E.g., a [`ProjectedDynamicalSystem`](@ref)
could be used for lower dimensional projections, etc. A special case here is
a [`PoincareMap`](@ref) with `plane` being `Tuple{Int, <: Real}`. In this special
scenario the grid can be one dimension smaller than the state space, in which case
the partitioning happens directly on the hyperplane the Poincaré map operates on.
`basins_of_attraction` function is a convenience 5-lines-of-code wrapper which uses the
`labels` returned by [`basins_fractions`](@ref) and simply assigns them to a full array
corresponding to the state space partitioning indicated by `grid`.
See also [`convergence_and_basins_of_attraction`](@ref).
"""
function basins_of_attraction(mapper::AttractorMapper, grid::Tuple; kwargs...)
basins = zeros(Int32, map(length, grid))
I = CartesianIndices(basins)
A = StateSpaceSet([generate_ic_on_grid(grid, i) for i in vec(I)])
fs, labels = basins_fractions(mapper, A; kwargs...)
attractors = extract_attractors(mapper)
vec(basins) .= vec(labels)
return basins, attractors
end

# Type-stable generation of an initial condition given a grid array index
@generated function generate_ic_on_grid(grid::NTuple{B, T}, ind) where {B, T}
gens = [:(grid[$k][ind[$k]]) for k=1:B]
quote
Base.@_inline_meta
@inbounds return SVector{$B, Float64}($(gens...))
end
end

#########################################################################################
# Includes
#########################################################################################
Expand Down

0 comments on commit 0bd6178

Please sign in to comment.