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

import java.util.Objects;
import java.io.Serializable;
import java.util.function.LongConsumer;
import java.util.function.DoubleConsumer;
import org.opengis.util.InternationalString;
import org.apache.sis.util.iso.SimpleInternationalString;
import org.apache.sis.util.ArgumentChecks;

import static java.lang.Math.*;
import static java.lang.Double.NaN;
import static java.lang.Double.isNaN;
import static java.lang.Double.isFinite;
import static java.lang.Double.doubleToLongBits;


/**
 * Holds some statistics derived from a series of sample values.
 * Given a series of <var>y₀</var>, <var>y₁</var>, <var>y₂</var>, <var>y₃</var>, <i>etc…</i> samples,
 * this class computes the {@linkplain #minimum() minimum}, {@linkplain #maximum() maximum},
 * {@linkplain #mean() mean}, {@linkplain #rms() root mean square} and
 * {@linkplain #standardDeviation(boolean) standard deviation} of the given samples.
 *
 * <p>In addition to the statistics on the sample values, this class can optionally compute
 * statistics on the differences between consecutive sample values, i.e. the statistics on
 * <var>y₁</var>-<var>y₀</var>, <var>y₂</var>-<var>y₁</var>, <var>y₃</var>-<var>y₂</var>, <i>etc…</i>,
 * Those statistics can be fetched by a call to {@link #differences()}.
 * They are useful for verifying if the interval between sample values is approximately constant.</p>
 *
 * <p>If the samples are (at least conceptually) the result of some <var>y</var>=<var>f</var>(<var>x</var>)
 * function for <var>x</var> values increasing or decreasing at a constant interval Δ<var>x</var>,
 * then one can get the statistics on the <cite>discrete derivatives</cite> by a call to
 * <code>differences().{@linkplain #scale(double) scale}(1/Δx)</code>.</p>
 *
 * <p>Statistics are computed on the fly using the
 * <a href="http://en.wikipedia.org/wiki/Kahan_summation_algorithm">Kahan summation algorithm</a>
 * for reducing the numerical errors; the sample values are never stored in memory.</p>
 *
 * <p>An instance of {@code Statistics} is initially empty: the {@linkplain #count() count} of
 * values is set to zero, and all above-cited statistical values are set to {@link Double#NaN NaN}.
 * The statistics are updated every time an {@link #accept(double)} method is invoked with a non-NaN
 * value.</p>
 *
 * <h2>Examples</h2>
 * The following examples assume that a <var>y</var>=<var>f</var>(<var>x</var>) function
 * is defined. A simple usage is:
 *
 * {@preformat java
 *     Statistics stats = new Statistics("y");
 *     for (int i=0; i<numberOfValues; i++) {
 *         stats.accept(f(i));
 *     }
 *     System.out.println(stats);
 * }
 *
 * Following example computes the statistics on the first and second derivatives
 * in addition to the statistics on the sample values:
 *
 * {@preformat java
 *     final double x₀ = ...; // Put here the x value at i=0
 *     final double Δx = ...; // Put here the interval between x values
 *     Statistics stats = Statistics.forSeries("y", "∂y/∂x", "∂²y/∂x²");
 *     for (int i=0; i<numberOfValues; i++) {
 *         stats.accept(f(x₀ + i*Δx));
 *     }
 *     stats.differences().scale(1/Δx);
 *     System.out.println(stats);
 * }
 *
 * @author  Martin Desruisseaux (MPO, IRD, Geomatys)
 * @version 1.0
 * @since   0.3
 * @module
 */
public class Statistics implements DoubleConsumer, LongConsumer, Cloneable, Serializable {
    /**
     * Serial number for compatibility with different versions.
     */
    private static final long serialVersionUID = 8495118253884975477L;

    /**
     * The name of the phenomenon for which this object is collecting statistics.
     * If non-null, then this name will be shown as column header in the table formatted
     * by {@link StatisticsFormat}.
     *
     * @see #name()
     */
    private final InternationalString name;

    /**
     * The minimal value given to the {@link #accept(double)} method.
     */
    private double minimum = NaN;

    /**
     * The maximal value given to the {@link #accept(double)} method.
     */
    private double maximum = NaN;

