Skip to content

Commit 9f377af

Browse files
authored
Merge pull request #1 from steppi/xsref
ENH: Set up initial reference framework and add reference tables for scipy special test cases
2 parents c365ce4 + f17a04f commit 9f377af

File tree

712 files changed

+4262
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

712 files changed

+4262
-1
lines changed

README.md

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,82 @@
11
# xsref
2-
Test case generation for xsf special function library
2+
3+
## Introduction and Installation
4+
5+
This package is used to generate test cases for scalar kernels in the xsf
6+
special function library. Reference values are computed using
7+
[`mpmath`](https://mpmath.org/). Reference tables are stored in
8+
[parquet](https://parquet.apache.org/docs/file-format/) files within the
9+
`xref` repo itself at `xsref/tables/`. Since `xsref` relies on these parquet
10+
files being part of the repo itself, it should be installed using an inplace
11+
build
12+
13+
```bash
14+
pip install -e .
15+
```
16+
17+
from inside the top level directory of the `xsf` repo. Or
18+
19+
```bash
20+
pip install -e .[test]
21+
```
22+
23+
if one wants to install the test dependencies.
24+
25+
## Reference tables
26+
27+
Subdirectories under `xsref/tables` should correspond to conceptually related
28+
collections of test cases. Subdirectories under these subdirectories should
29+
correspond to special functions, and share a name with the corresponding `xsf`
30+
scalar kernel function name (not the SciPy ufunc name). For example
31+
`xsref/tables/scipy_special_tests` is for parquet files for all test cases
32+
that appeared in the `scipy.special` tests prior to the separation of scalar kernels
33+
into the separate [xsf](https://github.com/scipy/xsf) library.
34+
`xsref/tables/scipy_special_tests/cyl_bessel_i` contains parquet files containing
35+
reference test cases for the [modified Bessel function $I_v$](https://dlmf.nist.gov/10.25#E2)
36+
which corresponds to the SciPy ufunc
37+
[`iv`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.iv.html).
38+
39+
Within a directory like `xsref/tables/scipy_special_tests/cyl_bessel_i`, for
40+
each type overload, there will be a parquet file for inputs, such as `In_d_d-d.parquet`
41+
[^1]. The substring `d_d-d` says that this is for cases for the
42+
signature `double cyl_bessel_i(double, double)`. There will be a corresponding
43+
parquet file containing reference output values `Out_d_d-d.parquet`. For each
44+
tested platform there will be parquet files like `Err_d_d-d_gcc-linux-x86_x6.parquet`
45+
containing current extended relative error [^2] values for `xsf`'s implementation compared
46+
to the reference implementation. Rather than having some fixed tolerance
47+
standard, we track the current relative error at each snapshot of development history,
48+
and test that it is not made worse by some fixed multiple. The idea is to use just
49+
tests to drive continuous improvement, helping us identify cases where the scalar
50+
kernels could be improved.
51+
52+
The hope is that the reference implementations be independent of the `xsf`
53+
implementations, relying on arbitrary precision calculations based on simple
54+
definitions. In this case, agreement between the `xsf` implementation and the
55+
reference implementation should make us reasonably confident that the `xsf`
56+
implementation is accurate. However, disagreement could occur either due to
57+
flaws in the `xsf` implementation, or flaws in the reference implementation.
58+
Such situations must be investigated on a case by case basis.
59+
60+
There are functions and parameter regions where we do not yet have an
61+
arbitrary precision reference implementation. Currently there is a fallback to
62+
the SciPy implementations from just before the scalar kernels were split
63+
into the separate `xsf` library. The `Out` parquet files contain a boolean column,
64+
`"fallback"` which is True for cases where such a fallback was used.
65+
66+
## Testing
67+
68+
The test suite uses `pytest` and can be run by invoking the `pytest` command
69+
in a shell from within the top level of the `xsref` repo. Currently the test
70+
suite only checks the consistency of the reference tables.
71+
72+
--
73+
74+
[^1]: For complex valued cases, it would be nice to be able to use NumPy typecodes
75+
such as `In_d_D-D.parquet`, but this will not work on case insensitive file
76+
systems such as the default on MacOS. Instead of `D` we use `cd` for complex
77+
double and instead of `F` we use `cf` for complex float. The filename in
78+
question here would thus be `In_d_cd-cd.parquet`.
79+
80+
[^2]: Extended relative error is a metric we've devised which given any two floating
81+
point numbers (or complex floating point numbers), including exceptional values like
82+
`NaN`s, infinities, and zeros, will return a non-`NaN` result.

pyproject.toml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[build-system]
2+
requires = ["setuptools", "wheel"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "xsref"
7+
version = "0.0.0"
8+
license = {file = "LICENSE"}
9+
maintainers = [
10+
{name = "xsf developers", email = "[email protected]"}
11+
]
12+
requires-python = ">=3.11"
13+
dependencies = [
14+
"mpmath==1.3.0",
15+
"numpy",
16+
"packaging",
17+
"polars",
18+
"pyarrow",
19+
"scipy==1.15.1",
20+
]
21+
readme = "README.md"
22+
23+
[project.optional-dependencies]
24+
test = ["pytest"]

pytest.ini

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
[pytest]
2+
markers =
3+
airy: mark a test as pertaining to airy.
4+
airye: mark a test as pertaining to airye.
5+
bdtr: mark a test as pertaining to bdtr.
6+
bdtrc: mark a test as pertaining to bdtrc.
7+
bdtri: mark a test as pertaining to bdtri.
8+
bei: mark a test as pertaining to bei.
9+
beip: mark a test as pertaining to beip.
10+
ber: mark a test as pertaining to ber.
11+
berp: mark a test as pertaining to berp.
12+
besselpoly: mark a test as pertaining to besselpoly.
13+
beta: mark a test as pertaining to beta.
14+
betaln: mark a test as pertaining to betaln.
15+
betainc: mark a test as pertaining to betainc.
16+
betaincc: mark a test as pertaining to betaincc.
17+
betaincinv: mark a test as pertaining to betaincinv.
18+
betainccinv: mark a test as pertaining to betainccinv.
19+
binom: mark a test as pertaining to binom.
20+
cbrt: mark a test as pertaining to cbrt.
21+
cem: mark a test as pertaining to cem.
22+
cem_cva: mark a test as pertaining to cem_cva.
23+
chdtr: mark a test as pertaining to chdtr.
24+
chdtrc: mark a test as pertaining to chdtrc.
25+
chdtri: mark a test as pertaining to chdtri.
26+
cosdg: mark a test as pertaining to cosdg.
27+
cosm1: mark a test as pertaining to cosm1.
28+
cospi: mark a test as pertaining to cospi.
29+
cotdg: mark a test as pertaining to cotdg.
30+
cyl_bessel_i: mark a test as pertaining to cyl_bessel_i.
31+
cyl_bessel_i0: mark a test as pertaining to cyl_bessel_i0.
32+
cyl_bessel_i0e: mark a test as pertaining to cyl_bessel_i0e.
33+
cyl_bessel_i1: mark a test as pertaining to cyl_bessel_i1.
34+
cyl_bessel_i1e: mark a test as pertaining to cyl_bessel_i1e.
35+
cyl_bessel_ie: mark a test as pertaining to cyl_bessel_ie.
36+
cyl_bessel_j: mark a test as pertaining to cyl_bessel_j.
37+
cyl_bessel_j0: mark a test as pertaining to cyl_bessel_j0.
38+
cyl_bessel_j1: mark a test as pertaining to cyl_bessel_j1.
39+
cyl_bessel_je: mark a test as pertaining to cyl_bessel_je.
40+
cyl_bessel_k: mark a test as pertaining to cyl_bessel_k.
41+
cyl_bessel_k0: mark a test as pertaining to cyl_bessel_k0.
42+
cyl_bessel_k0e: mark a test as pertaining to cyl_bessel_k0e.
43+
cyl_bessel_k1: mark a test as pertaining to cyl_bessel_k1.
44+
cyl_bessel_k1e: mark a test as pertaining to cyl_bessel_k1e.
45+
cyl_bessel_ke: mark a test as pertaining to cyl_bessel_ke.
46+
cyl_bessel_y: mark a test as pertaining to cyl_bessel_y.
47+
cyl_bessel_y0: mark a test as pertaining to cyl_bessel_y0.
48+
cyl_bessel_y1: mark a test as pertaining to cyl_bessel_y1.
49+
cyl_bessel_ye: mark a test as pertaining to cyl_bessel_ye.
50+
cyl_hankel_1: mark a test as pertaining to cyl_hankel_1.
51+
cyl_hankel_1e: mark a test as pertaining to cyl_hankel_1e.
52+
cyl_hankel_2: mark a test as pertaining to cyl_hankel_2.
53+
cyl_hankel_2e: mark a test as pertaining to cyl_hankel_2e.
54+
dawsn: mark a test as pertaining to dawsn.
55+
digamma: mark a test as pertaining to digamma.
56+
ellipe: mark a test as pertaining to ellipe.
57+
ellipeinc: mark a test as pertaining to ellipeinc.
58+
ellipj: mark a test as pertaining to ellipj.
59+
ellipk: mark a test as pertaining to ellipk.
60+
ellipkinc: mark a test as pertaining to ellipkinc.
61+
ellipkm1: mark a test as pertaining to ellipkm1.
62+
erf: mark a test as pertaining to erf.
63+
erfi: mark a test as pertaining to erfi.
64+
erfc: mark a test as pertaining to erfc.
65+
erfcx: mark a test as pertaining to erfcx.
66+
erfcinv: mark a test as pertaining to erfcinv.
67+
exp1: mark a test as pertaining to exp1.
68+
exp10: mark a test as pertaining to exp10.
69+
exp2: mark a test as pertaining to exp2.
70+
expi: mark a test as pertaining to expi.
71+
expit: mark a test as pertaining to expit.
72+
expm1: mark a test as pertaining to expm1.
73+
expn: mark a test as pertaining to expn.
74+
exprel: mark a test as pertaining to exprel.
75+
fdtr: mark a test as pertaining to fdtr.
76+
fdtrc: mark a test as pertaining to fdtrc.
77+
fdtri: mark a test as pertaining to fdtri.
78+
fresnel: mark a test as pertaining to fresnel.
79+
gamma: mark a test as pertaining to gamma.
80+
gammaincc: mark a test as pertaining to gammaincc.
81+
gammainc: mark a test as pertaining to gammainc.
82+
gammainccinv: mark a test as pertaining to gammainccinv.
83+
gammaincinv: mark a test as pertaining to gammaincinv.
84+
gammaln: mark a test as pertaining to gammaln.
85+
gammasgn: mark a test as pertaining to gammasgn.
86+
gdtr: mark a test as pertaining to gdtr.
87+
gdtrc: mark a test as pertaining to gdtrc.
88+
gdtrib: mark a test as pertaining to gdtrib.
89+
hyp1f1: mark a test as pertaining to hyp1f1.
90+
hyp2f1: mark a test as pertaining to hyp2f1.
91+
hyperu: mark a test as pertaining to hyperu.
92+
it1i0k0: mark a test as pertaining to it1i0k0.
93+
it1j0y0: mark a test as pertaining to it1j0y0.
94+
it2i0k0: mark a test as pertaining to it2i0k0.
95+
it2j0y0: mark a test as pertaining to it2j0y0.
96+
it2struve0: mark a test as pertaining to it2struve0.
97+
itairy: mark a test as pertaining to itairy.
98+
itmodstruve0: mark a test as pertaining to itmodstruve0.
99+
itstruve0: mark a test as pertaining to itstruve0.
100+
iv_ratio: mark a test as pertaining to iv_ratio.
101+
iv_ratio_c: mark a test as pertaining to iv_ratio_c.
102+
kei: mark a test as pertaining to kei.
103+
keip: mark a test as pertaining to keip.
104+
kelvin: mark a test as pertaining to kelvin.
105+
ker: mark a test as pertaining to ker.
106+
kerp: mark a test as pertaining to kerp.
107+
kolmogc: mark a test as pertaining to kolmogc.
108+
kolmogci: mark a test as pertaining to kolmogci.
109+
kolmogi: mark a test as pertaining to kolmogi.
110+
kolmogorov: mark a test as pertaining to kolmogorov.
111+
kolmogp: mark a test as pertaining to kolmogp.
112+
lambertw: mark a test as pertaining to lambertw.
113+
lanczos_sum_expg_scaled: mark a test as pertaining to lanczos_sum_expg_scaled.
114+
lgam1p: mark a test as pertaining to lgam1p.
115+
log1p: mark a test as pertaining to log1p.
116+
log1pmx: mark a test as pertaining to log1pmx.
117+
loggamma: mark a test as pertaining to loggamma.
118+
log_expit: mark a test as pertaining to log_expit.
119+
log_wright_bessel: mark a test as pertaining to log_wright_bessel.
120+
logit: mark a test as pertaining to logit.
121+
mcm1: mark a test as pertaining to mcm1.
122+
mcm2: mark a test as pertaining to mcm2.
123+
modified_fresnel_minus: mark a test as pertaining to modified_fresnel_minus.
124+
modified_fresnel_plus: mark a test as pertaining to modified_fresnel_plus.
125+
msm1: mark a test as pertaining to msm1.
126+
msm2: mark a test as pertaining to msm2.
127+
nbdtr: mark a test as pertaining to nbdtr.
128+
nbdtrc: mark a test as pertaining to nbdtrc.
129+
ndtr: mark a test as pertaining to ndtr.
130+
ndtri: mark a test as pertaining to ndtri.
131+
oblate_aswfa: mark a test as pertaining to oblate_aswfa.
132+
oblate_aswfa_nocv: mark a test as pertaining to oblate_aswfa_nocv.
133+
oblate_radial1: mark a test as pertaining to oblate_radial1.
134+
oblate_radial1_nocv: mark a test as pertaining to oblate_radial1_nocv.
135+
oblate_radial2: mark a test as pertaining to oblate_radial2.
136+
oblate_radial2_nocv: mark a test as pertaining to oblate_radial2_nocv.
137+
oblate_segv: mark a test as pertaining to oblate_segv.
138+
owens_t: mark a test as pertaining to owens_t.
139+
pbdv: mark a test as pertaining to pbdv.
140+
pbvv: mark a test as pertaining to pbvv.
141+
pbwa: mark a test as pertaining to pbwa.
142+
pdtr: mark a test as pertaining to pdtr.
143+
pdtrc: mark a test as pertaining to pdtrc.
144+
pdtri: mark a test as pertaining to pdtri.
145+
pmv: mark a test as pertaining to pmv.
146+
poch: mark a test as pertaining to poch.
147+
prolate_aswfa: mark a test as pertaining to prolate_aswfa.
148+
prolate_aswfa_nocv: mark a test as pertaining to prolate_aswfa_nocv.
149+
prolate_radial1: mark a test as pertaining to prolate_radial1.
150+
prolate_radial1_nocv: mark a test as pertaining to prolate_radial1_nocv.
151+
prolate_radial2: mark a test as pertaining to prolate_radial2.
152+
prolate_radial2_nocv: mark a test as pertaining to prolate_radial2_nocv.
153+
prolate_segv: mark a test as pertaining to prolate_segv.
154+
radian: mark a test as pertaining to radian.
155+
rgamma: mark a test as pertaining to rgamma.
156+
riemann_zeta: mark a test as pertaining to riemann_zeta.
157+
round: mark a test as pertaining to round.
158+
scaled_exp1: mark a test as pertaining to scaled_exp1.
159+
sem: mark a test as pertaining to sem.
160+
sem_cva: mark a test as pertaining to sem_cva.
161+
shichi: mark a test as pertaining to shichi.
162+
sici: mark a test as pertaining to sici.
163+
sindg: mark a test as pertaining to sindg.
164+
sinpi: mark a test as pertaining to sinpi.
165+
smirnov: mark a test as pertaining to smirnov.
166+
smirnovc: mark a test as pertaining to smirnovc.
167+
smirnovci: mark a test as pertaining to smirnovci.
168+
smirnovi: mark a test as pertaining to smirnovi.
169+
smirnovp: mark a test as pertaining to smirnovp.
170+
spence: mark a test as pertaining to spence.
171+
struve_h: mark a test as pertaining to struve_h.
172+
struve_l: mark a test as pertaining to struve_l.
173+
tandg: mark a test as pertaining to tandg.
174+
voigt_profile: mark a test as pertaining to voigt_profile.
175+
wofz: mark a test as pertaining to wofz.
176+
wright_bessel: mark a test as pertaining to wright_bessel.
177+
xlogy: mark a test as pertaining to xlogy.
178+
xlog1py: mark a test as pertaining to xlog1py.
179+
zeta: mark a test as pertaining to zeta.
180+
zetac: mark a test as pertaining to zetac.

src/xsref/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import xsref._reference._functions
2+
from xsref._reference._functions import * # noqa
3+
4+
__all__ = xsref._reference._functions.__all__

src/xsref/_reference/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)