package hep.aida.ref.fitter;
import hep.aida.IAnalysisFactory;
import hep.aida.IAnnotation;
import hep.aida.IBaseHistogram;
import hep.aida.ICloud;
import hep.aida.IDataPointSet;
import hep.aida.IFitData;
import hep.aida.IFitParameterSettings;
import hep.aida.IFitResult;
import hep.aida.IFunction;
import hep.aida.IFunctionFactory;
import hep.aida.IHistogram;
import hep.aida.IHistogram1D;
import hep.aida.IHistogramFactory;
import hep.aida.IManagedObject;
import hep.aida.IModelFunction;
import hep.aida.IProfile;
import hep.aida.IRangeSet;
import hep.aida.ITree;
import hep.aida.ITupleFactory;
import hep.aida.dev.IDevFitData;
import hep.aida.dev.IDevFitDataIterator;
import hep.aida.dev.IDevFitResult;
import hep.aida.ext.IExtFitter;
import hep.aida.ext.IFitMethod;
import hep.aida.ext.IOptimizer;
import hep.aida.ext.IOptimizerConfiguration;
import hep.aida.ext.IOptimizerFactory;
import hep.aida.ext.IVariableSettings;
import hep.aida.ref.AidaUtils;
import hep.aida.ref.fitter.fitdata.FitDataCreator;
import hep.aida.ref.function.BaseModelFunction;
import hep.aida.ref.function.FunctionCatalog;
import hep.aida.ref.function.RangeSet;
import hep.aida.ref.histogram.DataPointSet;
import hep.aida.ref.pdf.Dependent;
import hep.aida.ref.pdf.Function;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import org.freehep.util.FreeHEPLookup;
import org.openide.util.Lookup;
/**
* @author The AIDA team @ SLAC.
*
*/
public class Fitter implements IExtFitter {
// The IOptimizer.
private String engineType;
private IOptimizer optimizer = null;
// The IFitMethod.
private String fitMethodType;
private IFitMethod fitMethod = null;
// The IFunction to be minimized.
private IFunction fitFunction;
// IFitParameterSettings
private Hashtable fitParHash = new Hashtable();
private boolean useGradient = true;
private ArrayList constraintList = new ArrayList();
private Hashtable simpleConstraintHash = new Hashtable();
private boolean createClone = true;
/**
* Create a new Fitter specifying the underlying optimizing engine.
* @param fitMethodType The type of fitter.
* @param engineType The type of optimizer to use.
* @throws IllegalArgumentException if the engineType does not exist.
*
*/
public Fitter(String fitMethodType, String engineType, String options) throws IllegalArgumentException {
setFitMethod(fitMethodType);
setEngine(engineType);
Map opt = hep.aida.ref.AidaUtils.parseOptions(options);
String val = (String) opt.get("noClone");
if ( val != null && val.trim().equalsIgnoreCase("true") ) createClone = false;
}
public void setEngine(String engineType) throws IllegalArgumentException {
if (engineType == null || engineType.length() == 0) engineType = "jminuit";
String enType = engineType.toLowerCase();
IOptimizerFactory tmpOptimizerFactory = null;
Lookup.Template template = new Lookup.Template(IOptimizerFactory.class);
Lookup.Result result = FreeHEPLookup.instance().lookup(template);
Collection c = result.allInstances();
for (Iterator i = c.iterator(); i.hasNext(); ) {
IOptimizerFactory of = (IOptimizerFactory)i.next();
String[] names = of.optimizerFactoryNames();
if ( names == null || names.length == 0 )
throw new IllegalArgumentException("IOptimizerFactory with illegal names!");
for ( int j = 0; j < names.length; j++ ) {
if ( enType.equals( names[j].toLowerCase() ) ) {
tmpOptimizerFactory = of;
break;
}
}
}
if (tmpOptimizerFactory == null) throw new IllegalArgumentException("Cannot create IOptimizer of type: "+engineType);
this.engineType = engineType;
this.optimizer = tmpOptimizerFactory.create(engineType);
}
public String engineName() {
return engineType;
}
public void setFitMethod(String fitMethodType) throws IllegalArgumentException {
if (fitMethodType == null || fitMethodType.length() == 0) fitMethodType = "chi2";
// Check the lookup table to look for the fitMethod of the given type.
String fitMet = fitMethodType.toLowerCase();
IFitMethod tmpFitMethod = null;
Lookup.Template template = new Lookup.Template(IFitMethod.class);
Lookup.Result result = FreeHEPLookup.instance().lookup(template);
Collection c = result.allInstances();
for (Iterator i = c.iterator(); i.hasNext(); ) {
IFitMethod fm = (IFitMethod)i.next();
String[] names = fm.fitMethodNames();
if ( names == null || names.length == 0 )
throw new IllegalArgumentException("IFitMethod with illegal names!");
for ( int j = 0; j < names.length; j++ ) {
if ( fitMet.equals( names[j].toLowerCase() ) ) {
tmpFitMethod = fm;
break;
}
}
}
if (tmpFitMethod == null) throw new IllegalArgumentException("Unknown IFitMethod type: "+fitMethodType);
this.fitMethodType = fitMethodType;
this.fitMethod = tmpFitMethod;
}
public IOptimizer optimizer() {
return optimizer;
}
public String fitMethodName() {
return fitMethodType;
}
public IFitParameterSettings fitParameterSettings(String name) {
if ( fitParHash.containsKey(name) ) return (IFitParameterSettings) fitParHash.get(name);
IFitParameterSettings fitPar = new FitParameterSettings(name);
fitParHash.put(name,fitPar);
return fitPar;
}
public String[] listParameterSettings() {
int size = fitParHash.size();
String[] parNames = new String[size];
Enumeration e = fitParHash.keys();
for (int i = 0; e.hasMoreElements(); i++)
parNames[i] = (String) e.nextElement();
return parNames;
}
public void resetParameterSettings() {
fitParHash.clear();
}
public IFitResult fit( Function f ) {
if ( f.numberOfDependents() != 1 )
throw new IllegalArgumentException("Currently we only fit 1 dimensional functions.");
Dependent x = f.getDependent(0);
if ( ! x.isConnected() )
throw new IllegalArgumentException("Dependent "+x.name()+" is not connected to a data set");
IFitData data = x.data();
return fit( data, f );
}
public IFitResult fit(IFitData d, IFunction originalFunction) {
return fit(d, originalFunction, null);
}
public IFitResult fit(IFitData d, IFunction originalFunction, String range) {
return fit(d, originalFunction, range, null);
}
private void addBounds(IRangeSet rs, int index, double[] lb, double[] ub) {
if ( lb.length == 0 ) throw new RuntimeException("No ranges are set in the FitData. Please report the problem");
for ( int j = 0; j < ub.length; j++ )
rs.include(lb[j],ub[j]);
}
public IFitResult fit(IFitData d, IFunction originalFunction, String range, Object correlationObject) {
String name = "";
if ( originalFunction instanceof IManagedObject ) {
name = ((IManagedObject) originalFunction).name();
} else {
name = originalFunction.title();
}
name += " "+engineName()+" fit";
IFunction fClone = cloneFunction(name,originalFunction);
boolean setRange = false;
if ( originalFunction instanceof IFunction )
setRange = true;
// IModelFunction f = (IModelFunction)originalFunction;
IModelFunction f;
if ( fClone instanceof IModelFunction ) {
f = (IModelFunction)fClone;
} else if (fClone instanceof IFunction) {
f = new BaseModelFunction(name, name, fClone);
} else {
throw new RuntimeException("Fitter for now can only use IModelFunctions and IFunctions. Please report this problem");
}
if ( range != null ) {
Map optionsMap = AidaUtils.parseOptions( range );
range = (String) optionsMap.get("range");
RangeSet usersRange = new RangeSet(range);
IRangeSet rs = d.range(0);
rs.excludeAll();
addBounds(rs, 0, usersRange.lowerBounds(), usersRange.upperBounds());
}
if ( setRange ) {
f.excludeNormalizationAll();
//Set ranges on function.
IRangeSet d_rs = null;
for ( int i = 0; i < d.dimension(); i++ ) {
d_rs = d.range(i);
IRangeSet f_rs = f.normalizationRange(i);
addBounds(f_rs, i, d_rs.lowerBounds(), d_rs.upperBounds());
}
}
//Clear the fit method and set the correlation Object
fitMethod.clear();
fitMethod.setCorrelationObject(correlationObject);
loadFitDataAndFunction(d,f);
long startFit = System.currentTimeMillis();
optimizer.optimize();
long endFit = System.currentTimeMillis();
double fitSeconds = (double)(endFit-startFit)/1000.;
// Set the minimum parameters on the function
String[] parNames = f.parameterNames();
for( int i = 0; i < parNames.length; i++ )
f.setParameter(parNames[i],optimizer.result().parameters()[i]);
double[][] covMatrix = optimizer.result().covarianceMatrix();
int status = optimizer.result().optimizationStatus();
int dataEntries = ((FitFunction) fitFunction).dataEntries();
int freePars = ((FitFunction) fitFunction).nFreePars();
int nDoF = dataEntries - freePars;
double funcVal = fitFunction.value(f.parameters());
IDevFitResult result = new FitResult(fitFunction.dimension(), fitSeconds);
result.setConstraints( constraints() );
result.setDataDescription( d.dataDescription() );
result.setEngineName( engineName() );
result.setFitMethodName( fitMethodName() );
result.setFitStatus( status );
result.setFittedFunction( f ); // FIX ME! Replace with clone.
result.setIsValid( true ); ////??????
result.setNdf( nDoF );
if ( fitMethod.fitType() == IFitMethod.UNBINNED_FIT )
result.setQuality( funcVal/nDoF/Math.sqrt(2.) );
else
result.setQuality( funcVal/nDoF );
int countI = 0;
for( int i = 0; i < parNames.length; i++ ) {
result.setFitParameterSettings( parNames[i], fitParameterSettings(parNames[i]) );
int countJ = 0;
for( int j = 0; j < parNames.length; j++ ) {
if ( ! optimizer.variableSettings(parNames[i]).isFixed() && ! optimizer.variableSettings(parNames[j]).isFixed() )
result.setCovMatrixElement( i, j , covMatrix[countI][countJ++] );
}
if ( ! optimizer.variableSettings(parNames[i]).isFixed() ) countI++;
}
return (IFitResult)result;
}
public IFitResult fit(IBaseHistogram h, IFunction f) {
return fit( h, f, null);
}
public IFitResult fit(IBaseHistogram h, IFunction f, String range) {
if ( h instanceof IHistogram || h instanceof IProfile )
if ( fitMethod.fitType() == IFitMethod.UNBINNED_FIT ) throw new IllegalArgumentException("Cannot perform unbinned fit on a IHistogram!!");
else if ( h instanceof ICloud )
if ( fitMethod.fitType() == IFitMethod.BINNED_FIT ) throw new IllegalArgumentException("Cannot perform binned fit on a ICloud!!");
IFitData fitData = FitDataCreator.create(h);
return fit( fitData, f, range );
}
private void setDefaultInitialParameters(IFunction f, String model, Object data) {
if ( model.equals("g") ) {
if ( data instanceof IHistogram1D ) {
IHistogram1D h1 = (IHistogram1D) data;
double[] pars = new double[3];
pars[0] = h1.maxBinHeight();
pars[1] = h1.mean();
pars[2] = h1.rms();
f.setParameters(pars);
}
}
}
public IFitResult fit(IBaseHistogram h, String model) {
return fit(h, model, (String)null);
}
public IFitResult fit(IBaseHistogram h, String model, String range) {
IFunction func = FunctionCatalog.getFunctionCatalog().create(model);
setDefaultInitialParameters(func, model, h);
return fit(h,func, range);
}
public IFitResult fit(IBaseHistogram h, String model, double[] initialParameters) {
return fit(h,model, initialParameters, null);
}
public IFitResult fit(IBaseHistogram h, String model, double[] initialParameters, String range) {
IFunction func = FunctionCatalog.getFunctionCatalog().create(model);
if ( initialParameters.length != func.numberOfParameters() ) throw new IllegalArgumentException("Wrong number of parameters "+initialParameters.length+
"! This function requires "+func.numberOfParameters());
func.setParameters(initialParameters);
return fit(h,func, range);
}
public IFitResult fit(IDataPointSet dataPointSet, IFunction f) {
return fit(dataPointSet, f, (String)null);
}
public IFitResult fit(IDataPointSet dataPointSet, IFunction f, String range) {
return fit(dataPointSet, f, range, null);
}
public IFitResult fit(IDataPointSet dataPointSet, IFunction f, double[] initialParameters) {
return fit(dataPointSet, f, initialParameters, null, null);
}
public IFitResult fit(IDataPointSet dataPointSet, IFunction f, String range, Object correlationObject) {
return fit(dataPointSet, f, null, range, correlationObject);
}
public IFitResult fit(IDataPointSet dataPointSet, IFunction f, double[] initialParameters, String range, Object correlationObject) {
if ( fitMethod.fitType() == IFitMethod.UNBINNED_FIT ) throw new IllegalArgumentException("Cannot perform unbinned fit on a IDataPointSet!!");
if ( dataPointSet.dimension() != f.dimension() + 1 ) throw new IllegalArgumentException("Wrong dimension match. DataPointSets can only be fitted if"+
" their dimension is one unit bigger than the one of the function");
if ( initialParameters != null ) {
if ( initialParameters.length != f.numberOfParameters() ) throw new IllegalArgumentException("Wrong number of parameters "+initialParameters.length+
"! This function requires "+f.numberOfParameters());
f.setParameters(initialParameters);
}
IFitData fitData = FitDataCreator.create(dataPointSet);
return fit( fitData, f, range, correlationObject );
}
public IFitResult fit(IDataPointSet dataPointSet, String model) {
return fit(dataPointSet, model, (String)null);
}
public IFitResult fit(IDataPointSet dataPointSet, String model, String range) {
return fit(dataPointSet,model, range, null);
}
public IFitResult fit(IDataPointSet dataPointSet, String model, String range, Object correlationObject) {
IFunction func = FunctionCatalog.getFunctionCatalog().create(model);
setDefaultInitialParameters(func, model, dataPointSet);
return fit(dataPointSet,func, range, correlationObject);
}
public IFitResult fit(IDataPointSet dataPointSet, String model, double[] initialParameters) {
return fit(dataPointSet, model, initialParameters, null, null);
}
public IFitResult fit(IDataPointSet dataPointSet, String model, double[] initialParameters, String range) {
return fit(dataPointSet, model, initialParameters, range, null);
}
public IFitResult fit(IDataPointSet dataPointSet, String model, double[] initialParameters, String range, Object correlationObject) {
IFunction func = FunctionCatalog.getFunctionCatalog().create(model);
return fit(dataPointSet,func, initialParameters, range, correlationObject);
}
public IFitResult fit(IFitData d, String model, double[] initialParameters) {
return fit(d,model,initialParameters,null);
}
public IFitResult fit(IFitData d, String model, double[] initialParameters, String range) {
return fit(d,model,initialParameters, range, null);
}
public IFitResult fit(IFitData d, String model, double[] initialParameters, String range, Object correlationObject) {
IFunction func = FunctionCatalog.getFunctionCatalog().create(model);
if ( initialParameters != null ) {
if ( initialParameters.length != func.numberOfParameters() ) throw new IllegalArgumentException("Wrong number of parameters "+initialParameters.length+
"! This function requires "+func.numberOfParameters());
func.setParameters(initialParameters);
}
return fit(d,func, range, correlationObject);
}
public IFitResult fit(IFitData d, String model) {
return fit(d,model,(String)null);
}
public IFitResult fit(IFitData d, String model, String range) {
return fit(d,model, range, null);
}
public IFitResult fit(IFitData d, String model, String range, Object correlationObject) {
IFunction func = FunctionCatalog.getFunctionCatalog().create(model);
return fit(d,func, range, correlationObject);
}
public void setConstraint(String expression) throws IllegalArgumentException {
if ( ! optimizer.acceptsConstraints() )
throw new UnsupportedOperationException("Optimizer "+engineName()+" does not accept constraints.");
StringTokenizer st = new StringTokenizer(expression,"=");
if ( st.countTokens() != 2 ) throw new IllegalArgumentException("Only constraints of the form \" parName = SomeExpression \" are supported");
String parName = st.nextToken().trim();
if ( ! Pattern.matches("\\w+", parName) ) throw new IllegalArgumentException("Incorrect parameter name "+parName);
String constrExpression = st.nextToken().trim();
if ( Pattern.matches("\\w+",constrExpression) ) {
simpleConstraintHash.put(parName,constrExpression);
} else {
throw new IllegalArgumentException("This type of constraint is not supported yet "+parName+" = "+constrExpression);
}
constraintList.add(expression);
}
public String[] constraints() {
int size = constraintList.size();
String[] constraints = new String[size];
for ( int i = 0; i<size; i++ )
constraints[i] = (String) constraintList.get(i);
return constraints;
}
public void resetConstraints() {
simpleConstraintHash.clear();
constraintList.clear();
}
public IDataPointSet createScan1D(IFitData d, IFunction originalFunction, String parName, int npts, double pmin, double pmax) {
if ( pmin > pmax ) throw new IllegalArgumentException("Incorret parameter limits : "+pmin+" has to be less than "+pmax);
if ( npts < 1 ) throw new IllegalArgumentException("The number of points has to be greater than zero : "+npts);
IFunction fClone = cloneFunction(null, originalFunction);
IModelFunction f;
if ( fClone instanceof IModelFunction ) {
f = (IModelFunction)fClone;
} else {
f = new BaseModelFunction("", "", fClone);
}
loadFitDataAndFunction(d,f);
int index = f.indexOfParameter( parName );
IFitParameterSettings fitParSet = fitParameterSettings(parName);
if ( fitParSet.isFixed() ) throw new IllegalArgumentException("Parameter "+parName+" is fixed");
IDataPointSet dps = new DataPointSet("",parName+" scan",2,npts);
double step = (pmax - pmin)/(npts-1);
double startValue = optimizer.variableSettings(parName).value();
for ( int i = 0; i<npts; i++ ) {
double val = pmin + i*step;
if ( i == npts-1 ) val = pmax;
optimizer.variableSettings(parName).setValue(val);
String[] parNames = f.parameterNames();
double[] fitParsVal = new double[ parNames.length ];
for( int j = 0; j < parNames.length; j++ )
fitParsVal[j] = optimizer.variableSettings(parNames[j]).value();
dps.point(i).coordinate(0).setValue( val );
dps.point(i).coordinate(0).setErrorPlus(0);
dps.point(i).coordinate(0).setErrorMinus(0);
dps.point(i).coordinate(1).setValue( fitFunction.value(fitParsVal) );
dps.point(i).coordinate(1).setErrorPlus(0);
dps.point(i).coordinate(1).setErrorMinus(0);
}
optimizer.variableSettings(parName).setValue(startValue);
f.setParameter(parName,startValue);
return dps;
}
public IDataPointSet createContour(IFitData d, IFitResult r, String par1, String par2, int npts, double nSigmas) {
IFunction result = r.fittedFunction();
IModelFunction f;
if ( result instanceof IModelFunction ) {
f = (IModelFunction)result;
} else {
f = new BaseModelFunction("", "", result);
}
loadFitDataAndFunction(d,f);
double[][] contour;
if ( optimizer.canCalculateContours() )
contour = optimizer.calculateContour(par1,par2, npts, nSigmas);
else {
String eName = engineName();
setEngine("minuit");
contour = optimizer.calculateContour(par1, par2, npts, nSigmas);
setEngine(eName);
}
int found = contour[0].length;
IDataPointSet dps = new DataPointSet("",par1+" vs "+par2+" "+nSigmas+" sigma contour",2,found);
for ( int i = 0; i<found; i++ ) {
dps.point(i).coordinate(0).setValue( contour[0][i] );
dps.point(i).coordinate(0).setErrorPlus(0);
dps.point(i).coordinate(0).setErrorMinus(0);
dps.point(i).coordinate(1).setValue( contour[1][i] );
dps.point(i).coordinate(1).setErrorPlus(0);
dps.point(i).coordinate(1).setErrorMinus(0);
}
return dps;
}
private IFunction fitFunction() {
return fitFunction;
}
public boolean useFunctionGradient() {
return useGradient;
}
public void setUseFunctionGradient(boolean useGradient) {
this.useGradient = useGradient;
}
private void loadFitDataAndFunction(IFitData d, IModelFunction f) {
if ( fitMethod.fitType() != ( (IDevFitData) d ).fitType() ) throw new IllegalArgumentException("This FitData is incompatible with the selected fit method");
if ( d.dimension() != f.dimension() ) throw new IllegalArgumentException("Dimension mismatch!! Function's dimension "+f.dimension()+" FitData's dimension "+d.dimension());
optimizer.reset();
if ( fitMethod.fitType() == IFitMethod.BINNED_FIT ) {
optimizer.configuration().setErrorDefinition(IOptimizerConfiguration.CHI2_FIT_ERROR);
f.normalize(false);
} else {
optimizer.configuration().setErrorDefinition(IOptimizerConfiguration.LOGL_FIT_ERROR);
f.normalize(true);
}
IDevFitDataIterator dataIter = ( (IDevFitData) d ).dataIterator();
fitFunction = new FitFunction(dataIter, f);
// Create the FitParameterSettings
String[] parNames = f.parameterNames();
for( int i = 0; i < parNames.length; i++ ) {
String parName = parNames[i];
IFitParameterSettings fitPar = fitParameterSettings(parName);
double parVal = f.parameter(parName);
IVariableSettings varSet = optimizer.variableSettings(parName);
varSet.setValue( parVal );
varSet.setFixed( fitPar.isFixed() );
String simpleConstrString = (String)simpleConstraintHash.get( parName );
if ( simpleConstrString != null )
if ( ( (FitFunction)fitFunction ).isValidSimpleConstraint( parName, simpleConstrString ) ) {
( (FitFunction) fitFunction ).setSimpleConstraint( parName, simpleConstrString );
varSet.setFixed( true );
}
double stepSize = fitPar.stepSize();
if ( Double.isNaN( stepSize ) ) {
stepSize = 0.1*Math.abs(parVal);
if ( stepSize < 1 ) stepSize = 1;
}
varSet.setStepSize( stepSize );
if ( fitPar.isBound() )
varSet.setBounds( fitPar.lowerBound(), fitPar.upperBound() );
}
optimizer.setFunction( fitFunction );
// For the time being don't use function's derivatives. The seem to be incorrect.
// optimizer.configuration().setUseFunctionGradient(fitFunction.providesGradient() && useFunctionGradient());
optimizer.configuration().setUseFunctionGradient(false);
optimizer.configuration().setMaxIterations(500);
// optimizer.configuration().setPrintLevel(-2);
}
private IFunction cloneFunction(String name, IFunction originalFunction) {
IFunction fClone = originalFunction;
if (createClone) fClone = FunctionCatalog.getFunctionCatalog().clone(name, originalFunction);
return fClone;
}
public static void main(String args[]) throws java.io.IOException {
IAnalysisFactory af = IAnalysisFactory.create();
ITree tree = af.createTreeFactory().create();
IHistogramFactory hf = af.createHistogramFactory( tree );
ITupleFactory tf = af.createTupleFactory( tree );
IFunctionFactory ff = af.createFunctionFactory( tree );
/*
hep.aida.IHistogram1D hist = hf.createHistogram1D("hist","hist",100,0,1);
hep.aida.IHistogram1D gaussHist = hf.createHistogram1D("gaussHist","gaussHist",100,-5,5);
hep.aida.IHistogram2D hist2d = hf.createHistogram2D("hist2d","hist2d",100,-5,5,10,-10,0);
java.util.Random r = new java.util.Random();
hep.aida.IHistogram1D parabola1 = hf.createHistogram1D("parabola1","parabola1",100,0,1);
hep.aida.IHistogram1D parabola2 = hf.createHistogram1D("parabola2","parabola2",50,0,1);
ITuple tup = tf.create("tup","tup","double x, double y");
for ( int i = 0; i < 5000; i++ ) {
double x = r.nextDouble();
double y = r.nextGaussian()-5;
double w = Math.exp(-.1*x);
hist.fill(x, w);
hist2d.fill(x,y);
tup.fill(0,x);
tup.fill(1,y);
tup.addRow();
parabola1.fill(x,x*x-x+1);
parabola2.fill(x,x*x-x+1);
gaussHist.fill(r.nextGaussian());
}
Fitter fitter = new Fitter("Chi2","uncmin");
// fitter.setConstraint(" mean1 = mean2");
// fitter.setConstraint(" mean1=Math.sqrt(mean2)");
// fitter.setConstraint(" mean1 =2*mean2");
*/
IFunction f = ff.createFunctionByName("parabola","p2");
/*
FitResult fitr1 = (FitResult)fitter.fit(parabola1,f);
fitr1.printResult();
FitResult fitr2 = (FitResult)fitter.fit(parabola2,f);
fitr2.printResult();
/*
IFunction f = ff.createFunctionFromScript("f",1,"b*exp(c*x[0])","b,c","",null);
f.setParameter("b",50);
f.setParameter("c",.1);
// f.setParameter("d",.1);
// fitter.setConstraint( "d = c");
// fitter.fitParameterSettings("c").setFixed(true);
// fitter.fitParameterSettings("d").setFixed(true);
// fitter.setFitMethod("uml");
// FitResult fitResult = (FitResult)fitter.fit( hist, f );
// fitResult.printResult();
fitter.setEngine("minuit");
FitResult fitResult2 = (FitResult)fitter.fit( hist, f );
fitResult2.printResult();
//IFunction f = ff.createFunctionByName("gauss","g");
/*
IModelFunction exp = new ExponentialModel();
FitResult expFitRes = (FitResult)fitter.fit(hist, exp);
expFitRes.printResult();
FitResult expFitRes2 = (FitResult)fitter.fit(hist, "e");
expFitRes2.printResult();
*/
// f.normalize(false);
// f2.normalize(false);
/*
f2.setParameter("mean",0);
f2.setParameter("sigma",1);
f2.setParameter("mean1",-5);
f2.setParameter("sigma1",1);
f2.setParameter("norm",5000);
*/
/*
fitter.fitParameterSettings("sigma").setFixed(true);
// fitter.fitParameterSettings("mean").setFixed(true);
// fitter.fitParameterSettings("sigma1").setFixed(true);
//fitter.fitParameterSettings("mean1").setFixed(true);
// fitter.fitParameterSettings("norm").setFixed(true);
fitter.fitParameterSettings("mean").setStepSize(0.0001);
fitter.fitParameterSettings("sigma").setStepSize(0.01);
fitter.fitParameterSettings("norm").setStepSize(0.1);
fitter.fitParameterSettings("mean1").setStepSize(0.0001);
fitter.fitParameterSettings("sigma1").setStepSize(0.01);
/*
fitter.fit(hist,f);
fitter.setFitMethod("chi2");
fitter.fit(hist,f);
fitter.setEngine("uncmin");
fitter.fit(hist,f);
fitter.setFitMethod("cleverChi2");
fitter.fit(hist,f);
fitter.setFitMethod("bml");
//fitter.setFitMethod("chi2");
fitter.fit(hist,f);
*/
/*
// fitter.setEngine("uncmin");
IEvaluator[] ev = null;
FitData fd = new FitData();
fitter.setFitMethod("chi2");
fitter.setUseFunctionGradient(true);
fitter.fit(hist,f);
fitter.setUseFunctionGradient(false);
fitter.fit(hist,f);
/*
fitter.setFitMethod("uml");
fd.connectPipes(f.variableNames(),tup,ev);
f.normalize(true);
fitter.fit(fd,f);
/*
fitter.setFitMethod("chi2");
fitter.fit(hist2d,f2);
fitter.setFitMethod("uml");
fd.connectPipes(f2.variableNames(),tup,ev);
f2.normalize(true);
fitter.fit(fd,f2);
/*
f2.setParameter("mean",-5);
f2.setParameter("mean1",0);
String[] varNames = {f2.variableName(1),f2.variableName(0)};
FitData fitData = new FitData();
fitData.connectPipes(varNames,hist2d);
fitter.fit(fitData,f2);
hep.aida.IHistogram1D hist2 = hf.createHistogram1D("hist2","hist2",100,0,1);
for ( int i = 0; i < 500; i++ )
hist2.fill(r.nextDouble());
IModelFunction fd = new FlatDistributionModel();
fitter.fit(hist2,fd);
*/
}
private class FitFunction implements IFunction {
private IDevFitDataIterator dataIterator;
private IModelFunction func;
private ArrayList varSimpleConstraint1;
private ArrayList varSimpleConstraint2;
FitFunction(IDevFitDataIterator dataIterator,IModelFunction func) {
this.dataIterator = dataIterator;
this.func = func;
varSimpleConstraint1 = new ArrayList();
varSimpleConstraint2 = new ArrayList();
}
public int dimension() { return func.numberOfParameters(); }
public double value(double[] x) {
if ( varSimpleConstraint1.size() != 0 ) applySimpleConstraint(x);
func.setParameters( x );
return fitMethod.evaluate(dataIterator, func);
}
public boolean providesGradient() { return func.providesParameterGradient(); }
public String variableName(int i) { return func.parameterNames()[i]; }
public String[] variableNames() { return func.parameterNames(); }
public int numberOfParameters() { return 0; }
public double[] gradient(double[] x) {
if ( varSimpleConstraint1.size() != 0 ) applySimpleConstraint(x);
func.setParameters( x );
double[] result = fitMethod.evaluateGradient(dimension(), dataIterator, func);
return result;
}
public boolean isEqual(IFunction f) { throw new UnsupportedOperationException(); }
public IAnnotation annotation() { throw new UnsupportedOperationException(); }
public String codeletString() { throw new UnsupportedOperationException(); }
public void setParameters(double[] params) { throw new UnsupportedOperationException(); }
public double[] parameters() { throw new UnsupportedOperationException(); }
public int indexOfParameter(String name) { throw new UnsupportedOperationException(); }
public String[] parameterNames() { throw new UnsupportedOperationException(); }
public void setParameter(String name, double x) { throw new UnsupportedOperationException(); }
public double parameter(String name) { throw new UnsupportedOperationException(); }
public void setTitle(String str) { throw new UnsupportedOperationException(); }
public String title() { throw new UnsupportedOperationException(); }
public String normalizationParameter() { throw new UnsupportedOperationException(); }
protected int nFreePars() {
int freePars = 0;
String[] names = variableNames();
for( int i = 0; i < names.length; i++ ) {
IFitParameterSettings fitPar = Fitter.this.fitParameterSettings(names[i]);
if ( ! fitPar.isFixed() ) freePars++;
}
return freePars;
}
protected int dataEntries() {
return dataIterator.entries();
}
protected int indexOfVariable( String varName ) {
return func.indexOfParameter( varName );
}
protected void setSimpleConstraint(String varName1, String varName2) {
int ind1 = indexOfVariable( varName1 );
int ind2 = indexOfVariable( varName2 );
if ( ind1 > -1 && ind2 > -1 ) {
varSimpleConstraint1.add( new Integer(ind1) );
varSimpleConstraint2.add( new Integer(ind2) );
}
}
protected boolean isValidSimpleConstraint(String varName1, String varName2 ) {
int ind1 = indexOfVariable( varName1 );
int ind2 = indexOfVariable( varName2 );
if ( ind1 > -1 && ind2 > -1 ) return true;
return false;
}
protected void applySimpleConstraint( double[] x ) {
for ( int i = 0; i < varSimpleConstraint1.size(); i++ ) {
int ind1 = ( (Integer) varSimpleConstraint1.get(i) ).intValue();
int ind2 = ( (Integer) varSimpleConstraint2.get(i) ).intValue();
x[ind1] = x[ind2];
}
}
}
}