int TLogRegFit::MLENewton(const double& ChangeEps, const int& MaxStep, const TStr PlotNm) { TExeTm ExeTm; TFltV GradV(Theta.Len()), DeltaLV(Theta.Len()); TFltVV HVV(Theta.Len(), Theta.Len()); int iter = 0; double MinVal = -1e10, MaxVal = 1e10; for(iter = 0; iter < MaxStep; iter++) { Gradient(GradV); Hessian(HVV); GetNewtonStep(HVV, GradV, DeltaLV); double Increment = TLinAlg::DotProduct(GradV, DeltaLV); if (Increment <= ChangeEps) { break; } double LearnRate = GetStepSizeByLineSearch(DeltaLV, GradV, 0.15, 0.5);//InitLearnRate/double(0.01*(double)iter + 1); for(int i = 0; i < Theta.Len(); i++) { double Change = LearnRate * DeltaLV[i]; Theta[i] += Change; if(Theta[i] < MinVal) { Theta[i] = MinVal; } if(Theta[i] > MaxVal) { Theta[i] = MaxVal; } } } if (! PlotNm.Empty()) { printf("MLE with Newton method completed with %d iterations(%s)\n",iter,ExeTm.GetTmStr()); } return iter; }
double TakeStep(OPTOBJ * opt, const double tol, double *factor, int *newbound) { double norm; double *direct, *space; double maxfactor; int i; space = opt->space; direct = opt->space; space += opt->n; for (i = 0; i < opt->n; i++) { opt->onbound[i] = 0; } do { norm = GetNewtonStep(direct, opt->H, opt->dx, opt->n, opt->onbound); } while (UpdateActiveSet (opt->x, direct, ((struct scaleinfo *) opt->state)->scale, opt->H, opt->lb, opt->ub, opt->onbound, opt->n)); /*assert(VectorDotProduct(opt->dx, direct, opt->n));*/ /* Scale step to satisfy trust region */ if ( norm<opt->trust){ scale_vector (direct,opt->n,opt->trust/norm); } *factor = 1.; *newbound = 0; maxfactor = TrimAtBoundaries(opt->x, direct, ((struct scaleinfo *) opt->state)->scale, opt->n, opt->lb, opt->ub, opt->onbound); /* * Three tier decision criteria. i. If Newton step is valid, accept. * ii. If not, look at function and gradient at boundary and decide * whether to accept. iii. Otherwise do line search to find maximum. */ if (maxfactor <= 1.0) { /* Don't accept Newton step -- will hit boundary */ double fbound; ScaledStep(maxfactor, opt->x, opt->xn, direct, opt->onbound, opt->n); fbound = opt->f(opt->xn, opt->state); opt->neval++; if (fbound < opt->fc) { /* * Point on boundary is better than current point, * check grad */ double fnearbound; ScaledStep(maxfactor * (1. - BOUND_TOL), opt->x, opt->xn, direct, opt->onbound, opt->n); fnearbound = opt->f(opt->xn, opt->state); opt->neval++; if (fnearbound > fbound) { /* * If point on boundary appears to be * maximum, keep it */ ScaledStep(maxfactor, opt->x, opt->xn, direct, opt->onbound, opt->n); opt->fn = fbound; *newbound = 1; UpdateActiveSet (opt->xn, direct, ((struct scaleinfo *) opt->state)->scale, opt->H, opt->lb, opt->ub, opt->onbound, opt->n); OPTMESS(printf("Newton step hit boundary, appears optimal (maxfactor = %e)\n",maxfactor);) goto optexit;