8000 MAINT:Translate the entirety of cephes into C++ by steppi · Pull Request #20390 · scipy/scipy · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

MAINT:Translate the entirety of cephes into C++ #20390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 100 commits into from
Apr 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
33b3825
Add new functions to config.h
steppi Feb 7, 2024
196b6e1
MAINT: Translate Cephes hyp2f1 to C++
steppi Feb 15, 2024
bc92dea
EMPTY: [skip actions] [skip cirrus]
steppi Jan 28, 2024
0cf9ec0
EMPTY: [skip actions] [skip cirrus]
steppi Jan 28, 2024
a148863
EMPTY: [skip actions] [skip cirrus]
steppi Jan 28, 2024
8c9bf25
Use C++ implementations for cephes functions
steppi Feb 21, 2024
e5d4a36
Translate besselpoly to C++
steppi Feb 21, 2024
f4fcab5
Translate i0, i1, i0e, i1e to C++ from cephes
steppi Feb 21, 2024
73e5dec
Add note about besselpoly translation
steppi Feb 21, 2024
48d235a
Add missing declarations of functions as inline
steppi Feb 21, 2024
0fd5165
Translate cephes iv to C++
steppi Feb 21, 2024
fd424df
Add missing #pragma once to scipy_iv.h
steppi Feb 21, 2024
7a74d2f
Translate cephes j0, j1 to C++
steppi Feb 21, 2024
7a1bf8e
Check in changes so I can switch branch
steppi Feb 21, 2024
519d083
Translate cephes jv to C++
steppi Feb 21, 2024
d797b29
Add C wrappers for C++ special functions
steppi Feb 22, 2024
58c2284
Check in missing cephes headers
steppi Feb 22, 2024
c437173
Translate cephes k0 to C++
steppi Feb 22, 2024
8b00e00
Make k0 inline
steppi Feb 22, 2024
178d8db
Remove unnecessary include
steppi Feb 22, 2024
d382c9b
Clang format code
steppi Feb 22, 2024
7b2e7a2
Translate cephes k1 to C++
steppi Feb 22, 2024
117ad11
Translate cephes kn to C++
steppi Feb 22, 2024
af8bea7
Translate more things from cephes
steppi Feb 22, 2024
266f161
Translate still more of cephes into C++
steppi Feb 22, 2024
00a1cef
Use cephes C++ impl in cbrt ufunc
steppi Feb 22, 2024
4738c81
Translate cephes hyperg (hyp1f1) to C++
steppi Feb 23, 2024
122e25b
Translate cephes expn to C++
steppi Mar 28, 2024
ad8c6e1
Add fmod to config.h
steppi Mar 28, 2024
cedbc0e
Translate cephes elliptic integrals to C++
steppi Mar 29, 2024
f7da18e
Translate more cephes trig functions
steppi Mar 29, 2024
6f7c059
Translate more cephes stuff
steppi Mar 29, 2024
2e0ac59
Clang format code
steppi Mar 29, 2024
f55512f
Translate more cephes stuff
steppi Mar 29, 2024
226e550
Translate more cephes stuff
steppi Mar 29, 2024
174f6e1
Translate F distribution functions to C++
steppi Mar 29, 2024
3b2c9bf
squash with previous
steppi Mar 29, 2024
6c1c8c2
Translate cephes gamma distribution stuff to C++
steppi Mar 29, 2024
50229f8
Translate cephes negative binomial functions to C++
steppi Mar 29, 2024
e68bc05
Translate cephes Poisson distribution functions to C++
steppi Mar 29, 2024
4027e41
Remove extra blank line
steppi Mar 29, 2024
1030de8
Add clamp and fix merge conflicts
steppi Mar 30, 2024
2d80514
Add more functions
steppi Apr 2, 2024
ed5a61d
Translate cephes frensl to C++
steppi Apr 2, 2024
b776437
Apply clang format
steppi Apr 2, 2024
26abb6c
Translate cephes owens_t to C++
steppi Apr 2, 2024
758deae
Add missing pragma once's
steppi Apr 2, 2024
24c203d
Translate cephes tukeylambdacdf to C++
steppi Apr 2, 2024
2f8957f
Translate cephes round to C++
steppi Apr 2, 2024
59707ff
Add missing #pragma once
steppi Apr 2, 2024
8d430ac
Translate cephes spence to C++
steppi Apr 2, 2024
8232d18
Translate cephes sici to C++
steppi Apr 2, 2024
574de2b
Translate cephes shichi to C++
steppi Apr 2, 2024
cca87a8
Swap to C++ sici in functions.json
steppi Apr 2, 2024
3ea906b
Check in, in-progress float128 header
steppi Apr 4, 2024
caf4628
Minor updates to float128.h
steppi Apr 4, 2024
755e653
cephes translation is nearing completion
steppi Apr 4, 2024
db741d4
Get error handling working in C wrappers of C++ funcs
steppi Apr 4, 2024
0210d2c
Fix path to include
steppi Apr 4, 2024
589d07c
Start using C++ cephes in Cython functions dependent on cephes
steppi Apr 5, 2024
833b879
Use C++ cephes polevl in Cython files
steppi Apr 5, 2024
27fd376
Overload type conversion operators for DoubleDouble
steppi Apr 5, 2024
d8003c1
Implement != operators for DoubleDouble
steppi Apr 5, 2024
880b458
Add infinity and quiet_NaN for DoubleDouble type
steppi Apr 5, 2024
ad4cbb8
Remove unnecessary DoubleDouble functions
steppi Apr 5, 2024
b4c0346
Add exp and log for C++ double double
steppi Apr 5, 2024
571c33b
Clang format code
steppi Apr 5, 2024
841399e
Translate kolmogorov and smirnov functions to C++
steppi Apr 6, 2024
2a9bd8c
Fix smirnov bug
steppi Apr 6, 2024
f4ee49f
Unhook old cephes in more places
steppi Apr 6, 2024
a1d1cea
npy_math include must come first
steppi Apr 6, 2024
d2b75d3
Start using c wrappers for double double arithmetic
steppi Apr 6, 2024
c872b7d
Remove C cephes and finishing touches that allow this
steppi Apr 6, 2024
3132463
EMPTY: [skip ci]
steppi Apr 6, 2024
14d6657
Remove now unneeded cephes headers
steppi Apr 6, 2024
99cf93b
Fix bug in double double exp
steppi Apr 6, 2024
aeb6f6e
Fix bug in _kolmogi, nan when should be inf
steppi Apr 6, 2024
1124858
Terminate when nonfinite value reached in cephes yn
steppi Apr 6, 2024
fa45204
Adjust position of unary - in C++ cephes lbeta to match original
steppi Apr 6, 2024
41c1fec
Add header with original copyright to translation of double-double
steppi Apr 6, 2024
e3e0d9d
Clang format code
steppi Apr 6, 2024
dc0d69a
Add helpful comments
steppi Apr 6, 2024
5f19611
Fix amos bug, missing return block
steppi Apr 7, 2024
8658be8
Remove cephes-lib from special_ufuncs
steppi Apr 7, 2024
4046372
EMPTY: [skip ci]
steppi Apr 7, 2024
6ef3d55
Fix conflicts with #20403
steppi Apr 7, 2024
f320d62
Apply suggestions from code review
steppi Apr 8, 2024
168d840
Remove unneeded include
steppi Apr 8, 2024
abd03ee
Get rid of dd_real namespace
steppi Apr 8, 2024
61b4869
Get rid of unnecessary ThreeProbs constructor
steppi Apr 8, 2024
2e560af
Disable compiler optimizations for lgam_sgn on 32bit gcc
steppi Apr 10, 2024
743a2a3
Only disable optimizations for lgam large_x calculation
steppi Apr 10, 2024
9039852
Clang format code.
steppi Apr 10, 2024
820ed56
Finish resolving merge conflicts
steppi Apr 10, 2024
5223836
Merged
Apr 15, 2024
3f7d5b7
Added missing pragma once
Apr 15, 2024
4f39582
merged
Apr 19, 2024
a0c420e
fixes for rebasing;
Apr 19, 2024
433dbdc
Removed _special.h
Apr 19, 2024 8000
d5890e2
Remove unnecessary static's from variables
steppi Apr 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions scipy/special/_agm.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import cython

