1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.analysis.differentiation;
23
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29
30 import org.hipparchus.CalculusFieldElementAbstractTest;
31 import org.hipparchus.Field;
32 import org.hipparchus.UnitTestUtils;
33 import org.hipparchus.analysis.polynomials.PolynomialFunction;
34 import org.hipparchus.random.Well1024a;
35 import org.hipparchus.util.FastMath;
36 import org.hipparchus.util.FieldSinCos;
37 import org.junit.Assert;
38 import org.junit.Test;
39
40 public class SparseGradientTest extends CalculusFieldElementAbstractTest<SparseGradient> {
41
42 @Override
43 protected SparseGradient build(final double x) {
44 return SparseGradient.createVariable(0, x);
45 }
46
47 @Test
48 public void testConstant() {
49 double c = 1.0;
50 SparseGradient grad = SparseGradient.createConstant(c);
51 Assert.assertEquals(c, grad.getValue(), 1.0e-15);
52 Assert.assertEquals(0, grad.getFreeParameters(), 1.0e-15);
53 }
54
55 @Test
56 public void testVariable() {
57 double v = 1.0;
58 int id = 0;
59 SparseGradient grad = SparseGradient.createVariable(id, v);
60 Assert.assertEquals(v, grad.getValue(), 1.0e-15);
61 Assert.assertEquals(1, grad.getFreeParameters(), 1.0e-15);
62 Assert.assertEquals(1.0, grad.getDerivative(id), 1.0e-15);
63 }
64
65 @Test
66 public void testVarAddition() {
67 final double v1 = 1.0;
68 final double v2 = 2.0;
69 final int id1 = -1;
70 final int id2 = 3;
71 final SparseGradient var1 = SparseGradient.createVariable(id1, v1);
72 final SparseGradient var2 = SparseGradient.createVariable(id2, v2);
73 final SparseGradient sum = var1.add(var2);
74
75 Assert.assertEquals(v1 + v2, sum.getValue(), 1.0e-15);
76 Assert.assertEquals(2, sum.getFreeParameters());
77 Assert.assertEquals(1.0, sum.getDerivative(id1), 1.0e-15);
78 Assert.assertEquals(1.0, sum.getDerivative(id2), 1.0e-15);
79 }
80
81 @Test
82 public void testSubtraction() {
83 final double v1 = 1.0;
84 final double v2 = 2.0;
85 final int id1 = -1;
86 final int id2 = 3;
87 final SparseGradient var1 = SparseGradient.createVariable(id1, v1);
88 final SparseGradient var2 = SparseGradient.createVariable(id2, v2);
89 final SparseGradient sum = var1.subtract(var2);
90
91 Assert.assertEquals(v1 - v2, sum.getValue(), 1.0e-15);
92 Assert.assertEquals(2, sum.getFreeParameters());
93 Assert.assertEquals(1.0, sum.getDerivative(id1), 1.0e-15);
94 Assert.assertEquals(-1.0, sum.getDerivative(id2), 1.0e-15);
95 }
96
97 @Test
98 public void testDivision() {
99 final double v1 = 1.0;
100 final double v2 = 2.0;
101 final int id1 = -1;
102 final int id2 = 3;
103 final SparseGradient var1 = SparseGradient.createVariable(id1, v1);
104 final SparseGradient var2 = SparseGradient.createVariable(id2, v2);
105 final SparseGradient out = var1.divide(var2);
106 Assert.assertEquals(v1 / v2, out.getValue(), 1.0e-15);
107 Assert.assertEquals(2, out.getFreeParameters());
108 Assert.assertEquals(1 / v2, out.getDerivative(id1), 1.0e-15);
109 Assert.assertEquals(-1 / (v2 * v2), out.getDerivative(id2), 1.0e-15);
110 }
111
112 @Test
113 public void testMult() {
114 final double v1 = 1.0;
115 final double c1 = 0.5;
116 final double v2 = 2.0;
117 final int id1 = -1;
118 final int id2 = 3;
119 final SparseGradient var1 = SparseGradient.createVariable(id1, v1);
120 final SparseGradient unit1 = var1.multiply(c1);
121 final SparseGradient unit2 = SparseGradient.createVariable(id2, v2).multiply(var1);
122 final SparseGradient sum = unit1.add(unit2);
123 Assert.assertEquals(v1 * c1 + v2 * v1, sum.getValue(), 1.0e-15);
124 Assert.assertEquals(2, sum.getFreeParameters());
125 Assert.assertEquals(c1 + v2, sum.getDerivative(id1), 1.0e-15);
126 Assert.assertEquals(v1, sum.getDerivative(id2), 1.0e-15);
127 }
128
129 @Test
130 public void testVarMultInPlace() {
131 final double v1 = 1.0;
132 final double c1 = 0.5;
133 final double v2 = 2.0;
134 final int id1 = -1;
135 final int id2 = 3;
136 final SparseGradient var1 = SparseGradient.createVariable(id1, v1);
137 final SparseGradient sum = var1.multiply(c1);
138 final SparseGradient mult = SparseGradient.createVariable(id2, v2);
139 mult.multiplyInPlace(var1);
140 sum.addInPlace(mult);
141 Assert.assertEquals(v1 * c1 + v2 * v1, sum.getValue(), 1.0e-15);
142 Assert.assertEquals(2, sum.getFreeParameters());
143 Assert.assertEquals(c1 + v2, sum.getDerivative(id1), 1.0e-15);
144 Assert.assertEquals(v1, sum.getDerivative(id2), 1.0e-15);
145 }
146
147 @Test
148 public void testPrimitiveAdd() {
149 checkF0F1(SparseGradient.createVariable(0, 1.0).add(5), 6.0, 1.0, 0.0, 0.0);
150 checkF0F1(SparseGradient.createVariable(1, 2.0).add(5), 7.0, 0.0, 1.0, 0.0);
151 checkF0F1(SparseGradient.createVariable(2, 3.0).add(5), 8.0, 0.0, 0.0, 1.0);
152 }
153
154 @Test
155 public void testAdd() {
156 SparseGradient x = SparseGradient.createVariable(0, 1.0);
157 SparseGradient y = SparseGradient.createVariable(1, 2.0);
158 SparseGradient z = SparseGradient.createVariable(2, 3.0);
159 SparseGradient xyz = x.add(y.add(z));
160 checkF0F1(xyz, x.getValue() + y.getValue() + z.getValue(), 1.0, 1.0, 1.0);
161 }
162
163 @Test
164 public void testPrimitiveSubtract() {
165 checkF0F1(SparseGradient.createVariable(0, 1.0).subtract(5), -4.0, 1.0, 0.0, 0.0);
166 checkF0F1(SparseGradient.createVariable(1, 2.0).subtract(5), -3.0, 0.0, 1.0, 0.0);
167 checkF0F1(SparseGradient.createVariable(2, 3.0).subtract(5), -2.0, 0.0, 0.0, 1.0);
168 }
169
170 @Test
171 public void testSubtract() {
172 SparseGradient x = SparseGradient.createVariable(0, 1.0);
173 SparseGradient y = SparseGradient.createVariable(1, 2.0);
174 SparseGradient z = SparseGradient.createVariable(2, 3.0);
175 SparseGradient xyz = x.subtract(y.subtract(z));
176 checkF0F1(xyz, x.getValue() - (y.getValue() - z.getValue()), 1.0, -1.0, 1.0);
177 }
178
179 @Test
180 public void testPrimitiveMultiply() {
181 checkF0F1(SparseGradient.createVariable(0, 1.0).multiply(5), 5.0, 5.0, 0.0, 0.0);
182 checkF0F1(SparseGradient.createVariable(1, 2.0).multiply(5), 10.0, 0.0, 5.0, 0.0);
183 checkF0F1(SparseGradient.createVariable(2, 3.0).multiply(5), 15.0, 0.0, 0.0, 5.0);
184 }
185
186 @Test
187 public void testMultiply() {
188 SparseGradient x = SparseGradient.createVariable(0, 1.0);
189 SparseGradient y = SparseGradient.createVariable(1, 2.0);
190 SparseGradient z = SparseGradient.createVariable(2, 3.0);
191 SparseGradient xyz = x.multiply(y.multiply(z));
192 checkF0F1(xyz, 6.0, 6.0, 3.0, 2.0);
193 }
194
195 @Test
196 public void testNegate() {
197 checkF0F1(SparseGradient.createVariable(0, 1.0).negate(), -1.0, -1.0, 0.0, 0.0);
198 checkF0F1(SparseGradient.createVariable(1, 2.0).negate(), -2.0, 0.0, -1.0, 0.0);
199 checkF0F1(SparseGradient.createVariable(2, 3.0).negate(), -3.0, 0.0, 0.0, -1.0);
200 }
201
202 @Test
203 public void testReciprocal() {
204 for (double x = 0.1; x < 1.2; x += 0.1) {
205 SparseGradient r = SparseGradient.createVariable(0, x).reciprocal();
206 Assert.assertEquals(1 / x, r.getValue(), 1.0e-15);
207 final double expected = -1 / (x * x);
208 Assert.assertEquals(expected, r.getDerivative(0), 1.0e-15 * FastMath.abs(expected));
209 }
210 }
211
212 @Test
213 public void testPow() {
214 for (int n = 0; n < 10; ++n) {
215
216 SparseGradient x = SparseGradient.createVariable(0, 1.0);
217 SparseGradient y = SparseGradient.createVariable(1, 2.0);
218 SparseGradient z = SparseGradient.createVariable(2, 3.0);
219 List<SparseGradient> list = Arrays.asList(x, y, z,
220 x.add(y).add(z),
221 x.multiply(y).multiply(z));
222
223 if (n == 0) {
224 for (SparseGradient sg : list) {
225 Assert.assertEquals(sg.getField().getOne(), sg.pow(n));
226 }
227 } else if (n == 1) {
228 for (SparseGradient sg : list) {
229 Assert.assertEquals(sg, sg.pow(n));
230 }
231 } else {
232 for (SparseGradient sg : list) {
233 SparseGradient p = sg.getField().getOne();
234 for (int i = 0; i < n; ++i) {
235 p = p.multiply(sg);
236 }
237 Assert.assertEquals(p, sg.pow(n));
238 }
239 }
240 }
241 }
242
243 @Test
244 public void testPowDoubleDS() {
245 for (int maxOrder = 1; maxOrder < 5; ++maxOrder) {
246
247 SparseGradient x = SparseGradient.createVariable(0, 0.1);
248 SparseGradient y = SparseGradient.createVariable(1, 0.2);
249 SparseGradient z = SparseGradient.createVariable(2, 0.3);
250 List<SparseGradient> list = Arrays.asList(x, y, z,
251 x.add(y).add(z),
252 x.multiply(y).multiply(z));
253
254 for (SparseGradient sg : list) {
255
256 for (double a : new double[] { 0.0, 0.1, 1.0, 2.0, 5.0 }) {
257 SparseGradient reference = (a == 0) ?
258 x.getField().getZero() :
259 SparseGradient.createConstant(a).pow(sg);
260 SparseGradient result = SparseGradient.pow(a, sg);
261 Assert.assertEquals(reference, result);
262 }
263
264 }
265
266
267 SparseGradient negEvenInteger = SparseGradient.pow(-2.0, SparseGradient.createVariable(0, 2.0));
268 Assert.assertEquals(4.0, negEvenInteger.getValue(), 1.0e-15);
269 Assert.assertTrue(Double.isNaN(negEvenInteger.getDerivative(0)));
270 SparseGradient negOddInteger = SparseGradient.pow(-2.0, SparseGradient.createVariable(0, 3.0));
271 Assert.assertEquals(-8.0, negOddInteger.getValue(), 1.0e-15);
272 Assert.assertTrue(Double.isNaN(negOddInteger.getDerivative(0)));
273 SparseGradient negNonInteger = SparseGradient.pow(-2.0, SparseGradient.createVariable(0, 2.001));
274 Assert.assertTrue(Double.isNaN(negNonInteger.getValue()));
275 Assert.assertTrue(Double.isNaN(negNonInteger.getDerivative(0)));
276
277 SparseGradient zeroNeg = SparseGradient.pow(0.0, SparseGradient.createVariable(0, -1.0));
278 Assert.assertTrue(Double.isNaN(zeroNeg.getValue()));
279 Assert.assertTrue(Double.isNaN(zeroNeg.getDerivative(0)));
280 SparseGradient posNeg = SparseGradient.pow(2.0, SparseGradient.createVariable(0, -2.0));
281 Assert.assertEquals(1.0 / 4.0, posNeg.getValue(), 1.0e-15);
282 Assert.assertEquals(FastMath.log(2.0) / 4.0, posNeg.getDerivative(0), 1.0e-15);
283
284
285 SparseGradient zeroZero = SparseGradient.pow(0.0, SparseGradient.createVariable(0, 0.0));
286
287
288 Assert.assertEquals(1.0, zeroZero.getValue(), 1.0e-15);
289 Assert.assertEquals(Double.NEGATIVE_INFINITY, zeroZero.getDerivative(0), 1.0e-15);
290 Assert.assertEquals(0.0, zeroZero.getDerivative(1), 1.0e-15);
291 Assert.assertEquals(0.0, zeroZero.getDerivative(2), 1.0e-15);
292
293 }
294
295 }
296
297 @Test
298 public void testExpression() {
299 double epsilon = 2.5e-13;
300 for (double x = 0; x < 2; x += 0.2) {
301 SparseGradient sgX = SparseGradient.createVariable(0, x);
302 for (double y = 0; y < 2; y += 0.2) {
303 SparseGradient sgY = SparseGradient.createVariable(1, y);
304 for (double z = 0; z >- 2; z -= 0.2) {
305 SparseGradient sgZ = SparseGradient.createVariable(2, z);
306
307
308 SparseGradient sg =
309 sgZ.linearCombination(1, sgX,
310 5, sgX.multiply(sgY),
311 -2, sgZ,
312 1, sgZ.linearCombination(8, sgZ.multiply(sgX), -1, sgY).pow(3));
313 double f = x + 5 * x * y - 2 * z + FastMath.pow(8 * z * x - y, 3);
314 Assert.assertEquals(f, sg.getValue(), FastMath.abs(epsilon * f));
315
316
317 double dfdx = 1 + 5 * y + 24 * z * FastMath.pow(8 * z * x - y, 2);
318 Assert.assertEquals(dfdx, sg.getDerivative(0), FastMath.abs(epsilon * dfdx));
319
320 }
321
322 }
323 }
324 }
325
326 @Test
327 public void testCompositionOneVariableX() {
328 double epsilon = 1.0e-13;
329 for (double x = 0.1; x < 1.2; x += 0.1) {
330 SparseGradient sgX = SparseGradient.createVariable(0, x);
331 for (double y = 0.1; y < 1.2; y += 0.1) {
332 SparseGradient sgY = SparseGradient.createConstant(y);
333 SparseGradient f = sgX.divide(sgY).sqrt();
334 double f0 = FastMath.sqrt(x / y);
335 Assert.assertEquals(f0, f.getValue(), FastMath.abs(epsilon * f0));
336 double f1 = 1 / (2 * FastMath.sqrt(x * y));
337 Assert.assertEquals(f1, f.getDerivative(0), FastMath.abs(epsilon * f1));
338 }
339 }
340 }
341
342 @Test
343 public void testTrigo() {
344 double epsilon = 2.0e-12;
345 for (double x = 0.1; x < 1.2; x += 0.1) {
346 SparseGradient sgX = SparseGradient.createVariable(0, x);
347 for (double y = 0.1; y < 1.2; y += 0.1) {
348 SparseGradient sgY = SparseGradient.createVariable(1, y);
349 for (double z = 0.1; z < 1.2; z += 0.1) {
350 SparseGradient sgZ = SparseGradient.createVariable(2, z);
351 SparseGradient f = sgX.divide(sgY.cos().add(sgZ.tan())).sin();
352 double a = FastMath.cos(y) + FastMath.tan(z);
353 double f0 = FastMath.sin(x / a);
354 Assert.assertEquals(f0, f.getValue(), FastMath.abs(epsilon * f0));
355 double dfdx = FastMath.cos(x / a) / a;
356 Assert.assertEquals(dfdx, f.getDerivative(0), FastMath.abs(epsilon * dfdx));
357 double dfdy = x * FastMath.sin(y) * dfdx / a;
358 Assert.assertEquals(dfdy, f.getDerivative(1), FastMath.abs(epsilon * dfdy));
359 double cz = FastMath.cos(z);
360 double cz2 = cz * cz;
361 double dfdz = -x * dfdx / (a * cz2);
362 Assert.assertEquals(dfdz, f.getDerivative(2), FastMath.abs(epsilon * dfdz));
363 }
364 }
365 }
366 }
367
368 @Test
369 public void testSqrtDefinition() {
370 for (double x = 0.1; x < 1.2; x += 0.001) {
371 SparseGradient sgX = SparseGradient.createVariable(0, x);
372 SparseGradient sqrt1 = sgX.pow(0.5);
373 SparseGradient sqrt2 = sgX.sqrt();
374 SparseGradient zero = sqrt1.subtract(sqrt2);
375 checkF0F1(zero, 0.0, 0.0);
376 }
377 }
378
379 @Test
380 public void testRootNSingularity() {
381 for (int n = 2; n < 10; ++n) {
382 SparseGradient sgZero = SparseGradient.createVariable(0, 0.0);
383 SparseGradient rootN = sgZero.rootN(n);
384 Assert.assertEquals(0.0, rootN.getValue(), 1.0e-5);
385 Assert.assertTrue(Double.isInfinite(rootN.getDerivative(0)));
386 Assert.assertTrue(rootN.getDerivative(0) > 0);
387 }
388
389 }
390
391 @Test
392 public void testSqrtPow2() {
393 for (double x = 0.1; x < 1.2; x += 0.001) {
394 SparseGradient sgX = SparseGradient.createVariable(0, x);
395 SparseGradient rebuiltX = sgX.multiply(sgX).sqrt();
396 SparseGradient zero = rebuiltX.subtract(sgX);
397 checkF0F1(zero, 0.0, 0.0);
398 }
399 }
400
401 @Test
402 public void testCbrtDefinition() {
403 for (double x = 0.1; x < 1.2; x += 0.001) {
404 SparseGradient sgX = SparseGradient.createVariable(0, x);
405 SparseGradient cbrt1 = sgX.pow(1.0 / 3.0);
406 SparseGradient cbrt2 = sgX.cbrt();
407 SparseGradient zero = cbrt1.subtract(cbrt2);
408 checkF0F1(zero, 0.0, 0.0);
409 }
410 }
411
412 @Test
413 public void testCbrtPow3() {
414 for (double x = 0.1; x < 1.2; x += 0.001) {
415 SparseGradient sgX = SparseGradient.createVariable(0, x);
416 SparseGradient rebuiltX = sgX.multiply(sgX.multiply(sgX)).cbrt();
417 SparseGradient zero = rebuiltX.subtract(sgX);
418 checkF0F1(zero, 0.0, 0.0);
419 }
420 }
421
422 @Test
423 public void testPowReciprocalPow() {
424 for (double x = 0.1; x < 1.2; x += 0.01) {
425 SparseGradient sgX = SparseGradient.createVariable(0, x);
426 for (double y = 0.1; y < 1.2; y += 0.01) {
427 SparseGradient sgY = SparseGradient.createVariable(1, y);
428 SparseGradient rebuiltX = sgX.pow(sgY).pow(sgY.reciprocal());
429 SparseGradient zero = rebuiltX.subtract(sgX);
430 checkF0F1(zero, 0.0, 0.0, 0.0);
431 }
432 }
433 }
434
435 @Test
436 public void testHypotDefinition() {
437 for (double x = -1.7; x < 2; x += 0.2) {
438 SparseGradient sgX = SparseGradient.createVariable(0, x);
439 for (double y = -1.7; y < 2; y += 0.2) {
440 SparseGradient sgY = SparseGradient.createVariable(1, y);
441 SparseGradient hypot = SparseGradient.hypot(sgY, sgX);
442 SparseGradient ref = sgX.multiply(sgX).add(sgY.multiply(sgY)).sqrt();
443 SparseGradient zero = hypot.subtract(ref);
444 checkF0F1(zero, 0.0, 0.0, 0.0);
445
446 }
447 }
448 }
449
450 @Test
451 public void testHypotNoOverflow() {
452
453 SparseGradient sgX = SparseGradient.createVariable(0, +3.0e250);
454 SparseGradient sgY = SparseGradient.createVariable(1, -4.0e250);
455 SparseGradient hypot = SparseGradient.hypot(sgX, sgY);
456 Assert.assertEquals(5.0e250, hypot.getValue(), 1.0e235);
457 Assert.assertEquals(sgX.getValue() / hypot.getValue(), hypot.getDerivative(0), 1.0e-10);
458 Assert.assertEquals(sgY.getValue() / hypot.getValue(), hypot.getDerivative(1), 1.0e-10);
459
460 SparseGradient sqrt = sgX.multiply(sgX).add(sgY.multiply(sgY)).sqrt();
461 Assert.assertTrue(Double.isInfinite(sqrt.getValue()));
462
463 }
464
465 @Test
466 public void testHypotNeglectible() {
467
468 SparseGradient sgSmall = SparseGradient.createVariable(0, +3.0e-10);
469 SparseGradient sgLarge = SparseGradient.createVariable(1, -4.0e25);
470
471 Assert.assertEquals(sgLarge.abs().getValue(),
472 SparseGradient.hypot(sgSmall, sgLarge).getValue(),
473 1.0e-10);
474 Assert.assertEquals(0,
475 SparseGradient.hypot(sgSmall, sgLarge).getDerivative(0),
476 1.0e-10);
477 Assert.assertEquals(-1,
478 SparseGradient.hypot(sgSmall, sgLarge).getDerivative(1),
479 1.0e-10);
480
481 Assert.assertEquals(sgLarge.abs().getValue(),
482 SparseGradient.hypot(sgLarge, sgSmall).getValue(),
483 1.0e-10);
484 Assert.assertEquals(0,
485 SparseGradient.hypot(sgLarge, sgSmall).getDerivative(0),
486 1.0e-10);
487 Assert.assertEquals(-1,
488 SparseGradient.hypot(sgLarge, sgSmall).getDerivative(1),
489 1.0e-10);
490
491 }
492
493 @Test
494 public void testHypotSpecial() {
495 Assert.assertTrue(Double.isNaN(SparseGradient.hypot(SparseGradient.createVariable(0, Double.NaN),
496 SparseGradient.createVariable(0, +3.0e250)).getValue()));
497 Assert.assertTrue(Double.isNaN(SparseGradient.hypot(SparseGradient.createVariable(0, +3.0e250),
498 SparseGradient.createVariable(0, Double.NaN)).getValue()));
499 Assert.assertTrue(Double.isInfinite(SparseGradient.hypot(SparseGradient.createVariable(0, Double.POSITIVE_INFINITY),
500 SparseGradient.createVariable(0, +3.0e250)).getValue()));
501 Assert.assertTrue(Double.isInfinite(SparseGradient.hypot(SparseGradient.createVariable(0, +3.0e250),
502 SparseGradient.createVariable(0, Double.POSITIVE_INFINITY)).getValue()));
503 }
504
505 @Test
506 public void testPrimitiveRemainder() {
507 for (double x = -1.7; x < 2; x += 0.2) {
508 SparseGradient sgX = SparseGradient.createVariable(0, x);
509 for (double y = -1.7; y < 2; y += 0.2) {
510 SparseGradient remainder = sgX.remainder(y);
511 SparseGradient ref = sgX.subtract(x - FastMath.IEEEremainder(x, y));
512 SparseGradient zero = remainder.subtract(ref);
513 checkF0F1(zero, 0.0, 0.0, 0.0);
514 }
515 }
516 }
517
518 @Test
519 public void testRemainder() {
520 for (double x = -1.7; x < 2; x += 0.2) {
521 SparseGradient sgX = SparseGradient.createVariable(0, x);
522 for (double y = -1.7; y < 2; y += 0.2) {
523 SparseGradient sgY = SparseGradient.createVariable(1, y);
524 SparseGradient remainder = sgX.remainder(sgY);
525 SparseGradient ref = sgX.subtract(sgY.multiply((x - FastMath.IEEEremainder(x, y)) / y));
526 SparseGradient zero = remainder.subtract(ref);
527 checkF0F1(zero, 0.0, 0.0, 0.0);
528 }
529 }
530 }
531
532 @Override
533 @Test
534 public void testExp() {
535 for (double x = 0.1; x < 1.2; x += 0.001) {
536 double refExp = FastMath.exp(x);
537 checkF0F1(SparseGradient.createVariable(0, x).exp(), refExp, refExp);
538 }
539 }
540
541 @Test
542 public void testExpm1Definition() {
543 for (double x = 0.1; x < 1.2; x += 0.001) {
544 SparseGradient sgX = SparseGradient.createVariable(0, x);
545 SparseGradient expm11 = sgX.expm1();
546 SparseGradient expm12 = sgX.exp().subtract(sgX.getField().getOne());
547 SparseGradient zero = expm11.subtract(expm12);
548 checkF0F1(zero, 0.0, 0.0);
549 }
550 }
551
552 @Override
553 @Test
554 public void testLog() {
555 for (double x = 0.1; x < 1.2; x += 0.001) {
556 checkF0F1(SparseGradient.createVariable(0, x).log(), FastMath.log(x), 1.0 / x);
557 }
558 }
559
560 @Test
561 public void testLog1pDefinition() {
562 for (double x = 0.1; x < 1.2; x += 0.001) {
563 SparseGradient sgX = SparseGradient.createVariable(0, x);
564 SparseGradient log1p1 = sgX.log1p();
565 SparseGradient log1p2 = sgX.add(sgX.getField().getOne()).log();
566 SparseGradient zero = log1p1.subtract(log1p2);
567 checkF0F1(zero, 0.0, 0.0);
568 }
569 }
570
571 @Test
572 public void testLog10Definition() {
573 for (double x = 0.1; x < 1.2; x += 0.001) {
574 SparseGradient sgX = SparseGradient.createVariable(0, x);
575 SparseGradient log101 = sgX.log10();
576 SparseGradient log102 = sgX.log().divide(FastMath.log(10.0));
577 SparseGradient zero = log101.subtract(log102);
578 checkF0F1(zero, 0.0, 0.0);
579 }
580 }
581
582 @Test
583 public void testLogExp() {
584 for (double x = 0.1; x < 1.2; x += 0.001) {
585 SparseGradient sgX = SparseGradient.createVariable(0, x);
586 SparseGradient rebuiltX = sgX.exp().log();
587 SparseGradient zero = rebuiltX.subtract(sgX);
588 checkF0F1(zero, 0.0, 0.0);
589 }
590 }
591
592 @Test
593 public void testLog1pExpm1() {
594 for (double x = 0.1; x < 1.2; x += 0.001) {
595 SparseGradient sgX = SparseGradient.createVariable(0, x);
596 SparseGradient rebuiltX = sgX.expm1().log1p();
597 SparseGradient zero = rebuiltX.subtract(sgX);
598 checkF0F1(zero, 0.0, 0.0);
599 }
600 }
601
602 @Test
603 public void testLog10Power() {
604 for (double x = 0.1; x < 1.2; x += 0.001) {
605 SparseGradient sgX = SparseGradient.createVariable(0, x);
606 SparseGradient rebuiltX = SparseGradient.pow(10.0, sgX).log10();
607 SparseGradient zero = rebuiltX.subtract(sgX);
608 checkF0F1(zero, 0.0, 0.0);
609 }
610 }
611
612 @Test
613 public void testSinCos() {
614 for (double x = 0.1; x < 1.2; x += 0.001) {
615 SparseGradient sgX = SparseGradient.createVariable(0, x);
616 SparseGradient sin = sgX.sin();
617 SparseGradient cos = sgX.cos();
618 FieldSinCos<SparseGradient> sinCos = sgX.sinCos();
619 double s = FastMath.sin(x);
620 double c = FastMath.cos(x);
621 checkF0F1(sin, s, c);
622 checkF0F1(cos, c, -s);
623 checkF0F1(sinCos.sin(), s, c);
624 checkF0F1(sinCos.cos(), c, -s);
625 }
626 }
627
628 @Test
629 public void testSinAsin() {
630 for (double x = 0.1; x < 1.2; x += 0.001) {
631 SparseGradient sgX = SparseGradient.createVariable(0, x);
632 SparseGradient rebuiltX = sgX.sin().asin();
633 SparseGradient zero = rebuiltX.subtract(sgX);
634 checkF0F1(zero, 0.0, 0.0);
635 }
636 }
637
638 @Test
639 public void testCosAcos() {
640 for (double x = 0.1; x < 1.2; x += 0.001) {
641 SparseGradient sgX = SparseGradient.createVariable(0, x);
642 SparseGradient rebuiltX = sgX.cos().acos();
643 SparseGradient zero = rebuiltX.subtract(sgX);
644 checkF0F1(zero, 0.0, 0.0);
645 }
646 }
647
648 @Test
649 public void testTanAtan() {
650 for (double x = 0.1; x < 1.2; x += 0.001) {
651 SparseGradient sgX = SparseGradient.createVariable(0, x);
652 SparseGradient rebuiltX = sgX.tan().atan();
653 SparseGradient zero = rebuiltX.subtract(sgX);
654 checkF0F1(zero, 0.0, 0.0);
655 }
656 }
657
658 @Test
659 public void testTangentDefinition() {
660 for (double x = 0.1; x < 1.2; x += 0.001) {
661 SparseGradient sgX = SparseGradient.createVariable(0, x);
662 SparseGradient tan1 = sgX.sin().divide(sgX.cos());
663 SparseGradient tan2 = sgX.tan();
664 SparseGradient zero = tan1.subtract(tan2);
665 checkF0F1(zero, 0.0, 0.0);
666 }
667 }
668
669 @Override
670 @Test
671 public void testAtan2() {
672 for (double x = -1.7; x < 2; x += 0.2) {
673 SparseGradient sgX = SparseGradient.createVariable(0, x);
674 for (double y = -1.7; y < 2; y += 0.2) {
675 SparseGradient sgY = SparseGradient.createVariable(1, y);
676 SparseGradient atan2 = SparseGradient.atan2(sgY, sgX);
677 SparseGradient ref = sgY.divide(sgX).atan();
678 if (x < 0) {
679 ref = (y < 0) ? ref.subtract(FastMath.PI) : ref.add(FastMath.PI);
680 }
681 SparseGradient zero = atan2.subtract(ref);
682 checkF0F1(zero, 0.0, 0.0);
683 }
684 }
685 }
686
687 @Test
688 public void testAtan2SpecialCasesSparseGradient() {
689
690 SparseGradient pp =
691 SparseGradient.atan2(SparseGradient.createVariable(1, +0.0),
692 SparseGradient.createVariable(1, +0.0));
693 Assert.assertEquals(0, pp.getValue(), 1.0e-15);
694 Assert.assertEquals(+1, FastMath.copySign(1, pp.getValue()), 1.0e-15);
695
696 SparseGradient pn =
697 SparseGradient.atan2(SparseGradient.createVariable(1, +0.0),
698 SparseGradient.createVariable(1, -0.0));
699 Assert.assertEquals(FastMath.PI, pn.getValue(), 1.0e-15);
700
701 SparseGradient np =
702 SparseGradient.atan2(SparseGradient.createVariable(1, -0.0),
703 SparseGradient.createVariable(1, +0.0));
704 Assert.assertEquals(0, np.getValue(), 1.0e-15);
705 Assert.assertEquals(-1, FastMath.copySign(1, np.getValue()), 1.0e-15);
706
707 SparseGradient nn =
708 SparseGradient.atan2(SparseGradient.createVariable(1, -0.0),
709 SparseGradient.createVariable(1, -0.0));
710 Assert.assertEquals(-FastMath.PI, nn.getValue(), 1.0e-15);
711
712 }
713
714 @Test
715 public void testSinhDefinition() {
716 for (double x = 0.1; x < 1.2; x += 0.001) {
717 SparseGradient sgX = SparseGradient.createVariable(0, x);
718 SparseGradient sinh1 = sgX.exp().subtract(sgX.exp().reciprocal()).multiply(0.5);
719 SparseGradient sinh2 = sgX.sinh();
720 SparseGradient zero = sinh1.subtract(sinh2);
721 checkF0F1(zero, 0.0, 0.0);
722 }
723 }
724
725 @Test
726 public void testCoshDefinition() {
727 for (double x = 0.1; x < 1.2; x += 0.001) {
728 SparseGradient sgX = SparseGradient.createVariable(0, x);
729 SparseGradient cosh1 = sgX.exp().add(sgX.exp().reciprocal()).multiply(0.5);
730 SparseGradient cosh2 = sgX.cosh();
731 SparseGradient zero = cosh1.subtract(cosh2);
732 checkF0F1(zero, 0.0, 0.0);
733 }
734 }
735
736 @Test
737 public void testTanhDefinition() {
738 for (double x = 0.1; x < 1.2; x += 0.001) {
739 SparseGradient sgX = SparseGradient.createVariable(0, x);
740 SparseGradient tanh1 = sgX.exp().subtract(sgX.exp().reciprocal()).divide(sgX.exp().add(sgX.exp().reciprocal()));
741 SparseGradient tanh2 = sgX.tanh();
742 SparseGradient zero = tanh1.subtract(tanh2);
743 checkF0F1(zero, 0.0, 0.0);
744 }
745 }
746
747 @Test
748 public void testSinhAsinh() {
749 for (double x = 0.1; x < 1.2; x += 0.001) {
750 SparseGradient sgX = SparseGradient.createVariable(0, x);
751 SparseGradient rebuiltX = sgX.sinh().asinh();
752 SparseGradient zero = rebuiltX.subtract(sgX);
753 checkF0F1(zero, 0.0, 0.0);
754 }
755 }
756
757 @Test
758 public void testCoshAcosh() {
759 for (double x = 0.1; x < 1.2; x += 0.001) {
760 SparseGradient sgX = SparseGradient.createVariable(0, x);
761 SparseGradient rebuiltX = sgX.cosh().acosh();
762 SparseGradient zero = rebuiltX.subtract(sgX);
763 checkF0F1(zero, 0.0, 0.0);
764 }
765 }
766
767 @Test
768 public void testTanhAtanh() {
769 for (double x = 0.1; x < 1.2; x += 0.001) {
770 SparseGradient sgX = SparseGradient.createVariable(0, x);
771 SparseGradient rebuiltX = sgX.tanh().atanh();
772 SparseGradient zero = rebuiltX.subtract(sgX);
773 checkF0F1(zero, 0.0, 0.0);
774 }
775 }
776
777 @Test
778 public void testCompositionOneVariableY() {
779 for (double x = 0.1; x < 1.2; x += 0.1) {
780 SparseGradient sgX = SparseGradient.createConstant(x);
781 for (double y = 0.1; y < 1.2; y += 0.1) {
782 SparseGradient sgY = SparseGradient.createVariable(0, y);
783 SparseGradient f = sgX.divide(sgY).sqrt();
784 double f0 = FastMath.sqrt(x / y);
785 double f1 = -x / (2 * y * y * f0);
786 checkF0F1(f, f0, f1);
787 }
788 }
789 }
790
791 @Test
792 public void testTaylorPolynomial() {
793 for (double x = 0; x < 1.2; x += 0.1) {
794 SparseGradient sgX = SparseGradient.createVariable(0, x);
795 for (double y = 0; y < 1.2; y += 0.2) {
796 SparseGradient sgY = SparseGradient.createVariable(1, y);
797 for (double z = 0; z < 1.2; z += 0.2) {
798 SparseGradient sgZ = SparseGradient.createVariable(2, z);
799 SparseGradient f = sgX.multiply(3).add(sgZ.multiply(-2)).add(sgY.multiply(5));
800 for (double dx = -0.2; dx < 0.2; dx += 0.2) {
801 for (double dy = -0.2; dy < 0.2; dy += 0.1) {
802 for (double dz = -0.2; dz < 0.2; dz += 0.1) {
803 double ref = 3 * (x + dx) + 5 * (y + dy) -2 * (z + dz);
804 Assert.assertEquals(ref, f.taylor(dx, dy, dz), 3.0e-15);
805 }
806 }
807 }
808 }
809 }
810 }
811 }
812
813 @Test
814 public void testTaylorAtan2() {
815 double x0 = 0.1;
816 double y0 = -0.3;
817 SparseGradient sgX = SparseGradient.createVariable(0, x0);
818 SparseGradient sgY = SparseGradient.createVariable(1, y0);
819 SparseGradient atan2 = SparseGradient.atan2(sgY, sgX);
820 double maxError = 0;
821 for (double dx = -0.05; dx < 0.05; dx += 0.001) {
822 for (double dy = -0.05; dy < 0.05; dy += 0.001) {
823 double ref = FastMath.atan2(y0 + dy, x0 + dx);
824 maxError = FastMath.max(maxError, FastMath.abs(ref - atan2.taylor(dx, dy)));
825 }
826 }
827 double expectedError = 0.0241;
828 Assert.assertEquals(expectedError, maxError, 0.01 * expectedError);
829 }
830
831 @Test
832 public void testAbs() {
833
834 SparseGradient minusOne = SparseGradient.createVariable(0, -1.0);
835 Assert.assertEquals(+1.0, minusOne.abs().getValue(), 1.0e-15);
836 Assert.assertEquals(-1.0, minusOne.abs().getDerivative(0), 1.0e-15);
837
838 SparseGradient plusOne = SparseGradient.createVariable(0, +1.0);
839 Assert.assertEquals(+1.0, plusOne.abs().getValue(), 1.0e-15);
840 Assert.assertEquals(+1.0, plusOne.abs().getDerivative(0), 1.0e-15);
841
842 SparseGradient minusZero = SparseGradient.createVariable(0, -0.0);
843 Assert.assertEquals(+0.0, minusZero.abs().getValue(), 1.0e-15);
844 Assert.assertEquals(-1.0, minusZero.abs().getDerivative(0), 1.0e-15);
845
846 SparseGradient plusZero = SparseGradient.createVariable(0, +0.0);
847 Assert.assertEquals(+0.0, plusZero.abs().getValue(), 1.0e-15);
848 Assert.assertEquals(+1.0, plusZero.abs().getDerivative(0), 1.0e-15);
849
850 }
851
852 @Override
853 @Test
854 public void testSign() {
855
856 SparseGradient minusOne = SparseGradient.createVariable(0, -1.0);
857 Assert.assertEquals(-1.0, minusOne.sign().getValue(), 1.0e-15);
858 Assert.assertEquals( 0.0, minusOne.sign().getDerivative(0), 1.0e-15);
859
860 SparseGradient plusOne = SparseGradient.createVariable(0, +1.0);
861 Assert.assertEquals(+1.0, plusOne.sign().getValue(), 1.0e-15);
862 Assert.assertEquals( 0.0, plusOne.sign().getDerivative(0), 1.0e-15);
863
864 SparseGradient minusZero = SparseGradient.createVariable(0, -0.0);
865 Assert.assertEquals(-0.0, minusZero.sign().getValue(), 1.0e-15);
866 Assert.assertTrue(Double.doubleToLongBits(minusZero.sign().getValue()) < 0);
867 Assert.assertEquals( 0.0, minusZero.sign().getDerivative(0), 1.0e-15);
868
869 SparseGradient plusZero = SparseGradient.createVariable(0, +0.0);
870 Assert.assertEquals(+0.0, plusZero.sign().getValue(), 1.0e-15);
871 Assert.assertTrue(Double.doubleToLongBits(plusZero.sign().getValue()) == 0);
872 Assert.assertEquals( 0.0, plusZero.sign().getDerivative(0), 1.0e-15);
873
874 }
875
876 @Test
877 public void testCeilFloorRintLong() {
878
879 SparseGradient x = SparseGradient.createVariable(0, -1.5);
880 Assert.assertEquals(-1.5, x.getValue(), 1.0e-15);
881 Assert.assertEquals(+1.0, x.getDerivative(0), 1.0e-15);
882 Assert.assertEquals(-1.0, x.ceil().getValue(), 1.0e-15);
883 Assert.assertEquals(+0.0, x.ceil().getDerivative(0), 1.0e-15);
884 Assert.assertEquals(-2.0, x.floor().getValue(), 1.0e-15);
885 Assert.assertEquals(+0.0, x.floor().getDerivative(0), 1.0e-15);
886 Assert.assertEquals(-2.0, x.rint().getValue(), 1.0e-15);
887 Assert.assertEquals(+0.0, x.rint().getDerivative(0), 1.0e-15);
888 Assert.assertEquals(-2.0, x.subtract(x.getField().getOne()).rint().getValue(), 1.0e-15);
889
890 }
891
892 @Test
893 public void testCopySign() {
894
895 SparseGradient minusOne = SparseGradient.createVariable(0, -1.0);
896 Assert.assertEquals(+1.0, minusOne.copySign(+1.0).getValue(), 1.0e-15);
897 Assert.assertEquals(-1.0, minusOne.copySign(+1.0).getDerivative(0), 1.0e-15);
898 Assert.assertEquals(-1.0, minusOne.copySign(-1.0).getValue(), 1.0e-15);
899 Assert.assertEquals(+1.0, minusOne.copySign(-1.0).getDerivative(0), 1.0e-15);
900 Assert.assertEquals(+1.0, minusOne.copySign(+0.0).getValue(), 1.0e-15);
901 Assert.assertEquals(-1.0, minusOne.copySign(+0.0).getDerivative(0), 1.0e-15);
902 Assert.assertEquals(-1.0, minusOne.copySign(-0.0).getValue(), 1.0e-15);
903 Assert.assertEquals(+1.0, minusOne.copySign(-0.0).getDerivative(0), 1.0e-15);
904 Assert.assertEquals(+1.0, minusOne.copySign(Double.NaN).getValue(), 1.0e-15);
905 Assert.assertEquals(-1.0, minusOne.copySign(Double.NaN).getDerivative(0), 1.0e-15);
906
907 SparseGradient plusOne = SparseGradient.createVariable(0, +1.0);
908 Assert.assertEquals(+1.0, plusOne.copySign(+1.0).getValue(), 1.0e-15);
909 Assert.assertEquals(+1.0, plusOne.copySign(+1.0).getDerivative(0), 1.0e-15);
910 Assert.assertEquals(-1.0, plusOne.copySign(-1.0).getValue(), 1.0e-15);
911 Assert.assertEquals(-1.0, plusOne.copySign(-1.0).getDerivative(0), 1.0e-15);
912 Assert.assertEquals(+1.0, plusOne.copySign(+0.0).getValue(), 1.0e-15);
913 Assert.assertEquals(+1.0, plusOne.copySign(+0.0).getDerivative(0), 1.0e-15);
914 Assert.assertEquals(-1.0, plusOne.copySign(-0.0).getValue(), 1.0e-15);
915 Assert.assertEquals(-1.0, plusOne.copySign(-0.0).getDerivative(0), 1.0e-15);
916 Assert.assertEquals(+1.0, plusOne.copySign(Double.NaN).getValue(), 1.0e-15);
917 Assert.assertEquals(+1.0, plusOne.copySign(Double.NaN).getDerivative(0), 1.0e-15);
918
919 }
920
921 @Test
922 public void testToDegreesDefinition() {
923 double epsilon = 3.0e-16;
924 for (int maxOrder = 0; maxOrder < 6; ++maxOrder) {
925 for (double x = 0.1; x < 1.2; x += 0.001) {
926 SparseGradient sgX = SparseGradient.createVariable(0, x);
927 Assert.assertEquals(FastMath.toDegrees(x), sgX.toDegrees().getValue(), epsilon);
928 Assert.assertEquals(180 / FastMath.PI, sgX.toDegrees().getDerivative(0), epsilon);
929 }
930 }
931 }
932
933 @Test
934 public void testToRadiansDefinition() {
935 double epsilon = 3.0e-16;
936 for (int maxOrder = 0; maxOrder < 6; ++maxOrder) {
937 for (double x = 0.1; x < 1.2; x += 0.001) {
938 SparseGradient sgX = SparseGradient.createVariable(0, x);
939 Assert.assertEquals(FastMath.toRadians(x), sgX.toRadians().getValue(), epsilon);
940 Assert.assertEquals(FastMath.PI / 180, sgX.toRadians().getDerivative(0), epsilon);
941 }
942 }
943 }
944
945 @Test
946 public void testDegRad() {
947 for (double x = 0.1; x < 1.2; x += 0.001) {
948 SparseGradient sgX = SparseGradient.createVariable(0, x);
949 SparseGradient rebuiltX = sgX.toDegrees().toRadians();
950 SparseGradient zero = rebuiltX.subtract(sgX);
951 checkF0F1(zero, 0, 0);
952 }
953 }
954
955 @Test
956 public void testCompose() {
957 PolynomialFunction poly =
958 new PolynomialFunction(new double[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 });
959 for (double x = 0.1; x < 1.2; x += 0.001) {
960 SparseGradient sgX = SparseGradient.createVariable(0, x);
961 SparseGradient sgY1 = sgX.getField().getZero();
962 for (int i = poly.degree(); i >= 0; --i) {
963 sgY1 = sgY1.multiply(sgX).add(poly.getCoefficients()[i]);
964 }
965 SparseGradient sgY2 = sgX.compose(poly.value(x), poly.polynomialDerivative().value(x));
966 SparseGradient zero = sgY1.subtract(sgY2);
967 checkF0F1(zero, 0.0, 0.0);
968 }
969 }
970
971 @Test
972 public void testField() {
973 SparseGradient x = SparseGradient.createVariable(0, 1.0);
974 checkF0F1(x.getField().getZero(), 0.0, 0.0, 0.0, 0.0);
975 checkF0F1(x.getField().getOne(), 1.0, 0.0, 0.0, 0.0);
976 Assert.assertEquals(SparseGradient.class, x.getField().getRuntimeClass());
977 }
978
979 @Test
980 public void testLinearCombination1DSDS() {
981 final SparseGradient[] a = new SparseGradient[] {
982 SparseGradient.createVariable(0, -1321008684645961.0 / 268435456.0),
983 SparseGradient.createVariable(1, -5774608829631843.0 / 268435456.0),
984 SparseGradient.createVariable(2, -7645843051051357.0 / 8589934592.0)
985 };
986 final SparseGradient[] b = new SparseGradient[] {
987 SparseGradient.createVariable(3, -5712344449280879.0 / 2097152.0),
988 SparseGradient.createVariable(4, -4550117129121957.0 / 2097152.0),
989 SparseGradient.createVariable(5, 8846951984510141.0 / 131072.0)
990 };
991
992 final SparseGradient abSumInline = a[0].linearCombination(a[0], b[0], a[1], b[1], a[2], b[2]);
993 final SparseGradient abSumArray = a[0].linearCombination(a, b);
994
995 Assert.assertEquals(abSumInline.getValue(), abSumArray.getValue(), 1.0e-15);
996 Assert.assertEquals(-1.8551294182586248737720779899, abSumInline.getValue(), 1.0e-15);
997 Assert.assertEquals(b[0].getValue(), abSumInline.getDerivative(0), 1.0e-15);
998 Assert.assertEquals(b[1].getValue(), abSumInline.getDerivative(1), 1.0e-15);
999 Assert.assertEquals(b[2].getValue(), abSumInline.getDerivative(2), 1.0e-15);
1000 Assert.assertEquals(a[0].getValue(), abSumInline.getDerivative(3), 1.0e-15);
1001 Assert.assertEquals(a[1].getValue(), abSumInline.getDerivative(4), 1.0e-15);
1002 Assert.assertEquals(a[2].getValue(), abSumInline.getDerivative(5), 1.0e-15);
1003
1004 }
1005
1006 @Test
1007 public void testLinearCombination1DoubleDS() {
1008 final double[] a = new double[] {
1009 -1321008684645961.0 / 268435456.0,
1010 -5774608829631843.0 / 268435456.0,
1011 -7645843051051357.0 / 8589934592.0
1012 };
1013 final SparseGradient[] b = new SparseGradient[] {
1014 SparseGradient.createVariable(0, -5712344449280879.0 / 2097152.0),
1015 SparseGradient.createVariable(1, -4550117129121957.0 / 2097152.0),
1016 SparseGradient.createVariable(2, 8846951984510141.0 / 131072.0)
1017 };
1018
1019 final SparseGradient abSumInline = b[0].linearCombination(a[0], b[0],
1020 a[1], b[1],
1021 a[2], b[2]);
1022 final SparseGradient abSumArray = b[0].linearCombination(a, b);
1023
1024 Assert.assertEquals(abSumInline.getValue(), abSumArray.getValue(), 1.0e-15);
1025 Assert.assertEquals(-1.8551294182586248737720779899, abSumInline.getValue(), 1.0e-15);
1026 Assert.assertEquals(a[0], abSumInline.getDerivative(0), 1.0e-15);
1027 Assert.assertEquals(a[1], abSumInline.getDerivative(1), 1.0e-15);
1028 Assert.assertEquals(a[2], abSumInline.getDerivative(2), 1.0e-15);
1029
1030 }
1031
1032 @Test
1033 public void testLinearCombination2DSDS() {
1034
1035
1036 Well1024a random = new Well1024a(0xc6af886975069f11l);
1037
1038 for (int i = 0; i < 10000; ++i) {
1039 final SparseGradient[] u = new SparseGradient[4];
1040 final SparseGradient[] v = new SparseGradient[4];
1041 for (int j = 0; j < u.length; ++j) {
1042 u[j] = SparseGradient.createVariable(j, 1e17 * random.nextDouble());
1043 v[j] = SparseGradient.createConstant(1e17 * random.nextDouble());
1044 }
1045
1046 SparseGradient lin = u[0].linearCombination(u[0], v[0], u[1], v[1]);
1047 double ref = u[0].getValue() * v[0].getValue() +
1048 u[1].getValue() * v[1].getValue();
1049 Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
1050 Assert.assertEquals(v[0].getValue(), lin.getDerivative(0), 1.0e-15 * FastMath.abs(v[0].getValue()));
1051 Assert.assertEquals(v[1].getValue(), lin.getDerivative(1), 1.0e-15 * FastMath.abs(v[1].getValue()));
1052
1053 lin = u[0].linearCombination(u[0], v[0], u[1], v[1], u[2], v[2]);
1054 ref = u[0].getValue() * v[0].getValue() +
1055 u[1].getValue() * v[1].getValue() +
1056 u[2].getValue() * v[2].getValue();
1057 Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
1058 Assert.assertEquals(v[0].getValue(), lin.getDerivative(0), 1.0e-15 * FastMath.abs(v[0].getValue()));
1059 Assert.assertEquals(v[1].getValue(), lin.getDerivative(1), 1.0e-15 * FastMath.abs(v[1].getValue()));
1060 Assert.assertEquals(v[2].getValue(), lin.getDerivative(2), 1.0e-15 * FastMath.abs(v[2].getValue()));
1061
1062 lin = u[0].linearCombination(u[0], v[0], u[1], v[1], u[2], v[2], u[3], v[3]);
1063 ref = u[0].getValue() * v[0].getValue() +
1064 u[1].getValue() * v[1].getValue() +
1065 u[2].getValue() * v[2].getValue() +
1066 u[3].getValue() * v[3].getValue();
1067 Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
1068 Assert.assertEquals(v[0].getValue(), lin.getDerivative(0), 1.0e-15 * FastMath.abs(v[0].getValue()));
1069 Assert.assertEquals(v[1].getValue(), lin.getDerivative(1), 1.0e-15 * FastMath.abs(v[1].getValue()));
1070 Assert.assertEquals(v[2].getValue(), lin.getDerivative(2), 1.0e-15 * FastMath.abs(v[2].getValue()));
1071 Assert.assertEquals(v[3].getValue(), lin.getDerivative(3), 1.0e-15 * FastMath.abs(v[3].getValue()));
1072
1073 }
1074 }
1075
1076 @Test
1077 public void testLinearCombination2DoubleDS() {
1078
1079
1080 Well1024a random = new Well1024a(0xc6af886975069f11l);
1081
1082 for (int i = 0; i < 10000; ++i) {
1083 final double[] u = new double[4];
1084 final SparseGradient[] v = new SparseGradient[4];
1085 for (int j = 0; j < u.length; ++j) {
1086 u[j] = 1e17 * random.nextDouble();
1087 v[j] = SparseGradient.createVariable(j, 1e17 * random.nextDouble());
1088 }
1089
1090 SparseGradient lin = v[0].linearCombination(u[0], v[0], u[1], v[1]);
1091 double ref = u[0] * v[0].getValue() +
1092 u[1] * v[1].getValue();
1093 Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
1094 Assert.assertEquals(u[0], lin.getDerivative(0), 1.0e-15 * FastMath.abs(v[0].getValue()));
1095 Assert.assertEquals(u[1], lin.getDerivative(1), 1.0e-15 * FastMath.abs(v[1].getValue()));
1096
1097 lin = v[0].linearCombination(u[0], v[0], u[1], v[1], u[2], v[2]);
1098 ref = u[0] * v[0].getValue() +
1099 u[1] * v[1].getValue() +
1100 u[2] * v[2].getValue();
1101 Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
1102 Assert.assertEquals(u[0], lin.getDerivative(0), 1.0e-15 * FastMath.abs(v[0].getValue()));
1103 Assert.assertEquals(u[1], lin.getDerivative(1), 1.0e-15 * FastMath.abs(v[1].getValue()));
1104 Assert.assertEquals(u[2], lin.getDerivative(2), 1.0e-15 * FastMath.abs(v[2].getValue()));
1105
1106 lin = v[0].linearCombination(u[0], v[0], u[1], v[1], u[2], v[2], u[3], v[3]);
1107 ref = u[0] * v[0].getValue() +
1108 u[1] * v[1].getValue() +
1109 u[2] * v[2].getValue() +
1110 u[3] * v[3].getValue();
1111 Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
1112 Assert.assertEquals(u[0], lin.getDerivative(0), 1.0e-15 * FastMath.abs(v[0].getValue()));
1113 Assert.assertEquals(u[1], lin.getDerivative(1), 1.0e-15 * FastMath.abs(v[1].getValue()));
1114 Assert.assertEquals(u[2], lin.getDerivative(2), 1.0e-15 * FastMath.abs(v[2].getValue()));
1115 Assert.assertEquals(u[3], lin.getDerivative(3), 1.0e-15 * FastMath.abs(v[3].getValue()));
1116
1117 }
1118 }
1119
1120 @Test
1121 public void testSerialization() {
1122 SparseGradient a = SparseGradient.createVariable(0, 1.3);
1123 SparseGradient b = (SparseGradient) UnitTestUtils.serializeAndRecover(a);
1124 Assert.assertEquals(a, b);
1125 }
1126
1127 @Test
1128 public void testZero() {
1129 SparseGradient zero = SparseGradient.createVariable(0, 17.0).getField().getZero();
1130 Assert.assertEquals(0, zero.getFreeParameters());
1131 Assert.assertEquals(0.0, zero.getValue(), 1.0e-15);
1132 Assert.assertEquals(0.0, zero.getDerivative(0), 1.0e-15);
1133 }
1134
1135 @Test
1136 public void testOne() {
1137 SparseGradient one = SparseGradient.createVariable(0, 17.0).getField().getOne();
1138 Assert.assertEquals(0, one.getFreeParameters());
1139 Assert.assertEquals(1.0, one.getValue(), 1.0e-15);
1140 Assert.assertEquals(0.0, one.getDerivative(0), 1.0e-15);
1141 }
1142
1143 @Test
1144 public void testMap() {
1145 List<int[]> pairs = new ArrayList<>();
1146 for (int parameters = 1; parameters < 5; ++parameters) {
1147 for (int order = 0; order < 3; ++order) {
1148 pairs.add(new int[] { parameters, order });
1149 }
1150 }
1151 Map<Field<?>, Integer> map = new HashMap<>();
1152 for (int i = 0; i < 1000; ++i) {
1153 map.put(SparseGradient.createVariable(i, 17.0).getField(), 0);
1154 }
1155
1156 Assert.assertEquals(1, map.size());
1157 @SuppressWarnings("unchecked")
1158 Field<SparseGradient> first = (Field<SparseGradient>) map.entrySet().iterator().next().getKey();
1159 Assert.assertTrue(first.equals(first));
1160 Assert.assertFalse(first.equals(new DSFactory(1, 1).constant(0.0).getField()));
1161
1162 }
1163
1164 @Test
1165 public void testRunTimeClass() {
1166 Field<SparseGradient> field = SparseGradient.createVariable(5, 17.0).getField();
1167 Assert.assertEquals(SparseGradient.class, field.getRuntimeClass());
1168 }
1169
1170 private void checkF0F1(SparseGradient sg, double value, double...derivatives) {
1171
1172
1173 Assert.assertEquals(value, sg.getValue(), 1.0e-13);
1174
1175
1176 for (int i = 0; i < derivatives.length; ++i) {
1177 Assert.assertEquals(derivatives[i], sg.getDerivative(i), 1.0e-13);
1178 }
1179
1180 }
1181
1182 }