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

import java.util.Arrays;

import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.linear.InvalidMatrixException;
import org.apache.commons.math.linear.LUDecompositionImpl;
import org.apache.commons.math.linear.MatrixUtils;
import org.apache.commons.math.linear.RealMatrix;
import org.apache.commons.math.util.FastMath;

/**
 * Base class for implementing estimators.
 * <p>This base class handles the boilerplates methods associated to thresholds
 * settings, jacobian and error estimation.</p>
 * @version $Revision: 990655 $ $Date: 2010-08-29 23:49:40 +0200 (dim. 29 août 2010) $
 * @since 1.2
 * @deprecated as of 2.0, everything in package org.apache.commons.math.estimation has
 * been deprecated and replaced by package org.apache.commons.math.optimization.general
 *
 */
@Deprecated
public abstract class AbstractEstimator implements Estimator {

    /** Default maximal number of cost evaluations allowed. */
    public static final int DEFAULT_MAX_COST_EVALUATIONS = 100;

    /** Array of measurements. */
    protected WeightedMeasurement[] measurements;

    /** Array of parameters. */
    protected EstimatedParameter[] parameters;

    /**
     * Jacobian matrix.
     * <p>This matrix is in canonical form just after the calls to
     * {@link #updateJacobian()}, but may be modified by the solver
     * in the derived class (the {@link LevenbergMarquardtEstimator
     * Levenberg-Marquardt estimator} does this).</p>
     */
    protected double[] jacobian;

    /** Number of columns of the jacobian matrix. */
    protected int cols;

    /** Number of rows of the jacobian matrix. */
    protected int rows;

    /** Residuals array.
     * <p>This array is in canonical form just after the calls to
     * {@link #updateJacobian()}, but may be modified by the solver
     * in the derived class (the {@link LevenbergMarquardtEstimator
     * Levenberg-Marquardt estimator} does this).</p>
     */
    protected double[] residuals;

    /** Cost value (square root of the sum of the residuals). */
    protected double cost;

    /** Maximal allowed number of cost evaluations. */
    private int maxCostEval;

    /** Number of cost evaluations. */
    private int costEvaluations;

    /** Number of jacobian evaluations. */
    private int jacobianEvaluations;

    /**
     * Build an abstract estimator for least squares problems.
     * <p>The maximal number of cost evaluations allowed is set
     * to its default value {@link #DEFAULT_MAX_COST_EVALUATIONS}.</p>
     */
    protected AbstractEstimator() {
        setMaxCostEval(DEFAULT_MAX_COST_EVALUATIONS);
    }

    /**
     * Set the maximal number of cost evaluations allowed.
     *
     * @param maxCostEval maximal number of cost evaluations allowed
     * @see #estimate
     */
    public final void setMaxCostEval(int maxCostEval) {
        this.maxCostEval = maxCostEval;
    }

    /**
     * Get the number of cost evaluations.
     *
     * @return number of cost evaluations
     * */
    public final int getCostEvaluations() {
        return costEvaluations;
    }

    /**
     * Get the number of jacobian evaluations.
     *
     * @return number of jacobian evaluations
     * */
    public final int getJacobianEvaluations() {
        return jacobianEvaluations;
    }

    /**
     * Update the jacobian matrix.
     */
    protected void updateJacobian() {
        incrementJacobianEvaluationsCounter();
        Arrays.fill(jacobian, 0);
        int index = 0;
        for (int i = 0; i < rows; i++) {
            WeightedMeasurement wm = measurements[i];
            double factor = -FastMath.sqrt(wm.getWeight());
            for (int j = 0; j < cols; ++j) {
                jacobian[index++] = factor * wm.getPartial(parameters[j]);
            }
        }
    }

    /**
     * Increment the jacobian evaluations counter.
     */
    protected final void incrementJacobianEvaluationsCounter() {
      ++jacobianEvaluations;
    }

    /**
     * Update the residuals array and cost function value.
     * @exception EstimationException if the number of cost evaluations
     * exceeds the maximum allowed
     */
    protected void updateResidualsAndCost()
    throws EstimationException {

        if (++costEvaluations > maxCostEval) {
            throw new EstimationException(LocalizedFormats.MAX_EVALUATIONS_EXCEEDED,
                                          maxCostEval);
        }

        cost = 0;
        int index = 0;
        for (int i = 0; i < rows; i++, index += cols) {
            WeightedMeasurement wm = measurements[i];
            double residual = wm.getResidual();
            residuals[i] = FastMath.sqrt(wm.getWeight()) * residual;
            cost += wm.getWeight() * residual * residual;
        }
        cost = FastMath.sqrt(cost);

    }

