Still, this isn't a complete answer, but a stepfoward.
There're at least 3 issues:
The capability of Integrate
seems to be limited, in other words, InverseLaplaceTransform
seems to be targetedly optimized.
As noticed by bbgodfrey, the assumption t > 0
is important to make Integrate
work.
The r
in my il
function actually doesn't have any effect.
3rd item is worth elaborating. We know (OK, perhaps many of us don't know) Integrate
doesn't have Hold*
attribute:
Attributes@Integrate
(* {Protected, ReadProtected} *)
This means the arguments of Integrate
will be evaluated before going into Integrate
. Then guess what will happen on the r - I ∞
and r + I ∞
?:
{s, r - I ∞, r + I ∞}

Aha, the r
simply disappears! This feature isn't surprising, but easy to overlook.
To make the r
play a role in integration, we modify il
to the following:
ilfixed[f_, s_, t_, r_ : 10] :=
1/(2 π I) Integrate[
f Exp[s t] /. s -> s + r, {s, -I ∞, +I ∞},
Assumptions -> t > 0]
Since v13.3 ContourIntegrate
is introduced, we'll test one more approach:
ilnew[f_, s_, t_, r_ : 10] :=
1/(2 π I) ContourIntegrate[f Exp[s t],
s ∈ InfiniteLine[{r, 0}, {0, 1}], Assumptions -> t > 0]
Given that $\gamma$ (r
in code) is an arbitrary positive constant chosen so that the contour of integration lies to the right of all singularities for inverse Laplace transform, let's first check the singularities of ex
. Luckily FunctionSingularities
has been introduced in v12.2:
Grid[MapIndexed[{#2[[1]], N@Reduce[FunctionSingularities[#, s], s]} &, ex],
Frame -> All]

11th result looks a bit suspicious, let's check the ComplexPlot
for safety:
pic =
ParallelTable[
ComplexPlot[e, {s, -10 - 10 I, 10 + 10 I}, PlotLabel -> e], {e,
ex}]; // AbsoluteTiming
(* {545.658, Null} on 2-core laptop. *)
Grid[MapIndexed[{#2[[1]], #} &, pic]\[Transpose] // Map[Partition[#, 8] &] //
Transpose // Flatten[#, 1] &, Frame -> All]

OK, FindSingularities
indeed mis-calculates ex[[11]]
. From the analysis above, we know that, except for the special ex[[16]]
, a naive positive $\gamma$ (r
in code) should work in principle. Let's try it:
freeze = # -> Inactive@# & /@ {InverseLaplaceTransform, Integrate,
ContourIntegrate};
lst =
ParallelTable[{InverseLaplaceTransform[e, s, t], ilfixed[e, s, t, 0],
ilfixed[e, s, t], ilnew[e, s, t]} /. freeze, {e, ex}]; // AbsoluteTiming
(* {1245.389, Null} on 2-core laptop. *)
For comparison I've also calculated the integration on $\gamma=0$. The results are as follows:
typeset = Function[expr,
If[! FreeQ[expr, Inactive], "×", expr] /. _Piecewise :>
"Piecewise[…]", Listable];
Grid[Prepend[
MapIndexed[Prepend[#, #2[[1]]] &, typeset@lst] // FullSimplify[#, t > 0] &, {"",
"InverseLaplaceTransform", "γ = 0, Integrate", "γ = 10, Integrate",
"γ = 10, ContourIntegrate"}], Frame -> All]

As we can see, by moving the contour, Integrate
finds the correct answer for ex[[10]]
, and finds solutions for ex[[{4, 8, 14, 15}]]
, but it's not immediately clear if results for ex[[{8, 14}]]
are correct or not. Let's plot them as a quick test:
Prepend[MapThread[
Plot[#, {t, 0, 2}, WorkingPrecision -> 16,
PlotLabel -> #2] &, {lst[[#, {1, 3, 4}]], {InverseLaplaceTransform, Integrate,
ContourIntegrate}}], #] & /@ {8, 14}

As shown above, Integrate
doesn't handle ex[[8]]
properly, but the inverse transform of ex[[14]]
is correct.
To sum up, by setting $\gamma$ (r
in code) in correct way, we now manage to calculate the inverse transform with Integrate
for ex[[{1, 2, 4, 5, 6, 10, 14, 15}]]
. If we turn to ContourIntegrate
, we can further calculate inverse transform of ex[[{7, 8, 9}]]
.
Remark
It's a bit funny that for ex[[3]]
, even InverseLaplaceTransform
itself fails nowadays. By checking the legacy document, we can find this example has been removed in v12.2:
v12.1 document
v12.2 document
The assumption t > 0
isn't actually necessary for ContourIntegrate
.
Though owning the attribute HoldAll
, NIntegrate
suffers from the I ∞
issue, too. See this answer for more info.
The following should be a correct setup for calculating Laplace inversion of ex[[16]]
, but sadly it doesn't work at least for now:
ilnew2[f_, s_, t_, line_] :=
1/(2 π I) ContourIntegrate[f Exp[s t], s ∈ line, Assumptions -> t > 0]
ilnew2[ex[[16]], s, t, HalfLine[{{0, 0}, {1, 1}} + Threaded@{1, 0}]] -
ilnew2[ex[[16]], s, t,
HalfLine[{{0, 0}, {1, -1}} + Threaded@{1, 0}]] // AbsoluteTiming
(* ContourIntegrate returns unevaluated. *)
Integrate[]
, correct? $\endgroup$