package joptima;

import java.util.*;

/**
 * 

* χ² fitter. * This class can be passed to a {@link Minimizer} to minimize χ² of a * sum of one or more functions fit to the given data set. * Error bars may be provided for the data points if the data has * compounded errors that are Gaussian. sqrt(y) errors are assumed otherwise. * For different likelihood functions you can extend the {@link #calculate} * method on this class. *

* *

* A typical usage of this class would go as follows: *

 *   // The data points.
 *   double[] x = new double[]{  1,   2,   3,    4,  5};
 *   double[] y = new double[]{1.1, 4.0, 8.7, 15.4, 26};
 *
 *   // The {@link Function} to fit to the data points.
 *   Function f = new Quadratic();
 *
 *   ChiSquaredFitter fitter = new ChiSquaredFitter();
 *   fitter.setData(x, y);
 *   fitter.addFunction(f);
 *   Minimizer.minimize(fitter);
 *
 *   // At this point, if the fit converged, the {@link Function} f will have
 *   // its {@link Parameter}s set to the optimal values.
 * 
*

* * @author Dejan Vucinic <dvucinic@users.sourceforge.net> */ public class ChiSquaredFitter extends Fitter { private double[] xpoint, ypoint; private double[] yerror = null; /** * Constructor. */ public ChiSquaredFitter() { } /** * Constructor. * Assumes sqrt(y) errors. * @param x the x coordinates of points * @param y the y coordinates of points */ public ChiSquaredFitter(double[] x, double[] y) { setData(x, y); } /** * Constructor. * @param x the x coordinates of points * @param y the y coordinates of points * @param errors the error bars on y coordinates of points */ public ChiSquaredFitter(double[] x, double[] y, double[] errors) { setData(x, y, errors); } /** * Constructor. * Assumes sqrt(y) errors. * @param x the x coordinates of points * @param y the y coordinates of points * @param f the {@link Function} to fit to the given set of points */ public ChiSquaredFitter(double[] x, double[] y, Function f) { this(x, y); addFunction(f); } /** * Constructor. * @param x the x coordinates of points * @param y the y coordinates of points * @param errors the error bars on y coordinates of points * @param f the {@link Function} to fit to the given set of points */ public ChiSquaredFitter(double[] x, double[] y, double[] errors, Function f) { this(x, y, errors); addFunction(f); } /** * Fit the sum of functions to this set of points. * Assumes sqrt(y) error bars. * @param x the x coordinates of points * @param y the y coordinates of points */ public void setData(double[] x, double[] y) { xpoint = x; ypoint = y; yerror = null; } /** * Fit the sum of functions to this set of points. * @param x the x coordinates of points * @param y the y coordinates of points * @param errors the error bars on y coordinates of points */ public void setData(double[] x, double[] y, double[] errors) { xpoint = x; ypoint = y; yerror = errors; } /** * Calculates the χ² given parameter values set by a {@link Minimizer} * using reflection. * The formula is: *
   *   for each point in the data set {
   *     f = 0
   *     for each {@link Function} {
   *       f += {@link Function#calculate}(x[point])
   *     }
   *     χ² += (y[point] - f)² / error[point]²
   *   }
   * 
*/ public double calculate() { double value = 0; for (int point = 0; point < xpoint.length; point++) { Iterator it = m_functions.iterator(); double fvalue = 0; while (it.hasNext()) { Function f = (Function) it.next(); fvalue += f.calculate(xpoint[point]); } double chisq = (ypoint[point] - fvalue); chisq = chisq * chisq; if (null != yerror) chisq /= yerror[point] * yerror[point]; value += chisq; } return value; } }

Ads help maintain this website.