5
$\begingroup$

I'm working with fractional derivatives, primarily Riemann-Liouville and Caputo derivatives. In these definitions n=Ceiling[\alpha], and a is chosen to be 0. They are defined as:

https://www.hindawi.com/journals/mpe/2014/238459/

https://www.hindawi.com/journals/mpe/2014/238459/

I implemented the Caputo fractional derivative on Sech[x] like so

derivC[q_, x_] := Module[{s=Ceiling[q]}, If[FractionalPart[q]==0, D[Sech[x], {x, s}], 1/Gamma[s-q] NIntegrate[Derivative[s][Sech][x-u] u^(s-q-1), {u,0,x}]]] 

Inside the integrand we change variables x->t in accordance with the definition then x-t->u for ease of computation. Inside the integrand we take an integer number of derivatives on Sech and then integrate with a power law. If the order of the derivative q is integer then it should reduce to an integer-order derivative. Then using NIntegrate I integrate up to a bound x that's a real number because it is given by the function wrapper.

Whew! Long backstory.

The problem with implementing the Riemann-Liouville derivative though is that you take the integer number of derivatives outside of the integral. Since I'm using NIntegrate I only have numbers, not a function, which would make the derivative 0.

I do not know of a way to implement this. Any help or hints or suggestions are appreciated.

$\endgroup$
2

1 Answer 1

8
$\begingroup$

To obtain derivatives of a numerical integral, one can try inactivating the integral, then differentiate, then activate. For example:

Inactive[NIntegrate][(x-ξ)^n f[ξ], {ξ, 0, x}]; D[%, x] 

0^n f[x] + Inactive[NIntegrate][n (x - ξ)^(-1 + n) f[ξ], {ξ, 0, x}]

The problem with this approach is that in your application, $n<0$, and so differentiating this form of the integral is not useful. However, I again suggest that you transform the integration variable $\xi \to x - u$. Then:

Inactive[NIntegrate][u^n f[x-u], {u, 0, x}]; D[%, x] 

x^n f[0] + Inactive[NIntegrate][u^n Derivative1[f][-u + x], {u, 0, x}]

This version doesn't suffer from fatal divide by 0 issues. We can package up the above ideas into a function:

RLDerivative[α_][f_] := With[{s = 1/Gamma[Ceiling[α]-α]}, RLFunction[ α, f, Function[{x,ϵ}, Evaluate @ D[ s Inactive[NIntegrate][u^(Ceiling[α]-α-1)f[x-u], {u, 0, ϵ I, x}], {x, Ceiling[α]} ] ] ] ] RLFunction[α_, f_, func_][x_?NumericQ] := Replace[ Quiet @ Check[Activate[func[x,0]], $Failed],	$Failed :> (Message[RLFunction::ipath]; Activate[func[x, .1]]) ] RLFunction::ipath = "Unable to achieve convergence along the real axis. Integral path was deformed"; 

First note that I changed the path of integration to include $i \epsilon$. The default is to use $\epsilon =0$. However, there can be situations where the numerical integral doesn't converge. In that case, deforming the path of the integral can avoid this convergence issue. One down side is that using a complex path can introduce a spurious machine epsilon imaginary part. The other issue is the function under consideration may have a pole near $i \epsilon$ which will cause the deformed path integration to return an incorrect result.

Next, I split up the computation into two pieces. RLDerivative[α][f] will return an RLFunction object that can be applied to x values. This way the derivative of the inactive NIntegrate object only needs to be done once.

With those caveats mentioned, let's see how it works. First a test case that can be performed exactly:

int[n_, x_] = Integrate[(x-ξ)^n Exp[ξ], {ξ, 0, x}]; rlexp[α_, x_] := 1/Gamma[Ceiling[α]-α] D[int[Ceiling[α]-α-1, \[FormalX]], {\[FormalX], Ceiling[α]}]/. \[FormalX]->x 

Now, compare RLDerivative with the exact rlexp:

rf = RLDerivative[.9][Exp]; rf /@ Range[5] rlexp[.9, Range[5]//N] rf = RLDerivative[12.2][Exp]; rf /@ Range[5] rlexp[12.2, Range[5]//N] 

{2.75781, 7.40346, 20.0932, 54.603, 148.416}

{2.75781, 7.40346, 20.0932, 54.603, 148.416}

{1.12015*10^7, 2211.05, 34.6723, 55.0066, 148.438}

{1.12015*10^7, 2211.05, 34.6723, 55.0066, 148.438}

Now, for an example where the default integral path has convergence issues:

rf = RLDerivative[.9][Sin]; rf[.9] 

RLFunction::ipath: Unable to achieve convergence along the real axis. Integral path was deformed

0.698049 + 2.99218*10^-14 I

Notice the warning message and the appearance of the small imaginary part resulting from the deformed path. Finally, the RLFunction looks like:

RLDerivative[1.9][Sin] (* RLFunction[1.9, Sin, Function[{x$, ϵ$}, 0.105114 (1/x$^0.9 + Inactive[NIntegrate][Sin[u - x$]/u^0.9, {u, 0, I ϵ$, x$}])]] *) 

This looks a bit ugly, so here is a MakeBoxes rules for RLFunction, intended to mimic the standard M11 appearance of summary boxes for these types of functions:

RLFunction /: MakeBoxes[RLFunction[a_, f_, _], StandardForm] := RowBox[{ "FractionalDerivative","[", PanelBox[ RowBox[{ ToBoxes @ Plot[ f[x], {x,0,1}, Axes->False,Frame->True,FrameTicks->None, AspectRatio->1,ImageSize->20 ], "\" Order:\"", MakeBoxes[a,TraditionalForm] }], Background->GrayLevel[.95] ], "]" }] 

Now, the RLFunction format hides the gory details:

RLDerivative[1.9][Sin] 

enter image description here

$\endgroup$
2
  • $\begingroup$ A couple comments: 1. I don't think negative values for α work properly. 2. Functions with an integrable singularity at the origin won't work with this method. I could fix both issues with a bit of time. $\endgroup$ Commented Jun 8, 2017 at 2:57
  • $\begingroup$ What a nice answer! $\endgroup$ Commented Jun 8, 2017 at 6:18

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.