Integral Transforms - New Features in Maple 2020 - Maplesoft

What's New in Maple 2020

Integral Tranforms

Integral transforms are special integrals that appear frequently in mathematical physics and that have remarkable properties.  For Maple 2020, the implementation of these integrals has been extended in several ways, making them more useful for a variety of applications, including computing integrals, finding exact solutions to PDEs with boundary conditions (see What's New in ODEs and PDEs). Improvements include the option to compute derivatives, numeric support, an alternate definition of the Hankel transform, and the ability to compute more transforms.

As background, these integrals are represented by the commands of the inttrans package: 

> with(inttrans);
 

[addtable, fourier, fouriercos, fouriersin, hankel, hilbert, invfourier, invhilbert, invlaplace, invmellin, laplace, mellin, savetable, setup] (1)
 

Three of these commands, addtable, savetable, and setup (new as of Maple 2020) are "administrative" commands, while the others are computational representations for definite integrals. For example, 

> FunctionAdvisor(integral_form, fourier);
 

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (2)
 

> FunctionAdvisor(integral_form, mellin);
 

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (3)
 

For all integral transform commands, the first argument is the integrand, the second one is the dummy integration variable of a definite integral and the third one is the evaluation point (also called transform variable).  


Compute derivatives: yes or no. 

Generally speaking, in computer algebra, "given a function f(x); , the input diff(f(x), x); should return the derivative of f(x); ". For the purpose of using integral transforms to solve differential equations, however, the implementation in previous Maple releases worked in the opposite direction: if you were to input the result of the derivative, you would receive the derivative representation. For example, to the input laplace(`+`(`-`(`*`(t, `*`(f(t))))), t, s); you would receive `/`(`*`(d, `*`(laplace(f(t), t, s))), `*`(ds)); . To extend the capabilities of the system and have the best result in any scenario, a new command, setup, has been added to the package, so that you can set whether or not to compute derivatives, and the default has been changed to computederivatives = true while the previous behavior is obtained only if you input setup(computederivatives = false); . To query about the status of this new setting enter 

 

> setup(computederivatives);
 

computederivatives = true (1.1)
 

and so differentiating returns the derivative computed 

> (%diff = diff)(laplace(f(t), t, s), s);
 

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (1.2)
 

while changing this setting to work as in previous releases you have this computation reversed: you input the output (%diff = diff)(laplace(f(t), t, s), s); and you get the corresponding input 

> setup(computederivatives = false);
 

computederivatives = false (1.3)
 

> %diff(laplace(f(t), t, s), s) = `+`(`-`(laplace(`*`(t, `*`(f(t))), t, s)));
 

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (1.4)
 

Reset the value of computederivatives 

> setup(computederivatives = true);
 

computederivatives = true (1.5)
 

> %diff(laplace(f(t), t, s), s) = `+`(`-`(laplace(`*`(t, `*`(f(t))), t, s)));
 

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (1.6)
 

In summary: by default, derivatives of all the 11 integral transforms are now computed. This setting can be changed any time you want within a Maple session without restarting, and changing it does not have any impact on the performance of intsolve, dsolve and pdsolve to solve differential equations using integral transforms. 

Numerical evaluation 

In previous releases, integral transforms had no numerical evaluation implemented. This is in the process of changing. So, for example, to numerically evaluate the inverse laplace transform (invlaplace command), three different algorithms have been implemented: Gaver-Stehfest, Talbot and Euler, following the presentation by Abate and Whitt, "Unified Framework for Numerically Inverting Laplace Transforms", INFORMS Journal on Computing 18(4), pp. 408-421, 2006. 

For example, consider the exact solution to this partial differential equation subject to initial and boundary conditions 

> pde := diff(u(x, t), x) = `+`(`*`(4, `*`(diff(u(x, t), t, t)))); -1
 

> iv := u(x, 0) = 0, u(0, t) = 1; -1

 

Note that these two conditions are not entirely compatible: the solution returned cannot be valid for x = 0; and t = 0; simultaneously. However, a solution discarding that point does exist and is given by 

> sol := pdsolve([pde, iv]);
 

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (2.1)
 

Verifying the solution, one condition remains to be tested 

> pdetest(sol, [pde, iv]);
 

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mn( (2.2)
 

Since we now have numerical evaluation rules, we can test that what looks different from 0 in the above is actually 0. 

> zero := [0, 0, `+`(`-`(invlaplace(`/`(`*`(exp(`+`(`-`(`*`(`/`(1, 2), `*`(`^`(s, `/`(1, 2)), `*`(t))))))), `*`(s)), s, 0)))][-1];
 

Typesetting:-mrow(Typesetting:-mo( (2.3)
 

Add a small number to the initial value of t to skip the point t = 0; -1 

> plot(zero, t = `^`(10, -10) .. 1);
 

Plot_2d
 

The default method used is the method of Euler sums and the numerical evaluation is performed as usual using the evalf command. For example, consider 

> F := sin(sqrt(`+`(`*`(2, `*`(t)))));
 

Typesetting:-mprintslash([F := sin(`*`(`^`(2, `/`(1, 2)), `*`(`^`(t, `/`(1, 2)))))], [sin(`*`(`^`(2, `/`(1, 2)), `*`(`^`(t, `/`(1, 2)))))]) (2.4)
 

 

The Laplace transform of F is given by 

> LT := laplace(F, t, s);
 

Typesetting:-mprintslash([LT := `+`(`/`(`*`(`/`(1, 2), `*`(`^`(2, `/`(1, 2)), `*`(`^`(Pi, `/`(1, 2)), `*`(exp(`+`(`-`(`/`(`*`(`/`(1, 2)), `*`(s))))))))), `*`(`^`(s, `/`(3, 2)))))], [`+`(`/`(`*`(`/`(1,... (2.5)
 

and the inverse Laplace transform of LT in inert form is 

> ILT := %invlaplace(LT, s, t);
 

Typesetting:-mrow(Typesetting:-mi( (2.6)
 

Since by construction ILT = F; , at t = 1; we have 

> eval(ILT = F, t = 1);
 

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (2.7)
 

This inert form on the left-hand side is numerically evaluated next, directly, without symbolically resolving it to be equal to sin(sqrt(2)); . The result of both sides is consistent: 

> evalf(%invlaplace(`+`(`/`(`*`(`/`(1, 2), `*`(`^`(2, `/`(1, 2)), `*`(`^`(Pi, `/`(1, 2)), `*`(exp(`+`(`-`(`/`(`*`(`/`(1, 2)), `*`(s))))))))), `*`(`^`(s, `/`(3, 2))))), s, 1) = sin(`*`(`^`(2, `/`(1, 2)))...
 

.9877659460 = .9877659459 (2.8)
 

In addition to the standard use of evalf to numerically evaluate inverse Laplace transforms, one can invoke each of the three different methods implemented using the MathematicalFunctions:-Evalf command 

> with(MathematicalFunctions, Evalf);
 

[Evalf] (2.9)
 

> Evalf(lhs(%invlaplace(`+`(`/`(`*`(`/`(1, 2), `*`(`^`(2, `/`(1, 2)), `*`(`^`(Pi, `/`(1, 2)), `*`(exp(`+`(`-`(`/`(`*`(`/`(1, 2)), `*`(s))))))))), `*`(`^`(s, `/`(3, 2))))), s, 1) = sin(`*`(`^`(2, `/`(1, ...
 

.9877659460 (2.10)
 

> MathematicalFunctions:-Evalf(lhs(%invlaplace(`+`(`/`(`*`(`/`(1, 2), `*`(`^`(2, `/`(1, 2)), `*`(`^`(Pi, `/`(1, 2)), `*`(exp(`+`(`-`(`/`(`*`(`/`(1, 2)), `*`(s))))))))), `*`(`^`(s, `/`(3, 2))))), s, 1) =...
 

.9877659460 (2.11)
 

> MathematicalFunctions:-Evalf(lhs(%invlaplace(`+`(`/`(`*`(`/`(1, 2), `*`(`^`(2, `/`(1, 2)), `*`(`^`(Pi, `/`(1, 2)), `*`(exp(`+`(`-`(`/`(`*`(`/`(1, 2)), `*`(s))))))))), `*`(`^`(s, `/`(3, 2))))), s, 1) =...
 

.9877659460 (2.12)
 

Regarding the method we use by default: from a numerical experiment with varied problems, we have concluded that our implementation of the Euler (sums) method is faster and more accurate than the other two. 

Two Hankel transform definitions 


In previous Maple releases, the definition of the Hankel transform was given by
 

hankel(f(t), t, s, nu) = Int(`*`(f(t), `*`(sqrt(`*`(s, `*`(t))), `*`(BesselJ(nu, `*`(s, `*`(t)))))), t = 0 .. infinity);  

where BesselJ(nu, `*`(s, `*`(t))); is the BesselJ(nu, `*`(s, `*`(t))); function. This definition, sometimes called alternative definition of the Hankel transform, has the advantage of having a large table of transforms presented in the literature (ref.[1]) but has the inconvenience of the square root sqrt(`*`(s, `*`(t))); in the integrand, complicating the form of the Hankel transform for the Laplacian in cylindrical coordinates. On the other hand, the other definition in the literature,
 

hankel(f(t), t, s, nu) = Int(`*`(f(t), `*`(t, `*`(BesselJ(nu, `*`(s, `*`(t)))))), t = 0 .. infinity);  

has the advantage that, with it, the Hankel transform of `+`(diff(u(r, t), r, r), `/`(`*`(diff(u(r, t), r)), `*`(r)), diff(u(r, t), t, t)); is given by the simple ODE form `+`(`/`(`*`(`^`(d, 2), `*`(`ℋ`(k, t))), `*`(`^`(dt, 2))), `-`(`*`(`^`(k, 2), `*`(`ℋ`(k, t))))); . Several other transforms also acquire a simpler form. So for Maple 2020 we added an algorithm that takes formulas for one definition and transforms them into formulas for the other definition, and have aligned Maple with this simpler definition (no sqrt(`*`(s, `*`(t))); in the integrand), while keeping the previous definition as an alternative.  

 

Hence, by default, when you load the inttrans package, the new definition in use for the Hankel transform is 

> hankel(f(t), t, s, nu); -1; % = convert(%, Int)
 

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (3.1)
 

You can change this default so that Maple works with the alternative definition as in previous releases.  For that purpose, use the new inttrans:-setup command (which you can also use to query about the definition in use at any moment): 

> setup(alternativehankeldefinition);
 

alternativehankeldefinition = false (3.2)
 

The change in the default definition implemented in Maple 2020 is automatically taken into account by other parts of the Maple library using the Hankel transform. For example, the differentiation rule with the new definition is 

> (%diff = diff)(hankel(f(t), t, z, nu), z);
 

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (3.3)
 

This differentiation rule resembles (is connected to) the differentiation rule for BesselJ, and this is another advantage of the new definition. 

> (%diff = diff)(BesselJ(nu, z), z);
 

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (3.4)
 

Furthermore, several transforms have acquired a simpler form, as for example:

> `assuming`([(%hankel = hankel)(`/`(`*`(exp(`*`(I, `*`(a, `*`(r))))), `*`(r)), r, k, 0)], [`>`(a, 0), `<`(k, a)]);
 

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (3.5)
 

Let's compare: make the definition be as in previous releases. 

> setup(alternativehankeldefinition = true);
 

alternativehankeldefinition = true (3.6)
 

> hankel(f(t), t, s, nu); -1; % = convert(%, Int)
 

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (3.7)
 

The differentiation rule with the previous (alternative) definition was not as simple: 

> (%diff = diff)(hankel(f(t), t, s, nu), s);
 

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (3.8)
 

And the transform `assuming`([(%hankel = hankel)(`/`(`*`(exp(`*`(I, `*`(a, `*`(r))))), `*`(r)), r, k, 0)], [`>`(a, 0), `<`(k, a)]); was also not so simple: 

> `assuming`([(%hankel = hankel)(`/`(`*`(exp(`*`(I, `*`(a, `*`(r))))), `*`(r)), r, k, 0)], [`>`(a, 0), `<`(k, a)]);
 

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (3.9)
 

Reset to the new default value of the definition. 

> setup(alternativehankeldefinition = false);
 

alternativehankeldefinition = false (3.10)
 

> hankel(f(t), t, s, nu); -1; % = convert(%, Int)
 

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (3.11)
 

References 

[1] Oberhettinger Fritz, Tables of Bessel Transforms. Springer Verlag, 1972. 

 

More integral transform results 

 

Maple is now able to compute more transforms. For example, for the Hankel transform, consider the operators 

> `D/t` := proc (u) options operator, arrow; `/`(`*`(diff(u, t)), `*`(t)) end proc; -1formula_plus := `*`(`^`(t, `+`(`-`(nu))), `*`((`@@`(`D/t`, m))(`*`(`^`(t, `+`(m, nu)), `*`(u(t)))))); -1formula_minus := `*`(`^`(t, nu), `*`((`@@`(`D/t`, m))(`*`(`^`(t, `+`(m, `-`(nu))), `*`(u(t)))))); -1

 

Being able to transform these operators into algebraic expressions or differential equations of lower order is key for solving ODE and PDE problems with Boundary Conditions. To illustrate that, set computederivatives = false; , a more convenient setting to use transforms to simplify differential equations, and insert some values in formula_minus 

> setup(computederivatives = false); 1
 

computederivatives = false (4.1)
 

> simplify(eval(formula_minus, [nu = 6, m = 3]));
 

Typesetting:-mprintslash([`/`(`*`(`+`(`*`(diff(u(t), `$`(t, 3)), `*`(`^`(t, 3))), `-`(`*`(12, `*`(diff(u(t), `$`(t, 2)), `*`(`^`(t, 2))))), `*`(57, `*`(diff(u(t), t), `*`(t))), `-`(`*`(105, `*`(u(t)))... (4.2)
 

Its Hankel transform is 

> hankel(`/`(`*`(`+`(`*`(diff(diff(diff(u(t), t), t), t), `*`(`^`(t, 3))), `-`(`*`(12, `*`(diff(diff(u(t), t), t), `*`(`^`(t, 2))))), `*`(57, `*`(diff(u(t), t), `*`(t))), `-`(`*`(105, `*`(u(t)))))), `*`...
 

Typesetting:-mrow(Typesetting:-mo( (4.3)
 

An example with formula_plus: 

> simplify(eval(formula_plus, [nu = 7, m = 4]));
 

Typesetting:-mprintslash([`/`(`*`(`+`(`*`(diff(u(t), `$`(t, 4)), `*`(`^`(t, 4))), `*`(38, `*`(diff(u(t), `$`(t, 3)), `*`(`^`(t, 3)))), `*`(477, `*`(diff(u(t), `$`(t, 2)), `*`(`^`(t, 2)))), `*`(2295, `... (4.4)
 

> hankel(`/`(`*`(`+`(`*`(diff(diff(diff(diff(u(t), t), t), t), t), `*`(`^`(t, 4))), `*`(38, `*`(diff(diff(diff(u(t), t), t), t), `*`(`^`(t, 3)))), `*`(477, `*`(diff(diff(u(t), t), t), `*`(`^`(t, 2)))), ...
 

Typesetting:-mrow(Typesetting:-msup(Typesetting:-mi( (4.5)
 

Not just differential operators but also several new transforms are now computable 

> hankel(1, r, k, nu);
 

Typesetting:-mprintslash([PIECEWISE([`/`(`*`(Dirac(k)), `*`(k)), nu = 0], [`/`(`*`(nu), `*`(`^`(k, 2))), otherwise])], [piecewise(nu = 0, `/`(`*`(Dirac(k)), `*`(k)), `/`(`*`(nu), `*`(`^`(k, 2))))]) (4.6)
 

> hankel(`^`(r, m), r, k, nu);
 

Typesetting:-mprintslash([PIECEWISE([`/`(`*`(Dirac(k)), `*`(k)), And(nu = 0, m = 0)], [`/`(`*`(`^`(2, `+`(m, 1)), `*`(`^`(k, `+`(`-`(m), `-`(2))), `*`(GAMMA(`+`(1, `*`(`/`(1, 2), `*`(m)), `*`(`/`(1, 2... (4.7)
 

 

> mellin(log(abs(`/`(`*`(`+`(4, x)), `*`(`+`(x, `-`(3)))))), x, s);
 

`/`(`*`(Pi, `*`(csc(`*`(Pi, `*`(s))), `*`(`+`(16, `-`(`*`(9, `*`(cos(`*`(Pi, `*`(s)))))))))), `*`(s)) (4.8)
 

> `assuming`([fouriersin(ln(abs(`/`(`*`(`+`(a, x)), `*`(`+`(x, `-`(b)))))), x, y)], [`<`(0, a), `<`(0, b)]);
 

`/`(`*`(`^`(2, `/`(1, 2)), `*`(`+`(ln(`/`(`*`(a), `*`(b))), `*`(cos(`*`(b, `*`(y))), `*`(Ci(`*`(b, `*`(y))))), `-`(`*`(cos(`*`(a, `*`(y))), `*`(Ci(`*`(a, `*`(y)))))), `*`(sin(`*`(b, `*`(y))), `*`(Si(`... (4.9)
 

> `assuming`([fouriersin(`/`(`*`(ln(abs(`/`(`*`(`+`(a, x)), `*`(`+`(x, `-`(a))))))), `*`(`^`(x, 2))), x, y)], [`<`(0, a)]);
 

`/`(`*`(`^`(2, `/`(1, 2)), `*`(`^`(Pi, `/`(1, 2)), `*`(`+`(1, `-`(cos(`*`(a, `*`(y)))), `-`(`*`(a, `*`(y, `*`(Ssi(`*`(a, `*`(y))))))))))), `*`(a)) (4.10)
 

> `assuming`([fouriersin(`/`(`*`(ln(abs(`/`(`*`(`+`(`*`(`^`(a, 2)), `*`(`^`(x, 2)))), `*`(`+`(`-`(`*`(`^`(b, 2))), `*`(`^`(x, 2)))))))), `*`(x)), x, y)], [`<`(0, a), `<`(0, b)]);
 

`*`(`^`(2, `/`(1, 2)), `*`(`^`(Pi, `/`(1, 2)), `*`(`+`(Ci(`*`(b, `*`(y))), `-`(Ei(`+`(`-`(`*`(a, `*`(y)))))), `-`(ln(`/`(`*`(b), `*`(a)))))))) (4.11)
 

> `assuming`([fouriercos(`/`(`*`(ln(abs(`/`(`*`(`+`(a, x)), `*`(`+`(x, `-`(a))))))), `*`(x)), x, y)], [`<`(0, a)]);
 

`+`(`-`(`*`(`^`(2, `/`(1, 2)), `*`(`^`(Pi, `/`(1, 2)), `*`(Ssi(`*`(a, `*`(y)))))))) (4.12)