Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
dd7b6f2
Add reference implementations
steppi Jan 14, 2025
d06f455
Implement fallbacks
steppi Jan 14, 2025
73d882a
Make some whitespace adjustments
steppi Jan 14, 2025
5da4970
Allow setting timeout at function call level
steppi Jan 14, 2025
6f467a2
Abstract out calculation of resolution precision
steppi Jan 14, 2025
f96c02b
Simplify scipy_func attribute name
steppi Jan 14, 2025
466766c
Remove dead code
steppi Jan 14, 2025
304d2b2
Fix resolution precision calculation for log1pmx
steppi Jan 14, 2025
1152340
Exclude get_resolution_precision from __all__
steppi Jan 14, 2025
24717c4
Some fixes
steppi Jan 14, 2025
415f5ea
Some fixes
steppi Jan 15, 2025
31e56ae
Add parquet tables for scipy.special test case input
steppi Jan 16, 2025
cffd6e6
Added extended error metrics
steppi Jan 16, 2025
93b7c15
Make it easier to keep unwanted things out of __all__
steppi Jan 16, 2025
f199220
Add pytest.ini with custom markers
steppi Jan 16, 2025
8981e97
Add function to read inputs from a parquet table
steppi Jan 16, 2025
33a5100
Add function to compute output table for parquet input table
steppi Jan 17, 2025
58d60d7
More table generation code
steppi Jan 18, 2025
77bb955
Add working tree state to metadata
steppi Jan 18, 2025
f7a5be0
Add tests for table consistency
steppi Jan 30, 2025
0298ced
Fix test method name
steppi Jan 30, 2025
02cdf91
Fix typo in comment
steppi Jan 30, 2025
c6ff1a0
Pin mpmath version in pyproject.toml
steppi Jan 30, 2025
44ecb96
Make updates to test_tables
steppi Jan 30, 2025
7f31bee
Improvements to table handling + some fixes
steppi Jan 31, 2025
8daf362
Add test of consistency of reference values
steppi Jan 31, 2025
5eaa0c1
Add TracedUFunc for identifying existing scipy.special test cases
steppi Jan 31, 2025
ecd1d7d
Add function to convert traced cases to a parquet file
steppi Jan 31, 2025
e289057
Update to more specific filename for scipy case generation
steppi Jan 31, 2025
19f6fcb
Add script for generating scipy test cases
steppi Jan 31, 2025
a8f4116
Make test_tables still work when no output tables yet
steppi Jan 31, 2025
84cf833
Fix bug, wrong function name
steppi Jan 31, 2025
e138e3a
Increase default timeout on betainc(c)inv
steppi Feb 1, 2025
f4941ab
Treat typecode p as int64
steppi Feb 1, 2025
75cd984
Make schema of output table explicit
steppi Feb 2, 2025
b5d886c
Fix for test_tables
steppi Feb 2, 2025
0162ed2
Add and update scipy special test reference tables
steppi Feb 2, 2025
375a015
Change directory structure for test case tables
steppi Feb 3, 2025
fe5bd0e
Add CLI for input table generation
steppi Feb 3, 2025
25c4631
Add help for argparse args for scipy_case_generation script
steppi Feb 3, 2025
55b7d00
Adjust table directory layout
steppi Feb 3, 2025
523001b
Add comments on output generation script
steppi Feb 3, 2025
f9e2c67
Add vectorization for extended relative error
steppi Feb 4, 2025
927706c
Upgrade SciPy dependency to 1.15.1
steppi Feb 4, 2025
ae5f5fa
Add function to compute initial error tables
steppi Feb 4, 2025
7e84ca9
Remove type restrictions on extended error functions
steppi Feb 13, 2025
40532eb
Fix initial err table calculation
steppi Feb 13, 2025
6bd4d72
Add script to compute initial reference tolerances table
steppi Feb 13, 2025
ecbd47a
Add reference tolerance tables
steppi Feb 13, 2025
50ec954
Add optional test dependencies
steppi Feb 13, 2025
3228a42
Add consistency checks for tolerance tables
steppi Feb 13, 2025
e359ba9
Remove flaky test_consistent_values_in_sample test
steppi Feb 13, 2025
bd4714e
Add tests that working tree state is clean during table generation
steppi Feb 13, 2025
fc6b128
Update _get_git_info to not care about modifications in tables
steppi Feb 13, 2025
6984948
Change filename format to work on case insensitive file systems
steppi Feb 13, 2025
16ea7bb
Update tests to account for new table filename format
steppi Feb 13, 2025
ee2fb59
Fix overflow case for extended_relative_error
steppi Feb 13, 2025
e161f7a
Make extended relative/absolute error functions not raise RuntimeWarning
steppi Feb 13, 2025
89bde49
Fix extended_relative_error very large desired case
steppi Feb 14, 2025
ed3aef1
Fix table filenames
steppi Feb 14, 2025
5ec59b9
Fix getting types from filename in tests
steppi Feb 14, 2025
393bbd1
Add GitHub workflow with tests
steppi Feb 14, 2025
d4cac00
Update tables
steppi Feb 14, 2025
b372640
Flesh out the README
steppi Feb 14, 2025
1145b68
Fix types in filename for reference tolerances script
steppi Feb 14, 2025
9bbabc2
Fix tolerance table filenames
steppi Feb 14, 2025
7e98fc4
Fix github workflow formatting
steppi Feb 14, 2025
a483eff
Fix extended_absolute_error actual or desired infinite
steppi Feb 14, 2025
cc4fef5
Update tol tables in response to extended error fix
steppi Feb 14, 2025
cb3a826
Update table format to use two cols for complex instead of struct
steppi Mar 6, 2025
fc82707
Update table format to use two cols for complex types part 2
steppi Mar 6, 2025
9ef6bc8
Update comments in response to flattening of tables
steppi Mar 6, 2025
0cb5319
Ensure correct types in table schema
steppi Mar 7, 2025
e77ce00
Update tables tests for new table format
steppi Mar 7, 2025
1ca8cf8
Update all tables to use two columns for complex numbers
steppi Mar 7, 2025
9b04ef2
Fix order in call to extended_relative_error
steppi Mar 11, 2025
b88807a
Check in corrected parquet error tables
steppi Mar 11, 2025
7b15503
Remove tables for functions not in xsf yet
steppi Apr 4, 2025
6549bc5
Add argument names as attribute of reference implementations
steppi Apr 4, 2025
f17a04f
Add a script for generating test case files
steppi Apr 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
21 changes: 21 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: xsref tests

