Skip to content

Commit 03eb25f

Browse files
committed
Add Example5 in Docs
1 parent 2420997 commit 03eb25f

File tree

4 files changed

+226
-14
lines changed

4 files changed

+226
-14
lines changed

Project.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,15 @@ Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
1919
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
2020
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
2121
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
22+
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
23+
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
24+
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
25+
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
26+
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
27+
Optim = "429524aa-4258-5aef-a3af-852621145aeb"
28+
StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd"
2229

2330
[targets]
2431
examples = ["Plots", "MittagLeffler"]
2532
test = ["Test", "SafeTestsets", "Statistics"]
26-
docs = ["Plots", "SpecialFunctions"]
33+
docs = ["Plots", "SpecialFunctions", "CSV","HTTP","DataFrames","Dates","StatsBase", "Optim","StatsPlots", "StatsPlots.PlotMeasures"]

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,16 @@ This research has received funding from
6262

6363
**Kindly cite this work** as follows:
6464

65-
- Fdesolver: A Julia package for solving fractional differential equations. M Khalighi, G Benedetti, L Lahti. [ACM Transactions on Mathematical Software](https://doi.org/10.1145/3680280), 2024.
65+
- Fdesolver: A Julia package for solving fractional differential equations. M Khalighi, G Benedetti, L Lahti. ACM Transactions on Mathematical Software, 2024, [doi.org/10.1145/3680280](https://doi.org/10.1145/3680280).
6666

6767

6868
The package development is further linked with the following publications/preprints:
6969

70-
- Ebola epidemic model with dynamic population and memory, F Ndaïrou, M Khalighi, and L Lahti, Chaos, Solitons \& Fractals, 170: 113361, 2023. [doi:10.1016/j.chaos.2023.113361](https://doi.org/10.1016/j.chaos.2023.113361)
70+
- Ebola epidemic model with dynamic population and memory, F Ndaïrou, M Khalighi, and L Lahti, Chaos, Solitons \& Fractals, 170: 113361, 2023, [doi:10.1016/j.chaos.2023.113361](https://doi.org/10.1016/j.chaos.2023.113361).
7171

72-
- Quantifying the impact of ecological memory on the dynamics of interacting communities. M Khalighi, G Sommeria-Klein, D Gonze, K Faust, L Lahti. PLoS Computational Biology 18(6), 2022 [doi:10.1371/journal.pcbi.1009396](https://doi.org/10.1371/journal.pcbi.1009396)
72+
- Quantifying the impact of ecological memory on the dynamics of interacting communities. M Khalighi, G Sommeria-Klein, D Gonze, K Faust, L Lahti. PLoS Computational Biology 18(6), 2022, [doi:10.1371/journal.pcbi.1009396](https://doi.org/10.1371/journal.pcbi.1009396).
7373

74-
- Three-species Lotka-Volterra model with respect to Caputo and Caputo-Fabrizio fractional operators. M Khalighi, L Eftekhari, S Hosseinpour, L Lahti. Symmetry 13 (3):368, 2021. [doi:10.3390/sym13030368](https://doi.org/10.3390/sym13030368)
74+
- Three-species Lotka-Volterra model with respect to Caputo and Caputo-Fabrizio fractional operators. M Khalighi, L Eftekhari, S Hosseinpour, L Lahti. Symmetry 13 (3):368, 2021, [doi:10.3390/sym13030368](https://doi.org/10.3390/sym13030368).
7575

7676

7777

docs/Project.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,10 @@ Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
33
FdeSolver = "1746e360-1058-44a5-9855-ddd460437d0c"
44
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
55
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
6+
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
7+
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
8+
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
9+
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
10+
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
11+
Optim = "429524aa-4258-5aef-a3af-852621145aeb"
12+
StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd"

docs/src/examples.md

Lines changed: 207 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@
33
```@setup fde
44
using FdeSolver
55
using Plots, SpecialFunctions
6+
using CSV, HTTP, DataFrames, Dates, StatsBase, Optim, StatsPlots, StatsPlots.PlotMeasures
67
```
7-
88
## Example 1: [Fractional nonlinear equation](https://doi.org/10.1023/B:NUMA.0000027736.85078.be)
99

10+
$$
11+
D^\beta y(t) = \frac{40320}{\Gamma(9 - \beta)} t^{8 - \beta} - 3 \frac{\Gamma(5 + \beta / 2)}{\Gamma(5 - \beta / 2)} t^{4 - \beta / 2} + \frac{9}{4} \Gamma(\beta + 1) + \left( \frac{3}{2} t^{\beta / 2} - t^4 \right)^3 - \left[ y(t) \right]^{3 / 2}
12+
$$
13+
14+
1015
For `` 0<\beta\leq1 `` being subject to the initial condition `` y(0)=0 ``, the exact solution is:
1116

1217
```math
@@ -40,11 +45,18 @@ savefig("example1.png"); nothing # hide
4045

4146
## Example 2: [Lotka-volterra-predator-prey](https://mc-stan.org/users/documentation/case-studies/lotka-volterra-predator-prey.html)
4247

48+
$$
49+
\begin{align*}
50+
D^{μ_1}u &= (\alpha - \beta v) u = \alpha u - \beta u v \\
51+
D^{μ_2}v &= (-\gamma + \delta u) v = -\gamma v + \delta u v
52+
\end{align*}
53+
$$
54+
4355
```@example fde
4456
# Inputs
4557
tSpan = [0, 25]; # [initial time, final time]
4658
y0 = [34, 6]; # initial values
47-
beta = [0.98, 0.99]; # order of derivatives
59+
μ = [0.98, 0.99]; # order of derivatives
4860
par = [0.55, 0.028, 0.84, 0.026]; # model parameters
4961
5062
# ODE Model
@@ -67,7 +79,7 @@ function F(t, y, par)
6779
end
6880
6981
## Solution
70-
t, Yapp = FDEsolver(F, tSpan, y0, beta, par);
82+
t, Yapp = FDEsolver(F, tSpan, y0, μ, par);
7183
7284
# Plot
7385
plot(t, Yapp, linewidth = 5, title = "Solution to LV model with 2 FDEs",
@@ -81,7 +93,13 @@ savefig("example2.png"); nothing # hide
8193
## Example 3: [SIR model](https://en.wikipedia.org/wiki/Compartmental_models_in_epidemiology)
8294

8395
One application of using fractional calculus is taking into account effects of [memory](https://journals.aps.org/pre/abstract/10.1103/PhysRevE.95.022409) in modeling including epidemic evolution.
84-
96+
$$
97+
\begin{align*}
98+
D^{α_1}S &= -\beta IS, \\
99+
D^{α_2}I &= \beta IS - \gamma I, \\
100+
D^{α_3}R &= \gamma I.
101+
\end{align*}
102+
$$
85103
By defining the Jacobian matrix, the user can achieve a faster convergence based on the modified [Newton–Raphson](https://www.mdpi.com/2227-7390/6/2/16/htm) method.
86104

87105
```@example fde
@@ -157,7 +175,10 @@ savefig("example3.png"); nothing # hide
157175
## Example 4: [Dynamics of interaction of N species microbial communities](https://doi.org/10.1371/journal.pcbi.1009396)
158176

159177
The impact of [ecological memory](https://doi.org/10.1371/journal.pcbi.1009396) on the dynamics of interacting communities can be quantified by solving fractional form ODE systems.
160-
178+
$$
179+
D^{β_i}X_i = X_i \left( b_i f_i(\{X_k\}) - k_i X_i \right), \quad
180+
f_i(\{X_k\}) = \prod_{\substack{k=1 \\ k \neq i}}^N \frac{K_{ik}^n}{K_{ik}^n + X_k^n}.
181+
$$
161182
```@example fde
162183
tSpan = [0, 50]; # time span
163184
h = 0.1; # time step
@@ -166,10 +187,10 @@ N = 20; # number of species
166187
X0 = 2 * rand(N); # initial abundances
167188
168189
# parametrisation
169-
par = [2,
170-
2 * rand(N),
190+
par = [5,
171191
rand(N),
172-
4 * rand(N, N),
192+
rand(N),
193+
2 * rand(N, N),
173194
N];
174195
175196
# ODE model
@@ -205,8 +226,185 @@ t, Xapp = FDEsolver(F, tSpan, X0, β, par, h = h, nc = 3, tol = 10e-9);
205226
plot(t, Xapp, linewidth = 5,
206227
title = "Dynamics of microbial interaction model",
207228
xaxis = "Time (t)");
208-
yaxis!("Log Abundance", :log10, minorgrid = true);
229+
yaxis!("Log abundance", :log10, minorgrid = true);
209230
savefig("example4.png"); nothing # hide
210231
```
211232

212233
![example4](example4.png)
234+
235+
236+
## Example 5: Fitting orders of a [COVID-19 model](https://doi.org/10.1016/j.chaos.2020.109846)
237+
238+
Different methods are used to adjust the order of fractional differential equation models, which helps in analyzing systems across various fields.
239+
240+
We use [Optim.jl](https://github.com/JuliaNLSolvers/Optim.jl) to demonstrate how modifying system parameters and the order of derivatives in FdeSolver can enhance the fitting of COVID-19 data. The model is as follows:
241+
$$
242+
\begin{align*}
243+
{D}_t^{\alpha_S} S(t) =& -\beta \frac{I}{N} S - l\beta \frac{H}{N} S - \beta' \frac{P}{N} S, \\
244+
{D}_t^{\alpha_E} E(t) =& \beta \frac{I}{N} S + l\beta \frac{H}{N} S + \beta' \frac{P}{N} S - \kappa E, \\
245+
{D}_t^{\alpha_I} I(t) =& \kappa \rho_1 E - (\gamma_a + \gamma_i) I - \delta_i I, \\
246+
{D}_t^{\alpha_P} P(t) =& \kappa \rho_2 E - (\gamma_a + \gamma_i) P - \delta_p P, \\
247+
{D}_t^{\alpha_A} A(t) =& \kappa (1 - \rho_1 - \rho_2) E, \\
248+
{D}_t^{\alpha_H} H(t) =& \gamma_a (I + P) - \gamma_r H - \delta_h H, \\
249+
{D}_t^{\alpha_R} R(t) =& \gamma_i (I + P) + \gamma_r H, \\
250+
{D}_t^{\alpha_F} F(t) =& \delta_i I + \delta_p P + \delta_h H,
251+
\end{align*}
252+
$$
253+
254+
- **Model M1**: fits one parameter and uses integer orders.
255+
- **Model Mf1**: fits one parameter, but adjusts the derivative orders; however, all orders are equal, representing a commensurate fractional order.
256+
- **Model Mf8**: fits one parameter and allows for eight distinct derivative orders, accommodating incommensurate orders for more flexibility in modeling.
257+
258+
```@example fde
259+
# Dataset subset
260+
repo=HTTP.get("https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv"); # dataset of Covid from CSSE
261+
dataset_CC = CSV.read(repo.body, DataFrame); # all data of confirmed
262+
Confirmed=dataset_CC[dataset_CC[!,2].=="Portugal",45:121]; #comulative confirmed data of Portugal from 3/2/20 to 5/17/20
263+
C=diff(Float64.(Vector(Confirmed[1,:])));# Daily new confirmed cases
264+
265+
#preprocessing (map negative values to zero and remove outliers)
266+
₋Ind=findall(C.<0);
267+
C[₋Ind].=0.0;
268+
outlier=findall(C.>1500);
269+
C[outlier]=(C[outlier.-1]+C[outlier.-1])/2;
270+
271+
## System definition
272+
273+
# parameters
274+
β=2.55; # Transmission coefficient from infected individuals
275+
l=1.56; # Relative transmissibility of hospitalized patients
276+
β′=7.65; # Transmission coefficient due to super-spreaders
277+
κ=0.25; # Rate at which exposed become infectious
278+
ρ₁=0.58; # Rate at which exposed people become infected I
279+
ρ₂=0.001; # Rate at which exposed people become super-spreaders
280+
γₐ=0.94; # Rate of being hospitalized
281+
γᵢ=0.27; # Recovery rate without being hospitalized
282+
γᵣ=0.5; # Recovery rate of hospitalized patients
283+
δᵢ=1/23; # Disease induced death rate due to infected class
284+
δₚ=1/23; # Disease induced death rate due to super-spreaders
285+
δₕ=1/23; # Disease induced death rate due to hospitalized class
286+
# Define SIR model
287+
function SIR(t, u, par)
288+
# Model parameters.
289+
N, β, l, β′, κ, ρ₁, ρ₂, γₐ, γᵢ, γᵣ, δᵢ, δₚ, δₕ=par
290+
291+
# Current state.
292+
S, E, I, P, A, H, R, F = u
293+
294+
# ODE
295+
dS = - β * I * S/N - l * β * H * S/N - β′* P * S/N # susceptible individuals
296+
dE = β * I * S/N + l * β * H * S/N + β′ *P* S/N - κ * E # exposed individuals
297+
dI = κ * ρ₁ * E - (γₐ + γᵢ )*I - δᵢ * I #symptomatic and infectious individuals
298+
dP = κ* ρ₂ * E - (γₐ + γᵢ)*P - δₚ * P # super-spreaders individuals
299+
dA = κ *(1 - ρ₁ - ρ₂ )* E # infectious but asymptomatic individuals
300+
dH = γₐ *(I + P ) - γᵣ *H - δₕ *H # hospitalized individuals
301+
dR = γᵢ * (I + P ) + γᵣ* H # recovery individuals
302+
dF = δᵢ * I + δₚ* P + δₕ *H # dead individuals
303+
return [dS, dE, dI, dP, dA, dH, dR, dF]
304+
end;
305+
306+
#initial conditions
307+
N=10280000/875; # Population Size
308+
S0=N-5; E0=0; I0=4; P0=1; A0=0; H0=0; R0=0; F0=0;
309+
X0=[S0, E0, I0, P0, A0, H0, R0, F0]; # initial values
310+
tspan=[1,length(C)]; # time span [initial time, final time]
311+
312+
par=[N, β, l, β′, κ, ρ₁, ρ₂, γₐ, γᵢ, γᵣ, δᵢ, δₚ, δₕ]; # parameters
313+
314+
## optimazation of β for integer order model
315+
316+
function loss_1(b) # loss function
317+
par[2]=b[1]
318+
_, x = FDEsolver(SIR, tspan, X0, ones(8), par, h = .1)
319+
appX=vec(sum(x[1:10:end,[3,4,6]], dims=2))
320+
rmsd(C, appX; normalize=:true) # Normalized root-mean-square error
321+
end;
322+
323+
p_lo_1=[1.4]; #lower bound for β
324+
p_up_1=[4.0]; # upper bound for β
325+
p_vec_1=[2.5]; # initial guess for β
326+
Res1=optimize(loss_1,p_lo_1,p_up_1,p_vec_1,Fminbox(BFGS()),# Broyden–Fletcher–Goldfarb–Shanno algorithm
327+
# Result=optimize(loss_1,p_lo_1,p_up_1,p_vec_1,SAMIN(rt=.99), # Simulated Annealing algorithm (sometimes it has better perfomance than (L-)BFGS)
328+
Optim.Options(outer_iterations = 10,
329+
iterations=1000,
330+
show_trace=false, # turn it true to see the optimization
331+
show_every=1));
332+
p1=vcat(Optim.minimizer(Res1));
333+
par1=copy(par); par1[2]=p1[1];
334+
335+
## optimazation of β and order of commensurate fractional order model
336+
function loss_F_1(pμ)
337+
par[2] = pμ[1] # infectivity rate
338+
μ = pμ[2] # order of derivatives
339+
340+
_, x = FDEsolver(SIR, tspan, X0, μ*ones(8), par, h = .1)
341+
appX=vec(sum(x[1:10:end,[3,4,6]], dims=2))
342+
rmsd(C, appX; normalize=:true)
343+
end;
344+
345+
p_lo_f_1=vcat(1.4,.5); # lower bound for β and orders
346+
p_up_f_1=vcat(4,1); # upper bound for β and orders
347+
p_vec_f_1=vcat(2.5,.9); # initial guess for β and orders
348+
ResF1=optimize(loss_F_1,p_lo_f_1,p_up_f_1,p_vec_f_1,Fminbox(LBFGS()), # LBFGS is suitable for large scale problems
349+
# Result=optimize(loss,p_lo,p_up,pvec,SAMIN(rt=.99),
350+
Optim.Options(outer_iterations = 10,
351+
iterations=1000,
352+
show_trace=false, # turn it true to see the optimization
353+
show_every=1));
354+
pμ=vcat(Optim.minimizer(ResF1));
355+
parf1=copy(par); parf1[2]=pμ[1]; μ1=pμ[2];
356+
357+
## optimazation of β and order of incommensurate fractional order model
358+
function loss_F_8(pμ)
359+
par[2] = pμ[1] # infectivity rate
360+
μ = pμ[2:9] # order of derivatives
361+
if size(X0,2) != Int64(ceil(maximum(μ))) # to prevent any errors regarding orders higher than 1
362+
indx=findall(x-> x>1, μ)
363+
μ[indx]=ones(length(indx))
364+
end
365+
_, x = FDEsolver(SIR, tspan, X0, μ, par, h = .1)
366+
appX=vec(sum(x[1:10:end,[3,4,6]], dims=2))
367+
rmsd(C, appX; normalize=:true)
368+
end;
369+
370+
p_lo=vcat(1.4,.5*ones(8)); # lower bound for β and orders
371+
p_up=vcat(4,ones(8)); # upper bound for β and orders
372+
pvec=vcat(2.5,.9*ones(8)); # initial guess for β and orders
373+
ResF8=optimize(loss_F_8,p_lo,p_up,pvec,Fminbox(LBFGS()), # LBFGS is suitable for large scale problems
374+
# Result=optimize(loss,p_lo,p_up,pvec,SAMIN(rt=.99),
375+
Optim.Options(outer_iterations = 10,
376+
iterations=1000,
377+
show_trace=false, # turn it true to see the optimization
378+
show_every=1));
379+
pp=vcat(Optim.minimizer(ResF8));
380+
parf8=copy(par); parf8[2]=pp[1]; μ8=pp[2:9];
381+
382+
## plotting
383+
DateTick=Date(2020,3,3):Day(1):Date(2020,5,17);
384+
DateTick2= Dates.format.(DateTick, "d u");
385+
386+
t1, x1 = FDEsolver(SIR, tspan, X0, ones(8), par1, h = .1); # solve ode model
387+
_, xf1 = FDEsolver(SIR, tspan, X0, μ1*ones(8), parf1, h = .1); # solve commensurate fode model
388+
_, xf8 = FDEsolver(SIR, tspan, X0, μ8, parf8, h = .1); # solve incommensurate fode model
389+
390+
X1=sum(x1[1:10:end,[3,4,6]], dims=2);
391+
Xf1=sum(xf1[1:10:end,[3,4,6]], dims=2);
392+
Xf8=sum(xf8[1:10:end,[3,4,6]], dims=2);
393+
394+
Err1=rmsd(C, vec(X1)); # RMSD for ode model
395+
Errf1=rmsd(C, vec(Xf1)); # RMSD for commensurate fode model
396+
Errf8=rmsd(C, vec(Xf8)); # RMSD for incommensurate fode model
397+
398+
plot(DateTick2,X1, ylabel="Daily new confirmed cases in Portugal",lw=5,
399+
label="M1",xrotation=rad2deg(pi/3), linestyle=:dashdot)
400+
plot!(Xf1, label="Mf1", lw=5)
401+
plot!(Xf8, label="Mf8", linestyle=:dash, lw=5)
402+
scatter!(C, label= "Real data",legendposition=(.85,1),legend=:false)
403+
plPortugal=bar!(["M1" "Mf1" "Mf8"],[Err1 Errf1 Errf8], ylabel="Error (RMSD)",
404+
legend=:false, bar_width=2,yguidefontsize=8,xtickfontsize=7,
405+
inset = (bbox(0.04, 0.08, 70px, 60px, :right)),
406+
subplot = 2,
407+
bg_inside = nothing)
408+
savefig("example5.png"); nothing # hide
409+
```
410+
![example5](example5.png)

0 commit comments

Comments
 (0)