/*
 * 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 java.io.Serializable;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransform1D;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.util.FactoryException;
import org.apache.sis.internal.util.Numerics;
import org.apache.sis.util.ComparisonMode;


/**
 * A one dimensional exponential transform.
 * Input values <var>x</var> are converted into output values <var>y</var> using the following equation:
 *
 * <blockquote><var>y</var> = {@linkplain #scale}⋅{@linkplain #base}<sup><var>x</var></sup></blockquote>
 *
 * <div class="note"><b>Tip:</b>
 * if a linear transform is applied before this exponential transform, then the equation can be rewritten as:
 * <var>scale</var>⋅<var>base</var><sup><var>a</var> + <var>b</var>⋅<var>x</var></sup> =
 * <var>scale</var>⋅<var>base</var><sup><var>a</var></sup>⋅(<var>base</var><sup><var>b</var></sup>)<sup><var>x</var></sup>
 *
 * It is possible to find back the coefficients of the original linear transform by
 * pre-concatenating a logarithmic transform before the exponential one, as below:
 *
 * {@preformat java
 *   LinearTransform1D linear = MathTransforms.create(exponentialTransform,
 *           LogarithmicTransform1D.create(base, -Math.log(scale) / Math.log(base)));
 * }
 * </div>
 *
 * <div class="section">Serialization</div>
 * Serialized instances of this class are not guaranteed to be compatible with future SIS versions.
 * Serialization should be used only for short term storage or RMI between applications running the
 * same SIS version.
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @version 0.5
 * @since   0.5
 * @module
 */
final class ExponentialTransform1D extends AbstractMathTransform1D implements Serializable {
    /**
     * Serial number for inter-operability with different versions.
     */
    private static final long serialVersionUID = 5331178990358868947L;

    /**
     * The base to be raised to a power.
     */
    final double base;

    /**
     * Natural logarithm of {@link #base}, used for {@link #derivative(double)} computation.
     */
    final double lnBase;

    /**
     * The scale value to be multiplied.
     *
     * <div class="note">The scale could be handled by a concatenation with {@link LinearTransform1D} instead than
     * an explicit field in this class. However the <var>scale</var>⋅<var>base</var><sup><var>x</var></sup> formula
     * is extensively used as a <cite>transfer function</cite> in grid coverages. Consequently we keep this explicit
     * field for performance reasons.</div>
     */
    final double scale;

    /**
     * The inverse of this transform. Created only when first needed. Serialized in order to avoid
     * rounding error if this transform is actually the one which was created from the inverse.
     */
    private MathTransform1D inverse;

    /**
     * Constructs a new exponential transform which is the inverse of the supplied logarithmic transform.
     */
    ExponentialTransform1D(final LogarithmicTransform1D inverse) {
        this.base    = inverse.base();
        this.lnBase  = inverse.lnBase();
        this.scale   = inverse.pow(-inverse.offset());
        this.inverse = inverse;
    }

    /**
     * Constructs a new exponential transform. This constructor is provided for subclasses only.
     * Instances should be created using the {@linkplain #create(double, double) factory method},
     * which may returns optimized implementations for some particular argument values.
     *
     * @param base   the base to be raised to a power.
     * @param scale  the scale value to be multiplied.
     */
    protected ExponentialTransform1D(final double base, final double scale) {
        this.base   = base;
        this.scale  = scale;
        this.lnBase = Math.log(base);
    }

    /**
     * Constructs a new exponential transform which include the given scale factor applied after the exponentiation.
     *
     * @param  base   the base to be raised to a power.
     * @param  scale  the scale value to be multiplied.
     * @return the math transform.
     */
    public static MathTransform1D create(final double base, final double scale) {
        if (base == 0 || scale == 0) {
            return ConstantTransform1D.ZERO;
        }
        if (base == 1) {
            return LinearTransform1D.create(scale, 0);
        }
        return new ExponentialTransform1D(base, scale);
    }

    /**
     * Returns the inverse of this transform.
     */
    @Override
    public synchronized MathTransform1D inverse() {
        if (inverse == null) {
            inverse = LogarithmicTransform1D.create(this);
            // Above method will set LogarithmicTransform1D.inverse = this.
        }
        return inverse;
    }

    /**
     * Gets the derivative of this function at a value.
     */
    @Override
    public double derivative(final double value) {
        return lnBase * transform(value);
    }

    /**
     * Transforms the specified value.
     */
    @Override
    public double transform(final double value) {
        return scale * Math.pow(base, value);
    }

    /**
     * Transforms many coordinates in a list of ordinal values.
     */
    @Override
    public void transform(final double[] srcPts, int srcOff, final double[] dstPts, int dstOff, int numPts) {
        if (srcPts != dstPts || srcOff >= dstOff) {
            while (--numPts >= 0) {
                dstPts[dstOff++] = scale * Math.pow(base, srcPts[srcOff++]);
            }
        } else {
            srcOff += numPts;
            dstOff += numPts;
            while (--numPts >= 0) {
                dstPts[--dstOff] = scale * Math.pow(base, srcPts[--srcOff]);
            }
        }
    }

