コード例 #1
0
ファイル: minimiser.cpp プロジェクト: NielsHolst/UniSim
Minimiser::Solution Minimiser::solution() {
    Solution sol;
    sol.x.lower = gsl_min_fminimizer_x_lower(s);
    sol.x.upper = gsl_min_fminimizer_x_upper(s);
    sol.x.minimum = gsl_min_fminimizer_x_minimum(s);
    sol.f.lower = gsl_min_fminimizer_f_lower(s);
    sol.f.upper = gsl_min_fminimizer_f_upper(s);
    sol.f.minimum = gsl_min_fminimizer_f_minimum(s);
    sol.iterations = iterations;
    sol.converged = (status == GSL_SUCCESS);
    sol.statusCode = status;
    return sol;
}
コード例 #2
0
ファイル: GSLMinimizer.cpp プロジェクト: gpcr/rvtests
int Minimizer::minimize(gsl_function F, double startValue, double lowerBound,
                        double upperBound) {
  gsl_min_fminimizer_set(s, &F, startValue, lowerBound, upperBound);
  int iter = 0;
  int status;
  double a, b;
  do {
    iter++;
    status = gsl_min_fminimizer_iterate(s);
    if (status == GSL_EBADFUNC || status == GSL_FAILURE) {
      return -1;
    }

    finalX = gsl_min_fminimizer_x_minimum(s);
    a = gsl_min_fminimizer_x_lower(s);
    b = gsl_min_fminimizer_x_upper(s);

    // stopping rule
    // see
    // http://www.gnu.org/software/gsl/manual/html_node/Minimization-Stopping-Parameters.html
    status = gsl_min_test_interval(a, b, epsabs, epsrel);

    if (status == GSL_SUCCESS) {
      // printf ("Converged:\n");
      finalY = gsl_min_fminimizer_f_minimum(s);
      return 0;
    }
    // printf("%5d\ta=%g\tb=%g\tfinalX=%g\n", iter, a, b, finalX);
    // printf ("%5d .7f, [.7f] "
    //         "%.7f %+.7f %.7f\n",
    //         iter, a, b,
    //         m, m - m_expected, b - a);
  } while (status == GSL_CONTINUE && iter < this->maxIter);

  return -1;
}
コード例 #3
0
ファイル: min.c プロジェクト: engineyard/rb-gsl
static VALUE rb_gsl_min_fminimizer_f_minimum(VALUE obj)
{
  gsl_min_fminimizer *gmf = NULL;
  Data_Get_Struct(obj, gsl_min_fminimizer, gmf);
  return rb_float_new(gsl_min_fminimizer_f_minimum(gmf));
}
コード例 #4
0
void shearlayerkcrit_driver(char *input_file_name)
{
    PARAMS_STRUCT *params;
    GRID_STRUCT *grid;
    ROTATION_STRUCT *rotation;
    COMPRESSED_MATRIX *matrix;
    ARPACK_CONTROL *arpack_params;
    RESULTS_STRUCT *results;
    OUTPUT_CONTROL *output_control;

    double shear_width, shear_radius, E;

    //Parameters needed for the root-finding routine
    int status;
    int iter=0, max_iter=50;
    const gsl_root_fsolver_type *Troot;
    const gsl_min_fminimizer_type *Tmin;
    gsl_root_fsolver *sroot;
    gsl_min_fminimizer *smin;
    double k_low, k_high, k_guess;
    double k_min = NAN;
    double k_max = NAN;
    double k_peak = NAN;
    double gr_peak;
    double errabs, errrel;
    double width_prefactor;
    gsl_function F;
    struct FUNCTION_PARAMS function_params;

    //Get the physical parameters for the computation
    params = malloc(sizeof(PARAMS_STRUCT));
    probgen(input_file_name, params);

    //Set up the grid, based on the physical parameters
    grid = gridgen(params);

    //Set up the rotation profile of a shear layer. Derive the width
    //from the Ekman number, E=\nu/\Omega r^2, width = rE^(1/4)
    //Use r = (r2-r1) and Omega = (Omega1-Omega2)/2.

    shear_radius = get_dparam("shear_radius", input_file_name);
    /*
    width_prefactor = get_dparam("width_prefactor", input_file_name);
    E = params->nu/(0.5*fabs(params->omega1 - params->omega2) *
    	  pow((params->r2-params->r1),2));
    shear_width = width_prefactor*(params->r2-params->r1)*pow(E, 0.25);
    printf("Using shear layer width %g cm\n", shear_width);
    */
    shear_width = get_dparam("shear_width", input_file_name);
    rotation = shearlayer(params, grid, shear_width, shear_radius);

    //Set up the matrix structure for the computations.
    matrix = create_matrix(5*grid->numcells);

    //Setup the ARPACK parameters
    arpack_params = setup_arpack(input_file_name);

    //Setup the output control structure
    output_control = malloc(sizeof(OUTPUT_CONTROL));

    //Pull the error params from the input file to decide when
    //we have converged
    errabs = get_dparam("errabs", input_file_name);
    errrel = get_dparam("errrel", input_file_name);

    //Put pointers to all of our control structures in function_params
    function_params.params = params;
    function_params.grid = grid;
    function_params.rotation = rotation;
    function_params.matrix = matrix;
    function_params.arpack_params = arpack_params;

    //Assign the evaluation function and params structure to
    //the gsl_function
    F.function = &mindampingrate;
    F.params = &function_params;

    gsl_set_error_handler(&err_handler);

    /* Now we find the peak of the growth rate, by minimizing the
       damping rate. We set what we hope are reasonable numbers
       for the bounds and initial guess.
    */

    k_low = 0.01;
    k_high = 1000;
    k_guess = params->k;
    Tmin = gsl_min_fminimizer_brent;
    smin = gsl_min_fminimizer_alloc(Tmin);
    status = gsl_min_fminimizer_set(smin, &F, k_guess, k_low, k_high);
    //Make sure that we didn't thrown an error on initialization
    if (status == GSL_SUCCESS) {
        //Now iterate!
        iter = 0;
        do
        {
            iter++;
            status = gsl_min_fminimizer_iterate(smin);
            //Make sure that we didn't thrown an error in the iteration routine
            if (status != GSL_SUCCESS) {
                fprintf(stderr, "Aborted attempt to find k_peak.\n");
                break;
            }

            params->k = gsl_min_fminimizer_x_minimum(smin);
            k_low = gsl_min_fminimizer_x_lower(smin);
            k_high = gsl_min_fminimizer_x_upper(smin);
            status = gsl_min_test_interval(k_low, k_high, errabs, errrel);

            if(status == GSL_SUCCESS && params->VERBOSE) {
                printf("Converged with k_peak=%g\n", params->k);
            }
        }
        while (status == GSL_CONTINUE && iter < max_iter);
        //Save the peak growth rate for printing later, then free the solver
        gr_peak = -gsl_min_fminimizer_f_minimum(smin);
    } else {
        fprintf(stderr, "Aborted attempt to find k_peak.\n");
    }
    gsl_min_fminimizer_free(smin);

    //Check to make sure we converged. If not, don't save the results.
    if (status == GSL_SUCCESS) {
        k_peak = params->k;

        //Make sure everything is set up correctly for normal run
        params->kva = params->k*params->va;
        free(grid->r);
        free(grid->x);
        free(grid->r2inv);
        free(grid);
        grid = gridgen(params);

        //Now do a normal run with the chosen k
        arpack_params->sigma = find_sigma(matrix, params, grid, rotation,
                                          arpack_params);
        results = eigensolve(matrix, params, grid, rotation, arpack_params);

        //Setup the structures needed to output the data files, and write them.
        get_sparam("basefilename", input_file_name, output_control->basefilename);
        strcat(output_control->basefilename, "_kpeak");
        wnetcdf(params, grid, rotation, output_control, arpack_params, results);

        free(results->lambda);
        free(results->z);
        free(results->residual);
        free(results);
    }


    /* Now do a root finding search for k_min. */

    /*
    //Set up the root solver.
    Troot = gsl_root_fsolver_brent;
    sroot = gsl_root_fsolver_alloc(Troot);

    //Set the initial bounds for the search. We're searching for k_min,
    //so search from 0 up to k_peak.
    k_low = 0;
    k_high = k_peak;
    status = gsl_root_fsolver_set(sroot, &F, k_low, k_high);
    //Make sure that we didn't thrown an error on initialization
    if (status == GSL_SUCCESS) {
      //Now iterate!
      iter = 0;
      do
        {
    iter++;
    status = gsl_root_fsolver_iterate(sroot);
    //Make sure that we didn't thrown an error in the iteration routine
    if (status != GSL_SUCCESS) {
      fprintf(stderr, "Aborted attempt to find k_min.\n");
      break;
    }

    params->k = gsl_root_fsolver_root(sroot);
    k_low = gsl_root_fsolver_x_lower(sroot);
    k_high = gsl_root_fsolver_x_upper(sroot);
    status = gsl_root_test_interval(k_low, k_high, errabs, errrel);

    if(status == GSL_SUCCESS && params->VERBOSE) {
      printf("Converged with k_min=%g\n", params->k);
    }
        }
      while (status == GSL_CONTINUE && iter < max_iter);
    } else {
      fprintf(stderr, "Aborted attempt to find k_min.\n");
    }
    gsl_root_fsolver_free (sroot);

    //Check to make sure we converged. If not, don't save the results.
    if (status == GSL_SUCCESS) {
      k_min = params->k;

      //Make sure everything is set up correctly for the normal run
      params->kva = params->k*params->va;
      free(grid->r);
      free(grid->x);
      free(grid->r2inv);
      free(grid);
      grid = gridgen(params);

      //Now do a normal run with the chosen k
      arpack_params->sigma = find_sigma(matrix, params, grid, rotation,
    			      arpack_params);
      results = eigensolve(matrix, params, grid, rotation, arpack_params);

      //Set the new file name, and write the output
      get_sparam("basefilename", input_file_name, output_control->basefilename);
      strcat(output_control->basefilename, "_kmin");
      wnetcdf(params, grid, rotation, output_control, arpack_params, results);

      free(results->lambda);
      free(results->z);
      free(results->residual);
      free(results);
    }
    */

    /* Now move on to solving for k_max. */
    Troot = gsl_root_fsolver_brent;
    sroot = gsl_root_fsolver_alloc(Troot);

    //Set the initial bounds for the search. We're searching for k_max,
    //so search from k_peak to a large number
    k_low = k_peak;
    k_high = 10000;
    status = gsl_root_fsolver_set(sroot, &F, k_low, k_high);
    //Make sure that we didn't thrown an error on initialization
    if (status == GSL_SUCCESS) {
        //Now iterate!
        iter = 0;
        do
        {
            iter++;
            status = gsl_root_fsolver_iterate(sroot);
            //Make sure that we didn't thrown an error in the iteration routine
            if (status != GSL_SUCCESS) {
                fprintf(stderr, "Aborted attempt to find k_max.\n");
                break;
            }

            params->k = gsl_root_fsolver_root(sroot);
            k_low = gsl_root_fsolver_x_lower(sroot);
            k_high = gsl_root_fsolver_x_upper(sroot);
            status = gsl_root_test_interval(k_low, k_high, errabs, errrel);

            if(status == GSL_SUCCESS && params->VERBOSE) {
                printf("Converged with k_max=%g\n", params->k);
            }
        }
        while (status == GSL_CONTINUE && iter < max_iter);
    } else {
        fprintf(stderr, "Aborted attempt to find k_max.\n");
    }
    gsl_root_fsolver_free (sroot);

    //Check to make sure we converged. If not, don't save the results.
    if (status == GSL_SUCCESS) {
        k_max = params->k;

        //Make sure everything is set up correctly for the normal run
        params->kva = params->k*params->va;
        free(grid->r);
        free(grid->x);
        free(grid->r2inv);
        free(grid);
        grid = gridgen(params);

        //Now do a normal run with the chosen k
        arpack_params->sigma = find_sigma(matrix, params, grid, rotation,
                                          arpack_params);
        results = eigensolve(matrix, params, grid, rotation, arpack_params);

        //Set the new file name, and write the output
        get_sparam("basefilename", input_file_name, output_control->basefilename);
        strcat(output_control->basefilename, "_kmax");
        wnetcdf(params, grid, rotation, output_control, arpack_params, results);

        free(results->lambda);
        free(results->z);
        free(results->residual);
        free(results);
    }

    printf("Found k_min = %g, k_peak = %g, k_max = %g\n", k_min, k_peak, k_max);
    printf("Peak growth rate: %g\n", gr_peak);

    free(matrix->A);
    free(matrix->B);
    free(matrix->Bb);
    free(matrix);
    free(params);
    free(grid->r);
    free(grid->x);
    free(grid->r2inv);
    free(grid);
    free(rotation->omega);
    free(rotation);
    free(output_control);

    return;
}
コード例 #5
0
ファイル: lodo.cpp プロジェクト: Arkapravo/Player-3.0.2
// Find correction
double lodo_correct(lodo_t *self)
{
  int i, ni, erc;
  vector2_t q;
  double r;
  double interval;
  double offset, err;
  double best_offset, best_err, best_outliers;
  gsl_function func;

  // Pre-compute some values used in the test function
  for (i = 0; i < self->num_ranges; i++)
  {
    // Get range relative to laser
    r = self->scan.ranges[i];
    if (r > self->range_max)
    {
      self->scan_points[i].ni = -1;
      continue;
    }

    // Compute cartesian points relative to robot
    q.x = r * cos(i * self->range_step + self->range_start);
    q.y = r * sin(i * self->range_step + self->range_start);    //printf("ni=%d\n",ni);

    q = pose2_add_pos(q, self->laser_pose);

    // Compute range relative to robot
    r = vector2_mag(q);
    ni = LODO_LTOR(r);
	//printf ("ni = %d\tself->pef_num_ranges = %d\n", ni, self->pef_num_ranges);
    if (ni < 0 || ni > self->pef_num_ranges)
      ni = -1;
    self->scan_points[i].ni = ni;
  }

  best_offset = 0.0;
  best_err = DBL_MAX;

  // Initialize the minimizer
  func.function = (double (*) (double, void*)) lodo_correct_func;
  func.params = self;
  erc = gsl_min_fminimizer_set(self->mini, &func,
                               0.0, -self->fit_interval, +self->fit_interval);

  // If the minimizer failes, revert to exhaustive search
  if (erc != GSL_SUCCESS)
  {
    //printf("brute force\n\n");
    best_err = DBL_MAX;
    for (i = -100; i <= 100; i++)
    {
      offset = i * self->fit_interval / 100.0;
      err = lodo_test_offset(self, offset, NULL);
      //printf("%d %f %f\n", i, offset, err);
      if (err < best_err)
      {
        best_err = err;
        best_offset = offset;
      }
    }
    //printf("\n\n");
  }
  else
  {
    for (i = 0; i < 10; i++) // HACK
    {
      erc = gsl_min_fminimizer_iterate(self->mini);
      if (erc == GSL_EBADFUNC)
        assert(0);
      if (erc == GSL_FAILURE)
        break;

      // Test for convergence
      interval = gsl_min_fminimizer_x_upper(self->mini);
      interval -= gsl_min_fminimizer_x_lower(self->mini);
      if (interval < 0.01 * M_PI / 180) // HACK
        break;
    }

    best_offset = gsl_min_fminimizer_x_minimum(self->mini);
    best_err = gsl_min_fminimizer_f_minimum(self->mini);
  }

  // Re-do the test to get the outlier count
  lodo_test_offset(self, best_offset, &best_outliers);

  // Check it his is a good fit.
  if (best_err > self->fit_err_thresh)
  {
    self->fit_valid = 0;
    self->fit_add = 0;
    self->fit_correct = 0;
    return 0;
  }

  self->fit_valid = 1;

  // See if should add this scan to the map.  The logic is this: if we
  // have a good fit, but there are lots of points that are "outliers"
  // (i.e., large-ish error value), then these points should be added
  // to the map.  Works for both turning in place and "bursting"
  // through doorways.
  if (fabs(best_offset) < 5 * M_PI / 180) // HACK
  {
    if (best_outliers > self->fit_outlier_frac)
      self->fit_add = 1;
    else
      self->fit_add = 0;
  }

  // Correct the scan pose
  self->fit_correct = best_offset;
  self->scan.cpose.rot = pose2_add_rot(self->fit_correct, self->scan.cpose);

  return 0;
}
コード例 #6
0
REAL8 XLALMinimizeEThincaParameterOverTravelTime( REAL8 travelTime,
                                                  EThincaMinimizer *minimizer,
                                                  INT4   exttrig
                                                )
{
  REAL8 ethinca;


  /* If colocated detectors or known sky position, just return the e-thinca parameter */
  if (travelTime == 0.0 || exttrig )
  {
    ethinca = minimizeEThincaParameterOverTimeDiff( travelTime, minimizer );
    if ( XLAL_IS_REAL8_FAIL_NAN(ethinca) )
    {
      XLAL_ERROR_REAL8( XLAL_EFUNC );
    }
    return ethinca;
  }
  else
  {
    gsl_function        F;
    INT4                min_status;
    INT4                iter = 0;
    const INT4          max_iter = 100;
    REAL8               epsilon = 1.0 / 16384.0;
    REAL8               m = 0.0;
    REAL8               a = - travelTime, b = travelTime; /* Upper and lower bounds */
    REAL8               minEThinca, maxEThinca;
    REAL8               midEThinca;
    gsl_min_fminimizer  *s = gsl_min_fminimizer_alloc( minimizer->workSpace->T );

    if ( !s )
    {
      XLAL_ERROR_REAL8( XLAL_ENOMEM );
    }


    F.function = &minimizeEThincaParameterOverTimeDiff;
    F.params   = minimizer;

    /* Calculate e-thinca parameter at start, end and mid points */
    minEThinca = minimizeEThincaParameterOverTimeDiff( a, minimizer );
    maxEThinca = minimizeEThincaParameterOverTimeDiff( b, minimizer );
    midEThinca = minimizeEThincaParameterOverTimeDiff( m, minimizer );
    if ( XLAL_IS_REAL8_FAIL_NAN(minEThinca) || XLAL_IS_REAL8_FAIL_NAN(maxEThinca)
         || XLAL_IS_REAL8_FAIL_NAN(midEThinca) )
    {
      gsl_min_fminimizer_free( s );
      XLAL_ERROR_REAL8( XLAL_EFUNC );
    }

    /* Check we have contained a minimum. Otherwise take appropriate action */
    if ( midEThinca >= minEThinca || midEThinca >= maxEThinca )
    {
      REAL8 testEThinca; /* To contain the lowest end-point */
      if ( minEThinca < maxEThinca )
      {
        testEThinca = minEThinca;
        m           = a + 2.0 * epsilon;
      }
      else
      {
        testEThinca = maxEThinca;
        m = b - 2.0 * epsilon;
      }
      midEThinca = minimizeEThincaParameterOverTimeDiff( m, minimizer );
      if ( XLAL_IS_REAL8_FAIL_NAN(midEThinca) )
      {
        gsl_min_fminimizer_free( s );
        XLAL_ERROR_REAL8( XLAL_EFUNC );
      }

      /* If we still don't have the minimum return the lowest end-point */
      if ( midEThinca >= testEThinca )
      {
        gsl_min_fminimizer_free( s );
        return testEThinca;
      }
    }

    /* Set up the GSL minimizer */
    XLAL_CALLGSL( min_status = gsl_min_fminimizer_set_with_values(s, &F,
                       m, midEThinca, a, minEThinca, b, maxEThinca) );
    if ( min_status != GSL_SUCCESS )
    {
      gsl_min_fminimizer_free( s );
      XLAL_ERROR_REAL8( XLAL_EFUNC );
    }

    /* Loop to perform the minimization */
    do
    {
        iter++;
        XLAL_CALLGSL( min_status = gsl_min_fminimizer_iterate (s) );
        if (min_status != GSL_SUCCESS )
        {
            gsl_min_fminimizer_free( s );
            XLAL_ERROR_REAL8( XLAL_EFUNC );
        }

        m = gsl_min_fminimizer_x_minimum (s);
        a = gsl_min_fminimizer_x_lower (s);
        b = gsl_min_fminimizer_x_upper (s);

        XLAL_CALLGSL( min_status = gsl_min_test_interval (a, b, epsilon, 0.0) );
        if (min_status != GSL_CONTINUE && min_status != GSL_SUCCESS )
        {
          gsl_min_fminimizer_free( s );
          XLAL_ERROR_REAL8( XLAL_EFUNC );
        }
    }
    while ( min_status == GSL_CONTINUE && iter < max_iter );
    /* End of minimization routine */

    /* Throw an error if max iterations would have been exceeded */
    if ( iter == max_iter && min_status == GSL_CONTINUE )
    {
      gsl_min_fminimizer_free( s );
      XLAL_ERROR_REAL8( XLAL_EMAXITER );
    }

    /* Get the minimum e-thinca param, and free memory for minimizer */
    ethinca = gsl_min_fminimizer_f_minimum( s );
    gsl_min_fminimizer_free( s );
    XLALPrintInfo( "%s: Number of iterations = %d\n", __func__, iter);
  }

  /* Return the required e-thinca value */
  return ethinca;
}
コード例 #7
0
ファイル: PairMatchingCut.C プロジェクト: gaponenko/Clark
bool PairMatchingCut::Get_CDA_FromCalculation( EventClass &E, int t, int a, double &z, double &cda, int &iterations)
{
	//=====================================================================//

	double z1,z2;
	//------------------------------------------------------------------//
	// Find the range where to look for the CDA                         //
	//------------------------------------------------------------------//
	if( E.dcmin[t] < E.dcmin[a])
	{
          z1 = E.geo->dc(std::min(E.dcmax[t], E.dcmin[a])).center().z();
          z2 = E.geo->dc(std::max(E.dcmax[t], E.dcmin[a])).center().z();
	}
	else
	{
          z1 = E.geo->dc(std::min(E.dcmax[a], E.dcmin[t])).center().z();
          z2 = E.geo->dc(std::max(E.dcmax[a], E.dcmin[t])).center().z();
	}
	z1 = z1 -0.2;
	z2 = z2 +0.2;

	// L corresponding to the maximum frequency:
	// L1 --> omega1, L2 --> omega2, omega_max = w1 + w2 --> Lmin

	double lmin = fabs(E.wavelen[t])*fabs(E.wavelen[a])/(fabs(E.wavelen[t])+fabs(E.wavelen[a]));
	// cout<<" In Get_CDA_FromCalculation 2   lmin ="<<lmin<<endl;
	// cout<<" In Get_CDA_FromCalculation 2   wavelen ="<<E.wavelen[t]<<"   "<<E.wavelen[a]<<endl;
	// cout<<" In Get_CDA_FromCalculation 2   ptot ="<<E.ptot[t]<<"   "<<E.costh[a]<<endl;
	//------------------------------------------------------------------//
	// Sample the distance to isolate local minima                      //
	// First decide about the number of points in the sample            //
	//------------------------------------------------------------------//
	int nsample = int(12*(1.+fabs(z1-z2)/lmin));

	TrackDistanceUV distance(E, t, a, z1, z2);
	vector<double> dd(nsample);
	for(int i = 0; i<nsample; i++) {
		double z = z1 + (z2-z1)*i/double(nsample-1);
		dd[i] = distance(z);
	}

	double A,M,B;
	vector<MinBracket> brackets;
	for(int i=1; i<nsample-1; i++) {
		if( (dd[i] < dd[i-1]) && (dd[i] <= dd[i+1]) ) {
			A = z1 + (z2-z1)*(i-1)/double(nsample-1);
			M = z1 + (z2-z1)*i/double(nsample-1);
			B = z1 + (z2-z1)*(i+1)/double(nsample-1);
			brackets.push_back(MinBracket(A,M,B));
		}
	}

	//------------------------------------------------------------------//
	// Check the ends of the search interval                            //
	//------------------------------------------------------------------//

	// cout<<" In Get_CDA_FromCalculation 3"<<endl;
	// The distance of approach
	vector<double> Alldist;
	// Position of minimal distance of approach
	vector<double> Allz;
	vector<int> Alliter;

	if(dd[0] <= dd[1]) {
		double ztest = z1 + std::min(z2-z1, tolerance_abs);
		double ftest = distance(ztest);
		if( (ftest <= dd[0]) && (ftest <= dd[1])) {
			//std::cerr<<"                z1 bracket"<<std::endl;
			brackets.push_back(MinBracket(z1,ztest, z1 + (z2-z1)/double(nsample-1)));
		}
		else {
			//std::cerr<<"                z1 min"<<std::endl;
			// Extract the distances of approach here
			Alldist.push_back(dd[0]);
			// Position of minimal distance of approach
			Allz.push_back(z1);
			Alliter.push_back(0);
		}
	}

	if(dd[nsample-1] <= dd[nsample-2]) {
		double ztest = z2 - std::min(z2-z1, tolerance_abs);
		double ftest = distance(ztest);
		if( (ftest <= dd[nsample-1]) && (ftest <= dd[nsample-2])) {
			//std::cerr<<"                z2 bracket"<<std::endl;
			brackets.push_back(MinBracket(z1 + (z2-z1)*(nsample-2)/double(nsample-1), ztest, z2));
		}
		else {
			//std::cerr<<"                z2 min"<<std::endl;
			// Extract the distances of approach here
			Alldist.push_back(dd[nsample-1]);
			// Position of minimal distance of approach
			Allz.push_back(z2);
			Alliter.push_back(0);
		}
	}
	// cout<<" In Get_CDA_FromCalculation 4   brackets size ="<<brackets.size()<<endl;

	//------------------------------------------------------------------//
	// Loop over the brackets and for each one of them, find a minimum. //
	//------------------------------------------------------------------//

	for(unsigned i=0; i<brackets.size(); i++) {
		//std::cerr<<"Bracket{"<<brackets[i].a<<", "<<brackets[i].m<<", "<<brackets[i].b<<std::endl;
		const gsl_min_fminimizer_type *T = gsl_min_fminimizer_brent;
		gsl_min_fminimizer *s = gsl_min_fminimizer_alloc (T);

		gsl_function F;

		F.function = &TrackDistanceUV::fwrapper;
		F.params = &distance;

		gsl_min_fminimizer_set(s, &F, brackets[i].m, brackets[i].a, brackets[i].b);

		int iter=0;
		while(1)
		{
			iter++;
			int status;
			if(GSL_SUCCESS != (status = gsl_min_fminimizer_iterate (s)) )
			{
				gsl_min_fminimizer_free(s);
				Log->warn("PairMatchingCut: Get_CDA_FromCalculation(): failure from gsl_min_fminimizer_iterate(): status==%i", status);
				return false;
			}

			M = gsl_min_fminimizer_x_minimum (s);
			A = gsl_min_fminimizer_x_lower (s);
			B = gsl_min_fminimizer_x_upper (s);

			status = gsl_min_test_interval (A, B, tolerance_abs, tolerance_rel);

			if (status == GSL_SUCCESS) { 
				//printf ("Converged:\n");
				//printf ("%5d [%.7f, %.7f] %.7f %.7f\n", iter, a, b, m, b - a);

				// Extract the distances of approach here
				Alldist.push_back(gsl_min_fminimizer_f_minimum(s));
				// Position of minimal distance of approach
				Allz.push_back(M);
				Alliter.push_back(iter);
				break;
			}
			else if(status == GSL_CONTINUE) {
				if(iter>max_iter) {
					gsl_min_fminimizer_free(s);
					Log->warn("PairMatchingCut: Get_CDA_FromCalculation(): exceeded max_iter=");
					return false;
				}
			}
			else {
				gsl_min_fminimizer_free(s);
				Log->warn("PairMatchingCut: Get_CDA_FromCalculation(); failure from gsl_min_test_interval(): status=");
				return false;
			}	

		} // while(1) minimize

		gsl_min_fminimizer_free(s);

	} // for(brackets)

	// cout<<" In Get_CDA_FromCalculation 5    Alldist size ="<<Alldist.size()<<endl;
	//------------------------------------------------------------------//
	// The CDA is the minimum of all the distances of approach          //
	//------------------------------------------------------------------//
	int MinIndex = -1;
	cda = 500.;
	z	= 1000.;
	iterations = 0;
	// cout<<" In Get_CDA_FromCalculation 6   cda = "<<cda<<endl;
	for (int i = 0; i < Alldist.size(); i++)
	{
		// cout<<" In Get_CDA_FromCalculation 6.1   AllDist[0] = "<<Alldist[0]<<endl;
		if ( Alldist[i] < cda )
		{
			MinIndex = i;
			cda	= Alldist[i];
			// cout<<" In Get_CDA_FromCalculation 6.2   cda = "<<cda<<endl;
		}
	}
	if (MinIndex == -1)
	{
		Log->warn("PairMatchingCut: Get_CDA_FromCalculation(); The cda could not be found.");
		cda	= 500;	// Safer with a large number since we cut on the small cda.
		return false;
	}
	else
	{
		z = Allz[MinIndex];
		iterations = Alliter[MinIndex];
	}
	// cout<<" In Get_CDA_FromCalculation 7   cda = "<<cda<<endl;
	
	return true;
}