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

import java.util.Random;

import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.exception.MathIllegalArgumentException;
import org.apache.commons.math3.exception.NotStrictlyPositiveException;
import org.apache.commons.math3.exception.NumberIsTooLargeException;
import org.apache.commons.math3.util.FastMath;
import org.junit.Assert;
import org.junit.Test;

/**
 * Abstract test for classes implementing the {@link RealTransformer} interface.
 * This abstract test handles the automatic generation of random data of various
 * sizes. For each generated data array, actual values (returned by the
 * transformer to be tested) are compared to expected values, returned by the
 * {@link #transform(double[], TransformType)} (to be implemented by the user:
 * a naive method may be used). Methods are also provided to test that invalid
 * parameters throw the expected exceptions.
 *
 * @since 3.0
 */
public abstract class RealTransformerAbstractTest {

    /** The common seed of all random number generators used in this test. */
    private final static long SEED = 20110119L;

    /**
     * Returns a new instance of the {@link RealTransformer} to be tested.
     *
     * @return a the transformer to be tested
     */
    abstract RealTransformer createRealTransformer();

    /**
     * Returns an invalid data size. Transforms with this data size should
     * trigger a {@link MathIllegalArgumentException}.
     *
     * @param i the index of the invalid data size ({@code 0 <= i <}
     * {@link #getNumberOfInvalidDataSizes()}
     * @return an invalid data size
     */
    abstract int getInvalidDataSize(int i);

    /**
     * Returns the total number of invalid data sizes to be tested. If data
     * array of any
     * size can be handled by the {@link RealTransformer} to be tested, this
     * method should return {@code 0}.
     *
     * @return the total number of invalid data sizes
     */
    abstract int getNumberOfInvalidDataSizes();

    /**
     * Returns the total number of valid data sizes to be tested.
     *
     * @return the total number of valid data sizes
     */
    abstract int getNumberOfValidDataSizes();

    /**
     * Returns the expected relative accuracy for data arrays of size
     * {@code getValidDataSize(i)}.
     *
     * @param i the index of the valid data size
     * @return the expected relative accuracy
     */
    abstract double getRelativeTolerance(int i);

    /**
     * Returns a valid data size. This method allows for data arrays of various
     * sizes to be automatically tested (by allowing multiple values of the
     * specified index).
     *
     * @param i the index of the valid data size ({@code 0 <= i <}
     * {@link #getNumberOfValidDataSizes()}
     * @return a valid data size
     */
    abstract int getValidDataSize(int i);

    /**
     * Returns a function for the accuracy check of
     * {@link RealTransformer#transform(UnivariateFunction, double, double, int, TransformType)}.
     * This function should be valid. In other words, none of the above methods
     * should throw an exception when passed this function.
     *
     * @return a valid function
     */
    abstract UnivariateFunction getValidFunction();

    /**
     * Returns a sampling lower bound for the accuracy check of
     * {@link RealTransformer#transform(UnivariateFunction, double, double, int, TransformType)}.
     * This lower bound should be valid. In other words, none of the above
     * methods should throw an exception when passed this bound.
     *
     * @return a valid lower bound
     */
    abstract double getValidLowerBound();

    /**
     * Returns a sampling upper bound for the accuracy check of
     * {@link RealTransformer#transform(UnivariateFunction, double, double, int, TransformType)}.
     * This upper bound should be valid. In other words, none of the above
     * methods should throw an exception when passed this bound.
     *
     * @return a valid bound
     */
    abstract double getValidUpperBound();

    /**
     * Returns the expected transform of the specified real data array.
     *
     * @param x the real data array to be transformed
     * @param type the type of transform (forward, inverse) to be performed
     * @return the expected transform
     */
    abstract double[] transform(double[] x, TransformType type);

    /*
     * Check of preconditions.
     */

    /**
     * {@link RealTransformer#transform(double[], TransformType)} should throw a
     * {@link MathIllegalArgumentException} if data size is invalid.
     */
    @Test
    public void testTransformRealInvalidDataSize() {
        final TransformType[] type = TransformType.values();
        final RealTransformer transformer = createRealTransformer();
        for (int i = 0; i < getNumberOfInvalidDataSizes(); i++) {
            final int n = getInvalidDataSize(i);
            for (int j = 0; j < type.length; j++) {
                try {
                    transformer.transform(createRealData(n), type[j]);
                    Assert.fail(type[j] + ", " + n);
                } catch (MathIllegalArgumentException e) {
                    // Expected: do nothing
                }
            }
        }
    }

    /**
     * {@link RealTransformer#transform(UnivariateFunction, double, double, int, TransformType)}
     * should throw a {@link MathIllegalArgumentException} if number of samples
     * is invalid.
     */
    @Test
    public void testTransformFunctionInvalidDataSize() {
        final TransformType[] type = TransformType.values();
        final RealTransformer transformer = createRealTransformer();
        final UnivariateFunction f = getValidFunction();
        final double a = getValidLowerBound();
        final double b = getValidUpperBound();
        for (int i = 0; i < getNumberOfInvalidDataSizes(); i++) {
            final int n = getInvalidDataSize(i);
            for (int j = 0; j < type.length; j++) {
                try {
                    transformer.transform(f, a, b, n, type[j]);
                    Assert.fail(type[j] + ", " + n);
                } catch (MathIllegalArgumentException e) {
                    // Expected: do nothing
                }
            }
        }
    }

