Skip to content

Commit 782b4f4

Browse files
authored
correct licensing and incorporation of FastMath (#49122)
this resolves incorrectly licensed code in #49009. ESSloppyMath is made as a wrapper around FastMath.java which is not meant to be modified with code beyond the original source
1 parent 4db330d commit 782b4f4

File tree

3 files changed

+213
-173
lines changed

3 files changed

+213
-173
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,23 @@
11
/*
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
89
*
9-
* http://www.apache.org/licenses/LICENSE-2.0
10+
* http://www.apache.org/licenses/LICENSE-2.0
1011
*
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.
3418
*/
3519

20+
package org.elasticsearch.common.util;
3621

3722
/**
3823
* Similar to Lucene's SloppyMath, but for additional math functions.
@@ -41,140 +26,11 @@ public class ESSloppyMath {
4126

4227
private ESSloppyMath() {}
4328

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-
*/
11329
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);
13631
}
13732

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-
*/
14433
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);
17935
}
18036
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/*
2+
* Copyright 2012 Jeff Hain
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/*
18+
* =============================================================================
19+
* Notice of fdlibm package this program is partially derived from:
20+
*
21+
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
22+
*
23+
* Developed at SunSoft, a Sun Microsystems, Inc. business.
24+
* Permission to use, copy, modify, and distribute this
25+
* software is freely granted, provided that this notice
26+
* is preserved.
27+
* =============================================================================
28+
*/
29+
30+
/*
31+
* This code sourced from:
32+
* https://github.com/yannrichet/jmathplot/blob/f25426e0ab0e68647ad2b75f577c7be050ecac86/src/main/java/org/math/plot/utils/FastMath.java
33+
*/
34+
35+
package org.elasticsearch.common.util;
36+
37+
/**
38+
* Additions or modifications to this class should only come from the original org.math.plot.utils.FastMath source
39+
*/
40+
final class FastMath {
41+
42+
private FastMath() { }
43+
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+
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+
}
136+
}
137+
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+
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+
}
179+
}
180+
181+
}

0 commit comments

Comments
 (0)