1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.hipparchus.analysis.function;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.analysis.UnivariateFunction;
21 import org.hipparchus.analysis.differentiation.DSFactory;
22 import org.hipparchus.analysis.differentiation.DerivativeStructure;
23 import org.hipparchus.analysis.differentiation.Gradient;
24 import org.hipparchus.analysis.differentiation.UnivariateDifferentiableFunction;
25 import org.hipparchus.util.FastMath;
26 import org.junit.jupiter.api.Test;
27
28 import java.lang.reflect.InvocationTargetException;
29 import java.lang.reflect.Method;
30
31 import static org.junit.jupiter.api.Assertions.assertEquals;
32 import static org.junit.jupiter.api.Assertions.assertTrue;
33 import static org.junit.jupiter.api.Assertions.fail;
34
35 class FunctionsWithFastMathVersionTest {
36
37 @Test
38 void testAcos() {
39 doTestF0(new Acos(), -1.25, -0.25, 0.0, 0.25, 1.25);
40 doTestFn(new Acos(), -1.25, -0.25, 0.0, 0.25, 1.25);
41 doTestF1(new Acos(), -1.25, -0.25, 0.0, 0.25, 1.25);
42 }
43
44 @Test
45 void testAcosH() {
46 doTestF0(new Acosh(), -10.0, -5.0, -0.5, 0.5, 5.0, 10.0);
47 doTestFn(new Acosh(), -10.0, -5.0, -0.5, 0.5, 5.0, 10.0);
48 doTestF1(new Acosh(), -10.0, -5.0, -0.5, 0.5, 5.0, 10.0);
49 }
50
51 @Test
52 void testAsin() {
53 doTestF0(new Asin(), -1.25, -0.25, 0.0, 0.25, 1.25);
54 doTestFn(new Asin(), -1.25, -0.25, 0.0, 0.25, 1.25);
55 doTestF1(new Asin(), -1.25, -0.25, 0.0, 0.25, 1.25);
56 }
57
58 @Test
59 void testAsinh() {
60 doTestF0(new Asinh(), -10.0, -1.25, 0.0, 1.25, 10.0);
61 doTestFn(new Asinh(), -10.0, -1.25, 0.0, 1.25, 10.0);
62 doTestF1(new Asinh(), -10.0, -1.25, 0.0, 1.25, 10.0);
63 }
64
65 @Test
66 void testAtan() {
67 doTestF0(new Atan(), -10.0, -1.25, 0.0, 1.25, 10.0);
68 doTestFn(new Atan(), -10.0, -1.25, 0.0, 1.25, 10.0);
69 doTestF1(new Atan(), -10.0, -1.25, 0.0, 1.25, 10.0);
70 }
71
72 @Test
73 void testAtanh() {
74 doTestF0(new Atanh(), -10.0, -1.25, 0.0, 1.25, 10.0);
75 doTestFn(new Atanh(), -10.0, -1.25, 0.0, 1.25, 10.0);
76 doTestF1(new Atanh(), -10.0, -1.25, 0.0, 1.25, 10.0);
77 }
78
79 @Test
80 void testCbrt() {
81 doTestF0(new Cbrt(), -10.0, -1.25, 0.0, 1.25, 10.0);
82 doTestFn(new Cbrt(), -10.0, -1.25, 0.0, 1.25, 10.0);
83 doTestF1(new Cbrt(), -10.0, -1.25, 0.0, 1.25, 10.0);
84 }
85
86 @Test
87 void testCeil() {
88 doTestF0(new Ceil(), -10.0, -1.25, 0.0, 1.25, 10.0);
89 doTestFn(new Ceil(), -10.0, -1.25, 0.0, 1.25, 10.0);
90 doTestF1(new Ceil(), -10.0, -1.25, 0.0, 1.25, 10.0);
91 }
92
93 @Test
94 void testCos() {
95 doTestF0(new Cos(), -10.0, -1.25, 0.0, 1.25, 10.0);
96 doTestFn(new Cos(), -10.0, -1.25, 0.0, 1.25, 10.0);
97 doTestF1(new Cos(), -10.0, -1.25, 0.0, 1.25, 10.0);
98 }
99
100 @Test
101 void testCosh() {
102 doTestF0(new Cosh(), -10.0, -1.25, -0.5, 0.0, 0.5, 1.25, 10.0);
103 doTestFn(new Cosh(), -10.0, -1.25, -0.5, 0.0, 0.5, 1.25, 10.0);
104 doTestF1(new Cosh(), -10.0, -1.25, -0.5, 0.0, 0.5, 1.25, 10.0);
105 }
106
107 @Test
108 void testExp() {
109 doTestF0(new Exp(), -10.0, -1.25, 0.0, 1.25, 10.0);
110 doTestFn(new Exp(), -10.0, -1.25, 0.0, 1.25, 10.0);
111 doTestF1(new Exp(), -10.0, -1.25, 0.0, 1.25, 10.0);
112 }
113
114 @Test
115 void testExpm1() {
116 doTestF0(new Expm1(), -10.0, -1.25, 0.0, 1.25, 10.0);
117 doTestFn(new Expm1(), -10.0, -1.25, 0.0, 1.25, 10.0);
118 doTestF1(new Expm1(), -10.0, -1.25, 0.0, 1.25, 10.0);
119 }
120
121 @Test
122 void testFloor() {
123 doTestF0(new Floor(), -10.0, -1.25, 0.0, 1.25, 10.0);
124 doTestFn(new Floor(), -10.0, -1.25, 0.0, 1.25, 10.0);
125 doTestF1(new Floor(), -10.0, -1.25, 0.0, 1.25, 10.0);
126 }
127
128 @Test
129 void testLog() {
130 doTestF0(new Log(), -10.0, -1.25, 0.0, 1.25, 10.0);
131 doTestFn(new Log(), -10.0, -1.25, 0.0, 1.25, 10.0);
132 doTestF1(new Log(), -10.0, -1.25, 0.0, 1.25, 10.0);
133 }
134
135 @Test
136 void testLog10() {
137 doTestF0(new Log10(), -10.0, -1.25, 0.0, 1.25, 10.0);
138 doTestFn(new Log10(), -10.0, -1.25, 0.0, 1.25, 10.0);
139 doTestF1(new Log10(), -10.0, -1.25, 0.0, 1.25, 10.0);
140 }
141
142 @Test
143 void testLog1p() {
144 doTestF0(new Log1p(), -10.0, -1.25, 0.0, 1.25, 10.0);
145 doTestFn(new Log1p(), -10.0, -1.25, 0.0, 1.25, 10.0);
146 doTestF1(new Log1p(), -10.0, -1.25, 0.0, 1.25, 10.0);
147 }
148
149 @Test
150 void testRint() {
151 doTestF0(new Rint(), -10.0, -1.25, 0.0, 1.25, 10.0);
152 doTestFn(new Rint(), -10.0, -1.25, 0.0, 1.25, 10.0);
153 doTestF1(new Rint(), -10.0, -1.25, 0.0, 1.25, 10.0);
154 }
155
156 @Test
157 void testSin() {
158 doTestF0(new Sin(), -10.0, -1.25, 0.0, 1.25, 10.0);
159 doTestFn(new Sin(), -10.0, -1.25, 0.0, 1.25, 10.0);
160 doTestF1(new Sin(), -10.0, -1.25, 0.0, 1.25, 10.0);
161 }
162
163 @Test
164 void testSinh() {
165 doTestF0(new Sinh(), -10.0, -1.25, 0.0, 1.25, 10.0);
166 doTestFn(new Sinh(), -10.0, -1.25, 0.0, 1.25, 10.0);
167 doTestF1(new Sinh(), -10.0, -1.25, 0.0, 1.25, 10.0);
168 }
169
170 @Test
171 void testSqrt() {
172 doTestF0(new Sqrt(), -10.0, -1.25, 0.0, 1.25, 10.0);
173 doTestFn(new Sqrt(), -10.0, -1.25, 0.0, 1.25, 10.0);
174 doTestF1(new Sqrt(), -10.0, -1.25, 0.0, 1.25, 10.0);
175 }
176
177 @Test
178 void testTan() {
179 doTestF0(new Tan(), -10.0, -1.25, 0.0, 1.25, 10.0);
180 doTestFn(new Tan(), -10.0, -1.25, 0.0, 1.25, 10.0);
181 doTestF1(new Tan(), -10.0, -1.25, 0.0, 1.25, 10.0);
182 }
183
184 @Test
185 void testTanh() {
186 doTestF0(new Tanh(), -10.0, -1.25, 0.0, 1.25, 10.0);
187 doTestFn(new Tanh(), -10.0, -1.25, 0.0, 1.25, 10.0);
188 doTestF1(new Tanh(), -10.0, -1.25, 0.0, 1.25, 10.0);
189 }
190
191 @Test
192 void testUlp() {
193 doTestF0(new Ulp(), -10.0, -1.25, 0.0, 1.25, 10.0);
194 }
195
196 @Test
197 void testAtan2() {
198 final double[] d = { Double.NEGATIVE_INFINITY, -13.4, -0.4, 0.0, 0.4, 13.4, Double.POSITIVE_INFINITY, Double.NaN};
199 for (double x : d) {
200 for (double y : d) {
201 double aRef = FastMath.atan2(y, x);
202 double a = new Atan2().value(y, x);
203 if (Double.isNaN(aRef)) {
204 assertTrue(Double.isNaN(a));
205 } else if (Double.isInfinite(aRef)) {
206 assertTrue(Double.isInfinite(a));
207 assertTrue(a * aRef > 0.0);
208 } else {
209 assertEquals(aRef, a, FastMath.ulp(aRef));
210 }
211 }
212 }
213 }
214
215 private void doTestF0(final UnivariateFunction f, double... x) {
216 try {
217 final Method fastMathVersion = FastMath.class.getMethod(f.getClass().getSimpleName().toLowerCase(), Double.TYPE);
218 for (double xi : x) {
219 checkF0Equality(f, fastMathVersion, xi);
220 }
221 checkF0Equality(f, fastMathVersion, Double.NEGATIVE_INFINITY);
222 checkF0Equality(f, fastMathVersion, Double.POSITIVE_INFINITY);
223 checkF0Equality(f, fastMathVersion, Double.NaN);
224 } catch (NoSuchMethodException e) {
225 fail(e.getLocalizedMessage());
226 }
227 }
228
229 private void checkF0Equality(final UnivariateFunction f, final Method ref, final double x) {
230 try {
231 double yRef = ((Double) ref.invoke(null, x)).doubleValue();
232 double y = f.value(x);
233 if (Double.isNaN(yRef)) {
234 assertTrue(Double.isNaN(y));
235 } else if (Double.isInfinite(yRef)) {
236 assertTrue(Double.isInfinite(y));
237 assertTrue(y * yRef > 0.0);
238 } else {
239 assertEquals(yRef, y, FastMath.ulp(yRef));
240 }
241 } catch (InvocationTargetException | IllegalAccessException | IllegalArgumentException e) {
242 fail(e.getLocalizedMessage());
243 }
244 }
245
246 private void doTestFn(final UnivariateDifferentiableFunction f, double... x) {
247 try {
248 final Method fastMathVersion = FastMath.class.getMethod(f.getClass().getSimpleName().toLowerCase(),
249 CalculusFieldElement.class);
250 for (double xi : x) {
251 checkFnEqualities(f, fastMathVersion, xi);
252 }
253 checkFnEqualities(f, fastMathVersion, Double.NEGATIVE_INFINITY);
254 checkFnEqualities(f, fastMathVersion, Double.POSITIVE_INFINITY);
255 checkFnEqualities(f, fastMathVersion, Double.NaN);
256 } catch (NoSuchMethodException e) {
257 fail(e.getLocalizedMessage());
258 }
259 }
260
261 private void checkFnEqualities(final UnivariateDifferentiableFunction f, final Method ref, final double x) {
262 try {
263 DSFactory factory = new DSFactory(1, 5);
264 DerivativeStructure xDS = factory.variable(0, x);
265 DerivativeStructure yRef = (DerivativeStructure) ref.invoke(null, xDS);
266 DerivativeStructure y = f.value(xDS);
267 for (int order = 0; order < factory.getCompiler().getOrder(); ++order) {
268 if (Double.isNaN(yRef.getPartialDerivative(order))) {
269 assertTrue(Double.isNaN(y.getPartialDerivative(order)));
270 } else if (Double.isInfinite(yRef.getPartialDerivative(order))) {
271 assertTrue(Double.isInfinite(y.getPartialDerivative(order)));
272 assertTrue(y.getPartialDerivative(order) * yRef.getPartialDerivative(order) > 0.0);
273 } else {
274 assertEquals(yRef.getPartialDerivative(order), y.getPartialDerivative(order), FastMath.ulp(yRef.getPartialDerivative(order)));
275 }
276 }
277 } catch (InvocationTargetException | IllegalAccessException | IllegalArgumentException e) {
278 fail(e.getLocalizedMessage());
279 }
280 }
281
282 private void doTestF1(final UnivariateDifferentiableFunction f, double... x) {
283 try {
284 final Method fastMathVersion = FastMath.class.getMethod(f.getClass().getSimpleName().toLowerCase(),
285 CalculusFieldElement.class);
286 for (double xi : x) {
287 checkF1Equalities(f, fastMathVersion, xi);
288 }
289 checkF1Equalities(f, fastMathVersion, Double.NEGATIVE_INFINITY);
290 checkF1Equalities(f, fastMathVersion, Double.POSITIVE_INFINITY);
291 checkF1Equalities(f, fastMathVersion, Double.NaN);
292 } catch (NoSuchMethodException e) {
293 fail(e.getLocalizedMessage());
294 }
295 }
296
297 private void checkF1Equalities(final UnivariateDifferentiableFunction f, final Method ref, final double x) {
298 try {
299 Gradient xDS = Gradient.variable(1, 0, x);
300 Gradient yRef = (Gradient) ref.invoke(null, xDS);
301 Gradient y = f.value(xDS);
302 if (Double.isNaN(yRef.getPartialDerivative(0))) {
303 assertTrue(Double.isNaN(y.getPartialDerivative(0)));
304 } else if (Double.isInfinite(yRef.getPartialDerivative(0))) {
305 assertTrue(Double.isInfinite(y.getPartialDerivative(0)));
306 assertTrue(y.getPartialDerivative(0) * yRef.getPartialDerivative(0) > 0.0);
307 } else {
308 assertEquals(yRef.getPartialDerivative(0), y.getPartialDerivative(0), FastMath.ulp(yRef.getPartialDerivative(0)));
309 }
310 } catch (InvocationTargetException | IllegalAccessException | IllegalArgumentException e) {
311 fail(e.getLocalizedMessage());
312 }
313 }
314
315 }