Add support for Clenshaw-Curtis and Fejér second rule quadrature / sampling schemes#381
Add support for Clenshaw-Curtis and Fejér second rule quadrature / sampling schemes#381matt-graham wants to merge 42 commits into
Conversation
…larities in numpy forward transform
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #381 +/- ##
==========================================
+ Coverage 96.10% 96.37% +0.26%
==========================================
Files 34 34
Lines 3543 3612 +69
==========================================
+ Hits 3405 3481 +76
+ Misses 138 131 -7 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| elif sampling == "cc": | ||
| return 2 * n_theta - 2 | ||
| elif sampling == "f2": | ||
| return 2 * n_theta + 2 |
There was a problem hiding this comment.
@jasonmcewen I arrived at these by trial and error as I could not see the pattern in how the values for the other schemes was derived - if there some underlying relationship here it would be good to document. It might also be worth moving this to one of modules under s2fft.sampling
| @@ -1,5 +1,10 @@ | |||
| import numpy as np | |||
|
|
|||
| M_OFFSET_1_SCHEMES = frozenset(("mwss", "healpix", "cc", "f2")) | |||
There was a problem hiding this comment.
I am not sure if there is a more descriptive / explanatory name for what unites these schemes. I found that including cc and f2 in this set was required to get tests passing but this more by trial and error than due to having a strong handle on what property of schemes requires us to offset m indices like this.
There was a problem hiding this comment.
Related to whether number of
|
|
||
| sampling (str, optional): Sampling scheme. Supported sampling schemes include | ||
| {"mwss", "dh", "gl", "healpix}. Defaults to "mwss". | ||
| {"mwss", "dh", "gl", "healpix", "cc"}. Defaults to "mwss". |
There was a problem hiding this comment.
Add "f2" to list here
| ], | ||
| ) | ||
| @pytest.mark.parametrize("rule", ["cc", "f2", "mw", "mwss", "gl", "dh"]) | ||
| @pytest.mark.parametrize("n_points", [6, 8, 16]) |
There was a problem hiding this comment.
Check whether minimum number of points here corresponds to critical threshold
Should resolve #251 and also does some work towards #340
Adds implementations of the Clenshaw-Curtis and Fejér's (second) quadrature rules and corresponding sampling schemes.
The quadrature weights are computed using the FFT based approach described in
Following the definitions in that paper the Clenshaw-Curtis scheme includes samples at both poles ($\theta = \pm \pi$ ) while the Fejér's second rule scheme excludes both poles. The Clenshaw-Curtis scheme is selected with
sampling="cc"and Fejér's second rule withsampling="f2"arguments to relevant functions.To facilitate adding these new schemes, this PR also does some light refactoring of the existing quadrature and sample related modules to try to make the code more DRY and with a more standardized interfaced across the different schemes. In some cases the rationale for special casing code paths on different sampling schemes was a bit unclear, particularly around handling of pole singularities and setting
m_offset, so I've done a best efforts attempt at trying to rationalise this but this probably could do with some careful checking.Currently for a bandlimit$L$ both schemes have $N_\theta = 2L - 1$ and $N_\phi = 2L$ . The former appears to be required to be $\sim 2L$ to give round-trip errors close to machine precision; I believe this related to the comment
in the paper Hotte and Ujiie (2018) A nestable, multigrid-friendly grid on a sphere for global spectral models based on Clenshaw–Curtis quadrature with their definition of$N$ corresponding to $L - 1$ and $J$ to $N_\theta$ in our notation and hence we require $N_\theta \geq 2 L - 1$ .
Choosing$N_\theta = 2L - 1$ gives an odd number of nodes in the latitude axis and so includes the equator as a node, this matching the co-latitude points used in Hotte and Ujiie (2018). This still leaves $N_\phi$ undetermined - here I have chosen $N_\phi = 2L$ which is sufficient to avoid aliasing in FFT operations (which requires $N_\phi > 2L - 2$ ), and matches the MW scheme, but gives $N_\theta \approx N_\phi$ while it seems quite common in grids used in practice in climate applications to have $N_\phi \approx 2N_\theta$ which might suggest using $N_\phi = 4L$ .
@jasonmcewen I'm tagging you as you mentioned you would be interested in looking through the details of this.
TODO: