Index: generic/include/clc/clc.h =================================================================== --- generic/include/clc/clc.h +++ generic/include/clc/clc.h @@ -50,8 +50,6 @@ #include #include #include -#include -#include #include #include #include @@ -70,8 +68,6 @@ #include #include #include -#include -#include #include #include #include Index: generic/include/clc/math/erf.h =================================================================== --- generic/include/clc/math/erf.h +++ /dev/null @@ -1,9 +0,0 @@ -#undef erfc - -#define __CLC_BODY -#define __CLC_FUNCTION erf - -#include - -#undef __CLC_BODY -#undef __CLC_FUNCTION Index: generic/include/clc/math/erfc.h =================================================================== --- generic/include/clc/math/erfc.h +++ /dev/null @@ -1,9 +0,0 @@ -#undef erfc - -#define __CLC_BODY -#define __CLC_FUNCTION erfc - -#include - -#undef __CLC_BODY -#undef __CLC_FUNCTION Index: generic/include/clc/math/lgamma.h =================================================================== --- generic/include/clc/math/lgamma.h +++ /dev/null @@ -1,2 +0,0 @@ -#define __CLC_BODY -#include Index: generic/include/clc/math/lgamma.inc =================================================================== --- generic/include/clc/math/lgamma.inc +++ /dev/null @@ -1 +0,0 @@ -_CLC_OVERLOAD _CLC_DECL __CLC_GENTYPE lgamma(__CLC_GENTYPE a); Index: generic/include/clc/math/lgamma_r.h =================================================================== --- generic/include/clc/math/lgamma_r.h +++ /dev/null @@ -1,2 +0,0 @@ -#define __CLC_BODY -#include Index: generic/include/clc/math/lgamma_r.inc =================================================================== --- generic/include/clc/math/lgamma_r.inc +++ /dev/null @@ -1,3 +0,0 @@ -_CLC_OVERLOAD _CLC_DECL __CLC_GENTYPE lgamma_r(__CLC_GENTYPE x, global __CLC_INTN *iptr); -_CLC_OVERLOAD _CLC_DECL __CLC_GENTYPE lgamma_r(__CLC_GENTYPE x, local __CLC_INTN *iptr); -_CLC_OVERLOAD _CLC_DECL __CLC_GENTYPE lgamma_r(__CLC_GENTYPE x, private __CLC_INTN *iptr); Index: generic/lib/SOURCES =================================================================== --- generic/lib/SOURCES +++ generic/lib/SOURCES @@ -79,8 +79,6 @@ math/cosh.cl math/cospi.cl math/ep_log.cl -math/erf.cl -math/erfc.cl math/exp.cl math/exp_helper.cl math/expm1.cl @@ -98,8 +96,6 @@ math/ilogb.cl math/clc_ldexp.cl math/ldexp.cl -math/lgamma.cl -math/lgamma_r.cl math/log.cl math/log10.cl math/log1p.cl Index: generic/lib/math/erf.cl =================================================================== --- generic/lib/math/erf.cl +++ /dev/null @@ -1,380 +0,0 @@ -#include - -#include "math.h" -#include "../clcmacro.h" - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== -*/ - -#define erx 8.4506291151e-01f /* 0x3f58560b */ - -// Coefficients for approximation to erf on [00.84375] - -#define efx 1.2837916613e-01f /* 0x3e0375d4 */ -#define efx8 1.0270333290e+00f /* 0x3f8375d4 */ - -#define pp0 1.2837916613e-01f /* 0x3e0375d4 */ -#define pp1 -3.2504209876e-01f /* 0xbea66beb */ -#define pp2 -2.8481749818e-02f /* 0xbce9528f */ -#define pp3 -5.7702702470e-03f /* 0xbbbd1489 */ -#define pp4 -2.3763017452e-05f /* 0xb7c756b1 */ -#define qq1 3.9791721106e-01f /* 0x3ecbbbce */ -#define qq2 6.5022252500e-02f /* 0x3d852a63 */ -#define qq3 5.0813062117e-03f /* 0x3ba68116 */ -#define qq4 1.3249473704e-04f /* 0x390aee49 */ -#define qq5 -3.9602282413e-06f /* 0xb684e21a */ - -// Coefficients for approximation to erf in [0.843751.25] - -#define pa0 -2.3621185683e-03f /* 0xbb1acdc6 */ -#define pa1 4.1485610604e-01f /* 0x3ed46805 */ -#define pa2 -3.7220788002e-01f /* 0xbebe9208 */ -#define pa3 3.1834661961e-01f /* 0x3ea2fe54 */ -#define pa4 -1.1089469492e-01f /* 0xbde31cc2 */ -#define pa5 3.5478305072e-02f /* 0x3d1151b3 */ -#define pa6 -2.1663755178e-03f /* 0xbb0df9c0 */ -#define qa1 1.0642088205e-01f /* 0x3dd9f331 */ -#define qa2 5.4039794207e-01f /* 0x3f0a5785 */ -#define qa3 7.1828655899e-02f /* 0x3d931ae7 */ -#define qa4 1.2617121637e-01f /* 0x3e013307 */ -#define qa5 1.3637083583e-02f /* 0x3c5f6e13 */ -#define qa6 1.1984500103e-02f /* 0x3c445aa3 */ - -// Coefficients for approximation to erfc in [1.251/0.35] - -#define ra0 -9.8649440333e-03f /* 0xbc21a093 */ -#define ra1 -6.9385856390e-01f /* 0xbf31a0b7 */ -#define ra2 -1.0558626175e+01f /* 0xc128f022 */ -#define ra3 -6.2375331879e+01f /* 0xc2798057 */ -#define ra4 -1.6239666748e+02f /* 0xc322658c */ -#define ra5 -1.8460508728e+02f /* 0xc3389ae7 */ -#define ra6 -8.1287437439e+01f /* 0xc2a2932b */ -#define ra7 -9.8143291473e+00f /* 0xc11d077e */ -#define sa1 1.9651271820e+01f /* 0x419d35ce */ -#define sa2 1.3765776062e+02f /* 0x4309a863 */ -#define sa3 4.3456588745e+02f /* 0x43d9486f */ -#define sa4 6.4538726807e+02f /* 0x442158c9 */ -#define sa5 4.2900814819e+02f /* 0x43d6810b */ -#define sa6 1.0863500214e+02f /* 0x42d9451f */ -#define sa7 6.5702495575e+00f /* 0x40d23f7c */ -#define sa8 -6.0424413532e-02f /* 0xbd777f97 */ - -// Coefficients for approximation to erfc in [1/.3528] - -#define rb0 -9.8649431020e-03f /* 0xbc21a092 */ -#define rb1 -7.9928326607e-01f /* 0xbf4c9dd4 */ -#define rb2 -1.7757955551e+01f /* 0xc18e104b */ -#define rb3 -1.6063638306e+02f /* 0xc320a2ea */ -#define rb4 -6.3756646729e+02f /* 0xc41f6441 */ -#define rb5 -1.0250950928e+03f /* 0xc480230b */ -#define rb6 -4.8351919556e+02f /* 0xc3f1c275 */ -#define sb1 3.0338060379e+01f /* 0x41f2b459 */ -#define sb2 3.2579251099e+02f /* 0x43a2e571 */ -#define sb3 1.5367296143e+03f /* 0x44c01759 */ -#define sb4 3.1998581543e+03f /* 0x4547fdbb */ -#define sb5 2.5530502930e+03f /* 0x451f90ce */ -#define sb6 4.7452853394e+02f /* 0x43ed43a7 */ -#define sb7 -2.2440952301e+01f /* 0xc1b38712 */ - -_CLC_OVERLOAD _CLC_DEF float erf(float x) { - int hx = as_uint(x); - int ix = hx & 0x7fffffff; - float absx = as_float(ix); - - float x2 = absx * absx; - float t = 1.0f / x2; - float tt = absx - 1.0f; - t = absx < 1.25f ? tt : t; - t = absx < 0.84375f ? x2 : t; - - float u, v, tu, tv; - - // |x| < 6 - u = mad(t, mad(t, mad(t, mad(t, mad(t, mad(t, rb6, rb5), rb4), rb3), rb2), rb1), rb0); - v = mad(t, mad(t, mad(t, mad(t, mad(t, mad(t, sb7, sb6), sb5), sb4), sb3), sb2), sb1); - - tu = mad(t, mad(t, mad(t, mad(t, mad(t, mad(t, mad(t, ra7, ra6), ra5), ra4), ra3), ra2), ra1), ra0); - tv = mad(t, mad(t, mad(t, mad(t, mad(t, mad(t, mad(t, sa8, sa7), sa6), sa5), sa4), sa3), sa2), sa1); - u = absx < 0x1.6db6dcp+1f ? tu : u; - v = absx < 0x1.6db6dcp+1f ? tv : v; - - tu = mad(t, mad(t, mad(t, mad(t, mad(t, mad(t, pa6, pa5), pa4), pa3), pa2), pa1), pa0); - tv = mad(t, mad(t, mad(t, mad(t, mad(t, qa6, qa5), qa4), qa3), qa2), qa1); - u = absx < 1.25f ? tu : u; - v = absx < 1.25f ? tv : v; - - tu = mad(t, mad(t, mad(t, mad(t, pp4, pp3), pp2), pp1), pp0); - tv = mad(t, mad(t, mad(t, mad(t, qq5, qq4), qq3), qq2), qq1); - u = absx < 0.84375f ? tu : u; - v = absx < 0.84375f ? tv : v; - - v = mad(t, v, 1.0f); - float q = MATH_DIVIDE(u, v); - - float ret = 1.0f; - - // |x| < 6 - float z = as_float(ix & 0xfffff000); - float r = exp(mad(-z, z, -0.5625f)) * exp(mad(z-absx, z+absx, q)); - r = 1.0f - MATH_DIVIDE(r, absx); - ret = absx < 6.0f ? r : ret; - - r = erx + q; - ret = absx < 1.25f ? r : ret; - - ret = as_float((hx & 0x80000000) | as_int(ret)); - - r = mad(x, q, x); - ret = absx < 0.84375f ? r : ret; - - // Prevent underflow - r = 0.125f * mad(8.0f, x, efx8 * x); - ret = absx < 0x1.0p-28f ? r : ret; - - ret = isnan(x) ? x : ret; - - return ret; -} - -_CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, erf, float); - -#ifdef cl_khr_fp64 - -#pragma OPENCL EXTENSION cl_khr_fp64 : enable - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* double erf(double x) - * double erfc(double x) - * x - * 2 |\ - * erf(x) = --------- | exp(-t*t)dt - * sqrt(pi) \| - * 0 - * - * erfc(x) = 1-erf(x) - * Note that - * erf(-x) = -erf(x) - * erfc(-x) = 2 - erfc(x) - * - * Method: - * 1. For |x| in [0, 0.84375] - * erf(x) = x + x*R(x^2) - * erfc(x) = 1 - erf(x) if x in [-.84375,0.25] - * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375] - * where R = P/Q where P is an odd poly of degree 8 and - * Q is an odd poly of degree 10. - * -57.90 - * | R - (erf(x)-x)/x | <= 2 - * - * - * Remark. The formula is derived by noting - * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) - * and that - * 2/sqrt(pi) = 1.128379167095512573896158903121545171688 - * is close to one. The interval is chosen because the fix - * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is - * near 0.6174), and by some experiment, 0.84375 is chosen to - * guarantee the error is less than one ulp for erf. - * - * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and - * c = 0.84506291151 rounded to single (24 bits) - * erf(x) = sign(x) * (c + P1(s)/Q1(s)) - * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0 - * 1+(c+P1(s)/Q1(s)) if x < 0 - * |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06 - * Remark: here we use the taylor series expansion at x=1. - * erf(1+s) = erf(1) + s*Poly(s) - * = 0.845.. + P1(s)/Q1(s) - * That is, we use rational approximation to approximate - * erf(1+s) - (c = (single)0.84506291151) - * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] - * where - * P1(s) = degree 6 poly in s - * Q1(s) = degree 6 poly in s - * - * 3. For x in [1.25,1/0.35(~2.857143)], - * erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1) - * erf(x) = 1 - erfc(x) - * where - * R1(z) = degree 7 poly in z, (z=1/x^2) - * S1(z) = degree 8 poly in z - * - * 4. For x in [1/0.35,28] - * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0 - * = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6 x >= 28 - * erf(x) = sign(x) *(1 - tiny) (raise inexact) - * erfc(x) = tiny*tiny (raise underflow) if x > 0 - * = 2 - tiny if x<0 - * - * 7. Special case: - * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1, - * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, - * erfc/erf(NaN) is NaN - */ - -#define AU0 -9.86494292470009928597e-03 -#define AU1 -7.99283237680523006574e-01 -#define AU2 -1.77579549177547519889e+01 -#define AU3 -1.60636384855821916062e+02 -#define AU4 -6.37566443368389627722e+02 -#define AU5 -1.02509513161107724954e+03 -#define AU6 -4.83519191608651397019e+02 - -#define AV1 3.03380607434824582924e+01 -#define AV2 3.25792512996573918826e+02 -#define AV3 1.53672958608443695994e+03 -#define AV4 3.19985821950859553908e+03 -#define AV5 2.55305040643316442583e+03 -#define AV6 4.74528541206955367215e+02 -#define AV7 -2.24409524465858183362e+01 - -#define BU0 -9.86494403484714822705e-03 -#define BU1 -6.93858572707181764372e-01 -#define BU2 -1.05586262253232909814e+01 -#define BU3 -6.23753324503260060396e+01 -#define BU4 -1.62396669462573470355e+02 -#define BU5 -1.84605092906711035994e+02 -#define BU6 -8.12874355063065934246e+01 -#define BU7 -9.81432934416914548592e+00 - -#define BV1 1.96512716674392571292e+01 -#define BV2 1.37657754143519042600e+02 -#define BV3 4.34565877475229228821e+02 -#define BV4 6.45387271733267880336e+02 -#define BV5 4.29008140027567833386e+02 -#define BV6 1.08635005541779435134e+02 -#define BV7 6.57024977031928170135e+00 -#define BV8 -6.04244152148580987438e-02 - -#define CU0 -2.36211856075265944077e-03 -#define CU1 4.14856118683748331666e-01 -#define CU2 -3.72207876035701323847e-01 -#define CU3 3.18346619901161753674e-01 -#define CU4 -1.10894694282396677476e-01 -#define CU5 3.54783043256182359371e-02 -#define CU6 -2.16637559486879084300e-03 - -#define CV1 1.06420880400844228286e-01 -#define CV2 5.40397917702171048937e-01 -#define CV3 7.18286544141962662868e-02 -#define CV4 1.26171219808761642112e-01 -#define CV5 1.36370839120290507362e-02 -#define CV6 1.19844998467991074170e-02 - -#define DU0 1.28379167095512558561e-01 -#define DU1 -3.25042107247001499370e-01 -#define DU2 -2.84817495755985104766e-02 -#define DU3 -5.77027029648944159157e-03 -#define DU4 -2.37630166566501626084e-05 - -#define DV1 3.97917223959155352819e-01 -#define DV2 6.50222499887672944485e-02 -#define DV3 5.08130628187576562776e-03 -#define DV4 1.32494738004321644526e-04 -#define DV5 -3.96022827877536812320e-06 - -_CLC_OVERLOAD _CLC_DEF double erf(double y) { - double x = fabs(y); - double x2 = x * x; - double xm1 = x - 1.0; - - // Poly variable - double t = 1.0 / x2; - t = x < 1.25 ? xm1 : t; - t = x < 0.84375 ? x2 : t; - - double u, ut, v, vt; - - // Evaluate rational poly - // XXX We need to see of we can grab 16 coefficents from a table - // faster than evaluating 3 of the poly pairs - // if (x < 6.0) - u = fma(t, fma(t, fma(t, fma(t, fma(t, fma(t, AU6, AU5), AU4), AU3), AU2), AU1), AU0); - v = fma(t, fma(t, fma(t, fma(t, fma(t, fma(t, AV7, AV6), AV5), AV4), AV3), AV2), AV1); - - ut = fma(t, fma(t, fma(t, fma(t, fma(t, fma(t, fma(t, BU7, BU6), BU5), BU4), BU3), BU2), BU1), BU0); - vt = fma(t, fma(t, fma(t, fma(t, fma(t, fma(t, fma(t, BV8, BV7), BV6), BV5), BV4), BV3), BV2), BV1); - u = x < 0x1.6db6ep+1 ? ut : u; - v = x < 0x1.6db6ep+1 ? vt : v; - - ut = fma(t, fma(t, fma(t, fma(t, fma(t, fma(t, CU6, CU5), CU4), CU3), CU2), CU1), CU0); - vt = fma(t, fma(t, fma(t, fma(t, fma(t, CV6, CV5), CV4), CV3), CV2), CV1); - u = x < 1.25 ? ut : u; - v = x < 1.25 ? vt : v; - - ut = fma(t, fma(t, fma(t, fma(t, DU4, DU3), DU2), DU1), DU0); - vt = fma(t, fma(t, fma(t, fma(t, DV5, DV4), DV3), DV2), DV1); - u = x < 0.84375 ? ut : u; - v = x < 0.84375 ? vt : v; - - v = fma(t, v, 1.0); - - // Compute rational approximation - double q = u / v; - - // Compute results - double z = as_double(as_long(x) & 0xffffffff00000000L); - double r = exp(-z * z - 0.5625) * exp((z - x) * (z + x) + q); - r = 1.0 - r / x; - - double ret = x < 6.0 ? r : 1.0; - - r = 8.45062911510467529297e-01 + q; - ret = x < 1.25 ? r : ret; - - q = x < 0x1.0p-28 ? 1.28379167095512586316e-01 : q; - - r = fma(x, q, x); - ret = x < 0.84375 ? r : ret; - - ret = isnan(x) ? x : ret; - - return y < 0.0 ? -ret : ret; -} - -_CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, erf, double); - -#endif Index: generic/lib/math/erfc.cl =================================================================== --- generic/lib/math/erfc.cl +++ /dev/null @@ -1,391 +0,0 @@ -#include - -#include "math.h" -#include "../clcmacro.h" - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#define erx_f 8.4506291151e-01f /* 0x3f58560b */ - -// Coefficients for approximation to erf on [00.84375] - -#define efx 1.2837916613e-01f /* 0x3e0375d4 */ -#define efx8 1.0270333290e+00f /* 0x3f8375d4 */ - -#define pp0 1.2837916613e-01f /* 0x3e0375d4 */ -#define pp1 -3.2504209876e-01f /* 0xbea66beb */ -#define pp2 -2.8481749818e-02f /* 0xbce9528f */ -#define pp3 -5.7702702470e-03f /* 0xbbbd1489 */ -#define pp4 -2.3763017452e-05f /* 0xb7c756b1 */ -#define qq1 3.9791721106e-01f /* 0x3ecbbbce */ -#define qq2 6.5022252500e-02f /* 0x3d852a63 */ -#define qq3 5.0813062117e-03f /* 0x3ba68116 */ -#define qq4 1.3249473704e-04f /* 0x390aee49 */ -#define qq5 -3.9602282413e-06f /* 0xb684e21a */ - -// Coefficients for approximation to erf in [0.843751.25] - -#define pa0 -2.3621185683e-03f /* 0xbb1acdc6 */ -#define pa1 4.1485610604e-01f /* 0x3ed46805 */ -#define pa2 -3.7220788002e-01f /* 0xbebe9208 */ -#define pa3 3.1834661961e-01f /* 0x3ea2fe54 */ -#define pa4 -1.1089469492e-01f /* 0xbde31cc2 */ -#define pa5 3.5478305072e-02f /* 0x3d1151b3 */ -#define pa6 -2.1663755178e-03f /* 0xbb0df9c0 */ -#define qa1 1.0642088205e-01f /* 0x3dd9f331 */ -#define qa2 5.4039794207e-01f /* 0x3f0a5785 */ -#define qa3 7.1828655899e-02f /* 0x3d931ae7 */ -#define qa4 1.2617121637e-01f /* 0x3e013307 */ -#define qa5 1.3637083583e-02f /* 0x3c5f6e13 */ -#define qa6 1.1984500103e-02f /* 0x3c445aa3 */ - -// Coefficients for approximation to erfc in [1.251/0.35] - -#define ra0 -9.8649440333e-03f /* 0xbc21a093 */ -#define ra1 -6.9385856390e-01f /* 0xbf31a0b7 */ -#define ra2 -1.0558626175e+01f /* 0xc128f022 */ -#define ra3 -6.2375331879e+01f /* 0xc2798057 */ -#define ra4 -1.6239666748e+02f /* 0xc322658c */ -#define ra5 -1.8460508728e+02f /* 0xc3389ae7 */ -#define ra6 -8.1287437439e+01f /* 0xc2a2932b */ -#define ra7 -9.8143291473e+00f /* 0xc11d077e */ -#define sa1 1.9651271820e+01f /* 0x419d35ce */ -#define sa2 1.3765776062e+02f /* 0x4309a863 */ -#define sa3 4.3456588745e+02f /* 0x43d9486f */ -#define sa4 6.4538726807e+02f /* 0x442158c9 */ -#define sa5 4.2900814819e+02f /* 0x43d6810b */ -#define sa6 1.0863500214e+02f /* 0x42d9451f */ -#define sa7 6.5702495575e+00f /* 0x40d23f7c */ -#define sa8 -6.0424413532e-02f /* 0xbd777f97 */ - -// Coefficients for approximation to erfc in [1/.3528] - -#define rb0 -9.8649431020e-03f /* 0xbc21a092 */ -#define rb1 -7.9928326607e-01f /* 0xbf4c9dd4 */ -#define rb2 -1.7757955551e+01f /* 0xc18e104b */ -#define rb3 -1.6063638306e+02f /* 0xc320a2ea */ -#define rb4 -6.3756646729e+02f /* 0xc41f6441 */ -#define rb5 -1.0250950928e+03f /* 0xc480230b */ -#define rb6 -4.8351919556e+02f /* 0xc3f1c275 */ -#define sb1 3.0338060379e+01f /* 0x41f2b459 */ -#define sb2 3.2579251099e+02f /* 0x43a2e571 */ -#define sb3 1.5367296143e+03f /* 0x44c01759 */ -#define sb4 3.1998581543e+03f /* 0x4547fdbb */ -#define sb5 2.5530502930e+03f /* 0x451f90ce */ -#define sb6 4.7452853394e+02f /* 0x43ed43a7 */ -#define sb7 -2.2440952301e+01f /* 0xc1b38712 */ - -_CLC_OVERLOAD _CLC_DEF float erfc(float x) { - int hx = as_int(x); - int ix = hx & 0x7fffffff; - float absx = as_float(ix); - - // Argument for polys - float x2 = absx * absx; - float t = 1.0f / x2; - float tt = absx - 1.0f; - t = absx < 1.25f ? tt : t; - t = absx < 0.84375f ? x2 : t; - - // Evaluate polys - float tu, tv, u, v; - - u = mad(t, mad(t, mad(t, mad(t, mad(t, mad(t, rb6, rb5), rb4), rb3), rb2), rb1), rb0); - v = mad(t, mad(t, mad(t, mad(t, mad(t, mad(t, sb7, sb6), sb5), sb4), sb3), sb2), sb1); - - tu = mad(t, mad(t, mad(t, mad(t, mad(t, mad(t, mad(t, ra7, ra6), ra5), ra4), ra3), ra2), ra1), ra0); - tv = mad(t, mad(t, mad(t, mad(t, mad(t, mad(t, mad(t, sa8, sa7), sa6), sa5), sa4), sa3), sa2), sa1); - u = absx < 0x1.6db6dap+1f ? tu : u; - v = absx < 0x1.6db6dap+1f ? tv : v; - - tu = mad(t, mad(t, mad(t, mad(t, mad(t, mad(t, pa6, pa5), pa4), pa3), pa2), pa1), pa0); - tv = mad(t, mad(t, mad(t, mad(t, mad(t, qa6, qa5), qa4), qa3), qa2), qa1); - u = absx < 1.25f ? tu : u; - v = absx < 1.25f ? tv : v; - - tu = mad(t, mad(t, mad(t, mad(t, pp4, pp3), pp2), pp1), pp0); - tv = mad(t, mad(t, mad(t, mad(t, qq5, qq4), qq3), qq2), qq1); - u = absx < 0.84375f ? tu : u; - v = absx < 0.84375f ? tv : v; - - v = mad(t, v, 1.0f); - - float q = MATH_DIVIDE(u, v); - - float ret = 0.0f; - - float z = as_float(ix & 0xfffff000); - float r = exp(mad(-z, z, -0.5625f)) * exp(mad(z - absx, z + absx, q)); - r = MATH_DIVIDE(r, absx); - t = 2.0f - r; - r = x < 0.0f ? t : r; - ret = absx < 28.0f ? r : ret; - - r = 1.0f - erx_f - q; - t = erx_f + q + 1.0f; - r = x < 0.0f ? t : r; - ret = absx < 1.25f ? r : ret; - - r = 0.5f - mad(x, q, x - 0.5f); - ret = absx < 0.84375f ? r : ret; - - ret = x < -6.0f ? 2.0f : ret; - - ret = isnan(x) ? x : ret; - - return ret; -} - -_CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, erfc, float); - -#ifdef cl_khr_fp64 - -#pragma OPENCL EXTENSION cl_khr_fp64 : enable - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* double erf(double x) - * double erfc(double x) - * x - * 2 |\ - * erf(x) = --------- | exp(-t*t)dt - * sqrt(pi) \| - * 0 - * - * erfc(x) = 1-erf(x) - * Note that - * erf(-x) = -erf(x) - * erfc(-x) = 2 - erfc(x) - * - * Method: - * 1. For |x| in [0, 0.84375] - * erf(x) = x + x*R(x^2) - * erfc(x) = 1 - erf(x) if x in [-.84375,0.25] - * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375] - * where R = P/Q where P is an odd poly of degree 8 and - * Q is an odd poly of degree 10. - * -57.90 - * | R - (erf(x)-x)/x | <= 2 - * - * - * Remark. The formula is derived by noting - * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) - * and that - * 2/sqrt(pi) = 1.128379167095512573896158903121545171688 - * is close to one. The interval is chosen because the fix - * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is - * near 0.6174), and by some experiment, 0.84375 is chosen to - * guarantee the error is less than one ulp for erf. - * - * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and - * c = 0.84506291151 rounded to single (24 bits) - * erf(x) = sign(x) * (c + P1(s)/Q1(s)) - * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0 - * 1+(c+P1(s)/Q1(s)) if x < 0 - * |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06 - * Remark: here we use the taylor series expansion at x=1. - * erf(1+s) = erf(1) + s*Poly(s) - * = 0.845.. + P1(s)/Q1(s) - * That is, we use rational approximation to approximate - * erf(1+s) - (c = (single)0.84506291151) - * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] - * where - * P1(s) = degree 6 poly in s - * Q1(s) = degree 6 poly in s - * - * 3. For x in [1.25,1/0.35(~2.857143)], - * erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1) - * erf(x) = 1 - erfc(x) - * where - * R1(z) = degree 7 poly in z, (z=1/x^2) - * S1(z) = degree 8 poly in z - * - * 4. For x in [1/0.35,28] - * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0 - * = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6 x >= 28 - * erf(x) = sign(x) *(1 - tiny) (raise inexact) - * erfc(x) = tiny*tiny (raise underflow) if x > 0 - * = 2 - tiny if x<0 - * - * 7. Special case: - * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1, - * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, - * erfc/erf(NaN) is NaN - */ - -#define AU0 -9.86494292470009928597e-03 -#define AU1 -7.99283237680523006574e-01 -#define AU2 -1.77579549177547519889e+01 -#define AU3 -1.60636384855821916062e+02 -#define AU4 -6.37566443368389627722e+02 -#define AU5 -1.02509513161107724954e+03 -#define AU6 -4.83519191608651397019e+02 - -#define AV0 3.03380607434824582924e+01 -#define AV1 3.25792512996573918826e+02 -#define AV2 1.53672958608443695994e+03 -#define AV3 3.19985821950859553908e+03 -#define AV4 2.55305040643316442583e+03 -#define AV5 4.74528541206955367215e+02 -#define AV6 -2.24409524465858183362e+01 - -#define BU0 -9.86494403484714822705e-03 -#define BU1 -6.93858572707181764372e-01 -#define BU2 -1.05586262253232909814e+01 -#define BU3 -6.23753324503260060396e+01 -#define BU4 -1.62396669462573470355e+02 -#define BU5 -1.84605092906711035994e+02 -#define BU6 -8.12874355063065934246e+01 -#define BU7 -9.81432934416914548592e+00 - -#define BV0 1.96512716674392571292e+01 -#define BV1 1.37657754143519042600e+02 -#define BV2 4.34565877475229228821e+02 -#define BV3 6.45387271733267880336e+02 -#define BV4 4.29008140027567833386e+02 -#define BV5 1.08635005541779435134e+02 -#define BV6 6.57024977031928170135e+00 -#define BV7 -6.04244152148580987438e-02 - -#define CU0 -2.36211856075265944077e-03 -#define CU1 4.14856118683748331666e-01 -#define CU2 -3.72207876035701323847e-01 -#define CU3 3.18346619901161753674e-01 -#define CU4 -1.10894694282396677476e-01 -#define CU5 3.54783043256182359371e-02 -#define CU6 -2.16637559486879084300e-03 - -#define CV0 1.06420880400844228286e-01 -#define CV1 5.40397917702171048937e-01 -#define CV2 7.18286544141962662868e-02 -#define CV3 1.26171219808761642112e-01 -#define CV4 1.36370839120290507362e-02 -#define CV5 1.19844998467991074170e-02 - -#define DU0 1.28379167095512558561e-01 -#define DU1 -3.25042107247001499370e-01 -#define DU2 -2.84817495755985104766e-02 -#define DU3 -5.77027029648944159157e-03 -#define DU4 -2.37630166566501626084e-05 - -#define DV0 3.97917223959155352819e-01 -#define DV1 6.50222499887672944485e-02 -#define DV2 5.08130628187576562776e-03 -#define DV3 1.32494738004321644526e-04 -#define DV4 -3.96022827877536812320e-06 - -_CLC_OVERLOAD _CLC_DEF double erfc(double x) { - long lx = as_long(x); - long ax = lx & 0x7fffffffffffffffL; - double absx = as_double(ax); - int xneg = lx != ax; - - // Poly arg - double x2 = x * x; - double xm1 = absx - 1.0; - double t = 1.0 / x2; - t = absx < 1.25 ? xm1 : t; - t = absx < 0.84375 ? x2 : t; - - - // Evaluate rational poly - // XXX Need to evaluate if we can grab the 14 coefficients from a - // table faster than evaluating 3 pairs of polys - double tu, tv, u, v; - - // |x| < 28 - u = fma(t, fma(t, fma(t, fma(t, fma(t, fma(t, AU6, AU5), AU4), AU3), AU2), AU1), AU0); - v = fma(t, fma(t, fma(t, fma(t, fma(t, fma(t, AV6, AV5), AV4), AV3), AV2), AV1), AV0); - - tu = fma(t, fma(t, fma(t, fma(t, fma(t, fma(t, fma(t, BU7, BU6), BU5), BU4), BU3), BU2), BU1), BU0); - tv = fma(t, fma(t, fma(t, fma(t, fma(t, fma(t, fma(t, BV7, BV6), BV5), BV4), BV3), BV2), BV1), BV0); - u = absx < 0x1.6db6dp+1 ? tu : u; - v = absx < 0x1.6db6dp+1 ? tv : v; - - tu = fma(t, fma(t, fma(t, fma(t, fma(t, fma(t, CU6, CU5), CU4), CU3), CU2), CU1), CU0); - tv = fma(t, fma(t, fma(t, fma(t, fma(t, CV5, CV4), CV3), CV2), CV1), CV0); - u = absx < 1.25 ? tu : u; - v = absx < 1.25 ? tv : v; - - tu = fma(t, fma(t, fma(t, fma(t, DU4, DU3), DU2), DU1), DU0); - tv = fma(t, fma(t, fma(t, fma(t, DV4, DV3), DV2), DV1), DV0); - u = absx < 0.84375 ? tu : u; - v = absx < 0.84375 ? tv : v; - - v = fma(t, v, 1.0); - double q = u / v; - - - // Evaluate return value - - // |x| < 28 - double z = as_double(ax & 0xffffffff00000000UL); - double ret = exp(-z * z - 0.5625) * exp((z - absx) * (z + absx) + q) / absx; - t = 2.0 - ret; - ret = xneg ? t : ret; - - const double erx = 8.45062911510467529297e-01; - z = erx + q + 1.0; - t = 1.0 - erx - q; - t = xneg ? z : t; - ret = absx < 1.25 ? t : ret; - - // z = 1.0 - fma(x, q, x); - // t = 0.5 - fma(x, q, x - 0.5); - // t = xneg == 1 | absx < 0.25 ? z : t; - t = fma(-x, q, 1.0 - x); - ret = absx < 0.84375 ? t : ret; - - ret = x >= 28.0 ? 0.0 : ret; - ret = x <= -6.0 ? 2.0 : ret; - ret = ax > 0x7ff0000000000000UL ? x : ret; - - return ret; -} - -_CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, erfc, double); - -#endif Index: generic/lib/math/lgamma.cl =================================================================== --- generic/lib/math/lgamma.cl +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2016 Aaron Watry - * Copyright (c) 2014 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include "../clcmacro.h" - -_CLC_OVERLOAD _CLC_DEF float lgamma(float x) { - int s; - return lgamma_r(x, &s); -} - -_CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, lgamma, float) - -#ifdef cl_khr_fp64 -#pragma OPENCL EXTENSION cl_khr_fp64 : enable - -_CLC_OVERLOAD _CLC_DEF double lgamma(double x) { - int s; - return lgamma_r(x, &s); -} - -_CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, lgamma, double) - -#endif \ No newline at end of file Index: generic/lib/math/lgamma_r.cl =================================================================== --- generic/lib/math/lgamma_r.cl +++ /dev/null @@ -1,11 +0,0 @@ -#include - -#include "../clcmacro.h" -#include "math.h" - -#ifdef cl_khr_fp64 -#pragma OPENCL EXTENSION cl_khr_fp64 : enable -#endif - -#define __CLC_BODY -#include Index: generic/lib/math/lgamma_r.inc =================================================================== --- generic/lib/math/lgamma_r.inc +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Copyright (c) 2014 Advanced Micro Devices, Inc. - * Copyright (c) 2016 Aaron Watry - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#if __CLC_FPSIZE == 32 -#ifdef __CLC_SCALAR -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -#define pi_f 3.1415927410e+00f /* 0x40490fdb */ - -#define a0_f 7.7215664089e-02f /* 0x3d9e233f */ -#define a1_f 3.2246702909e-01f /* 0x3ea51a66 */ -#define a2_f 6.7352302372e-02f /* 0x3d89f001 */ -#define a3_f 2.0580807701e-02f /* 0x3ca89915 */ -#define a4_f 7.3855509982e-03f /* 0x3bf2027e */ -#define a5_f 2.8905137442e-03f /* 0x3b3d6ec6 */ -#define a6_f 1.1927076848e-03f /* 0x3a9c54a1 */ -#define a7_f 5.1006977446e-04f /* 0x3a05b634 */ -#define a8_f 2.2086278477e-04f /* 0x39679767 */ -#define a9_f 1.0801156895e-04f /* 0x38e28445 */ -#define a10_f 2.5214456400e-05f /* 0x37d383a2 */ -#define a11_f 4.4864096708e-05f /* 0x383c2c75 */ - -#define tc_f 1.4616321325e+00f /* 0x3fbb16c3 */ - -#define tf_f -1.2148628384e-01f /* 0xbdf8cdcd */ -/* tt -(tail of tf) */ -#define tt_f 6.6971006518e-09f /* 0x31e61c52 */ - -#define t0_f 4.8383611441e-01f /* 0x3ef7b95e */ -#define t1_f -1.4758771658e-01f /* 0xbe17213c */ -#define t2_f 6.4624942839e-02f /* 0x3d845a15 */ -#define t3_f -3.2788541168e-02f /* 0xbd064d47 */ -#define t4_f 1.7970675603e-02f /* 0x3c93373d */ -#define t5_f -1.0314224288e-02f /* 0xbc28fcfe */ -#define t6_f 6.1005386524e-03f /* 0x3bc7e707 */ -#define t7_f -3.6845202558e-03f /* 0xbb7177fe */ -#define t8_f 2.2596477065e-03f /* 0x3b141699 */ -#define t9_f -1.4034647029e-03f /* 0xbab7f476 */ -#define t10_f 8.8108185446e-04f /* 0x3a66f867 */ -#define t11_f -5.3859531181e-04f /* 0xba0d3085 */ -#define t12_f 3.1563205994e-04f /* 0x39a57b6b */ -#define t13_f -3.1275415677e-04f /* 0xb9a3f927 */ -#define t14_f 3.3552918467e-04f /* 0x39afe9f7 */ - -#define u0_f -7.7215664089e-02f /* 0xbd9e233f */ -#define u1_f 6.3282704353e-01f /* 0x3f2200f4 */ -#define u2_f 1.4549225569e+00f /* 0x3fba3ae7 */ -#define u3_f 9.7771751881e-01f /* 0x3f7a4bb2 */ -#define u4_f 2.2896373272e-01f /* 0x3e6a7578 */ -#define u5_f 1.3381091878e-02f /* 0x3c5b3c5e */ - -#define v1_f 2.4559779167e+00f /* 0x401d2ebe */ -#define v2_f 2.1284897327e+00f /* 0x4008392d */ -#define v3_f 7.6928514242e-01f /* 0x3f44efdf */ -#define v4_f 1.0422264785e-01f /* 0x3dd572af */ -#define v5_f 3.2170924824e-03f /* 0x3b52d5db */ - -#define s0_f -7.7215664089e-02f /* 0xbd9e233f */ -#define s1_f 2.1498242021e-01f /* 0x3e5c245a */ -#define s2_f 3.2577878237e-01f /* 0x3ea6cc7a */ -#define s3_f 1.4635047317e-01f /* 0x3e15dce6 */ -#define s4_f 2.6642270386e-02f /* 0x3cda40e4 */ -#define s5_f 1.8402845599e-03f /* 0x3af135b4 */ -#define s6_f 3.1947532989e-05f /* 0x3805ff67 */ - -#define r1_f 1.3920053244e+00f /* 0x3fb22d3b */ -#define r2_f 7.2193557024e-01f /* 0x3f38d0c5 */ -#define r3_f 1.7193385959e-01f /* 0x3e300f6e */ -#define r4_f 1.8645919859e-02f /* 0x3c98bf54 */ -#define r5_f 7.7794247773e-04f /* 0x3a4beed6 */ -#define r6_f 7.3266842264e-06f /* 0x36f5d7bd */ - -#define w0_f 4.1893854737e-01f /* 0x3ed67f1d */ -#define w1_f 8.3333335817e-02f /* 0x3daaaaab */ -#define w2_f -2.7777778450e-03f /* 0xbb360b61 */ -#define w3_f 7.9365057172e-04f /* 0x3a500cfd */ -#define w4_f -5.9518753551e-04f /* 0xba1c065c */ -#define w5_f 8.3633989561e-04f /* 0x3a5b3dd2 */ -#define w6_f -1.6309292987e-03f /* 0xbad5c4e8 */ - -_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE lgamma_r(float x, private int *signp) { - int hx = as_int(x); - int ix = hx & 0x7fffffff; - float absx = as_float(ix); - - if (ix >= 0x7f800000) { - *signp = 1; - return x; - } - - if (absx < 0x1.0p-70f) { - *signp = hx < 0 ? -1 : 1; - return -log(absx); - } - - float r; - - if (absx == 1.0f | absx == 2.0f) - r = 0.0f; - - else if (absx < 2.0f) { - float y = 2.0f - absx; - int i = 0; - - int c = absx < 0x1.bb4c30p+0f; - float yt = absx - tc_f; - y = c ? yt : y; - i = c ? 1 : i; - - c = absx < 0x1.3b4c40p+0f; - yt = absx - 1.0f; - y = c ? yt : y; - i = c ? 2 : i; - - r = -log(absx); - yt = 1.0f - absx; - c = absx <= 0x1.ccccccp-1f; - r = c ? r : 0.0f; - y = c ? yt : y; - i = c ? 0 : i; - - c = absx < 0x1.769440p-1f; - yt = absx - (tc_f - 1.0f); - y = c ? yt : y; - i = c ? 1 : i; - - c = absx < 0x1.da6610p-3f; - y = c ? absx : y; - i = c ? 2 : i; - - float z, w, p1, p2, p3, p; - switch (i) { - case 0: - z = y * y; - p1 = mad(z, mad(z, mad(z, mad(z, mad(z, a10_f, a8_f), a6_f), a4_f), a2_f), a0_f); - p2 = z * mad(z, mad(z, mad(z, mad(z, mad(z, a11_f, a9_f), a7_f), a5_f), a3_f), a1_f); - p = mad(y, p1, p2); - r += mad(y, -0.5f, p); - break; - case 1: - z = y * y; - w = z * y; - p1 = mad(w, mad(w, mad(w, mad(w, t12_f, t9_f), t6_f), t3_f), t0_f); - p2 = mad(w, mad(w, mad(w, mad(w, t13_f, t10_f), t7_f), t4_f), t1_f); - p3 = mad(w, mad(w, mad(w, mad(w, t14_f, t11_f), t8_f), t5_f), t2_f); - p = mad(z, p1, -mad(w, -mad(y, p3, p2), tt_f)); - r += tf_f + p; - break; - case 2: - p1 = y * mad(y, mad(y, mad(y, mad(y, mad(y, u5_f, u4_f), u3_f), u2_f), u1_f), u0_f); - p2 = mad(y, mad(y, mad(y, mad(y, mad(y, v5_f, v4_f), v3_f), v2_f), v1_f), 1.0f); - r += mad(y, -0.5f, MATH_DIVIDE(p1, p2)); - break; - } - } else if (absx < 8.0f) { - int i = (int) absx; - float y = absx - (float) i; - float p = y * mad(y, mad(y, mad(y, mad(y, mad(y, mad(y, s6_f, s5_f), s4_f), s3_f), s2_f), s1_f), s0_f); - float q = mad(y, mad(y, mad(y, mad(y, mad(y, mad(y, r6_f, r5_f), r4_f), r3_f), r2_f), r1_f), 1.0f); - r = mad(y, 0.5f, MATH_DIVIDE(p, q)); - - float y6 = y + 6.0f; - float y5 = y + 5.0f; - float y4 = y + 4.0f; - float y3 = y + 3.0f; - float y2 = y + 2.0f; - - float z = 1.0f; - z *= i > 6 ? y6 : 1.0f; - z *= i > 5 ? y5 : 1.0f; - z *= i > 4 ? y4 : 1.0f; - z *= i > 3 ? y3 : 1.0f; - z *= i > 2 ? y2 : 1.0f; - - r += log(z); - } else if (absx < 0x1.0p+58f) { - float z = 1.0f / absx; - float y = z * z; - float w = mad(z, mad(y, mad(y, mad(y, mad(y, mad(y, w6_f, w5_f), w4_f), w3_f), w2_f), w1_f), w0_f); - r = mad(absx - 0.5f, log(absx) - 1.0f, w); - } else - // 2**58 <= x <= Inf - r = absx * (log(absx) - 1.0f); - - int s = 1; - - if (x < 0.0f) { - float t = sinpi(x); - r = log(pi_f / fabs(t * x)) - r; - r = t == 0.0f ? as_float(PINFBITPATT_SP32) : r; - s = t < 0.0f ? -1 : s; - } - - *signp = s; - return r; -} - -_CLC_V_V_VP_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, float, lgamma_r, float, private, int) - -#endif -#endif - -#if __CLC_FPSIZE == 64 -#ifdef __CLC_SCALAR -// ==================================================== -// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. -// -// Developed at SunPro, a Sun Microsystems, Inc. business. -// Permission to use, copy, modify, and distribute this -// software is freely granted, provided that this notice -// is preserved. -// ==================================================== - -// lgamma_r(x, i) -// Reentrant version of the logarithm of the Gamma function -// with user provide pointer for the sign of Gamma(x). -// -// Method: -// 1. Argument Reduction for 0 < x <= 8 -// Since gamma(1+s)=s*gamma(s), for x in [0,8], we may -// reduce x to a number in [1.5,2.5] by -// lgamma(1+s) = log(s) + lgamma(s) -// for example, -// lgamma(7.3) = log(6.3) + lgamma(6.3) -// = log(6.3*5.3) + lgamma(5.3) -// = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3) -// 2. Polynomial approximation of lgamma around its -// minimun ymin=1.461632144968362245 to maintain monotonicity. -// On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use -// Let z = x-ymin; -// lgamma(x) = -1.214862905358496078218 + z^2*poly(z) -// where -// poly(z) is a 14 degree polynomial. -// 2. Rational approximation in the primary interval [2,3] -// We use the following approximation: -// s = x-2.0; -// lgamma(x) = 0.5*s + s*P(s)/Q(s) -// with accuracy -// |P/Q - (lgamma(x)-0.5s)| < 2**-61.71 -// Our algorithms are based on the following observation -// -// zeta(2)-1 2 zeta(3)-1 3 -// lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ... -// 2 3 -// -// where Euler = 0.5771... is the Euler constant, which is very -// close to 0.5. -// -// 3. For x>=8, we have -// lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+.... -// (better formula: -// lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...) -// Let z = 1/x, then we approximation -// f(z) = lgamma(x) - (x-0.5)(log(x)-1) -// by -// 3 5 11 -// w = w0 + w1*z + w2*z + w3*z + ... + w6*z -// where -// |w - f(z)| < 2**-58.74 -// -// 4. For negative x, since (G is gamma function) -// -x*G(-x)*G(x) = pi/sin(pi*x), -// we have -// G(x) = pi/(sin(pi*x)*(-x)*G(-x)) -// since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0 -// Hence, for x<0, signgam = sign(sin(pi*x)) and -// lgamma(x) = log(|Gamma(x)|) -// = log(pi/(|x*sin(pi*x)|)) - lgamma(-x); -// Note: one should avoid compute pi*(-x) directly in the -// computation of sin(pi*(-x)). -// -// 5. Special Cases -// lgamma(2+s) ~ s*(1-Euler) for tiny s -// lgamma(1)=lgamma(2)=0 -// lgamma(x) ~ -log(x) for tiny x -// lgamma(0) = lgamma(inf) = inf -// lgamma(-integer) = +-inf -// -#define pi 3.14159265358979311600e+00 /* 0x400921FB, 0x54442D18 */ - -#define a0 7.72156649015328655494e-02 /* 0x3FB3C467, 0xE37DB0C8 */ -#define a1 3.22467033424113591611e-01 /* 0x3FD4A34C, 0xC4A60FAD */ -#define a2 6.73523010531292681824e-02 /* 0x3FB13E00, 0x1A5562A7 */ -#define a3 2.05808084325167332806e-02 /* 0x3F951322, 0xAC92547B */ -#define a4 7.38555086081402883957e-03 /* 0x3F7E404F, 0xB68FEFE8 */ -#define a5 2.89051383673415629091e-03 /* 0x3F67ADD8, 0xCCB7926B */ -#define a6 1.19270763183362067845e-03 /* 0x3F538A94, 0x116F3F5D */ -#define a7 5.10069792153511336608e-04 /* 0x3F40B6C6, 0x89B99C00 */ -#define a8 2.20862790713908385557e-04 /* 0x3F2CF2EC, 0xED10E54D */ -#define a9 1.08011567247583939954e-04 /* 0x3F1C5088, 0x987DFB07 */ -#define a10 2.52144565451257326939e-05 /* 0x3EFA7074, 0x428CFA52 */ -#define a11 4.48640949618915160150e-05 /* 0x3F07858E, 0x90A45837 */ - -#define tc 1.46163214496836224576e+00 /* 0x3FF762D8, 0x6356BE3F */ -#define tf -1.21486290535849611461e-01 /* 0xBFBF19B9, 0xBCC38A42 */ -#define tt -3.63867699703950536541e-18 /* 0xBC50C7CA, 0xA48A971F */ - -#define t0 4.83836122723810047042e-01 /* 0x3FDEF72B, 0xC8EE38A2 */ -#define t1 -1.47587722994593911752e-01 /* 0xBFC2E427, 0x8DC6C509 */ -#define t2 6.46249402391333854778e-02 /* 0x3FB08B42, 0x94D5419B */ -#define t3 -3.27885410759859649565e-02 /* 0xBFA0C9A8, 0xDF35B713 */ -#define t4 1.79706750811820387126e-02 /* 0x3F9266E7, 0x970AF9EC */ -#define t5 -1.03142241298341437450e-02 /* 0xBF851F9F, 0xBA91EC6A */ -#define t6 6.10053870246291332635e-03 /* 0x3F78FCE0, 0xE370E344 */ -#define t7 -3.68452016781138256760e-03 /* 0xBF6E2EFF, 0xB3E914D7 */ -#define t8 2.25964780900612472250e-03 /* 0x3F6282D3, 0x2E15C915 */ -#define t9 -1.40346469989232843813e-03 /* 0xBF56FE8E, 0xBF2D1AF1 */ -#define t10 8.81081882437654011382e-04 /* 0x3F4CDF0C, 0xEF61A8E9 */ -#define t11 -5.38595305356740546715e-04 /* 0xBF41A610, 0x9C73E0EC */ -#define t12 3.15632070903625950361e-04 /* 0x3F34AF6D, 0x6C0EBBF7 */ -#define t13 -3.12754168375120860518e-04 /* 0xBF347F24, 0xECC38C38 */ -#define t14 3.35529192635519073543e-04 /* 0x3F35FD3E, 0xE8C2D3F4 */ - -#define u0 -7.72156649015328655494e-02 /* 0xBFB3C467, 0xE37DB0C8 */ -#define u1 6.32827064025093366517e-01 /* 0x3FE4401E, 0x8B005DFF */ -#define u2 1.45492250137234768737e+00 /* 0x3FF7475C, 0xD119BD6F */ -#define u3 9.77717527963372745603e-01 /* 0x3FEF4976, 0x44EA8450 */ -#define u4 2.28963728064692451092e-01 /* 0x3FCD4EAE, 0xF6010924 */ -#define u5 1.33810918536787660377e-02 /* 0x3F8B678B, 0xBF2BAB09 */ - -#define v1 2.45597793713041134822e+00 /* 0x4003A5D7, 0xC2BD619C */ -#define v2 2.12848976379893395361e+00 /* 0x40010725, 0xA42B18F5 */ -#define v3 7.69285150456672783825e-01 /* 0x3FE89DFB, 0xE45050AF */ -#define v4 1.04222645593369134254e-01 /* 0x3FBAAE55, 0xD6537C88 */ -#define v5 3.21709242282423911810e-03 /* 0x3F6A5ABB, 0x57D0CF61 */ - -#define s0 -7.72156649015328655494e-02 /* 0xBFB3C467, 0xE37DB0C8 */ -#define s1 2.14982415960608852501e-01 /* 0x3FCB848B, 0x36E20878 */ -#define s2 3.25778796408930981787e-01 /* 0x3FD4D98F, 0x4F139F59 */ -#define s3 1.46350472652464452805e-01 /* 0x3FC2BB9C, 0xBEE5F2F7 */ -#define s4 2.66422703033638609560e-02 /* 0x3F9B481C, 0x7E939961 */ -#define s5 1.84028451407337715652e-03 /* 0x3F5E26B6, 0x7368F239 */ -#define s6 3.19475326584100867617e-05 /* 0x3F00BFEC, 0xDD17E945 */ - -#define r1 1.39200533467621045958e+00 /* 0x3FF645A7, 0x62C4AB74 */ -#define r2 7.21935547567138069525e-01 /* 0x3FE71A18, 0x93D3DCDC */ -#define r3 1.71933865632803078993e-01 /* 0x3FC601ED, 0xCCFBDF27 */ -#define r4 1.86459191715652901344e-02 /* 0x3F9317EA, 0x742ED475 */ -#define r5 7.77942496381893596434e-04 /* 0x3F497DDA, 0xCA41A95B */ -#define r6 7.32668430744625636189e-06 /* 0x3EDEBAF7, 0xA5B38140 */ - -#define w0 4.18938533204672725052e-01 /* 0x3FDACFE3, 0x90C97D69 */ -#define w1 8.33333333333329678849e-02 /* 0x3FB55555, 0x5555553B */ -#define w2 -2.77777777728775536470e-03 /* 0xBF66C16C, 0x16B02E5C */ -#define w3 7.93650558643019558500e-04 /* 0x3F4A019F, 0x98CF38B6 */ -#define w4 -5.95187557450339963135e-04 /* 0xBF4380CB, 0x8C0FE741 */ -#define w5 8.36339918996282139126e-04 /* 0x3F4B67BA, 0x4CDAD5D1 */ -#define w6 -1.63092934096575273989e-03 /* 0xBF5AB89D, 0x0B9E43E4 */ - -_CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE lgamma_r(__CLC_GENTYPE x, private __CLC_INTN *ip) { - ulong ux = as_ulong(x); - ulong ax = ux & EXSIGNBIT_DP64; - double absx = as_double(ax); - - if (ax >= 0x7ff0000000000000UL) { - // +-Inf, NaN - *ip = 1; - return absx; - } - - if (absx < 0x1.0p-70) { - *ip = ax == ux ? 1 : -1; - return -log(absx); - } - - // Handle rest of range - double r; - - if (absx < 2.0) { - int i = 0; - double y = 2.0 - absx; - - int c = absx < 0x1.bb4c3p+0; - double t = absx - tc; - i = c ? 1 : i; - y = c ? t : y; - - c = absx < 0x1.3b4c4p+0; - t = absx - 1.0; - i = c ? 2 : i; - y = c ? t : y; - - c = absx <= 0x1.cccccp-1; - t = -log(absx); - r = c ? t : 0.0; - t = 1.0 - absx; - i = c ? 0 : i; - y = c ? t : y; - - c = absx < 0x1.76944p-1; - t = absx - (tc - 1.0); - i = c ? 1 : i; - y = c ? t : y; - - c = absx < 0x1.da661p-3; - i = c ? 2 : i; - y = c ? absx : y; - - double p, q; - - switch (i) { - case 0: - p = fma(y, fma(y, fma(y, fma(y, a11, a10), a9), a8), a7); - p = fma(y, fma(y, fma(y, fma(y, p, a6), a5), a4), a3); - p = fma(y, fma(y, fma(y, p, a2), a1), a0); - r = fma(y, p - 0.5, r); - break; - case 1: - p = fma(y, fma(y, fma(y, fma(y, t14, t13), t12), t11), t10); - p = fma(y, fma(y, fma(y, fma(y, fma(y, p, t9), t8), t7), t6), t5); - p = fma(y, fma(y, fma(y, fma(y, fma(y, p, t4), t3), t2), t1), t0); - p = fma(y*y, p, -tt); - r += (tf + p); - break; - case 2: - p = y * fma(y, fma(y, fma(y, fma(y, fma(y, u5, u4), u3), u2), u1), u0); - q = fma(y, fma(y, fma(y, fma(y, fma(y, v5, v4), v3), v2), v1), 1.0); - r += fma(-0.5, y, p / q); - } - } else if (absx < 8.0) { - int i = absx; - double y = absx - (double) i; - double p = y * fma(y, fma(y, fma(y, fma(y, fma(y, fma(y, s6, s5), s4), s3), s2), s1), s0); - double q = fma(y, fma(y, fma(y, fma(y, fma(y, fma(y, r6, r5), r4), r3), r2), r1), 1.0); - r = fma(0.5, y, p / q); - double z = 1.0; - // lgamma(1+s) = log(s) + lgamma(s) - double y6 = y + 6.0; - double y5 = y + 5.0; - double y4 = y + 4.0; - double y3 = y + 3.0; - double y2 = y + 2.0; - z *= i > 6 ? y6 : 1.0; - z *= i > 5 ? y5 : 1.0; - z *= i > 4 ? y4 : 1.0; - z *= i > 3 ? y3 : 1.0; - z *= i > 2 ? y2 : 1.0; - r += log(z); - } else { - double z = 1.0 / absx; - double z2 = z * z; - double w = fma(z, fma(z2, fma(z2, fma(z2, fma(z2, fma(z2, w6, w5), w4), w3), w2), w1), w0); - r = (absx - 0.5) * (log(absx) - 1.0) + w; - } - - if (x < 0.0) { - double t = sinpi(x); - r = log(pi / fabs(t * x)) - r; - r = t == 0.0 ? as_double(PINFBITPATT_DP64) : r; - *ip = t < 0.0 ? -1 : 1; - } else - *ip = 1; - - return r; -} - -_CLC_V_V_VP_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, double, lgamma_r, double, private, int) -#endif -#endif - -#define __CLC_LGAMMA_R_DEF(addrspace) \ - _CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE lgamma_r(__CLC_GENTYPE x, addrspace __CLC_INTN *iptr) { \ - __CLC_INTN private_iptr; \ - __CLC_GENTYPE ret = lgamma_r(x, &private_iptr); \ - *iptr = private_iptr; \ - return ret; \ -} -__CLC_LGAMMA_R_DEF(local); -__CLC_LGAMMA_R_DEF(global); - -#undef __CLC_LGAMMA_R_DEF