from libc.math cimport log, exp, fabs, sqrt, isnan, isinf, NAN, M_PI

from ._cephes cimport ellpk

cdef extern from "special_wrappers.h" nogil:
double cephes_ellpk_wrap(double x)


cdef inline double _agm_iter(double a, double b) noexcept nogil:
Expand Down Expand Up @@ -64,7 +66,7 @@ cdef inline double agm(double a, double b) noexcept nogil:

if (invsqrthalfmax < a < sqrthalfmax) and (invsqrthalfmax < b < sqrthalfmax):
e = 4*a*b/(a + b)**2
return sgn*(M_PI/4)*(a + b)/ellpk(e)
return sgn*(M_PI/4)*(a + b)/cephes_ellpk_wrap(e)
else:
# At least one value is "extreme" (very big or very small).
# Use the iteration to avoid overflow or underflow.
Expand Down
11 changes: 6 additions & 5 deletions scipy/special/_cdflib_wrappers.pxd
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from . cimport sf_error

from libc.math cimport NAN, isnan, isinf, isfinite
cdef extern from "cephes.h" nogil:
double ndtr(double a)
double ndtri(double y0)

cdef extern from "special_wrappers.h" nogil:
double cephes_ndtr_wrap(double a)
double cephes_ndtri_wrap(double y0)