    /**
     * The sum of all values given to the {@link #accept(double)} method.
     */
    private double sum;

    /**
     * The sum of square of all values given to the {@link #accept(double)} method.
     */
    private double squareSum;

    /**
     * The low-order bits in last update of {@link #sum}.
     * This is used for the Kahan summation algorithm.
     */
    private transient double lowBits;

    /**
     * The low-order bits in last update of {@link #squareSum}.
     * This is used for the Kahan summation algorithm.
     */
    private transient double squareLowBits;

    /**
     * Number of non-NaN values given to the {@link #accept(double)} method.
     */
    private int count;

    /**
     * Number of NaN values given to the {@link #accept(double)} method.
     * Those value are ignored in the computation of all above values.
     */
    private int countNaN;

    /**
     * Constructs an initially empty set of statistics.
     * The {@linkplain #count()} and the {@link #sum()} are initialized to zero
     * and all other statistical values are initialized to {@link Double#NaN}.
     *
     * <p>Instances created by this constructor do not compute differences between sample values.
     * If differences or discrete derivatives are wanted, use the {@link #forSeries forSeries(…)}
     * method instead.</p>
     *
     * @param  name  the phenomenon for which this object is collecting statistics, or {@code null}
     *               if none. If non-null, then this name will be shown as column header in the table
     *               formatted by {@link StatisticsFormat}.
     */
    public Statistics(final CharSequence name) {
        if (name == null || name instanceof InternationalString) {
            this.name = (InternationalString) name;
        } else {
            this.name = new SimpleInternationalString(name.toString());
        }
    }

    /**
     * Constructs a new {@code Statistics} object which will also compute finite differences
     * up to the given order. If the values to be given to the {@code accept(…)} methods are
     * the <var>y</var> values of some <var>y</var>=<var>f</var>(<var>x</var>) function for
     * <var>x</var> values increasing or decreasing at a constant interval Δ<var>x</var>,
     * then the finite differences are proportional to discrete derivatives.
     *
     * <p>The {@code Statistics} object created by this method know nothing about the Δ<var>x</var>
     * interval. In order to get the discrete derivatives, the following method needs to be invoked
     * <em>after</em> all sample values have been added:</p>
     *
     * {@preformat java
     *     statistics.differences().scale(1/Δx);
     * }
     *
     * The maximal "derivative" order is determined by the length of the {@code differenceNames} array:
     *
     * <ul>
     *   <li>0 if no differences are needed (equivalent to direct instantiation of a new
     *       {@code Statistics} object).</li>
     *   <li>1 for computing the statistics on the differences between consecutive samples
     *       (proportional to the statistics on the first discrete derivatives) in addition
     *       to the sample statistics.</li>
     *   <li>2 for computing also the statistics on the differences between consecutive differences
     *       (proportional to the statistics on the second discrete derivatives) in addition to the
     *       above.</li>
     *   <li><i>etc</i>.</li>
     * </ul>
     *
     * @param  name  the phenomenon for which this object is collecting statistics, or {@code null}
     *               if none. If non-null, then this name will be shown as column header in the table
     *               formatted by {@link StatisticsFormat}.
     * @param  differenceNames  the names of the statistics on differences.
     *         The given array can not be null, but can contain null elements.
     * @return the newly constructed, initially empty, set of statistics.
     *
     * @see #differences()
     */
    public static Statistics forSeries(final CharSequence name, final CharSequence... differenceNames) {
        ArgumentChecks.ensureNonNull("differenceNames", differenceNames);
        Statistics stats = null;
        for (int i=differenceNames.length; --i >= -1;) {
            final CharSequence n = (i >= 0) ? differenceNames[i] : name;
            stats = (stats == null) ? new Statistics(n) : new WithDelta(n, stats);
        }
        return stats;
    }

    /**
     * Returns the name of the phenomenon for which this object is collecting statistics.
     * If non-null, then this name will be shown as column header in the table formatted
     * by {@link StatisticsFormat}.
     *
     * @return the phenomenon for which this object is collecting statistics, or {@code null} if none.
     */
    public InternationalString name() {
        return name;
    }

