/*
 * 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.sis.referencing.operation.transform;

import org.opengis.referencing.operation.MathTransform1D;
import org.opengis.referencing.operation.TransformException;
import static java.lang.StrictMath.*;

// Test imports
import org.junit.Test;
import org.apache.sis.test.DependsOn;
import org.apache.sis.test.DependsOnMethod;
import static org.apache.sis.test.ReferencingAssert.*;


/**
 * Tests the {@link LogarithmicTransform1D} class. Note that this is closely related to
 * {@link ExponentialTransform1DTest}, since one transform is the inverse of the other.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.6
 * @since   0.5
 * @module
 */
@DependsOn(ExponentialTransform1DTest.class)
public final strictfp class LogarithmicTransform1DTest extends MathTransformTestCase {
    /**
     * Arbitrary parameter of the logarithmic transform to be tested.
     */
    private static final double OFFSET = 1.5;

    /**
     * Arbitrary coefficients of a linear transform to be concatenated to the exponential transform.
     */
    private static final double C0 = 0.75, C1 = 0.25;

    /**
     * Creates a new test case.
     */
    public LogarithmicTransform1DTest() {
        tolerance         = 1E-5; // Tolerance is much smaller on other branches.
//      toleranceModifier = ToleranceModifier.RELATIVE; // Not available on GeoAPI 3.0.
    }

    /**
     * Tests the current transform using random values as input points, and
     * comparing with the expected values computed using the given coefficients.
     *
     * The {@link #transform} field must be set before to invoke this method.
     *
     * @param  expectedType  the expected base type of the math transform.
     * @param  base          the exponent base given to the {@link LogarithmicTransform1D} constructor.
     * @param  offset        the offset given to the {@link LogarithmicTransform1D} constructor.
     * @param  preAffine     {@code true} for applying an additional affine transform before the transform.
     * @param  postAffine    {@code true} for applying an additional affine transform after the transform.
     */
    private void run(final Class<? extends MathTransform1D> expectedType, final double base, final double offset,
            final boolean preAffine, final boolean postAffine) throws TransformException
    {
        assertInstanceOf("Expected the use of mathematical identities.", expectedType, transform);
        assertIsNotIdentity(transform);
        validate();

        final double[] values = generateRandomCoordinates(CoordinateDomain.RANGE_10, 0);
        final double[] expected = new double[values.length];
        final double lnBase = log(base);
        for (int i=0; i<values.length; i++) {
            double value = abs(values[i]) + 0.001;                      // Makes the values valid for logarithms.
            values[i] = value;
            if (preAffine) {
                value = C0 + C1*value;
            }
            value = log(value) / lnBase + offset;
            if (postAffine) {
                value = C0 + C1*value;
            }
            expected[i] = value;
        }
        verifyTransform(values, expected);
    }

    /**
     * Implementation of {@link #testSingle()} and {@link #testSingleWithOffset()} for the given base.
     */
    private void testSingle(final double base, final double offset,
            final Class<? extends MathTransform1D> expectedType) throws TransformException
    {
        transform = LogarithmicTransform1D.create(base, offset);
        run(expectedType, base, offset, false, false);
    }

    /**
     * Implementation of {@link #testAffinePreConcatenation()} for the given base.
     */
    private void testAffinePreConcatenation(final double base) throws TransformException {
        transform = MathTransforms.concatenate(LinearTransform1D.create(C1, C0),
                LogarithmicTransform1D.create(base, OFFSET));
        run(ConcatenatedTransformDirect1D.class, base, OFFSET, true, false);
    }

    /**
     * Implementation of {@link #testAffinePostConcatenation()} for the given base.
     */
    private void testAffinePostConcatenation(final double base) throws TransformException {
        transform = MathTransforms.concatenate(LogarithmicTransform1D.create(base, OFFSET),
                LinearTransform1D.create(C1, C0));
        run(ConcatenatedTransformDirect1D.class, base, OFFSET, false, true);
    }

    /**
     * Implementation of {@link #testAffineConcatenations()} for the given base.
     */
    private void testAffineConcatenations(final double base) throws TransformException {
        final MathTransform1D linear = LinearTransform1D.create(C1, C0);
        transform = MathTransforms.concatenate(linear, LogarithmicTransform1D.create(base, OFFSET), linear);
        run(ConcatenatedTransformDirect1D.class, base, OFFSET, true, true);
    }

    /**
     * A single (non-concatenated) test case without offset.
     *
     * @throws TransformException should never happen.
     */
    @Test
    public void testSingle() throws TransformException {
        testSingle( 10, 0, LogarithmicTransform1D.class);         // Logarithmic transform in base 10
        testSingle(  E, 0, LogarithmicTransform1D.class);         // Logarithmic transform in base E
        testSingle(8.4, 0, ConcatenatedTransformDirect1D.class);  // Logarithmic transform in base 8.4 (arbitrary base)
    }

    /**
     * A single (non-concatenated) test case with an offset.
     *
     * @throws TransformException should never happen.
     */
    @Test
    @DependsOnMethod("testSingle")
    public void testSingleWithOffset() throws TransformException {
        testSingle( 10, 0.25, LogarithmicTransform1D.class);         // Logarithmic transform in base 10
        testSingle(  E, 0.25, ConcatenatedTransformDirect1D.class);  // Logarithmic transform in base E
        testSingle(8.4, 0.25, ConcatenatedTransformDirect1D.class);  // Logarithmic transform in base 8.4 (arbitrary base)
    }

    /**
     * Tests the concatenation of a linear operation before the logarithmic one.
     *
     * @throws TransformException should never happen.
     */
    @Test
    @DependsOnMethod("testSingleWithOffset")
    public void testAffinePreConcatenation() throws TransformException {
        testAffinePreConcatenation(10);   // Affine + logarithmic transform in base 10
        testAffinePreConcatenation(E);    // Affine + logarithmic transform in base E
        testAffinePreConcatenation(8.4);  // Affine + logarithmic transform in base 8.4 (arbitrary base)
    }

    /**
     * Tests the concatenation of a linear operation after the logarithmic one.
     *
     * @throws TransformException should never happen.
     */
    @Test
    @DependsOnMethod("testSingleWithOffset")
    public void testAffinePostConcatenation() throws TransformException {
        testAffinePostConcatenation(10);    // Logarithmic transform in base 10  + affine
        testAffinePostConcatenation(E);     // Logarithmic transform in base E   + affine
        testAffinePostConcatenation(8.4);   // Logarithmic transform in base 8.4 + affine (arbitrary base)
    }

    /**
     * Tests the concatenation of a linear operation before and after the logarithmic one.
     *
     * @throws TransformException should never happen.
     */
    @Test
    @DependsOnMethod({
        "testAffinePreConcatenation",
        "testAffinePostConcatenation"
    })
    public void testAffineConcatenations() throws TransformException {
        testAffineConcatenations(10);   // Affine + logarithmic transform in base 10  + affine
        testAffineConcatenations(E);    // Affine + logarithmic transform in base E   + affine
        testAffineConcatenations(8.4);  // Affine + logarithmic transform in base 8.4 + affine
    }

    /**
     * Tests the concatenation of a logarithmic operation with the exponential one.
     *
     * @throws TransformException should never happen.
     */
    @Test
    @DependsOnMethod("testSingleWithOffset")
    public void testLogarithmicConcatenation() throws TransformException {
        transform = MathTransforms.concatenate(
                LogarithmicTransform1D.create(8, C0),
                ExponentialTransform1D.create(10, ExponentialTransform1DTest.SCALE));
        validate();

        final double lnBase = log(8);
        final double[] values = generateRandomCoordinates(CoordinateDomain.RANGE_10, 0);
        final double[] expected = new double[values.length];
        for (int i=0; i<values.length; i++) {
            final double value = abs(values[i]) + 0.001;        // Makes the values valid for logarithms.
            values[i] = value;
            expected[i] = ExponentialTransform1DTest.SCALE * pow(10, log(value) / lnBase + C0);
        }
        verifyTransform(values, expected);
    }
}
