package org.freehep.math.minuit; /** * * @version $Id: MnSeedGenerator.java 8584 2006-08-10 23:06:37Z duns $ */ class MnSeedGenerator implements MinimumSeedGenerator { public MinimumSeed generate(MnFcn fcn, GradientCalculator gc, MnUserParameterState st, MnStrategy stra) { int n = st.variableParameters(); MnMachinePrecision prec = st.precision(); // initial starting values MnAlgebraicVector x = new MnAlgebraicVector(n); for( int i = 0; i < n; i++) x.set(i,st.intParameters().get(i)); double fcnmin = fcn.valueOf(x); MinimumParameters pa = new MinimumParameters(x, fcnmin); FunctionGradient dgrad; if (gc instanceof AnalyticalGradientCalculator) { InitialGradientCalculator igc = new InitialGradientCalculator(fcn, st.trafo(), stra); FunctionGradient tmp = igc.gradient(pa); FunctionGradient grd = gc.gradient(pa); dgrad = new FunctionGradient(grd.grad(), tmp.g2(), tmp.gstep()); if (((AnalyticalGradientCalculator) gc).checkGradient()) { boolean good = true; HessianGradientCalculator hgc = new HessianGradientCalculator(fcn, st.trafo(), new MnStrategy(2)); Pair<FunctionGradient, MnAlgebraicVector> hgrd = hgc.deltaGradient(pa, dgrad); for(int i = 0; i < n; i++) { if(Math.abs(hgrd.first.grad().get(i) - grd.grad().get(i)) > hgrd.second.get(i)) { System.err.println("gradient discrepancy of external parameter "+st.trafo().extOfInt(i)+" (internal parameter "+i+") too large."); good = false; } } if(!good) { System.err.println("Minuit does not accept user specified gradient. To force acceptance, override 'virtual bool checkGradient() const' of FCNGradientBase.h in the derived class."); assert(good); } } } else { dgrad = gc.gradient(pa); } MnAlgebraicSymMatrix mat = new MnAlgebraicSymMatrix(n); double dcovar = 1.; if(st.hasCovariance()) { for( int i = 0; i < n; i++) for(int j = i; j < n; j++) mat.set(i,j,st.intCovariance().get(i,j)); dcovar = 0.; } else { for(int i = 0; i < n; i++) mat.set(i,i,(Math.abs(dgrad.g2().get(i)) > prec.eps2() ? 1./dgrad.g2().get(i) : 1.)); } MinimumError err = new MinimumError(mat, dcovar); double edm = new VariableMetricEDMEstimator().estimate(dgrad, err); MinimumState state = new MinimumState(pa, err, dgrad, edm, fcn.numOfCalls()); if(NegativeG2LineSearch.hasNegativeG2(dgrad, prec)) { if (gc instanceof AnalyticalGradientCalculator) { Numerical2PGradientCalculator ngc = new Numerical2PGradientCalculator(fcn, st.trafo(), stra); state = NegativeG2LineSearch.search(fcn, state, ngc, prec); } else { state = NegativeG2LineSearch.search(fcn, state, gc, prec); } } if(stra.strategy() == 2 && !st.hasCovariance()) { //calculate full 2nd derivative MinimumState tmp = new MnHesse(stra).calculate(fcn, state, st.trafo(),0); return new MinimumSeed(tmp, st.trafo()); } return new MinimumSeed(state, st.trafo()); } }