ROOT   Reference Guide
Searching...
No Matches
NegativeG2LineSearch.cxx
Go to the documentation of this file.
1// @(#)root/minuit2:$Id$
2// Authors: M. Winkler, F. James, L. Moneta, A. Zsenei 2003-2005
3
4/**********************************************************************
5 * *
6 * Copyright (c) 2005 LCG ROOT Math team, CERN/PH-SFT *
7 * *
8 **********************************************************************/
9
11#include "Minuit2/MnFcn.h"
18#include "Minuit2/MnPrint.h"
19
20#include <cmath>
21
22namespace ROOT {
23
24namespace Minuit2 {
25
27 const MnMachinePrecision &prec) const
28{
29
30 // when the second derivatives are negative perform a line search along Parameter which gives
31 // negative second derivative and magnitude equal to the Gradient step size.
32 // Recalculate the gradients for all the Parameter after the correction and
33 // continue iteration in case the second derivatives are still negative
34 //
35 MnPrint print("NegativeG2LineSearch");
36
37 bool negG2 = HasNegativeG2(st.Gradient(), prec);
38 if (!negG2)
39 return st;
40
41 print.Info("Doing a NegativeG2LineSearch since one of the G2 component is negative");
42
43 unsigned int n = st.Parameters().Vec().size();
46 bool iterate = false;
47 unsigned int iter = 0;
48 // in case of analytical gradients we don't have step sizes
51 // gradient present in the state must have G2 otherwise something is wrong
54 return st;
55 }
56
57 do {
58 iterate = false;
59 for (unsigned int i = 0; i < n; i++) {
60
61 if (dgrad.G2()(i) <= 0) {
62
63 // check also the gradient (if it is zero ) I can skip the param)
64
66 continue;
67 // if(dgrad.G2()(i) < prec.Eps()) {
68 // do line search if second derivative negative
69 MnAlgebraicVector step(n);
70 MnLineSearch lsearch;
71
72 // when using analytical gradient use as step size a dummy value of 1
73 // maybe could do better using user given parameter step sizes
74 // tested using inverse of G2() gives worse behaviour
76 step(i) = (hasGStep) ? dgrad.Gstep()(i) : 1;
77 else
78 step(i) = (hasGStep) ? -dgrad.Gstep()(i) : -1;
79
80 double gdel = step(i) * dgrad.Vec()(i);
81
82 // if using sec derivative information
83 // double g2del = step(i)*step(i) * dgrad.G2()(i);
84
87
88 MnParabolaPoint pp = lsearch(fcn, pa, step, gdel, prec);
89
90 print.Debug("Line search result", pp.X(), "f(0)", pa.Fval(), "f(1)", pp.Y());
91
92 step *= pp.X();
93 pa = MinimumParameters(pa.Vec() + step, pp.Y());
94
96 // re-compute also G2 if needed
98 //no need to compute Hessian here but only G2
99 print.Debug("Compute G2 at the new point", pa.Vec());
101 bool ret = gc.G2(pa,g2);
102 if (!ret) {
103 print.Error("Cannot compute G2");
104 assert(false);
105 return st;
106 }
107
109 }
110
111 print.Debug("New result after Line search - iter", iter, "param", i, pa.Vec()(i), "step", step(i), "new grad2",
113
114 iterate = true;
115 break;
116 }
117 }
118 } while (iter++ < 2 * n && iterate);
119
120 // even if we computed the Hessian it is still better to use the diagonal part, the G2
121 print.Debug("Approximate new covariance after NegativeG2LS using only G2");
123 for (unsigned int i = 0; i < n; i++) {
124 mat(i, i) = std::fabs(dgrad.G2()(i)) > prec.Eps() ? 1. / dgrad.G2()(i) :
125 1; // use an arbitrary value (e.g. 1)
126 }
127
128 MinimumError err(mat, 1.);
129 double edm = VariableMetricEDMEstimator().Estimate(dgrad, err);
130
131 if (edm < 0) {
133 }
134
135 return MinimumState(pa, err, dgrad, edm, fcn.NumOfCalls());
136}
137
139{
140 // check if function gradient has any component which is negative
141
142 for (unsigned int i = 0; i < grad.Vec().size(); i++)
143
144 if (grad.G2()(i) <= 0) {
145
146 return true;
147 }
148
149 return false;
150}
151
152} // namespace Minuit2
153
154} // namespace ROOT
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void gc
const MnAlgebraicVector & Gstep() const
const MnAlgebraicVector & Vec() const
const MnAlgebraicVector & G2() const
Class describing a symmetric matrix of size n.
Definition LASymMatrix.h:45
unsigned int size() const
Definition LAVector.h:231
MinimumError keeps the inv.
const MnAlgebraicVector & Vec() const
MinimumState keeps the information (position, Gradient, 2nd deriv, etc) after one minimization step (...
const MinimumParameters & Parameters() const
Wrapper class to FCNBase interface used internally by Minuit.
Definition MnFcn.h:30
unsigned int NumOfCalls() const
Definition MnFcn.h:39
Implements a 1-dimensional minimization along a given direction (i.e.
Sets the relative floating point (double) arithmetic precision.
double Eps() const
eps returns the smallest possible number so that 1.+eps > 1.
double Y() const
Accessor to the y (second) coordinate.
double X() const
Accessor to the x (first) coordinate.
void Debug(const Ts &... args)
Definition MnPrint.h:147
void Error(const Ts &... args)
Definition MnPrint.h:129
void Info(const Ts &... args)
Definition MnPrint.h:141
bool HasNegativeG2(const FunctionGradient &, const MnMachinePrecision &) const
MinimumState operator()(const MnFcn &, const MinimumState &, const GradientCalculator &, const MnMachinePrecision &) const
double Estimate(const FunctionGradient &, const MinimumError &) const
const Int_t n
Definition legend1.C:16
int iterate(rng_state_t *X)
Definition mixmax.icc:34
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...