@@ -211,15 +211,15 @@ while(time <= 1)
211211end
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)
296297end
297298
@@ -315,10 +316,11 @@ prob = ODEProblem(sys, [], tspan)
315316sol = 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)
385458end
386459
0 commit comments