From ae7a40bd771f8eb26f83dfb77c103e769c5af8d4 Mon Sep 17 00:00:00 2001 From: Jiri Pittner Date: Mon, 26 Oct 2026 11:34:03 +0100 Subject: [PATCH] optimize: reorganization of hyperparameters and optevaluator and optstate --- optimize.cc | 126 ++++++++++++++++++++++++++-------------------------- optimize.h | 82 +++++++++++++++++++++++++++++----- 2 files changed, 134 insertions(+), 74 deletions(-) diff --git a/optimize.cc b/optimize.cc index 641d3cf..c1b8053 100644 --- a/optimize.cc +++ b/optimize.cc @@ -70,14 +70,19 @@ return r; template -T linesearch_wolfe(const OptProblem *o, NRVec &x, T &f, NRVec &g, const NRVec &p, T alpha1, const T c1, const T c2, const T alphamax, const int maxiter, int &nfunc, const int verbose) +T linesearch_wolfe(optevaluator &e, NRVec &x, T &f, NRVec &g, const NRVec &p, const T alpha1, const linesearch_hyperparameters &lp) { +const T c1=lp.my_c1; +const T c2=lp.my_c2; +const int verbose=lp.my_verbose; +const int maxiter= std::min(lp.my_maxlinesearch,e.remaining()); const int n=x.size(); const NRVec x0(x); const T f0=f; const T d0= g*p; if(d0>=0) {if(verbose) std::cout <<"linesearch: not a descent direction\n"; return 0;} -if(alpha1>alphamax) alpha1=alphamax; +const T alphamax=lp.my_maxsteplength/p.norm(); +T alpha=std::min(alpha1,alphamax); //data of trial points; vectors are always freshly allocated, so that assignments (which share data) are safe T alpha0=0, f_alpha0=f0, d_alpha0=d0; NRVec x_alpha0(x0), g_alpha0(g); //previous trial point @@ -88,28 +93,28 @@ int it; //bracketing phase for(it=0; it xt = x0 + p*alpha1; + NRVec xt = x0 + p*alpha; NRVec gt(n); - T ft=o->funcgrad(xt,>); ++nfunc; + T ft=e(xt,>); T dt= gt*p; - if(verbose>1) std::cout <<"linesearch bracket "< +optresult optstate::finish(hyperparameters *achieved) const +{ +if(hp.my_verbose) + { + std::cout < e(o,hp.my_maxfunc); +optstate st("BFGS",hp,e); const int n=x.size(); NRVec g(n); -T f=o->funcgrad(x,&g); -int nfunc=1; +T f=e(x,&g); NRSMat H(n); H=1.; bool Hinit=true; //H is the initial guess, rescale it after the first step -bool converged=false; -T last_df=0, last_dx=0; -int iter; -for(iter=0; iter p = H*g; p *= (T)-1; @@ -205,15 +229,11 @@ for(iter=0; iter xold(x), gold(g); T fold=f; - T pnorm=p.norm(); - T alpha1 = Hinit ? 1/pnorm : 1; //on the first step (or after restart) try unit step length in x, otherwise the Newton step - T alphamax = hp.my_maxsteplength/pnorm; - int maxls=hp.my_maxlinesearch; - if(hp.my_maxfunc>0 && hp.my_maxfunc-nfunc0 && nfunc>=hp.my_maxfunc) continue; //reported at the top of the loop + if(e.exhausted()) continue; //reported by stop() if(Hinit) {if(verbose) std::cout <<"BFGS: line search failed along steepest descent, giving up\n"; break;} if(verbose) std::cout <<"BFGS: line search failed, resetting inverse Hessian\n"; H=1.; Hinit=true; @@ -232,39 +252,17 @@ for(iter=0; iter