    /**
     * Transforms many coordinates in a list of ordinal values.
     */
    @Override
    public void transform(final float[] srcPts, int srcOff, final float[] dstPts, int dstOff, int numPts) {
        if (srcPts != dstPts || srcOff >= dstOff) {
            while (--numPts >= 0) {
                dstPts[dstOff++] = (float) (scale * Math.pow(base, srcPts[srcOff++]));
            }
        } else {
            srcOff += numPts;
            dstOff += numPts;
            while (--numPts >= 0) {
                dstPts[--dstOff] = (float) (scale * Math.pow(base, srcPts[--srcOff]));
            }
        }
    }

    /**
     * Transforms many coordinates in a list of ordinal values.
     */
    @Override
    public void transform(final double[] srcPts, int srcOff, final float[] dstPts, int dstOff, int numPts) {
        while (--numPts >= 0) {
            dstPts[dstOff++] = (float) (scale * Math.pow(base, srcPts[srcOff++]));
        }
    }

    /**
     * Transforms many coordinates in a list of ordinal values.
     */
    @Override
    public void transform(final float[] srcPts, int srcOff, final double[] dstPts, int dstOff, int numPts) {
        while (--numPts >= 0) {
            dstPts[dstOff++] = scale * Math.pow(base, srcPts[srcOff++]);
        }
    }

    /**
     * Concatenates in an optimized way a {@link MathTransform} {@code other} to this
     * {@code MathTransform}. This implementation can optimize some concatenation with
     * {@link LinearTransform1D} and {@link LogarithmicTransform1D}.
     *
     * @param  applyOtherFirst  {@code true} if the transformation order is {@code other} followed by {@code this}, or
     *                          {@code false} if the transformation order is {@code this} followed by {@code other}.
     * @param  other            the other math transform to (pre-)concatenate with this transform.
     * @param  factory          the factory which is (indirectly) invoking this method, or {@code null} if none.
     * @return the combined math transform, or {@code null} if no optimized combined transform is available.
     */
    @Override
    protected MathTransform tryConcatenate(final boolean applyOtherFirst, final MathTransform other,
            final MathTransformFactory factory) throws FactoryException
    {
        if (other instanceof LinearTransform) {
            final LinearTransform1D linear = (LinearTransform1D) other;
            if (applyOtherFirst) {
                final double newBase  = Math.pow(base, linear.scale);
                final double newScale = Math.pow(base, linear.offset) * scale;
                if (!Double.isNaN(newBase) && !Double.isNaN(newScale)) {
                    return create(newBase, newScale);
                }
            } else {
                if (linear.offset == 0) {
                    return create(base, scale * linear.scale);
                }
            }
        } else if (other instanceof LogarithmicTransform1D) {
            return concatenateLog((LogarithmicTransform1D) other, applyOtherFirst);
        }
        return super.tryConcatenate(applyOtherFirst, other, factory);
    }

    /**
     * Concatenates in an optimized way a {@link LogarithmicTransform1D} {@code other}
     * to this {@code ExponentialTransform1D}.
     *
     * @param  other            the math transform to apply.
     * @param  applyOtherFirst  {@code true} if the transformation order is {@code other} followed by {@code this}, or
     *                          {@code false} if the transformation order is {@code this} followed by {@code other}.
     * @return the combined math transform, or {@code null} if no optimized combined transform is available.
     */
    final MathTransform concatenateLog(final LogarithmicTransform1D other, final boolean applyOtherFirst) {
        final double newScale = lnBase / other.lnBase();
        if (applyOtherFirst) {
            return MathTransforms.concatenate(PowerTransform1D.create(newScale),
                    LinearTransform1D.create(scale * Math.pow(base, other.offset()), 0));
        } else {
            final double newOffset;
            if (scale > 0) {
                newOffset = other.log(scale) + other.offset();
            } else {
                /*
                 * Maybe the Math.log(double) argument will become
                 * positive if we rewrite the equation that way...
                 */
                newOffset = other.log(scale * other.offset() * other.lnBase());
            }
            if (!Double.isNaN(newOffset)) {
                return LinearTransform1D.create(newScale, newOffset);
            }
        }
        return null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected int computeHashCode() {
        return Long.hashCode(Double.doubleToLongBits(base)
                + 31 * Double.doubleToLongBits(scale)) ^ super.computeHashCode();
    }

    /**
     * Compares the specified object with this math transform for equality.
     */
    @Override
    public boolean equals(final Object object, final ComparisonMode mode) {
        if (object == this) {
            return true;                    // Optimization for a common case.
        }
        if (super.equals(object, mode)) {
            final ExponentialTransform1D that = (ExponentialTransform1D) object;
            return Numerics.equals(this.base,  that.base) &&
                   Numerics.equals(this.scale, that.scale);
        }
        return false;
    }
}