    /**
     * Resets this object state as if it was just created.
     * The {@linkplain #count()} and the {@link #sum()} are set to zero
     * and all other statistical values are set to {@link Double#NaN}.
     */
    public void reset() {
        minimum       = NaN;
        maximum       = NaN;
        sum           = 0;
        squareSum     = 0;
        lowBits       = 0;
        squareLowBits = 0;
        count         = 0;
        countNaN      = 0;
    }

    /**
     * Updates statistics for the specified floating-point sample value.
     * {@link Double#NaN NaN} values increment the {@linkplain #countNaN() NaN count},
     * but are otherwise ignored.
     *
     * @param  sample  the sample value (may be NaN).
     *
     * @see #accept(long)
     * @see #combine(Statistics)
     */
    @Override
    public void accept(final double sample) {
        if (isFinite(sample)) {
            real(sample);
        } else if (isNaN(sample)) {
            countNaN++;
        } else {
            real(sample);
            sum = sample;                           // Replace NaN by the infinite value.
            squareSum = Double.POSITIVE_INFINITY;
            squareLowBits = lowBits = 0;
        }
    }

    /**
     * Implementation of {@link #accept(double)} for real (non-NaN) numbers.
     *
     * @see org.apache.sis.internal.util.DoubleDouble#addKahan(double)
     */
    private void real(double sample) {
        /*
         * Two next lines use !(a >= b) instead than
         * (a < b) in order to take NaN in account.
         */
        if (!(minimum <= sample)) minimum = sample;
        if (!(maximum >= sample)) maximum = sample;
        /*
         * According algebraic laws, 'lowBits' should always been zero. But it is
         * not when using floating points with limited precision. Do not simplify!
         */
        double y = sample + lowBits;
        lowBits = y + (sum - (sum += y));

        sample *= sample;
        y = sample + squareLowBits;
        squareLowBits = y + (squareSum - (squareSum += y));

        count++;
    }

    /**
     * Updates statistics for the specified integer sample value.
     * For very large integer values (greater than 2<sup>52</sup> in magnitude),
     * this method may be more accurate than the {@link #accept(double)} version.
     *
     * @param  sample  the sample value.
     *
     * @see #accept(double)
     * @see #combine(Statistics)
     */
    @Override
    public void accept(long sample) {
        double y = sample;
        real(y);
        sample -= (long) y;
        if (sample != 0) {
            y = sample + lowBits;
            lowBits = y + (sum - (sum += y));
        }
    }

    /**
     * Updates statistics with all samples from the specified {@code stats}.
     * Invoking this method is equivalent (except for rounding errors) to invoking
     * {@link #accept(double) accept(…)} for all samples that were added to {@code stats}.
     *
     * @param  stats  the statistics to be added to {@code this}.
     */
    public void combine(final Statistics stats) {
        ArgumentChecks.ensureNonNull("stats", stats);

        // "if (a < b)" is equivalent to "if (!isNaN(a) && a < b)".
        if (isNaN(minimum) || stats.minimum < minimum) minimum = stats.minimum;
        if (isNaN(maximum) || stats.maximum > maximum) maximum = stats.maximum;

        double y = stats.sum + lowBits;
        lowBits = y + (sum - (sum += y)) + stats.lowBits;

        y = stats.squareSum + squareLowBits;
        squareLowBits = y + (squareSum - (squareSum += y)) + stats.squareLowBits;

        count += stats.count;
        countNaN += max(stats.countNaN, 0);
    }

    /**
     * Multiplies the statistics by the given factor. The given scale factory is also applied
     * recursively on the {@linkplain #differences() differences} statistics, if any.
     * Invoking this method transforms the statistics as if every values given to the
     * {@code accept(…)} had been first multiplied by the given factor.
     *
     * <p>This method is useful for computing discrete derivatives from the differences between
     * sample values. See {@link #differences()} or {@link #forSeries forSeries(…)} for more
     * information.</p>
     *
     * @param  factor  the factor by which to multiply the statistics.
     */
    public void scale(double factor) {
        ArgumentChecks.ensureFinite("factor", factor);
        minimum       *= factor;
        maximum       *= factor;
        sum           *= factor;
        lowBits       *= factor;
        factor        *= factor;
        squareSum     *= factor;
        squareLowBits *= factor;
    }

