1
1
/*
2
- * Licensed to the Apache Software Foundation (ASF) under one or more
3
- * contributor license agreements. See the NOTICE file distributed with
4
- * this work for additional information regarding copyright ownership.
5
- * The ASF licenses this file to You under the Apache License, Version 2.0
6
- * (the "License"); you may not use this file except in compliance with
7
- * the License. You may obtain a copy of the License at
2
+ * Licensed to Elasticsearch under one or more contributor
3
+ * license agreements. See the NOTICE file distributed with
4
+ * this work for additional information regarding copyright
5
+ * ownership. Elasticsearch licenses this file to you under
6
+ * the Apache License, Version 2.0 (the "License"); you may
7
+ * not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
8
9
*
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
+ * http://www.apache.org/licenses/LICENSE-2.0
10
11
*
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
- package org .elasticsearch .common .util ;
18
-
19
- /*
20
- * =============================================================================
21
- *
22
- * sinh and atan ported from
23
- * https://github.com/yannrichet/jmathplot/blob/f25426e0ab0e68647ad2b75f577c7be050ecac86/src/main/java/org/math/plot/utils/FastMath.java
24
- * (Apache 2.0) Copyright 2012 Jeff Hain, which is partially derived from fdlibm package
25
- *
26
- * =============================================================================
27
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
28
- *
29
- * Developed at SunSoft, a Sun Microsystems, Inc. business.
30
- * Permission to use, copy, modify, and distribute this
31
- * software is freely granted, provided that this notice
32
- * is preserved.
33
- * =============================================================================
12
+ * Unless required by applicable law or agreed to in writing,
13
+ * software distributed under the License is distributed on an
14
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ * KIND, either express or implied. See the License for the
16
+ * specific language governing permissions and limitations
17
+ * under the License.
34
18
*/
35
19
20
+ package org .elasticsearch .common .util ;
36
21
37
22
/**
38
23
* Similar to Lucene's SloppyMath, but for additional math functions.
@@ -41,140 +26,11 @@ public class ESSloppyMath {
41
26
42
27
private ESSloppyMath () {}
43
28
44
- //--------------------------------------------------------------------------
45
- // RE-USABLE CONSTANTS
46
- //--------------------------------------------------------------------------
47
-
48
- private static final double ONE_DIV_F2 = 1 /2.0 ;
49
- private static final double ONE_DIV_F3 = 1 /6.0 ;
50
- private static final double ONE_DIV_F4 = 1 /24.0 ;
51
- private static final double TWO_POW_N28 = Double .longBitsToDouble (0x3E30000000000000L );
52
- private static final double TWO_POW_66 = Double .longBitsToDouble (0x4410000000000000L );
53
- private static final double LOG_DOUBLE_MAX_VALUE = StrictMath .log (Double .MAX_VALUE );
54
-
55
- //--------------------------------------------------------------------------
56
- // CONSTANTS AND TABLES FOR ATAN
57
- //--------------------------------------------------------------------------
58
-
59
- // We use the formula atan(-x) = -atan(x)
60
- // ---> we only have to compute atan(x) on [0,+infinity[.
61
- // For values corresponding to angles not close to +-PI/2, we use look-up tables;
62
- // for values corresponding to angles near +-PI/2, we use code derived from fdlibm.
63
-
64
- // Supposed to be >= tan(67.7deg), as fdlibm code is supposed to work with values > 2.4375.
65
- private static final double ATAN_MAX_VALUE_FOR_TABS = StrictMath .tan (Math .toRadians (74.0 ));
66
-
67
- private static final int ATAN_TABS_SIZE = 1 <<12 + 1 ;
68
- private static final double ATAN_DELTA = ATAN_MAX_VALUE_FOR_TABS /(ATAN_TABS_SIZE - 1 );
69
- private static final double ATAN_INDEXER = 1 /ATAN_DELTA ;
70
- private static final double [] atanTab = new double [ATAN_TABS_SIZE ];
71
- private static final double [] atanDer1DivF1Tab = new double [ATAN_TABS_SIZE ];
72
- private static final double [] atanDer2DivF2Tab = new double [ATAN_TABS_SIZE ];
73
- private static final double [] atanDer3DivF3Tab = new double [ATAN_TABS_SIZE ];
74
- private static final double [] atanDer4DivF4Tab = new double [ATAN_TABS_SIZE ];
75
-
76
- private static final double ATAN_HI3 = Double .longBitsToDouble (0x3ff921fb54442d18L ); // 1.57079632679489655800e+00 atan(inf)hi
77
- private static final double ATAN_LO3 = Double .longBitsToDouble (0x3c91a62633145c07L ); // 6.12323399573676603587e-17 atan(inf)lo
78
- private static final double ATAN_AT0 = Double .longBitsToDouble (0x3fd555555555550dL ); // 3.33333333333329318027e-01
79
- private static final double ATAN_AT1 = Double .longBitsToDouble (0xbfc999999998ebc4L ); // -1.99999999998764832476e-01
80
- private static final double ATAN_AT2 = Double .longBitsToDouble (0x3fc24924920083ffL ); // 1.42857142725034663711e-01
81
- private static final double ATAN_AT3 = Double .longBitsToDouble (0xbfbc71c6fe231671L ); // -1.11111104054623557880e-01
82
- private static final double ATAN_AT4 = Double .longBitsToDouble (0x3fb745cdc54c206eL ); // 9.09088713343650656196e-02
83
- private static final double ATAN_AT5 = Double .longBitsToDouble (0xbfb3b0f2af749a6dL ); // -7.69187620504482999495e-02
84
- private static final double ATAN_AT6 = Double .longBitsToDouble (0x3fb10d66a0d03d51L ); // 6.66107313738753120669e-02
85
- private static final double ATAN_AT7 = Double .longBitsToDouble (0xbfadde2d52defd9aL ); // -5.83357013379057348645e-02
86
- private static final double ATAN_AT8 = Double .longBitsToDouble (0x3fa97b4b24760debL ); // 4.97687799461593236017e-02
87
- private static final double ATAN_AT9 = Double .longBitsToDouble (0xbfa2b4442c6a6c2fL ); // -3.65315727442169155270e-02
88
- private static final double ATAN_AT10 = Double .longBitsToDouble (0x3f90ad3ae322da11L ); // 1.62858201153657823623e-02
89
-
90
- static {
91
- // atan
92
- for (int i =0 ;i <ATAN_TABS_SIZE ;i ++) {
93
- // x: in [0,ATAN_MAX_VALUE_FOR_TABS].
94
- double x = i * ATAN_DELTA ;
95
- double onePlusXSqInv = 1.0 /(1 +x *x );
96
- double onePlusXSqInv2 = onePlusXSqInv *onePlusXSqInv ;
97
- double onePlusXSqInv3 = onePlusXSqInv2 *onePlusXSqInv ;
98
- double onePlusXSqInv4 = onePlusXSqInv2 *onePlusXSqInv2 ;
99
- atanTab [i ] = StrictMath .atan (x );
100
- atanDer1DivF1Tab [i ] = onePlusXSqInv ;
101
- atanDer2DivF2Tab [i ] = (-2 *x *onePlusXSqInv2 ) * ONE_DIV_F2 ;
102
- atanDer3DivF3Tab [i ] = ((-2 +6 *x *x )*onePlusXSqInv3 ) * ONE_DIV_F3 ;
103
- atanDer4DivF4Tab [i ] = ((24 *x *(1 -x *x ))*onePlusXSqInv4 ) * ONE_DIV_F4 ;
104
- }
105
- }
106
-
107
- /**
108
- * A faster and less accurate {@link Math#sinh}
109
- *
110
- * @param value A double value.
111
- * @return Value hyperbolic sine.
112
- */
113
29
public static double sinh (double value ) {
114
- // sinh(x) = (exp(x)-exp(-x))/2
115
- double h ;
116
- if (value < 0.0 ) {
117
- value = -value ;
118
- h = -0.5 ;
119
- } else {
120
- h = 0.5 ;
121
- }
122
- if (value < 22.0 ) {
123
- if (value < TWO_POW_N28 ) {
124
- return (h < 0.0 ) ? -value : value ;
125
- } else {
126
- double t = Math .expm1 (value );
127
- // Might be more accurate, if value < 1: return h*((t+t)-t*t/(t+1.0)).
128
- return h * (t + t /(t +1.0 ));
129
- }
130
- } else if (value < LOG_DOUBLE_MAX_VALUE ) {
131
- return h * Math .exp (value );
132
- } else {
133
- double t = Math .exp (value *0.5 );
134
- return (h *t )*t ;
135
- }
30
+ return FastMath .sinh (value );
136
31
}
137
32
138
- /**
139
- * A faster and less accurate {@link Math#atan}
140
- *
141
- * @param value A double value.
142
- * @return Value arctangent, in radians, in [-PI/2,PI/2].
143
- */
144
33
public static double atan (double value ) {
145
- boolean negateResult ;
146
- if (value < 0.0 ) {
147
- value = -value ;
148
- negateResult = true ;
149
- } else {
150
- negateResult = false ;
151
- }
152
- if (value == 1.0 ) {
153
- // We want "exact" result for 1.0.
154
- return negateResult ? -Math .PI /4 : Math .PI /4 ;
155
- } else if (value <= ATAN_MAX_VALUE_FOR_TABS ) {
156
- int index = (int )(value * ATAN_INDEXER + 0.5 );
157
- double delta = value - index * ATAN_DELTA ;
158
- double result = atanTab [index ] + delta * (atanDer1DivF1Tab [index ] + delta * (atanDer2DivF2Tab [index ]
159
- + delta * (atanDer3DivF3Tab [index ] + delta * atanDer4DivF4Tab [index ])));
160
- return negateResult ? -result : result ;
161
- } else { // value > ATAN_MAX_VALUE_FOR_TABS, or value is NaN
162
- // This part is derived from fdlibm.
163
- if (value < TWO_POW_66 ) {
164
- double x = -1 /value ;
165
- double x2 = x *x ;
166
- double x4 = x2 *x2 ;
167
- double s1 = x2 *(ATAN_AT0 +x4 *(ATAN_AT2 +x4 *(ATAN_AT4 +x4 *(ATAN_AT6 +x4 *(ATAN_AT8 +x4 *ATAN_AT10 )))));
168
- double s2 = x4 *(ATAN_AT1 +x4 *(ATAN_AT3 +x4 *(ATAN_AT5 +x4 *(ATAN_AT7 +x4 *ATAN_AT9 ))));
169
- double result = ATAN_HI3 -((x *(s1 +s2 )-ATAN_LO3 )-x );
170
- return negateResult ? -result : result ;
171
- } else { // value >= 2^66, or value is NaN
172
- if (Double .isNaN (value )) {
173
- return Double .NaN ;
174
- } else {
175
- return negateResult ? -Math .PI /2 : Math .PI /2 ;
176
- }
177
- }
178
- }
34
+ return FastMath .atan (value );
179
35
}
180
36
}
0 commit comments