    /**
     * Get the Root Mean Square value.
     * Get the Root Mean Square value, i.e. the root of the arithmetic
     * mean of the square of all weighted residuals. This is related to the
     * criterion that is minimized by the estimator as follows: if
     * <em>c</em> if the criterion, and <em>n</em> is the number of
     * measurements, then the RMS is <em>sqrt (c/n)</em>.
     *
     * @param problem estimation problem
     * @return RMS value
     */
    public double getRMS(EstimationProblem problem) {
        WeightedMeasurement[] wm = problem.getMeasurements();
        double criterion = 0;
        for (int i = 0; i < wm.length; ++i) {
            double residual = wm[i].getResidual();
            criterion += wm[i].getWeight() * residual * residual;
        }
        return FastMath.sqrt(criterion / wm.length);
    }

    /**
     * Get the Chi-Square value.
     * @param problem estimation problem
     * @return chi-square value
     */
    public double getChiSquare(EstimationProblem problem) {
        WeightedMeasurement[] wm = problem.getMeasurements();
        double chiSquare = 0;
        for (int i = 0; i < wm.length; ++i) {
            double residual = wm[i].getResidual();
            chiSquare += residual * residual / wm[i].getWeight();
        }
        return chiSquare;
    }

    /**
     * Get the covariance matrix of unbound estimated parameters.
     * @param problem estimation problem
     * @return covariance matrix
     * @exception EstimationException if the covariance matrix
     * cannot be computed (singular problem)
     */
    public double[][] getCovariances(EstimationProblem problem)
      throws EstimationException {

        // set up the jacobian
        updateJacobian();

        // compute transpose(J).J, avoiding building big intermediate matrices
        final int n = problem.getMeasurements().length;
        final int m = problem.getUnboundParameters().length;
        final int max  = m * n;
        double[][] jTj = new double[m][m];
        for (int i = 0; i < m; ++i) {
            for (int j = i; j < m; ++j) {
                double sum = 0;
                for (int k = 0; k < max; k += m) {
                    sum += jacobian[k + i] * jacobian[k + j];
                }
                jTj[i][j] = sum;
                jTj[j][i] = sum;
            }
        }

        try {
            // compute the covariances matrix
            RealMatrix inverse =
                new LUDecompositionImpl(MatrixUtils.createRealMatrix(jTj)).getSolver().getInverse();
            return inverse.getData();
        } catch (InvalidMatrixException ime) {
            throw new EstimationException(LocalizedFormats.UNABLE_TO_COMPUTE_COVARIANCE_SINGULAR_PROBLEM);
        }

    }

    /**
     * Guess the errors in unbound estimated parameters.
     * <p>Guessing is covariance-based, it only gives rough order of magnitude.</p>
     * @param problem estimation problem
     * @return errors in estimated parameters
     * @exception EstimationException if the covariances matrix cannot be computed
     * or the number of degrees of freedom is not positive (number of measurements
     * lesser or equal to number of parameters)
     */
    public double[] guessParametersErrors(EstimationProblem problem)
      throws EstimationException {
        int m = problem.getMeasurements().length;
        int p = problem.getUnboundParameters().length;
        if (m <= p) {
            throw new EstimationException(
                    LocalizedFormats.NO_DEGREES_OF_FREEDOM,
                    m, p);
        }
        double[] errors = new double[problem.getUnboundParameters().length];
        final double c = FastMath.sqrt(getChiSquare(problem) / (m - p));
        double[][] covar = getCovariances(problem);
        for (int i = 0; i < errors.length; ++i) {
            errors[i] = FastMath.sqrt(covar[i][i]) * c;
        }
        return errors;
    }

    /**
     * Initialization of the common parts of the estimation.
     * <p>This method <em>must</em> be called at the start
     * of the {@link #estimate(EstimationProblem) estimate}
     * method.</p>
     * @param problem estimation problem to solve
     */
    protected void initializeEstimate(EstimationProblem problem) {

        // reset counters
        costEvaluations     = 0;
        jacobianEvaluations = 0;

        // retrieve the equations and the parameters
        measurements = problem.getMeasurements();
        parameters   = problem.getUnboundParameters();

        // arrays shared with the other private methods
        rows      = measurements.length;
        cols      = parameters.length;
        jacobian  = new double[rows * cols];
        residuals = new double[rows];

        cost = Double.POSITIVE_INFINITY;

    }

    /**
     * Solve an estimation problem.
     *
     * <p>The method should set the parameters of the problem to several
     * trial values until it reaches convergence. If this method returns
     * normally (i.e. without throwing an exception), then the best
     * estimate of the parameters can be retrieved from the problem
     * itself, through the {@link EstimationProblem#getAllParameters
     * EstimationProblem.getAllParameters} method.</p>
     *
     * @param problem estimation problem to solve
     * @exception EstimationException if the problem cannot be solved
     *
     */
    public abstract void estimate(EstimationProblem problem)
    throws EstimationException;

}