    /**
     * For {@link WithDelta} usage only.
     */
    void decrementCountNaN() {
        countNaN--;
    }

    /**
     * Returns the number of {@link Double#NaN NaN} samples.
     * {@code NaN} samples are ignored in all other statistical computation.
     * This method count them for information purpose only.
     *
     * @return the number of NaN values.
     */
    public int countNaN() {
        return max(countNaN, 0);                // The Delta subclass initializes countNaN to -1.
    }

    /**
     * Returns the number of samples, excluding {@link Double#NaN NaN} values.
     *
     * @return the number of sample values, excluding NaN.
     */
    public int count() {
        return count;
    }

    /**
     * Returns the minimum sample value, or {@link Double#NaN NaN} if none.
     *
     * @return the minimum sample value, or NaN if none.
     */
    public double minimum() {
        return minimum;
    }

    /**
     * Returns the maximum sample value, or {@link Double#NaN NaN} if none.
     *
     * @return the maximum sample value, or NaN if none.
     */
    public double maximum() {
        return maximum;
    }

    /**
     * Equivalents to {@linkplain #maximum() maximum} - {@linkplain #minimum() minimum}.
     * If no samples were added, then returns {@link Double#NaN NaN}.
     *
     * @return the span of sample values, or NaN if none.
     */
    public double span() {
        return maximum - minimum;
    }

    /**
     * Returns the sum, or 0 if none.
     *
     * @return the sum, or 0 if none.
     */
    public double sum() {
        return sum;
    }

    /**
     * Returns the mean value, or {@link Double#NaN NaN} if none.
     *
     * @return the mean value, or NaN if none.
     */
    public double mean() {
        return sum / count;
    }

    /**
     * Returns the root mean square, or {@link Double#NaN NaN} if none.
     *
     * @return the root mean square, or NaN if none.
     */
    public double rms() {
        return sqrt(squareSum / count);
    }

    /**
     * Returns the standard deviation. If the sample values given to the {@code accept(…)}
     * methods have a uniform distribution, then the returned value should be close to
     * <code>sqrt({@linkplain #span() span}² / 12)</code>. If they have a
     * Gaussian distribution (which is the most common case), then the returned value
     * is related to the <a href="http://en.wikipedia.org/wiki/Error_function">error
     * function</a>.
     *
     * <p>As a reminder, the table below gives the probability for a sample value to be
     * inside the {@linkplain #mean() mean} ± <var>n</var> × <var>deviation range</var>,
     * assuming that the distribution is Gaussian (first column) or assuming that the
     * distribution is uniform (second column).</p>
     *
     * <table class="sis">
     *   <caption>Probability values for some standard deviations</caption>
     *   <tr><th>n</th><th>Gaussian</th><th>uniform</th>
     *   <tr><td>0.5</td><td>69.1%</td><td>28.9%</td></tr>
     *   <tr><td>1.0</td><td>84.2%</td><td>57.7%</td></tr>
     *   <tr><td>1.5</td><td>93.3%</td><td>86.6%</td></tr>
     *   <tr><td>2.0</td><td>97.7%</td><td>100%</td></tr>
     *   <tr><td>3.0</td><td>99.9%</td><td>100%</td></tr>
     * </table>
     *
     * @param  allPopulation  {@code true} if sample values given to {@code accept(…)} methods were the totality
     *                        of the population under study, or {@code false} if they were only a sampling.
     * @return the standard deviation.
     */
    public double standardDeviation(final boolean allPopulation) {
        return sqrt((squareSum - sum*sum/count) / (allPopulation ? count : count-1));
    }