cdef extern from "cdflib.h" nogil:
cdef struct TupleDDI:
Expand Down Expand Up @@ -671,7 +672,7 @@ cdef inline double stdtr(double df, double t) noexcept nogil:
argnames[1] = "df"

if isinf(df) and df > 0:
return NAN if isnan(t) else ndtr(t)
return NAN if isnan(t) else cephes_ndtr_wrap(t)

if isnan(df) or isnan(t):
return NAN
Expand Down Expand Up @@ -710,7 +711,7 @@ cdef inline double stdtrit(double df, double p) noexcept nogil:
TupleDID ret

if isinf(df) and df > 0:
return NAN if isnan(p) else ndtri(p)
return NAN if isnan(p) else cephes_ndtri_wrap(p)

if isnan(p) or isnan(df):
return NAN
Expand Down
111 changes: 0 additions & 111 deletions scipy/special/_cephes.pxd

This file was deleted.

12 changes: 6 additions & 6 deletions scipy/special/_cosine.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* The ufuncs are used by the class scipy.stats.cosine_gen.
*/

#include "special_wrappers.h"
#include <math.h>
#include "cephes/polevl.h"

// M_PI64 is the 64 bit floating point representation of π, e.g.
// >>> math.pi.hex()
Expand Down Expand Up @@ -101,9 +101,9 @@ double cosine_cdf_pade_approx_at_neg_pi(double x)
h = (x + M_PI64) + 1.2246467991473532e-16;
h2 = h*h;
h3 = h2*h;
numer = h3*polevl(h2, numer_coeffs,
numer = h3*cephes_polevl_wrap(h2, numer_coeffs,
sizeof(numer_coeffs)/sizeof(numer_coeffs[0]) - 1);
denom = polevl(h2, denom_coeffs,
denom = cephes_polevl_wrap(h2, denom_coeffs,
sizeof(denom_coeffs)/sizeof(denom_coeffs[0]) - 1);
return numer / denom;
}
Expand Down Expand Up @@ -178,7 +178,7 @@ double _p2(double t)
0.5};
double v;

v = polevl(t, coeffs, sizeof(coeffs) / sizeof(coeffs[0]) - 1);
v = cephes_polevl_wrap(t, coeffs, sizeof(coeffs) / sizeof(coeffs[0]) - 1);
return v;
}

Expand All @@ -193,7 +193,7 @@ double _q2(double t)
1.0};
double v;

v = polevl(t, coeffs, sizeof(coeffs) / sizeof(coeffs[0]) - 1);
v = cephes_polevl_wrap(t, coeffs, sizeof(coeffs) / sizeof(coeffs[0]) - 1);
return v;
}

