2 * Copyright
(c) 2014,2015 Advanced Micro Devices
, Inc.
4 * Permission is hereby granted
, free of charge
, to any person obtaining a copy
5 * of this software and associated documentation files
(the "Software"), to deal
6 * in the Software without restriction
, including without limitation the rights
7 * to use
, copy
, modify
, merge
, publish
, distribute
, sublicense
, and
/or sell
8 * copies of the Software
, and to permit persons to whom the Software is
9 * furnished to do so
, subject to the following conditions
:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED
"AS IS", WITHOUT WARRANTY OF ANY KIND
, EXPRESS OR
15 * IMPLIED
, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM
, DAMAGES OR OTHER
18 * LIABILITY
, WHETHER IN AN ACTION OF CONTRACT
, TORT OR OTHERWISE
, ARISING FROM
,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 #include
"../clcmacro.h"
29 _CLC_OVERLOAD _CLC_DEF float cosh
(float x
) {
31 // After dealing with special cases the computation is split into regions as follows.
32 // abs
(x) >= max_cosh_arg
:
33 // cosh
(x) = sign
(x)*Inf
34 // abs
(x) >= small_threshold
:
35 // cosh
(x) = sign
(x)*exp
(abs(x))/2 computed using the
36 // splitexp and scaleDouble functions as for exp_amd
().
37 // abs
(x) < small_threshold
:
38 // compute p
= exp
(y) -
1 and then z
= 0.5*(p+(p/(p+1.0)))
41 const float max_cosh_arg
= 0x1.65a9fap
+6f
;
42 const float small_threshold
= 0x1.0a2b24p
+3f
;
45 uint aux
= ux
& EXSIGNBIT_SP32
;
46 float y
= as_float
(aux);
48 // Find the integer part y0 of y and the increment dy
= y - y0. We then compute
49 // z
= sinh
(y) = sinh
(y0)cosh
(dy) + cosh
(y0)sinh
(dy)
50 // z
= cosh
(y) = cosh
(y0)cosh
(dy) + sinh
(y0)sinh
(dy)
51 // where sinh
(y0) and cosh
(y0) are tabulated above.
54 ind
= (uint)ind
> 36U ?
0 : ind
;
64 mad
(dy2, 0.7746188980094184251527126e-12f
, 0.160576793121939886190847e-9f
),
65 0.250521176994133472333666e-7f
),
66 0.275573191913636406057211e-5f
),
67 0.198412698413242405162014e-3f
),
68 0.833333333333329931873097e-2f
),
69 0.166666666666666667013899e0f
);
70 sdy
= mad
(sdy, dy
*dy2
, dy
);
77 mad
(dy2, 0.1163921388172173692062032e-10f
, 0.208744349831471353536305e-8f
),
78 0.275573350756016588011357e-6f
),
79 0.248015872460622433115785e-4f
),
80 0.138888888889814854814536e-2f
),
81 0.416666666666660876512776e-1f
),
82 0.500000000000000005911074e0f
);
83 cdy
= mad
(cdy, dy2
, 1.0f
);
85 float2 tv
= USE_TABLE
(sinhcosh_tbl, ind
);
86 float z
= mad
(tv.s0
, sdy
, tv.s1
* cdy
);
88 // When exp
(-x) is insignificant compared to exp
(x), return exp
(x)/2
89 float t
= exp
(y -
0x1.62e500p-1f
);
90 float zsmall
= mad
(0x1.a0210ep-18f
, t
, t
);
91 z
= y
>= small_threshold ? zsmall
: z
;
94 z
= y
>= max_cosh_arg ? as_float
(PINFBITPATT_SP32) : z
;
95 z
= aux
> PINFBITPATT_SP32 ? as_float
(QNANBITPATT_SP32) : z
;
96 z
= aux
< 0x38800000 ?
1.0f
: z
;
101 _CLC_UNARY_VECTORIZE
(_CLC_OVERLOAD _CLC_DEF
, float
, cosh
, float
);
104 #pragma OPENCL EXTENSION cl_khr_fp64
: enable
106 _CLC_OVERLOAD _CLC_DEF double cosh
(double x
) {
108 // After dealing with special cases the computation is split into
109 // regions as follows
:
111 // abs
(x) >= max_cosh_arg
:
112 // cosh
(x) = sign
(x)*Inf
114 // abs
(x) >= small_threshold
:
115 // cosh
(x) = sign
(x)*exp
(abs(x))/2 computed using the
116 // splitexp and scaleDouble functions as for exp_amd
().
118 // abs
(x) < small_threshold
:
119 // compute p
= exp
(y) -
1 and then z
= 0.5*(p+(p/(p+1.0)))
120 // cosh
(x) is then sign
(x)*z.
122 // This is ln
(2^
1025)
123 const double max_cosh_arg
= 7.10475860073943977113e+02; // 0x408633ce8fb9f87e
125 // This is where exp
(-x) is insignificant compared to exp
(x) = ln
(2^
27)
126 const double small_threshold
= 0x1.2b708872320e2p
+4;
130 // In this range we find the integer part y0 of y
131 // and the increment dy
= y - y0. We then compute
132 // z
= cosh
(y) = cosh
(y0)cosh
(dy) + sinh
(y0)sinh
(dy)
133 // where sinh
(y0) and cosh
(y0) are tabulated above.
135 int ind
= min
((int)y
, 36);
137 double dy2
= dy
* dy
;
139 double sdy
= dy
* dy2
*
145 fma
(dy2, 0.7746188980094184251527126e-12, 0.160576793121939886190847e-9),
146 0.250521176994133472333666e-7),
147 0.275573191913636406057211e-5),
148 0.198412698413242405162014e-3),
149 0.833333333333329931873097e-2),
150 0.166666666666666667013899e0
);
152 double cdy
= dy2
* fma
(dy2,
157 fma
(dy2, 0.1163921388172173692062032e-10, 0.208744349831471353536305e-8),
158 0.275573350756016588011357e-6),
159 0.248015872460622433115785e-4),
160 0.138888888889814854814536e-2),
161 0.416666666666660876512776e-1),
162 0.500000000000000005911074e0
);
164 // At this point sinh
(dy) is approximated by dy
+ sdy
,
165 // and cosh
(dy) is approximated by
1 + cdy.
166 double2 tv
= USE_TABLE
(cosh_tbl, ind
);
169 tv
= USE_TABLE
(sinh_tbl, ind
);
173 double z
= fma
(sl, dy
, fma
(sl, sdy
, fma
(cl, cdy
, fma
(st, dy
, fma
(st, sdy
, ct
*cdy
)) + ct
))) + cl
;
176 z
= y
< 0x1.0p-28 ?
1.0 : z
;
178 double t
= exp
(y -
0x1.62e42fefa3800p-1
);
179 t
= fma
(t, -
0x1.ef35793c76641p-45
, t
);
180 z
= y
>= small_threshold ? t
: z
;
182 z
= y
>= max_cosh_arg ? as_double
(PINFBITPATT_DP64) : z
;
184 z
= isinf
(x) | isnan
(x) ? y
: z
;
190 _CLC_UNARY_VECTORIZE
(_CLC_OVERLOAD _CLC_DEF
, double
, cosh
, double
)