    /**
     * Returns the statistics on the differences between sample values, or {@code null} if none.
     * For example if the sample values given to the {@code accept(…)} methods were <var>y₀</var>,
     * <var>y₁</var>, <var>y₂</var> and <var>y₃</var>, then this method returns statistics on
     * <var>y₁</var>-<var>y₀</var>, <var>y₂</var>-<var>y₁</var> and <var>y₃</var>-<var>y₂</var>.
     *
     * <p>The differences between sample values are related to the discrete derivatives as below,
     * where Δ<var>x</var> is the constant interval between the <var>x</var> values of the
     * <var>y</var>=<var>f</var>(<var>x</var>) function:</p>
     *
     * {@preformat java
     *     Statistics derivative = statistics.differences();
     *     derivative.scale(1/Δx); // Shall be invoked only once.
     *     Statistics secondDerivative = derivative.differences();
     *     // Do not invoke scale(1/Δx) again.
     * }
     *
     * This method returns a non-null value only if this {@code Statistics} instance has been created by a
     * call to the {@link #forSeries forSeries(…)} method with a non-empty {@code differenceNames} array.
     * More generally, calls to this method can be chained up to {@code differenceNames.length} times for
     * fetching second or higher order derivatives, as in the above example.
     *
     * @return the statistics on the differences between consecutive sample values,
     *         or {@code null} if not calculated by this object.
     *
     * @see #forSeries(CharSequence, CharSequence[])
     * @see #scale(double)
     */
    public Statistics differences() {
        return null;
    }

    /**
     * Returns a string representation of this statistics. This string will span
     * multiple lines, one for each statistical value. For example:
     *
     * {@preformat text
     *     Number of values:     8726
     *     Minimum value:       6.853
     *     Maximum value:       8.259
     *     Mean value:          7.421
     *     Root Mean Square:    7.846
     *     Standard deviation:  6.489
     * }
     *
     * @return a string representation of this statistics object.
     *
     * @see StatisticsFormat
     */
    @Override
    public String toString() {
        return StatisticsFormat.getInstance().format(this);
    }

    /**
     * Returns a clone of this statistics.
     *
     * @return a clone of this statistics.
     */
    @Override
    public Statistics clone() {
        try {
            return (Statistics) super.clone();
        } catch (CloneNotSupportedException exception) {
            // Should not happen since we are cloneable
            throw new AssertionError(exception);
        }
    }

    /**
     * Returns a hash code value for this statistics.
     */
    @Override
    public int hashCode() {
        final long code = (doubleToLongBits(minimum) +
                     31 * (doubleToLongBits(maximum) +
                     31 * (doubleToLongBits(sum) +
                     31 * (doubleToLongBits(squareSum)))));
        return (int) code ^ (int) (code >>> 32) ^ count;
    }

    /**
     * Compares this statistics with the specified object for equality.
     *
     * @param  object  the object to compare with.
     * @return {@code true} if both objects are equal.
     */
    @Override
    public boolean equals(final Object object) {
        if (object != null && getClass() == object.getClass()) {
            final Statistics cast = (Statistics) object;
            return count == cast.count && countNaN == cast.countNaN
                    && doubleToLongBits(minimum)   == doubleToLongBits(cast.minimum)
                    && doubleToLongBits(maximum)   == doubleToLongBits(cast.maximum)
                    && doubleToLongBits(sum)       == doubleToLongBits(cast.sum)
                    && doubleToLongBits(squareSum) == doubleToLongBits(cast.squareSum)
                    && Objects.equals(name, cast.name);
        }
        return false;
    }




    /**
     * Holds some statistics about the difference between consecutive sample values.
     * Given a series of <var>s₀</var>, <var>s₁</var>, <var>s₂</var>, <var>s₃</var>,
     * <i>etc…</i> samples, this class computes statistics for <var>s₁</var>-<var>s₀</var>,
     * <var>s₂</var>-<var>s₁</var>, <var>s₃</var>-<var>s₂</var>, <i>etc…</i>
     * which are stored in a {@link #delta} statistics object.
     *
     * @author  Martin Desruisseaux (MPO, IRD, Geomatys)
     * @version 0.3
     * @since   0.3
     * @module
     */
    private static final class WithDelta extends Statistics {
        /**
         * Serial number for compatibility with different versions.
         */
        private static final long serialVersionUID = -5149634417399815874L;

        /**
         * Statistics about the differences between consecutive sample values.
         * Consider this field as final; it is modified only by the {@link #clone()} method.
         */
        private Statistics delta;

        /**
         * Last value given to an {@link #accept(double)} method as
         * a {@code double}, or {@link Double#NaN} if none.
         */
        private double last = NaN;

        /**
         * Last value given to an {@link #accept(long)}
         * method as a {@code long}, or 0 if none.
         */
        private long lastAsLong;

