package org.freehep.math.minuit;
import java.util.List;
/** Base class for minimizers.
* @version $Id: MnApplication.java 8584 2006-08-10 23:06:37Z duns $
*/
public abstract class MnApplication
{
static int DEFAULT_STRATEGY = 1;
static int DEFAULT_MAXFCN = 0;
static double DEFAULT_TOLER = 0.1;
MnApplication(FCNBase fcn, MnUserParameterState state, MnStrategy stra)
{
theFCN = fcn;
theState = state;
theStrategy = stra;
checkAnalyticalDerivatives = true;
useAnalyticalDerivatives = true;
}
MnApplication(FCNBase fcn, MnUserParameterState state, MnStrategy stra, int nfcn)
{
theFCN = fcn;
theState = state;
theStrategy = stra;
theNumCall = nfcn;
checkAnalyticalDerivatives = true;
useAnalyticalDerivatives = true;
}
/**
*
*/
public FunctionMinimum minimize()
{
return minimize(DEFAULT_MAXFCN);
}
public FunctionMinimum minimize(int maxfcn)
{
return minimize(maxfcn,DEFAULT_TOLER);
}
/**
* Causes minimization of the FCN and returns the result in form of a FunctionMinimum.
* @param maxfcn specifies the (approximate) maximum number of function calls after
* which the calculation will be stopped even if it has not yet converged.
* @param toler specifies the required tolerance on the function value at the minimum.
* The default tolerance value is 0.1, and the minimization will stop when the
* estimated vertical distance to the minimum (EDM) is less than 0:001*tolerance*errorDef
*/
public FunctionMinimum minimize(int maxfcn, double toler)
{
if(!theState.isValid()) throw new RuntimeException("Invalid state");
int npar = variableParameters();
if(maxfcn == 0) maxfcn = 200 + 100*npar + 5*npar*npar;
FunctionMinimum min = minimizer().minimize(theFCN, theState, theStrategy, maxfcn, toler, theErrorDef, useAnalyticalDerivatives,checkAnalyticalDerivatives);
theNumCall += min.nfcn();
theState = min.userState();
return min;
}
abstract ModularFunctionMinimizer minimizer();
public MnMachinePrecision precision()
{
return theState.precision();
}
public MnUserParameterState state()
{
return theState;
}
public MnUserParameters parameters()
{
return theState.parameters();
}
public MnUserCovariance covariance()
{
return theState.covariance();
}
public FCNBase fcnbase()
{
return theFCN;
}
public MnStrategy strategy()
{
return theStrategy;
}
public int numOfCalls()
{
return theNumCall;
}
// facade: forward interface of MnUserParameters and MnUserTransformation
// via MnUserParameterState
/** access to parameters (row-wise) */
List<MinuitParameter> minuitParameters()
{
return theState.minuitParameters();
}
/** access to parameters and errors in column-wise representation */
public double[] params()
{
return theState.params();
}
public double[] errors()
{
return theState.errors();
}
/** access to single parameter */
MinuitParameter parameter(int i)
{
return theState.parameter(i);
}
/** add free parameter */
public void add(String name, double val, double err)
{
theState.add(name, val, err);
}
/** add limited parameter */
public void add(String name, double val, double err, double low, double up)
{
theState.add(name, val, err, low, up);
}
/** add const parameter */
public void add(String name, double val)
{
theState.add(name, val);
}
//interaction via external number of parameter
public void fix(int index)
{
theState.fix(index);
}
public void release(int index)
{
theState.release(index);
}
public void setValue(int index, double val)
{
theState.setValue(index,val);
}
public void setError(int index, double err)
{
theState.setError(index,err);
}
public void setLimits(int index, double low, double up)
{
theState.setLimits(index,low,up);
}
public void removeLimits(int index)
{
theState.removeLimits(index);
}
public double value(int index)
{
return theState.value(index);
}
public double error(int index)
{
return theState.error(index);
}
//interaction via name of parameter
public void fix(String name)
{
theState.fix(name);
}
public void release(String name)
{
theState.release(name);
}
public void setValue(String name, double val)
{
theState.setValue(name,val);
}
public void setError(String name, double err)
{
theState.setError(name,err);
}
public void setLimits(String name, double low, double up)
{
theState.setLimits(name,low,up);
}
public void removeLimits(String name)
{
theState.removeLimits(name);
}
public void setPrecision(double prec)
{
theState.setPrecision(prec);
}
public double value(String name)
{
return theState.value(name);
}
public double error(String name)
{
return theState.error(name);
}
/** convert name into external number of parameter */
public int index(String name)
{
return theState.index(name);
}
/** convert external number into name of parameter */
public String name(int index)
{
return theState.name(index);
}
// transformation internal <-> external
double int2ext(int i, double value)
{
return theState.int2ext(i,value);
}
double ext2int(int i, double value)
{
return theState.ext2int(i,value);
}
int intOfExt(int i)
{
return theState.intOfExt(i);
}
int extOfInt(int i)
{
return theState.extOfInt(i);
}
public int variableParameters()
{
return theState.variableParameters();
}
/**
* By default if the function to be minimized implements FCNGradientBase then the
* analytical gradient provided by the function will be used. Set this to <CODE>false</CODE>
* to disable this behaviour and force numerical calculation of the gradient.
*/
public void setUseAnalyticalDerivatives(boolean use)
{
useAnalyticalDerivatives = use;
}
public boolean useAnalyticalDerivaties()
{
return useAnalyticalDerivatives;
}
/**
* Minuit does a check of the user gradient at the beginning, if this is not
* wanted the set this to "false".
*/
public void setCheckAnalyticalDerivatives(boolean check)
{
checkAnalyticalDerivatives = check;
}
public boolean checkAnalyticalDerivatives()
{
return checkAnalyticalDerivatives;
}
/** errorDef() is the error definition of the function.
* E.g. is 1 if function is Chi2 and
* 0.5 if function is -logLikelihood. If the user wants instead the 2-sigma
* errors, errorDef() = 4, as Chi2(x+n*sigma) = Chi2(x) + n*n.
*/
public void setErrorDef(double errorDef)
{
theErrorDef = errorDef;
}
public double errorDef()
{
return theErrorDef;
}
/* package protected */ boolean useAnalyticalDerivatives;
/* package protected */ boolean checkAnalyticalDerivatives;
/* package protected */ FCNBase theFCN;
/* package protected */ MnUserParameterState theState;
/* package protected */ MnStrategy theStrategy;
/* package protected */ int theNumCall;
/* package protected */ double theErrorDef = 1;
}