Skip to content

Commit a01857f

Browse files
author
fchen121
committed
Added matrix form for linear FDE to ODE and new test case
1 parent c64979c commit a01857f

File tree

2 files changed

+51
-32
lines changed

2 files changed

+51
-32
lines changed

src/systems/diffeqs/basic_transformations.jl

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -342,14 +342,14 @@ prob = ODEProblem(sys, [], tspan)
342342
sol = solve(prob, radau5(), abstol = 1e-5, reltol = 1e-5)
343343
```
344344
"""
345-
function linear_fractional_to_ordinary(degrees, coeffs, rhs, epsilon, T; initials = 0, symbol = :x, iv = only(@independent_variables t))
345+
function linear_fractional_to_ordinary(degrees, coeffs, rhs, epsilon, T; initials = 0, symbol = :x, iv = only(@independent_variables t), matrix=false)
346346
previous = Symbol(symbol, :_, 0)
347347
previous = ModelingToolkit.unwrap(only(@variables $previous(iv)))
348348
@variables x_0(iv)
349349
D = Differential(iv)
350350
i = 0
351351
all_eqs = Equation[]
352-
all_def = Pair{Num, Int64}[]
352+
all_def = Pair[]
353353

354354
function fto_helper(sub_eq, α)
355355
δ = (gamma+1) * epsilon)^(1/α)
@@ -370,16 +370,29 @@ function linear_fractional_to_ordinary(degrees, coeffs, rhs, epsilon, T; initial
370370
end
371371

372372
new_eqs = Equation[]
373-
def = Pair{Num, Int64}[]
374-
sum = 0
375-
for index in range(M, N-1; step=1)
373+
def = Pair[]
374+
if matrix
376375
new_z = Symbol(, :_, i)
377376
i += 1
378-
new_z = ModelingToolkit.unwrap(only(@variables $new_z(iv)))
379-
new_eq = D(new_z) ~ sub_eq - γ_i(index)*new_z
377+
γs = diagm([γ_i(index) for index in M:N-1])
378+
cs = [c_i(index) for index in M:N-1]
379+
380+
new_z = only(@variables $new_z(iv)[1:N-M])
381+
new_eq = D(new_z) ~ -γs*new_z .+ sub_eq
382+
sum = dot(cs, new_z)
383+
push!(def, new_z=>zeros(N-M))
380384
push!(new_eqs, new_eq)
381-
push!(def, new_z=>0)
382-
sum += c_i(index)*new_z
385+
else
386+
sum = 0
387+
for index in range(M, N-1; step=1)
388+
new_z = Symbol(, :_, i)
389+
i += 1
390+
new_z = ModelingToolkit.unwrap(only(@variables $new_z(iv)))
391+
new_eq = D(new_z) ~ sub_eq - γ_i(index)*new_z
392+
push!(new_eqs, new_eq)
393+
push!(def, new_z=>0)
394+
sum += c_i(index)*new_z
395+
end
383396
end
384397
return (new_eqs, def, sum)
385398
end

test/fractional_to_ordinary.jl

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using ModelingToolkit, OrdinaryDiffEq, ODEInterfaceDiffEq, SpecialFunctions
1+
using ModelingToolkit, OrdinaryDiffEq, ODEInterfaceDiffEq, SpecialFunctions, LinearAlgebra
22
using Test
33

44
# Testing for α < 1
@@ -55,31 +55,37 @@ while(time <= 1)
5555
time += 0.1
5656
end
5757

58-
# # Testing for example 2 of Section 7
59-
# @independent_variables t
60-
# @variables x(t) y(t)
61-
# D = Differential(t)
62-
# tspan = (0., 220.)
58+
# Testing for example 2 of Section 7
59+
@independent_variables t
60+
@variables x(t) y(t)
61+
D = Differential(t)
62+
tspan = (0., 220.)
6363

64-
# sys = fractional_to_ordinary([1 - 4*x + x^2 * y, 3*x - x^2 * y], [x, y], [1.3, 0.8], 10^-8, 220; initials=[[1.2, 1], 2.8]; matrix=true)
65-
# prob = ODEProblem(sys, [], tspan)
66-
# sol = solve(prob, radau5(), abstol = 1e-8, reltol = 1e-8)
64+
sys = fractional_to_ordinary([1 - 4*x + x^2 * y, 3*x - x^2 * y], [x, y], [1.3, 0.8], 10^-8, 220; initials=[[1.2, 1], 2.8]; matrix=true)
65+
prob = ODEProblem(sys, [], tspan)
66+
sol = solve(prob, radau5(), abstol = 1e-8, reltol = 1e-8)
6767

68-
# @test isapprox(1.0097684171, sol(220, idxs=x), atol=1e-5)
69-
# @test isapprox(2.1581264031, sol(220, idxs=y), atol=1e-5)
68+
@test isapprox(1.0097684171, sol(220, idxs=x), atol=1e-5)
69+
@test isapprox(2.1581264031, sol(220, idxs=y), atol=1e-5)
7070

71-
# #Testing for example 3 of Section 7
72-
# @independent_variables t
73-
# @variables x_0(t)
74-
# D = Differential(t)
75-
# tspan = (0., 5000.)
71+
#Testing for example 3 of Section 7
72+
@independent_variables t
73+
@variables x_0(t)
74+
D = Differential(t)
75+
tspan = (0., 5000.)
76+
77+
function expect(t)
78+
return sqrt(2) * sin(t + pi/4)
79+
end
80+
81+
sys = linear_fractional_to_ordinary([3, 2.5, 2, 1, .5, 0], [1, 1, 1, 4, 1, 4], 6*cos(t), 10^-5, 5000; initials=[1, 1, -1])
82+
prob = ODEProblem(sys, [], tspan)
83+
sol = solve(prob, radau5(), abstol = 1e-5, reltol = 1e-5)
7684

77-
# function expect(t)
78-
# return sqrt(2) * sin(t + pi/4)
79-
# end
85+
@test isapprox(expect(5000), sol(5000, idxs=x_0), atol=1e-5)
8086

81-
# sys = linear_fractional_to_ordinary([3, 2.5, 2, 1, .5, 0], [1, 1, 1, 4, 1, 4], 6*cos(t), 10^-5, 5000; initials=[1, 1, -1])
82-
# prob = ODEProblem(sys, [], tspan)
83-
# sol = solve(prob, radau5(), abstol = 1e-5, reltol = 1e-5)
87+
msys = linear_fractional_to_ordinary([3, 2.5, 2, 1, .5, 0], [1, 1, 1, 4, 1, 4], 6*cos(t), 10^-5, 5000; initials=[1, 1, -1], matrix=true)
88+
mprob = ODEProblem(sys, [], tspan)
89+
msol = solve(prob, radau5(), abstol = 1e-5, reltol = 1e-5)
8490

85-
# @test isapprox(expect(5000), sol(5000, idxs=x_0), atol=1e-5)
91+
@test isapprox(expect(5000), msol(5000, idxs=x_0), atol=1e-5)

0 commit comments

Comments
 (0)