Class LeastSquaresFit

All Implemented Interfaces:
DoubleUnaryOperator, RealValuedDomainOps, RealValuedFunctOps, RealValuedFunctVAOps, VADomainOps
Direct Known Subclasses:
LeastSquaresFit.BSpline, LeastSquaresFit.Linear, LeastSquaresFit.NonLinear

public abstract class LeastSquaresFit extends RealValuedFunction
Class representing common operations for least square fits.

A collection of data points yi, each corresponding to a value of an argument x, xi is represented by some function y(x; a), where x is the function's argument and 'a' is a vector of parameters. A least-squares fit minimizes the quantity $$\chi^2 = \sum_i \frac{[y_i - y(x_i; a)]^2}{\sigma_i^2}$$

χ2 ≡ ∑i[yi-y(xi; a)]2i2.
where σi is the standard deviation for yi. Errors in the variable x are assumed to be negligible.

A basic assumption is that each yi is the value of a random variable whose standard deviation is σi. If we were to repeat the fit using a different set of values of these random variables, we will, as expected, get a different set of parameters. Naturally, one would like to know the variances or standard deviations for these sets of parameters. This is provided by a covariance matrix, which gives the variances of the parameters and the covariances between parameters, as described in the documentation for getCovarianceMatrix().

Subclasses of LeastSquaresFit will typically compute the parameters in a constructor. After the least squares fit is constructed, one may obtain the values of the function y(x; a) and its derivatives, the parameters, the value of χ2 for the fit, the covariance matrix, and the covariance of y computed at two values of x.

Note: since the class LeastSquaresFit extends RealValuedFunction, it can be used by SplinePath2D to provide values for a smooth path for plotting. For example,

 import org.bzdev.math.*;
 import org.bzdev.geom.*;
 double x1 = 0.0;
 double x2 = 10.0;
 LeastSquaresFit lsf = new ....;
 int n = 20;
 SplinePath2D path =
     new SplinePath2D(RealValuedFunction.xFunction, lsf, x1, x2, n);
 
The calling convention for the constructors and chiSquare methods places x values before y values. This is the same convention used by the CubicSpline and BSpline classes.