on: [ push, pull_request ]

jobs:
xsref_tests:
name: xsref table consistency tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Setup Python
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
with:
python-version: '3.12'

- name: Install xsref and dependencies
run: pip install .[test]

- name: Run tests
run: pytest
82 changes: 81 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,82 @@
# xsref
Test case generation for xsf special function library

## Introduction and Installation

This package is used to generate test cases for scalar kernels in the xsf
special function library. Reference values are computed using
[`mpmath`](https://mpmath.org/). Reference tables are stored in
[parquet](https://parquet.apache.org/docs/file-format/) files within the
`xref` repo itself at `xsref/tables/`. Since `xsref` relies on these parquet
files being part of the repo itself, it should be installed using an inplace
build

```bash
pip install -e .
```

from inside the top level directory of the `xsf` repo. Or

```bash
pip install -e .[test]
```

if one wants to install the test dependencies.

## Reference tables

Subdirectories under `xsref/tables` should correspond to conceptually related
collections of test cases. Subdirectories under these subdirectories should
correspond to special functions, and share a name with the corresponding `xsf`
scalar kernel function name (not the SciPy ufunc name). For example
`xsref/tables/scipy_special_tests` is for parquet files for all test cases
that appeared in the `scipy.special` tests prior to the separation of scalar kernels
into the separate [xsf](https://github.com/scipy/xsf) library.
`xsref/tables/scipy_special_tests/cyl_bessel_i` contains parquet files containing
reference test cases for the [modified Bessel function $I_v$](https://dlmf.nist.gov/10.25#E2)
which corresponds to the SciPy ufunc
[`iv`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.iv.html).

Within a directory like `xsref/tables/scipy_special_tests/cyl_bessel_i`, for
each type overload, there will be a parquet file for inputs, such as `In_d_d-d.parquet`
[^1]. The substring `d_d-d` says that this is for cases for the
signature `double cyl_bessel_i(double, double)`. There will be a corresponding
parquet file containing reference output values `Out_d_d-d.parquet`. For each
tested platform there will be parquet files like `Err_d_d-d_gcc-linux-x86_x6.parquet`
containing current extended relative error [^2] values for `xsf`'s implementation compared
to the reference implementation. Rather than having some fixed tolerance
standard, we track the current relative error at each snapshot of development history,
and test that it is not made worse by some fixed multiple. The idea is to use just
tests to drive continuous improvement, helping us identify cases where the scalar
kernels could be improved.

The hope is that the reference implementations be independent of the `xsf`
implementations, relying on arbitrary precision calculations based on simple
definitions. In this case, agreement between the `xsf` implementation and the
reference implementation should make us reasonably confident that the `xsf`
implementation is accurate. However, disagreement could occur either due to
flaws in the `xsf` implementation, or flaws in the reference implementation.
Such situations must be investigated on a case by case basis.

There are functions and parameter regions where we do not yet have an
arbitrary precision reference implementation. Currently there is a fallback to
the SciPy implementations from just before the scalar kernels were split
into the separate `xsf` library. The `Out` parquet files contain a boolean column,
`"fallback"` which is True for cases where such a fallback was used.

## Testing

The test suite uses `pytest` and can be run by invoking the `pytest` command
in a shell from within the top level of the `xsref` repo. Currently the test
suite only checks the consistency of the reference tables.

--

[^1]: For complex valued cases, it would be nice to be able to use NumPy typecodes
such as `In_d_D-D.parquet`, but this will not work on case insensitive file
systems such as the default on MacOS. Instead of `D` we use `cd` for complex
double and instead of `F` we use `cf` for complex float. The filename in
question here would thus be `In_d_cd-cd.parquet`.

[^2]: Extended relative error is a metric we've devised which given any two floating
point numbers (or complex floating point numbers), including exceptional values like
`NaN`s, infinities, and zeros, will return a non-`NaN` result.
24 changes: 24 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "xsref"
version = "0.0.0"
license = {file = "LICENSE"}
maintainers = [
{name = "xsf developers", email = "albert.steppi@gmail.com"}
]
requires-python = ">=3.11"
dependencies = [
"mpmath==1.3.0",
"numpy",
"packaging",
"polars",
"pyarrow",
"scipy==1.15.1",
]
readme = "README.md"

[project.optional-dependencies]
test = ["pytest"]
180 changes: 180 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
[pytest]
markers =
airy: mark a test as pertaining to airy.
airye: mark a test as pertaining to airye.
bdtr: mark a test as pertaining to bdtr.
bdtrc: mark a test as pertaining to bdtrc.
bdtri: mark a test as pertaining to bdtri.
bei: mark a test as pertaining to bei.
beip: mark a test as pertaining to beip.
ber: mark a test as pertaining to ber.
berp: mark a test as pertaining to berp.
besselpoly: mark a test as pertaining to besselpoly.
beta: mark a test as pertaining to beta.
betaln: mark a test as pertaining to betaln.
betainc: mark a test as pertaining to betainc.
betaincc: mark a test as pertaining to betaincc.
betaincinv: mark a test as pertaining to betaincinv.
betainccinv: mark a test as pertaining to betainccinv.
binom: mark a test as pertaining to binom.
cbrt: mark a test as pertaining to cbrt.
cem: mark a test as pertaining to cem.
cem_cva: mark a test as pertaining to cem_cva.
chdtr: mark a test as pertaining to chdtr.
chdtrc: mark a test as pertaining to chdtrc.
chdtri: mark a test as pertaining to chdtri.
cosdg: mark a test as pertaining to cosdg.
cosm1: mark a test as pertaining to cosm1.
cospi: mark a test as pertaining to cospi.
cotdg: mark a test as pertaining to cotdg.
cyl_bessel_i: mark a test as pertaining to cyl_bessel_i.
cyl_bessel_i0: mark a test as pertaining to cyl_bessel_i0.
cyl_bessel_i0e: mark a test as pertaining to cyl_bessel_i0e.
cyl_bessel_i1: mark a test as pertaining to cyl_bessel_i1.
cyl_bessel_i1e: mark a test as pertaining to cyl_bessel_i1e.
cyl_bessel_ie: mark a test as pertaining to cyl_bessel_ie.
cyl_bessel_j: mark a test as pertaining to cyl_bessel_j.
cyl_bessel_j0: mark a test as pertaining to cyl_bessel_j0.
cyl_bessel_j1: mark a test as pertaining to cyl_bessel_j1.
cyl_bessel_je: mark a test as pertaining to cyl_bessel_je.
cyl_bessel_k: mark a test as pertaining to cyl_bessel_k.
cyl_bessel_k0: mark a test as pertaining to cyl_bessel_k0.
cyl_bessel_k0e: mark a test as pertaining to cyl_bessel_k0e.
cyl_bessel_k1: mark a test as pertaining to cyl_bessel_k1.
cyl_bessel_k1e: mark a test as pertaining to cyl_bessel_k1e.
cyl_bessel_ke: mark a test as pertaining to cyl_bessel_ke.
cyl_bessel_y: mark a test as pertaining to cyl_bessel_y.
cyl_bessel_y0: mark a test as pertaining to cyl_bessel_y0.
cyl_bessel_y1: mark a test as pertaining to cyl_bessel_y1.
cyl_bessel_ye: mark a test as pertaining to cyl_bessel_ye.
cyl_hankel_1: mark a test as pertaining to cyl_hankel_1.
cyl_hankel_1e: mark a test as pertaining to cyl_hankel_1e.
cyl_hankel_2: mark a test as pertaining to cyl_hankel_2.
cyl_hankel_2e: mark a test as pertaining to cyl_hankel_2e.
dawsn: mark a test as pertaining to dawsn.
digamma: mark a test as pertaining to digamma.
ellipe: mark a test as pertaining to ellipe.
ellipeinc: mark a test as pertaining to ellipeinc.
ellipj: mark a test as pertaining to ellipj.
ellipk: mark a test as pertaining to ellipk.
ellipkinc: mark a test as pertaining to ellipkinc.
ellipkm1: mark a test as pertaining to ellipkm1.
erf: mark a test as pertaining to erf.
erfi: mark a test as pertaining to erfi.
erfc: mark a test as pertaining to erfc.
erfcx: mark a test as pertaining to erfcx.
erfcinv: mark a test as pertaining to erfcinv.
exp1: mark a test as pertaining to exp1.
exp10: mark a test as pertaining to exp10.
exp2: mark a test as pertaining to exp2.
expi: mark a test as pertaining to expi.
expit: mark a test as pertaining to expit.
expm1: mark a test as pertaining to expm1.
expn: mark a test as pertaining to expn.
exprel: mark a test as pertaining to exprel.
fdtr: mark a test as pertaining to fdtr.
fdtrc: mark a test as pertaining to fdtrc.
fdtri: mark a test as pertaining to fdtri.
fresnel: mark a test as pertaining to fresnel.
gamma: mark a test as pertaining to gamma.
gammaincc: mark a test as pertaining to gammaincc.
gammainc: mark a test as pertaining to gammainc.
gammainccinv: mark a test as pertaining to gammainccinv.
gammaincinv: mark a test as pertaining to gammaincinv.
gammaln: mark a test as pertaining to gammaln.
gammasgn: mark a test as pertaining to gammasgn.
gdtr: mark a test as pertaining to gdtr.
gdtrc: mark a test as pertaining to gdtrc.
gdtrib: mark a test as pertaining to gdtrib.
hyp1f1: mark a test as pertaining to hyp1f1.
hyp2f1: mark a test as pertaining to hyp2f1.
hyperu: mark a test as pertaining to hyperu.
it1i0k0: mark a test as pertaining to it1i0k0.
it1j0y0: mark a test as pertaining to it1j0y0.
it2i0k0: mark a test as pertaining to it2i0k0.
it2j0y0: mark a test as pertaining to it2j0y0.
it2struve0: mark a test as pertaining to it2struve0.
itairy: mark a test as pertaining to itairy.
itmodstruve0: mark a test as pertaining to itmodstruve0.
itstruve0: mark a test as pertaining to itstruve0.
iv_ratio: mark a test as pertaining to iv_ratio.
iv_ratio_c: mark a test as pertaining to iv_ratio_c.
kei: mark a test as pertaining to kei.
keip: mark a test as pertaining to keip.
kelvin: mark a test as pertaining to kelvin.
ker: mark a test as pertaining to ker.
kerp: mark a test as pertaining to kerp.
kolmogc: mark a test as pertaining to kolmogc.
kolmogci: mark a test as pertaining to kolmogci.
kolmogi: mark a test as pertaining to kolmogi.
kolmogorov: mark a test as pertaining to kolmogorov.
kolmogp: mark a test as pertaining to kolmogp.
lambertw: mark a test as pertaining to lambertw.
lanczos_sum_expg_scaled: mark a test as pertaining to lanczos_sum_expg_scaled.
lgam1p: mark a test as pertaining to lgam1p.
log1p: mark a test as pertaining to log1p.
log1pmx: mark a test as pertaining to log1pmx.
loggamma: mark a test as pertaining to loggamma.
log_expit: mark a test as pertaining to log_expit.
log_wright_bessel: mark a test as pertaining to log_wright_bessel.
logit: mark a test as pertaining to logit.
mcm1: mark a test as pertaining to mcm1.
mcm2: mark a test as pertaining to mcm2.
modified_fresnel_minus: mark a test as pertaining to modified_fresnel_minus.
modified_fresnel_plus: mark a test as pertaining to modified_fresnel_plus.
msm1: mark a test as pertaining to msm1.
msm2: mark a test as pertaining to msm2.
nbdtr: mark a test as pertaining to nbdtr.
nbdtrc: mark a test as pertaining to nbdtrc.
ndtr: mark a test as pertaining to ndtr.
ndtri: mark a test as pertaining to ndtri.
oblate_aswfa: mark a test as pertaining to oblate_aswfa.
oblate_aswfa_nocv: mark a test as pertaining to oblate_aswfa_nocv.
oblate_radial1: mark a test as pertaining to oblate_radial1.
oblate_radial1_nocv: mark a test as pertaining to oblate_radial1_nocv.
oblate_radial2: mark a test as pertaining to oblate_radial2.
oblate_radial2_nocv: mark a test as pertaining to oblate_radial2_nocv.
oblate_segv: mark a test as pertaining to oblate_segv.
owens_t: mark a test as pertaining to owens_t.
pbdv: mark a test as pertaining to pbdv.
pbvv: mark a test as pertaining to pbvv.
pbwa: mark a test as pertaining to pbwa.
pdtr: mark a test as pertaining to pdtr.
pdtrc: mark a test as pertaining to pdtrc.
pdtri: mark a test as pertaining to pdtri.
pmv: mark a test as pertaining to pmv.
poch: mark a test as pertaining to poch.
prolate_aswfa: mark a test as pertaining to prolate_aswfa.
prolate_aswfa_nocv: mark a test as pertaining to prolate_aswfa_nocv.
prolate_radial1: mark a test as pertaining to prolate_radial1.
prolate_radial1_nocv: mark a test as pertaining to prolate_radial1_nocv.
prolate_radial2: mark a test as pertaining to prolate_radial2.
prolate_radial2_nocv: mark a test as pertaining to prolate_radial2_nocv.
prolate_segv: mark a test as pertaining to prolate_segv.
radian: mark a test as pertaining to radian.
rgamma: mark a test as pertaining to rgamma.
riemann_zeta: mark a test as pertaining to riemann_zeta.
round: mark a test as pertaining to round.
scaled_exp1: mark a test as pertaining to scaled_exp1.
sem: mark a test as pertaining to sem.
sem_cva: mark a test as pertaining to sem_cva.
shichi: mark a test as pertaining to shichi.
sici: mark a test as pertaining to sici.
sindg: mark a test as pertaining to sindg.
sinpi: mark a test as pertaining to sinpi.
smirnov: mark a test as pertaining to smirnov.
smirnovc: mark a test as pertaining to smirnovc.
smirnovci: mark a test as pertaining to smirnovci.
smirnovi: mark a test as pertaining to smirnovi.
smirnovp: mark a test as pertaining to smirnovp.
spence: mark a test as pertaining to spence.
struve_h: mark a test as pertaining to struve_h.
struve_l: mark a test as pertaining to struve_l.
tandg: mark a test as pertaining to tandg.
voigt_profile: mark a test as pertaining to voigt_profile.
wofz: mark a test as pertaining to wofz.
wright_bessel: mark a test as pertaining to wright_bessel.
xlogy: mark a test as pertaining to xlogy.
xlog1py: mark a test as pertaining to xlog1py.
zeta: mark a test as pertaining to zeta.
zetac: mark a test as pertaining to zetac.
4 changes: 4 additions & 0 deletions src/xsref/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import xsref._reference._functions
from xsref._reference._functions import * # noqa

__all__ = xsref._reference._functions.__all__
Empty file.
Loading