alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (SparseGradientTest.java)

This example Java source code file (SparseGradientTest.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

extendedfieldelementabstracttest, list, override, polynomialfunction, sparsegradient, sparsegradienttest, test, util, well1024a

The SparseGradientTest.java Java example source code

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.math3.analysis.differentiation;

import java.util.Arrays;
import java.util.List;

import org.apache.commons.math3.ExtendedFieldElementAbstractTest;
import org.apache.commons.math3.TestUtils;
import org.apache.commons.math3.analysis.polynomials.PolynomialFunction;
import org.apache.commons.math3.random.Well1024a;
import org.apache.commons.math3.util.FastMath;
import org.junit.Assert;
import org.junit.Test;

public class SparseGradientTest extends ExtendedFieldElementAbstractTest<SparseGradient> {

    @Override
    protected SparseGradient build(final double x) {
        return SparseGradient.createVariable(0, x);
    }

    @Test
    public void testConstant() {
        double c = 1.0;
        SparseGradient grad = SparseGradient.createConstant(c);
        Assert.assertEquals(c, grad.getValue(), 1.0e-15); // returns the value
        Assert.assertEquals(0, grad.numVars(), 1.0e-15); // has no variables
    }

    @Test
    public void testVariable() {
        double v = 1.0;
        int id = 0;
        SparseGradient grad = SparseGradient.createVariable(id, v);
        Assert.assertEquals(v, grad.getValue(), 1.0e-15); // returns the value
        Assert.assertEquals(1, grad.numVars(), 1.0e-15); // has one variable
        Assert.assertEquals(1.0, grad.getDerivative(id), 1.0e-15); // derivative wr.t itself is 1
    }

    @Test
    public void testVarAddition() {
        final double v1 = 1.0;
        final double v2 = 2.0;
        final int id1 = -1;
        final int id2 = 3;
        final SparseGradient var1 = SparseGradient.createVariable(id1, v1);
        final SparseGradient var2 = SparseGradient.createVariable(id2, v2);
        final SparseGradient sum = var1.add(var2);

        Assert.assertEquals(v1 + v2, sum.getValue(), 1.0e-15); // returns the value
        Assert.assertEquals(2, sum.numVars());
        Assert.assertEquals(1.0, sum.getDerivative(id1), 1.0e-15);
        Assert.assertEquals(1.0, sum.getDerivative(id2), 1.0e-15);
    }

    @Test
    public void testSubtraction() {
        final double v1 = 1.0;
        final double v2 = 2.0;
        final int id1 = -1;
        final int id2 = 3;
        final SparseGradient var1 = SparseGradient.createVariable(id1, v1);
        final SparseGradient var2 = SparseGradient.createVariable(id2, v2);
        final SparseGradient sum = var1.subtract(var2);

        Assert.assertEquals(v1 - v2, sum.getValue(), 1.0e-15); // returns the value
        Assert.assertEquals(2, sum.numVars());
        Assert.assertEquals(1.0, sum.getDerivative(id1), 1.0e-15);
        Assert.assertEquals(-1.0, sum.getDerivative(id2), 1.0e-15);
    }

    @Test
    public void testDivision() {
        final double v1 = 1.0;
        final double v2 = 2.0;
        final int id1 = -1;
        final int id2 = 3;
        final SparseGradient var1 = SparseGradient.createVariable(id1, v1);
        final SparseGradient var2 = SparseGradient.createVariable(id2, v2);
        final SparseGradient out = var1.divide(var2);
        Assert.assertEquals(v1 / v2, out.getValue(), 1.0e-15); // returns the value
        Assert.assertEquals(2, out.numVars());
        Assert.assertEquals(1 / v2, out.getDerivative(id1), 1.0e-15);
        Assert.assertEquals(-1 / (v2 * v2), out.getDerivative(id2), 1.0e-15);
    }

    @Test
    public void testMult() {
        final double v1 = 1.0;
        final double c1 = 0.5;
        final double v2 = 2.0;
        final int id1 = -1;
        final int id2 = 3;
        final SparseGradient var1 = SparseGradient.createVariable(id1, v1);
        final SparseGradient unit1 = var1.multiply(c1);
        final SparseGradient unit2 = SparseGradient.createVariable(id2, v2).multiply(var1);
        final SparseGradient sum = unit1.add(unit2);
        Assert.assertEquals(v1 * c1 + v2 * v1, sum.getValue(), 1.0e-15); // returns the value
        Assert.assertEquals(2, sum.numVars());
        Assert.assertEquals(c1 + v2, sum.getDerivative(id1), 1.0e-15);
        Assert.assertEquals(v1, sum.getDerivative(id2), 1.0e-15);
    }

    @Test
    public void testVarMultInPlace() {
        final double v1 = 1.0;
        final double c1 = 0.5;
        final double v2 = 2.0;
        final int id1 = -1;
        final int id2 = 3;
        final SparseGradient var1 = SparseGradient.createVariable(id1, v1);
        final SparseGradient sum = var1.multiply(c1);
        final SparseGradient mult = SparseGradient.createVariable(id2, v2);
        mult.multiplyInPlace(var1);
        sum.addInPlace(mult);
        Assert.assertEquals(v1 * c1 + v2 * v1, sum.getValue(), 1.0e-15); // returns the value
        Assert.assertEquals(2, sum.numVars());
        Assert.assertEquals(c1 + v2, sum.getDerivative(id1), 1.0e-15);
        Assert.assertEquals(v1, sum.getDerivative(id2), 1.0e-15);
    }

    @Test
    public void testPrimitiveAdd() {
        checkF0F1(SparseGradient.createVariable(0, 1.0).add(5), 6.0, 1.0, 0.0, 0.0);
        checkF0F1(SparseGradient.createVariable(1, 2.0).add(5), 7.0, 0.0, 1.0, 0.0);
        checkF0F1(SparseGradient.createVariable(2, 3.0).add(5), 8.0, 0.0, 0.0, 1.0);
    }

    @Test
    public void testAdd() {
        SparseGradient x = SparseGradient.createVariable(0, 1.0);
        SparseGradient y = SparseGradient.createVariable(1, 2.0);
        SparseGradient z = SparseGradient.createVariable(2, 3.0);
        SparseGradient xyz = x.add(y.add(z));
        checkF0F1(xyz, x.getValue() + y.getValue() + z.getValue(), 1.0, 1.0, 1.0);
    }

    @Test
    public void testPrimitiveSubtract() {
        checkF0F1(SparseGradient.createVariable(0, 1.0).subtract(5), -4.0, 1.0, 0.0, 0.0);
        checkF0F1(SparseGradient.createVariable(1, 2.0).subtract(5), -3.0, 0.0, 1.0, 0.0);
        checkF0F1(SparseGradient.createVariable(2, 3.0).subtract(5), -2.0, 0.0, 0.0, 1.0);
    }

    @Test
    public void testSubtract() {
        SparseGradient x = SparseGradient.createVariable(0, 1.0);
        SparseGradient y = SparseGradient.createVariable(1, 2.0);
        SparseGradient z = SparseGradient.createVariable(2, 3.0);
        SparseGradient xyz = x.subtract(y.subtract(z));
        checkF0F1(xyz, x.getValue() - (y.getValue() - z.getValue()), 1.0, -1.0, 1.0);
    }

    @Test
    public void testPrimitiveMultiply() {
        checkF0F1(SparseGradient.createVariable(0, 1.0).multiply(5),  5.0, 5.0, 0.0, 0.0);
        checkF0F1(SparseGradient.createVariable(1, 2.0).multiply(5), 10.0, 0.0, 5.0, 0.0);
        checkF0F1(SparseGradient.createVariable(2, 3.0).multiply(5), 15.0, 0.0, 0.0, 5.0);
    }

    @Test
    public void testMultiply() {
        SparseGradient x = SparseGradient.createVariable(0, 1.0);
        SparseGradient y = SparseGradient.createVariable(1, 2.0);
        SparseGradient z = SparseGradient.createVariable(2, 3.0);
        SparseGradient xyz = x.multiply(y.multiply(z));
        checkF0F1(xyz, 6.0, 6.0, 3.0, 2.0);
    }

    @Test
    public void testNegate() {
        checkF0F1(SparseGradient.createVariable(0, 1.0).negate(), -1.0, -1.0, 0.0, 0.0);
        checkF0F1(SparseGradient.createVariable(1, 2.0).negate(), -2.0, 0.0, -1.0, 0.0);
        checkF0F1(SparseGradient.createVariable(2, 3.0).negate(), -3.0, 0.0, 0.0, -1.0);
    }

    @Test
    public void testReciprocal() {
        for (double x = 0.1; x < 1.2; x += 0.1) {
            SparseGradient r = SparseGradient.createVariable(0, x).reciprocal();
            Assert.assertEquals(1 / x, r.getValue(), 1.0e-15);
            final double expected = -1 / (x * x);
            Assert.assertEquals(expected, r.getDerivative(0), 1.0e-15 * FastMath.abs(expected));
        }
    }

    @Test
    public void testPow() {
        for (int n = 0; n < 10; ++n) {

            SparseGradient x = SparseGradient.createVariable(0, 1.0);
            SparseGradient y = SparseGradient.createVariable(1, 2.0);
            SparseGradient z = SparseGradient.createVariable(2, 3.0);
            List<SparseGradient> list = Arrays.asList(x, y, z,
                                                      x.add(y).add(z),
                                                      x.multiply(y).multiply(z));

            if (n == 0) {
                for (SparseGradient sg : list) {
                    Assert.assertEquals(sg.getField().getOne(), sg.pow(n));
                }
            } else if (n == 1) {
                for (SparseGradient sg : list) {
                    Assert.assertEquals(sg, sg.pow(n));
                }
            } else {
                for (SparseGradient sg : list) {
                    SparseGradient p = sg.getField().getOne();
                    for (int i = 0; i < n; ++i) {
                        p = p.multiply(sg);
                    }
                    Assert.assertEquals(p, sg.pow(n));
                }
            }
        }
    }

    @Test
    public void testPowDoubleDS() {
        for (int maxOrder = 1; maxOrder < 5; ++maxOrder) {

            SparseGradient x = SparseGradient.createVariable(0, 0.1);
            SparseGradient y = SparseGradient.createVariable(1, 0.2);
            SparseGradient z = SparseGradient.createVariable(2, 0.3);
            List<SparseGradient> list = Arrays.asList(x, y, z,
                                                      x.add(y).add(z),
                                                      x.multiply(y).multiply(z));

            for (SparseGradient sg : list) {
                // the special case a = 0 is included here
                for (double a : new double[] { 0.0, 0.1, 1.0, 2.0, 5.0 }) {
                    SparseGradient reference = (a == 0) ?
                                               x.getField().getZero() :
                                               SparseGradient.createConstant(a).pow(sg);
                    SparseGradient result = SparseGradient.pow(a, sg);
                    Assert.assertEquals(reference, result);
                }

            }

            // negative base: -1^x can be evaluated for integers only, so value is sometimes OK, derivatives are always NaN
            SparseGradient negEvenInteger = SparseGradient.pow(-2.0, SparseGradient.createVariable(0, 2.0));
            Assert.assertEquals(4.0, negEvenInteger.getValue(), 1.0e-15);
            Assert.assertTrue(Double.isNaN(negEvenInteger.getDerivative(0)));
            SparseGradient negOddInteger = SparseGradient.pow(-2.0, SparseGradient.createVariable(0, 3.0));
            Assert.assertEquals(-8.0, negOddInteger.getValue(), 1.0e-15);
            Assert.assertTrue(Double.isNaN(negOddInteger.getDerivative(0)));
            SparseGradient negNonInteger = SparseGradient.pow(-2.0, SparseGradient.createVariable(0, 2.001));
            Assert.assertTrue(Double.isNaN(negNonInteger.getValue()));
            Assert.assertTrue(Double.isNaN(negNonInteger.getDerivative(0)));

            SparseGradient zeroNeg = SparseGradient.pow(0.0, SparseGradient.createVariable(0, -1.0));
            Assert.assertTrue(Double.isNaN(zeroNeg.getValue()));
            Assert.assertTrue(Double.isNaN(zeroNeg.getDerivative(0)));
            SparseGradient posNeg = SparseGradient.pow(2.0, SparseGradient.createVariable(0, -2.0));
            Assert.assertEquals(1.0 / 4.0, posNeg.getValue(), 1.0e-15);
            Assert.assertEquals(FastMath.log(2.0) / 4.0, posNeg.getDerivative(0), 1.0e-15);

            // very special case: a = 0 and power = 0
            SparseGradient zeroZero = SparseGradient.pow(0.0, SparseGradient.createVariable(0, 0.0));

            // this should be OK for simple first derivative with one variable only ...
            Assert.assertEquals(1.0, zeroZero.getValue(), 1.0e-15);
            Assert.assertEquals(Double.NEGATIVE_INFINITY, zeroZero.getDerivative(0), 1.0e-15);
            Assert.assertEquals(0.0, zeroZero.getDerivative(1), 1.0e-15);
            Assert.assertEquals(0.0, zeroZero.getDerivative(2), 1.0e-15);

        }

    }

    @Test
    public void testExpression() {
        double epsilon = 2.5e-13;
        for (double x = 0; x < 2; x += 0.2) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            for (double y = 0; y < 2; y += 0.2) {
                SparseGradient sgY = SparseGradient.createVariable(1, y);
                for (double z = 0; z >- 2; z -= 0.2) {
                    SparseGradient sgZ = SparseGradient.createVariable(2, z);

                    // f(x, y, z) = x + 5 x y - 2 z + (8 z x - y)^3
                    SparseGradient sg =
                            sgZ.linearCombination(1, sgX,
                                                  5, sgX.multiply(sgY),
                                                 -2, sgZ,
                                                 1, sgZ.linearCombination(8, sgZ.multiply(sgX), -1, sgY).pow(3));
                    double f = x + 5 * x * y - 2 * z + FastMath.pow(8 * z * x - y, 3);
                    Assert.assertEquals(f, sg.getValue(), FastMath.abs(epsilon * f));

                    // df/dx = 1 + 5 y + 24 (8 z x - y)^2 z
                    double dfdx = 1 + 5 * y + 24 * z * FastMath.pow(8 * z * x - y, 2);
                    Assert.assertEquals(dfdx, sg.getDerivative(0), FastMath.abs(epsilon * dfdx));

                }

            }
        }
    }

    @Test
    public void testCompositionOneVariableX() {
        double epsilon = 1.0e-13;
        for (double x = 0.1; x < 1.2; x += 0.1) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            for (double y = 0.1; y < 1.2; y += 0.1) {
                SparseGradient sgY = SparseGradient.createConstant(y);
                SparseGradient f = sgX.divide(sgY).sqrt();
                double f0 = FastMath.sqrt(x / y);
                Assert.assertEquals(f0, f.getValue(), FastMath.abs(epsilon * f0));
                double f1 = 1 / (2 * FastMath.sqrt(x * y));
                Assert.assertEquals(f1, f.getDerivative(0), FastMath.abs(epsilon * f1));
            }
        }
    }

    @Test
    public void testTrigo() {
        double epsilon = 2.0e-12;
            for (double x = 0.1; x < 1.2; x += 0.1) {
                SparseGradient sgX = SparseGradient.createVariable(0, x);
                for (double y = 0.1; y < 1.2; y += 0.1) {
                    SparseGradient sgY = SparseGradient.createVariable(1, y);
                    for (double z = 0.1; z < 1.2; z += 0.1) {
                        SparseGradient sgZ = SparseGradient.createVariable(2, z);
                        SparseGradient f = sgX.divide(sgY.cos().add(sgZ.tan())).sin();
                        double a = FastMath.cos(y) + FastMath.tan(z);
                        double f0 = FastMath.sin(x / a);
                        Assert.assertEquals(f0, f.getValue(), FastMath.abs(epsilon * f0));
                        double dfdx = FastMath.cos(x / a) / a;
                        Assert.assertEquals(dfdx, f.getDerivative(0), FastMath.abs(epsilon * dfdx));
                        double dfdy =  x * FastMath.sin(y) * dfdx / a;
                        Assert.assertEquals(dfdy, f.getDerivative(1), FastMath.abs(epsilon * dfdy));
                        double cz = FastMath.cos(z);
                        double cz2 = cz * cz;
                        double dfdz = -x * dfdx / (a * cz2);
                        Assert.assertEquals(dfdz, f.getDerivative(2), FastMath.abs(epsilon * dfdz));
                    }
                }
            }
    }

    @Test
    public void testSqrtDefinition() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient sqrt1 = sgX.pow(0.5);
            SparseGradient sqrt2 = sgX.sqrt();
            SparseGradient zero = sqrt1.subtract(sqrt2);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testRootNSingularity() {
        for (int n = 2; n < 10; ++n) {
            SparseGradient sgZero = SparseGradient.createVariable(0, 0.0);
            SparseGradient rootN  = sgZero.rootN(n);
            Assert.assertEquals(0.0, rootN.getValue(), 1.0e-5);
            Assert.assertTrue(Double.isInfinite(rootN.getDerivative(0)));
            Assert.assertTrue(rootN.getDerivative(0) > 0);
        }

    }

    @Test
    public void testSqrtPow2() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient rebuiltX = sgX.multiply(sgX).sqrt();
            SparseGradient zero = rebuiltX.subtract(sgX);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testCbrtDefinition() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient cbrt1 = sgX.pow(1.0 / 3.0);
            SparseGradient cbrt2 = sgX.cbrt();
            SparseGradient zero = cbrt1.subtract(cbrt2);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testCbrtPow3() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient rebuiltX = sgX.multiply(sgX.multiply(sgX)).cbrt();
            SparseGradient zero = rebuiltX.subtract(sgX);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testPowReciprocalPow() {
        for (double x = 0.1; x < 1.2; x += 0.01) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            for (double y = 0.1; y < 1.2; y += 0.01) {
                SparseGradient sgY = SparseGradient.createVariable(1, y);
                SparseGradient rebuiltX = sgX.pow(sgY).pow(sgY.reciprocal());
                SparseGradient zero = rebuiltX.subtract(sgX);
                checkF0F1(zero, 0.0, 0.0, 0.0);
            }
        }
    }

    @Test
    public void testHypotDefinition() {
        for (double x = -1.7; x < 2; x += 0.2) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            for (double y = -1.7; y < 2; y += 0.2) {
                SparseGradient sgY = SparseGradient.createVariable(1, y);
                SparseGradient hypot = SparseGradient.hypot(sgY, sgX);
                SparseGradient ref = sgX.multiply(sgX).add(sgY.multiply(sgY)).sqrt();
                SparseGradient zero = hypot.subtract(ref);
                checkF0F1(zero, 0.0, 0.0, 0.0);

            }
        }
    }

    @Test
    public void testHypotNoOverflow() {

        SparseGradient sgX = SparseGradient.createVariable(0, +3.0e250);
        SparseGradient sgY = SparseGradient.createVariable(1, -4.0e250);
        SparseGradient hypot = SparseGradient.hypot(sgX, sgY);
        Assert.assertEquals(5.0e250, hypot.getValue(), 1.0e235);
        Assert.assertEquals(sgX.getValue() / hypot.getValue(), hypot.getDerivative(0), 1.0e-10);
        Assert.assertEquals(sgY.getValue() / hypot.getValue(), hypot.getDerivative(1), 1.0e-10);

        SparseGradient sqrt  = sgX.multiply(sgX).add(sgY.multiply(sgY)).sqrt();
        Assert.assertTrue(Double.isInfinite(sqrt.getValue()));

    }

    @Test
    public void testHypotNeglectible() {

        SparseGradient sgSmall = SparseGradient.createVariable(0, +3.0e-10);
        SparseGradient sgLarge = SparseGradient.createVariable(1, -4.0e25);

        Assert.assertEquals(sgLarge.abs().getValue(),
                            SparseGradient.hypot(sgSmall, sgLarge).getValue(),
                            1.0e-10);
        Assert.assertEquals(0,
                            SparseGradient.hypot(sgSmall, sgLarge).getDerivative(0),
                            1.0e-10);
        Assert.assertEquals(-1,
                            SparseGradient.hypot(sgSmall, sgLarge).getDerivative(1),
                            1.0e-10);

        Assert.assertEquals(sgLarge.abs().getValue(),
                            SparseGradient.hypot(sgLarge, sgSmall).getValue(),
                            1.0e-10);
        Assert.assertEquals(0,
                            SparseGradient.hypot(sgLarge, sgSmall).getDerivative(0),
                            1.0e-10);
        Assert.assertEquals(-1,
                            SparseGradient.hypot(sgLarge, sgSmall).getDerivative(1),
                            1.0e-10);

    }

    @Test
    public void testHypotSpecial() {
        Assert.assertTrue(Double.isNaN(SparseGradient.hypot(SparseGradient.createVariable(0, Double.NaN),
                                                                 SparseGradient.createVariable(0, +3.0e250)).getValue()));
        Assert.assertTrue(Double.isNaN(SparseGradient.hypot(SparseGradient.createVariable(0, +3.0e250),
                                                                 SparseGradient.createVariable(0, Double.NaN)).getValue()));
        Assert.assertTrue(Double.isInfinite(SparseGradient.hypot(SparseGradient.createVariable(0, Double.POSITIVE_INFINITY),
                                                                      SparseGradient.createVariable(0, +3.0e250)).getValue()));
        Assert.assertTrue(Double.isInfinite(SparseGradient.hypot(SparseGradient.createVariable(0, +3.0e250),
                                                                      SparseGradient.createVariable(0, Double.POSITIVE_INFINITY)).getValue()));
    }

    @Test
    public void testPrimitiveRemainder() {
        for (double x = -1.7; x < 2; x += 0.2) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            for (double y = -1.7; y < 2; y += 0.2) {
                SparseGradient remainder = sgX.remainder(y);
                SparseGradient ref = sgX.subtract(x - FastMath.IEEEremainder(x, y));
                SparseGradient zero = remainder.subtract(ref);
                checkF0F1(zero, 0.0, 0.0, 0.0);
            }
        }
    }

    @Test
    public void testRemainder() {
        for (double x = -1.7; x < 2; x += 0.2) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            for (double y = -1.7; y < 2; y += 0.2) {
                SparseGradient sgY = SparseGradient.createVariable(1, y);
                SparseGradient remainder = sgX.remainder(sgY);
                SparseGradient ref = sgX.subtract(sgY.multiply((x - FastMath.IEEEremainder(x, y)) / y));
                SparseGradient zero = remainder.subtract(ref);
                checkF0F1(zero, 0.0, 0.0, 0.0);
            }
        }
    }

    @Override
    @Test
    public void testExp() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            double refExp = FastMath.exp(x);
            checkF0F1(SparseGradient.createVariable(0, x).exp(), refExp, refExp);
        }
    }

    @Test
    public void testExpm1Definition() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient expm11 = sgX.expm1();
            SparseGradient expm12 = sgX.exp().subtract(sgX.getField().getOne());
            SparseGradient zero = expm11.subtract(expm12);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Override
    @Test
    public void testLog() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            checkF0F1(SparseGradient.createVariable(0, x).log(), FastMath.log(x), 1.0 / x);
        }
    }

    @Test
    public void testLog1pDefinition() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient log1p1 = sgX.log1p();
            SparseGradient log1p2 = sgX.add(sgX.getField().getOne()).log();
            SparseGradient zero = log1p1.subtract(log1p2);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testLog10Definition() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient log101 = sgX.log10();
            SparseGradient log102 = sgX.log().divide(FastMath.log(10.0));
            SparseGradient zero = log101.subtract(log102);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testLogExp() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient rebuiltX = sgX.exp().log();
            SparseGradient zero = rebuiltX.subtract(sgX);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testLog1pExpm1() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient rebuiltX = sgX.expm1().log1p();
            SparseGradient zero = rebuiltX.subtract(sgX);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testLog10Power() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient rebuiltX = SparseGradient.pow(10.0, sgX).log10();
            SparseGradient zero = rebuiltX.subtract(sgX);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testSinCos() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient sin = sgX.sin();
            SparseGradient cos = sgX.cos();
            double s = FastMath.sin(x);
            double c = FastMath.cos(x);
            checkF0F1(sin, s, c);
            checkF0F1(cos, c, -s);
        }
    }

    @Test
    public void testSinAsin() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient rebuiltX = sgX.sin().asin();
            SparseGradient zero = rebuiltX.subtract(sgX);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testCosAcos() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient rebuiltX = sgX.cos().acos();
            SparseGradient zero = rebuiltX.subtract(sgX);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testTanAtan() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient rebuiltX = sgX.tan().atan();
            SparseGradient zero = rebuiltX.subtract(sgX);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testTangentDefinition() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient tan1 = sgX.sin().divide(sgX.cos());
            SparseGradient tan2 = sgX.tan();
            SparseGradient zero = tan1.subtract(tan2);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Override
    @Test
    public void testAtan2() {
        for (double x = -1.7; x < 2; x += 0.2) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            for (double y = -1.7; y < 2; y += 0.2) {
                SparseGradient sgY = SparseGradient.createVariable(1, y);
                SparseGradient atan2 = SparseGradient.atan2(sgY, sgX);
                SparseGradient ref = sgY.divide(sgX).atan();
                if (x < 0) {
                    ref = (y < 0) ? ref.subtract(FastMath.PI) : ref.add(FastMath.PI);
                }
                SparseGradient zero = atan2.subtract(ref);
                checkF0F1(zero, 0.0, 0.0);
            }
        }
    }

    @Test
    public void testAtan2SpecialCases() {

        SparseGradient pp =
                SparseGradient.atan2(SparseGradient.createVariable(1, +0.0),
                                          SparseGradient.createVariable(1, +0.0));
        Assert.assertEquals(0, pp.getValue(), 1.0e-15);
        Assert.assertEquals(+1, FastMath.copySign(1, pp.getValue()), 1.0e-15);

        SparseGradient pn =
                SparseGradient.atan2(SparseGradient.createVariable(1, +0.0),
                                          SparseGradient.createVariable(1, -0.0));
        Assert.assertEquals(FastMath.PI, pn.getValue(), 1.0e-15);

        SparseGradient np =
                SparseGradient.atan2(SparseGradient.createVariable(1, -0.0),
                                          SparseGradient.createVariable(1, +0.0));
        Assert.assertEquals(0, np.getValue(), 1.0e-15);
        Assert.assertEquals(-1, FastMath.copySign(1, np.getValue()), 1.0e-15);

        SparseGradient nn =
                SparseGradient.atan2(SparseGradient.createVariable(1, -0.0),
                                          SparseGradient.createVariable(1, -0.0));
        Assert.assertEquals(-FastMath.PI, nn.getValue(), 1.0e-15);

    }

    @Test
    public void testSinhDefinition() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient sinh1 = sgX.exp().subtract(sgX.exp().reciprocal()).multiply(0.5);
            SparseGradient sinh2 = sgX.sinh();
            SparseGradient zero = sinh1.subtract(sinh2);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testCoshDefinition() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient cosh1 = sgX.exp().add(sgX.exp().reciprocal()).multiply(0.5);
            SparseGradient cosh2 = sgX.cosh();
            SparseGradient zero = cosh1.subtract(cosh2);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testTanhDefinition() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient tanh1 = sgX.exp().subtract(sgX.exp().reciprocal()).divide(sgX.exp().add(sgX.exp().reciprocal()));
            SparseGradient tanh2 = sgX.tanh();
            SparseGradient zero = tanh1.subtract(tanh2);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testSinhAsinh() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient rebuiltX = sgX.sinh().asinh();
            SparseGradient zero = rebuiltX.subtract(sgX);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testCoshAcosh() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient rebuiltX = sgX.cosh().acosh();
            SparseGradient zero = rebuiltX.subtract(sgX);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testTanhAtanh() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient rebuiltX = sgX.tanh().atanh();
            SparseGradient zero = rebuiltX.subtract(sgX);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testCompositionOneVariableY() {
        for (double x = 0.1; x < 1.2; x += 0.1) {
            SparseGradient sgX = SparseGradient.createConstant(x);
            for (double y = 0.1; y < 1.2; y += 0.1) {
                SparseGradient sgY = SparseGradient.createVariable(0, y);
                SparseGradient f = sgX.divide(sgY).sqrt();
                double f0 = FastMath.sqrt(x / y);
                double f1 = -x / (2 * y * y * f0);
                checkF0F1(f, f0, f1);
            }
        }
    }

    @Test
    public void testTaylorPolynomial() {
        for (double x = 0; x < 1.2; x += 0.1) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            for (double y = 0; y < 1.2; y += 0.2) {
                SparseGradient sgY = SparseGradient.createVariable(1, y);
                for (double z = 0; z < 1.2; z += 0.2) {
                    SparseGradient sgZ = SparseGradient.createVariable(2, z);
                    SparseGradient f = sgX.multiply(3).add(sgZ.multiply(-2)).add(sgY.multiply(5));
                    for (double dx = -0.2; dx < 0.2; dx += 0.2) {
                        for (double dy = -0.2; dy < 0.2; dy += 0.1) {
                            for (double dz = -0.2; dz < 0.2; dz += 0.1) {
                                double ref = 3 * (x + dx) + 5 * (y + dy) -2 * (z + dz);
                                Assert.assertEquals(ref, f.taylor(dx, dy, dz), 3.0e-15);
                            }
                        }
                    }
                }
            }
        }
    }

    @Test
    public void testTaylorAtan2() {
        double x0 =  0.1;
        double y0 = -0.3;
            SparseGradient sgX   = SparseGradient.createVariable(0, x0);
            SparseGradient sgY   = SparseGradient.createVariable(1, y0);
            SparseGradient atan2 = SparseGradient.atan2(sgY, sgX);
            double maxError = 0;
            for (double dx = -0.05; dx < 0.05; dx += 0.001) {
                for (double dy = -0.05; dy < 0.05; dy += 0.001) {
                    double ref = FastMath.atan2(y0 + dy, x0 + dx);
                    maxError = FastMath.max(maxError, FastMath.abs(ref - atan2.taylor(dx, dy)));
                }
            }
            double expectedError = 0.0241;
            Assert.assertEquals(expectedError, maxError, 0.01 * expectedError);
    }

    @Override
    @Test
    public void testAbs() {

        SparseGradient minusOne = SparseGradient.createVariable(0, -1.0);
        Assert.assertEquals(+1.0, minusOne.abs().getValue(), 1.0e-15);
        Assert.assertEquals(-1.0, minusOne.abs().getDerivative(0), 1.0e-15);

        SparseGradient plusOne = SparseGradient.createVariable(0, +1.0);
        Assert.assertEquals(+1.0, plusOne.abs().getValue(), 1.0e-15);
        Assert.assertEquals(+1.0, plusOne.abs().getDerivative(0), 1.0e-15);

        SparseGradient minusZero = SparseGradient.createVariable(0, -0.0);
        Assert.assertEquals(+0.0, minusZero.abs().getValue(), 1.0e-15);
        Assert.assertEquals(-1.0, minusZero.abs().getDerivative(0), 1.0e-15);

        SparseGradient plusZero = SparseGradient.createVariable(0, +0.0);
        Assert.assertEquals(+0.0, plusZero.abs().getValue(), 1.0e-15);
        Assert.assertEquals(+1.0, plusZero.abs().getDerivative(0), 1.0e-15);

    }

    @Override
    @Test
    public void testSignum() {

        SparseGradient minusOne = SparseGradient.createVariable(0, -1.0);
        Assert.assertEquals(-1.0, minusOne.signum().getValue(), 1.0e-15);
        Assert.assertEquals( 0.0, minusOne.signum().getDerivative(0), 1.0e-15);

        SparseGradient plusOne = SparseGradient.createVariable(0, +1.0);
        Assert.assertEquals(+1.0, plusOne.signum().getValue(), 1.0e-15);
        Assert.assertEquals( 0.0, plusOne.signum().getDerivative(0), 1.0e-15);

        SparseGradient minusZero = SparseGradient.createVariable(0, -0.0);
        Assert.assertEquals(-0.0, minusZero.signum().getValue(), 1.0e-15);
        Assert.assertTrue(Double.doubleToLongBits(minusZero.signum().getValue()) < 0);
        Assert.assertEquals( 0.0, minusZero.signum().getDerivative(0), 1.0e-15);

        SparseGradient plusZero = SparseGradient.createVariable(0, +0.0);
        Assert.assertEquals(+0.0, plusZero.signum().getValue(), 1.0e-15);
        Assert.assertTrue(Double.doubleToLongBits(plusZero.signum().getValue()) == 0);
        Assert.assertEquals( 0.0, plusZero.signum().getDerivative(0), 1.0e-15);

    }

    @Test
    public void testCeilFloorRintLong() {

        SparseGradient x = SparseGradient.createVariable(0, -1.5);
        Assert.assertEquals(-1.5, x.getValue(), 1.0e-15);
        Assert.assertEquals(+1.0, x.getDerivative(0), 1.0e-15);
        Assert.assertEquals(-1.0, x.ceil().getValue(), 1.0e-15);
        Assert.assertEquals(+0.0, x.ceil().getDerivative(0), 1.0e-15);
        Assert.assertEquals(-2.0, x.floor().getValue(), 1.0e-15);
        Assert.assertEquals(+0.0, x.floor().getDerivative(0), 1.0e-15);
        Assert.assertEquals(-2.0, x.rint().getValue(), 1.0e-15);
        Assert.assertEquals(+0.0, x.rint().getDerivative(0), 1.0e-15);
        Assert.assertEquals(-2.0, x.subtract(x.getField().getOne()).rint().getValue(), 1.0e-15);
        Assert.assertEquals(-1l, x.round(), 1.0e-15);

    }

    @Test
    public void testCopySign() {

        SparseGradient minusOne = SparseGradient.createVariable(0, -1.0);
        Assert.assertEquals(+1.0, minusOne.copySign(+1.0).getValue(), 1.0e-15);
        Assert.assertEquals(-1.0, minusOne.copySign(+1.0).getDerivative(0), 1.0e-15);
        Assert.assertEquals(-1.0, minusOne.copySign(-1.0).getValue(), 1.0e-15);
        Assert.assertEquals(+1.0, minusOne.copySign(-1.0).getDerivative(0), 1.0e-15);
        Assert.assertEquals(+1.0, minusOne.copySign(+0.0).getValue(), 1.0e-15);
        Assert.assertEquals(-1.0, minusOne.copySign(+0.0).getDerivative(0), 1.0e-15);
        Assert.assertEquals(-1.0, minusOne.copySign(-0.0).getValue(), 1.0e-15);
        Assert.assertEquals(+1.0, minusOne.copySign(-0.0).getDerivative(0), 1.0e-15);
        Assert.assertEquals(+1.0, minusOne.copySign(Double.NaN).getValue(), 1.0e-15);
        Assert.assertEquals(-1.0, minusOne.copySign(Double.NaN).getDerivative(0), 1.0e-15);

        SparseGradient plusOne = SparseGradient.createVariable(0, +1.0);
        Assert.assertEquals(+1.0, plusOne.copySign(+1.0).getValue(), 1.0e-15);
        Assert.assertEquals(+1.0, plusOne.copySign(+1.0).getDerivative(0), 1.0e-15);
        Assert.assertEquals(-1.0, plusOne.copySign(-1.0).getValue(), 1.0e-15);
        Assert.assertEquals(-1.0, plusOne.copySign(-1.0).getDerivative(0), 1.0e-15);
        Assert.assertEquals(+1.0, plusOne.copySign(+0.0).getValue(), 1.0e-15);
        Assert.assertEquals(+1.0, plusOne.copySign(+0.0).getDerivative(0), 1.0e-15);
        Assert.assertEquals(-1.0, plusOne.copySign(-0.0).getValue(), 1.0e-15);
        Assert.assertEquals(-1.0, plusOne.copySign(-0.0).getDerivative(0), 1.0e-15);
        Assert.assertEquals(+1.0, plusOne.copySign(Double.NaN).getValue(), 1.0e-15);
        Assert.assertEquals(+1.0, plusOne.copySign(Double.NaN).getDerivative(0), 1.0e-15);

    }

    @Test
    public void testToDegreesDefinition() {
        double epsilon = 3.0e-16;
        for (int maxOrder = 0; maxOrder < 6; ++maxOrder) {
            for (double x = 0.1; x < 1.2; x += 0.001) {
                SparseGradient sgX = SparseGradient.createVariable(0, x);
                Assert.assertEquals(FastMath.toDegrees(x), sgX.toDegrees().getValue(), epsilon);
                Assert.assertEquals(180 / FastMath.PI, sgX.toDegrees().getDerivative(0), epsilon);
            }
        }
    }

    @Test
    public void testToRadiansDefinition() {
        double epsilon = 3.0e-16;
        for (int maxOrder = 0; maxOrder < 6; ++maxOrder) {
            for (double x = 0.1; x < 1.2; x += 0.001) {
                SparseGradient sgX = SparseGradient.createVariable(0, x);
                Assert.assertEquals(FastMath.toRadians(x), sgX.toRadians().getValue(), epsilon);
                Assert.assertEquals(FastMath.PI / 180, sgX.toRadians().getDerivative(0), epsilon);
            }
        }
    }

    @Test
    public void testDegRad() {
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient rebuiltX = sgX.toDegrees().toRadians();
            SparseGradient zero = rebuiltX.subtract(sgX);
            checkF0F1(zero, 0, 0);
        }
    }

    @Test
    public void testCompose() {
        PolynomialFunction poly =
                new PolynomialFunction(new double[] { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 });
        for (double x = 0.1; x < 1.2; x += 0.001) {
            SparseGradient sgX = SparseGradient.createVariable(0, x);
            SparseGradient sgY1 = sgX.getField().getZero();
            for (int i = poly.degree(); i >= 0; --i) {
                sgY1 = sgY1.multiply(sgX).add(poly.getCoefficients()[i]);
            }
            SparseGradient sgY2 = sgX.compose(poly.value(x), poly.derivative().value(x));
            SparseGradient zero = sgY1.subtract(sgY2);
            checkF0F1(zero, 0.0, 0.0);
        }
    }

    @Test
    public void testField() {
            SparseGradient x = SparseGradient.createVariable(0, 1.0);
            checkF0F1(x.getField().getZero(), 0.0, 0.0, 0.0, 0.0);
            checkF0F1(x.getField().getOne(), 1.0, 0.0, 0.0, 0.0);
            Assert.assertEquals(SparseGradient.class, x.getField().getRuntimeClass());
    }

    @Test
    public void testLinearCombination1DSDS() {
        final SparseGradient[] a = new SparseGradient[] {
            SparseGradient.createVariable(0, -1321008684645961.0 / 268435456.0),
            SparseGradient.createVariable(1, -5774608829631843.0 / 268435456.0),
            SparseGradient.createVariable(2, -7645843051051357.0 / 8589934592.0)
        };
        final SparseGradient[] b = new SparseGradient[] {
            SparseGradient.createVariable(3, -5712344449280879.0 / 2097152.0),
            SparseGradient.createVariable(4, -4550117129121957.0 / 2097152.0),
            SparseGradient.createVariable(5, 8846951984510141.0 / 131072.0)
        };

        final SparseGradient abSumInline = a[0].linearCombination(a[0], b[0], a[1], b[1], a[2], b[2]);
        final SparseGradient abSumArray = a[0].linearCombination(a, b);

        Assert.assertEquals(abSumInline.getValue(), abSumArray.getValue(), 1.0e-15);
        Assert.assertEquals(-1.8551294182586248737720779899, abSumInline.getValue(), 1.0e-15);
        Assert.assertEquals(b[0].getValue(), abSumInline.getDerivative(0), 1.0e-15);
        Assert.assertEquals(b[1].getValue(), abSumInline.getDerivative(1), 1.0e-15);
        Assert.assertEquals(b[2].getValue(), abSumInline.getDerivative(2), 1.0e-15);
        Assert.assertEquals(a[0].getValue(), abSumInline.getDerivative(3), 1.0e-15);
        Assert.assertEquals(a[1].getValue(), abSumInline.getDerivative(4), 1.0e-15);
        Assert.assertEquals(a[2].getValue(), abSumInline.getDerivative(5), 1.0e-15);

    }

    @Test
    public void testLinearCombination1DoubleDS() {
        final double[] a = new double[] {
            -1321008684645961.0 / 268435456.0,
            -5774608829631843.0 / 268435456.0,
            -7645843051051357.0 / 8589934592.0
        };
        final SparseGradient[] b = new SparseGradient[] {
            SparseGradient.createVariable(0, -5712344449280879.0 / 2097152.0),
            SparseGradient.createVariable(1, -4550117129121957.0 / 2097152.0),
            SparseGradient.createVariable(2, 8846951984510141.0 / 131072.0)
        };

        final SparseGradient abSumInline = b[0].linearCombination(a[0], b[0],
                                                                       a[1], b[1],
                                                                       a[2], b[2]);
        final SparseGradient abSumArray = b[0].linearCombination(a, b);

        Assert.assertEquals(abSumInline.getValue(), abSumArray.getValue(), 1.0e-15);
        Assert.assertEquals(-1.8551294182586248737720779899, abSumInline.getValue(), 1.0e-15);
        Assert.assertEquals(a[0], abSumInline.getDerivative(0), 1.0e-15);
        Assert.assertEquals(a[1], abSumInline.getDerivative(1), 1.0e-15);
        Assert.assertEquals(a[2], abSumInline.getDerivative(2), 1.0e-15);

    }

    @Test
    public void testLinearCombination2DSDS() {
        // we compare accurate versus naive dot product implementations
        // on regular vectors (i.e. not extreme cases like in the previous test)
        Well1024a random = new Well1024a(0xc6af886975069f11l);

        for (int i = 0; i < 10000; ++i) {
            final SparseGradient[] u = new SparseGradient[4];
            final SparseGradient[] v = new SparseGradient[4];
            for (int j = 0; j < u.length; ++j) {
                u[j] = SparseGradient.createVariable(j, 1e17 * random.nextDouble());
                v[j] = SparseGradient.createConstant(1e17 * random.nextDouble());
            }

            SparseGradient lin = u[0].linearCombination(u[0], v[0], u[1], v[1]);
            double ref = u[0].getValue() * v[0].getValue() +
                         u[1].getValue() * v[1].getValue();
            Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
            Assert.assertEquals(v[0].getValue(), lin.getDerivative(0), 1.0e-15 * FastMath.abs(v[0].getValue()));
            Assert.assertEquals(v[1].getValue(), lin.getDerivative(1), 1.0e-15 * FastMath.abs(v[1].getValue()));

            lin = u[0].linearCombination(u[0], v[0], u[1], v[1], u[2], v[2]);
            ref = u[0].getValue() * v[0].getValue() +
                  u[1].getValue() * v[1].getValue() +
                  u[2].getValue() * v[2].getValue();
            Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
            Assert.assertEquals(v[0].getValue(), lin.getDerivative(0), 1.0e-15 * FastMath.abs(v[0].getValue()));
            Assert.assertEquals(v[1].getValue(), lin.getDerivative(1), 1.0e-15 * FastMath.abs(v[1].getValue()));
            Assert.assertEquals(v[2].getValue(), lin.getDerivative(2), 1.0e-15 * FastMath.abs(v[2].getValue()));

            lin = u[0].linearCombination(u[0], v[0], u[1], v[1], u[2], v[2], u[3], v[3]);
            ref = u[0].getValue() * v[0].getValue() +
                  u[1].getValue() * v[1].getValue() +
                  u[2].getValue() * v[2].getValue() +
                  u[3].getValue() * v[3].getValue();
            Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
            Assert.assertEquals(v[0].getValue(), lin.getDerivative(0), 1.0e-15 * FastMath.abs(v[0].getValue()));
            Assert.assertEquals(v[1].getValue(), lin.getDerivative(1), 1.0e-15 * FastMath.abs(v[1].getValue()));
            Assert.assertEquals(v[2].getValue(), lin.getDerivative(2), 1.0e-15 * FastMath.abs(v[2].getValue()));
            Assert.assertEquals(v[3].getValue(), lin.getDerivative(3), 1.0e-15 * FastMath.abs(v[3].getValue()));

        }
    }

    @Test
    public void testLinearCombination2DoubleDS() {
        // we compare accurate versus naive dot product implementations
        // on regular vectors (i.e. not extreme cases like in the previous test)
        Well1024a random = new Well1024a(0xc6af886975069f11l);

        for (int i = 0; i < 10000; ++i) {
            final double[] u = new double[4];
            final SparseGradient[] v = new SparseGradient[4];
            for (int j = 0; j < u.length; ++j) {
                u[j] = 1e17 * random.nextDouble();
                v[j] = SparseGradient.createVariable(j, 1e17 * random.nextDouble());
            }

            SparseGradient lin = v[0].linearCombination(u[0], v[0], u[1], v[1]);
            double ref = u[0] * v[0].getValue() +
                         u[1] * v[1].getValue();
            Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
            Assert.assertEquals(u[0], lin.getDerivative(0), 1.0e-15 * FastMath.abs(v[0].getValue()));
            Assert.assertEquals(u[1], lin.getDerivative(1), 1.0e-15 * FastMath.abs(v[1].getValue()));

            lin = v[0].linearCombination(u[0], v[0], u[1], v[1], u[2], v[2]);
            ref = u[0] * v[0].getValue() +
                  u[1] * v[1].getValue() +
                  u[2] * v[2].getValue();
            Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
            Assert.assertEquals(u[0], lin.getDerivative(0), 1.0e-15 * FastMath.abs(v[0].getValue()));
            Assert.assertEquals(u[1], lin.getDerivative(1), 1.0e-15 * FastMath.abs(v[1].getValue()));
            Assert.assertEquals(u[2], lin.getDerivative(2), 1.0e-15 * FastMath.abs(v[2].getValue()));

            lin = v[0].linearCombination(u[0], v[0], u[1], v[1], u[2], v[2], u[3], v[3]);
            ref = u[0] * v[0].getValue() +
                  u[1] * v[1].getValue() +
                  u[2] * v[2].getValue() +
                  u[3] * v[3].getValue();
            Assert.assertEquals(ref, lin.getValue(), 1.0e-15 * FastMath.abs(ref));
            Assert.assertEquals(u[0], lin.getDerivative(0), 1.0e-15 * FastMath.abs(v[0].getValue()));
            Assert.assertEquals(u[1], lin.getDerivative(1), 1.0e-15 * FastMath.abs(v[1].getValue()));
            Assert.assertEquals(u[2], lin.getDerivative(2), 1.0e-15 * FastMath.abs(v[2].getValue()));
            Assert.assertEquals(u[3], lin.getDerivative(3), 1.0e-15 * FastMath.abs(v[3].getValue()));

        }
    }

    @Test
    public void testSerialization() {
        SparseGradient a = SparseGradient.createVariable(0, 1.3);
        SparseGradient b = (SparseGradient) TestUtils.serializeAndRecover(a);
        Assert.assertEquals(a, b);
    }

    private void checkF0F1(SparseGradient sg, double value, double...derivatives) {

        // check value
        Assert.assertEquals(value, sg.getValue(), 1.0e-13);

        // check first order derivatives
        for (int i = 0; i < derivatives.length; ++i) {
            Assert.assertEquals(derivatives[i], sg.getDerivative(i), 1.0e-13);
        }

    }

}

Other Java examples (source code examples)

Here is a short list of links related to this Java SparseGradientTest.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.