]> granicus.if.org Git - liblinear/commitdiff
Add new region updating rule in TRON method
authorb92paul <b92paul@gmail.com>
Tue, 21 Feb 2017 08:52:58 +0000 (16:52 +0800)
committerb92paul <b92paul@gmail.com>
Tue, 21 Feb 2017 09:01:08 +0000 (17:01 +0800)
The new rule will change delta to delta*sigma3 when
actred >= eta2*prered and step reach trust region boundary in CG
iterations.

Following lines are the changes:
- Add new argument reach_boundary in TRON::trcg method to return whether
step from CG iterations reached boundary or not.
- Add new enlarge rule using the result reach_boundary returned from
TRON::trcg in TRON::tron method.

tron.cpp
tron.h

index 3c32d7f32f502a7ce85bc3bfb0fff570580eb251..6c7e3c70f83844c8233abe62c546be4588d92acc 100644 (file)
--- a/tron.cpp
+++ b/tron.cpp
@@ -91,9 +91,10 @@ void TRON::tron(double *w)
        iter = 1;
 
        double *w_new = new double[n];
+       bool reach_boundary;
        while (iter <= max_iter && search)
        {
-               cg_iter = trcg(delta, g, s, r);
+               cg_iter = trcg(delta, g, s, r, &reach_boundary);
 
                memcpy(w_new, w, sizeof(double)*n);
                daxpy_(&n, &one, s, &inc, w_new, &inc);
@@ -124,7 +125,12 @@ void TRON::tron(double *w)
                else if (actred < eta2*prered)
                        delta = max(sigma1*delta, min(alpha*snorm, sigma3*delta));
                else
-                       delta = max(delta, min(alpha*snorm, sigma3*delta));
+               {
+                       if (reach_boundary)
+                               delta = sigma3*delta;
+                       else
+                               delta = max(delta, min(alpha*snorm, sigma3*delta));
+               }
 
                info("iter %2d act %5.3e pre %5.3e delta %5.3e f %5.3e |g| %5.3e CG %3d\n", iter, actred, prered, delta, f, gnorm, cg_iter);
 
@@ -163,7 +169,7 @@ void TRON::tron(double *w)
        delete[] s;
 }
 
-int TRON::trcg(double delta, double *g, double *s, double *r)
+int TRON::trcg(double delta, double *g, double *s, double *r, bool* reach_boundary)
 {
        int i, inc = 1;
        int n = fun_obj->get_nr_variable();
@@ -172,6 +178,7 @@ int TRON::trcg(double delta, double *g, double *s, double *r)
        double *Hd = new double[n];
        double rTr, rnewTrnew, alpha, beta, cgtol;
 
+       *reach_boundary = false;
        for (i=0; i<n; i++)
        {
                s[i] = 0;
@@ -194,6 +201,7 @@ int TRON::trcg(double delta, double *g, double *s, double *r)
                if (dnrm2_(&n, s, &inc) > delta)
                {
                        info("cg reaches trust region boundary\n");
+                       *reach_boundary = true;
                        alpha = -alpha;
                        daxpy_(&n, &alpha, d, &inc, s, &inc);
 
diff --git a/tron.h b/tron.h
index 56002dcdbd0224d469196375d1aa9e053ae4addc..86b639263f0e3a2ac726895bf7856d96ab99e46a 100644 (file)
--- a/tron.h
+++ b/tron.h
@@ -22,7 +22,7 @@ public:
        void set_print_string(void (*i_print) (const char *buf));
 
 private:
-       int trcg(double delta, double *g, double *s, double *r);
+       int trcg(double delta, double *g, double *s, double *r, bool* reach_boundary);
        double norm_inf(int n, double *x);
 
        double eps;