    /**
     * {@link RealTransformer#transform(UnivariateFunction, double, double, int, TransformType)}
     * should throw a {@link NotStrictlyPositiveException} if number of samples
     * is not strictly positive.
     */
    @Test
    public void testTransformFunctionNotStrictlyPositiveNumberOfSamples() {
        final TransformType[] type = TransformType.values();
        final RealTransformer transformer = createRealTransformer();
        final UnivariateFunction f = getValidFunction();
        final double a = getValidLowerBound();
        final double b = getValidUpperBound();
        for (int i = 0; i < getNumberOfValidDataSizes(); i++) {
            final int n = getValidDataSize(i);
            for (int j = 0; j < type.length; j++) {
                try {
                    transformer.transform(f, a, b, -n, type[j]);
                    Assert.fail(type[j] + ", " + (-n));
                } catch (NotStrictlyPositiveException e) {
                    // Expected: do nothing
                }
            }
        }
    }

    /**
     * {@link RealTransformer#transform(UnivariateFunction, double, double, int, TransformType)}
     * should throw a {@link NumberIsTooLargeException} if sampling bounds are
     * not correctly ordered.
     */
    @Test
    public void testTransformFunctionInvalidBounds() {
        final TransformType[] type = TransformType.values();
        final RealTransformer transformer = createRealTransformer();
        final UnivariateFunction f = getValidFunction();
        final double a = getValidLowerBound();
        final double b = getValidUpperBound();
        for (int i = 0; i < getNumberOfValidDataSizes(); i++) {
            final int n = getValidDataSize(i);
            for (int j = 0; j < type.length; j++) {
                try {
                    transformer.transform(f, b, a, n, type[j]);
                    Assert.fail(type[j] + ", " + b + ", " + a);
                } catch (NumberIsTooLargeException e) {
                    // Expected: do nothing
                }
            }
        }
    }

    /*
     * Accuracy tests of transform of valid data.
     */

    /**
     * Accuracy check of {@link RealTransformer#transform(double[], TransformType)}.
     * For each valid data size returned by
     * {@link #getValidDataSize(int) getValidDataSize(i)},
     * a random data array is generated with
     * {@link #createRealData(int) createRealData(i)}. The actual
     * transform is computed and compared to the expected transform, return by
     * {@link #transform(double[], TransformType)}. Actual and expected values
     * should be equal to within the relative error returned by
     * {@link #getRelativeTolerance(int) getRelativeTolerance(i)}.
     */
    @Test
    public void testTransformReal() {
        final TransformType[] type = TransformType.values();
        for (int i = 0; i < getNumberOfValidDataSizes(); i++) {
            final int n = getValidDataSize(i);
            final double tol = getRelativeTolerance(i);
            for (int j = 0; j < type.length; j++) {
                doTestTransformReal(n, tol, type[j]);
            }
        }
    }

    /**
     * Accuracy check of
     * {@link RealTransformer#transform(UnivariateFunction, double, double, int, TransformType)}.
     * For each valid data size returned by
     * {@link #getValidDataSize(int) getValidDataSize(i)},
     * the {@link UnivariateFunction} returned by {@link #getValidFunction()} is
     * sampled. The actual transform is computed and compared to the expected
     * transform, return by {@link #transform(double[], TransformType)}. Actual
     * and expected values should be equal to within the relative error returned
     * by {@link #getRelativeTolerance(int) getRelativeTolerance(i)}.
     */
    @Test
    public void testTransformFunction() {
        final TransformType[] type = TransformType.values();
        for (int i = 0; i < getNumberOfValidDataSizes(); i++) {
            final int n = getValidDataSize(i);
            final double tol = getRelativeTolerance(i);
            for (int j = 0; j < type.length; j++) {
                doTestTransformFunction(n, tol, type[j]);
            }
        }
    }

    /*
     * Utility methods.
     */

    /**
     * Returns a random array of doubles. Random generator always uses the same
     * seed.
     *
     * @param n the size of the array to be returned
     * @return a random array of specified size
     */
    double[] createRealData(final int n) {
        final Random random = new Random(SEED);
        final double[] data = new double[n];
        for (int i = 0; i < n; i++) {
            data[i] = 2.0 * random.nextDouble() - 1.0;
        }
        return data;
    }

    /*
     * The tests per se.
     */

    private void doTestTransformReal(final int n, final double tol,
        final TransformType type) {
        final RealTransformer transformer = createRealTransformer();
        final double[] x = createRealData(n);
        final double[] expected = transform(x, type);
        final double[] actual = transformer.transform(x, type);
        for (int i = 0; i < n; i++) {
            final String msg = String.format("%d, %d", n, i);
            final double delta = tol * FastMath.abs(expected[i]);
            Assert.assertEquals(msg, expected[i], actual[i], delta);
        }
    }

    private void doTestTransformFunction(final int n, final double tol,
        final TransformType type) {
        final RealTransformer transformer = createRealTransformer();
        final UnivariateFunction f = getValidFunction();
        final double a = getValidLowerBound();
        final double b = getValidUpperBound();
        final double[] x = createRealData(n);
        for (int i = 0; i < n; i++) {
            final double t = a + i * (b - a) / n;
            x[i] = f.value(t);
        }
        final double[] expected = transform(x, type);
        final double[] actual = transformer.transform(f, a, b, n, type);
        for (int i = 0; i < n; i++) {
            final String msg = String.format("%d, %d", n, i);
            final double delta = tol * FastMath.abs(expected[i]);
            Assert.assertEquals(msg, expected[i], actual[i], delta);
        }
    }
}
