Exemple #1
0
void SolversTR::Run(void)
{
	Variable *xTemp;
	Vector *gfTemp;
	starttime = getTickCount();
	Solvers::Run();
	double sqeps = sqrt(std::numeric_limits<double>::epsilon());

	f1 = Prob->f(x1);
	Prob->Grad(x1, gf1);

	ngf0 = sqrt(Mani->Metric(x1, gf1, gf1));
	ngf = ngf0;

	iter = 0;
	if (DEBUG >= ITERRESULT)
	{
		Rprintf("i:%d,f:%.3e,|gf|:%.3e,\n", iter, f1, ngf);
		timeSeries[iter] = static_cast<double>(getTickCount() - starttime) / CLK_PS;
		funSeries[iter] = f1; gradSeries[iter] = ngf;
		nf++; ng++;
	}
	Delta = initial_Delta;
	bool isstop = false;
	while (((! isstop) && iter < Max_Iteration) || iter < Min_Iteration)
	{
		InitialVector(); // Obtain initial guess, eta1, for local model
		tCG_TR(); // obtain eta2
		Mani->Retraction(x1, eta2, x2);	nR++;
		f2 = Prob->f(x2); nf++;
		HessianEta(eta2, zeta); nH++; // Hessian * eta2

		Mani->ScalerVectorAddVector(x1, 0.5, zeta, gf1, eta1);
		rho = (f1 - f2) / (-Mani->Metric(x1, eta2, eta1));
		UpdateData(); // Update S&Y or H or B

		if (rho > 0.75)
		{
			if (tCGstatus == TR_EXCREGION || tCGstatus == TR_NEGCURVTURE)
				Delta *= Magnified_tau;
			if (Delta > maximum_Delta)
			{
				Rcpp::Rcout << "reach the maximum of radius" << std::endl;
				Delta = maximum_Delta;
			}
		}
		else
		if (rho < 0.25)
		{
			Delta *= Shrinked_tau;
			if (Delta < minimum_Delta)
			{
				Rcpp::Rcout << "reach the minimum of radius" << std::endl;
				break;
			}
		}
		isstop = IsStopped();
		if (rho > Acceptence_Rho || (fabs(f1 - f2) / (fabs(f1) + 1) < sqeps && f2 < f1))
		{
			Acceptence(); // Algorithm specific operations
			ngf = sqrt(Mani->Metric(x2, gf2, gf2));
			xTemp = x1; x1 = x2; x2 = xTemp;
			gfTemp = gf1; gf1 = gf2; gf2 = gfTemp;
            iter++;
			if (DEBUG >= ITERRESULT && iter % OutputGap == 0)
			{
				PrintGenInfo();
				PrintInfo(); // Output information specific to Algorithms
			}
			f1 = f2;
		}
		else
		{
            iter++;
			if (DEBUG >= ITERRESULT && iter % OutputGap == 0)
			{
				//Rcpp::Rcout << "X_{" << iter << "} WAS REJECTED." << std::endl;
				PrintGenInfo();
				PrintInfo(); // Output information specific to Algorithms
			}
		}

		if (DEBUG >= ITERRESULT)
		{
			timeSeries[iter] = static_cast<double>(getTickCount() - starttime) / CLK_PS;
			funSeries[iter] = f2; gradSeries[iter] = ngf;
		}
	}
	ComTime = static_cast<double>(getTickCount() - starttime) / CLK_PS;
	if (DEBUG >= ITERRESULT)
		lengthSeries = iter + 1;

	if (DEBUG >= FINALRESULT)
	{
		Rprintf("Iter:%d,f:%.3e,|gf|:%.3e,|gf|/|gf0|:%.3e,time:%.2e,nf:%d,ng:%d,nR:%d,", iter, f2,
			ngf, ngf / ngf0, ComTime, nf, ng, nR);
		if (nH != 0)
		{
			Rprintf("nH:%d,", nH);
		}
		if (nV != 0)
		{
			Rprintf("nV(nVp):%d(%d),", nV, nVp);
		}
		Rprintf("\n");
	}
};
Exemple #2
0
void Problem::CheckGradHessian(const Variable *xin) const
{
	UseGrad = true;
	UseHess = true;
	integer length;
	double normxi;
	double t, fx, fy;
	double *X, *Y;
	Vector *etax;
	Variable *x = xin->ConstructEmpty();
	xin->CopyTo(x);
	if (Domain->GetIsIntrinsic())
		etax = Domain->GetEMPTYINTR()->ConstructEmpty();
	else
		etax = Domain->GetEMPTYEXTR()->ConstructEmpty();
	etax->RandUnform();
	Vector *xi = etax->ConstructEmpty();
	Vector *gfx = etax->ConstructEmpty();
	Vector *Hv = etax->ConstructEmpty();
	Variable *y = x->ConstructEmpty();
	fx = f(x);
	Grad(x, gfx);
	gfx->CopyTo(etax);//--
	//double *etaxTV = etax->ObtainWriteEntireData();///---
	//integer nnn = etax->Getlength();
	//for (integer i = 0; i < nnn; i++)//--
	//{
	//	etaxTV[i] = sin(static_cast<double> (i) / (etax->Getlength() - 1) / 2);
	//}
	//for (integer i = 0; i < 5; i++)//---
	//	etaxTV[nnn - 1 - i] = 0;//--

	//etax->Print("etax:");//--
	Domain->Projection(x, etax, xi);
	normxi = sqrt(Domain->Metric(x, xi, xi));
	Domain->ScaleTimesVector(x, 100.0 / normxi, xi, xi); // initial length of xi is 100
	//xi->Print("xi:");//---
	// the length of xi variances from 100 to 100*2^(-35) approx 6e-9
	t = 1;
	length = 35;
	X = new double [length * 2];
	Y = X + length;
	for (integer i = 0; i < length; i++)
	{
		Domain->Retraction(x, xi, y);
		fy = f(y);
		HessianEta(x, xi, Hv);
		Y[i] = log(fabs(fy - fx - Domain->Metric(x, gfx, xi) - 0.5 * Domain->Metric(x, xi, Hv)));
		X[i] = 0.5 * log(Domain->Metric(x, xi, xi));
		Rprintf("i:%d,|eta|:%.3e,(fy-fx)/<gfx,eta>:%.3e,(fy-fx-<gfx,eta>)/<0.5 eta, Hessian eta>:%.3e\n", i, 
			sqrt(Domain->Metric(x, xi, xi)), (fy-fx)/Domain->Metric(x, gfx, xi), 
			(fy - fx - Domain->Metric(x, gfx, xi)) / (0.5 * Domain->Metric(x, xi, Hv)));
		Domain->ScaleTimesVector(x, 0.5, xi, xi);
	}

	Rcpp::Rcout << "CHECK GRADIENT:" << std::endl;
	Rcpp::Rcout << "\tSuppose the point is not a critical point." << std::endl;
	Rcpp::Rcout << "\tIf there exists an interval of |eta| such that (fy - fx) / <gfx, eta>" << std::endl;
	Rcpp::Rcout << "\tapproximates ONE, then the gradient is probably correct!" << std::endl;

	Rcpp::Rcout << "CHECK THE ACTION OF THE HESSIAN (PRESUME GRADIENT IS CORRECT):" << std::endl;
	Rcpp::Rcout << "\tSuppose the retraction is second order or the point is a critical point." << std::endl;
	Rcpp::Rcout << "\tIf there exists an interval of |eta| such that (fy-fx-<gfx,eta>)/<0.5 eta, Hessian eta>" << std::endl;
	Rcpp::Rcout << "\tapproximates ONE, then the action of Hessian is probably correct." << std::endl;

	////TEST IDEA2: 
	//for (integer i = 1; i < length - 1; i++)
	//	Rprintf("log(|eta|):%.3e, slope:%.3e\n", X[i], (Y[i + 1] - Y[i - 1]) / (X[i + 1] - X[i - 1]));
	//Rcpp::Rcout << "CHECK GRADIENT:" << std::endl;
	//Rcpp::Rcout << "\tIf there exists an interval of |eta| such that the slopes " << std::endl;
	//Rcpp::Rcout << "\tapproximate TWO, then the gradient is probably correct!" << std::endl;

	//Rcpp::Rcout << "CHECK THE ACTION OF THE HESSIAN (PRESUME GRADIENT IS CORRECT AND" << std::endl;
	//Rcpp::Rcout << "THE COST FUNCTION IS NOT ONLY QUADRATIC):" << std::endl;
	//Rcpp::Rcout << "\tIf there exists an interval of |eta| such that the slopes" << std::endl;
	//Rcpp::Rcout << "\tapproximate THREE, then the action of Hessian is probably correct." << std::endl;

	//x->Print("1, x:", false);//---
	delete xi;
	//x->Print("2, x:", false);//---
	//gfx->Print("2, gfx:", false);//---
	delete gfx;
	//x->Print("3, x:", false);//---
	delete y;
	//x->Print("4, x:", false);//---
	delete Hv;
	//x->Print("5, x:", false);//---
	delete[] X;
	delete etax;
	//x->Print("x:", false);//---
	delete x;
};
Exemple #3
0
void SolversTR::tCG_TR(void)
{
	double e_Pe, r_r, norm_r, norm_r0, d_Pd, z_r, e_Pd, d_Hd, alphatemp, e_Pe_new, tempnum, zold_rold, betatemp, tautemp;
	integer j;

	if (useRand)
	{
		HessianEta(eta1, r); nH++;
		Mani->VectorAddVector(x1, gf1, r, r);
		e_Pe = Mani->Metric(x1, eta1, eta1);
	}
	else
	{
		gf1->CopyTo(r);
		e_Pe = 0;
	}

	r_r = Mani->Metric(x1, r, r);
	norm_r = sqrt(r_r);
	norm_r0 = norm_r;

	PreConditioner(x1, r, z);

	z_r = Mani->Metric(x1, z, r);
	d_Pd = z_r;

	Mani->ScaleTimesVector(x1, -1.0, z, delta);

	if (useRand)
		e_Pd = Mani->Metric(x1, eta1, delta);
	else
		e_Pd = 0;

	tCGstatus = TR_MAXITER; /* pre-assume termination j == max_inner*/

	eta1->CopyTo(eta2);

	for (j = 0; j < Max_Inner_Iter; j++)
	{
		HessianEta(delta, Hd); nH++;
		d_Hd = Mani->Metric(x1, delta, Hd);
		alphatemp = z_r / d_Hd;
		e_Pe_new = e_Pe + 2.0 * alphatemp * e_Pd + alphatemp * alphatemp * d_Pd;

		if (d_Hd <= 0 || e_Pe_new >= (Delta * Delta))
		{
			tautemp = (-e_Pd + sqrt(e_Pd * e_Pd + d_Pd * (Delta * Delta - e_Pe))) / d_Pd;
			Mani->ScalerVectorAddVector(x1, tautemp, delta, eta2, eta2);

			if (d_Hd < 0)
				tCGstatus = TR_NEGCURVTURE; /* negative curvature*/
			else
				tCGstatus = TR_EXCREGION; /* exceeded trust region*/
			break;
		}
		e_Pe = e_Pe_new;
		Mani->ScalerVectorAddVector(x1, alphatemp, delta, eta2, eta2);

		Mani->ScalerVectorAddVector(x1, alphatemp, Hd, r, r);

		Mani->Projection(x1, r, zeta);
		zeta->CopyTo(r);

		r_r = Mani->Metric(x1, r, r);
		norm_r = sqrt(r_r);

		tempnum = pow(norm_r0, theta);
		if (j >= Min_Inner_Iter && norm_r <= norm_r0 * ((tempnum < kappa) ? tempnum : kappa))
		{
			if (kappa < tempnum)
				tCGstatus = TR_LCON; /* linear convergence*/
			else
				tCGstatus = TR_SCON; /* superlinear convergence*/
			break;
		}

		PreConditioner(x1, r, z);

		zold_rold = z_r;
		z_r = Mani->Metric(x1, z, r);

		betatemp = z_r / zold_rold;
		Mani->ScalerVectorMinusVector(x1, betatemp, delta, z, delta);
		e_Pd = betatemp * (e_Pd + alphatemp * d_Pd);
		d_Pd = z_r + betatemp * betatemp * d_Pd;
	}
	innerIter = j;
};