int checkTrivialCase_vi(VariationalInequality* problem, double* x, 
                        double* w, SolverOptions* options)
{
  int n = problem->size;
  if (problem->ProjectionOnX)
  {
    problem->ProjectionOnX(problem,x,w);
  }
  else
  {
    cblas_dcopy(problem->size, x, 1, w, 1);
    project_on_set(problem->size, w, problem->set);
  }
  cblas_daxpy(n, -1.0,x, 1, w , 1);
  double nnorm = cblas_dnrm2(n,w,1);
  DEBUG_PRINTF("checkTrivialCase_vi, nnorm = %6.4e\n",nnorm);
  
  if (nnorm > fmin(options->dparam[0], 1e-12))
    return 1;

  problem->F(problem,n,x,w);
  nnorm = cblas_dnrm2(n,w,1);
  DEBUG_PRINTF("checkTrivialCase_vi, nnorm = %6.4e\n",nnorm);

  if (nnorm > fmin(options->dparam[0], 1e-12))
    return 1;

  if (verbose == 1)
    printf("variationalInequality driver, trivial solution F(x) = 0, x in X.\n");
  return 0;
}
Пример #2
0
double search_Armijo_standalone(int n, double* theta, double preRHS, search_data* ls_data)
{
  assert(ls_data->alpha0 > 0.0);
  assert(ls_data->alpha0 > ls_data->alpha_min);
  double alpha = ls_data->alpha0;
  double theta_iter = *theta, theta_ref = *theta;
  double* z = ls_data->z;
  double* zc = ls_data->zc;
  double* F = ls_data->F;
  double* F_merit = ls_data->F_merit;
  double* desc_dir = ls_data->desc_dir;
  void* data = ls_data->data;
  bool arcsearch = ls_data->searchtype == ARCSEARCH;
  void* set = ls_data->set;
  double RHS;

  armijo_extra_params* aep = (armijo_extra_params*) ls_data->extra_params;
  assert(aep);
  preRHS *= aep->gamma;

  while (alpha >= ls_data->alpha_min)
  {
    DEBUG_PRINTF("search_Armijo :: alpha %g, ls_data->alpha_min %g \n", alpha, ls_data->alpha_min);

     // desc_dir contains the direction d
     cblas_dcopy(n, z, 1, zc, 1);
     cblas_daxpy(n, alpha, desc_dir, 1, zc, 1);     //  z + alpha*d --> z
     if (arcsearch)
     {
       project_on_set(n, zc, set);
       /* we use F as a work vector here */
       cblas_dcopy(n, z, 1, F, 1);
       cblas_daxpy(n, -1.0, zc, 1, F, 1); /* F = z(0) - z(alpha) */
       /* warning desc_dir = -JacMerit !*/
       double dotprod = cblas_ddot(n, desc_dir, 1, F, 1);
       if (dotprod > 0.0)
         RHS = ls_data->sigma*dotprod;
       else
         RHS = -alpha*ls_data->sigma*theta_ref;
     }
     else
     {
       RHS = alpha*preRHS;
     }

     // compute new F_merit
     ls_data->compute_F(data, zc, F);
     ls_data->compute_F_merit(data, zc, F, F_merit);

     DEBUG_PRINT("z ");
     DEBUG_EXPR_WE(for (unsigned int i = 0; i < n; ++i)
         { DEBUG_PRINTF("% 2.2e ", zc[i]) }
         DEBUG_PRINT("\n"));
 
     DEBUG_PRINT("F ");
     DEBUG_EXPR_WE(for (unsigned int i = 0; i < n; ++i)
         { DEBUG_PRINTF("% 2.2e ", F[i]) }
         DEBUG_PRINT("\n"));
 
     DEBUG_PRINT("F_merit ");
     DEBUG_EXPR_WE(for (unsigned int i = 0; i < n; ++i)
         { DEBUG_PRINTF("% 2.2e ", F_merit[i]) }
         DEBUG_PRINT("\n"));
 
     theta_iter = 0.5 * cblas_ddot(n, F_merit, 1, F_merit, 1);
 
     DEBUG_PRINTF("search_Armijo :: alpha %g\n", alpha);
     DEBUG_PRINTF("search_Armijo :: theta_iter %.*e ; theta_ref %.*e  \n", DECIMAL_DIG, theta_iter, DECIMAL_DIG, theta_ref);
 
     // acceptance test
     if (theta_iter <= theta_ref + RHS)
     {
       if (verbose > 1)
         printf("search_Armijo :: alpha %g\n", alpha);
       break;
     }
     else
     {
       // alpha too large, decrease it
       alpha /= 2.0;
     }
  }
  *theta = theta_iter;
  return alpha;
}