void TRON::tron(double *w) { // Parameters for updating the iterates. double eta0 = 1e-4, eta1 = 0.25, eta2 = 0.75; // Parameters for updating the trust region size delta. double sigma1 = 0.25, sigma2 = 0.5, sigma3 = 4; Int n = fun_obj->get_nr_variable(); Int i, cg_iter; double delta, snorm, one=1.0; double alpha, f, fnew, prered, actred, gs; Int search = 1, iter = 1, inc = 1; double *s = new double[n]; double *r = new double[n]; double *g = new double[n]; // calculate gradient norm at w=0 for stopping condition. double *w0 = new double[n]; for (i=0; i<n; i++) w0[i] = 0; fun_obj->fun(w0); fun_obj->grad(w0, g); double gnorm0 = dnrm2_(&n, g, &inc); delete [] w0; f = fun_obj->fun(w); fun_obj->grad(w, g); delta = dnrm2_(&n, g, &inc); double gnorm = delta; if (gnorm <= eps*gnorm0) search = 0; iter = 1; double *w_new = new double[n]; while (iter <= max_iter && search) { cg_iter = trcg(delta, g, s, r); memcpy(w_new, w, sizeof(double)*n); daxpy_(&n, &one, s, &inc, w_new, &inc); gs = ddot_(&n, g, &inc, s, &inc); prered = -0.5*(gs-ddot_(&n, s, &inc, r, &inc)); fnew = fun_obj->fun(w_new); // Compute the actual reduction. actred = f - fnew; // On the first iteration, adjust the initial step bound. snorm = dnrm2_(&n, s, &inc); if (iter == 1) delta = min(delta, snorm); // Compute prediction alpha*snorm of the step. if (fnew - f - gs <= 0) alpha = sigma3; else alpha = max(sigma1, -0.5*(gs/(fnew - f - gs))); // Update the trust region bound according to the ratio of actual to predicted reduction. if (actred < eta0*prered) delta = min(max(alpha, sigma1)*snorm, sigma2*delta); else if (actred < eta1*prered) delta = max(sigma1*delta, min(alpha*snorm, sigma2*delta)); else if (actred < eta2*prered) delta = max(sigma1*delta, min(alpha*snorm, 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); if (actred > eta0*prered) { iter++; memcpy(w, w_new, sizeof(double)*n); f = fnew; fun_obj->grad(w, g); gnorm = dnrm2_(&n, g, &inc); if (gnorm <= eps*gnorm0) break; } if (f < -1.0e+32) { info("WARNING: f < -1.0e+32\n"); break; } if (fabs(actred) <= 0 && prered <= 0) { info("WARNING: actred and prered <= 0\n"); break; } if (fabs(actred) <= 1.0e-12*fabs(f) && fabs(prered) <= 1.0e-12*fabs(f)) { info("WARNING: actred and prered too small\n"); break; } } delete[] g; delete[] r; delete[] w_new; delete[] s; }
void TRON::tron(double *w) { int i; srand(0); double eta = 1e-4; int n = fun_obj->get_nr_variable(); int l = fun_obj->get_nr_instance(); double gnorm1, alpha, f, fnew, actred, gs; int cg_iter, search = 1, iter = 1, inc = 1; long int num_data = 0; int *Hsample = new int[l]; double *s = new double[n]; double *r = new double[n]; double *w_new = new double[n]; double *g = new double[n]; for (i=0; i<l; i++) Hsample[i] = rand() % num_sample; for (i=0; i<n; i++) { s[i] = 0.0; w[i] = 0.0; } f = fun_obj->fun(w, &num_data); iter = 1; fun_obj->grad(w, g, Hsample, iter, num_sample, &num_data); gnorm1 = dnrm2_(&n, g, &inc); double gnorm = gnorm1; if (gnorm <= eps*gnorm1) search = 0; double sTs,shift_time = 0.0,cg_time = 0.0,line_search_time = 0.0; const clock_t start = clock(); while (iter <= max_iter && search) { info("FUN %20.15e TIME %20.15e\n", f,(double)(clock()-start)/CLOCKS_PER_SEC); const clock_t begin_time = clock(); cg_iter = trcg(g, s, r, num_sample,&num_data); cg_time = float(clock() - begin_time)/CLOCKS_PER_SEC; gs = ddot_(&n, g, &inc, s, &inc); // ***Method 1*** if(num_sample == 1) { alpha = 1; }else{ sTs = ddot_(&n, s, &inc, s, &inc); fun_obj->get_alpha(&alpha, gs, sTs, s, &num_data); for(i=0;i<n;i++) s[i] *= alpha; gs = alpha*gs; alpha = 1; } const clock_t line_begin_time = clock(); alpha = 1; while(1) { memcpy(w_new, w, sizeof(double)*n); daxpy_(&n, &alpha, s, &inc, w_new, &inc); fnew = fun_obj->fun(w_new,&num_data); actred = f - fnew; if (actred+eta*alpha*gs >= 0) break; alpha /= 2; } line_search_time = float( clock() - line_begin_time)/CLOCKS_PER_SEC; memcpy(w, w_new, sizeof(double)*n); f = fnew; fun_obj->grad(w, g, Hsample, iter+1, num_sample,&num_data); gnorm = dnrm2_(&n, g, &inc); shift_time += float(clock() - begin_time)/CLOCKS_PER_SEC; info("iter %2d act %5.3e fun %5.3e |g| %5.3e CG %3d cg_time: %g line_search_time: %g time %.6f num_data %ld f %.16f alpha %g\n", iter, actred, f, gnorm, cg_iter, cg_time, line_search_time, shift_time, num_data, f, alpha); iter++; if (gnorm <= eps*gnorm1) break; if(fabs(actred) <= 1.0e-12*fabs(f)) { printf("actual reduction is too small"); break; } if (f < -1.0e+32) { info("WARNING: f < -1.0e+32\n"); break; } } delete[] g; delete[] r; delete[] w_new; delete[] s; delete[] Hsample; }