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"); } };
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; };
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; };