_ellip_harm.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. import numpy as np
  2. from ._ufuncs import _ellip_harm
  3. from ._ellip_harm_2 import _ellipsoid, _ellipsoid_norm
  4. def ellip_harm(h2, k2, n, p, s, signm=1, signn=1):
  5. r"""
  6. Ellipsoidal harmonic functions E^p_n(l)
  7. These are also known as Lamé functions of the first kind, and are
  8. solutions to the Lamé equation:
  9. .. math:: (s^2 - h^2)(s^2 - k^2)E''(s)
  10. + s(2s^2 - h^2 - k^2)E'(s) + (a - q s^2)E(s) = 0
  11. where :math:`q = (n+1)n` and :math:`a` is the eigenvalue (not
  12. returned) corresponding to the solutions.
  13. Parameters
  14. ----------
  15. h2 : float
  16. ``h**2``
  17. k2 : float
  18. ``k**2``; should be larger than ``h**2``
  19. n : int
  20. Degree
  21. s : float
  22. Coordinate
  23. p : int
  24. Order, can range between [1,2n+1]
  25. signm : {1, -1}, optional
  26. Sign of prefactor of functions. Can be +/-1. See Notes.
  27. signn : {1, -1}, optional
  28. Sign of prefactor of functions. Can be +/-1. See Notes.
  29. Returns
  30. -------
  31. E : float
  32. the harmonic :math:`E^p_n(s)`
  33. See Also
  34. --------
  35. ellip_harm_2, ellip_normal
  36. Notes
  37. -----
  38. The geometric interpretation of the ellipsoidal functions is
  39. explained in [2]_, [3]_, [4]_. The `signm` and `signn` arguments control the
  40. sign of prefactors for functions according to their type::
  41. K : +1
  42. L : signm
  43. M : signn
  44. N : signm*signn
  45. .. versionadded:: 0.15.0
  46. References
  47. ----------
  48. .. [1] Digital Library of Mathematical Functions 29.12
  49. https://dlmf.nist.gov/29.12
  50. .. [2] Bardhan and Knepley, "Computational science and
  51. re-discovery: open-source implementations of
  52. ellipsoidal harmonics for problems in potential theory",
  53. Comput. Sci. Disc. 5, 014006 (2012)
  54. :doi:`10.1088/1749-4699/5/1/014006`.
  55. .. [3] David J.and Dechambre P, "Computation of Ellipsoidal
  56. Gravity Field Harmonics for small solar system bodies"
  57. pp. 30-36, 2000
  58. .. [4] George Dassios, "Ellipsoidal Harmonics: Theory and Applications"
  59. pp. 418, 2012
  60. Examples
  61. --------
  62. >>> from scipy.special import ellip_harm
  63. >>> w = ellip_harm(5,8,1,1,2.5)
  64. >>> w
  65. 2.5
  66. Check that the functions indeed are solutions to the Lamé equation:
  67. >>> import numpy as np
  68. >>> from scipy.interpolate import UnivariateSpline
  69. >>> def eigenvalue(f, df, ddf):
  70. ... r = (((s**2 - h**2) * (s**2 - k**2) * ddf
  71. ... + s * (2*s**2 - h**2 - k**2) * df
  72. ... - n * (n + 1)*s**2*f) / f)
  73. ... return -r.mean(), r.std()
  74. >>> s = np.linspace(0.1, 10, 200)
  75. >>> k, h, n, p = 8.0, 2.2, 3, 2
  76. >>> E = ellip_harm(h**2, k**2, n, p, s)
  77. >>> E_spl = UnivariateSpline(s, E)
  78. >>> a, a_err = eigenvalue(E_spl(s), E_spl(s,1), E_spl(s,2))
  79. >>> a, a_err
  80. (583.44366156701483, 6.4580890640310646e-11)
  81. """ # noqa: E501
  82. return _ellip_harm(h2, k2, n, p, s, signm, signn)
  83. _ellip_harm_2_vec = np.vectorize(_ellipsoid, otypes='d')
  84. def ellip_harm_2(h2, k2, n, p, s):
  85. r"""
  86. Ellipsoidal harmonic functions F^p_n(l)
  87. These are also known as Lamé functions of the second kind, and are
  88. solutions to the Lamé equation:
  89. .. math:: (s^2 - h^2)(s^2 - k^2)F''(s)
  90. + s(2s^2 - h^2 - k^2)F'(s) + (a - q s^2)F(s) = 0
  91. where :math:`q = (n+1)n` and :math:`a` is the eigenvalue (not
  92. returned) corresponding to the solutions.
  93. Parameters
  94. ----------
  95. h2 : float
  96. ``h**2``
  97. k2 : float
  98. ``k**2``; should be larger than ``h**2``
  99. n : int
  100. Degree.
  101. p : int
  102. Order, can range between [1,2n+1].
  103. s : float
  104. Coordinate
  105. Returns
  106. -------
  107. F : float
  108. The harmonic :math:`F^p_n(s)`
  109. See Also
  110. --------
  111. ellip_harm, ellip_normal
  112. Notes
  113. -----
  114. Lamé functions of the second kind are related to the functions of the first kind:
  115. .. math::
  116. F^p_n(s)=(2n + 1)E^p_n(s)\int_{0}^{1/s}
  117. \frac{du}{(E^p_n(1/u))^2\sqrt{(1-u^2k^2)(1-u^2h^2)}}
  118. .. versionadded:: 0.15.0
  119. Examples
  120. --------
  121. >>> from scipy.special import ellip_harm_2
  122. >>> w = ellip_harm_2(5,8,2,1,10)
  123. >>> w
  124. 0.00108056853382
  125. """
  126. with np.errstate(all='ignore'):
  127. return _ellip_harm_2_vec(h2, k2, n, p, s)
  128. def _ellip_normal_vec(h2, k2, n, p):
  129. return _ellipsoid_norm(h2, k2, n, p)
  130. _ellip_normal_vec = np.vectorize(_ellip_normal_vec, otypes='d')
  131. def ellip_normal(h2, k2, n, p):
  132. r"""
  133. Ellipsoidal harmonic normalization constants gamma^p_n
  134. The normalization constant is defined as
  135. .. math::
  136. \gamma^p_n=8\int_{0}^{h}dx\int_{h}^{k}dy
  137. \frac{(y^2-x^2)(E^p_n(y)E^p_n(x))^2}{\sqrt((k^2-y^2)(y^2-h^2)(h^2-x^2)(k^2-x^2)}
  138. Parameters
  139. ----------
  140. h2 : float
  141. ``h**2``
  142. k2 : float
  143. ``k**2``; should be larger than ``h**2``
  144. n : int
  145. Degree.
  146. p : int
  147. Order, can range between [1,2n+1].
  148. Returns
  149. -------
  150. gamma : float
  151. The normalization constant :math:`\gamma^p_n`
  152. See Also
  153. --------
  154. ellip_harm, ellip_harm_2
  155. Notes
  156. -----
  157. .. versionadded:: 0.15.0
  158. Examples
  159. --------
  160. >>> from scipy.special import ellip_normal
  161. >>> w = ellip_normal(5,8,3,7)
  162. >>> w
  163. 1723.38796997
  164. """
  165. with np.errstate(all='ignore'):
  166. return _ellip_normal_vec(h2, k2, n, p)