コード例 #1
0
ファイル: tron.cpp プロジェクト: teddylfwu/RandomBinning
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;
}
コード例 #2
0
ファイル: tron.cpp プロジェクト: jinshubai/subsampling
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;
}