Skip to content

Commit 9480748

Browse files
author
fchen121
committed
Implemented matrix ver. and changed test cases
1 parent 4293364 commit 9480748

File tree

2 files changed

+99
-26
lines changed

2 files changed

+99
-26
lines changed

src/systems/diffeqs/basic_transformations.jl

Lines changed: 95 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -211,15 +211,15 @@ while(time <= 1)
211211
end
212212
```
213213
"""
214-
function fractional_to_ordinary(eqs, variables, alphas, epsilon, T; initials = 0)
215-
@independent_variables t
216-
D = Differential(t)
214+
function fractional_to_ordinary(eqs, variables, alphas, epsilon, T; initials = 0, additional_eqs = [], iv = only(@independent_variables t))
215+
D = Differential(iv)
217216
i = 0
218217
all_eqs = Equation[]
219218
all_def = Pair{Num, Int64}[]
220219

221220
function fto_helper(sub_eq, sub_var, α; initial=0)
222221
alpha_0 = α
222+
223223
if> 1)
224224
coeff = 1/- 1)
225225
m = 2
@@ -253,9 +253,9 @@ function fractional_to_ordinary(eqs, variables, alphas, epsilon, T; initials = 0
253253
if< 1)
254254
rhs = initial
255255
for index in range(M, N-1; step=1)
256-
new_z = Symbol(:z, :_, i)
256+
new_z = Symbol(:ʐ, :_, i)
257257
i += 1
258-
new_z = ModelingToolkit.unwrap(only(@variables $new_z(t)))
258+
new_z = ModelingToolkit.unwrap(only(@variables $new_z(iv)))
259259
new_eq = D(new_z) ~ sub_eq - γ_i(index)*new_z
260260
push!(new_eqs, new_eq)
261261
push!(def, new_z=>0)
@@ -264,16 +264,16 @@ function fractional_to_ordinary(eqs, variables, alphas, epsilon, T; initials = 0
264264
else
265265
rhs = 0
266266
for (index, value) in enumerate(initial)
267-
rhs += value * t^(index - 1) / gamma(index)
267+
rhs += value * iv^(index - 1) / gamma(index)
268268
end
269269
for index in range(M, N-1; step=1)
270-
new_z = Symbol(:z, :_, i)
270+
new_z = Symbol(:ʐ, :_, i)
271271
i += 1
272272
γ = γ_i(index)
273273
base = sub_eq
274274
for k in range(1, m; step=1)
275-
new_z = Symbol(:z, :_, index-M, :_, k)
276-
new_z = ModelingToolkit.unwrap(only(@variables $new_z(t)))
275+
new_z = Symbol(:ʐ, :_, index-M, :_, k)
276+
new_z = ModelingToolkit.unwrap(only(@variables $new_z(iv)))
277277
new_eq = D(new_z) ~ base - γ*new_z
278278
base = k * new_z
279279
push!(new_eqs, new_eq)
@@ -291,7 +291,8 @@ function fractional_to_ordinary(eqs, variables, alphas, epsilon, T; initials = 0
291291
append!(all_eqs, new_eqs)
292292
append!(all_def, def)
293293
end
294-
@named sys = System(all_eqs, t; defaults=all_def)
294+
append!(all_eqs, additional_eqs)
295+
@named sys = System(all_eqs, iv; defaults=all_def)
295296
return mtkcompile(sys)
296297
end
297298

@@ -315,10 +316,11 @@ prob = ODEProblem(sys, [], tspan)
315316
sol = solve(prob, radau5(), abstol = 1e-5, reltol = 1e-5)
316317
```
317318
"""
318-
function linear_fractional_to_ordinary(degrees, coeffs, rhs, epsilon, T; initials = 0)
319-
@independent_variables t
320-
@variables x_0(t)
321-
D = Differential(t)
319+
function linear_fractional_to_ordinary(degrees, coeffs, rhs, epsilon, T; initials = 0, symbol = :x, iv = only(@independent_variables t))
320+
previous = Symbol(symbol, :_, 0)
321+
previous = ModelingToolkit.unwrap(only(@variables $previous(iv)))
322+
@variables x_0(iv)
323+
D = Differential(iv)
322324
i = 0
323325
all_eqs = Equation[]
324326
all_def = Pair{Num, Int64}[]
@@ -345,9 +347,9 @@ function linear_fractional_to_ordinary(degrees, coeffs, rhs, epsilon, T; initial
345347
def = Pair{Num, Int64}[]
346348
sum = 0
347349
for index in range(M, N-1; step=1)
348-
new_z = Symbol(:z, :_, i)
350+
new_z = Symbol(:ʐ, :_, i)
349351
i += 1
350-
new_z = ModelingToolkit.unwrap(only(@variables $new_z(t)))
352+
new_z = ModelingToolkit.unwrap(only(@variables $new_z(iv)))
351353
new_eq = D(new_z) ~ sub_eq - γ_i(index)*new_z
352354
push!(new_eqs, new_eq)
353355
push!(def, new_z=>0)
@@ -356,10 +358,9 @@ function linear_fractional_to_ordinary(degrees, coeffs, rhs, epsilon, T; initial
356358
return (new_eqs, def, sum)
357359
end
358360

359-
previous = x_0
360361
for i in range(1, ceil(Int, degrees[1]); step=1)
361-
new_x = Symbol(:x, :_, i)
362-
new_x = ModelingToolkit.unwrap(only(@variables $new_x(t)))
362+
new_x = Symbol(symbol, :_, i)
363+
new_x = ModelingToolkit.unwrap(only(@variables $new_x(iv)))
363364
push!(all_eqs, D(previous) ~ new_x)
364365
push!(all_def, previous => initials[i])
365366
previous = new_x
@@ -368,8 +369,8 @@ function linear_fractional_to_ordinary(degrees, coeffs, rhs, epsilon, T; initial
368369
new_rhs = -rhs
369370
for (degree, coeff) in zip(degrees, coeffs)
370371
rounded = ceil(Int, degree)
371-
new_x = Symbol(:x, :_, rounded)
372-
new_x = ModelingToolkit.unwrap(only(@variables $new_x(t)))
372+
new_x = Symbol(symbol, :_, rounded)
373+
new_x = ModelingToolkit.unwrap(only(@variables $new_x(iv)))
373374
if isinteger(degree)
374375
new_rhs += coeff * new_x
375376
else
@@ -380,7 +381,79 @@ function linear_fractional_to_ordinary(degrees, coeffs, rhs, epsilon, T; initial
380381
end
381382
end
382383
push!(all_eqs, 0 ~ new_rhs)
383-
@named sys = System(all_eqs, t; defaults=all_def)
384+
@named sys = System(all_eqs, iv; defaults=all_def)
385+
return mtkcompile(sys)
386+
end
387+
388+
function fto_matrix(eqs, variables, alphas, epsilon, T; initials = 0, additional_eqs = [], iv = only(@independent_variables t))
389+
D = Differential(iv)
390+
i = 0
391+
all_eqs = Equation[]
392+
all_def = Pair[]
393+
394+
function fto_helper(sub_eq, sub_var, α; initial=0)
395+
alpha_0 = α
396+
397+
if> 1)
398+
coeff = 1/- 1)
399+
m = 2
400+
while- m > 0)
401+
coeff /= α - m
402+
m += 1
403+
end
404+
alpha_0 = α - m + 1
405+
end
406+
407+
δ = (gamma(alpha_0+1) * epsilon)^(1/alpha_0)
408+
a = pi/2*(1-(1-alpha_0)/((2-alpha_0) * log(epsilon^-1)))
409+
h = 2*pi*a / log(1 + (2/epsilon * (cos(a))^(alpha_0 - 1)))
410+
411+
x_sub = (gamma(2-alpha_0) * epsilon)^(1/(1-alpha_0))
412+
x_sup = -log(gamma(1-alpha_0) * epsilon)
413+
M = floor(Int, log(x_sub / T) / h)
414+
N = ceil(Int, log(x_sup / δ) / h)
415+
416+
function c_i(index)
417+
h * sin(pi * alpha_0) / pi * exp((1-alpha_0)*h*index)
418+
end
419+
420+
function γ_i(index)
421+
exp(h * index)
422+
end
423+
424+
new_eqs = Equation[]
425+
def = Pair[]
426+
new_z = Symbol(, :_, i)
427+
i += 1
428+
γs = diagm([γ_i(index) for index in M:N-1])
429+
cs = [c_i(index) for index in M:N-1]
430+
431+
if< 1)
432+
new_z = only(@variables $new_z(iv)[1:N-M])
433+
new_eq = D(new_z) ~ -γs*new_z .+ sub_eq
434+
rhs = dot(cs, new_z) + initial
435+
push!(def, new_z=>zeros(N-M))
436+
else
437+
new_z = only(@variables $new_z(iv)[1:N-M, 1:m])
438+
new_eq = D(new_z) ~ -γs*new_z + hcat(fill(sub_eq, N-M, 1), collect(new_z[:, 1:m-1]*diagm(1:m-1)))
439+
rhs = coeff*sum(cs[i]*new_z[i, m] for i in 1:N-M)
440+
for (index, value) in enumerate(initial)
441+
rhs += value * iv^(index - 1) / gamma(index)
442+
end
443+
push!(def, new_z=>zeros(N-M, m))
444+
end
445+
push!(new_eqs, new_eq)
446+
push!(new_eqs, sub_var ~ rhs)
447+
return (new_eqs, def)
448+
end
449+
450+
for (eq, cur_var, alpha, init) in zip(eqs, variables, alphas, initials)
451+
(new_eqs, def) = fto_helper(eq, cur_var, alpha; initial=init)
452+
append!(all_eqs, new_eqs)
453+
append!(all_def, def)
454+
end
455+
append!(all_eqs, additional_eqs)
456+
@named sys = System(all_eqs, iv; defaults=all_def)
384457
return mtkcompile(sys)
385458
end
386459

test/fractional_to_ordinary.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ sol = solve(prob, radau5(), saveat=timepoint, abstol = 1e-10, reltol = 1e-10)
2323

2424
time = 0
2525
while(time <= 1)
26-
@test isapprox(expect(time, α), sol(time, idxs=x), atol=1e-3)
26+
@test isapprox(expect(time, α), sol(time, idxs=x), atol=1e-7)
2727
time += 0.1
2828
end
2929

3030
α = 0.3
3131
eqs = (9*gamma(1 + α)/4) - (3*t^(4 - α/2)*gamma(5 + α/2)/gamma(5 - α/2))
3232
eqs += (gamma(9)*t^(8 - α)/gamma(9 - α)) + (3/2*t^/2)-t^4)^3 - x^(3/2)
33-
sys = fractional_to_ordinary(eqs, x, α, 10^-7, 1)
33+
sys = fto_matrix(eqs, x, α, 10^-7, 1)
3434

3535
prob = ODEProblem(sys, [], tspan)
3636
sol = solve(prob, radau5(), saveat=timepoint, abstol = 1e-10, reltol = 1e-10)
@@ -61,7 +61,7 @@ end
6161
D = Differential(t)
6262
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])
64+
sys = fto_matrix([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])
6565
prob = ODEProblem(sys, [], tspan)
6666
sol = solve(prob, radau5(), abstol = 1e-8, reltol = 1e-8)
6767

@@ -82,4 +82,4 @@ sys = linear_fractional_to_ordinary([3, 2.5, 2, 1, .5, 0], [1, 1, 1, 4, 1, 4], 6
8282
prob = ODEProblem(sys, [], tspan)
8383
sol = solve(prob, radau5(), abstol = 1e-5, reltol = 1e-5)
8484

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

0 commit comments

Comments
 (0)