├── .clang-format ├── .git-blame-ignore-revs ├── .gitattributes ├── .github └── workflows │ └── tests.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── LICENSES_bundled.txt ├── README.md ├── include └── xsf │ ├── airy.h │ ├── alg.h │ ├── amos.h │ ├── amos │ └── amos.h │ ├── bessel.h │ ├── beta.h │ ├── binom.h │ ├── cdflib.h │ ├── cephes │ ├── airy.h │ ├── bdtr.h │ ├── besselpoly.h │ ├── beta.h │ ├── cbrt.h │ ├── chbevl.h │ ├── chdtr.h │ ├── const.h │ ├── dd_real.h │ ├── ellie.h │ ├── ellik.h │ ├── ellpe.h │ ├── ellpj.h │ ├── ellpk.h │ ├── erfinv.h │ ├── exp10.h │ ├── exp2.h │ ├── expn.h │ ├── fdtr.h │ ├── fresnl.h │ ├── gamma.h │ ├── gdtr.h │ ├── hyp2f1.h │ ├── hyperg.h │ ├── i0.h │ ├── i1.h │ ├── igam.h │ ├── igam_asymp_coeff.h │ ├── igami.h │ ├── incbet.h │ ├── incbi.h │ ├── j0.h │ ├── j1.h │ ├── jv.h │ ├── k0.h │ ├── k1.h │ ├── kn.h │ ├── kolmogorov.h │ ├── lanczos.h │ ├── nbdtr.h │ ├── ndtr.h │ ├── ndtri.h │ ├── owens_t.h │ ├── pdtr.h │ ├── poch.h │ ├── polevl.h │ ├── psi.h │ ├── rgamma.h │ ├── round.h │ ├── scipy_iv.h │ ├── shichi.h │ ├── sici.h │ ├── sindg.h │ ├── spence.h │ ├── struve.h │ ├── tandg.h │ ├── trig.h │ ├── tukey.h │ ├── unity.h │ ├── yn.h │ ├── yv.h │ ├── zeta.h │ └── zetac.h │ ├── config.h │ ├── digamma.h │ ├── dual.h │ ├── ellip.h │ ├── erf.h │ ├── error.h │ ├── evalpoly.h │ ├── exp.h │ ├── expint.h │ ├── faddeeva.h │ ├── fp_error_metrics.h │ ├── fresnel.h │ ├── gamma.h │ ├── hyp2f1.h │ ├── iv_ratio.h │ ├── kelvin.h │ ├── lambertw.h │ ├── legendre.h │ ├── log.h │ ├── log_exp.h │ ├── loggamma.h │ ├── mathieu.h │ ├── numbers.h │ ├── numpy.h │ ├── par_cyl.h │ ├── recur.h │ ├── sici.h │ ├── specfun.h │ ├── specfun │ └── specfun.h │ ├── sph_bessel.h │ ├── sph_harm.h │ ├── sphd_wave.h │ ├── stats.h │ ├── struve.h │ ├── third_party │ └── kokkos │ │ └── mdspan.hpp │ ├── tools.h │ ├── trig.h │ ├── wright_bessel.h │ ├── zeta.h │ └── zlog1.h ├── meson.build ├── pixi.lock ├── pixi.toml └── tests ├── CMakeLists.txt ├── Coverage.cmake ├── scipy_special_tests ├── test_airy.cpp ├── test_airye.cpp ├── test_bdtr.cpp ├── test_bdtrc.cpp ├── test_bdtri.cpp ├── test_bei.cpp ├── test_beip.cpp ├── test_ber.cpp ├── test_berp.cpp ├── test_besselpoly.cpp ├── test_beta.cpp ├── test_betaln.cpp ├── test_binom.cpp ├── test_cbrt.cpp ├── test_cem.cpp ├── test_cem_cva.cpp ├── test_chdtr.cpp ├── test_chdtrc.cpp ├── test_chdtri.cpp ├── test_cosdg.cpp ├── test_cosm1.cpp ├── test_cospi.cpp ├── test_cotdg.cpp ├── test_cyl_bessel_i.cpp ├── test_cyl_bessel_i0.cpp ├── test_cyl_bessel_i0e.cpp ├── test_cyl_bessel_i1.cpp ├── test_cyl_bessel_i1e.cpp ├── test_cyl_bessel_ie.cpp ├── test_cyl_bessel_j.cpp ├── test_cyl_bessel_j0.cpp ├── test_cyl_bessel_j1.cpp ├── test_cyl_bessel_je.cpp ├── test_cyl_bessel_k.cpp ├── test_cyl_bessel_k0.cpp ├── test_cyl_bessel_k0e.cpp ├── test_cyl_bessel_k1.cpp ├── test_cyl_bessel_k1e.cpp ├── test_cyl_bessel_ke.cpp ├── test_cyl_bessel_y.cpp ├── test_cyl_bessel_y0.cpp ├── test_cyl_bessel_y1.cpp ├── test_cyl_bessel_ye.cpp ├── test_cyl_hankel_1.cpp ├── test_cyl_hankel_1e.cpp ├── test_cyl_hankel_2.cpp ├── test_cyl_hankel_2e.cpp ├── test_dawsn.cpp ├── test_digamma.cpp ├── test_ellipe.cpp ├── test_ellipeinc.cpp ├── test_ellipj.cpp ├── test_ellipk.cpp ├── test_ellipkinc.cpp ├── test_ellipkm1.cpp ├── test_erf.cpp ├── test_erfc.cpp ├── test_erfcinv.cpp ├── test_erfcx.cpp ├── test_erfi.cpp ├── test_exp1.cpp ├── test_exp10.cpp ├── test_exp2.cpp ├── test_expi.cpp ├── test_expit.cpp ├── test_expm1.cpp ├── test_expn.cpp ├── test_exprel.cpp ├── test_fdtr.cpp ├── test_fdtrc.cpp ├── test_fdtri.cpp ├── test_fresnel.cpp ├── test_gamma.cpp ├── test_gammainc.cpp ├── test_gammaincc.cpp ├── test_gammainccinv.cpp ├── test_gammaincinv.cpp ├── test_gammaln.cpp ├── test_gammasgn.cpp ├── test_gdtr.cpp ├── test_gdtrc.cpp ├── test_gdtrib.cpp ├── test_hyp1f1.cpp ├── test_hyp2f1.cpp ├── test_it1i0k0.cpp ├── test_it1j0y0.cpp ├── test_it2i0k0.cpp ├── test_it2j0y0.cpp ├── test_it2struve0.cpp ├── test_itairy.cpp ├── test_itmodstruve0.cpp ├── test_itstruve0.cpp ├── test_iv_ratio.cpp ├── test_iv_ratio_c.cpp ├── test_kei.cpp ├── test_keip.cpp ├── test_kelvin.cpp ├── test_ker.cpp ├── test_kerp.cpp ├── test_kolmogc.cpp ├── test_kolmogci.cpp ├── test_kolmogi.cpp ├── test_kolmogorov.cpp ├── test_kolmogp.cpp ├── test_lambertw.cpp ├── test_lanczos_sum_expg_scaled.cpp ├── test_lgam1p.cpp ├── test_log1p.cpp ├── test_log1pmx.cpp ├── test_log_expit.cpp ├── test_log_wright_bessel.cpp ├── test_loggamma.cpp ├── test_logit.cpp ├── test_mcm1.cpp ├── test_mcm2.cpp ├── test_modified_fresnel_minus.cpp ├── test_modified_fresnel_plus.cpp ├── test_msm1.cpp ├── test_msm2.cpp ├── test_nbdtr.cpp ├── test_nbdtrc.cpp ├── test_ndtr.cpp ├── test_ndtri.cpp ├── test_oblate_aswfa.cpp ├── test_oblate_aswfa_nocv.cpp ├── test_oblate_radial1.cpp ├── test_oblate_radial1_nocv.cpp ├── test_oblate_radial2.cpp ├── test_oblate_radial2_nocv.cpp ├── test_owens_t.cpp ├── test_pbdv.cpp ├── test_pbvv.cpp ├── test_pbwa.cpp ├── test_pdtr.cpp ├── test_pdtrc.cpp ├── test_pdtri.cpp ├── test_pmv.cpp ├── test_poch.cpp ├── test_prolate_aswfa.cpp ├── test_prolate_aswfa_nocv.cpp ├── test_prolate_radial1.cpp ├── test_prolate_radial1_nocv.cpp ├── test_prolate_radial2.cpp ├── test_prolate_radial2_nocv.cpp ├── test_prolate_segv.cpp ├── test_radian.cpp ├── test_rgamma.cpp ├── test_riemann_zeta.cpp ├── test_round.cpp ├── test_scaled_exp1.cpp ├── test_sem.cpp ├── test_sem_cva.cpp ├── test_shichi.cpp ├── test_sici.cpp ├── test_sindg.cpp ├── test_sinpi.cpp ├── test_smirnov.cpp ├── test_smirnovc.cpp ├── test_smirnovci.cpp ├── test_smirnovi.cpp ├── test_smirnovp.cpp ├── test_spence.cpp ├── test_struve_h.cpp ├── test_struve_l.cpp ├── test_tandg.cpp ├── test_voigt_profile.cpp ├── test_wofz.cpp ├── test_wright_bessel.cpp ├── test_xlog1py.cpp ├── test_xlogy.cpp ├── test_zeta.cpp └── test_zetac.cpp ├── test_hyp2f1.cpp └── testing_utils.h /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | Standard: c++17 3 | UseTab: Never 4 | IndentWidth: 4 5 | BreakBeforeBraces: Attach 6 | Cpp11BracedListStyle: true 7 | NamespaceIndentation: Inner 8 | AlwaysBreakTemplateDeclarations: true 9 | SpaceAfterCStyleCast: false 10 | ColumnLimit: 120 11 | InsertNewlineAtEOF: true 12 | AlignAfterOpenBracket: BlockIndent 13 | IncludeBlocks: Preserve 14 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # clang-format repo gh-5 2 | b5e297bba45b56af14d6f057002d16efdf27ad59 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # SCM syntax highlighting 2 | pixi.lock linguist-language=YAML linguist-generated=true 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # cmake build 35 | build/ 36 | 37 | # test executable extension 38 | *.test 39 | 40 | # pixi environments 41 | .pixi 42 | *.egg-info 43 | 44 | # xsref 45 | xsref/ 46 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | project(xsf) 3 | 4 | # Scipy is restricted to C++17 5 | # https://docs.scipy.org/doc/scipy/dev/toolchain.html#c-language-standards 6 | set(CMAKE_CXX_STANDARD 17) 7 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 8 | 9 | # Tests 10 | option(BUILD_TESTS "Build the tests" OFF) 11 | 12 | if(BUILD_TESTS) 13 | enable_testing() 14 | add_subdirectory(tests) 15 | endif() 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2024, SciPy 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # xsf 2 | Special function implementations. 3 | 4 | See https://github.com/scipy/xsf/issues/1 for context. 5 | 6 | ## Tests 7 | 8 | To run the tests: 9 | - [clone this repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) 10 | - `cd xsf` 11 | - [install Pixi](https://pixi.sh/latest/#installation) 12 | - `pixi run tests` 13 | 14 | You can trigger a rebuild inbetween test runs with: 15 | 16 | ```shell 17 | pixi run build-tests 18 | ``` 19 | 20 | For subsequent test runs, to skip re-cloning [`xsref`](https://github.com/scipy/xsref) or to control parallelism for individual commands, you can use: 21 | 22 | ```shell 23 | pixi run clone-xsf 24 | pixi run configure-tests 25 | pixi run build-only -j8 26 | pixi run --skip-deps tests -j2 27 | ``` 28 | 29 | > [!NOTE] 30 | > This has currently only been tested on Linux. 31 | -------------------------------------------------------------------------------- /include/xsf/alg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cephes/cbrt.h" 4 | 5 | namespace xsf { 6 | 7 | XSF_HOST_DEVICE inline double cbrt(double x) { return cephes::cbrt(x); } 8 | 9 | XSF_HOST_DEVICE inline float cbrt(float x) { return cbrt(static_cast(x)); } 10 | 11 | } // namespace xsf 12 | -------------------------------------------------------------------------------- /include/xsf/amos.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "amos/amos.h" 4 | #include "error.h" 5 | 6 | namespace xsf { 7 | 8 | // 9 | // Return sf_error equivalents for AMOS ierr values. 10 | // 'ierr' refers to the last parameter of the AMOS functions 11 | // airy(), besh(), besi(), besj(), besk(), besy(), and biry(). 12 | // 13 | inline sf_error_t ierr_to_sferr(int nz, int ierr) { 14 | if (nz != 0) { 15 | return SF_ERROR_UNDERFLOW; 16 | } 17 | 18 | switch (ierr) { 19 | case 1: 20 | return SF_ERROR_DOMAIN; 21 | case 2: 22 | return SF_ERROR_OVERFLOW; 23 | case 3: 24 | return SF_ERROR_LOSS; 25 | case 4: 26 | return SF_ERROR_NO_RESULT; 27 | case 5: /* Algorithm termination condition not met */ 28 | return SF_ERROR_NO_RESULT; 29 | case 6: /* Memory allocation failed */ 30 | return SF_ERROR_MEMORY; 31 | } 32 | 33 | return SF_ERROR_OK; 34 | } 35 | } // namespace xsf 36 | -------------------------------------------------------------------------------- /include/xsf/beta.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cephes/beta.h" 4 | 5 | namespace xsf { 6 | 7 | XSF_HOST_DEVICE inline double beta(double a, double b) { return cephes::beta(a, b); } 8 | 9 | XSF_HOST_DEVICE inline float beta(float a, float b) { return beta(static_cast(a), static_cast(b)); } 10 | 11 | XSF_HOST_DEVICE inline double betaln(double a, double b) { return cephes::lbeta(a, b); } 12 | 13 | XSF_HOST_DEVICE inline float betaln(float a, float b) { return betaln(static_cast(a), static_cast(b)); } 14 | 15 | } // namespace xsf 16 | -------------------------------------------------------------------------------- /include/xsf/cephes/besselpoly.h: -------------------------------------------------------------------------------- 1 | /* Translated into C++ by SciPy developers in 2024. 2 | * 3 | * This was not part of the original cephes library. 4 | */ 5 | #pragma once 6 | 7 | #include "../config.h" 8 | #include "gamma.h" 9 | 10 | namespace xsf { 11 | namespace cephes { 12 | namespace detail { 13 | 14 | constexpr double besselpoly_EPS = 1.0e-17; 15 | } 16 | 17 | XSF_HOST_DEVICE inline double besselpoly(double a, double lambda, double nu) { 18 | 19 | int m, factor = 0; 20 | double Sm, relerr, Sol; 21 | double sum = 0.0; 22 | 23 | /* Special handling for a = 0.0 */ 24 | if (a == 0.0) { 25 | if (nu == 0.0) { 26 | return 1.0 / (lambda + 1); 27 | } else { 28 | return 0.0; 29 | } 30 | } 31 | /* Special handling for negative and integer nu */ 32 | if ((nu < 0) && (std::floor(nu) == nu)) { 33 | nu = -nu; 34 | factor = static_cast(nu) % 2; 35 | } 36 | Sm = std::exp(nu * std::log(a)) / (Gamma(nu + 1) * (lambda + nu + 1)); 37 | m = 0; 38 | do { 39 | sum += Sm; 40 | Sol = Sm; 41 | Sm *= -a * a * (lambda + nu + 1 + 2 * m) / ((nu + m + 1) * (m + 1) * (lambda + nu + 1 + 2 * m + 2)); 42 | m++; 43 | relerr = std::abs((Sm - Sol) / Sm); 44 | } while (relerr > detail::besselpoly_EPS && m < 1000); 45 | if (!factor) 46 | return sum; 47 | else 48 | return -sum; 49 | } 50 | } // namespace cephes 51 | } // namespace xsf 52 | -------------------------------------------------------------------------------- /include/xsf/cephes/round.h: -------------------------------------------------------------------------------- 1 | /* Translated into C++ by SciPy developers in 2024. 2 | * Original header with Copyright information appears below. 3 | */ 4 | 5 | /* round.c 6 | * 7 | * Round double to nearest or even integer valued double 8 | * 9 | * 10 | * 11 | * SYNOPSIS: 12 | * 13 | * double x, y, round(); 14 | * 15 | * y = round(x); 16 | * 17 | * 18 | * 19 | * DESCRIPTION: 20 | * 21 | * Returns the nearest integer to x as a double precision 22 | * floating point result. If x ends in 0.5 exactly, the 23 | * nearest even integer is chosen. 24 | * 25 | * 26 | * 27 | * ACCURACY: 28 | * 29 | * If x is greater than 1/(2*MACHEP), its closest machine 30 | * representation is already an integer, so rounding does 31 | * not change it. 32 | */ 33 | 34 | /* 35 | * Cephes Math Library Release 2.1: January, 1989 36 | * Copyright 1984, 1987, 1989 by Stephen L. Moshier 37 | * Direct inquiries to 30 Frost Street, Cambridge, MA 02140 38 | */ 39 | #pragma once 40 | 41 | #include "../config.h" 42 | 43 | namespace xsf { 44 | namespace cephes { 45 | 46 | double round(double x) { 47 | double y, r; 48 | 49 | /* Largest integer <= x */ 50 | y = std::floor(x); 51 | 52 | /* Fractional part */ 53 | r = x - y; 54 | 55 | /* Round up to nearest. */ 56 | if (r > 0.5) { 57 | goto rndup; 58 | } 59 | 60 | /* Round to even */ 61 | if (r == 0.5) { 62 | r = y - 2.0 * std::floor(0.5 * y); 63 | if (r == 1.0) { 64 | rndup: 65 | y += 1.0; 66 | } 67 | } 68 | 69 | /* Else round down. */ 70 | return (y); 71 | } 72 | 73 | } // namespace cephes 74 | } // namespace xsf 75 | -------------------------------------------------------------------------------- /include/xsf/cephes/trig.h: -------------------------------------------------------------------------------- 1 | /* Translated into C++ by SciPy developers in 2024. 2 | * 3 | * Original author: Josh Wilson, 2020. 4 | */ 5 | 6 | /* 7 | * Implement sin(pi * x) and cos(pi * x) for real x. Since the periods 8 | * of these functions are integral (and thus representable in double 9 | * precision), it's possible to compute them with greater accuracy 10 | * than sin(x) and cos(x). 11 | */ 12 | #pragma once 13 | 14 | #include "../config.h" 15 | 16 | namespace xsf { 17 | namespace cephes { 18 | 19 | /* Compute sin(pi * x). */ 20 | template 21 | XSF_HOST_DEVICE T sinpi(T x) { 22 | T s = 1.0; 23 | 24 | if (x < 0.0) { 25 | x = -x; 26 | s = -1.0; 27 | } 28 | 29 | T r = std::fmod(x, 2.0); 30 | if (r < 0.5) { 31 | return s * std::sin(M_PI * r); 32 | } else if (r > 1.5) { 33 | return s * std::sin(M_PI * (r - 2.0)); 34 | } else { 35 | return -s * std::sin(M_PI * (r - 1.0)); 36 | } 37 | } 38 | 39 | /* Compute cos(pi * x) */ 40 | template 41 | XSF_HOST_DEVICE T cospi(T x) { 42 | if (x < 0.0) { 43 | x = -x; 44 | } 45 | 46 | T r = std::fmod(x, 2.0); 47 | if (r == 0.5) { 48 | // We don't want to return -0.0 49 | return 0.0; 50 | } 51 | if (r < 1.0) { 52 | return -std::sin(M_PI * (r - 0.5)); 53 | } else { 54 | return std::sin(M_PI * (r - 1.5)); 55 | } 56 | } 57 | } // namespace cephes 58 | } // namespace xsf 59 | -------------------------------------------------------------------------------- /include/xsf/cephes/yv.h: -------------------------------------------------------------------------------- 1 | /* Translated into C++ by SciPy developers in 2024. 2 | * Original header with Copyright information appears below. 3 | */ 4 | 5 | /* 6 | * Cephes Math Library Release 2.8: June, 2000 7 | * Copyright 1984, 1987, 2000 by Stephen L. Moshier 8 | */ 9 | #pragma once 10 | 11 | #include "../config.h" 12 | #include "../error.h" 13 | 14 | #include "const.h" 15 | #include "jv.h" 16 | #include "yn.h" 17 | 18 | namespace xsf { 19 | namespace cephes { 20 | 21 | /* 22 | * Bessel function of noninteger order 23 | */ 24 | XSF_HOST_DEVICE inline double yv(double v, double x) { 25 | double y, t; 26 | int n; 27 | 28 | n = v; 29 | if (n == v) { 30 | y = yn(n, x); 31 | return (y); 32 | } else if (v == std::floor(v)) { 33 | /* Zero in denominator. */ 34 | set_error("yv", SF_ERROR_DOMAIN, NULL); 35 | return std::numeric_limits::quiet_NaN(); 36 | } 37 | 38 | t = M_PI * v; 39 | y = (std::cos(t) * jv(v, x) - jv(-v, x)) / std::sin(t); 40 | 41 | if (std::isinf(y)) { 42 | if (v > 0) { 43 | set_error("yv", SF_ERROR_OVERFLOW, NULL); 44 | return -std::numeric_limits::infinity(); 45 | } else if (v < -1e10) { 46 | /* Whether it's +inf or -inf is numerically ill-defined. */ 47 | set_error("yv", SF_ERROR_DOMAIN, NULL); 48 | return std::numeric_limits::quiet_NaN(); 49 | } 50 | } 51 | 52 | return (y); 53 | } 54 | } // namespace cephes 55 | } // namespace xsf 56 | -------------------------------------------------------------------------------- /include/xsf/ellip.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "cephes/ellie.h" 4 | #include "cephes/ellik.h" 5 | #include "cephes/ellpe.h" 6 | #include "cephes/ellpj.h" 7 | #include "cephes/ellpk.h" 8 | #include "config.h" 9 | 10 | namespace xsf { 11 | 12 | inline double ellipe(double m) { return cephes::ellpe(m); } 13 | 14 | inline float ellipe(float m) { return ellipe(static_cast(m)); } 15 | 16 | inline double ellipeinc(double phi, double m) { return cephes::ellie(phi, m); } 17 | 18 | inline float ellipeinc(float phi, float m) { return ellipeinc(static_cast(phi), static_cast(m)); } 19 | 20 | inline void ellipj(double u, double m, double &sn, double &cn, double &dn, double &ph) { 21 | cephes::ellpj(u, m, &sn, &cn, &dn, &ph); 22 | } 23 | 24 | inline void ellipj(float u, float m, float &sn, float &cn, float &dn, float &ph) { 25 | double sn_double; 26 | double cn_double; 27 | double dn_double; 28 | double ph_double; 29 | ellipj(static_cast(u), static_cast(m), sn_double, cn_double, dn_double, ph_double); 30 | 31 | sn = sn_double; 32 | cn = cn_double; 33 | dn = dn_double; 34 | ph = ph_double; 35 | } 36 | 37 | inline double ellipkinc(double phi, double m) { return cephes::ellik(phi, m); } 38 | 39 | inline float ellipkinc(float phi, float m) { return ellipkinc(static_cast(phi), static_cast(m)); } 40 | 41 | XSF_HOST_DEVICE inline double ellipk(double m) { return cephes::ellpk(1.0 - m); } 42 | 43 | XSF_HOST_DEVICE inline float ellipk(float m) { return ellipk(static_cast(m)); } 44 | 45 | inline double ellipkm1(double p) { return cephes::ellpk(p); } 46 | 47 | inline float ellipkm1(float p) { return ellipkm1(static_cast(p)); } 48 | 49 | } // namespace xsf 50 | -------------------------------------------------------------------------------- /include/xsf/evalpoly.h: -------------------------------------------------------------------------------- 1 | /* Translated from Cython into C++ by SciPy developers in 2024. 2 | * 3 | * Original author: Josh Wilson, 2016. 4 | */ 5 | 6 | /* Evaluate polynomials. 7 | * 8 | * All of the coefficients are stored in reverse order, i.e. if the 9 | * polynomial is 10 | * 11 | * u_n x^n + u_{n - 1} x^{n - 1} + ... + u_0, 12 | * 13 | * then coeffs[0] = u_n, coeffs[1] = u_{n - 1}, ..., coeffs[n] = u_0. 14 | * 15 | * References 16 | * ---------- 17 | * [1] Knuth, "The Art of Computer Programming, Volume II" 18 | */ 19 | 20 | #pragma once 21 | 22 | #include "config.h" 23 | 24 | namespace xsf { 25 | 26 | XSF_HOST_DEVICE inline std::complex cevalpoly(const double *coeffs, int degree, std::complex z) { 27 | /* Evaluate a polynomial with real coefficients at a complex point. 28 | * 29 | * Uses equation (3) in section 4.6.4 of [1]. Note that it is more 30 | * efficient than Horner's method. 31 | */ 32 | double a = coeffs[0]; 33 | double b = coeffs[1]; 34 | double r = 2 * z.real(); 35 | double s = std::norm(z); 36 | double tmp; 37 | 38 | for (int j = 2; j < degree + 1; j++) { 39 | tmp = b; 40 | b = std::fma(-s, a, coeffs[j]); 41 | a = std::fma(r, a, tmp); 42 | } 43 | 44 | return z * a + b; 45 | } 46 | 47 | } // namespace xsf 48 | -------------------------------------------------------------------------------- /include/xsf/numbers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "config.h" 4 | 5 | namespace xsf { 6 | namespace numbers { 7 | 8 | template 9 | std::complex i_v; 10 | 11 | template <> 12 | std::complex i_v = std::literals::complex_literals::operator""if(1.0L); 13 | 14 | template <> 15 | std::complex i_v = std::literals::complex_literals::operator""i(1.0L); 16 | 17 | } // namespace numbers 18 | } // namespace xsf 19 | -------------------------------------------------------------------------------- /include/xsf/zlog1.h: -------------------------------------------------------------------------------- 1 | /* Translated from Cython into C++ by SciPy developers in 2023. 2 | * 3 | * Original author: Josh Wilson, 2016. 4 | */ 5 | 6 | #pragma once 7 | 8 | #include "config.h" 9 | 10 | namespace xsf { 11 | namespace detail { 12 | 13 | XSF_HOST_DEVICE inline std::complex zlog1(std::complex z) { 14 | /* Compute log, paying special attention to accuracy around 1. We 15 | * implement this ourselves because some systems (most notably the 16 | * Travis CI machines) are weak in this regime. */ 17 | std::complex coeff = -1.0; 18 | std::complex res = 0.0; 19 | 20 | if (std::abs(z - 1.0) > 0.1) { 21 | return std::log(z); 22 | } 23 | 24 | z -= 1.0; 25 | for (int n = 1; n < 17; n++) { 26 | coeff *= -z; 27 | res += coeff / static_cast(n); 28 | if (std::abs(res / coeff) < std::numeric_limits::epsilon()) { 29 | break; 30 | } 31 | } 32 | return res; 33 | } 34 | } // namespace detail 35 | } // namespace xsf 36 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project( 2 | 'xsf', 3 | 'cpp', 4 | version : '0.1.1.dev0', 5 | license : 'BSD-3-Clause AND MIT AND BSD-3-Clause-LBNL AND Apache-2.0 WITH LLVM-exception', 6 | license_files : ['LICENSE', 'LICENSES_bundled.txt'], 7 | meson_version : '>=1.5.0' 8 | ) 9 | 10 | xsf_dep = declare_dependency(include_directories : 'include') 11 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(XSREF_TABLES_PATH "${CMAKE_SOURCE_DIR}/xsref/tables") 2 | find_package(Catch2 3 REQUIRED) 3 | find_package(Arrow REQUIRED) 4 | find_package(Parquet REQUIRED) 5 | 6 | add_library(xsf INTERFACE) 7 | target_include_directories(xsf INTERFACE ${CMAKE_SOURCE_DIR}/include) 8 | 9 | set(TEST_BASE_DIR "${CMAKE_SOURCE_DIR}/tests") 10 | 11 | include(${CMAKE_SOURCE_DIR}/tests/Coverage.cmake) 12 | 13 | file(GLOB TEST_SOURCES "*/test_*.cpp") 14 | foreach(test_file ${TEST_SOURCES}) 15 | # Families of tests go in subfolders of xsf/tests. Test files in different 16 | # folders can have the same name. Try to generate a unique target name based 17 | # on the test name and its parent folder(s). 18 | get_filename_component(test_name ${test_file} NAME_WE) 19 | get_filename_component(test_dir ${test_file} DIRECTORY) 20 | file(RELATIVE_PATH test_dir ${TEST_BASE_DIR} ${test_dir}) 21 | string(REPLACE "/" "-" test_dir ${test_dir}) 22 | set(target_name ${test_dir}_${test_name}) 23 | 24 | add_executable(${target_name} ${test_file}) 25 | 26 | target_link_libraries(${target_name} PRIVATE Catch2::Catch2WithMain Arrow::arrow_shared Parquet::parquet_shared xsf) 27 | 28 | target_compile_definitions(${target_name} PRIVATE XSREF_TABLES_PATH="${XSREF_TABLES_PATH}") 29 | include(CTest) 30 | include(Catch) 31 | catch_discover_tests(${target_name}) 32 | endforeach() 33 | -------------------------------------------------------------------------------- /tests/Coverage.cmake: -------------------------------------------------------------------------------- 1 | if(CMAKE_BUILD_TYPE STREQUAL "Coverage") 2 | 3 | # Enable coverage compilation option 4 | if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") 5 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") 6 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage") 7 | endif() 8 | if(MSVC) 9 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /coverage") 10 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /coverage") 11 | endif() 12 | 13 | # Add custom targets for generating coverage reports 14 | add_custom_target(coverage 15 | COMMAND lcov --capture --directory . --output-file coverage.info 16 | COMMAND lcov --output-file coverage.info --extract coverage.info '*/include/xsf/*' 17 | COMMAND lcov --list coverage.info 18 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 19 | COMMENT "Generating coverage report" 20 | ) 21 | 22 | # Generate coverage reports in HTML format 23 | add_custom_target(coverage_html 24 | COMMAND genhtml --demangle-cpp --legend coverage.info --output-directory coverage_report 25 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 26 | COMMENT "Generating HTML coverage report" 27 | ) 28 | add_dependencies(coverage_html coverage) 29 | 30 | endif() # CMAKE_BUILD_TYPE=Coverage 31 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_bdtr.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "bdtr"}; 8 | 9 | TEST_CASE("bdtr dpd->d scipy_special_tests", "[bdtr][dpd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_p_d-d.parquet", tables_path / "Out_d_p_d-d.parquet", 14 | tables_path / ("Err_d_p_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [k, n, p] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::bdtr(k, n, p); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(k, n, p, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_bdtrc.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "bdtrc"}; 8 | 9 | TEST_CASE("bdtrc dpd->d scipy_special_tests", "[bdtrc][dpd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_p_d-d.parquet", tables_path / "Out_d_p_d-d.parquet", 14 | tables_path / ("Err_d_p_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [k, n, p] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::bdtrc(k, n, p); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(k, n, p, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_bdtri.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "bdtri"}; 8 | 9 | TEST_CASE("bdtri dpd->d scipy_special_tests", "[bdtri][dpd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_p_d-d.parquet", tables_path / "Out_d_p_d-d.parquet", 14 | tables_path / ("Err_d_p_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [k, n, y] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::bdtri(k, n, y); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(k, n, y, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_bei.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "bei"}; 8 | 9 | TEST_CASE("bei d->d scipy_special_tests", "[bei][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::bei(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_beip.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "beip"}; 8 | 9 | TEST_CASE("beip d->d scipy_special_tests", "[beip][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::beip(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_ber.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "ber"}; 8 | 9 | TEST_CASE("ber d->d scipy_special_tests", "[ber][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::ber(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_berp.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "berp"}; 8 | 9 | TEST_CASE("berp d->d scipy_special_tests", "[berp][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::berp(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_besselpoly.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "besselpoly"}; 8 | 9 | TEST_CASE("besselpoly ddd->d scipy_special_tests", "[besselpoly][ddd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d_d-d.parquet", tables_path / "Out_d_d_d-d.parquet", 14 | tables_path / ("Err_d_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [a, lmb, nu] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::besselpoly(a, lmb, nu); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(a, lmb, nu, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_beta.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "beta"}; 8 | 9 | TEST_CASE("beta dd->d scipy_special_tests", "[beta][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [a, b] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::beta(a, b); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(a, b, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_betaln.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "betaln"}; 8 | 9 | TEST_CASE("betaln dd->d scipy_special_tests", "[betaln][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [a, b] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::betaln(a, b); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(a, b, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_binom.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "binom"}; 8 | 9 | TEST_CASE("binom dd->d scipy_special_tests", "[binom][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [n, k] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::binom(n, k); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(n, k, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cbrt.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cbrt"}; 8 | 9 | TEST_CASE("cephes::cbrt d->d scipy_special_tests", "[cephes::cbrt][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cbrt(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cem.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cem"}; 8 | 9 | TEST_CASE("cem ddd->dd scipy_special_tests", "[cem][ddd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::tuple, std::tuple>( 14 | tables_path / "In_d_d_d-d_d.parquet", tables_path / "Out_d_d_d-d_d.parquet", 15 | tables_path / ("Err_d_d_d-d_d_" + get_platform_str() + ".parquet") 16 | ) 17 | ); 18 | 19 | auto [m, q, x] = input; 20 | auto [desired0, desired1, fallback] = output; 21 | 22 | double out0; 23 | double out1; 24 | 25 | xsf::cem(m, q, x, out0, out1); 26 | auto [tol0, tol1] = tol; 27 | 28 | auto error0 = xsf::extended_relative_error(out0, desired0); 29 | tol0 = adjust_tolerance(tol0); 30 | CAPTURE(m, q, x, out0, desired0, error0, tol0, fallback); 31 | REQUIRE(error0 <= tol0); 32 | 33 | auto error1 = xsf::extended_relative_error(out1, desired1); 34 | tol1 = adjust_tolerance(tol1); 35 | CAPTURE(m, q, x, out1, desired1, error1, tol1, fallback); 36 | REQUIRE(error1 <= tol1); 37 | } 38 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cem_cva.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cem_cva"}; 8 | 9 | TEST_CASE("cem_cva dd->d scipy_special_tests", "[cem_cva][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [m, q] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cem_cva(m, q); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(m, q, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_chdtr.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "chdtr"}; 8 | 9 | TEST_CASE("chdtr dd->d scipy_special_tests", "[chdtr][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::chdtr(v, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(v, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("chdtr ff->f scipy_special_tests", "[chdtr][ff->f][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, std::tuple, float>( 31 | tables_path / "In_f_f-f.parquet", tables_path / "Out_f_f-f.parquet", 32 | tables_path / ("Err_f_f-f_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto [v, x] = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::chdtr(v, x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(v, x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_chdtrc.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "chdtrc"}; 8 | 9 | TEST_CASE("chdtrc dd->d scipy_special_tests", "[chdtrc][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::chdtrc(v, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(v, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("chdtrc ff->f scipy_special_tests", "[chdtrc][ff->f][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, std::tuple, float>( 31 | tables_path / "In_f_f-f.parquet", tables_path / "Out_f_f-f.parquet", 32 | tables_path / ("Err_f_f-f_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto [v, x] = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::chdtrc(v, x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(v, x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_chdtri.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "chdtri"}; 8 | 9 | TEST_CASE("chdtri dd->d scipy_special_tests", "[chdtri][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, p] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::chdtri(v, p); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(v, p, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cosdg.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cosdg"}; 8 | 9 | TEST_CASE("cosdg d->d scipy_special_tests", "[cosdg][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cosdg(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cosm1.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cosm1"}; 8 | 9 | TEST_CASE("cosm1 d->d scipy_special_tests", "[cosm1][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cosm1(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cospi.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cospi"}; 8 | 9 | TEST_CASE("cospi D->D scipy_special_tests", "[cospi][D->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, bool>, double>( 13 | tables_path / "In_cd-cd.parquet", tables_path / "Out_cd-cd.parquet", 14 | tables_path / ("Err_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cospi(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("cospi d->d scipy_special_tests", "[cospi][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto x = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::cospi(x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cotdg.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cotdg"}; 8 | 9 | TEST_CASE("cotdg d->d scipy_special_tests", "[cotdg][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cotdg(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_bessel_i.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_bessel_i"}; 8 | 9 | TEST_CASE("cyl_bessel_i dd->d scipy_special_tests", "[cyl_bessel_i][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, z] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_bessel_i(v, z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(v, z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("cyl_bessel_i dD->D scipy_special_tests", "[cyl_bessel_i][dD->D][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases>, std::tuple, bool>, double>( 31 | tables_path / "In_d_cd-cd.parquet", tables_path / "Out_d_cd-cd.parquet", 32 | tables_path / ("Err_d_cd-cd_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto [v, z] = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::cyl_bessel_i(v, z); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol, 12.0); 41 | CAPTURE(v, z, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_bessel_i0.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_bessel_i0"}; 8 | 9 | TEST_CASE("cyl_bessel_i0 f->f scipy_special_tests", "[cyl_bessel_i0][f->f][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, float>( 13 | tables_path / "In_f-f.parquet", tables_path / "Out_f-f.parquet", 14 | tables_path / ("Err_f-f_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto z = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_bessel_i0(z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("cyl_bessel_i0 d->d scipy_special_tests", "[cyl_bessel_i0][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto z = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::cyl_bessel_i0(z); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(z, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_bessel_i0e.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_bessel_i0e"}; 8 | 9 | TEST_CASE("cyl_bessel_i0e f->f scipy_special_tests", "[cyl_bessel_i0e][f->f][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, float>( 13 | tables_path / "In_f-f.parquet", tables_path / "Out_f-f.parquet", 14 | tables_path / ("Err_f-f_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto z = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_bessel_i0e(z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("cyl_bessel_i0e d->d scipy_special_tests", "[cyl_bessel_i0e][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto z = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::cyl_bessel_i0e(z); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(z, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_bessel_i1.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_bessel_i1"}; 8 | 9 | TEST_CASE("cyl_bessel_i1 f->f scipy_special_tests", "[cyl_bessel_i1][f->f][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, float>( 13 | tables_path / "In_f-f.parquet", tables_path / "Out_f-f.parquet", 14 | tables_path / ("Err_f-f_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto z = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_bessel_i1(z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("cyl_bessel_i1 d->d scipy_special_tests", "[cyl_bessel_i1][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto z = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::cyl_bessel_i1(z); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(z, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_bessel_i1e.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_bessel_i1e"}; 8 | 9 | TEST_CASE("cyl_bessel_i1e f->f scipy_special_tests", "[cyl_bessel_i1e][f->f][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, float>( 13 | tables_path / "In_f-f.parquet", tables_path / "Out_f-f.parquet", 14 | tables_path / ("Err_f-f_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto z = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_bessel_i1e(z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("cyl_bessel_i1e d->d scipy_special_tests", "[cyl_bessel_i1e][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto z = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::cyl_bessel_i1e(z); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(z, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_bessel_j.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_bessel_j"}; 8 | 9 | TEST_CASE("cyl_bessel_j dd->d scipy_special_tests", "[cyl_bessel_j][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, z] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_bessel_j(v, z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(v, z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("cyl_bessel_j dD->D scipy_special_tests", "[cyl_bessel_j][dD->D][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases>, std::tuple, bool>, double>( 31 | tables_path / "In_d_cd-cd.parquet", tables_path / "Out_d_cd-cd.parquet", 32 | tables_path / ("Err_d_cd-cd_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto [v, z] = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::cyl_bessel_j(v, z); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(v, z, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_bessel_j0.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_bessel_j0"}; 8 | 9 | TEST_CASE("cyl_bessel_j0 d->d scipy_special_tests", "[cyl_bessel_j0][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_bessel_j0(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_bessel_j1.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_bessel_j1"}; 8 | 9 | TEST_CASE("cyl_bessel_j1 d->d scipy_special_tests", "[cyl_bessel_j1][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_bessel_j1(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_bessel_k.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_bessel_k"}; 8 | 9 | TEST_CASE("cyl_bessel_k dd->d scipy_special_tests", "[cyl_bessel_k][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, z] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_bessel_k(v, z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(v, z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("cyl_bessel_k dD->D scipy_special_tests", "[cyl_bessel_k][dD->D][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases>, std::tuple, bool>, double>( 31 | tables_path / "In_d_cd-cd.parquet", tables_path / "Out_d_cd-cd.parquet", 32 | tables_path / ("Err_d_cd-cd_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto [v, z] = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::cyl_bessel_k(v, z); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(v, z, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_bessel_k0.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_bessel_k0"}; 8 | 9 | TEST_CASE("cyl_bessel_k0 d->d scipy_special_tests", "[cyl_bessel_k0][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_bessel_k0(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_bessel_k0e.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_bessel_k0e"}; 8 | 9 | TEST_CASE("cyl_bessel_k0e d->d scipy_special_tests", "[cyl_bessel_k0e][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_bessel_k0e(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_bessel_k1.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_bessel_k1"}; 8 | 9 | TEST_CASE("cyl_bessel_k1 d->d scipy_special_tests", "[cyl_bessel_k1][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_bessel_k1(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_bessel_k1e.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_bessel_k1e"}; 8 | 9 | TEST_CASE("cyl_bessel_k1e d->d scipy_special_tests", "[cyl_bessel_k1e][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_bessel_k1e(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_bessel_y.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_bessel_y"}; 8 | 9 | TEST_CASE("cyl_bessel_y dd->d scipy_special_tests", "[cyl_bessel_y][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, z] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_bessel_y(v, z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(v, z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("cyl_bessel_y dD->D scipy_special_tests", "[cyl_bessel_y][dD->D][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases>, std::tuple, bool>, double>( 31 | tables_path / "In_d_cd-cd.parquet", tables_path / "Out_d_cd-cd.parquet", 32 | tables_path / ("Err_d_cd-cd_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto [v, z] = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::cyl_bessel_y(v, z); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(v, z, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_bessel_y0.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_bessel_y0"}; 8 | 9 | TEST_CASE("cyl_bessel_y0 d->d scipy_special_tests", "[cyl_bessel_y0][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto z = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_bessel_y0(z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_bessel_y1.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_bessel_y1"}; 8 | 9 | TEST_CASE("cyl_bessel_y1 d->d scipy_special_tests", "[cyl_bessel_y1][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto z = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_bessel_y1(z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_hankel_1.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_hankel_1"}; 8 | 9 | TEST_CASE("cyl_hankel_1 dD->D scipy_special_tests", "[cyl_hankel_1][dD->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases>, std::tuple, bool>, double>( 13 | tables_path / "In_d_cd-cd.parquet", tables_path / "Out_d_cd-cd.parquet", 14 | tables_path / ("Err_d_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, z] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_hankel_1(v, z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(v, z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_hankel_1e.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_hankel_1e"}; 8 | 9 | TEST_CASE("cyl_hankel_1e dD->D scipy_special_tests", "[cyl_hankel_1e][dD->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases>, std::tuple, bool>, double>( 13 | tables_path / "In_d_cd-cd.parquet", tables_path / "Out_d_cd-cd.parquet", 14 | tables_path / ("Err_d_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, z] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_hankel_1e(v, z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(v, z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_hankel_2.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_hankel_2"}; 8 | 9 | TEST_CASE("cyl_hankel_2 dD->D scipy_special_tests", "[cyl_hankel_2][dD->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases>, std::tuple, bool>, double>( 13 | tables_path / "In_d_cd-cd.parquet", tables_path / "Out_d_cd-cd.parquet", 14 | tables_path / ("Err_d_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, z] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_hankel_2(v, z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(v, z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_cyl_hankel_2e.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "cyl_hankel_2e"}; 8 | 9 | TEST_CASE("cyl_hankel_2e dD->D scipy_special_tests", "[cyl_hankel_2e][dD->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases>, std::tuple, bool>, double>( 13 | tables_path / "In_d_cd-cd.parquet", tables_path / "Out_d_cd-cd.parquet", 14 | tables_path / ("Err_d_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, z] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cyl_hankel_2e(v, z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(v, z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_dawsn.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "dawsn"}; 8 | 9 | TEST_CASE("dawsn D->D scipy_special_tests", "[dawsn][D->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, bool>, double>( 13 | tables_path / "In_cd-cd.parquet", tables_path / "Out_cd-cd.parquet", 14 | tables_path / ("Err_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::dawsn(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("dawsn d->d scipy_special_tests", "[dawsn][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto x = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::dawsn(x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_digamma.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "digamma"}; 8 | 9 | TEST_CASE("digamma D->D scipy_special_tests", "[digamma][D->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, bool>, double>( 13 | tables_path / "In_cd-cd.parquet", tables_path / "Out_cd-cd.parquet", 14 | tables_path / ("Err_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::digamma(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("digamma d->d scipy_special_tests", "[digamma][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto x = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::digamma(x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_ellipe.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "ellipe"}; 8 | 9 | TEST_CASE("ellipe d->d scipy_special_tests", "[ellipe][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto m = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::ellipe(m); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(m, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_ellipeinc.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "ellipeinc"}; 8 | 9 | TEST_CASE("ellipeinc dd->d scipy_special_tests", "[ellipeinc][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [phi, m] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::ellipeinc(phi, m); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(phi, m, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_ellipk.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "ellipk"}; 8 | 9 | TEST_CASE("ellipk d->d scipy_special_tests", "[ellipk][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto m = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::ellipk(m); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(m, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_ellipkinc.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "ellipkinc"}; 8 | 9 | TEST_CASE("ellipkinc dd->d scipy_special_tests", "[ellipkinc][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [phi, m] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::ellipkinc(phi, m); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(phi, m, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_ellipkm1.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "ellipkm1"}; 8 | 9 | TEST_CASE("ellipkm1 d->d scipy_special_tests", "[ellipkm1][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto p = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::ellipkm1(p); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(p, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_erfcinv.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "erfcinv"}; 8 | 9 | TEST_CASE("cephes::erfcinv d->d scipy_special_tests", "[cephes::erfcinv][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cephes::erfcinv(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_erfcx.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "erfcx"}; 8 | 9 | TEST_CASE("erfcx D->D scipy_special_tests", "[erfcx][D->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, bool>, double>( 13 | tables_path / "In_cd-cd.parquet", tables_path / "Out_cd-cd.parquet", 14 | tables_path / ("Err_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::erfcx(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("erfcx d->d scipy_special_tests", "[erfcx][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto x = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::erfcx(x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_erfi.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "erfi"}; 8 | 9 | TEST_CASE("erfi D->D scipy_special_tests", "[erfi][D->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, bool>, double>( 13 | tables_path / "In_cd-cd.parquet", tables_path / "Out_cd-cd.parquet", 14 | tables_path / ("Err_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::erfi(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("erfi d->d scipy_special_tests", "[erfi][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto x = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::erfi(x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_exp1.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "exp1"}; 8 | 9 | TEST_CASE("exp1 D->D scipy_special_tests", "[exp1][D->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, bool>, double>( 13 | tables_path / "In_cd-cd.parquet", tables_path / "Out_cd-cd.parquet", 14 | tables_path / ("Err_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::exp1(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("exp1 d->d scipy_special_tests", "[exp1][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto x = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::exp1(x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_exp10.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "exp10"}; 8 | 9 | TEST_CASE("exp10 d->d scipy_special_tests", "[exp10][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::exp10(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_exp2.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "exp2"}; 8 | 9 | TEST_CASE("exp2 d->d scipy_special_tests", "[exp2][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::exp2(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_expi.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "expi"}; 8 | 9 | TEST_CASE("expi D->D scipy_special_tests", "[expi][D->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, bool>, double>( 13 | tables_path / "In_cd-cd.parquet", tables_path / "Out_cd-cd.parquet", 14 | tables_path / ("Err_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::expi(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("expi d->d scipy_special_tests", "[expi][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto x = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::expi(x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_expit.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "expit"}; 8 | 9 | TEST_CASE("expit f->f scipy_special_tests", "[expit][f->f][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, float>( 13 | tables_path / "In_f-f.parquet", tables_path / "Out_f-f.parquet", 14 | tables_path / ("Err_f-f_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::expit(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("expit d->d scipy_special_tests", "[expit][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto x = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::expit(x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_expm1.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "expm1"}; 8 | 9 | TEST_CASE("expm1 D->D scipy_special_tests", "[expm1][D->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, bool>, double>( 13 | tables_path / "In_cd-cd.parquet", tables_path / "Out_cd-cd.parquet", 14 | tables_path / ("Err_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::expm1(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("expm1 d->d scipy_special_tests", "[expm1][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto x = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::expm1(x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_expn.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "expn"}; 8 | 9 | TEST_CASE("cephes::expn dd->d scipy_special_tests", "[cephes::expn][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [n, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cephes::expn(n, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(n, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("cephes::expn pd->d scipy_special_tests", "[cephes::expn][pd->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, std::tuple, double>( 31 | tables_path / "In_p_d-d.parquet", tables_path / "Out_p_d-d.parquet", 32 | tables_path / ("Err_p_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto [n, x] = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::cephes::expn(n, x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(n, x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_exprel.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "exprel"}; 8 | 9 | TEST_CASE("exprel d->d scipy_special_tests", "[exprel][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::exprel(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_fdtr.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "fdtr"}; 8 | 9 | TEST_CASE("fdtr ddd->d scipy_special_tests", "[fdtr][ddd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d_d-d.parquet", tables_path / "Out_d_d_d-d.parquet", 14 | tables_path / ("Err_d_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [dfn, dfd, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::fdtr(dfn, dfd, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(dfn, dfd, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_fdtrc.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "fdtrc"}; 8 | 9 | TEST_CASE("fdtrc ddd->d scipy_special_tests", "[fdtrc][ddd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d_d-d.parquet", tables_path / "Out_d_d_d-d.parquet", 14 | tables_path / ("Err_d_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [dfn, dfd, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::fdtrc(dfn, dfd, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(dfn, dfd, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_fdtri.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "fdtri"}; 8 | 9 | TEST_CASE("fdtri ddd->d scipy_special_tests", "[fdtri][ddd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d_d-d.parquet", tables_path / "Out_d_d_d-d.parquet", 14 | tables_path / ("Err_d_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [dfn, dfd, p] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::fdtri(dfn, dfd, p); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(dfn, dfd, p, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_gamma.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "gamma"}; 8 | 9 | TEST_CASE("gamma D->D scipy_special_tests", "[gamma][D->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, bool>, double>( 13 | tables_path / "In_cd-cd.parquet", tables_path / "Out_cd-cd.parquet", 14 | tables_path / ("Err_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::gamma(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("gamma d->d scipy_special_tests", "[gamma][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto x = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::gamma(x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_gammainc.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "gammainc"}; 8 | 9 | TEST_CASE("gammainc dd->d scipy_special_tests", "[gammainc][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [a, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::gammainc(a, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(a, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("gammainc ff->f scipy_special_tests", "[gammainc][ff->f][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, std::tuple, float>( 31 | tables_path / "In_f_f-f.parquet", tables_path / "Out_f_f-f.parquet", 32 | tables_path / ("Err_f_f-f_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto [a, x] = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::gammainc(a, x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(a, x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_gammaincc.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "gammaincc"}; 8 | 9 | TEST_CASE("gammaincc dd->d scipy_special_tests", "[gammaincc][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [a, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::gammaincc(a, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(a, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("gammaincc ff->f scipy_special_tests", "[gammaincc][ff->f][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, std::tuple, float>( 31 | tables_path / "In_f_f-f.parquet", tables_path / "Out_f_f-f.parquet", 32 | tables_path / ("Err_f_f-f_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto [a, x] = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::gammaincc(a, x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(a, x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_gammainccinv.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "gammainccinv"}; 8 | 9 | TEST_CASE("gammainccinv dd->d scipy_special_tests", "[gammainccinv][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [a, y] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::gammainccinv(a, y); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(a, y, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_gammaincinv.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "gammaincinv"}; 8 | 9 | TEST_CASE("gammaincinv dd->d scipy_special_tests", "[gammaincinv][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [a, y] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::gammaincinv(a, y); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(a, y, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_gammaln.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "gammaln"}; 8 | 9 | TEST_CASE("gammaln f->f scipy_special_tests", "[gammaln][f->f][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, float>( 13 | tables_path / "In_f-f.parquet", tables_path / "Out_f-f.parquet", 14 | tables_path / ("Err_f-f_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::gammaln(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("gammaln d->d scipy_special_tests", "[gammaln][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto x = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::gammaln(x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_gammasgn.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "gammasgn"}; 8 | 9 | TEST_CASE("gammasgn d->d scipy_special_tests", "[gammasgn][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::gammasgn(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_gdtr.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "gdtr"}; 8 | 9 | TEST_CASE("gdtr ddd->d scipy_special_tests", "[gdtr][ddd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d_d-d.parquet", tables_path / "Out_d_d_d-d.parquet", 14 | tables_path / ("Err_d_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [a, b, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::gdtr(a, b, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(a, b, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_gdtrc.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "gdtrc"}; 8 | 9 | TEST_CASE("gdtrc ddd->d scipy_special_tests", "[gdtrc][ddd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d_d-d.parquet", tables_path / "Out_d_d_d-d.parquet", 14 | tables_path / ("Err_d_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [a, b, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::gdtrc(a, b, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(a, b, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_gdtrib.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "gdtrib"}; 8 | 9 | TEST_CASE("gdtrib ddd->d scipy_special_tests", "[gdtrib][ddd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d_d-d.parquet", tables_path / "Out_d_d_d-d.parquet", 14 | tables_path / ("Err_d_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [a, p, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::gdtrib(a, p, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(a, p, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_hyp1f1.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "hyp1f1"}; 8 | 9 | TEST_CASE("hyp1f1 ddD->D scipy_special_tests", "[hyp1f1][ddD->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple>, std::tuple, bool>, double>( 14 | tables_path / "In_d_d_cd-cd.parquet", tables_path / "Out_d_d_cd-cd.parquet", 15 | tables_path / ("Err_d_d_cd-cd_" + get_platform_str() + ".parquet") 16 | ) 17 | ); 18 | 19 | auto [a, b, z] = input; 20 | auto [desired, fallback] = output; 21 | auto out = xsf::hyp1f1(a, b, z); 22 | auto error = xsf::extended_relative_error(out, desired); 23 | tol = adjust_tolerance(tol); 24 | CAPTURE(a, b, z, out, desired, error, tol, fallback); 25 | REQUIRE(error <= tol); 26 | } 27 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_it1i0k0.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "it1i0k0"}; 8 | 9 | TEST_CASE("it1i0k0 d->dd scipy_special_tests", "[it1i0k0][d->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple>( 13 | tables_path / "In_d-d_d.parquet", tables_path / "Out_d-d_d.parquet", 14 | tables_path / ("Err_d-d_d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired0, desired1, fallback] = output; 20 | 21 | double out0; 22 | double out1; 23 | 24 | xsf::it1i0k0(x, out0, out1); 25 | auto [tol0, tol1] = tol; 26 | 27 | auto error0 = xsf::extended_relative_error(out0, desired0); 28 | tol0 = adjust_tolerance(tol0); 29 | CAPTURE(x, out0, desired0, error0, tol0, fallback); 30 | REQUIRE(error0 <= tol0); 31 | 32 | auto error1 = xsf::extended_relative_error(out1, desired1); 33 | tol1 = adjust_tolerance(tol1); 34 | CAPTURE(x, out1, desired1, error1, tol1, fallback); 35 | REQUIRE(error1 <= tol1); 36 | } 37 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_it1j0y0.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "it1j0y0"}; 8 | 9 | TEST_CASE("it1j0y0 d->dd scipy_special_tests", "[it1j0y0][d->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple>( 13 | tables_path / "In_d-d_d.parquet", tables_path / "Out_d-d_d.parquet", 14 | tables_path / ("Err_d-d_d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired0, desired1, fallback] = output; 20 | 21 | double out0; 22 | double out1; 23 | 24 | xsf::it1j0y0(x, out0, out1); 25 | auto [tol0, tol1] = tol; 26 | 27 | auto error0 = xsf::extended_relative_error(out0, desired0); 28 | tol0 = adjust_tolerance(tol0); 29 | CAPTURE(x, out0, desired0, error0, tol0, fallback); 30 | REQUIRE(error0 <= tol0); 31 | 32 | auto error1 = xsf::extended_relative_error(out1, desired1); 33 | tol1 = adjust_tolerance(tol1); 34 | CAPTURE(x, out1, desired1, error1, tol1, fallback); 35 | REQUIRE(error1 <= tol1); 36 | } 37 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_it2i0k0.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "it2i0k0"}; 8 | 9 | TEST_CASE("it2i0k0 d->dd scipy_special_tests", "[it2i0k0][d->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple>( 13 | tables_path / "In_d-d_d.parquet", tables_path / "Out_d-d_d.parquet", 14 | tables_path / ("Err_d-d_d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired0, desired1, fallback] = output; 20 | 21 | double out0; 22 | double out1; 23 | 24 | xsf::it2i0k0(x, out0, out1); 25 | auto [tol0, tol1] = tol; 26 | 27 | auto error0 = xsf::extended_relative_error(out0, desired0); 28 | tol0 = adjust_tolerance(tol0); 29 | CAPTURE(x, out0, desired0, error0, tol0, fallback); 30 | REQUIRE(error0 <= tol0); 31 | 32 | auto error1 = xsf::extended_relative_error(out1, desired1); 33 | tol1 = adjust_tolerance(tol1); 34 | CAPTURE(x, out1, desired1, error1, tol1, fallback); 35 | REQUIRE(error1 <= tol1); 36 | } 37 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_it2j0y0.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "it2j0y0"}; 8 | 9 | TEST_CASE("it2j0y0 d->dd scipy_special_tests", "[it2j0y0][d->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple>( 13 | tables_path / "In_d-d_d.parquet", tables_path / "Out_d-d_d.parquet", 14 | tables_path / ("Err_d-d_d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired0, desired1, fallback] = output; 20 | 21 | double out0; 22 | double out1; 23 | 24 | xsf::it2j0y0(x, out0, out1); 25 | auto [tol0, tol1] = tol; 26 | 27 | auto error0 = xsf::extended_relative_error(out0, desired0); 28 | tol0 = adjust_tolerance(tol0); 29 | CAPTURE(x, out0, desired0, error0, tol0, fallback); 30 | REQUIRE(error0 <= tol0); 31 | 32 | auto error1 = xsf::extended_relative_error(out1, desired1); 33 | tol1 = adjust_tolerance(tol1); 34 | CAPTURE(x, out1, desired1, error1, tol1, fallback); 35 | REQUIRE(error1 <= tol1); 36 | } 37 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_it2struve0.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "it2struve0"}; 8 | 9 | TEST_CASE("it2struve0 d->d scipy_special_tests", "[it2struve0][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::it2struve0(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_itmodstruve0.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "itmodstruve0"}; 8 | 9 | TEST_CASE("itmodstruve0 d->d scipy_special_tests", "[itmodstruve0][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::itmodstruve0(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_itstruve0.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "itstruve0"}; 8 | 9 | TEST_CASE("itstruve0 d->d scipy_special_tests", "[itstruve0][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::itstruve0(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_iv_ratio.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "iv_ratio"}; 8 | 9 | TEST_CASE("iv_ratio dd->d scipy_special_tests", "[iv_ratio][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::iv_ratio(v, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(v, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_iv_ratio_c.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "iv_ratio_c"}; 8 | 9 | TEST_CASE("iv_ratio_c dd->d scipy_special_tests", "[iv_ratio_c][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::iv_ratio_c(v, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(v, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_kei.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "kei"}; 8 | 9 | TEST_CASE("kei d->d scipy_special_tests", "[kei][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::kei(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_keip.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "keip"}; 8 | 9 | TEST_CASE("keip d->d scipy_special_tests", "[keip][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::keip(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_ker.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "ker"}; 8 | 9 | TEST_CASE("ker d->d scipy_special_tests", "[ker][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::ker(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_kerp.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "kerp"}; 8 | 9 | TEST_CASE("kerp d->d scipy_special_tests", "[kerp][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::kerp(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_kolmogc.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "kolmogc"}; 8 | 9 | TEST_CASE("kolmogc d->d scipy_special_tests", "[kolmogc][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::kolmogc(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_kolmogci.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "kolmogci"}; 8 | 9 | TEST_CASE("kolmogci d->d scipy_special_tests", "[kolmogci][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::kolmogci(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_kolmogi.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "kolmogi"}; 8 | 9 | TEST_CASE("kolmogi d->d scipy_special_tests", "[kolmogi][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::kolmogi(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_kolmogorov.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "kolmogorov"}; 8 | 9 | TEST_CASE("kolmogorov d->d scipy_special_tests", "[kolmogorov][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::kolmogorov(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_kolmogp.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "kolmogp"}; 8 | 9 | TEST_CASE("kolmogp d->d scipy_special_tests", "[kolmogp][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::kolmogp(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_lambertw.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "lambertw"}; 8 | 9 | TEST_CASE("lambertw Dpd->D scipy_special_tests", "[lambertw][Dpd->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::ptrdiff_t, double>, std::tuple, bool>, double>( 14 | tables_path / "In_cd_p_d-cd.parquet", tables_path / "Out_cd_p_d-cd.parquet", 15 | tables_path / ("Err_cd_p_d-cd_" + get_platform_str() + ".parquet") 16 | ) 17 | ); 18 | 19 | auto [z, k, eps] = input; 20 | auto [desired, fallback] = output; 21 | auto out = xsf::lambertw(z, k, eps); 22 | auto error = xsf::extended_relative_error(out, desired); 23 | tol = adjust_tolerance(tol); 24 | CAPTURE(z, k, eps, out, desired, error, tol, fallback); 25 | REQUIRE(error <= tol); 26 | } 27 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_lanczos_sum_expg_scaled.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "lanczos_sum_expg_scaled"}; 8 | 9 | TEST_CASE( 10 | "cephes::lanczos_sum_expg_scaled d->d scipy_special_tests", 11 | "[cephes::lanczos_sum_expg_scaled][d->d][scipy_special_tests]" 12 | ) { 13 | SET_FP_FORMAT() 14 | auto [input, output, tol] = GENERATE( 15 | xsf_test_cases, double>( 16 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 17 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 18 | ) 19 | ); 20 | 21 | auto z = input; 22 | auto [desired, fallback] = output; 23 | auto out = xsf::cephes::lanczos_sum_expg_scaled(z); 24 | auto error = xsf::extended_relative_error(out, desired); 25 | tol = adjust_tolerance(tol); 26 | CAPTURE(z, out, desired, error, tol, fallback); 27 | REQUIRE(error <= tol); 28 | } 29 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_lgam1p.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "lgam1p"}; 8 | 9 | TEST_CASE("cephes::lgam1p d->d scipy_special_tests", "[cephes::lgam1p][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cephes::lgam1p(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_log1p.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "log1p"}; 8 | 9 | TEST_CASE("log1p D->D scipy_special_tests", "[log1p][D->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, bool>, double>( 13 | tables_path / "In_cd-cd.parquet", tables_path / "Out_cd-cd.parquet", 14 | tables_path / ("Err_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto z = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::log1p(z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("log1p d->d scipy_special_tests", "[log1p][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto z = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::log1p(z); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(z, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_log1pmx.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "log1pmx"}; 8 | 9 | TEST_CASE("log1pmx d->d scipy_special_tests", "[log1pmx][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto z = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::log1pmx(z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_log_expit.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "log_expit"}; 8 | 9 | TEST_CASE("log_expit f->f scipy_special_tests", "[log_expit][f->f][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, float>( 13 | tables_path / "In_f-f.parquet", tables_path / "Out_f-f.parquet", 14 | tables_path / ("Err_f-f_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::log_expit(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("log_expit d->d scipy_special_tests", "[log_expit][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto x = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::log_expit(x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_log_wright_bessel.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "log_wright_bessel"}; 8 | 9 | TEST_CASE("log_wright_bessel ddd->d scipy_special_tests", "[log_wright_bessel][ddd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d_d-d.parquet", tables_path / "Out_d_d_d-d.parquet", 14 | tables_path / ("Err_d_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [a, b, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::log_wright_bessel(a, b, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(a, b, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_loggamma.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "loggamma"}; 8 | 9 | TEST_CASE("loggamma D->D scipy_special_tests", "[loggamma][D->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, bool>, double>( 13 | tables_path / "In_cd-cd.parquet", tables_path / "Out_cd-cd.parquet", 14 | tables_path / ("Err_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto z = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::loggamma(z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("loggamma d->d scipy_special_tests", "[loggamma][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto z = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::loggamma(z); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(z, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_logit.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "logit"}; 8 | 9 | TEST_CASE("logit f->f scipy_special_tests", "[logit][f->f][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, float>( 13 | tables_path / "In_f-f.parquet", tables_path / "Out_f-f.parquet", 14 | tables_path / ("Err_f-f_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto p = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::logit(p); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(p, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("logit d->d scipy_special_tests", "[logit][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto p = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::logit(p); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(p, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_mcm1.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "mcm1"}; 8 | 9 | TEST_CASE("mcm1 ddd->dd scipy_special_tests", "[mcm1][ddd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::tuple, std::tuple>( 14 | tables_path / "In_d_d_d-d_d.parquet", tables_path / "Out_d_d_d-d_d.parquet", 15 | tables_path / ("Err_d_d_d-d_d_" + get_platform_str() + ".parquet") 16 | ) 17 | ); 18 | 19 | auto [m, q, x] = input; 20 | auto [desired0, desired1, fallback] = output; 21 | 22 | double out0; 23 | double out1; 24 | 25 | xsf::mcm1(m, q, x, out0, out1); 26 | auto [tol0, tol1] = tol; 27 | 28 | auto error0 = xsf::extended_relative_error(out0, desired0); 29 | tol0 = adjust_tolerance(tol0); 30 | CAPTURE(m, q, x, out0, desired0, error0, tol0, fallback); 31 | REQUIRE(error0 <= tol0); 32 | 33 | auto error1 = xsf::extended_relative_error(out1, desired1); 34 | tol1 = adjust_tolerance(tol1); 35 | CAPTURE(m, q, x, out1, desired1, error1, tol1, fallback); 36 | REQUIRE(error1 <= tol1); 37 | } 38 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_mcm2.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "mcm2"}; 8 | 9 | TEST_CASE("mcm2 ddd->dd scipy_special_tests", "[mcm2][ddd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::tuple, std::tuple>( 14 | tables_path / "In_d_d_d-d_d.parquet", tables_path / "Out_d_d_d-d_d.parquet", 15 | tables_path / ("Err_d_d_d-d_d_" + get_platform_str() + ".parquet") 16 | ) 17 | ); 18 | 19 | auto [m, q, x] = input; 20 | auto [desired0, desired1, fallback] = output; 21 | 22 | double out0; 23 | double out1; 24 | 25 | xsf::mcm2(m, q, x, out0, out1); 26 | auto [tol0, tol1] = tol; 27 | 28 | auto error0 = xsf::extended_relative_error(out0, desired0); 29 | tol0 = adjust_tolerance(tol0); 30 | CAPTURE(m, q, x, out0, desired0, error0, tol0, fallback); 31 | REQUIRE(error0 <= tol0); 32 | 33 | auto error1 = xsf::extended_relative_error(out1, desired1); 34 | tol1 = adjust_tolerance(tol1); 35 | CAPTURE(m, q, x, out1, desired1, error1, tol1, fallback); 36 | REQUIRE(error1 <= tol1); 37 | } 38 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_modified_fresnel_minus.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "modified_fresnel_minus"}; 8 | 9 | TEST_CASE("modified_fresnel_minus d->DD scipy_special_tests", "[modified_fresnel_minus][d->DD][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | double, std::tuple, std::complex, bool>, std::tuple>( 14 | tables_path / "In_d-cd_cd.parquet", tables_path / "Out_d-cd_cd.parquet", 15 | tables_path / ("Err_d-cd_cd_" + get_platform_str() + ".parquet") 16 | ) 17 | ); 18 | 19 | auto x = input; 20 | auto [desired0, desired1, fallback] = output; 21 | 22 | std::complex out0; 23 | std::complex out1; 24 | 25 | xsf::modified_fresnel_minus(x, out0, out1); 26 | auto [tol0, tol1] = tol; 27 | 28 | auto error0 = xsf::extended_relative_error(out0, desired0); 29 | tol0 = adjust_tolerance(tol0); 30 | CAPTURE(x, out0, desired0, error0, tol0, fallback); 31 | REQUIRE(error0 <= tol0); 32 | 33 | auto error1 = xsf::extended_relative_error(out1, desired1); 34 | tol1 = adjust_tolerance(tol1); 35 | CAPTURE(x, out1, desired1, error1, tol1, fallback); 36 | REQUIRE(error1 <= tol1); 37 | } 38 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_modified_fresnel_plus.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "modified_fresnel_plus"}; 8 | 9 | TEST_CASE("modified_fresnel_plus d->DD scipy_special_tests", "[modified_fresnel_plus][d->DD][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | double, std::tuple, std::complex, bool>, std::tuple>( 14 | tables_path / "In_d-cd_cd.parquet", tables_path / "Out_d-cd_cd.parquet", 15 | tables_path / ("Err_d-cd_cd_" + get_platform_str() + ".parquet") 16 | ) 17 | ); 18 | 19 | auto x = input; 20 | auto [desired0, desired1, fallback] = output; 21 | 22 | std::complex out0; 23 | std::complex out1; 24 | 25 | xsf::modified_fresnel_plus(x, out0, out1); 26 | auto [tol0, tol1] = tol; 27 | 28 | auto error0 = xsf::extended_relative_error(out0, desired0); 29 | tol0 = adjust_tolerance(tol0); 30 | CAPTURE(x, out0, desired0, error0, tol0, fallback); 31 | REQUIRE(error0 <= tol0); 32 | 33 | auto error1 = xsf::extended_relative_error(out1, desired1); 34 | tol1 = adjust_tolerance(tol1); 35 | CAPTURE(x, out1, desired1, error1, tol1, fallback); 36 | REQUIRE(error1 <= tol1); 37 | } 38 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_msm1.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "msm1"}; 8 | 9 | TEST_CASE("msm1 ddd->dd scipy_special_tests", "[msm1][ddd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::tuple, std::tuple>( 14 | tables_path / "In_d_d_d-d_d.parquet", tables_path / "Out_d_d_d-d_d.parquet", 15 | tables_path / ("Err_d_d_d-d_d_" + get_platform_str() + ".parquet") 16 | ) 17 | ); 18 | 19 | auto [m, q, x] = input; 20 | auto [desired0, desired1, fallback] = output; 21 | 22 | double out0; 23 | double out1; 24 | 25 | xsf::msm1(m, q, x, out0, out1); 26 | auto [tol0, tol1] = tol; 27 | 28 | auto error0 = xsf::extended_relative_error(out0, desired0); 29 | tol0 = adjust_tolerance(tol0); 30 | CAPTURE(m, q, x, out0, desired0, error0, tol0, fallback); 31 | REQUIRE(error0 <= tol0); 32 | 33 | auto error1 = xsf::extended_relative_error(out1, desired1); 34 | tol1 = adjust_tolerance(tol1); 35 | CAPTURE(m, q, x, out1, desired1, error1, tol1, fallback); 36 | REQUIRE(error1 <= tol1); 37 | } 38 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_msm2.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "msm2"}; 8 | 9 | TEST_CASE("msm2 ddd->dd scipy_special_tests", "[msm2][ddd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::tuple, std::tuple>( 14 | tables_path / "In_d_d_d-d_d.parquet", tables_path / "Out_d_d_d-d_d.parquet", 15 | tables_path / ("Err_d_d_d-d_d_" + get_platform_str() + ".parquet") 16 | ) 17 | ); 18 | 19 | auto [m, q, x] = input; 20 | auto [desired0, desired1, fallback] = output; 21 | 22 | double out0; 23 | double out1; 24 | 25 | xsf::msm2(m, q, x, out0, out1); 26 | auto [tol0, tol1] = tol; 27 | 28 | auto error0 = xsf::extended_relative_error(out0, desired0); 29 | tol0 = adjust_tolerance(tol0); 30 | CAPTURE(m, q, x, out0, desired0, error0, tol0, fallback); 31 | REQUIRE(error0 <= tol0); 32 | 33 | auto error1 = xsf::extended_relative_error(out1, desired1); 34 | tol1 = adjust_tolerance(tol1); 35 | CAPTURE(m, q, x, out1, desired1, error1, tol1, fallback); 36 | REQUIRE(error1 <= tol1); 37 | } 38 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_nbdtr.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "nbdtr"}; 8 | 9 | TEST_CASE("nbdtr ppd->d scipy_special_tests", "[nbdtr][ppd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_p_p_d-d.parquet", tables_path / "Out_p_p_d-d.parquet", 14 | tables_path / ("Err_p_p_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [k, n, p] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::nbdtr(k, n, p); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(k, n, p, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_nbdtrc.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "nbdtrc"}; 8 | 9 | TEST_CASE("nbdtrc ppd->d scipy_special_tests", "[nbdtrc][ppd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_p_p_d-d.parquet", tables_path / "Out_p_p_d-d.parquet", 14 | tables_path / ("Err_p_p_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [k, n, p] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::nbdtrc(k, n, p); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(k, n, p, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_ndtri.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "ndtri"}; 8 | 9 | TEST_CASE("ndtri f->f scipy_special_tests", "[ndtri][f->f][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, float>( 13 | tables_path / "In_f-f.parquet", tables_path / "Out_f-f.parquet", 14 | tables_path / ("Err_f-f_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto y = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::ndtri(y); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(y, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("ndtri d->d scipy_special_tests", "[ndtri][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto y = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::ndtri(y); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(y, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_oblate_aswfa.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "oblate_aswfa"}; 8 | 9 | TEST_CASE("oblate_aswfa ddddd->dd scipy_special_tests", "[oblate_aswfa][ddddd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::tuple, 14 | std::tuple>( 15 | tables_path / "In_d_d_d_d_d-d_d.parquet", tables_path / "Out_d_d_d_d_d-d_d.parquet", 16 | tables_path / ("Err_d_d_d_d_d-d_d_" + get_platform_str() + ".parquet") 17 | ) 18 | ); 19 | 20 | auto [m, n, c, cv, x] = input; 21 | auto [desired0, desired1, fallback] = output; 22 | 23 | double out0; 24 | double out1; 25 | 26 | xsf::oblate_aswfa(m, n, c, cv, x, out0, out1); 27 | auto [tol0, tol1] = tol; 28 | 29 | auto error0 = xsf::extended_relative_error(out0, desired0); 30 | tol0 = adjust_tolerance(tol0); 31 | CAPTURE(m, n, c, cv, x, out0, desired0, error0, tol0, fallback); 32 | REQUIRE(error0 <= tol0); 33 | 34 | auto error1 = xsf::extended_relative_error(out1, desired1); 35 | tol1 = adjust_tolerance(tol1); 36 | CAPTURE(m, n, c, cv, x, out1, desired1, error1, tol1, fallback); 37 | REQUIRE(error1 <= tol1); 38 | } 39 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_oblate_aswfa_nocv.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "oblate_aswfa_nocv"}; 8 | 9 | TEST_CASE("oblate_aswfa_nocv dddd->dd scipy_special_tests", "[oblate_aswfa_nocv][dddd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::tuple, std::tuple>( 14 | tables_path / "In_d_d_d_d-d_d.parquet", tables_path / "Out_d_d_d_d-d_d.parquet", 15 | tables_path / ("Err_d_d_d_d-d_d_" + get_platform_str() + ".parquet") 16 | ) 17 | ); 18 | 19 | auto [m, n, c, x] = input; 20 | auto [desired0, desired1, fallback] = output; 21 | 22 | double out0; 23 | double out1; 24 | 25 | xsf::oblate_aswfa_nocv(m, n, c, x, out0, out1); 26 | auto [tol0, tol1] = tol; 27 | 28 | auto error0 = xsf::extended_relative_error(out0, desired0); 29 | tol0 = adjust_tolerance(tol0); 30 | CAPTURE(m, n, c, x, out0, desired0, error0, tol0, fallback); 31 | REQUIRE(error0 <= tol0); 32 | 33 | auto error1 = xsf::extended_relative_error(out1, desired1); 34 | tol1 = adjust_tolerance(tol1); 35 | CAPTURE(m, n, c, x, out1, desired1, error1, tol1, fallback); 36 | REQUIRE(error1 <= tol1); 37 | } 38 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_oblate_radial1.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "oblate_radial1"}; 8 | 9 | TEST_CASE("oblate_radial1 ddddd->dd scipy_special_tests", "[oblate_radial1][ddddd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::tuple, 14 | std::tuple>( 15 | tables_path / "In_d_d_d_d_d-d_d.parquet", tables_path / "Out_d_d_d_d_d-d_d.parquet", 16 | tables_path / ("Err_d_d_d_d_d-d_d_" + get_platform_str() + ".parquet") 17 | ) 18 | ); 19 | 20 | auto [m, n, c, cv, x] = input; 21 | auto [desired0, desired1, fallback] = output; 22 | 23 | double out0; 24 | double out1; 25 | 26 | xsf::oblate_radial1(m, n, c, cv, x, out0, out1); 27 | auto [tol0, tol1] = tol; 28 | 29 | auto error0 = xsf::extended_relative_error(out0, desired0); 30 | tol0 = adjust_tolerance(tol0); 31 | CAPTURE(m, n, c, cv, x, out0, desired0, error0, tol0, fallback); 32 | REQUIRE(error0 <= tol0); 33 | 34 | auto error1 = xsf::extended_relative_error(out1, desired1); 35 | tol1 = adjust_tolerance(tol1); 36 | CAPTURE(m, n, c, cv, x, out1, desired1, error1, tol1, fallback); 37 | REQUIRE(error1 <= tol1); 38 | } 39 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_oblate_radial1_nocv.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "oblate_radial1_nocv"}; 8 | 9 | TEST_CASE("oblate_radial1_nocv dddd->dd scipy_special_tests", "[oblate_radial1_nocv][dddd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::tuple, std::tuple>( 14 | tables_path / "In_d_d_d_d-d_d.parquet", tables_path / "Out_d_d_d_d-d_d.parquet", 15 | tables_path / ("Err_d_d_d_d-d_d_" + get_platform_str() + ".parquet") 16 | ) 17 | ); 18 | 19 | auto [m, n, c, x] = input; 20 | auto [desired0, desired1, fallback] = output; 21 | 22 | double out0; 23 | double out1; 24 | 25 | xsf::oblate_radial1_nocv(m, n, c, x, out0, out1); 26 | auto [tol0, tol1] = tol; 27 | 28 | auto error0 = xsf::extended_relative_error(out0, desired0); 29 | tol0 = adjust_tolerance(tol0); 30 | CAPTURE(m, n, c, x, out0, desired0, error0, tol0, fallback); 31 | REQUIRE(error0 <= tol0); 32 | 33 | auto error1 = xsf::extended_relative_error(out1, desired1); 34 | tol1 = adjust_tolerance(tol1); 35 | CAPTURE(m, n, c, x, out1, desired1, error1, tol1, fallback); 36 | REQUIRE(error1 <= tol1); 37 | } 38 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_oblate_radial2.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "oblate_radial2"}; 8 | 9 | TEST_CASE("oblate_radial2 ddddd->dd scipy_special_tests", "[oblate_radial2][ddddd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::tuple, 14 | std::tuple>( 15 | tables_path / "In_d_d_d_d_d-d_d.parquet", tables_path / "Out_d_d_d_d_d-d_d.parquet", 16 | tables_path / ("Err_d_d_d_d_d-d_d_" + get_platform_str() + ".parquet") 17 | ) 18 | ); 19 | 20 | auto [m, n, c, cv, x] = input; 21 | auto [desired0, desired1, fallback] = output; 22 | 23 | double out0; 24 | double out1; 25 | 26 | xsf::oblate_radial2(m, n, c, cv, x, out0, out1); 27 | auto [tol0, tol1] = tol; 28 | 29 | auto error0 = xsf::extended_relative_error(out0, desired0); 30 | tol0 = adjust_tolerance(tol0); 31 | CAPTURE(m, n, c, cv, x, out0, desired0, error0, tol0, fallback); 32 | REQUIRE(error0 <= tol0); 33 | 34 | auto error1 = xsf::extended_relative_error(out1, desired1); 35 | tol1 = adjust_tolerance(tol1); 36 | CAPTURE(m, n, c, cv, x, out1, desired1, error1, tol1, fallback); 37 | REQUIRE(error1 <= tol1); 38 | } 39 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_oblate_radial2_nocv.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "oblate_radial2_nocv"}; 8 | 9 | TEST_CASE("oblate_radial2_nocv dddd->dd scipy_special_tests", "[oblate_radial2_nocv][dddd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::tuple, std::tuple>( 14 | tables_path / "In_d_d_d_d-d_d.parquet", tables_path / "Out_d_d_d_d-d_d.parquet", 15 | tables_path / ("Err_d_d_d_d-d_d_" + get_platform_str() + ".parquet") 16 | ) 17 | ); 18 | 19 | auto [m, n, c, x] = input; 20 | auto [desired0, desired1, fallback] = output; 21 | 22 | double out0; 23 | double out1; 24 | 25 | xsf::oblate_radial2_nocv(m, n, c, x, out0, out1); 26 | auto [tol0, tol1] = tol; 27 | 28 | auto error0 = xsf::extended_relative_error(out0, desired0); 29 | tol0 = adjust_tolerance(tol0); 30 | CAPTURE(m, n, c, x, out0, desired0, error0, tol0, fallback); 31 | REQUIRE(error0 <= tol0); 32 | 33 | auto error1 = xsf::extended_relative_error(out1, desired1); 34 | tol1 = adjust_tolerance(tol1); 35 | CAPTURE(m, n, c, x, out1, desired1, error1, tol1, fallback); 36 | REQUIRE(error1 <= tol1); 37 | } 38 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_owens_t.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "owens_t"}; 8 | 9 | TEST_CASE("owens_t dd->d scipy_special_tests", "[owens_t][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [h, a] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::owens_t(h, a); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(h, a, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_pbdv.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "pbdv"}; 8 | 9 | TEST_CASE("pbdv dd->dd scipy_special_tests", "[pbdv][dd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, std::tuple>( 13 | tables_path / "In_d_d-d_d.parquet", tables_path / "Out_d_d-d_d.parquet", 14 | tables_path / ("Err_d_d-d_d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, x] = input; 19 | auto [desired0, desired1, fallback] = output; 20 | 21 | double out0; 22 | double out1; 23 | 24 | xsf::pbdv(v, x, out0, out1); 25 | auto [tol0, tol1] = tol; 26 | 27 | auto error0 = xsf::extended_relative_error(out0, desired0); 28 | tol0 = adjust_tolerance(tol0); 29 | CAPTURE(v, x, out0, desired0, error0, tol0, fallback); 30 | REQUIRE(error0 <= tol0); 31 | 32 | auto error1 = xsf::extended_relative_error(out1, desired1); 33 | tol1 = adjust_tolerance(tol1); 34 | CAPTURE(v, x, out1, desired1, error1, tol1, fallback); 35 | REQUIRE(error1 <= tol1); 36 | } 37 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_pbvv.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "pbvv"}; 8 | 9 | TEST_CASE("pbvv dd->dd scipy_special_tests", "[pbvv][dd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, std::tuple>( 13 | tables_path / "In_d_d-d_d.parquet", tables_path / "Out_d_d-d_d.parquet", 14 | tables_path / ("Err_d_d-d_d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, x] = input; 19 | auto [desired0, desired1, fallback] = output; 20 | 21 | double out0; 22 | double out1; 23 | 24 | xsf::pbvv(v, x, out0, out1); 25 | auto [tol0, tol1] = tol; 26 | 27 | auto error0 = xsf::extended_relative_error(out0, desired0); 28 | tol0 = adjust_tolerance(tol0); 29 | CAPTURE(v, x, out0, desired0, error0, tol0, fallback); 30 | REQUIRE(error0 <= tol0); 31 | 32 | auto error1 = xsf::extended_relative_error(out1, desired1); 33 | tol1 = adjust_tolerance(tol1); 34 | CAPTURE(v, x, out1, desired1, error1, tol1, fallback); 35 | REQUIRE(error1 <= tol1); 36 | } 37 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_pbwa.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "pbwa"}; 8 | 9 | TEST_CASE("pbwa dd->dd scipy_special_tests", "[pbwa][dd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, std::tuple>( 13 | tables_path / "In_d_d-d_d.parquet", tables_path / "Out_d_d-d_d.parquet", 14 | tables_path / ("Err_d_d-d_d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, x] = input; 19 | auto [desired0, desired1, fallback] = output; 20 | 21 | double out0; 22 | double out1; 23 | 24 | xsf::pbwa(v, x, out0, out1); 25 | auto [tol0, tol1] = tol; 26 | 27 | auto error0 = xsf::extended_relative_error(out0, desired0); 28 | tol0 = adjust_tolerance(tol0); 29 | CAPTURE(v, x, out0, desired0, error0, tol0, fallback); 30 | REQUIRE(error0 <= tol0); 31 | 32 | auto error1 = xsf::extended_relative_error(out1, desired1); 33 | tol1 = adjust_tolerance(tol1); 34 | CAPTURE(v, x, out1, desired1, error1, tol1, fallback); 35 | REQUIRE(error1 <= tol1); 36 | } 37 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_pdtr.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "pdtr"}; 8 | 9 | TEST_CASE("pdtr dd->d scipy_special_tests", "[pdtr][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [k, m] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::pdtr(k, m); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(k, m, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_pdtrc.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "pdtrc"}; 8 | 9 | TEST_CASE("pdtrc dd->d scipy_special_tests", "[pdtrc][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [k, m] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::pdtrc(k, m); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(k, m, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_pdtri.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "pdtri"}; 8 | 9 | TEST_CASE("pdtri pd->d scipy_special_tests", "[pdtri][pd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_p_d-d.parquet", tables_path / "Out_p_d-d.parquet", 14 | tables_path / ("Err_p_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [k, y] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::pdtri(k, y); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(k, y, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_pmv.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "pmv"}; 8 | 9 | TEST_CASE("pmv ddd->d scipy_special_tests", "[pmv][ddd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d_d-d.parquet", tables_path / "Out_d_d_d-d.parquet", 14 | tables_path / ("Err_d_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [m, v, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::pmv(m, v, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(m, v, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_poch.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "poch"}; 8 | 9 | TEST_CASE("cephes::poch dd->d scipy_special_tests", "[cephes::poch][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [z, m] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cephes::poch(z, m); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(z, m, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_prolate_aswfa.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "prolate_aswfa"}; 8 | 9 | TEST_CASE("prolate_aswfa ddddd->dd scipy_special_tests", "[prolate_aswfa][ddddd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::tuple, 14 | std::tuple>( 15 | tables_path / "In_d_d_d_d_d-d_d.parquet", tables_path / "Out_d_d_d_d_d-d_d.parquet", 16 | tables_path / ("Err_d_d_d_d_d-d_d_" + get_platform_str() + ".parquet") 17 | ) 18 | ); 19 | 20 | auto [m, n, c, cv, x] = input; 21 | auto [desired0, desired1, fallback] = output; 22 | 23 | double out0; 24 | double out1; 25 | 26 | xsf::prolate_aswfa(m, n, c, cv, x, out0, out1); 27 | auto [tol0, tol1] = tol; 28 | 29 | auto error0 = xsf::extended_relative_error(out0, desired0); 30 | tol0 = adjust_tolerance(tol0); 31 | CAPTURE(m, n, c, cv, x, out0, desired0, error0, tol0, fallback); 32 | REQUIRE(error0 <= tol0); 33 | 34 | auto error1 = xsf::extended_relative_error(out1, desired1); 35 | tol1 = adjust_tolerance(tol1); 36 | CAPTURE(m, n, c, cv, x, out1, desired1, error1, tol1, fallback); 37 | REQUIRE(error1 <= tol1); 38 | } 39 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_prolate_aswfa_nocv.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "prolate_aswfa_nocv"}; 8 | 9 | TEST_CASE("prolate_aswfa_nocv dddd->dd scipy_special_tests", "[prolate_aswfa_nocv][dddd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::tuple, std::tuple>( 14 | tables_path / "In_d_d_d_d-d_d.parquet", tables_path / "Out_d_d_d_d-d_d.parquet", 15 | tables_path / ("Err_d_d_d_d-d_d_" + get_platform_str() + ".parquet") 16 | ) 17 | ); 18 | 19 | auto [m, n, c, x] = input; 20 | auto [desired0, desired1, fallback] = output; 21 | 22 | double out0; 23 | double out1; 24 | 25 | xsf::prolate_aswfa_nocv(m, n, c, x, out0, out1); 26 | auto [tol0, tol1] = tol; 27 | 28 | auto error0 = xsf::extended_relative_error(out0, desired0); 29 | tol0 = adjust_tolerance(tol0); 30 | CAPTURE(m, n, c, x, out0, desired0, error0, tol0, fallback); 31 | REQUIRE(error0 <= tol0); 32 | 33 | auto error1 = xsf::extended_relative_error(out1, desired1); 34 | tol1 = adjust_tolerance(tol1); 35 | CAPTURE(m, n, c, x, out1, desired1, error1, tol1, fallback); 36 | REQUIRE(error1 <= tol1); 37 | } 38 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_prolate_radial1.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "prolate_radial1"}; 8 | 9 | TEST_CASE("prolate_radial1 ddddd->dd scipy_special_tests", "[prolate_radial1][ddddd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::tuple, 14 | std::tuple>( 15 | tables_path / "In_d_d_d_d_d-d_d.parquet", tables_path / "Out_d_d_d_d_d-d_d.parquet", 16 | tables_path / ("Err_d_d_d_d_d-d_d_" + get_platform_str() + ".parquet") 17 | ) 18 | ); 19 | 20 | auto [m, n, c, cv, x] = input; 21 | auto [desired0, desired1, fallback] = output; 22 | 23 | double out0; 24 | double out1; 25 | 26 | xsf::prolate_radial1(m, n, c, cv, x, out0, out1); 27 | auto [tol0, tol1] = tol; 28 | 29 | auto error0 = xsf::extended_relative_error(out0, desired0); 30 | tol0 = adjust_tolerance(tol0); 31 | CAPTURE(m, n, c, cv, x, out0, desired0, error0, tol0, fallback); 32 | REQUIRE(error0 <= tol0); 33 | 34 | auto error1 = xsf::extended_relative_error(out1, desired1); 35 | tol1 = adjust_tolerance(tol1); 36 | CAPTURE(m, n, c, cv, x, out1, desired1, error1, tol1, fallback); 37 | REQUIRE(error1 <= tol1); 38 | } 39 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_prolate_radial1_nocv.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "prolate_radial1_nocv"}; 8 | 9 | TEST_CASE( 10 | "prolate_radial1_nocv dddd->dd scipy_special_tests", "[prolate_radial1_nocv][dddd->dd][scipy_special_tests]" 11 | ) { 12 | SET_FP_FORMAT() 13 | auto [input, output, tol] = GENERATE( 14 | xsf_test_cases< 15 | std::tuple, std::tuple, std::tuple>( 16 | tables_path / "In_d_d_d_d-d_d.parquet", tables_path / "Out_d_d_d_d-d_d.parquet", 17 | tables_path / ("Err_d_d_d_d-d_d_" + get_platform_str() + ".parquet") 18 | ) 19 | ); 20 | 21 | auto [m, n, c, x] = input; 22 | auto [desired0, desired1, fallback] = output; 23 | 24 | double out0; 25 | double out1; 26 | 27 | xsf::prolate_radial1_nocv(m, n, c, x, out0, out1); 28 | auto [tol0, tol1] = tol; 29 | 30 | auto error0 = xsf::extended_relative_error(out0, desired0); 31 | tol0 = adjust_tolerance(tol0); 32 | CAPTURE(m, n, c, x, out0, desired0, error0, tol0, fallback); 33 | REQUIRE(error0 <= tol0); 34 | 35 | auto error1 = xsf::extended_relative_error(out1, desired1); 36 | tol1 = adjust_tolerance(tol1); 37 | CAPTURE(m, n, c, x, out1, desired1, error1, tol1, fallback); 38 | REQUIRE(error1 <= tol1); 39 | } 40 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_prolate_radial2.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "prolate_radial2"}; 8 | 9 | TEST_CASE("prolate_radial2 ddddd->dd scipy_special_tests", "[prolate_radial2][ddddd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::tuple, 14 | std::tuple>( 15 | tables_path / "In_d_d_d_d_d-d_d.parquet", tables_path / "Out_d_d_d_d_d-d_d.parquet", 16 | tables_path / ("Err_d_d_d_d_d-d_d_" + get_platform_str() + ".parquet") 17 | ) 18 | ); 19 | 20 | auto [m, n, c, cv, x] = input; 21 | auto [desired0, desired1, fallback] = output; 22 | 23 | double out0; 24 | double out1; 25 | 26 | xsf::prolate_radial2(m, n, c, cv, x, out0, out1); 27 | auto [tol0, tol1] = tol; 28 | 29 | auto error0 = xsf::extended_relative_error(out0, desired0); 30 | tol0 = adjust_tolerance(tol0); 31 | CAPTURE(m, n, c, cv, x, out0, desired0, error0, tol0, fallback); 32 | REQUIRE(error0 <= tol0); 33 | 34 | auto error1 = xsf::extended_relative_error(out1, desired1); 35 | tol1 = adjust_tolerance(tol1); 36 | CAPTURE(m, n, c, cv, x, out1, desired1, error1, tol1, fallback); 37 | REQUIRE(error1 <= tol1); 38 | } 39 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_prolate_radial2_nocv.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "prolate_radial2_nocv"}; 8 | 9 | TEST_CASE( 10 | "prolate_radial2_nocv dddd->dd scipy_special_tests", "[prolate_radial2_nocv][dddd->dd][scipy_special_tests]" 11 | ) { 12 | SET_FP_FORMAT() 13 | auto [input, output, tol] = GENERATE( 14 | xsf_test_cases< 15 | std::tuple, std::tuple, std::tuple>( 16 | tables_path / "In_d_d_d_d-d_d.parquet", tables_path / "Out_d_d_d_d-d_d.parquet", 17 | tables_path / ("Err_d_d_d_d-d_d_" + get_platform_str() + ".parquet") 18 | ) 19 | ); 20 | 21 | auto [m, n, c, x] = input; 22 | auto [desired0, desired1, fallback] = output; 23 | 24 | double out0; 25 | double out1; 26 | 27 | xsf::prolate_radial2_nocv(m, n, c, x, out0, out1); 28 | auto [tol0, tol1] = tol; 29 | 30 | auto error0 = xsf::extended_relative_error(out0, desired0); 31 | tol0 = adjust_tolerance(tol0); 32 | CAPTURE(m, n, c, x, out0, desired0, error0, tol0, fallback); 33 | REQUIRE(error0 <= tol0); 34 | 35 | auto error1 = xsf::extended_relative_error(out1, desired1); 36 | tol1 = adjust_tolerance(tol1); 37 | CAPTURE(m, n, c, x, out1, desired1, error1, tol1, fallback); 38 | REQUIRE(error1 <= tol1); 39 | } 40 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_prolate_segv.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "prolate_segv"}; 8 | 9 | TEST_CASE("prolate_segv ddd->d scipy_special_tests", "[prolate_segv][ddd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d_d-d.parquet", tables_path / "Out_d_d_d-d.parquet", 14 | tables_path / ("Err_d_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [m, n, c] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::prolate_segv(m, n, c); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(m, n, c, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_radian.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "radian"}; 8 | 9 | TEST_CASE("radian ddd->d scipy_special_tests", "[radian][ddd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d_d-d.parquet", tables_path / "Out_d_d_d-d.parquet", 14 | tables_path / ("Err_d_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [d, m, s] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::radian(d, m, s); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(d, m, s, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_rgamma.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "rgamma"}; 8 | 9 | TEST_CASE("rgamma D->D scipy_special_tests", "[rgamma][D->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, bool>, double>( 13 | tables_path / "In_cd-cd.parquet", tables_path / "Out_cd-cd.parquet", 14 | tables_path / ("Err_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto z = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::rgamma(z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("rgamma d->d scipy_special_tests", "[rgamma][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto z = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::rgamma(z); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(z, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_riemann_zeta.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "riemann_zeta"}; 8 | 9 | TEST_CASE("riemann_zeta D->D scipy_special_tests", "[riemann_zeta][D->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, bool>, double>( 13 | tables_path / "In_cd-cd.parquet", tables_path / "Out_cd-cd.parquet", 14 | tables_path / ("Err_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto z = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::riemann_zeta(z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("riemann_zeta d->d scipy_special_tests", "[riemann_zeta][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto z = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::riemann_zeta(z); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(z, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_round.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "round"}; 8 | 9 | TEST_CASE("cephes::round d->d scipy_special_tests", "[cephes::round][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cephes::round(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_scaled_exp1.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "scaled_exp1"}; 8 | 9 | TEST_CASE("scaled_exp1 d->d scipy_special_tests", "[scaled_exp1][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::scaled_exp1(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_sem.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "sem"}; 8 | 9 | TEST_CASE("sem ddd->dd scipy_special_tests", "[sem][ddd->dd][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases< 13 | std::tuple, std::tuple, std::tuple>( 14 | tables_path / "In_d_d_d-d_d.parquet", tables_path / "Out_d_d_d-d_d.parquet", 15 | tables_path / ("Err_d_d_d-d_d_" + get_platform_str() + ".parquet") 16 | ) 17 | ); 18 | 19 | auto [m, q, x] = input; 20 | auto [desired0, desired1, fallback] = output; 21 | 22 | double out0; 23 | double out1; 24 | 25 | xsf::sem(m, q, x, out0, out1); 26 | auto [tol0, tol1] = tol; 27 | 28 | auto error0 = xsf::extended_relative_error(out0, desired0); 29 | tol0 = adjust_tolerance(tol0); 30 | CAPTURE(m, q, x, out0, desired0, error0, tol0, fallback); 31 | REQUIRE(error0 <= tol0); 32 | 33 | auto error1 = xsf::extended_relative_error(out1, desired1); 34 | tol1 = adjust_tolerance(tol1); 35 | CAPTURE(m, q, x, out1, desired1, error1, tol1, fallback); 36 | REQUIRE(error1 <= tol1); 37 | } 38 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_sem_cva.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "sem_cva"}; 8 | 9 | TEST_CASE("sem_cva dd->d scipy_special_tests", "[sem_cva][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [m, q] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::sem_cva(m, q); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(m, q, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_sindg.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "sindg"}; 8 | 9 | TEST_CASE("sindg d->d scipy_special_tests", "[sindg][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::sindg(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_sinpi.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "sinpi"}; 8 | 9 | TEST_CASE("sinpi D->D scipy_special_tests", "[sinpi][D->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, bool>, double>( 13 | tables_path / "In_cd-cd.parquet", tables_path / "Out_cd-cd.parquet", 14 | tables_path / ("Err_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::sinpi(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("sinpi d->d scipy_special_tests", "[sinpi][d->d][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases, double>( 31 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 32 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 33 | ) 34 | ); 35 | 36 | auto x = input; 37 | auto [desired, fallback] = output; 38 | auto out = xsf::sinpi(x); 39 | auto error = xsf::extended_relative_error(out, desired); 40 | tol = adjust_tolerance(tol); 41 | CAPTURE(x, out, desired, error, tol, fallback); 42 | REQUIRE(error <= tol); 43 | } 44 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_smirnov.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "smirnov"}; 8 | 9 | TEST_CASE("smirnov pd->d scipy_special_tests", "[smirnov][pd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_p_d-d.parquet", tables_path / "Out_p_d-d.parquet", 14 | tables_path / ("Err_p_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [n, d] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::smirnov(n, d); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(n, d, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_smirnovc.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "smirnovc"}; 8 | 9 | TEST_CASE("smirnovc pd->d scipy_special_tests", "[smirnovc][pd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_p_d-d.parquet", tables_path / "Out_p_d-d.parquet", 14 | tables_path / ("Err_p_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [n, d] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::smirnovc(n, d); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(n, d, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_smirnovci.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "smirnovci"}; 8 | 9 | TEST_CASE("smirnovci pd->d scipy_special_tests", "[smirnovci][pd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_p_d-d.parquet", tables_path / "Out_p_d-d.parquet", 14 | tables_path / ("Err_p_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [n, p] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::smirnovci(n, p); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(n, p, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_smirnovi.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "smirnovi"}; 8 | 9 | TEST_CASE("smirnovi pd->d scipy_special_tests", "[smirnovi][pd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_p_d-d.parquet", tables_path / "Out_p_d-d.parquet", 14 | tables_path / ("Err_p_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [n, p] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::smirnovi(n, p); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(n, p, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_smirnovp.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "smirnovp"}; 8 | 9 | TEST_CASE("smirnovp pd->d scipy_special_tests", "[smirnovp][pd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_p_d-d.parquet", tables_path / "Out_p_d-d.parquet", 14 | tables_path / ("Err_p_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [n, d] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::smirnovp(n, d); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(n, d, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_spence.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "spence"}; 8 | 9 | TEST_CASE("cephes::spence d->d scipy_special_tests", "[cephes::spence][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto z = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::cephes::spence(z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_struve_h.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "struve_h"}; 8 | 9 | TEST_CASE("struve_h dd->d scipy_special_tests", "[struve_h][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::struve_h(v, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(v, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_struve_l.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "struve_l"}; 8 | 9 | TEST_CASE("struve_l dd->d scipy_special_tests", "[struve_l][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [v, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::struve_l(v, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(v, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_tandg.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "tandg"}; 8 | 9 | TEST_CASE("tandg d->d scipy_special_tests", "[tandg][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::tandg(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_voigt_profile.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "voigt_profile"}; 8 | 9 | TEST_CASE("voigt_profile ddd->d scipy_special_tests", "[voigt_profile][ddd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d_d-d.parquet", tables_path / "Out_d_d_d-d.parquet", 14 | tables_path / ("Err_d_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [x, sigma, gamma] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::voigt_profile(x, sigma, gamma); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, sigma, gamma, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_wofz.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "wofz"}; 8 | 9 | TEST_CASE("wofz D->D scipy_special_tests", "[wofz][D->D][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, bool>, double>( 13 | tables_path / "In_cd-cd.parquet", tables_path / "Out_cd-cd.parquet", 14 | tables_path / ("Err_cd-cd_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto x = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::wofz(x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_wright_bessel.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "wright_bessel"}; 8 | 9 | TEST_CASE("wright_bessel ddd->d scipy_special_tests", "[wright_bessel][ddd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d_d-d.parquet", tables_path / "Out_d_d_d-d.parquet", 14 | tables_path / ("Err_d_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [a, b, x] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::wright_bessel(a, b, x); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(a, b, x, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_xlog1py.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "xlog1py"}; 8 | 9 | TEST_CASE("xlog1py dd->d scipy_special_tests", "[xlog1py][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [x, y] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::xlog1py(x, y); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(x, y, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | 27 | TEST_CASE("xlog1py DD->D scipy_special_tests", "[xlog1py][DD->D][scipy_special_tests]") { 28 | SET_FP_FORMAT() 29 | auto [input, output, tol] = GENERATE( 30 | xsf_test_cases< 31 | std::tuple, std::complex>, std::tuple, bool>, double>( 32 | tables_path / "In_cd_cd-cd.parquet", tables_path / "Out_cd_cd-cd.parquet", 33 | tables_path / ("Err_cd_cd-cd_" + get_platform_str() + ".parquet") 34 | ) 35 | ); 36 | 37 | auto [x, y] = input; 38 | auto [desired, fallback] = output; 39 | auto out = xsf::xlog1py(x, y); 40 | auto error = xsf::extended_relative_error(out, desired); 41 | tol = adjust_tolerance(tol); 42 | CAPTURE(x, y, out, desired, error, tol, fallback); 43 | REQUIRE(error <= tol); 44 | } 45 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_zeta.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "zeta"}; 8 | 9 | TEST_CASE("zeta dd->d scipy_special_tests", "[zeta][dd->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, std::tuple, double>( 13 | tables_path / "In_d_d-d.parquet", tables_path / "Out_d_d-d.parquet", 14 | tables_path / ("Err_d_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto [z, q] = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::zeta(z, q); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(z, q, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | -------------------------------------------------------------------------------- /tests/scipy_special_tests/test_zetac.cpp: -------------------------------------------------------------------------------- 1 | #include "../testing_utils.h" 2 | 3 | #include 4 | 5 | namespace fs = std::filesystem; 6 | 7 | fs::path tables_path{fs::path(XSREF_TABLES_PATH) / "scipy_special_tests" / "zetac"}; 8 | 9 | TEST_CASE("zetac d->d scipy_special_tests", "[zetac][d->d][scipy_special_tests]") { 10 | SET_FP_FORMAT() 11 | auto [input, output, tol] = GENERATE( 12 | xsf_test_cases, double>( 13 | tables_path / "In_d-d.parquet", tables_path / "Out_d-d.parquet", 14 | tables_path / ("Err_d-d_" + get_platform_str() + ".parquet") 15 | ) 16 | ); 17 | 18 | auto z = input; 19 | auto [desired, fallback] = output; 20 | auto out = xsf::zetac(z); 21 | auto error = xsf::extended_relative_error(out, desired); 22 | tol = adjust_tolerance(tol); 23 | CAPTURE(z, out, desired, error, tol, fallback); 24 | REQUIRE(error <= tol); 25 | } 26 | --------------------------------------------------------------------------------