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