示例#1
0
文件: hess.cpp 项目: cran/pcaPP
void Hess_R (int *pnPar, double *pdX, double *pdMu, double *pdHess)
{
	double *pdTempP1 = new double [pnPar[0]], *pdTempP2 = new double [pnPar[0]] ;
	Hess (pnPar[0], pnPar[1], pdX, pdMu, pdHess, pdTempP1, pdTempP2) ;

	delete pdTempP1 ;
	delete pdTempP2 ;
}
示例#2
0
bool minimizeMeritFunction(std::vector< Matrix<C_DIM> >& X, std::vector< Matrix<U_DIM> >& U, stateMPC_params& problem, stateMPC_output& output, stateMPC_info& info, double penalty_coeff)
{
	LOG_DEBUG("Solving sqp problem with penalty parameter: %2.4f", penalty_coeff);

	std::vector< Matrix<C_DIM,C_DIM> > F(T-1);
	std::vector< Matrix<C_DIM,U_DIM> > G(T-1);
	std::vector< Matrix<C_DIM> > h(T-1);

	double Xeps = cfg::initial_trust_box_size;
	double Ueps = cfg::initial_trust_box_size;

	double Xpos_eps = cfg::initial_trust_box_factor * cfg::initial_Xpos_trust_box_size;
	double Xangle_eps = cfg::initial_trust_box_factor * cfg::initial_Xangle_trust_box_size;
	double Uvel_eps = cfg::initial_trust_box_factor * cfg::initial_Uvel_trust_box_size;
	double Uangle_eps = cfg::initial_trust_box_factor * cfg::initial_Uangle_trust_box_size;
	double landmark_eps = cfg::initial_trust_box_factor * cfg::initial_landmark_trust_box_size;

	double optcost;

	std::vector<Matrix<C_DIM> > Xopt(T);
	std::vector<Matrix<U_DIM> > Uopt(T-1);

	double merit, model_merit, new_merit;
	double approx_merit_improve, exact_merit_improve, merit_improve_ratio;
	double constant_cost, hessian_constant, jac_constant;

	int sqp_iter = 1, index = 0, shrink_iters = 0;
	bool success;

	Matrix<C_DIM+U_DIM, C_DIM+U_DIM> HMat;
	Matrix<C_DIM,C_DIM> HfMat;
	Matrix<C_DIM> eVec;
	Matrix<C_DIM,3*C_DIM+U_DIM> CMat;

	Matrix<C_DIM,C_DIM> IX = identity<C_DIM>();
	Matrix<C_DIM,C_DIM> minusIX = IX;
	for(int i = 0; i < C_DIM; ++i) {
		minusIX(i,i) = -1;
	}

	Matrix<C_DIM+U_DIM> zbar;

	// full Hessian from current timstep
	Matrix<CU_DIM,CU_DIM>Hess = identity<CU_DIM>();

	Matrix<CU_DIM> Grad, Gradopt;
	double cost;
	int idx = 0;

	// sqp loop
	while(true)
	{
		// In this loop, we repeatedly construct a linear approximation to the nonlinear belief dynamics constraint
		LOG_DEBUG("  sqp iter: %d", sqp_iter);

		merit = casadiComputeMerit(X, U, penalty_coeff);

		LOG_DEBUG("  merit: %4.10f", merit);

		// Compute gradients
		casadiComputeCostGrad(X, U, cost, Grad);

		// Problem linearization and definition
		// fill in H, f

		hessian_constant = 0;
		jac_constant = 0;
		idx = 0;

		for (int t = 0; t < T-1; ++t)
		{
			Matrix<C_DIM>& xt = X[t];
			Matrix<U_DIM>& ut = U[t];

			idx = t*(C_DIM+U_DIM);

			// fill in gradients and Hessians

			HMat.reset();
			for(int i = 0; i < (C_DIM+U_DIM); ++i) {
				double val = Hess(idx+i,idx+i);
				HMat(i,i) = (val < 0) ? 0 : val;
			}

			// since diagonal, fill directly
			for(int i = 0; i < (C_DIM+U_DIM); ++i) { H[t][i] = HMat(i,i); }
			// TODO: why does this work???
			for(int i = 0; i < (2*C_DIM); ++i) { H[t][i + (C_DIM+U_DIM)] = 5e2; } //1e3

			zbar.insert(0,0,xt);
			zbar.insert(C_DIM,0,ut);

			for(int i = 0; i < (C_DIM+U_DIM); ++i) {
				hessian_constant += HMat(i,i)*zbar[i]*zbar[i];
				jac_constant -= Grad[idx+i]*zbar[i];
				f[t][i] = Grad[idx+i] - HMat(i,i)*zbar[i];
			}

			// penalize dynamics slack variables
			for(int i = C_DIM+U_DIM; i < 3*C_DIM+U_DIM; ++i) { f[t][i] = penalty_coeff; }

			// fill in linearizations
			linearizeCarDynamics(xt, ut, F[t], G[t], h[t]);


			CMat.reset();
			eVec.reset();

			CMat.insert<C_DIM,C_DIM>(0,0,F[t]);
			CMat.insert<C_DIM,U_DIM>(0,C_DIM,G[t]);
			CMat.insert<C_DIM,C_DIM>(0,C_DIM+U_DIM,IX);
			CMat.insert<C_DIM,C_DIM>(0,2*C_DIM+U_DIM,minusIX);

			fillColMajor(C[t], CMat);

			if (t == 0) {
				eVec.insert<C_DIM,1>(0,0,X[0]);
				fillCol(e[0], eVec);
			}

			eVec = -h[t] + F[t]*xt + G[t]*ut;
			fillCol(e[t+1], eVec);
		}

		// For last stage, fill in H, f
		Matrix<C_DIM>& xT = X[T-1];

		idx = (T-1)*(C_DIM+U_DIM);

		HfMat.reset();
		for(int i = 0; i < C_DIM; ++i) {
			double val = Hess(idx+i,idx+i);
			HfMat(i,i) = (val < 0) ? 0 : val;
		}

		// since diagonal, fill directly
		for(int i = 0; i < C_DIM; ++i) { H[T-1][i] = HfMat(i,i); }

		for(int i = 0; i < C_DIM; ++i) {
			hessian_constant += HfMat(i,i)*xT[i]*xT[i];
			jac_constant -= Grad[idx+i]*xT[i];
			f[T-1][i] = Grad[idx+i] - HfMat(i,i)*xT[i];
		}


		constant_cost = 0.5*hessian_constant + jac_constant + cost;
		LOG_DEBUG("  hessian cost: %4.10f", 0.5*hessian_constant);
		LOG_DEBUG("  jacobian cost: %4.10f", jac_constant);
		LOG_DEBUG("  constant cost: %4.10f", constant_cost);


		// trust region size adjustment
		while(true)
		{
			LOG_DEBUG("       trust region size: %2.6f %2.6f", Xeps, Ueps);

			// solve the innermost QP here
			for(int t = 0; t < T-1; ++t)
			{
				Matrix<C_DIM>& xt = X[t];
				Matrix<U_DIM>& ut = U[t];

				// Fill in lb, ub

				index = 0;
				// car pos lower bound
				for(int i = 0; i < P_DIM; ++i) { lb[t][index++] = MAX(xMin[i], xt[i] - Xpos_eps); }
				// car angle lower bound
				lb[t][index++] = MAX(xMin[P_DIM], xt[P_DIM] - Xangle_eps);

				// u velocity lower bound
				lb[t][index++] = MAX(uMin[0], ut[0] - Uvel_eps);
				// u angle lower bound
				lb[t][index++] = MAX(uMin[1], ut[1] - Uangle_eps);

				// for lower bound on L1 slacks
				for(int i = 0; i < 2*C_DIM; ++i) { lb[t][index++] = 0; }

				index = 0;
				// car pos upper bound
				for(int i = 0; i < P_DIM; ++i) { ub[t][index++] = MIN(xMax[i], xt[i] + Xpos_eps); }
				// car angle upper bound
				ub[t][index++] = MIN(xMax[P_DIM], xt[P_DIM] + Xangle_eps);

				// u velocity upper bound
				ub[t][index++] = MIN(uMax[0], ut[0] + Uvel_eps);
				// u angle upper bound
				ub[t][index++] = MIN(uMax[1], ut[1] + Uangle_eps);
			}

			// Fill in lb, ub
			double finalPosDelta = .1;
			double finalAngleDelta = M_PI/4;


			Matrix<C_DIM>& xT_MPC = X[T_MPC-1];

			index = 0;
			// xMidpoint lower bound
			for(int i = 0; i < P_DIM; ++i) { lb[T_MPC-1][index++] = xMidpoint[i] - finalPosDelta; }
			// loose on car angle and landmarks
			lb[T_MPC-1][index++] = nearestAngleFromTo(xT_MPC[2], xMidpoint[2] - finalAngleDelta);

			index = 0;
			// xMidpoint upper bound
			for(int i = 0; i < P_DIM; ++i) { ub[T_MPC-1][index++] = xMidpoint[i] + finalPosDelta; }
			// loose on car angle and landmarks
			ub[T_MPC-1][index++] = nearestAngleFromTo(xT_MPC[2], xMidpoint[2] + finalAngleDelta);


			Matrix<C_DIM>& xT = X[T-1];

			index = 0;
			// xGoal lower bound
			for(int i = 0; i < P_DIM; ++i) { lb[T-1][index++] = xGoal[i] - finalPosDelta; }
			// loose on car angle and landmarks
			//lb[T_MPC-1][index++] = xGoal[2] - finalAngleDelta;
			lb[T-1][index++] = nearestAngleFromTo(xT[2], xGoal[2] - finalAngleDelta);

			index = 0;
			// xGoal upper bound
			for(int i = 0; i < P_DIM; ++i) { ub[T-1][index++] = xGoal[i] + finalPosDelta; }
			// loose on car angle and landmarks
			//ub[T_MPC-1][index++] = xGoal[2] + finalAngleDelta;
			ub[T-1][index++] = nearestAngleFromTo(xT[2], xGoal[2] + finalAngleDelta);


			// Verify problem inputs
			if (!isValidInputs()) {
				LOG_ERROR("Inputs are not valid!");
				exit(-1);
			}


			int exitflag = stateMPC_solve(&problem, &output, &info);
			if (exitflag == 1) {
				for(int t = 0; t < T-1; ++t) {
					Matrix<C_DIM>& xt = Xopt[t];
					Matrix<U_DIM>& ut = Uopt[t];

					for(int i = 0; i < C_DIM; ++i) {
						xt[i] = z[t][i];
					}
					for(int i = 0; i < U_DIM; ++i) {
						ut[i] = z[t][C_DIM+i];
					}
					optcost = info.pobj;
				}
				for(int i = 0; i < C_DIM; ++i) {
					Xopt[T-1][i] = z[T-1][i];
				}
			}
			else {
				LOG_ERROR("Some problem in solver");
				throw forces_exception();
			}


			LOG_DEBUG("       Optimized cost: %4.10f", optcost);

			model_merit = optcost + constant_cost;

			new_merit = casadiComputeMerit(Xopt, Uopt, penalty_coeff);

			LOG_DEBUG("       merit: %4.10f", merit);
			LOG_DEBUG("       model_merit: %4.10f", model_merit);
			LOG_DEBUG("       new_merit: %4.10f", new_merit);

			approx_merit_improve = merit - model_merit;
			exact_merit_improve = merit - new_merit;
			merit_improve_ratio = exact_merit_improve / approx_merit_improve;

			LOG_DEBUG("       approx_merit_improve: %1.6f", approx_merit_improve);
			LOG_DEBUG("       exact_merit_improve: %1.6f", exact_merit_improve);
			LOG_DEBUG("       merit_improve_ratio: %1.6f", merit_improve_ratio);

			counter_inner_loop++;

			//std::cout << "PAUSED INSIDE minimizeMeritFunction AFTER OPTIMIZATION" << std::endl;
			//std::cin.ignore();


			if (approx_merit_improve < -1e-5) {
				LOG_ERROR("Approximate merit function got worse: %1.6f", approx_merit_improve);
				std::cout << "penalty coeff: " << penalty_coeff << "\n";
				//LOG_ERROR("Either convexification is wrong to zeroth order, or you are in numerical trouble");
				//LOG_ERROR("Failure!");
				counter_approx_hess_neg++;

				return false;
			} else if (approx_merit_improve < cfg::min_approx_improve) {
				LOG_DEBUG("Converged: improvement small enough");
				X = Xopt; U = Uopt;
				return true;
			} else if ((exact_merit_improve < 0) || (merit_improve_ratio < cfg::improve_ratio_threshold)) {
				//Xeps *= cfg::trust_shrink_ratio;
				//Ueps *= cfg::trust_shrink_ratio;
				Xpos_eps *= cfg::trust_shrink_ratio;
				Xangle_eps *= cfg::trust_shrink_ratio;
				Uvel_eps *= cfg::trust_shrink_ratio;
				Uangle_eps *= cfg::trust_shrink_ratio;
				landmark_eps *= cfg::trust_shrink_ratio;
				shrink_iters++;
				LOG_DEBUG("Shrinking trust region size to: %2.6f %2.6f %2.6f %2.6f", Xpos_eps, Xangle_eps, Uvel_eps, Uangle_eps);
			} else {
				//Xeps *= cfg::trust_expand_ratio;
				//Ueps *= cfg::trust_expand_ratio;
				Xpos_eps *= cfg::trust_expand_ratio;
				Xangle_eps *= cfg::trust_expand_ratio;
				Uvel_eps *= cfg::trust_expand_ratio;
				Uangle_eps *= cfg::trust_expand_ratio;
				landmark_eps *= cfg::trust_expand_ratio;
				shrink_iters--;


				casadiComputeCostGrad(Xopt, Uopt, cost, Gradopt);

				Matrix<CU_DIM> s, y;

				idx = 0;
				for(int t = 0; t < T-1; ++t) {
					for(int i=0; i < C_DIM; ++i) {
						s[idx+i] = Xopt[t][i] - X[t][i];
						y[idx+i] = Gradopt[idx+i] - Grad[idx+i];
					}
					idx += C_DIM;

					for(int i=0; i < U_DIM; ++i) {
						s[idx+i] = Uopt[t][i] - U[t][i];
						y[idx+i] = Gradopt[idx+i] - Grad[idx+i];
					}
					idx += U_DIM;
				}
				for(int i=0; i < C_DIM; ++i) {
					s[idx+i] = Xopt[T-1][i] - X[T-1][i];
					y[idx+i] = Gradopt[idx+i] - Grad[idx+i];
				}

				double theta;
				Matrix<CU_DIM> Bs = Hess*s;

				bool decision = ((~s*y)[0] >= .2*(~s*Bs)[0]);
				if (decision) {
					theta = 1;
				} else {
					theta = (.8*(~s*Bs)[0])/((~s*Bs-~s*y)[0]);
				}

				//std::cout << "theta: " << theta << std::endl;

				Matrix<CU_DIM> r = theta*y + (1-theta)*Bs;
				//Matrix<XU_DIM> rBs = theta*(y -Bs);

				// SR1 update
				//B = B + (rBs*~rBs)/((~rBs*s)[0]);

				// L-BFGS update
				Hess = Hess - (Bs*~Bs)/((~s*Bs)[0]) + (r*~r)/((~s*r)[0]);

				// take in diagonal of B
				// find minimum value among diagonal elements
				// negate and add to other vals
				double minValue = INFTY;
				double maxValue = -INFTY;
				for(int i=0; i < CU_DIM; ++i) {
					minValue = MIN(minValue, Hess(i,i));
					maxValue = MAX(maxValue, Hess(i,i));
				}

				if (minValue < 0) {
					std::cout << "negative minValue, press enter\n";
					std::cin.ignore();
					Hess = Hess + fabs(minValue)*identity<CU_DIM>();
				}

				// Do not update B
				//B = identity<XU_DIM>();

				X = Xopt; U = Uopt;

				LOG_DEBUG("Accepted, Increasing trust region size to:  %2.6f %2.6f %2.6f %2.6f", Xpos_eps, Xangle_eps, Uvel_eps, Uangle_eps);
				break;
			}


			if (Xpos_eps < cfg::min_trust_box_size && Xangle_eps < cfg::min_trust_box_size &&
					Uvel_eps < cfg::min_trust_box_size && Uangle_eps < cfg::min_trust_box_size && landmark_eps < cfg::min_trust_box_size) {
			//if (shrink_iters > cfg::min_trust_shrink_iters) {
			    LOG_DEBUG("Converged: x tolerance");
			    return true;
			}

			//std::cout << "U" << std::endl;
			//for(int t=0; t < T-1; ++t) {
			//	std::cout << ~U[t];
			//}
			//std::cout << std::endl << std::endl;
			//pythonDisplayTrajectory(U, T, true);
			//pythonDisplayTrajectory(X, T, true);

		} // trust region loop
		sqp_iter++;
	} // sqp loop

	return success;
}
示例#3
0
/**
 * Description not yet available.
 * \param
 */
