@@ -185,6 +185,242 @@ function change_of_variables(
185185    return  new_sys
186186end 
187187
188+ """ 
189+ Generates the system of ODEs to find solution to FDEs. 
190+ 
191+ Example: 
192+ 
193+ ```julia 
194+ @independent_variables t 
195+ @variables x(t) 
196+ D = Differential(t) 
197+ tspan = (0., 1.) 
198+ 
199+ α = 0.5 
200+ eqs = (9*gamma(1 + α)/4) - (3*t^(4 - α/2)*gamma(5 + α/2)/gamma(5 - α/2)) 
201+ eqs += (gamma(9)*t^(8 - α)/gamma(9 - α)) + (3/2*t^(α/2)-t^4)^3 - x^(3/2) 
202+ sys = fractional_to_ordinary(eqs, x, α, 10^-7, 1) 
203+ 
204+ prob = ODEProblem(sys, [], tspan) 
205+ sol = solve(prob, radau5(), abstol = 1e-10, reltol = 1e-10) 
206+ ``` 
207+ """ 
208+ function  fractional_to_ordinary (
209+         eqs, variables, alphas, epsilon, T;
210+         initials =  0 , additional_eqs =  [], iv =  only (@independent_variables  t), matrix= false 
211+ )
212+     D =  Differential (iv)
213+     i =  0 
214+     all_eqs =  Equation[]
215+     all_def =  Pair[]
216+     
217+     function  fto_helper (sub_eq, sub_var, α; initial= 0 )
218+         alpha_0 =  α
219+ 
220+         if  (α >  1 )
221+             coeff =  1 / (α -  1 )
222+             m =  2 
223+             while  (α -  m >  0 )
224+                 coeff /=  α -  m
225+                 m +=  1 
226+             end 
227+             alpha_0 =  α -  m +  1 
228+         end 
229+ 
230+         δ =  (gamma (alpha_0+ 1 ) *  epsilon)^ (1 / alpha_0)
231+         a =  pi / 2 * (1 - (1 - alpha_0)/ ((2 - alpha_0) *  log (epsilon^- 1 )))
232+         h =  2 * pi * a /  log (1  +  (2 / epsilon *  (cos (a))^ (alpha_0 -  1 )))
233+ 
234+         x_sub =  (gamma (2 - alpha_0) *  epsilon)^ (1 / (1 - alpha_0))
235+         x_sup =  - log (gamma (1 - alpha_0) *  epsilon)
236+         M =  floor (Int, log (x_sub /  T) /  h)
237+         N =  ceil (Int, log (x_sup /  δ) /  h)
238+ 
239+         function  c_i (index)
240+             h *  sin (pi  *  alpha_0) /  pi  *  exp ((1 - alpha_0)* h* index)
241+         end 
242+ 
243+         function  γ_i (index)
244+             exp (h *  index)
245+         end 
246+ 
247+         new_eqs =  Equation[]
248+         def =  Pair[]
249+ 
250+         if  matrix
251+             new_z =  Symbol (:ʐ , :_ , i)
252+             i +=  1 
253+             γs =  diagm ([γ_i (index) for  index in  M: N- 1 ])
254+             cs =  [c_i (index) for  index in  M: N- 1 ]
255+ 
256+             if  (α <  1 )
257+                 new_z =  only (@variables  $ new_z (iv)[1 : N- M])
258+                 new_eq =  D (new_z) ~  - γs* new_z .+  sub_eq
259+                 rhs =  dot (cs, new_z) +  initial
260+                 push! (def, new_z=> zeros (N- M))
261+             else 
262+                 new_z =  only (@variables  $ new_z (iv)[1 : N- M, 1 : m])
263+                 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 )))
264+                 rhs =  coeff* sum (cs[i]* new_z[i, m] for  i in  1 : N- M)
265+                 for  (index, value) in  enumerate (initial)
266+                     rhs +=  value *  iv^ (index -  1 ) /  gamma (index)
267+                 end 
268+                 push! (def, new_z=> zeros (N- M, m))
269+             end 
270+             push! (new_eqs, new_eq)
271+         else 
272+             if  (α <  1 )  
273+                 rhs =  initial
274+                 for  index in  range (M, N- 1 ; step= 1 )
275+                     new_z =  Symbol (:ʐ , :_ , i)
276+                     i +=  1 
277+                     new_z =  ModelingToolkit. unwrap (only (@variables  $ new_z (iv)))
278+                     new_eq =  D (new_z) ~  sub_eq -  γ_i (index)* new_z
279+                     push! (new_eqs, new_eq)
280+                     push! (def, new_z=> 0 )
281+                     rhs +=  c_i (index)* new_z
282+                 end 
283+             else 
284+                 rhs =  0 
285+                 for  (index, value) in  enumerate (initial)
286+                     rhs +=  value *  iv^ (index -  1 ) /  gamma (index)
287+                 end 
288+                 for  index in  range (M, N- 1 ; step= 1 )
289+                     new_z =  Symbol (:ʐ , :_ , i)
290+                     i +=  1 
291+                     γ =  γ_i (index)
292+                     base =  sub_eq
293+                     for  k in  range (1 , m; step= 1 )
294+                         new_z =  Symbol (:ʐ , :_ , index- M, :_ , k)
295+                         new_z =  ModelingToolkit. unwrap (only (@variables  $ new_z (iv)))
296+                         new_eq =  D (new_z) ~  base -  γ* new_z
297+                         base =  k *  new_z
298+                         push! (new_eqs, new_eq)
299+                         push! (def, new_z=> 0 )
300+                     end 
301+                     rhs +=  coeff* c_i (index)* new_z
302+                 end 
303+             end 
304+         end 
305+         push! (new_eqs, sub_var ~  rhs)
306+         return  (new_eqs, def)
307+     end 
308+ 
309+     for  (eq, cur_var, alpha, init) in  zip (eqs, variables, alphas, initials)
310+         (new_eqs, def) =  fto_helper (eq, cur_var, alpha; initial= init)
311+         append! (all_eqs, new_eqs)
312+         append! (all_def, def)
313+     end 
314+     append! (all_eqs, additional_eqs)
315+     @named  sys =  System (all_eqs, iv; defaults= all_def)
316+     return  mtkcompile (sys)
317+ end 
318+ 
319+ """ 
320+ Generates the system of ODEs to find solution to FDEs. 
321+ 
322+ Example: 
323+ 
324+ ```julia 
325+ @independent_variables t 
326+ @variables x_0(t) 
327+ D = Differential(t) 
328+ tspan = (0., 5000.) 
329+ 
330+ function expect(t) 
331+     return sqrt(2) * sin(t + pi/4) 
332+ end 
333+ 
334+ 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]) 
335+ prob = ODEProblem(sys, [], tspan) 
336+ sol = solve(prob, radau5(), abstol = 1e-5, reltol = 1e-5) 
337+ ``` 
338+ """ 
339+ function  linear_fractional_to_ordinary (
340+         degrees, coeffs, rhs, epsilon, T;
341+         initials =  0 , symbol =  :x , iv =  only (@independent_variables  t), matrix= false 
342+ )
343+     previous =  Symbol (symbol, :_ , 0 )
344+     previous =  ModelingToolkit. unwrap (only (@variables  $ previous (iv)))
345+     @variables  x_0 (iv)
346+     D =  Differential (iv)
347+     i =  0 
348+     all_eqs =  Equation[]
349+     all_def =  Pair[]
350+ 
351+     function  fto_helper (sub_eq, α)
352+         δ =  (gamma (α+ 1 ) *  epsilon)^ (1 / α)
353+         a =  pi / 2 * (1 - (1 - α)/ ((2 - α) *  log (epsilon^- 1 )))
354+         h =  2 * pi * a /  log (1  +  (2 / epsilon *  (cos (a))^ (α -  1 )))
355+ 
356+         x_sub =  (gamma (2 - α) *  epsilon)^ (1 / (1 - α))
357+         x_sup =  - log (gamma (1 - α) *  epsilon)
358+         M =  floor (Int, log (x_sub /  T) /  h)
359+         N =  ceil (Int, log (x_sup /  δ) /  h)
360+ 
361+         function  c_i (index)
362+             h *  sin (pi  *  α) /  pi  *  exp ((1 - α)* h* index)
363+         end 
364+ 
365+         function  γ_i (index)
366+             exp (h *  index)
367+         end 
368+ 
369+         new_eqs =  Equation[]
370+         def =  Pair[]
371+         if  matrix
372+             new_z =  Symbol (:ʐ , :_ , i)
373+             i +=  1 
374+             γs =  diagm ([γ_i (index) for  index in  M: N- 1 ])
375+             cs =  [c_i (index) for  index in  M: N- 1 ]
376+ 
377+             new_z =  only (@variables  $ new_z (iv)[1 : N- M])
378+             new_eq =  D (new_z) ~  - γs* new_z .+  sub_eq
379+             sum =  dot (cs, new_z)
380+             push! (def, new_z=> zeros (N- M))
381+             push! (new_eqs, new_eq)
382+         else 
383+             sum =  0 
384+             for  index in  range (M, N- 1 ; step= 1 )
385+                 new_z =  Symbol (:ʐ , :_ , i)
386+                 i +=  1 
387+                 new_z =  ModelingToolkit. unwrap (only (@variables  $ new_z (iv)))
388+                 new_eq =  D (new_z) ~  sub_eq -  γ_i (index)* new_z
389+                 push! (new_eqs, new_eq)
390+                 push! (def, new_z=> 0 )
391+                 sum +=  c_i (index)* new_z
392+             end 
393+         end 
394+         return  (new_eqs, def, sum)
395+     end 
396+ 
397+     for  i in  range (1 , ceil (Int, degrees[1 ]); step= 1 )
398+         new_x =  Symbol (symbol, :_ , i)
399+         new_x =  ModelingToolkit. unwrap (only (@variables  $ new_x (iv)))
400+         push! (all_eqs, D (previous) ~  new_x)
401+         push! (all_def, previous =>  initials[i])
402+         previous =  new_x
403+     end 
404+ 
405+     new_rhs =  - rhs
406+     for  (degree, coeff) in  zip (degrees, coeffs)
407+         rounded =  ceil (Int, degree)
408+         new_x =  Symbol (symbol, :_ , rounded)
409+         new_x =  ModelingToolkit. unwrap (only (@variables  $ new_x (iv)))
410+         if  isinteger (degree)
411+             new_rhs +=  coeff *  new_x
412+         else 
413+             (new_eqs, def, sum) =  fto_helper (new_x, rounded -  degree)
414+             append! (all_eqs, new_eqs)
415+             append! (all_def, def)
416+             new_rhs +=  coeff *  sum
417+         end 
418+     end 
419+     push! (all_eqs, 0  ~  new_rhs)
420+     @named  sys =  System (all_eqs, iv; defaults= all_def)
421+     return  mtkcompile (sys)
422+ end 
423+ 
188424""" 
189425    change_independent_variable( 
190426        sys::System, iv, eqs = []; 
0 commit comments