24 #if defined(DEBUG) || defined(WARNINGMSG) 
   27 #if defined(DEBUG) && !defined(WARNINGMSG) 
   38 MnUserParameterState MnHesse::operator()(
const FCNBase& fcn, 
const std::vector<double>& par, 
const std::vector<double>& err, 
unsigned int maxcalls)
 const {
 
   40    return (*
this)(fcn, MnUserParameterState(par, err), maxcalls);
 
   43 MnUserParameterState MnHesse::operator()(
const FCNBase& fcn, 
const std::vector<double>& par, 
unsigned int nrow, 
const std::vector<double>& cov,  
unsigned int maxcalls)
 const {
 
   45    return (*
this)(fcn, MnUserParameterState(par, cov, nrow), maxcalls);
 
   48 MnUserParameterState MnHesse::operator()(
const FCNBase& fcn, 
const std::vector<double>& par, 
const MnUserCovariance& cov, 
unsigned int maxcalls)
 const {
 
   50    return (*
this)(fcn, MnUserParameterState(par, cov), maxcalls);
 
   53 MnUserParameterState MnHesse::operator()(
const FCNBase& fcn, 
const MnUserParameters& par, 
unsigned int maxcalls)
 const {
 
   55    return (*
this)(fcn, MnUserParameterState(par), maxcalls);
 
   58 MnUserParameterState MnHesse::operator()(
const FCNBase& fcn, 
const MnUserParameters& par, 
const MnUserCovariance& cov, 
unsigned int maxcalls)
 const {
 
   60    return (*
this)(fcn, MnUserParameterState(par, cov), maxcalls);
 
   63 MnUserParameterState MnHesse::operator()(
const FCNBase& fcn, 
const MnUserParameterState& state, 
unsigned int maxcalls)
 const {
 
   66    unsigned int n = state.VariableParameters();
 
   67    MnUserFcn mfcn(fcn, state.Trafo(),state.NFcn());
 
   68    MnAlgebraicVector x(n);
 
   69    for(
unsigned int i = 0; i < n; i++) x(i) = state.IntParameters()[i];
 
   70    double amin = mfcn(x);
 
   71    Numerical2PGradientCalculator gc(mfcn, state.Trafo(), fStrategy);
 
   72    MinimumParameters par(x, amin);
 
   73    FunctionGradient gra = gc(par);
 
   74    MinimumState tmp = (*this)(mfcn, MinimumState(par, MinimumError(MnAlgebraicSymMatrix(n), 1.), gra, state.Edm(), state.NFcn()), state.Trafo(), maxcalls);
 
   76    return MnUserParameterState(tmp, fcn.Up(), state.Trafo());
 
   79 void MnHesse::operator()(
const FCNBase& fcn, FunctionMinimum& min, 
unsigned int maxcalls)
 const {
 
   83    MnUserFcn mfcn(fcn, min.UserState().Trafo(),min.NFcn());
 
   84    MinimumState st = (*this)( mfcn, min.State(), min.UserState().Trafo(), maxcalls);
 
   88 MinimumState MnHesse::operator()(
const MnFcn& mfcn, 
const MinimumState& st, 
const MnUserTransformation& trafo, 
unsigned int maxcalls)
 const {
 
   92    const MnMachinePrecision& prec = trafo.Precision();
 
   94    double amin = mfcn(st.Vec());
 
   95    double aimsag = sqrt(prec.Eps2())*(fabs(amin)+mfcn.Up());
 
   99    unsigned int n = st.Parameters().Vec().size();
 
  100    if(maxcalls == 0) maxcalls = 200 + 100*n + 5*n*n;
 
  102    MnAlgebraicSymMatrix vhmat(n);
 
  103    MnAlgebraicVector g2 = st.Gradient().G2();
 
  104    MnAlgebraicVector gst = st.Gradient().Gstep();
 
  105    MnAlgebraicVector grd = st.Gradient().Grad();
 
  106    MnAlgebraicVector dirin = st.Gradient().Gstep();
 
  107    MnAlgebraicVector yy(n);
 
  112    if(st.Gradient().IsAnalytical()  ) {
 
  113       Numerical2PGradientCalculator igc(mfcn, trafo, fStrategy);
 
  114       FunctionGradient tmp = igc(st.Parameters());
 
  120    MnAlgebraicVector x = st.Parameters().Vec();
 
  123    std::cout << 
"\nMnHesse " << std::endl;
 
  124    std::cout << 
" x " << x << std::endl;
 
  125    std::cout << 
" amin " << amin << 
"  " << st.Fval() << std::endl;
 
  126    std::cout << 
" grd " << grd << std::endl;
 
  127    std::cout << 
" gst " << gst << std::endl;
 
  128    std::cout << 
" g2  " << g2 << std::endl;
 
  129    std::cout << 
" Gradient is analytical  " << st.Gradient().IsAnalytical() << std::endl;
 
  133    for(
unsigned int i = 0; i < n; i++) {
 
  136       double dmin = 8.*prec.Eps2()*(fabs(xtf) + prec.Eps2());
 
  137       double d = fabs(gst(i));
 
  138       if(d < dmin) d = dmin;
 
  141       std::cout << 
"\nDerivative parameter  " << i << 
" d = " << d << 
" dmin = " << dmin << std::endl;
 
  145       for(
unsigned int icyc = 0; icyc < Ncycles(); icyc++) {
 
  149          for(
unsigned int multpy = 0; multpy < 5; multpy++) {
 
  155             sag = 0.5*(fs1+fs2-2.*amin);
 
  158             std::cout << 
"cycle " << icyc << 
" mul " << multpy << 
"\t sag = " << sag << 
" d = " << d << std::endl;
 
  161             if (sag != 0) 
goto L30; 
 
  162             if(trafo.Parameter(i).HasLimits()) {
 
  163                if(d > 0.5) 
goto L26;
 
  165                if(d > 0.5) d = 0.51;
 
  177             const char * name = trafo.Name( trafo.ExtOfInt(i));
 
  178             MN_INFO_VAL2(
"MnHesse: 2nd derivative zero for Parameter ", name);
 
  179             MN_INFO_MSG(
"MnHesse fails and will return diagonal matrix ");
 
  183          for(
unsigned int j = 0; j < n; j++) {
 
  184             double tmp = g2(j) < prec.Eps2() ? 1. : 1./g2(j);
 
  185             vhmat(j,j) = tmp < prec.Eps2() ? 1. : tmp;
 
  188          return MinimumState(st.Parameters(), MinimumError(vhmat, MinimumError::MnHesseFailed()), st.Gradient(), st.Edm(), mfcn.NumOfCalls());
 
  191             double g2bfor = g2(i);
 
  192          g2(i) = 2.*sag/(d*d);
 
  193          grd(i) = (fs1-fs2)/(2.*d);
 
  198          d = sqrt(2.*aimsag/fabs(g2(i)));
 
  199          if(trafo.Parameter(i).HasLimits()) d = std::min(0.5, d);
 
  200          if(d < dmin) d = dmin;
 
  203          std::cout << 
"\t g1 = " << grd(i) << 
" g2 = " << g2(i) << 
" step = " << gst(i) << 
" d = " << d
 
  204                    << 
" diffd = " <<  fabs(d-dlast)/d << 
" diffg2 = " << fabs(g2(i)-g2bfor)/g2(i) << std::endl;
 
  209          if(fabs((d-dlast)/d) < Tolerstp()) 
break;
 
  210          if(fabs((g2(i)-g2bfor)/g2(i)) < TolerG2()) 
break;
 
  211          d = std::min(d, 10.*dlast);
 
  212          d = std::max(d, 0.1*dlast);
 
  215       if(mfcn.NumOfCalls()  > maxcalls) {
 
  219          MN_INFO_MSG(
"MnHesse: maximum number of allowed function calls exhausted.");
 
  220          MN_INFO_MSG(
"MnHesse fails and will return diagonal matrix ");
 
  223          for(
unsigned int j = 0; j < n; j++) {
 
  224             double tmp = g2(j) < prec.Eps2() ? 1. : 1./g2(j);
 
  225             vhmat(j,j) = tmp < prec.Eps2() ? 1. : tmp;
 
  228          return MinimumState(st.Parameters(), MinimumError(vhmat, MinimumError::MnHesseFailed()), st.Gradient(), st.Edm(), mfcn.NumOfCalls());
 
  234    std::cout << 
"\n Second derivatives " << g2 << std::endl;
 
  237    if(fStrategy.Strategy() > 0) {
 
  239       HessianGradientCalculator hgc(mfcn, trafo, fStrategy);
 
  240       FunctionGradient gr = hgc(st.Parameters(), FunctionGradient(grd, g2, gst));
 
  249       MPIProcess mpiprocOffDiagonal(n*(n-1)/2,0);
 
  250       unsigned int startParIndexOffDiagonal = mpiprocOffDiagonal.StartElementIndex();
 
  251       unsigned int endParIndexOffDiagonal = mpiprocOffDiagonal.EndElementIndex();
 
  253       unsigned int offsetVect = 0;
 
  254       for (
unsigned int in = 0; in<startParIndexOffDiagonal; in++)
 
  255          if ((in+offsetVect)%(n-1)==0) offsetVect += (in+offsetVect)/(n-1);
 
  257       for (
unsigned int in = startParIndexOffDiagonal;
 
  258            in<endParIndexOffDiagonal; in++) {
 
  260          int i = (in+offsetVect)/(n-1);
 
  261          if ((in+offsetVect)%(n-1)==0) offsetVect += i;
 
  262          int j = (in+offsetVect)%(n-1)+1;
 
  264          if ((i+1)==j || in==startParIndexOffDiagonal)
 
  269          double fs1 = mfcn(x);
 
  270          double elem = (fs1 + amin - yy(i) - yy(j))/(dirin(i)*dirin(j));
 
  275          if (j%(n-1)==0 || in==endParIndexOffDiagonal-1)
 
  280       mpiprocOffDiagonal.SyncSymMatrixOffDiagonal(vhmat);
 
  286    std::cout << 
"Original error matrix " << vhmat << std::endl;
 
  289    MinimumError tmpErr = MnPosDef()(MinimumError(vhmat,1.), prec);
 
  292    std::cout << 
"Original error matrix " << vhmat << std::endl;
 
  295    vhmat = tmpErr.InvHessian();
 
  298    std::cout << 
"PosDef error matrix " << vhmat << std::endl;
 
  302    int ifail = Invert(vhmat);
 
  306       MN_INFO_MSG(
"MnHesse: matrix inversion fails!");
 
  307       MN_INFO_MSG(
"MnHesse fails and will return diagonal matrix.");
 
  310       MnAlgebraicSymMatrix tmpsym(vhmat.Nrow());
 
  311       for(
unsigned int j = 0; j < n; j++) {
 
  312          double tmp = g2(j) < prec.Eps2() ? 1. : 1./g2(j);
 
  313          tmpsym(j,j) = tmp < prec.Eps2() ? 1. : tmp;
 
  316       return MinimumState(st.Parameters(), MinimumError(tmpsym, MinimumError::MnInvertFailed()), st.Gradient(), st.Edm(), mfcn.NumOfCalls());
 
  319    FunctionGradient gr(grd, g2, gst);
 
  320    VariableMetricEDMEstimator estim;
 
  323    if(tmpErr.IsMadePosDef()) {
 
  324       MinimumError err(vhmat, MinimumError::MnMadePosDef() );
 
  325       double edm = estim.Estimate(gr, err);
 
  327       MN_INFO_MSG(
"MnHesse: matrix was forced pos. def. ");
 
  329       return MinimumState(st.Parameters(), err, gr, edm, mfcn.NumOfCalls());
 
  333    MinimumError err(vhmat, 0.);
 
  334    double edm = estim.Estimate(gr, err);
 
  337    std::cout << 
"\nHesse is ACCURATE. New state from MnHesse " << std::endl;
 
  338    std::cout << 
"Gradient " << grd << std::endl;
 
  339    std::cout << 
"Second Deriv " << g2 << std::endl;
 
  340    std::cout << 
"Gradient step " << gst << std::endl;
 
  341    std::cout << 
"Error  " << vhmat  << std::endl;
 
  342    std::cout << 
"edm  " << edm  << std::endl;
 
  346    return MinimumState(st.Parameters(), err, gr, edm, mfcn.NumOfCalls());