[Libclc-dev] [PATCH 2/2] lgamma: Move code from .inc to .cl file
Jan Vesely via Libclc-dev
libclc-dev at lists.llvm.org
Fri Sep 22 18:25:07 PDT 2017
Signed-off-by: Jan Vesely <jan.vesely at rutgers.edu>
---
generic/lib/math/lgamma_r.cl | 487 ++++++++++++++++++++++++++++++++++++++++++
generic/lib/math/lgamma_r.inc | 480 +----------------------------------------
2 files changed, 492 insertions(+), 475 deletions(-)
diff --git a/generic/lib/math/lgamma_r.cl b/generic/lib/math/lgamma_r.cl
index a15ff17..ff44738 100644
--- a/generic/lib/math/lgamma_r.cl
+++ b/generic/lib/math/lgamma_r.cl
@@ -1,11 +1,498 @@
+/*
+ * Copyright (c) 2014 Advanced Micro Devices, Inc.
+ * Copyright (c) 2016 Aaron Watry <awatry at gmail.com>
+ *
+ * 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 <clc/clc.h>
#include "../clcmacro.h"
#include "math.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 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 float 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)
+
#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.
+// ====================================================
+
+// 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 double lgamma_r(double x, private int *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
+
+#define __CLC_ADDRSPACE global
+#define __CLC_BODY <lgamma_r.inc>
+#include <clc/math/gentype.inc>
+#undef __CLC_ADDRSPACE
+
+#define __CLC_ADDRSPACE local
#define __CLC_BODY <lgamma_r.inc>
#include <clc/math/gentype.inc>
+#undef __CLC_ADDRSPACE
diff --git a/generic/lib/math/lgamma_r.inc b/generic/lib/math/lgamma_r.inc
index b4f73f6..316d4fa 100644
--- a/generic/lib/math/lgamma_r.inc
+++ b/generic/lib/math/lgamma_r.inc
@@ -21,480 +21,10 @@
* 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_OVERLOAD _CLC_DEF __CLC_GENTYPE lgamma_r(__CLC_GENTYPE x, __CLC_ADDRSPACE __CLC_INTN *iptr) {
+ __CLC_INTN private_iptr;
+ __CLC_GENTYPE ret = lgamma_r(x, &private_iptr);
+ *iptr = private_iptr;
+ return ret;
}
-
-_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
--
2.13.5
More information about the Libclc-dev
mailing list