23 #if defined(DEBUG) || defined(WARNINGMSG)
34 FunctionGradient HessianGradientCalculator::operator()(
const MinimumParameters& par)
const {
36 InitialGradientCalculator gc(fFcn, fTransformation, fStrategy);
37 FunctionGradient gra = gc(par);
39 return (*
this)(par, gra);
42 FunctionGradient HessianGradientCalculator::operator()(
const MinimumParameters& par,
const FunctionGradient& Gradient)
const {
44 std::pair<FunctionGradient, MnAlgebraicVector> mypair = DeltaGradient(par, Gradient);
49 const MnMachinePrecision& HessianGradientCalculator::Precision()
const {
51 return fTransformation.Precision();
54 unsigned int HessianGradientCalculator::Ncycle()
const {
56 return Strategy().HessianGradientNCycles();
59 double HessianGradientCalculator::StepTolerance()
const {
61 return Strategy().GradientStepTolerance();
64 double HessianGradientCalculator::GradTolerance()
const {
66 return Strategy().GradientTolerance();
69 std::pair<FunctionGradient, MnAlgebraicVector> HessianGradientCalculator::DeltaGradient(
const MinimumParameters& par,
const FunctionGradient& Gradient)
const {
71 assert(par.IsValid());
73 MnAlgebraicVector x = par.Vec();
74 MnAlgebraicVector grd = Gradient.Grad();
75 const MnAlgebraicVector& g2 = Gradient.G2();
78 MnAlgebraicVector gstep = Gradient.Gstep();
80 double fcnmin = par.Fval();
83 double dfmin = 4.*Precision().Eps2()*(fabs(fcnmin)+Fcn().Up());
85 unsigned int n = x.size();
86 MnAlgebraicVector dgrd(n);
88 MPIProcess mpiproc(n,0);
90 unsigned int startElementIndex = mpiproc.StartElementIndex();
91 unsigned int endElementIndex = mpiproc.EndElementIndex();
93 for(
unsigned int i = startElementIndex; i < endElementIndex; i++) {
95 double dmin = 4.*Precision().Eps2()*(xtf + Precision().Eps2());
96 double epspri = Precision().Eps2() + fabs(grd(i)*Precision().Eps2());
97 double optstp = sqrt(dfmin/(fabs(g2(i))+epspri));
98 double d = 0.2*fabs(gstep(i));
99 if(d > optstp) d = optstp;
100 if(d < dmin) d = dmin;
101 double chgold = 10000.;
105 for(
unsigned int j = 0; j < Ncycle(); j++) {
107 double fs1 = Fcn()(x);
109 double fs2 = Fcn()(x);
115 grdnew = (fs1-fs2)/(2.*d);
116 dgmin = Precision().Eps()*(fabs(fs1) + fabs(fs2))/d;
118 if (grdnew == 0)
break;
119 double change = fabs((grdold-grdnew)/grdnew);
120 if(change > chgold && j > 1)
break;
126 if(change < 0.05)
break;
127 if(fabs(grdold-grdnew) < dgmin)
break;
132 dgrd(i) = std::max(dgmin, fabs(grdold-grdnew));
135 std::cout <<
"HGC Param : " << i <<
"\t new g1 = " << grd(i) <<
" gstep = " << d <<
" dgrd = " << dgrd(i) << std::endl;
140 mpiproc.SyncVector(grd);
141 mpiproc.SyncVector(gstep);
142 mpiproc.SyncVector(dgrd);
144 return std::pair<FunctionGradient, MnAlgebraicVector>(FunctionGradient(grd, g2, gstep), dgrd);