Skip to content

Commit f61fb95

Browse files
authored
Add finishing touches for registration (#34)
* improve docstrings of key functions. improve periodic_orbits * improve the remake/solve call in optimized shooting * mention NLSolve algorithm used * separate error function in optimized shooting * bring algorithms to API section * a bit more info in developer's docs * better readme * improve tutorial * clarify what happens at algorithm failure * rename `isstable` to `postability` * better orient apio b * add todo for an example * update CI * fix almost all errors * fix davidchack tests
1 parent b148ec1 commit f61fb95

File tree

18 files changed

+273
-251
lines changed

18 files changed

+273
-251
lines changed

.github/workflows/CompatHelper.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,4 @@ jobs:
4242
env:
4343
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4444
COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }}
45+
# COMPATHELPER_PRIV: ${{ secrets.COMPATHELPER_PRIV }}

.github/workflows/test_coverage.yml renamed to .github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: CI - test & coverage
1+
name: CI
22
on:
33
pull_request:
44
branches:
@@ -34,7 +34,7 @@ jobs:
3434
with:
3535
version: ${{ matrix.version }}
3636
arch: ${{ matrix.arch }}
37-
- uses: actions/cache@v1
37+
- uses: actions/cache@v4
3838
env:
3939
cache-name: cache-artifacts
4040
with:

Project.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@ Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
88
DynamicalSystemsBase = "6e36e845-645a-534a-86f2-f5d4aa5a06b4"
99
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1010
NonlinearSolve = "8913a72c-1f9b-4ce2-8d82-65094dcecaec"
11-
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
1211
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
1312
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
1413

1514
[compat]
1615
Combinatorics = "1"
1716
DynamicalSystemsBase = "3.8"
1817
NonlinearSolve = "4"
19-
OrdinaryDiffEq = "6"
2018
Reexport = "1"
2119
julia = "1.9"

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
# PeriodicOrbits.jl
22

