001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.math3.fitting.leastsquares;
018
019import org.apache.commons.math3.linear.RealMatrix;
020import org.apache.commons.math3.linear.RealVector;
021import org.apache.commons.math3.optim.OptimizationProblem;
022
023/**
024 * The data necessary to define a non-linear least squares problem.
025 * <p>
026 * Includes the observed values, computed model function, and
027 * convergence/divergence criteria. Weights are implicit in {@link
028 * Evaluation#getResiduals()} and {@link Evaluation#getJacobian()}.
029 * </p>
030 * <p>
031 * Instances are typically either created progressively using a {@link
032 * LeastSquaresBuilder builder} or created at once using a {@link LeastSquaresFactory
033 * factory}.
034 * </p>
035 * @see LeastSquaresBuilder
036 * @see LeastSquaresFactory
037 * @see LeastSquaresAdapter
038 *
039 * @since 3.3
040 */
041public interface LeastSquaresProblem extends OptimizationProblem<LeastSquaresProblem.Evaluation> {
042
043    /**
044     * Gets the initial guess.
045     *
046     * @return the initial guess values.
047     */
048    RealVector getStart();
049
050    /**
051     * Get the number of observations (rows in the Jacobian) in this problem.
052     *
053     * @return the number of scalar observations
054     */
055    int getObservationSize();
056
057    /**
058     * Get the number of parameters (columns in the Jacobian) in this problem.
059     *
060     * @return the number of scalar parameters
061     */
062    int getParameterSize();
063
064    /**
065     * Evaluate the model at the specified point.
066     *
067     *
068     * @param point the parameter values.
069     * @return the model's value and derivative at the given point.
070     * @throws org.apache.commons.math3.exception.TooManyEvaluationsException
071     *          if the maximal number of evaluations (of the model vector function) is
072     *          exceeded.
073     */
074    Evaluation evaluate(RealVector point);
075
076    /**
077     * An evaluation of a {@link LeastSquaresProblem} at a particular point. This class
078     * also computes several quantities derived from the value and its Jacobian.
079     */
080    public interface Evaluation {
081
082        /**
083         * Get the covariance matrix of the optimized parameters. <br/> Note that this
084         * operation involves the inversion of the <code>J<sup>T</sup>J</code> matrix,
085         * where {@code J} is the Jacobian matrix. The {@code threshold} parameter is a
086         * way for the caller to specify that the result of this computation should be
087         * considered meaningless, and thus trigger an exception.
088         *
089         *
090         * @param threshold Singularity threshold.
091         * @return the covariance matrix.
092         * @throws org.apache.commons.math3.linear.SingularMatrixException
093         *          if the covariance matrix cannot be computed (singular problem).
094         */
095        RealMatrix getCovariances(double threshold);
096
097        /**
098         * Get an estimate of the standard deviation of the parameters. The returned
099         * values are the square root of the diagonal coefficients of the covariance
100         * matrix, {@code sd(a[i]) ~= sqrt(C[i][i])}, where {@code a[i]} is the optimized
101         * value of the {@code i}-th parameter, and {@code C} is the covariance matrix.
102         *
103         *
104         * @param covarianceSingularityThreshold Singularity threshold (see {@link
105         *                                       #getCovariances(double) computeCovariances}).
106         * @return an estimate of the standard deviation of the optimized parameters
107         * @throws org.apache.commons.math3.linear.SingularMatrixException
108         *          if the covariance matrix cannot be computed.
109         */
110        RealVector getSigma(double covarianceSingularityThreshold);
111
112        /**
113         * Get the normalized cost. It is the square-root of the sum of squared of
114         * the residuals, divided by the number of measurements.
115         *
116         * @return the cost.
117         */
118        double getRMS();
119
120        /**
121         * Get the weighted Jacobian matrix.
122         *
123         * @return the weighted Jacobian: W<sup>1/2</sup> J.
124         * @throws org.apache.commons.math3.exception.DimensionMismatchException
125         * if the Jacobian dimension does not match problem dimension.
126         */
127        RealMatrix getJacobian();
128
129        /**
130         * Get the cost.
131         *
132         * @return the cost.
133         * @see #getResiduals()
134         */
135        double getCost();
136
137        /**
138         * Get the weighted residuals. The residual is the difference between the
139         * observed (target) values and the model (objective function) value. There is one
140         * residual for each element of the vector-valued function. The raw residuals are
141         * then multiplied by the square root of the weight matrix.
142         *
143         * @return the weighted residuals: W<sup>1/2</sup> K.
144         * @throws org.apache.commons.math3.exception.DimensionMismatchException
145         * if the residuals have the wrong length.
146         */
147        RealVector getResiduals();
148
149        /**
150         * Get the abscissa (independent variables) of this evaluation.
151         *
152         * @return the point provided to {@link #evaluate(RealVector)}.
153         */
154        RealVector getPoint();
155    }
156}