Expand Down Expand Up @@ -225,7 +225,7 @@ double _poly_approx(double s)
// Here we include terms up to s**13.
//
s2 = s*s;
p = s*polevl(s2, coeffs, sizeof(coeffs)/sizeof(coeffs[0]) - 1);
p = s*cephes_polevl_wrap(s2, coeffs, sizeof(coeffs)/sizeof(coeffs[0]) - 1);
return p;
}

Expand Down
37 changes: 20 additions & 17 deletions scipy/special/_cunity.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,20 @@ cdef extern from "_complexstuff.h":
np.npy_cdouble npy_cexp(np.npy_cdouble x) nogil


cdef extern from "cephes/dd_real.h":
cdef extern from "dd_real_wrappers.h":
ctypedef struct double2:
double x[2]
double hi
double lo

double2 dd_create_d(double x) nogil
double2 dd_add(const double2 a, const double2 b) nogil
double2 dd_mul(const double2 a, const double2 b) nogil
double dd_to_double(const double2 a) nogil

from ._cephes cimport log1p, expm1, cosm1
double2 dd_add(const double2* a, const double2* b) nogil
double2 dd_mul(const double2* a, const double2* b) nogil
double dd_to_double(const double2* a) nogil

cdef extern from "special_wrappers.h" nogil:
double cephes_cosm1_wrap(double x)
double cephes_expm1_wrap(double x)
double cephes_log1p_wrap(double x)

# log(z + 1) = log(x + 1 + 1j*y)
# = log(sqrt((x+1)**2 + y**2)) + 1j*atan2(y, x+1)
Expand Down Expand Up @@ -49,15 +52,15 @@ cdef inline double complex clog1p(double complex z) noexcept nogil:
zi = z.imag

if zi == 0.0 and zr >= -1.0:
return zpack(log1p(zr), 0.0)
return zpack(cephes_log1p_wrap(zr), 0.0)

az = zabs(z)
if az < 0.707:
azi = fabs(zi)
if zr < 0 and fabs(-zr - azi*azi/2)/(-zr) < 0.5:
return clog1p_ddouble(zr, zi)
else:
x = 0.5 * log1p(az*(az + 2*zr/az))
x = 0.5 * cephes_log1p_wrap(az*(az + 2*zr/az))
y = atan2(zi, zr + 1.0)
return zpack(x, y)

Expand All @@ -73,13 +76,13 @@ cdef inline double complex clog1p_ddouble(double zr, double zi) noexcept nogil:
i = dd_create_d(zi)
two = dd_create_d(2.0)

rsqr = dd_mul(r, r)
isqr = dd_mul(i, i)
rtwo = dd_mul(two, r)
absm1 = dd_add(rsqr, isqr)
absm1 = dd_add(absm1, rtwo)
rsqr = dd_mul(&r,& r)
isqr = dd_mul(&i, &i)
rtwo = dd_mul(&two, &r)
absm1 = dd_add(&rsqr, &isqr)
absm1 = dd_add(&absm1, &rtwo)

x = 0.5 * log1p(dd_to_double(absm1))
x = 0.5 * cephes_log1p_wrap(dd_to_double(&absm1))
y = atan2(zi, zr+1.0)
return zpack(x, y)

Expand All @@ -104,8 +107,8 @@ cdef inline double complex cexpm1(double complex z) noexcept nogil:
if zr <= -40:
x = -1.0
else:
ezr = expm1(zr)
x = ezr*cos(zi) + cosm1(zi)
ezr = cephes_expm1_wrap(zr)
x = ezr*cos(zi) + cephes_cosm1_wrap(zi)
# don't compute exp(zr) too, unless necessary
if zr > -1.0:
y = (ezr + 1.0)*sin(zi)
Expand Down
5 changes: 3 additions & 2 deletions scipy/special/_ellipk.pxd
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from ._cephes cimport ellpk
cdef extern from "special_wrappers.h" nogil:
double cephes_ellpk_wrap(double x)


cdef inline double ellipk(double m) noexcept nogil:
return ellpk(1.0 - m)
return cephes_ellpk_wrap(1.0 - m)
5 changes: 3 additions & 2 deletions scipy/special/_factorial.pxd
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from ._cephes cimport Gamma
cdef extern from "special_wrappers.h" nogil:
double cephes_gamma_wrap(double x)


