Implementation of the Struve H and L functions



I have done a first implementation of the Struve H and L functions.

These are examples of the implemented expansions for a half integral
positive or negative order. The expansion is done, if the flag
$besselexpand is T:

(%i14) struve_h(1/2,z),besselexpand:true;
(%o14) -(sqrt(2)*cos(z)-sqrt(2))/(sqrt(%pi)*sqrt(z))

(%i15) struve_h(3/2,z),besselexpand:true;
(%o15) -(2*z*sin(z)+2*cos(z)-z^2-2)/(sqrt(2)*sqrt(%pi)*z^(3/2))

(%i16) struve_h(-1/2,z),besselexpand:true;
(%o16) sqrt(2)*sin(z)/(sqrt(%pi)*sqrt(z))

(%i17) struve_l(1/2,z),besselexpand:true;
(%o17) (sqrt(2)*%i*sinh((2*z-%i*%pi)/2)-sqrt(2))/(sqrt(%pi)*sqrt(z))

(%i18) struve_l(3/2,z),besselexpand:true;
(%o18) -(2*z*sinh(z-%i*%pi)-2*cosh(z-%i*%pi)+z^2-2)
        /(sqrt(2)*sqrt(%pi)*z^(3/2))

(%i19) struve_l(-1/2,z),besselexpand:true;
(%o19) sqrt(2)*sinh(z)/(sqrt(%pi)*sqrt(z))

To get the most simple results for the Struve L function it would be
nice to implement simplifications like

   sinh(x-%i*%pi)   -> -sinh(x)
   sinh(x-%i*%pi/2) -> -%i*cosh(x)

A more general rule can be obtained with the help of the following
formula:

  sinh(a+b*%i) -> %i*cosh(a)*sin(b)+cos(b)*sinh(a)

This can be done for cosh function too. I will try a general extension
to the simplifier of sinh and cosh.

To get numerical values I have used the new hypergeometric code. It
works for real and complex values. These are examples in float precision
for the Struve H function:

(%i20) struve_h(1,0.5);
(%o20) .05217374424234107

(%i21) struve_h(2,0.5);
(%o21) .005242357780206454

(%i22) struve_h(-1,0.5);
(%o22) .5844460281252403

(%i23) struve_h(%i,0.5);
(%o23) .02150713707510154-.4749580292190993*%i

(%i24) struve_h(%i,0.5+%i);
(%o24) .09182387904255078*%i+.3491876143558979

One issue is, that the code of the hypergeometric package is not
autoloaded. I think, we should implement the autoload functionality of
the hypergeometric package too.

The derivatives are implemented in a way that we do not get a
singularity at z = 0:

(%i25) diff(struve_h(v,z),z);
(%o25) (z^v/(sqrt(%pi)*2^v*gamma(v+3/2))-struve_h(v
+1,z)+struve_h(v-1,z))/2

(%i26) diff(struve_l(v,z),z);
(%o26) (z^v/(sqrt(%pi)*2^v*gamma(v+3/2))+struve_l(v
+1,z)+struve_l(v-1,z))/2

Therefore, Struve H and L can be expanded with taylor at the point z=0:

(%i27) taylor(struve_h(v,z),z,0,3);
(%o27) struve_h(v,0)+(struve_h(v-1,0)-struve_h(v+1,0))*z/2
                    +(struve_h(v-2,0)-2*struve_h(v,0)+struve_h(v
+2,0))*z^2/8
                    +(struve_h(v-3,0)-3*struve_h(v-1,0)+3*struve_h(v
+1,0)
                                     -struve_h(v+3,0))
                     *z^3
                     /48

Dieter Kaiser