From c8317c034d8417f1ac6f3fa1ae45f4248b08061a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 16:12:57 +0100 Subject: [PATCH] CompatHelper: bump compat for StateSpaceSets to 2, (keep existing compat) (#243) * CompatHelper: bump compat for StateSpaceSets to 2, (keep existing compat) * only use v2 * rename dataset * update tutorial * access solvers * fix mistak lyap henon --------- Co-authored-by: CompatHelper Julia Co-authored-by: Datseris --- Project.toml | 9 ++- docs/src/tutorial.jl | 68 ++++++++++++++----- ext/src/numericdata/plot_dataset.jl | 6 +- ext/src/numericdata/trajectory_highlighter.jl | 2 +- 4 files changed, 58 insertions(+), 27 deletions(-) diff --git a/Project.toml b/Project.toml index 61cdc52e..8477391d 100644 --- a/Project.toml +++ b/Project.toml @@ -1,13 +1,13 @@ name = "DynamicalSystems" uuid = "61744808-ddfa-5f27-97ff-6e42cc95d634" repo = "https://github.com/JuliaDynamics/DynamicalSystems.jl.git" -version = "3.3.20" +version = "3.3.21" [deps] Attractors = "f3fd9213-ca85-4dba-9dfd-7fc91308fec7" ChaosTools = "608a59af-f2a3-5ad4-90b4-758bdf3122a7" ComplexityMeasures = "ab4b797d-85ee-42ba-b621-05d793b346a2" -DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" # necessary for extension +DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" DelayEmbeddings = "5732040d-69e3-5649-938a-b6b4f237613f" DynamicalSystemsBase = "6e36e845-645a-534a-86f2-f5d4aa5a06b4" FractalDimensions = "4665ce21-e117-4649-aed8-08bbe5ccbead" @@ -37,14 +37,13 @@ PredefinedDynamicalSystems = "1" RecurrenceAnalysis = "2" Reexport = "1" Scratch = "1" -StateSpaceSets = "1" +StateSpaceSets = "2" TimeseriesSurrogates = "2.1" julia = "1.9" - [extras] -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] test = ["Test", "Makie"] diff --git a/docs/src/tutorial.jl b/docs/src/tutorial.jl index f093fa93..3899cd60 100644 --- a/docs/src/tutorial.jl +++ b/docs/src/tutorial.jl @@ -1,6 +1,6 @@ -# # [Overarching tutorial for DynamicalSystems.jl](@id tutorial) +# # [Overarching tutorial for **DynamicalSystems.jl**](@id tutorial) -# This page serves as a short but to-the-point introduction to the **DynamicalSystems.jl** +# This page serves as a short but to-the-point introduction to the ****DynamicalSystems.jl**** # library. It outlines the core components, and how they establish an interface that # is used by the rest of the library. It also provides a couple of usage examples # to connect the various packages of the library together. @@ -15,7 +15,7 @@ # ``` # This installs several packages for the Julia language. These are the sub-modules/packages -# that comprise DynamicalSystems.jl, see [contents](@ref contents) for more. +# that comprise **DynamicalSystems.jl**, see [contents](@ref contents) for more. # All of the functionality is brought into scope when doing: using DynamicalSystems @@ -31,7 +31,7 @@ import Pkg #nb Pkg.add(["DynamicalSystems", "CairoMakie", "GLMakie", "OrdinaryDiffEq", "BenchmarkTools"]) Pkg.status(["DynamicalSystems", "CairoMakie", "GLMakie", "OrdinaryDiffEq", "BenchmarkTools"]; mode = Pkg.PKGMODE_MANIFEST) -#nb # ## DynamicalSystems.jl summary +#nb # ## **DynamicalSystems.jl** summary #nb @doc DynamicalSystems @@ -103,16 +103,18 @@ p0 = [1.4, 0.3] henon = DeterministicIteratedMap(henon_rule, u0, p0) # `henon` is a `DynamicalSystem`, one of the two core structures of the library. -# They can evolved interactively, and queried, using the interface defined by [`DynamicalSystem`](@ref). The simplest thing you can do with a `DynamicalSystem` is to get its trajectory: +# They can evolved interactively, and queried, using the interface defined by [`DynamicalSystem`](@ref). +# The simplest thing you can do with a `DynamicalSystem` is to get its trajectory: total_time = 10_000 X, t = trajectory(henon, total_time) X -# `X` is a `StateSpaceSet`, the second of the core structures of the library. We'll see below how, and where, to use a `StateSpaceset`, but for now let's just do a scatter plot +# `X` is a `StateSpaceSet`, the second of the core structures of the library. +# We'll see below how, and where, to use a `StateSpaceset`, but for now let's just do a scatter plot using CairoMakie -scatter(X[:, 1], X[:, 2]) +scatter(X) # ### Example: Lorenz96 @@ -167,7 +169,7 @@ fig # Continuous time dynamical systems are evolved through DifferentialEquations.jl. # In this sense, the above `trajectory` function is a simplified version of `DifferentialEquations.solve`. # If you only care about evolving a dynamical system forwards in time, you are probably better off using -# DifferentialEquations.jl directly. DynamicalSystems.jl can be used to do many other things that either occur during +# DifferentialEquations.jl directly. **DynamicalSystems.jl** can be used to do many other things that either occur during # the time evolution or after it, see the section below on [using dynamical systems](@ref using). # When initializing a `CoupledODEs` you can tune the solver properties to your heart's @@ -175,7 +177,7 @@ fig # and any of the [common solver options](https://diffeq.sciml.ai/latest/basics/common_solver_opts/). # For example: -using OrdinaryDiffEq # accessing the ODE solvers +using OrdinaryDiffEq: Vern9 # accessing the ODE solvers diffeq = (alg = Vern9(), abstol = 1e-9, reltol = 1e-9) lorenz96_vern = ContinuousDynamicalSystem(lorenz96_rule!, u0, p0; diffeq) @@ -189,15 +191,15 @@ Y[end] # #### Higher accuracy, higher order -# The solver `Tsit5` (the default solver) is most performant when medium-high error -# tolerances are requested. When we require very small errors, choosing a different solver +# The solver `Tsit5` (the default solver) is most performant when medium-low error +# tolerances are requested. When we require very small error tolerances, choosing a different solver # can be more accurate. This can be especially impactful for chaotic dynamical systems. # Let's first expliclty ask for a given accuracy when solving the ODE by passing the # keywords `abstol, reltol` (for absolute and relative tolerance respectively), # and compare performance to a naive solver one would use: using BenchmarkTools: @btime -using OrdinaryDiffEq: BS3 # equivalent of odeint23 +using OrdinaryDiffEq: BS3 # 3rd order solver for alg in (BS3(), Vern9()) diffeq = (; alg, abstol = 1e-12, reltol = 1e-12) @@ -230,6 +232,8 @@ end # Let's compare +using OrdinaryDiffEq: Tsit5, Rodas5P + function vanderpol_rule(u, μ, t) x, y = u dx = y @@ -252,14 +256,28 @@ end # ## [Using dynamical systems](@id using) -# You may use the [`DynamicalSystem`](@ref) interface to develop algorithms that utilize dynamical systems with a known evolution rule. The two main packages of the library that do this are [`ChaosTools`](@ref) and [`Attractors`](@ref). For example, you may want to compute the Lyapunov spectrum of the Lorenz96 system from above. This is as easy as calling the `lyapunovspectrum` function with `lorenz96` +# You may use the [`DynamicalSystem`](@ref) interface to develop algorithms that utilize dynamical systems with a known evolution rule. +# The two main packages of the library that do this are [`ChaosTools`](@ref) and [`Attractors`](@ref). +# For example, you may want to compute the Lyapunov spectrum of the Lorenz96 system from above. +# This is as easy as calling the `lyapunovspectrum` function with `lorenz96` steps = 10_000 lyapunovspectrum(lorenz96, steps) -# As expected, there is at least one positive Lyapunov exponent, because the system is chaotic, and at least one zero Lyapunov exponent, because the system is continuous time. +# As expected, there is at least one positive Lyapunov exponent, because the system is chaotic, +# and at least one zero Lyapunov exponent, because the system is continuous time. + +# A fantastic feature of **DynamicalSystems.jl** is that all library functions work for any +# applicable dynamical system. The exact same `lyapunovspectrum` function would also work +# for the Henon map. -# Alternatively, you may want to estimate the basins of attraction of a multistable dynamical system. The Henon map is "multistable" in the sense that some initial conditions diverge to infinity, and some others converge to a chaotic attractor. Computing these basins of attraction is simple with [`Attractors`](@ref), and would work as follows: +lyapunovspectrum(henon, steps) + +# Something else that uses a dynamical system is estimating the basins of attraction +# of a multistable dynamical system. +# The Henon map is "multistable" in the sense that some initial conditions diverge to +# infinity, and some others converge to a chaotic attractor. +# Computing these basins of attraction is simple with [`Attractors`](@ref), and would work as follows: ## define a state space grid to compute the basins on: xg = yg = range(-2, 2; length = 201) @@ -315,7 +333,12 @@ step!(henon, 2) X -# It is printed like a matrix where each column is the timeseries of each dynamic variable. In reality, it is a vector of statically sized vectors (for performance reasons). When indexed with 1 index, it behaves like a vector of vectors +# This is the main data structure used in **DynamicalSystems.jl** to handle numerical data. +# It is printed like a matrix where each column is the timeseries of each dynamic variable. +# In reality, it is a vector equally-sized vectors representing state space points. +# _(For advanced users: `StateSpaceSet` directly subtypes `AbstractVector{<:AbstractVector}`)_ + +# When indexed with 1 index, it behaves like a vector of vectors X[1] @@ -343,6 +366,15 @@ map(point -> point[1] + 1/(point[2]+0.1), X) x, y = columns(X) summary.((x, y)) +# Because `StateSpaceSet` really is a vector of vectors, it can be given +# to any Julia function that accepts such an input. For example, +# the Makie plotting ecosystem knows how to plot vectors of vectors. +# That's why this works: + +scatter(X) + +# even though Makie has no knowledge of the specifics of `StateSpaceSet`. + # ## Using state space sets # Several packages of the library deal with `StateSpaceSets`. @@ -420,7 +452,7 @@ fig # ## Integration with ModelingToolkit.jl -# DynamicalSystems.jl understands when a model has been generated via [ModelingToolkit.jl](https://docs.sciml.ai/ModelingToolkit/stable/). The symbolic variables used in ModelingToolkit.jl can be used to access the state or parameters of the dynamical system. +# **DynamicalSystems.jl** understands when a model has been generated via [ModelingToolkit.jl](https://docs.sciml.ai/ModelingToolkit/stable/). The symbolic variables used in ModelingToolkit.jl can be used to access the state or parameters of the dynamical system. # To access this functionality, the `DynamicalSystem` must be created from a `DEProblem` of the SciML ecosystem, and the `DEProblem` itself must be created from a ModelingToolkit.jl model. @@ -514,4 +546,4 @@ current_parameter(roessler, :c) # ## Learn more -# To learn more, you need to visit the documentation pages of the modules that compose DynamicalSystems.jl. See the [contents](@ref contents) page for more! +# To learn more, you need to visit the documentation pages of the modules that compose **DynamicalSystems.jl**. See the [contents](@ref contents) page for more! diff --git a/ext/src/numericdata/plot_dataset.jl b/ext/src/numericdata/plot_dataset.jl index 40524a19..fd9f1476 100644 --- a/ext/src/numericdata/plot_dataset.jl +++ b/ext/src/numericdata/plot_dataset.jl @@ -1,7 +1,7 @@ -Dataset = DynamicalSystems.Dataset +StateSpaceSet = DynamicalSystems.StateSpaceSet plot_dataset(args...; kwargs...) = plot_dataset!(Scene(), args...; kwargs...) -function plot_dataset!(scene, data::Dataset{2}, color = :black; kwargs...) +function plot_dataset!(scene, data::StateSpaceSet{2}, color = :black; kwargs...) makiedata = [Point2f(d) for d in data] scatter!(scene, makiedata; color = color, markersize = 0.01, kwargs...) return scene @@ -12,7 +12,7 @@ function plot_dataset!(scene, data::Matrix, color = :black; kwargs...) scatter!(scene, makiedata; color = color, markersize = 0.01, kwargs...) return scene end -function plot_dataset!(scene, data::Dataset{3}, color = :black; kwargs...) +function plot_dataset!(scene, data::StateSpaceSet{3}, color = :black; kwargs...) makiedata = [Point3f(d) for d in data] lines!(scene, makiedata; color = color, transparency = true, linewidth = 2.0, kwargs...) return scene diff --git a/ext/src/numericdata/trajectory_highlighter.jl b/ext/src/numericdata/trajectory_highlighter.jl index d8df634e..850f8980 100644 --- a/ext/src/numericdata/trajectory_highlighter.jl +++ b/ext/src/numericdata/trajectory_highlighter.jl @@ -8,7 +8,7 @@ const DEFAULT_α = 0.01 """ trajectory_highlighter(datasets, vals; kwargs...) Open an interactive application for highlighting specific datasets -and properties of these datasets. `datasets` is a vector of `Dataset` from +and properties of these datasets. `datasets` is a vector of `StateSpaceSet` from **DynamicalSystems.jl**. Each dataset corresponds to a specific value from `vals` (a `Vector{<:Real}`). The value of `vals` gives each dataset a specific color based on a colormap.