33
[![docsdev](https://img.shields.io/badge/docs-dev-lightblue.svg)](https://juliadynamics.github.io/PeriodicOrbits.jl/dev/)
4-
[![docsstable](https://img.shields.io/badge/docs-stable-blue.svg)](https://juliadynamics.github.io/DynamicalSystemsDocs.jl/periodicorbits/stable/)
4+
<!-- [![docsstable](https://img.shields.io/badge/docs-stable-blue.svg)](https://juliadynamics.github.io/DynamicalSystemsDocs.jl/periodicorbits/stable/) -->
55
[![](https://img.shields.io/badge/DOI-10.1007%2F978--3--030--91032--7-purple)](https://link.springer.com/book/10.1007/978-3-030-91032-7)
66
[![CI](https://github.com/JuliaDynamics/PeriodicOrbits.jl/workflows/CI/badge.svg)](https://github.com/JuliaDynamics/PeriodicOrbits.jl/actions?query=workflow%3ACI)
77
[![codecov](https://codecov.io/gh/JuliaDynamics/PeriodicOrbits.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/JuliaDynamics/PeriodicOrbits.jl)
88
[![Package Downloads](https://shields.io/endpoint?url=https://pkgs.genieframework.com/api/v1/badge/PeriodicOrbits)](https://pkgs.genieframework.com?packages=PeriodicOrbits)
99

10-
Interface and algorithms for finding both stable and unstable periodic orbits of dynamical systems based on the DynamicalSystems.jl ecosystem.
10+
**PeriodicOrbits.jl** provides both the interface and algorithm implementations for finding stable and unstable periodic orbits of dynamical systems based on the DynamicalSystems.jl ecosystem.
1111

12-
Currently this is work in progress and the interface is being finalized. The package is not registered yet.
12+
Currently this is work in progress and the interface is being finalized. The package is not registered yet. To install it, run
13+
```
14+
import Pkg; Pkg.add(url = "https://github.com/JuliaDynamics/PeriodicOrbits.j")
15+
```
1316

14-
To install it, run `import Pkg; Pkg.add(url = "https://github.com/JuliaDynamics/PeriodicOrbits.j")`.
17+
In the future this package will be a basis for local continuation integrated with DynamicalSystems.jl.
1518

1619
All further information is provided in the documentation, which you can either find online or build locally by running the `docs/make.jl` file.
1720

docs/make.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ pages = [
77
"index.md",
88
"tutorial.md",
99
"api.md",
10-
"algorithms.md",
1110
"examples.md",
12-
"developer.md",
1311
"references.md"
1412
]
1513

docs/src/algorithms.md

Lines changed: 0 additions & 25 deletions
This file was deleted.

docs/src/api.md

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,51 @@
11
# The Public API
22

3+
## Main functions
34

45
```@docs
5-
PeriodicOrbit
6-
InitialGuess
76
periodic_orbit
87
periodic_orbits
8+
PeriodicOrbitFinder
9+
InitialGuess
10+
PeriodicOrbit
911
```
12+
1013
## Algorithms for Discrete-Time Systems
1114

1215
- [`SchmelcherDiakonos`](@ref)
1316
- [`DavidchackLai`](@ref)
1417

18+
```@docs
19+
SchmelcherDiakonos
20+
lambdamatrix
21+
lambdaperms
22+
```
23+
24+
```@docs
25+
DavidchackLai
26+
```
27+
1528
## Algorithms for Continuous-Time Systems
1629

1730
- [`OptimizedShooting`](@ref)
31+
32+
```@docs
33+
OptimizedShooting
34+
```
35+
36+
## Utility functions
37+
38+
```@docs
39+
postability
40+
minimal_period
41+
podistance
42+
poequal
43+
uniquepos
44+
PeriodicOrbits.isdiscretetime
45+
```
46+
47+
48+
## Adding new algorithms
49+
50+
To implement a new periodic orbit finding algorithm, simply create a new type,
51+
make it subtype `PeriodicOrbitFinder`, and then extend the function [`periodic_orbit`](@ref) for it.

docs/src/developer.md

Lines changed: 0 additions & 11 deletions
This file was deleted.

docs/src/examples.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Examples
22

33
## Optimized Shooting Example
4+
45
```@example MAIN
56
using PeriodicOrbits
67
using CairoMakie
@@ -30,6 +31,7 @@ plot_result(res, ds; azimuth = 1.3pi, elevation=0.1pi)
3031
```
3132

3233
## SchmelcherDiakonos example
34+
3335
For example, let's find the fixed points of the Standard map of period 2, 3, 4, 5, 6
3436
and 8. We will use all permutations for the `signs` but only one for the `inds`.
3537
We will also only use one `λ` value, and a 11×11 density of initial conditions.
@@ -124,7 +126,7 @@ Okay, this output is great, and we can tell that it is correct because:
124126
### Logistic map example
125127

126128
The idea of periodic orbits can be illustrated easily on 1D maps. Finding all periodic orbits of period
127-
$n$ is equivalent to finding all points $x$ such that $f^{n}(x)=x$, where $f^{n}$ is $n$-th composition of $f$. Hence, solving $f^{n}(x)-x=0$ yields such points. However, this is often impossible analytically.
129+
$n$ is equivalent to finding all points $x$ such that $f^{n}(x)=x$, where $f^{n}$ is $n$-th composition of $f$. Hence, solving $f^{n}(x)-x=0$ yields such points. However, this is often impossible analytically.
128130
Let's see how [`DavidchackLai`](@ref) deals with it:
129131

130132
First let's start with finding periodic orbits with period $1$ to $9$ for the logistic map with parameter $3.72$.
@@ -141,7 +143,7 @@ output = periodic_orbits(ds, alg, seeds)
141143
output = uniquepos(output);
142144
```
143145

144-
Let's plot the periodic orbits of period $6$.
146+
Let's plot the periodic orbits of period $6$.
145147

146148
```@example MAIN
147149
function ydata(ds, period, xdata)
@@ -168,14 +170,14 @@ lines!(axis, x, y, color = :blue, linewidth=1.7)
168170
scatter!(axis, [i[1] for i in fpsx], fpsy, color = :red, markersize=15)
169171
fig
170172
```
171-
Points $x$ which fulfill $f^{n}(x)=x$ can be interpreted as an intersection of the function
172-
$f^{n}(x)$ and the identity function $y=x$. Our result is correct because all the points of
173-
the intersection between the identity function and the sixth iterate of the logistic map
173+
Points $x$ which fulfill $f^{n}(x)=x$ can be interpreted as an intersection of the function
174+
$f^{n}(x)$ and the identity function $y=x$. Our result is correct because all the points of
175+
the intersection between the identity function and the sixth iterate of the logistic map
174176
were found.
175177

176178
### Henon Map example
177179

178-
Let's try to use [`DavidchackLai`](@ref) in higher dimension. We will try to detect
180+
Let's try to use [`DavidchackLai`](@ref) in higher dimension. We will try to detect
179181
all periodic points of Henon map of period `1` to `12`.
180182

181183
```@example MAIN
@@ -213,5 +215,5 @@ fig
213215
```
214216
The theory of periodic orbits states that UPOs form sort of a skeleton of the chaotic attractor. Our results supports this claim since it closely resembles the Henon attractor.
215217

216-
Note that in this case parameter `m` has to be set to at least `6`. Otherwise, the algorithm
218+
Note that in this case parameter `m` has to be set to at least `6`. Otherwise, the algorithm
217219
fails to detect orbits of higher periods correctly.

docs/src/tutorial.md

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,43 @@
11
# Tutorial
22

3-
Let's attempt to detect a periodic orbit of the Lorenz system. First we define the Lorenz
4-
system itself.
3+
In this tutorial we will detect an unstable periodic orbit of the well-known Lorenz-63 dynamical system. The tutorial assumes you are familiar with **DynamicalSystems.jl**; go through its overarching tutorial first if not.
4+
5+
First we define the Lorenz-63 system itself.
56

67
```@example MAIN
7-
using PeriodicOrbits
8+
using PeriodicOrbits # or `DynamicalSystems`
89
9-
function lorenz(u0=[0.0, 10.0, 0.0]; σ = 10.0, ρ = 28.0, β = 8/3)
10-
return CoupledODEs(lorenz_rule, u0, [σ, ρ, β]; diffeq=(abstol=1e-10, reltol=1e-10))
10+
function lorenz63(u0=[0.0, 10.0, 0.0]; σ = 10.0, ρ = 28.0, β = 8/3)
11+
diffeq = (abstol=1e-10, reltol=1e-10) # higher accuracy
12+
return CoupledODEs(lorenz63_rule, u0, [σ, ρ, β]; diffeq)
1113
end
12-
@inbounds function lorenz_rule(u, p, t)
14+
@inbounds function lorenz63_rule(u, p, t)
1315
du1 = p[1]*(u[2]-u[1])
1416
du2 = u[1]*(p[2]-u[3]) - u[2]
1517
du3 = u[1]*u[2] - p[3]*u[3]
1618
return SVector{3}(du1, du2, du3)
1719
end
1820
19-
ds = lorenz()
21+
ds = lorenz63()
2022
```
23+
At the default parameter values the system is chaotic; it only has unstable periodic orbits.
24+
25+
Given a dynamical system, the main function of the package is [`periodic_orbit`](@ref) which will find unstable/stable periodic orbits and return them.
26+
To call it, we need two things:
27+
1. An initial guess.
28+
2. A periodic orbit finding algorithm.
2129

22-
Next, we give initial guess of the location of the periodic orbit and its period.
30+
For the initial guess Next, we give initial guess of the location of the periodic orbit and its period. The initial guess must be an instance of [`InitialGuess`](@ref).
2331

2432
```@example MAIN
2533
u0_guess = SVector(1.0, 2.0, 5.0)
2634
T_guess = 4.2
27-
ig = InitialGuess(u0_guess, T_guess)
35+
ig = InitialGuess(u0_guess, T_guess)
2836
```
29-
Then we pick an appropriate algorithm that will detect the PO. In this case we can use
30-
any algorithm intended for continuous-time dynamical systems. We choose Optimized Shooting
31-
algorithm, for more information see [`OptimizedShooting`](@ref).
37+
38+
Then we pick an appropriate algorithm that will detect the PO.
39+
In this case we can use any algorithm intended for continuous time dynamical systems.
40+
We choose [`OptimizedShooting`](@ref) (see the documentation for more information).
3241

3342
```@example MAIN
3443
alg = OptimizedShooting(Δt=0.01, n=3)
@@ -41,43 +50,45 @@ po = periodic_orbit(ds, alg, ig)
4150
po
4251
```
4352

44-
The closed curve of the periodic orbit can be visualized using plotting library such as
45-
[`Makie`](https://github.com/MakieOrg/Makie.jl).
53+
The closed curve of the periodic orbit can be visualized using plotting library such as [`Makie`](https://github.com/MakieOrg/Makie.jl).
54+
Here we will visualize it inside an otherwise normal trajectory of the system.
4655

4756

4857
```@example MAIN
4958
using CairoMakie
5059
51-
u0 = po.points[1]
52-
T = po.T
53-
traj, t = trajectory(ds, T, u0; Dt = 0.01)
60+
# plot trajectory
61+
X, t = trajectory(ds, 100.0; Δt = 0.01)
5462
fig = Figure()
5563
ax = Axis3(fig[1,1], azimuth = 0.6pi, elevation= 0.1pi)
56-
lines!(ax, traj[:, 1], traj[:, 2], traj[:, 3], color = :blue, linewidth=1.7)
57-
scatter!(ax, u0)
64+
lines!(ax, X, color = :black, linewidth=1.0)
65+
# over-plot the PO
66+
u0 = po.points[1]
67+
T = po.T
68+
traj, t = trajectory(ds, T, u0; Δt = 0.01)
69+
lines!(ax, traj; color = :blue, linewidth=3)
5870
fig
5971
```
6072

61-
To ensure that the detected period is minimal, eg. it is not a multiple of the minimal
62-
period, we can use [`minimal_period`](@ref).
73+
To ensure that the detected period is minimal, eg. it is not a multiple of the minimal period, we can use [`minimal_period`](@ref).
6374

6475
```@example MAIN
6576
minT_po = minimal_period(ds, po)
6677
minT_po
6778
```
6879

69-
Whether two periodic orbits are equivalent up to some tolerance. Function [`poequal`](@ref)
70-
can be used.
80+
We see that the orbit is indeed minimal; the period did not change.
81+
To check whether two periodic orbits are equivalent up to some tolerance, the function [`poequal`](@ref) can be used.
7182

7283
```@example MAIN
7384
equal = poequal(po, minT_po; dthres=1e-3, Tthres=1e-3)
7485
"Detected periodic orbit had minimal period: $(equal)"
7586
```
7687

77-
To determine whether found periodic orbit is stable or unstable, we can apply
78-
[`isstable`](@ref) function.
88+
Most algorithms do not detect the stability of a PO automatically, so you can see it is reported as `missing` above.
89+
To determine whether found periodic orbit is stable or unstable, we can apply the [`postability`](@ref) function.
7990

8091
```@example MAIN
81-
po = isstable(ds, po)
92+
po = postability(ds, po)
8293
"Detected periodic orbit is $(po.stable ? "stable" : "unstable")."
83-
```
94+
```

0 commit comments

Comments
 (0)