        /**
         * Constructs an initially empty set of statistics using the specified object for
         * {@link #delta} statistics. This constructor allows chaining different kind of
         * statistics objects. For example, one could write:
         *
         * {@preformat java
         *     new Statistics.Delta(new Statistics.Delta());
         * }
         *
         * which would compute statistics of sample values, statistics of difference between
         * consecutive sample values, and statistics of difference of difference between
         * consecutive sample values. Other kinds of {@link Statistics} object could be
         * chained as well.
         *
         * @param  name   the phenomenon for which this object is collecting statistics, or {@code null}.
         * @param  delta  the object where to stores delta statistics.
         */
        WithDelta(final CharSequence name, final Statistics delta) {
            super(name);
            this.delta = delta;
            delta.decrementCountNaN();      // Do not count the first NaN, which will always be the first value.
        }

        /**
         * Resets this object state as if it was just created.
         */
        @Override
        public void reset() {
            super.reset();
            delta.reset();
            delta.decrementCountNaN();      // Do not count the first NaN, which will always be the first value.
            last       = NaN;
            lastAsLong = 0;
        }

        /**
         * Updates statistics for the specified sample value and its discrete derivatives.
         * The {@link #delta} statistics are updated with <code>sample - sample<sub>last</sub></code>
         * value, where <code>sample<sub>last</sub></code> is the value given to the previous call of
         * an {@code accept(…)} method.
         */
        @Override
        public void accept(final double sample) {
            super.accept(sample);
            delta.accept(sample - last);
            last       = sample;
            lastAsLong = (long) sample;
        }

        /**
         * Performs the same work than {@link #accept(double)}, but with greater precision for
         * very large integer values (greater than 2<sup>52</sup> in magnitude),
         */
        @Override
        public void accept(final long sample) {
            super.accept(sample);
            if (last == (double) lastAsLong) {
                /*
                 * 'lastAsLong' may have more precision than 'last' since the cast to the
                 * 'double' type may loose some digits. Invoke the 'delta.accept(long)' version.
                 */
                delta.accept(sample - lastAsLong);
            } else {
                /*
                 * The sample value is either fractional, outside 'long' range,
                 * infinity or NaN. Invoke the 'delta.accept(double)' version.
                 */
                delta.accept(sample - last);
            }
            last       = sample;
            lastAsLong = sample;
        }

        /**
         * Update statistics with all samples from the specified {@code stats}.
         *
         * @throws ClassCastException if {@code stats} is not an instance of {@code Statistics.Delta}.
         */
        @Override
        public void combine(final Statistics stats) throws ClassCastException {
            ArgumentChecks.ensureNonNull("stats", stats);
            delta.combine(stats.differences());
            super.combine(stats);
            if (stats instanceof WithDelta) {
                final WithDelta toAdd = (WithDelta) stats;
                last       = toAdd.last;
                lastAsLong = toAdd.lastAsLong;
            } else {
                last       = NaN;
                lastAsLong = 0;
            }
        }

        /**
         * Scales the statistics by the given factor.
         */
        @Override
        public void scale(final double factor) {
            super.scale(factor);
            delta.scale(factor);
        }

        /**
         * Decrements the count of NaN values by one. This method is invoked on construction
         * or on {@link #reset()} call, because the first discrete derivative always have one
         * less value than the original one, the second derivative two less values, etc.
         */
        @Override
        final void decrementCountNaN() {
            super.decrementCountNaN();
            delta.decrementCountNaN();
        }

        /**
         * Returns the statistics about difference between consecutive values.
         */
        @Override
        public Statistics differences() {
            return delta;
        }

        /**
         * Returns a clone of this statistics.
         */
        @Override
        public Statistics clone() {
            final WithDelta copy = (WithDelta) super.clone();
            copy.delta = copy.delta.clone();
            return copy;
        }

        /**
         * Tests this statistics with the specified object for equality.
         */
        @Override
        public boolean equals(final Object obj) {
            return super.equals(obj) && delta.equals(((WithDelta) obj).delta);
        }

        /**
         * Returns a hash code value for this statistics.
         */
        @Override
        public int hashCode() {
            return super.hashCode() + 31*delta.hashCode();
        }
    }
}