In addition, the inner classes for LeastSquaresFit fit implement the RealValuedFunction methods RealValuedFunction.derivAt(double) and RealValuedFunction.secondDerivAt(double), and all subclasses should implement these methods as well. For those inner classes whose constructs have arguments whose types are RealValuedFunction or RealValuedFunctionVA, the real-valued functions supplied should implement derivatives if the least squares fit's derivative methods are used.

  • Constructor Details

    • LeastSquaresFit

      public LeastSquaresFit()
  • Method Details

    • setParameters

      protected void setParameters(double[] parameters)
      Set the parameters array. Subclasses must call this method, generally in a constructor.
      Parameters:
      parameters - the array to use to store parameters
    • getParametersArray

      protected final double[] getParametersArray()
      Get the parameters array. This provides access to the parameters array.
      Returns:
      parameters the array to use to store parameters
    • setChiSquare

      protected void setChiSquare(double chiSq)
      Set the value of χ2.
      Parameters:
      chiSq - the value for χ2
    • setDegreesOfFreedom

      protected void setDegreesOfFreedom(int degrees)
      Set the number of degrees of freedom.
      Parameters:
      degrees - the number of degrees of freedom
    • getDegreesOfFreedom

      public int getDegreesOfFreedom()
      Get the number of degrees of freedom for this least-squares fit.
      Returns:
      the number of degrees of freedom.
    • setReducedChiSquare

      protected void setReducedChiSquare(double reducedChiSq)
      Set the value of χ2reduced. The reduced value of χ2 is the value of χ2 divided by the number of degrees of freedom (the number of points fitted minus the number of parameters).
      Parameters:
      reducedChiSq - the value for χ2reduced
    • getNumberOfParameters

      public int getNumberOfParameters()
      Get the number of parameters for this least-squares fit.
      Returns:
      the number of parameters/parameters
    • getParameters

      public double[] getParameters()
      Get the parameters.
      Returns:
      a copy of the parameters array
    • getParameters

      public double[] getParameters(double[] array) throws IllegalArgumentException
      Get the parameters, providing an array in which to store them.
      Parameters:
      array - an array to hold the parameters
      Returns:
      a copy of the parameters array
      Throws:
      IllegalArgumentException - the array dimensions were too small
    • getChiSquare

      public double getChiSquare()
      Get the χ2 value for this least squares fit.

      For the linear case, if standard deviations for the y values are not known, the variance is assumed to be constant and computed as the sum of squares divided by the number of degrees of freedom. The result is that the χ2 value turns out to be the number of data points minus the number of parameters (i.e., the number of degrees of freedom). The value for this case will not be particularly useful.

      Returns:
      the value of χ2.
    • getStat

      public Statistic getStat()
      Get the (chi-square) statistic
      Returns:
      the statistic
    • getReducedChiSquare

      public double getReducedChiSquare()
      Get the reduced χ2 value for this least squares fit. This is the value of χ2 divided by the number of degrees of freedom (the number of data points used for the fit minus the number of parameters). The value will be about 1.0 for a good fit. A much larger value typically means that the model used is not a good match for the data, and a value much smaller than 1.0 (but non-negative) indicates that the errors assumed for the data are not accurate.
      Returns:
      the reduced χ2 value
    • setCovariance

      protected void setCovariance(double[][] covariance)
      Set the covariance array. The array is an n by n array, where n is the number of parameters. Typically this method will be called by the method createCovariance() and nowhere else.
      Parameters:
      covariance - the covariance array
    • createCovariance

      protected abstract void createCovariance()
      Create the covariance array. Subclasses must implement this method, which is expected to set up the covariance array and then call setCovariance(double[][]) to make it available.
    • getCovarianceArray

      protected double[][] getCovarianceArray()
      Get the covariance array for the parameters. This method calls createCovariance(). As long as subclasses use this method to obtain the covariance array, they will not have to explicitly call createCovariance(). This method returns the covariance array, not a copy of the array.
      Returns:
      the covariance array.
    • getCovarianceMatrix

      public double[][] getCovarianceMatrix()
      Get the covariance matrix for the parameters. The covariance matrix C provides the variances (for the diagonal elements), and the covariances for the off-diagonal elements. For the diagonal elements, the values C[i][i] are the variance for the ith parameter. Otherwise C[i][j] provides the covariance between the ith and jth parameter.

      The value returned is a newly allocated matrix.

      Returns:
      the covariance matrix.
    • getCovarianceMatrix

      public double[][] getCovarianceMatrix(double[][] array) throws IllegalArgumentException
      Get the covariance matrix, using an array provided by the caller The value returned is a newly allocated matrix. If the array dimensions are larger than the number of parameters, indices with values larger than or equal to the number of parameters will be ignored.
      Parameters:
      array - an array used to store the covariance values
      Returns:
      the covariance matrix.
      Throws:
      IllegalArgumentException - the array dimensions were too small
    • covariance

      public abstract double covariance(double x1, double x2)
      Compute the covariance for the y values associated with two data points. The covariance for two random variables X and Y is E[(X-E[X](Y-E[Y])] where E[Z] is the expected value of a random variable Z. The covariance of X and X is simply the variance of X. The value returned allows one to estimate the error in the fit at any point, not just the data points, and whether errors at different values of X are correlated.
      Parameters:
      x1 - the x value for the first y value
      x2 - the x value for the second y value
      Returns:
      the covariance
    • sumOfSquares

      public static double sumOfSquares(LeastSquaresFit fit, double[] x, double[] y)
      Compute the sum of the squares of the difference between a fit and a set of data points.

      Note: If the variance of the Y values are not known, they can be estimated by first creating an instance of LeastSquares fit, calling LeastSquaresFit.sumOfSquares(fit, x, y), and dividing the value returned by this call by (n-m) where n is the length of the array x and m is the number of parameters. See "Ordinary least Squares" (Wikipedia) for details.

      Parameters:
      fit - the least-squares fit
      x - the X values
      y - the Y values
      Returns:
      the sum of the squares of the distance between the fit and data point y for each value of x
    • chiSquare

      public static double chiSquare(LeastSquaresFit fit, double[] x, double[] y, double sigma)
      Given a least squares fit, compute the value of χ2 for a set of data points in which the y values have the same standard deviation and the x values are accurate. Each data point is specified by an index into two arrays, one giving the value of X and the other the value of Y for that point.
      Parameters:
      fit - the least squares fit
      x - the X values for the data points
      y - the Y values for the data points
      sigma - the standard deviation for y
      Returns:
      the value of χ2
    • chiSquare

      public static double chiSquare(LeastSquaresFit fit, double[] x, double[] y, double[] sigma)
      Given a least squares fit, compute the value of χ2 for a set of data points in which the y values have a specified standard deviation and the x values are accurate. Each data point is specified by an index into two arrays, one giving the value of X and the other the value of Y for that point. The index also indicates which value to use in the sigma array to determine the standard deviation for the corresponding y value.
      Parameters:
      fit - the least squares fit
      x - the X values for the data points
      y - the Y values for the data points
      sigma - the standard deviations for the data points
      Returns:
      the value of χ2
    • getFunction

      public RealValuedFunction getFunction(double[] parameters) throws IllegalArgumentException
      Get the real valued function associated with this least squares fit but with altered parameters.

      This method is useful for testing (varying the parameters should result in a worse fit), but it can also be used in Monte-Carlo models: Given the parameters and covariance matrix, one can use the class GaussianRVs to generate parameters with the same mean value and covariance metrix. The real-valued functions corresponding to these parameters can then be used in Monte-Carlo simulations or models.

      Parameters:
      parameters - the parameters.
      Returns:
      a real-valued function using the specified parameters
      Throws:
      IllegalArgumentException - the argument has the wrong length
    • getFit

      protected abstract LeastSquaresFit getFit()
      Get a copy of this least squares fit but without its parameters, degrees of freedom, chi square value, reduced chi square value, or covariance set.

      This method is used by getFunction(double[]), which only provides a real-valued function. The only methods that will be called on the value returned are setChiSquare(double), setDegreesOfFreedom(int), setReducedChiSquare(double), setParameters(double[]), RealValuedFunction.valueAt(double), RealValuedFunction.derivAt(double), and RealValuedFunction.secondDerivAt(double).

      Returns:
      a least squares fit