Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit 03e076a

Browse files
committed
16221: implement Struve H/L functions
1 parent b3f1223 commit 03e076a

File tree

2 files changed

+204
-1
lines changed

2 files changed

+204
-1
lines changed

src/sage/functions/all.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
from transcendental import (zeta, zetaderiv, zeta_symmetric, hurwitz_zeta,
2828
dickman_rho)
2929

30-
from sage.functions.bessel import (bessel_I, bessel_J, bessel_K, bessel_Y, Bessel)
30+
from sage.functions.bessel import (bessel_I, bessel_J, bessel_K, bessel_Y,
31+
Bessel, struve_H, struve_L)
3132

3233
from special import (hypergeometric_U,
3334
spherical_bessel_J, spherical_bessel_Y,

src/sage/functions/bessel.py

+202
Original file line numberDiff line numberDiff line change
@@ -1666,3 +1666,205 @@ def plot(self,a,b):
16661666
f = lambda z: _bessel_Y(nu,z,s)
16671667
P = plot(f,a,b)
16681668
return P
1669+
1670+
class Function_Struve_H(BuiltinFunction):
1671+
r"""
1672+
The Struve functions, solutions to the non-homogeneous Bessel differential equation:
1673+
1674+
.. math::
1675+
1676+
x^2\frac{d^2y}{dx^2}+x\frac{dy}{dx}+(x^2-\alpha^2)y=\frac{4\bigl(\frac{x}{2}\bigr)^{\alpha+1}}{\sqrt\pi\Gamma(\alpha+\tfrac12)},
1677+
1678+
.. math::
1679+
1680+
\mathrm{H}_\alpha(x) = y(x)
1681+
1682+
EXAMPLES::
1683+
1684+
sage: struve_H(-1/2,x)
1685+
sqrt(2)*sqrt(1/(pi*x))*sin(x)
1686+
sage: struve_H(2,x)
1687+
struve_H(2, x)
1688+
sage: struve_H(1/2.,pi)
1689+
0.900316316157106
1690+
1691+
REFERENCES:
1692+
1693+
- Abramowitz and Stegun: Handbook of Mathematical Functions,
1694+
http://www.math.sfu.ca/~cbm/aands/
1695+
1696+
- http://en.wikipedia.org/wiki/Struve_function
1697+
"""
1698+
def __init__(self):
1699+
r"""
1700+
^ EXAMPLES::
1701+
1702+
sage: maxima("struve_h(n,x);").sage()
1703+
struve_H(n, x)
1704+
sage: struve_H(7/5,1)._maxima_()
1705+
struve_h(7/5,1)
1706+
"""
1707+
BuiltinFunction.__init__(self, 'struve_H', nargs=2,
1708+
conversions=dict(maple='StruveH',
1709+
mathematica='StruveH',
1710+
maxima='struve_h',
1711+
sympy='struveh'))
1712+
1713+
def _eval_(self, a, z):
1714+
"""
1715+
EXAMPLES::
1716+
1717+
sage: struve_H(0,0)
1718+
0
1719+
sage: struve_H(-1/2,x)
1720+
sqrt(2)*sqrt(1/(pi*x))*sin(x)
1721+
sage: struve_H(1/2,-1)
1722+
-sqrt(2)*sqrt(-1/pi)*(cos(1) - 1)
1723+
sage: struve_H(1/2,pi)
1724+
2*sqrt(2)/pi
1725+
sage: struve_H(2,x)
1726+
struve_H(2, x)
1727+
sage: struve_H(1/2.,pi)
1728+
0.900316316157106
1729+
sage: struve_H(1/2,pi).n(200)
1730+
0.9003163161571060695551991910...
1731+
"""
1732+
if a.is_zero() and z.is_zero():
1733+
return 0
1734+
if a == -Integer(1)/2:
1735+
from sage.functions.trig import sin
1736+
return sqrt(2/(pi*z)) * sin(z)
1737+
if a == Integer(1)/2:
1738+
from sage.functions.trig import cos
1739+
return sqrt(2/(pi*z)) * (1-cos(z))
1740+
if isinstance(a, Expression) or isinstance(z, Expression):
1741+
return None
1742+
if is_inexact(a) or is_inexact(z):
1743+
a, z = get_coercion_model().canonical_coercion(a, z)
1744+
return self._evalf_(a, z, parent(z))
1745+
return None
1746+
1747+
def _evalf_(self, a, z, parent=None, algorithm=None):
1748+
"""
1749+
EXAMPLES::
1750+
1751+
sage: struve_H(1/2.,pi)
1752+
0.900316316157106
1753+
"""
1754+
import mpmath
1755+
return mpmath_utils.call(mpmath.struveh, a, z, parent=parent)
1756+
1757+
def _derivative_(self, a, z, diff_param=None):
1758+
"""
1759+
EXAMPLES::
1760+
1761+
sage: diff(struve_H(3/2,x),x)
1762+
-1/2*sqrt(2)*sqrt(1/(pi*x))*(cos(x) - 1) + 1/16*sqrt(2)*x^(3/2)/sqrt(pi) - 1/2*struve_H(5/2, x)
1763+
"""
1764+
if diff_param == 0:
1765+
raise ValueError("cannot differentiate struve_H in the first parameter")
1766+
1767+
from sage.functions.other import sqrt, gamma
1768+
return (z**a/(sqrt(pi)*2**a*gamma(a+Integer(3)/Integer(2)))-struve_H(a+1,z)+struve_H(a-1,z))/2
1769+
1770+
def _print_latex_(self, a, z):
1771+
"""
1772+
sage: latex(struve_H(2,x))
1773+
H_{{2}}({x})
1774+
"""
1775+
return r"H_{{%s}}({%s})" % (a, z)
1776+
1777+
struve_H = Function_Struve_H()
1778+
1779+
class Function_Struve_L(BuiltinFunction):
1780+
r"""
1781+
The modified Struve functions.
1782+
1783+
.. math::
1784+
1785+
\mathrm{L}_\alpha(x) = -i\cdot e^{-\frac{i\alpha\pi}{2}}\cdot\mathrm{H}_\alpha(ix)
1786+
1787+
EXAMPLES::
1788+
1789+
sage: struve_L(2,x)
1790+
struve_L(2, x)
1791+
sage: struve_L(1/2.,pi)
1792+
4.76805417696286
1793+
sage: diff(struve_L(1,x),x)
1794+
1/3*x/pi - 1/2*struve_L(2, x) + 1/2*struve_L(0, x)
1795+
1796+
REFERENCES:
1797+
1798+
- Abramowitz and Stegun: Handbook of Mathematical Functions,
1799+
http://www.math.sfu.ca/~cbm/aands/
1800+
1801+
- http://en.wikipedia.org/wiki/Struve_function
1802+
"""
1803+
def __init__(self):
1804+
r"""
1805+
^ EXAMPLES::
1806+
1807+
sage: maxima("struve_l(n,x);").sage()
1808+
struve_L(n, x)
1809+
sage: struve_L(7/5,1)._maxima_()
1810+
struve_l(7/5,1)
1811+
"""
1812+
BuiltinFunction.__init__(self, 'struve_L', nargs=2,
1813+
conversions=dict(maple='StruveL',
1814+
mathematica='StruveL',
1815+
maxima='struve_l',
1816+
sympy='struvel'))
1817+
1818+
def _eval_(self, a, z):
1819+
"""
1820+
EXAMPLES::
1821+
1822+
sage: struve_L(0,0)
1823+
0
1824+
sage: struve_L(2,x)
1825+
struve_L(2, x)
1826+
sage: struve_L(1/2.,pi)
1827+
4.76805417696286
1828+
sage: struve_L(1/2,pi).n(200)
1829+
4.768054176962864289162484345...
1830+
"""
1831+
if a.is_zero() and z.is_zero():
1832+
return 0
1833+
if isinstance(a, Expression) or isinstance(z, Expression):
1834+
return None
1835+
if is_inexact(a) or is_inexact(z):
1836+
a, z = get_coercion_model().canonical_coercion(a, z)
1837+
return self._evalf_(a, z, parent(z))
1838+
return None
1839+
1840+
def _evalf_(self, a, z, parent=None, algorithm=None):
1841+
"""
1842+
EXAMPLES::
1843+
1844+
sage: struve_L(1/2.,pi)
1845+
4.76805417696286
1846+
"""
1847+
import mpmath
1848+
return mpmath_utils.call(mpmath.struvel, a, z, parent=parent)
1849+
1850+
def _derivative_(self, a, z, diff_param=None):
1851+
"""
1852+
EXAMPLES::
1853+
1854+
sage: diff(struve_L(1,x),x)
1855+
1/3*x/pi - 1/2*struve_L(2, x) + 1/2*struve_L(0, x)
1856+
"""
1857+
if diff_param == 0:
1858+
raise ValueError("cannot differentiate struve_L in the first parameter")
1859+
1860+
from sage.functions.other import sqrt, gamma
1861+
return (z**a/(sqrt(pi)*2**a*gamma(a+Integer(3)/Integer(2)))-struve_L(a+1,z)+struve_L(a-1,z))/2
1862+
1863+
def _print_latex_(self, a, z):
1864+
"""
1865+
sage: latex(struve_L(2,x))
1866+
L_{{2}}({x})
1867+
"""
1868+
return r"L_{{%s}}({%s})" % (a, z)
1869+
1870+
struve_L = Function_Struve_L()

0 commit comments

Comments
 (0)