/* * ChiSquaredFitMethod.java * * Created on August 15, 2002, 4:38 PM */ package hep.aida.ref.fitter.fitmethod; import hep.aida.IFunction; import hep.aida.IModelFunction; import hep.aida.dev.IDevFitDataIterator; import hep.aida.ext.IFitMethod; /** * * @author The AIDA team @ SLAC. * */ public class ChiSquaredFitMethod extends AbstractFitMethod { private static String[] names = new String[]{"chi2","chisquared"}; public ChiSquaredFitMethod() { super(IFitMethod.BINNED_FIT, names); } public double evaluate(IDevFitDataIterator dataIter, IFunction function) { if ( correlationObject() == null ) return super.evaluate(dataIter, function); double[][] errorMatrix = (double[][]) correlationObject(); // if ( errorMatrix[0].length != dataIter.entries() ) { // throw new IllegalArgumentException("Wrong dimension for the error matrix "+errorMatrix[0].length+" "+dataIter.entries()); // } double[] fVals = new double[ dataIter.entries() ]; dataIter.start(); double fitFunctionValue = 0; int count = 0; while( dataIter.next() ) fVals[count++] = dataIter.value() - function.value(dataIter.vars()); for ( int i = 0; i < dataIter.entries(); i++ ) for ( int k = 0; k < dataIter.entries(); k++ ) fitFunctionValue += (fVals[i]*fVals[k]*errorMatrix[i][k]); return fitFunctionValue; } public double evaluateSumElement(IDevFitDataIterator dataIter, IFunction function) { return Math.pow( dataIter.value() - function.value( dataIter.vars() ) , 2)/Math.pow( dataIter.error(), 2); } public double[] evaluateGradientSumElement(IDevFitDataIterator dataIter, IFunction function) { double f = function.value( dataIter.vars() ); double[] der = ((IModelFunction)function).parameterGradient( dataIter.vars() ); double[] newDer = new double[der.length]; double val = dataIter.value(); double err = dataIter.error(); double c = 2*(f-val)/(err*err); for ( int i = 0; i < der.length; i++ ) newDer[i] = der[i]*c; return newDer; } public double[] evaluateGradient(int dimension, IDevFitDataIterator dataIter, IFunction function) { if ( correlationObject() == null ) return super.evaluateGradient(dimension, dataIter, function); double[][] errorMatrix = (double[][]) correlationObject(); // if ( errorMatrix[0].length != dataIter.entries() ) // throw new IllegalArgumentException("Wrong dimension for the error matrix"); double[] fVals = new double[ dataIter.entries() ]; dataIter.start(); double[] fitFunctionGradients = new double[ dimension ]; double[][] derivatives = new double[dataIter.entries()][]; int count = 0; while( dataIter.next() ) { fVals[count] = dataIter.value() - function.value(dataIter.vars()); derivatives[count] = ((IModelFunction)function).parameterGradient( dataIter.vars() ); count++; } double[] newDerivatives = new double[dimension]; for ( int i = 0; i < dataIter.entries(); i++ ) for ( int k = 0; k < dataIter.entries(); k++ ) for ( int j = 0; j < dimension; j++ ) newDerivatives[j] += (derivatives[i][j]*fVals[k]*errorMatrix[i][k]) + (fVals[i]*derivatives[k][j]*errorMatrix[i][k]); return newDerivatives; } }