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 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 false
    * 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;
}

 

Ads help maintain this website.