cdef inline double _factorial(double n) noexcept nogil:
if n < 0:
return 0
else:
return Gamma(n + 1)
return cephes_gamma_wrap(n + 1)
22 changes: 14 additions & 8 deletions scipy/special/_hyp0f1.pxd
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
from libc.math cimport pow, sqrt, floor, log, log1p, exp, M_PI, NAN, fabs, isinf
cimport numpy as np

from ._cephes cimport iv, jv, Gamma, lgam, gammasgn
from ._xlogy cimport xlogy
from ._complexstuff cimport (
zsqrt, zpow, zabs, npy_cdouble_from_double_complex,
double_complex_from_npy_cdouble)

cdef extern from "special_wrappers.h" nogil:
double cephes_iv_wrap(double v, double x)
double cephes_jv_wrap(double v, double x)
double cephes_gamma_wrap(double x)
double cephes_lgam_wrap(double x)
double cephes_gammasgn_wrap(double x)

cdef extern from "float.h":
double DBL_MAX, DBL_MIN

Expand Down Expand Up @@ -37,17 +43,17 @@ cdef inline double _hyp0f1_real(double v, double z) noexcept nogil:

if z > 0:
arg = sqrt(z)
arg_exp = xlogy(1.0-v, arg) + lgam(v)
bess_val = iv(v-1, 2.0*arg)
arg_exp = xlogy(1.0-v, arg) + cephes_lgam_wrap(v)
bess_val = cephes_iv_wrap(v-1, 2.0*arg)

if (arg_exp > log(DBL_MAX) or bess_val == 0 or # overflow
arg_exp < log(DBL_MIN) or isinf(bess_val)): # underflow
return _hyp0f1_asy(v, z)
else:
return exp(arg_exp) * gammasgn(v) * bess_val
return exp(arg_exp) * cephes_gammasgn_wrap(v) * bess_val
else:
arg = sqrt(-z)
return pow(arg, 1.0 - v) * Gamma(v) * jv(v - 1, 2*arg)
return pow(arg, 1.0 - v) * cephes_gamma_wrap(v) * cephes_jv_wrap(v - 1, 2*arg)


cdef inline double _hyp0f1_asy(double v, double z) noexcept nogil:
Expand All @@ -68,8 +74,8 @@ cdef inline double _hyp0f1_asy(double v, double z) noexcept nogil:

arg_exp_i = -0.5*log(p1)
arg_exp_i -= 0.5*log(2.0*M_PI*v1)
arg_exp_i += lgam(v)
gs = gammasgn(v)
arg_exp_i += cephes_lgam_wrap(v)
gs = cephes_gammasgn_wrap(v)

arg_exp_k = arg_exp_i
arg_exp_i += v1 * eta
Expand Down Expand Up @@ -127,4 +133,4 @@ cdef inline double complex _hyp0f1_cmplx(double v, double complex z) noexcept no
s = 2.0 * arg
r = special_ccyl_bessel_j(v-1.0, npy_cdouble_from_double_complex(s))

return double_complex_from_npy_cdouble(r) * Gamma(v) * zpow(arg, 1.0 - v)
return double_complex_from_npy_cdouble(r) * cephes_gamma_wrap(v) * zpow(arg, 1.0 - v)
4 changes: 2 additions & 2 deletions scipy/special/_hypergeometric.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ from libc.math cimport fabs, exp, floor, isnan, M_PI, NAN, INFINITY
import cython

from . cimport sf_error
from ._cephes cimport expm1, poch

cdef extern from 'special_wrappers.h':
double hypU_wrap(double, double, double) nogil
double cephes_poch_wrap(double x, double m) nogil


@cython.cdivision(True)
Expand All @@ -25,6 +25,6 @@ cdef inline double hyperu(double a, double b, double x) noexcept nogil:
return INFINITY
else:
# DLMF 13.2.14-15 and 13.2.19-21
return poch(1.0 - b + a, -a)
return cephes_poch_wrap(1.0 - b + a, -a)

return hypU_wrap(a, b, x)
Loading
0