ext/numo/liblinear/src/newton.cpp in numo-liblinear-2.0.0 vs ext/numo/liblinear/src/newton.cpp in numo-liblinear-2.1.0

- old
+ new

@@ -115,59 +115,60 @@ fun_obj->grad(w0, g); double gnorm0 = dnrm2_(&n, g, &inc); delete [] w0; f = fun_obj->fun(w); - info("init f %5.3e\n", f); fun_obj->grad(w, g); double gnorm = dnrm2_(&n, g, &inc); + info("init f %5.3e |g| %5.3e\n", f, gnorm); if (gnorm <= eps*gnorm0) search = 0; - double *w_new = new double[n]; while (iter <= max_iter && search) { fun_obj->get_diag_preconditioner(M); for(i=0; i<n; i++) M[i] = (1-alpha_pcg) + alpha_pcg*M[i]; cg_iter = pcg(g, M, s, r); fold = f; - step_size = fun_obj->linesearch_and_update(w, s, & f, g, init_step_size); + step_size = fun_obj->linesearch_and_update(w, s, &f, g, init_step_size); if (step_size == 0) { info("WARNING: line search fails\n"); break; } - info("iter %2d f %5.3e |g| %5.3e CG %3d step_size %4.2e \n", iter, f, gnorm, cg_iter, step_size); - - actred = fold - f; - iter++; - fun_obj->grad(w, g); - gnorm = dnrm2_(&n, g, &inc); + + info("iter %2d f %5.3e |g| %5.3e CG %3d step_size %4.2e \n", iter, f, gnorm, cg_iter, step_size); + if (gnorm <= eps*gnorm0) break; if (f < -1.0e+32) { info("WARNING: f < -1.0e+32\n"); break; } + actred = fold - f; if (fabs(actred) <= 1.0e-12*fabs(f)) { info("WARNING: actred too small\n"); break; } + + iter++; } + if(iter >= max_iter) + info("\nWARNING: reaching max number of Newton iterations\n"); + delete[] g; delete[] r; - delete[] w_new; delete[] s; delete[] M; } int NEWTON::pcg(double *g, double *M, double *s, double *r) @@ -175,11 +176,11 @@ int i, inc = 1; int n = fun_obj->get_nr_variable(); double one = 1; double *d = new double[n]; double *Hd = new double[n]; - double zTr, znewTrnew, alpha, beta, cgtol; + double zTr, znewTrnew, alpha, beta, cgtol, dHd; double *z = new double[n]; double Q = 0, newQ, Qdiff; for (i=0; i<n; i++) { @@ -196,13 +197,18 @@ int max_cg_iter = max(n, 5); while (cg_iter < max_cg_iter) { cg_iter++; - fun_obj->Hv(d, Hd); - alpha = zTr/ddot_(&n, d, &inc, Hd, &inc); + fun_obj->Hv(d, Hd); + dHd = ddot_(&n, d, &inc, Hd, &inc); + // avoid 0/0 in getting alpha + if (dHd <= 1.0e-16) + break; + + alpha = zTr/dHd; daxpy_(&n, &alpha, d, &inc, s, &inc); alpha = -alpha; daxpy_(&n, &alpha, Hd, &inc, r, &inc); // Using quadratic approximation as CG stopping criterion @@ -234,10 +240,10 @@ delete[] d; delete[] Hd; delete[] z; - return(cg_iter); + return cg_iter; } void NEWTON::set_print_string(void (*print_string) (const char *buf)) { newton_print_string = print_string;