cosmotool/external/sharp/python/libsharp/tests/test_legendre.py

60 lines
1.7 KiB
Python

import numpy as np
from scipy.special import legendre
from scipy.special import p_roots
import libsharp
from numpy.testing import assert_allclose
def check_legendre_transform(lmax, ntheta):
l = np.arange(lmax + 1)
if lmax >= 1:
sigma = -np.log(1e-3) / lmax / (lmax + 1)
bl = np.exp(-sigma*l*(l+1))
bl *= (2 * l + 1)
else:
bl = np.asarray([1], dtype=np.double)
theta = np.linspace(0, np.pi, ntheta, endpoint=True)
x = np.cos(theta)
# Compute truth using scipy.special.legendre
P = np.zeros((ntheta, lmax + 1))
for l in range(lmax + 1):
P[:, l] = legendre(l)(x)
y0 = np.dot(P, bl)
# double-precision
y = libsharp.legendre_transform(x, bl)
assert_allclose(y, y0, rtol=1e-12, atol=1e-12)
# single-precision
y32 = libsharp.legendre_transform(x.astype(np.float32), bl)
assert_allclose(y, y0, rtol=1e-5, atol=1e-5)
def test_legendre_transform():
nthetas_to_try = [0, 9, 17, 19] + list(np.random.randint(500, size=20))
for ntheta in nthetas_to_try:
for lmax in [0, 1, 2, 3, 20] + list(np.random.randint(50, size=4)):
yield check_legendre_transform, lmax, ntheta
def check_legendre_roots(n):
xs, ws = ([], []) if n == 0 else p_roots(n) # from SciPy
xl, wl = libsharp.legendre_roots(n)
assert_allclose(xs, xl, rtol=1e-14, atol=1e-14)
assert_allclose(ws, wl, rtol=1e-14, atol=1e-14)
def test_legendre_roots():
"""
Test the Legendre root-finding algorithm from libsharp by comparing it with
the SciPy version.
"""
yield check_legendre_roots, 0
yield check_legendre_roots, 1
yield check_legendre_roots, 32
yield check_legendre_roots, 33
yield check_legendre_roots, 128