Skip to content

Commit b3d033c

Browse files
authored
Merge pull request #193 from astro-informatics/feature/gl_sampling
Feature/gl sampling
2 parents 8e111f4 + 43b2198 commit b3d033c

28 files changed

+251
-81
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ isolattitude sampling scheme. A number of sampling schemes are currently
5757
supported.
5858

5959
The equiangular sampling schemes of [McEwen & Wiaux
60-
(2012)](https://arxiv.org/abs/1110.6298) and [Driscoll & Healy
61-
(1995)](https://www.sciencedirect.com/science/article/pii/S0196885884710086)
60+
(2012)](https://arxiv.org/abs/1110.6298), [Driscoll & Healy
61+
(1995)](https://www.sciencedirect.com/science/article/pii/S0196885884710086)
62+
and [Gauss-Legendre (1986)](https://link.springer.com/article/10.1007/BF02519350)
6263
are supported, which exhibit associated sampling theorems and so
6364
harmonic transforms can be computed to machine precision. Note that the
6465
McEwen & Wiaux sampling theorem reduces the Nyquist rate on the sphere

docs/index.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ Algorithms |:zap:|
2121
``S2FFT`` leverages new algorithmic structures that can he highly parallelised and
2222
distributed, and so map very well onto the architecture of hardware accelerators (i.e.
2323
GPUs and TPUs). In particular, these algorithms are based on new Wigner-d recursions
24-
that are stable to high angular resolution :math:`L`. The diagram below illustrates the recursions (for further details see Price & McEwen 2023).
24+
that are stable to high angular resolution :math:`L`. The diagram below illustrates the
25+
recursions (for further details see Price & McEwen 2023).
2526

2627
.. image:: ./assets/figures/Wigner_recursion_github_docs.png
2728

@@ -46,7 +47,8 @@ Sampling |:earth_africa:|
4647

4748
The structure of the algorithms implemented in ``S2FFT`` can support any isolattitude sampling scheme. A number of sampling schemes are currently supported.
4849

49-
The equiangular sampling schemes of `McEwen & Wiaux (2012) <https://arxiv.org/abs/1110.6298>`_ and `Driscoll & Healy (1995) <https://www.sciencedirect.com/science/article/pii/S0196885884710086>`_ are supported, which exhibit associated sampling theorems and so harmonic transforms can be computed to machine precision. Note that the McEwen & Wiaux sampling theorem reduces the Nyquist rate on the sphere by a factor of two compared to the Driscoll & Healy approach, halving the number of spherical samples required.
50+
The equiangular sampling schemes of `McEwen & Wiaux (2012) <https://arxiv.org/abs/1110.6298>`_,
51+
`Driscoll & Healy (1995) <https://www.sciencedirect.com/science/article/pii/S0196885884710086>`_, and `Gauss-Legendre (1986) <https://link.springer.com/article/10.1007/BF02519350>`_ are supported, which exhibit associated sampling theorems and so harmonic transforms can be computed to machine precision. Note that the McEwen & Wiaux sampling theorem reduces the Nyquist rate on the sphere by a factor of two compared to the Driscoll & Healy approach, halving the number of spherical samples required.
5052

5153
The popular `HEALPix <https://healpix.jpl.nasa.gov>`_ sampling scheme (`Gorski et al. 2005 <https://arxiv.org/abs/astro-ph/0409513>`_) is also supported. The HEALPix sampling does not exhibit a sampling theorem and so the corresponding harmonic transforms do not achieve machine precision but exhibit some error. However, the HEALPix sampling provides pixels of equal areas, which has many practical advantages.
5254

requirements/requirements-core.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,7 @@ numpy>=1.20
33
colorlog
44
pyyaml
55
jax>=0.3.13
6-
jaxlib
6+
jaxlib
7+
8+
# Remove when subpackage functionality is fixed.
9+
torch

s2fft/_version.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# file generated by setuptools_scm
2+
# don't change, don't track in version control
3+
TYPE_CHECKING = False
4+
if TYPE_CHECKING:
5+
from typing import Tuple, Union
6+
VERSION_TUPLE = Tuple[Union[int, str], ...]
7+
else:
8+
VERSION_TUPLE = object
9+
10+
version: str
11+
__version__: str
12+
__version_tuple__: VERSION_TUPLE
13+
version_tuple: VERSION_TUPLE
14+
15+
__version__ = version = '1.0.1.dev12'
16+
__version_tuple__ = version_tuple = (1, 0, 1, 'dev12')

s2fft/base_transforms/spherical.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def inverse(
2727
spin (int, optional): Harmonic spin. Defaults to 0.
2828
2929
sampling (str, optional): Sampling scheme. Supported sampling schemes include
30-
{"mw", "mwss", "dh", "healpix"}. Defaults to "mw".
30+
{"mw", "mwss", "dh", "gl", "healpix"}. Defaults to "mw".
3131
3232
nside (int, optional): HEALPix Nside resolution parameter. Only required
3333
if sampling="healpix". Defaults to None.

s2fft/base_transforms/wigner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def inverse(
3333
L_lower (int, optional): Harmonic lower bound. Defaults to 0.
3434
3535
sampling (str, optional): Sampling scheme. Supported sampling schemes include
36-
{"mw", "mwss", "dh"}. Defaults to "mw".
36+
{"mw", "mwss", "dh", "gl"}. Defaults to "mw".
3737
3838
reality (bool, optional): Whether the signal on the sphere is real. If so,
3939
conjugate symmetry is exploited to reduce computational costs. Defaults to

s2fft/precompute_transforms/construct.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def spin_spherical_kernel(
3434
Defaults to False.
3535
3636
sampling (str, optional): Sampling scheme. Supported sampling schemes include
37-
{"mw", "mwss", "dh", "healpix"}. Defaults to "mw".
37+
{"mw", "mwss", "dh", "gl", "healpix"}. Defaults to "mw".
3838
3939
nside (int): HEALPix Nside resolution parameter. Only required
4040
if sampling="healpix".
@@ -106,7 +106,7 @@ def spin_spherical_kernel_jax(
106106
Defaults to False.
107107
108108
sampling (str, optional): Sampling scheme. Supported sampling schemes include
109-
{"mw", "mwss", "dh", "healpix"}. Defaults to "mw".
109+
{"mw", "mwss", "dh", "gl", "healpix"}. Defaults to "mw".
110110
111111
nside (int): HEALPix Nside resolution parameter. Only required
112112
if sampling="healpix".
@@ -185,7 +185,7 @@ def wigner_kernel(
185185
Defaults to False.
186186
187187
sampling (str, optional): Sampling scheme. Supported sampling schemes include
188-
{"mw", "mwss", "dh", "healpix"}. Defaults to "mw".
188+
{"mw", "mwss", "dh", "gl", "healpix"}. Defaults to "mw".
189189
190190
nside (int): HEALPix Nside resolution parameter. Only required
191191
if sampling="healpix".
@@ -258,7 +258,7 @@ def wigner_kernel_jax(
258258
Defaults to False.
259259
260260
sampling (str, optional): Sampling scheme. Supported sampling schemes include
261-
{"mw", "mwss", "dh", "healpix"}. Defaults to "mw".
261+
{"mw", "mwss", "dh", "gl", "healpix"}. Defaults to "mw".
262262
263263
nside (int): HEALPix Nside resolution parameter. Only required
264264
if sampling="healpix".

s2fft/precompute_transforms/spherical.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def inverse(
3232
kernel (np.ndarray, optional): Wigner-d kernel. Defaults to None.
3333
3434
sampling (str, optional): Sampling scheme. Supported sampling schemes include
35-
{"mw", "mwss", "dh", "healpix"}. Defaults to "mw".
35+
{"mw", "mwss", "dh", "gl", "healpix"}. Defaults to "mw".
3636
3737
reality (bool, optional): Whether the signal on the sphere is real. If so,
3838
conjugate symmetry is exploited to reduce computational costs.
@@ -88,7 +88,7 @@ def inverse_transform(
8888
L (int): Harmonic band-limit.
8989
9090
sampling (str): Sampling scheme. Supported sampling schemes include
91-
{"mw", "mwss", "dh", "healpix"}.
91+
{"mw", "mwss", "dh", "gl", "healpix"}.
9292
9393
reality (bool, optional): Whether the signal on the sphere is real. If so,
9494
conjugate symmetry is exploited to reduce computational costs.
@@ -152,7 +152,7 @@ def inverse_transform_jax(
152152
L (int): Harmonic band-limit.
153153
154154
sampling (str): Sampling scheme. Supported sampling schemes include
155-
{"mw", "mwss", "dh", "healpix"}.
155+
{"mw", "mwss", "dh", "gl", "healpix"}.
156156
157157
reality (bool, optional): Whether the signal on the sphere is real. If so,
158158
conjugate symmetry is exploited to reduce computational costs.
@@ -277,7 +277,7 @@ def forward(
277277
kernel (np.ndarray, optional): Wigner-d kernel. Defaults to None.
278278
279279
sampling (str, optional): Sampling scheme. Supported sampling schemes include
280-
{"mw", "mwss", "dh", "healpix"}. Defaults to "mw".
280+
{"mw", "mwss", "dh", "gl", "healpix"}. Defaults to "mw".
281281
282282
reality (bool, optional): Whether the signal on the sphere is real. If so,
283283
conjugate symmetry is exploited to reduce computational costs.
@@ -333,7 +333,7 @@ def forward_transform(
333333
L (int): Harmonic band-limit.
334334
335335
sampling (str): Sampling scheme. Supported sampling schemes include
336-
{"mw", "mwss", "dh", "healpix"}.
336+
{"mw", "mwss", "dh", "gl", "healpix"}.
337337
338338
reality (bool, optional): Whether the signal on the sphere is real. If so,
339339
conjugate symmetry is exploited to reduce computational costs.
@@ -401,7 +401,7 @@ def forward_transform_jax(
401401
L (int): Harmonic band-limit.
402402
403403
sampling (str): Sampling scheme. Supported sampling schemes include
404-
{"mw", "mwss", "dh", "healpix"}.
404+
{"mw", "mwss", "dh", "gl", "healpix"}.
405405
406406
reality (bool, optional): Whether the signal on the sphere is real. If so,
407407
conjugate symmetry is exploited to reduce computational costs.

s2fft/precompute_transforms/wigner.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def inverse(
3232
kernel (np.ndarray, optional): Wigner-d kernel. Defaults to None.
3333
3434
sampling (str, optional): Sampling scheme. Supported sampling schemes include
35-
{"mw", "mwss", "dh", "healpix"}. Defaults to "mw".
35+
{"mw", "mwss", "dh", "gl", "healpix"}. Defaults to "mw".
3636
3737
reality (bool, optional): Whether the signal on the sphere is real. If so,
3838
conjugate symmetry is exploited to reduce computational costs.
@@ -89,7 +89,7 @@ def inverse_transform(
8989
N (int): Directional band-limit.
9090
9191
sampling (str): Sampling scheme. Supported sampling schemes include
92-
{"mw", "mwss", "dh", "healpix"}.
92+
{"mw", "mwss", "dh", "gl", "healpix"}.
9393
9494
reality (bool, optional): Whether the signal on the sphere is real. If so,
9595
conjugate symmetry is exploited to reduce computational costs.
@@ -150,7 +150,7 @@ def inverse_transform_jax(
150150
N (int): Directional band-limit.
151151
152152
sampling (str): Sampling scheme. Supported sampling schemes include
153-
{"mw", "mwss", "dh", "healpix"}.
153+
{"mw", "mwss", "dh", "gl", "healpix"}.
154154
155155
reality (bool, optional): Whether the signal on the sphere is real. If so,
156156
conjugate symmetry is exploited to reduce computational costs.
@@ -306,7 +306,7 @@ def forward(
306306
kernel (np.ndarray, optional): Wigner-d kernel. Defaults to None.
307307
308308
sampling (str, optional): Sampling scheme. Supported sampling schemes include
309-
{"mw", "mwss", "dh", "healpix"}. Defaults to "mw".
309+
{"mw", "mwss", "dh", "gl", "healpix"}. Defaults to "mw".
310310
311311
reality (bool, optional): Whether the signal on the sphere is real. If so,
312312
conjugate symmetry is exploited to reduce computational costs.
@@ -361,7 +361,7 @@ def forward_transform(
361361
N (int): Directional band-limit.
362362
363363
sampling (str): Sampling scheme. Supported sampling schemes include
364-
{"mw", "mwss", "dh", "healpix"}.
364+
{"mw", "mwss", "dh", "gl", "healpix"}.
365365
366366
reality (bool, optional): Whether the signal on the sphere is real. If so,
367367
conjugate symmetry is exploited to reduce computational costs.
@@ -442,7 +442,7 @@ def forward_transform_jax(
442442
N (int): Directional band-limit.
443443
444444
sampling (str): Sampling scheme. Supported sampling schemes include
445-
{"mw", "mwss", "dh", "healpix"}.
445+
{"mw", "mwss", "dh", "gl", "healpix"}.
446446
447447
reality (bool, optional): Whether the signal on the sphere is real. If so,
448448
conjugate symmetry is exploited to reduce computational costs.

s2fft/sampling/s2_samples.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def ntheta(L: int = None, sampling: str = "mw", nside: int = None) -> int:
1010
Defaults to None.
1111
1212
sampling (str, optional): Sampling scheme. Supported sampling schemes include
13-
{"mw", "mwss", "dh", "healpix"}. Defaults to "mw".
13+
{"mw", "mwss", "dh", "gl", "healpix"}. Defaults to "mw".
1414
1515
nside (int, optional): HEALPix Nside resolution parameter. Only required
1616
if sampling="healpix". Defaults to None.
@@ -31,7 +31,7 @@ def ntheta(L: int = None, sampling: str = "mw", nside: int = None) -> int:
3131
f"Sampling scheme sampling={sampling} with L={L} not supported"
3232
)
3333

34-
if sampling.lower() == "mw":
34+
if sampling.lower() in ["mw", "gl"]:
3535
return L
3636

3737
elif sampling.lower() == "mwss":
@@ -93,7 +93,7 @@ def nphi_equiang(L: int, sampling: str = "mw") -> int:
9393
L (int): Harmonic band-limit.
9494
9595
sampling (str, optional): Sampling scheme. Supported sampling schemes include
96-
{"mw", "mwss", "dh"}. Defaults to "mw".
96+
{"mw", "mwss", "dh", "gl"}. Defaults to "mw".
9797
9898
Raises:
9999
ValueError: HEALPix sampling scheme.
@@ -104,7 +104,7 @@ def nphi_equiang(L: int, sampling: str = "mw") -> int:
104104
int: Number of :math:`\phi` samples.
105105
"""
106106

107-
if sampling.lower() == "mw":
107+
if sampling.lower() in ["mw", "gl"]:
108108
return 2 * L - 1
109109

110110
elif sampling.lower() == "mwss":
@@ -129,7 +129,7 @@ def ftm_shape(L: int, sampling: str = "mw", nside: int = None) -> Tuple[int, int
129129
L (int): Harmonic band-limit.
130130
131131
sampling (str, optional): Sampling scheme. Supported sampling schemes include
132-
{"mw", "mwss", "dh", "healpix"}. Defaults to "mw".
132+
{"mw", "mwss", "dh", "gl", "healpix"}. Defaults to "mw".
133133
134134
nside (int, optional): HEALPix Nside resolution parameter.
135135
@@ -144,7 +144,7 @@ def ftm_shape(L: int, sampling: str = "mw", nside: int = None) -> Tuple[int, int
144144
if sampling.lower() in ["mwss", "healpix"]:
145145
return ntheta(L, sampling, nside), 2 * L
146146

147-
elif sampling.lower() in ["mw", "dh"]:
147+
elif sampling.lower() in ["mw", "dh", "gl"]:
148148
return ntheta(L, sampling, nside), 2 * L - 1
149149

150150
else:
@@ -203,14 +203,17 @@ def thetas(L: int = None, sampling: str = "mw", nside: int = None) -> np.ndarray
203203
Defaults to None.
204204
205205
sampling (str, optional): Sampling scheme. Supported sampling schemes include
206-
{"mw", "mwss", "dh", "healpix"}. Defaults to "mw".
206+
{"mw", "mwss", "dh", "gl", "healpix"}. Defaults to "mw".
207207
208208
nside (int, optional): HEALPix Nside resolution parameter. Only required
209209
if sampling="healpix". Defaults to None.
210210
211211
Returns:
212212
np.ndarray: Array of :math:`\theta` samples for given sampling scheme.
213213
"""
214+
if sampling.lower() == "gl":
215+
return np.flip(np.arccos(np.polynomial.legendre.leggauss(L)[0]))
216+
214217
t = np.arange(0, ntheta(L=L, sampling=sampling, nside=nside)).astype(np.float64)
215218

216219
return t2theta(t, L, sampling, nside)
@@ -228,7 +231,7 @@ def t2theta(
228231
Defaults to None.
229232
230233
sampling (str, optional): Sampling scheme. Supported sampling schemes include
231-
{"mw", "mwss", "dh", "healpix"}. Defaults to "mw".
234+
{"mw", "mwss", "dh", "gl", "healpix"}. Defaults to "mw".
232235
233236
nside (int, optional): HEALPix Nside resolution parameter. Only required
234237
if sampling="healpix". Defaults to None.
@@ -346,7 +349,7 @@ def phis_equiang(L: int, sampling: str = "mw") -> np.ndarray:
346349
L (int, optional): Harmonic band-limit.
347350
348351
sampling (str, optional): Sampling scheme. Supported equiangular sampling
349-
schemes include {"mw", "mwss", "dh"}. Defaults to "mw".
352+
schemes include {"mw", "mwss", "dh", "gl"}. Defaults to "mw".
350353
351354
Returns:
352355
np.ndarray: Array of :math:`\phi` samples for given sampling scheme.
@@ -365,7 +368,7 @@ def p2phi_equiang(L: int, p: int, sampling: str = "mw") -> np.ndarray:
365368
p (int): :math:`\phi` index.
366369
367370
sampling (str, optional): Sampling scheme. Supported equiangular sampling
368-
schemes include {"mw", "mwss", "dh"}. Defaults to "mw".
371+
schemes include {"mw", "mwss", "dh", "gl"}. Defaults to "mw".
369372
370373
Raises:
371374
ValueError: HEALPix sampling not support (only equiangular schemes supported).
@@ -376,7 +379,7 @@ def p2phi_equiang(L: int, p: int, sampling: str = "mw") -> np.ndarray:
376379
np.ndarray: :math:`\phi` sample(s) for given sampling scheme.
377380
"""
378381

379-
if sampling.lower() == "mw":
382+
if sampling.lower() in ["mw", "gl"]:
380383
return 2 * p * np.pi / (2 * L - 1)
381384

382385
elif sampling.lower() == "mwss":
@@ -431,7 +434,7 @@ def f_shape(L: int = None, sampling: str = "mw", nside: int = None) -> Tuple[int
431434
L (int, optional): Harmonic band-limit.
432435
433436
sampling (str, optional): Sampling scheme. Supported sampling schemes include
434-
{"mw", "mwss", "dh", "healpix"}. Defaults to "mw".
437+
{"mw", "mwss", "dh", "gl", "healpix"}. Defaults to "mw".
435438
436439
nside (int, optional): HEALPix Nside resolution parameter. Only required
437440
if sampling="healpix". Defaults to None.

0 commit comments

Comments
 (0)