void function_minimizer::trust_region_update(int nvar,int _crit,
  independent_variables& x,const dvector& _g,const double& _f)
{
  double & f= (double&)_f;
  dvector & g= (dvector&)_g;
  fmm fmc(nvar);
  if (random_effects_flag)
  {
    initial_params::set_active_only_random_effects();
    //int unvar=initial_params::nvarcalc(); // get the number of active
    initial_params::restore_start_phase();
    initial_params::set_inactive_random_effects();
    int nvar1=initial_params::nvarcalc(); // get the number of active
    if (nvar1 != nvar)
    {
      cerr << "failed sanity check in "
       "void function_minimizer::quasi_newton_block" << endl;
      ad_exit(1);
    }
  }

  uistream uis("admodel.hes");
  if (!uis)
  {
    cerr << "Error trying to open file admodel.hes" << endl;
    ad_exit(1);
  }
  int hnvar = 0;
  uis >> hnvar;
  dmatrix Hess(1,hnvar,1,hnvar);
  uis >> Hess;
  if (!uis)
  {
    cerr << "Error trying to read Hessian from admodel.hes" << endl;
    ad_exit(1);
  }

  dmatrix tester(1,hnvar,1,hnvar);

  tester=Hess;

  dvector e=sort(eigenvalues(Hess));

  double lambda=-e(1)+100.;

  for (int i=1;i<=hnvar;i++)
  {
    tester(i,i)+=lambda;
  }
  dvector step =  x-solve(tester,g);

  {
    // calculate the number of random effects unvar
    // this turns on random effects variables and turns off
    // everything else
    //cout << nvar << endl;
    initial_params::set_active_only_random_effects();
    //cout << nvar << endl;
    int unvar=initial_params::nvarcalc(); // get the number of active
    //df1b2_gradlist::set_no_derivatives();

    if (lapprox)
    {
      delete lapprox;
      lapprox=0;
      df1b2variable::pool->deallocate();

      for (int i=0;i<df1b2variable::adpool_counter;i++)
      {
        delete df1b2variable::adpool_vector[i];
        df1b2variable::adpool_vector[i]=0;
        df1b2variable::nvar_vector[i]=0;
        df1b2variable::adpool_counter=0;
      }
    }
    lapprox=new laplace_approximation_calculator(nvar,unvar,1,nvar+unvar,
      this);
    initial_df1b2params::current_phase=initial_params::current_phase;

    initial_df1b2params::save_varsptr();
    allocate();
    initial_df1b2params::restore_varsptr();

    df1b2_gradlist::set_no_derivatives();
    int ynvar=initial_params::nvarcalc_all();
    dvector y(1,ynvar);
    initial_params::xinit_all(y);
    initial_df1b2params::reset_all(y);

    g=(*lapprox)(step,f,this);
  }
} // end block for quasi newton minimization
示例#4
0
文件: main.C 项目: gberan/HMBI
// Use analytical nuclear gradient to compute the hessian via finite
// difference
Matrix GetFiniteDifferenceHessian(Vector Original_coords, int imon) {

  int Natoms, istart;
  if (imon == 0) {
    Natoms = Cluster::cluster().GetTotalNumberOfAtoms();
    istart = 0;
  }
  else {
    Natoms = Cluster::cluster().GetNumberOfAtoms(imon);
    istart = 0;
    for (int q=1;q<imon;q++) {
      istart += 3*Cluster::cluster().GetNumberOfAtoms(q);
    }
  }
  printf("Natoms = %d\n",Natoms);
  //printf("istart = %d\n",istart);

  Matrix Hess(3*Natoms,3*Natoms);
  Hess.Set();
  
  // Do the finite difference
  double delta = 0.001; // step size
  for (int i=istart;i<istart+3*Natoms;i++) {
    
    printf("Shifting coord %d by -%f\n",i,delta);
    Vector Coords = Original_coords;
    Coords[i] -= delta;
    // Update the coordinates & get the gradient
    Cluster::cluster().SetNewCoordinates(Coords);
    Cluster::cluster().RunJobsAndComputeEnergy();
    Vector Gplus = Cluster::cluster().GetHMBIGradient();
    
    Gplus.PrintGradient("Gplus:");

    printf("Shifting coord %d by +%f\n",i,delta);
    Coords[i] += 2.0*delta;
    // Update the coordinates & get the gradient
    Cluster::cluster().SetNewCoordinates(Coords);
    Cluster::cluster().RunJobsAndComputeEnergy();
    Vector Gminus = Cluster::cluster().GetHMBIGradient();    

    Gminus.PrintGradient("Gminus:");

    // Use the two gradients to determine a column of the Hessian
    // H(i,*) = (Gminus - Gplus)/(2*delta)
    Gminus -= Gplus;
    Gminus.Scale(1.0/(2*delta*AngToBohr)); 

    if (imon == 0)
      Hess.SetColumnVector(Gminus,i);
    else {
      for (int j=0;j<3*Natoms;j++) {
	Hess(j,i-istart) = Gminus[j+istart];
      }
    }
  }
  
  // Form the actual hessian in atomic units, hartree/bohr^2

  Hess.Print("Finite Difference HMBI Hessian");
  
  return Hess;

}