Ejemplo n.º 1
0
static double
my_f (const gsl_vector *v, void *params)
{
  double val;

  my_fdf(v, params, &val, NULL);
  return val;
}
Ejemplo n.º 2
0
void measurement_df(const gsl_vector *v, void *params, gsl_vector *df) {
	double f;
	my_fdf(v, params, &f, df);
}
Ejemplo n.º 3
0
/* The gradient of f, df = (df/dx, df/dy). */
static void
my_df (const gsl_vector *v, void *params, gsl_vector *df)
{
  my_fdf(v, params, NULL, df);
}
Ejemplo n.º 4
0
void minim(density_t * ndft){
  const gsl_multimin_fdfminimizer_type *T;
  gsl_multimin_fdfminimizer *s;
  gsl_multimin_function_fdf my_func;
  gsl_vector * grad_initial;
  size_t iter;

  ipf_t ipf_previous;

  int  status;
  double minimum, g_initial, norm_initial;
  char * output_string;
  int i;
  params_gsl_multimin_function_t params;

  output_string = (char *) malloc(25*sizeof(char));

  params.nDFT = density_get_val(ndft);
  my_func.n = ipf.npar;
  my_func.f = my_f;
  my_func.df = my_df;
  my_func.fdf = my_fdf;
  my_func.params = (void *) (&params);

  /* We use the BFGS algorithm from thee GNU Scientific Library (GSL)
     in its optimized version bfgs2 */
  T = gsl_multimin_fdfminimizer_vector_bfgs2;

  messages_basic("\n\nStarting the optimization.\n\n\n");


  grad_initial = gsl_vector_alloc(ipf.npar);
  my_fdf (ipf.gamma, &params, &g_initial, grad_initial);
  norm_initial = gsl_blas_dnrm2(grad_initial);
  if(g_initial < epsilon_gvalue){
    if(myid == 0) printf("The value of G for the starting gamma is %.12lg,\n", g_initial);
    if(myid == 0) printf("which is already below the requested threshold of %.12lg\n", epsilon_gvalue);
    parallel_end(EXIT_SUCCESS);
  }
  if(norm_initial < epsilon_grad){
    if(myid == 0) printf("The value of the normm of the gradient of G for the starting gamma is %.12lg,\n", norm_initial);
    if(myid == 0) printf("which is already below the requested threshold of %.12lg\n", epsilon_grad);
    parallel_end(EXIT_SUCCESS);
  }
  if(myid == 0) printf("  Starting from gamma =  ");
  if(myid == 0) {for(i = 0; i < ipf.npar; i++) printf ("%.5f ", gsl_vector_get (ipf.gamma, i));}
  if(myid == 0) printf("\n  G(gamma) = %.12lg\n", g_initial);
  if(myid == 0) printf("  ||Grad G(gamma)|| = %.12lg\n\n", norm_initial);


  /* Initialization of the minimizer s for the function
     my_func starting at the x point
     The step for the first try is 0.1
     and the convergence criteria is 0.1 */
  messages_basic("\n\nInitialization of the minimizer.\n\n\n");
  s = gsl_multimin_fdfminimizer_alloc (T, ipf.npar);
  gsl_multimin_fdfminimizer_set (s, &my_func, ipf.gamma, 0.1, 0.1);

  minimum = g_initial;
  iter = 0;
  do{
    iter++;

    ipf_copy(&ipf_previous, &ipf);

    if(myid == 0) printf("  Iter = %d\n", (int)iter);
    if(myid == 0) printf("    starting gamma =  ");
    if(myid == 0) {for(i = 0; i < ipf.npar; i++) printf ("%.5f ", gsl_vector_get (gsl_multimin_fdfminimizer_x(s), i));}
    if(myid == 0) printf("\n    starting G(gamma) = %15.10f\n", minimum);
    /* We make an iteration of the minimizer s */
    status = gsl_multimin_fdfminimizer_iterate (s);
    minimum = gsl_multimin_fdfminimizer_minimum(s);

    if (status){
      if(myid == 0) printf("  Breaking. Reason: %s\n", gsl_strerror(status));
      break;
    }

    if(myid == 0) printf("    ||Grad G(gamma)|| = %15.10f\n", gsl_blas_dnrm2(gsl_multimin_fdfminimizer_gradient(s)));
    if(myid == 0) printf("    G(gamma) = %15.10f\n", minimum);

    /* Checks convergence */
    if(minimum < epsilon_gvalue){
       status = GSL_SUCCESS;
    }else{
       status = gsl_multimin_test_gradient (gsl_multimin_fdfminimizer_gradient(s), epsilon_grad);
    }

    gsl_vector_memcpy(ipf.gamma, gsl_multimin_fdfminimizer_x(s));
    ipf_write(ipf, ipf_ref, "intermediate-pot");


    /* Print the diff between initial and reference IPFs */
    if(myid == 0) printf("    Diff[ IPF(previous), IPF(new) ] = %.12lg\n", ipf_diff(&ipf_previous, &ipf));
    ipf_end(&ipf_previous);

  }
  while (status == GSL_CONTINUE && iter < minim_maxiter);

  if(myid == 0) printf("\n\nFinished optimization. status = %d (%s)\n", status, gsl_strerror(status));
  if(myid == 0) printf("  Final gamma =  ");
  if(myid == 0) {for(i = 0; i < ipf.npar; i++) printf ("%.5f ", gsl_vector_get (gsl_multimin_fdfminimizer_x(s), i));}
  if(myid == 0) printf("\n  With value: G(gamma) = %.12lg\n\n", gsl_multimin_fdfminimizer_minimum(s));

  gsl_vector_memcpy(ipf.gamma, gsl_multimin_fdfminimizer_x(s));
  sprintf(output_string, "pot");
  ipf_write(ipf, ipf_ref, output_string);
  gsl_multimin_fdfminimizer_free (s);
  fflush(stdout);

}