/**
 * The best member of the population will be used as starting point for the minimisation process. The algorithm will stop
 * if the size of the simplex falls below the tol parameter, if the maximum number of iterations max_iter is exceeded or if
 * the inner GSL routine call reports an error (which will be logged on std::cout). After the end of the minimisation process,
 * the minimised decision vector will replace the best individual in the population, after being modified to fall within
 * the problem bounds if necessary.
 *
 * @param[in,out] pop population to evolve.
 */
void gsl_derivative_free::evolve(population &pop) const
{
	// Do nothing if the population is empty.
	if (!pop.size()) {
		return;
	}
	// Useful variables.
	const problem::base &problem = pop.problem();
	if (problem.get_f_dimension() != 1) {
		pagmo_throw(value_error,"this algorithm does not support multi-objective optimisation");
	}
	if (problem.get_c_dimension()) {
		pagmo_throw(value_error,"this algorithm does not support constrained optimisation");
	}
	const problem::base::size_type cont_size = problem.get_dimension() - problem.get_i_dimension();
	if (!cont_size) {
		pagmo_throw(value_error,"the problem has no continuous part");
	}
	// Extract the best individual.
	const population::size_type best_ind_idx = pop.get_best_idx();
	const population::individual_type &best_ind = pop.get_individual(best_ind_idx);
	// GSL wrapper parameters structure.
	objfun_wrapper_params params;
	params.p = &problem;
	// Integer part of the temporay decision vector must be filled with the integer part of the best individual,
	// which will not be optimised.
	params.x.resize(problem.get_dimension());
	std::copy(best_ind.cur_x.begin() + cont_size, best_ind.cur_x.end(), params.x.begin() + cont_size);
	params.f.resize(1);
	// GSL function structure.
	gsl_multimin_function gsl_func;
	// Number of function components.
	gsl_func.n = boost::numeric_cast<std::size_t>(cont_size);
	gsl_func.f = &objfun_wrapper;
	gsl_func.params = (void *)&params;
	// Mimimizer.
	gsl_multimin_fminimizer *s = 0;
	// Starting point and step sizes.
	gsl_vector *x = 0, *ss = 0;
	// Here we start the allocations.
	// Recast as size_t here, in order to avoid potential overflows later.
	const std::size_t s_cont_size = boost::numeric_cast<std::size_t>(cont_size);
	// Allocate and check the allocation results.
	x = gsl_vector_alloc(s_cont_size);
	ss = gsl_vector_alloc(s_cont_size);
	const gsl_multimin_fminimizer_type *minimiser = get_gsl_minimiser_ptr();
	pagmo_assert(minimiser);
	s = gsl_multimin_fminimizer_alloc(minimiser,s_cont_size);
	// Check the allocations.
	check_allocs(x,ss,s);
	// Starting point comes from the best individual.
	for (std::size_t i = 0; i < s_cont_size; ++i) {
		gsl_vector_set(x,i,best_ind.cur_x[i]);
	}
	// Set initial step sizes.
	gsl_vector_set_all(ss,m_step_size);
	// Init the solver.
	gsl_multimin_fminimizer_set(s,&gsl_func,x,ss);
	// Iterate.
	std::size_t iter = 0;
	int status;
	double size;
	try {
		do
		{
			status = gsl_multimin_fminimizer_iterate(s);
			++iter;
			if (status) {
				break;
			}
			size = gsl_multimin_fminimizer_size(s);
			status = gsl_multimin_test_size(size, m_tol);
			if (m_screen_output) {
				if (!((iter-1)%20)) {
					std::cout << std::endl << std::left << std::setw(20) << 
					"Iter." << std::setw(20) << 
					"Best " << std::setw(20) <<
					"Size "<< std::endl; 
				}
			std::cout << std::left << std::setprecision(14) << std::setw(20) << 
			 iter << std::setw(20) << 
			 gsl_multimin_fminimizer_minimum(s) << std::setw(20) << 
			 size << std::endl;
			}
		} while (status == GSL_CONTINUE && iter < m_max_iter);
	} catch (const std::exception &e) {
		// Cleanup and re-throw.
		cleanup(x,ss,s);
		throw e;
	} catch (...) {
		// Cleanup and throw.
		cleanup(x,ss,s);
		pagmo_throw(std::runtime_error,"unknown exception caught in gsl_derivative_free::evolve");
	}
	// Free up resources.
	cleanup(x,ss,s);
	// Check the generated individual and change it to respect the bounds as necessary.
	for (problem::base::size_type i = 0; i < cont_size; ++i) {
		if (params.x[i] < problem.get_lb()[i]) {
			params.x[i] = problem.get_lb()[i];
		}
		if (params.x[i] > problem.get_ub()[i]) {
			params.x[i] = problem.get_ub()[i];
		}
	}
	// Replace the best individual.
	pop.set_x(best_ind_idx,params.x);
}
Exemple #2
0
void find_periodic_solution_multi_dims(struct_all_ode *sao) {
    struct_state_ode sx;
    int NB_PAR = 2;
    int nb_jump, ij, iq;
    double t_max = 2;
    ;
    double th_init = 2 * M_PI / 180, vz_init = -1;
    double vth_init, vth_min, vth_max, vth_tolabs, deltaf;

    int status;
    int iter = 0, max_iter = 100;
    double size;
    const gsl_multimin_fminimizer_type *T;
    gsl_multimin_fminimizer *s = NULL;
    gsl_vector *ss, *x;
    gsl_multimin_function F;

    // init the function to minimize
    vth_init = 0 * M_PI / 180;
    vth_min = -200 * M_PI / 180;
    vth_max = 200 * M_PI / 180;
    vth_tolabs = 0.001 * M_PI / 180;
    // find vth init such as to obtain a periodic solution
    if (sao == NULL) {
        sao = new_all_ode(sao, NULL);
    }
    sao->eps_rel = 1e-6;
    sao->eps_abs = 1e-6;
    sao->h = 1e-6;
    sao->hmax = 1;
    sao->mode = MODE_FLY;
    sao->x[INDX_PH] = 0 * M_PI / 180;
    sao->x[INDX_TH] = th_init;
    sao->x[INDX_X] = 0;
    sao->x[INDX_Z] = 0;
    sao->x[INDX_R] = sao->r0;
    sao->x[INDX_VPH] = 0 * M_PI / 180;
    sao->x[INDX_VTH] = 0;
    sao->x[INDX_VR] = 0; // vr for flying model
    sao->x[INDX_ROOT] = 0;
    // trajectoire periodique => pas de perte d'energie a l'aterrisage,
    // vx =-vz.tan(theta) est imposee par vz et theta
    // le seul parametre permettant de fixer la periodicite est vtheta
    sao->x[INDX_TH] = th_init;
    sao->x[INDX_VX] = -vz_init * sin(th_init) / cos(th_init);
    sao->x[INDX_VZ] = vz_init;
    sx.NX = sao->NX;
    memcpy(sx.x, sao->x, sx.NX * sizeof (double));
    sx.mode = sao->mode;
    sx.time_s = 0;
    sx.NX = sao->NX;
    sao->initial_state = sx;
    x = gsl_vector_alloc(NB_PAR);
    gsl_vector_set(x, 0, sao->x[INDX_VTH]);
    gsl_vector_set(x, 1, sao->x[INDX_VZ]);
    /* Initialize method and iterate */
    T =
            gsl_multimin_fminimizer_nmsimplex2;
    F.n = NB_PAR; // vth,vz
    F.f = &get_delta_x_on_period_multi_dims;
    F.params = (void *) sao;
    /* Set initial step sizes to 1 */
    ss = gsl_vector_alloc(2);
    gsl_vector_set(ss, 0, 0.1 * M_PI / 180);
    gsl_vector_set(ss, 1, 0.1);


    s = gsl_multimin_fminimizer_alloc(T, F.n);
    gsl_multimin_fminimizer_set(s, &F, x, ss);

    do {
        iter++;
        status = gsl_multimin_fminimizer_iterate(s);

        if (status)
            break;

        size = gsl_multimin_fminimizer_size(s);
        status = gsl_multimin_test_size(size, 1e-4);

        if (status == GSL_SUCCESS) {
            printf("converged to minimum at %d\n", iter);
        }

        if (status == GSL_SUCCESS) {
            deltaf = get_delta_x_on_period_multi_dims(x, sao);
            printf("Converged, delta f= %.5e:\n", deltaf);
        }
    } while (status == GSL_CONTINUE && iter < max_iter);
    gsl_vector_free(x);
    gsl_vector_free(ss);
    gsl_multimin_fminimizer_free(s);
    memcpy(sao->x, sao->initial_state.x, sao->NX * sizeof (double));
    sao->time_second = 0;
    sao->mode = sx.mode;
    sao->print_values_fly_to_sol = 1;
    printf("--- initial state at time t= %e ----------\n", sao->final_state.time_s);
    print_state(sao->initial_state.x, NULL);
    print_energies(sao, sao->initial_state.x);

    printf("--- final state at time t= %e ----------\n", sao->final_state.time_s);
    print_state(sao->final_state.x, NULL);
    print_energies(sao, sao->final_state.x);

}
std::vector<double> Calibrator::Calibrate(std::vector<double> initialVector, OptionParameterSet options[], double (*objectiveFunction)(const gsl_vector *v, void *params), std::ofstream &output){
    
    const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex2;
	gsl_multimin_fminimizer *s = NULL;
	gsl_vector *ss, *x;
	gsl_multimin_function minex_func;
    
	size_t iter = 0;
	int status;
	double size;
    
    std::vector<double> result;
	
    int numOfVariable = (int) initialVector.size();
    
    //Starting point
    x = gsl_vector_alloc(numOfVariable);
    
    for (int i = 0; i < numOfVariable; i++) {
        gsl_vector_set (x, i, initialVector[i]);
    }
    
    minex_func.f = objectiveFunction;
    ss = gsl_vector_alloc(numOfVariable);
    minex_func.n = numOfVariable;
    s = gsl_multimin_fminimizer_alloc (T, numOfVariable);
    
	//Set initial step sizes to 1
	gsl_vector_set_all (ss, 1);
    
	//Initialize method and iterate
	minex_func.params = options;
    
	gsl_multimin_fminimizer_set (s, &minex_func, x, ss);
	do{
        
		status = gsl_multimin_fminimizer_iterate(s);
		if (status)
            break;
		size = gsl_multimin_fminimizer_size (s);
		status = gsl_multimin_test_size (size, 1e-3); //1e-3 for Heston, 1e-4 for VGSA for better result
        
		if (status == GSL_SUCCESS){
            
            std::cout << "A solution is found!" << std::endl;
            output << "Final Result:"<< std::endl;
            
            for (int i = 0; i < numOfVariable; ++i)
                result.push_back( gsl_vector_get (s->x, i) );
		}
        
        //Print current step info
        std::cout << "size = " << size << ", f() = " << s->fval << ": ";
        output << "size = " << size << ",f() = " << s->fval << ",";
        
        for (int i = 0; i < numOfVariable; ++i) {
            double val = gsl_vector_get (s->x, i);
            output << val << ",";
            std::cout << val << ", ";
        }
        
        output << std::endl;
        std::cout << std::endl;
        
        iter++;
	}
	while (status == GSL_CONTINUE && iter < 50000 );
	
	gsl_vector_free(x);
	gsl_vector_free(ss);
	gsl_multimin_fminimizer_free (s);
    
    return result;
}
Exemple #4
0
/** Executes the algorithm
 *
 *  @throw runtime_error Thrown if algorithm cannot execute
 */
void Fit1D::exec()
{

  // Custom initialization
  prepare();

  // check if derivative defined in derived class
  bool isDerivDefined = true;
  gsl_matrix * M = NULL;
  try
  {
    const std::vector<double> inTest(m_parameterNames.size(),1.0);
    std::vector<double> outTest(m_parameterNames.size());
    const double xValuesTest = 0;
    JacobianImpl J;
    M = gsl_matrix_alloc(m_parameterNames.size(),1);
    J.setJ(M);
    // note nData set to zero (last argument) hence this should avoid further memory problems
    functionDeriv(&(inTest.front()), &J, &xValuesTest, 0);
  }
  catch (Exception::NotImplementedError&)
  {
    isDerivDefined = false;
  }
  gsl_matrix_free(M);

  // Try to retrieve optional properties
  int histNumber = getProperty("WorkspaceIndex");
  const int maxInterations = getProperty("MaxIterations");

  // Get the input workspace
  MatrixWorkspace_const_sptr localworkspace = getProperty("InputWorkspace");

  // number of histogram is equal to the number of spectra
  const size_t numberOfSpectra = localworkspace->getNumberHistograms();
  // Check that the index given is valid
  if ( histNumber >= static_cast<int>(numberOfSpectra) )
  {
    g_log.warning("Invalid Workspace index given, using first Workspace");
    histNumber = 0;
  }

  // Retrieve the spectrum into a vector
  const MantidVec& XValues = localworkspace->readX(histNumber);
  const MantidVec& YValues = localworkspace->readY(histNumber);
  const MantidVec& YErrors = localworkspace->readE(histNumber);

  //Read in the fitting range data that we were sent
  double startX = getProperty("StartX");
  double endX = getProperty("EndX");
  //check if the values had been set, otherwise use defaults
  if ( isEmpty( startX ) )
  {
    startX = XValues.front();
    modifyStartOfRange(startX); // does nothing by default but derived class may provide a more intelligent value
  }
  if ( isEmpty( endX ) )
  {
    endX = XValues.back();
    modifyEndOfRange(endX); // does nothing by default but derived class may previde a more intelligent value
  }

  int m_minX;
  int m_maxX;

  // Check the validity of startX
  if ( startX < XValues.front() )
  {
    g_log.warning("StartX out of range! Set to start of frame.");
    startX = XValues.front();
  }
  // Get the corresponding bin boundary that comes before (or coincides with) this value
  for (m_minX = 0; XValues[m_minX+1] < startX; ++m_minX) {}

  // Check the validity of endX and get the bin boundary that come after (or coincides with) it
  if ( endX >= XValues.back() || endX < startX )
  {
    g_log.warning("EndX out of range! Set to end of frame");
    endX = XValues.back();
    m_maxX = static_cast<int>(YValues.size());
  }
  else
  {
    for (m_maxX = m_minX; XValues[m_maxX] < endX; ++m_maxX) {}
  }

  afterDataRangedDetermined(m_minX, m_maxX);

  // create and populate GSL data container warn user if l_data.n < l_data.p 
  // since as a rule of thumb this is required as a minimum to obtained 'accurate'
  // fitting parameter values.

  FitData l_data(this,getProperty("Fix"));

  l_data.n = m_maxX - m_minX; // m_minX and m_maxX are array index markers. I.e. e.g. 0 & 19.
  if (l_data.n == 0)
  {
    g_log.error("The data set is empty.");
    throw std::runtime_error("The data set is empty.");
  }
  if (l_data.n < l_data.p)
  {
    g_log.error("Number of data points less than number of parameters to be fitted.");
    throw std::runtime_error("Number of data points less than number of parameters to be fitted.");
  }
  l_data.X = new double[l_data.n];
  l_data.sigmaData = new double[l_data.n];
  l_data.forSimplexLSwrap = new double[l_data.n];
  l_data.parameters = new double[nParams()];

  // check if histogram data in which case use mid points of histogram bins

  const bool isHistogram = localworkspace->isHistogramData();
  for (unsigned int i = 0; i < l_data.n; ++i)
  {
    if (isHistogram)
      l_data.X[i] = 0.5*(XValues[m_minX+i]+XValues[m_minX+i+1]); // take mid-point if histogram bin
    else
      l_data.X[i] = XValues[m_minX+i];
  }

  l_data.Y = &YValues[m_minX];

  // check that no error is negative or zero
  for (unsigned int i = 0; i < l_data.n; ++i)
  {
    if (YErrors[m_minX+i] <= 0.0)
    {
      l_data.sigmaData[i] = 1.0;
    }
    else
      l_data.sigmaData[i] = YErrors[m_minX+i];
  }


  // create array of fitted parameter. Take these to those input by the user. However, for doing the
  // underlying fitting it might be more efficient to actually perform the fitting on some of other
  // form of the fitted parameters. For instance, take the Gaussian sigma parameter. In practice it
  // in fact more efficient to perform the fitting not on sigma but 1/sigma^2. The methods 
  // modifyInitialFittedParameters() and modifyFinalFittedParameters() are used to allow for this;
  // by default these function do nothing.

  m_fittedParameter.clear();
  for (size_t i = 0; i < nParams(); i++)
  {
      m_fittedParameter.push_back(getProperty(m_parameterNames[i]));
  }
  modifyInitialFittedParameters(m_fittedParameter); // does nothing except if overwritten by derived class
  for (size_t i = 0; i < nParams(); i++)
  {
      l_data.parameters[i] = m_fittedParameter[i];
  }


  // set-up initial guess for fit parameters

  gsl_vector *initFuncArg;
  initFuncArg = gsl_vector_alloc(l_data.p);

  for (size_t i = 0,j = 0; i < nParams(); i++)
  {
      if (l_data.active[i])
          gsl_vector_set(initFuncArg, j++, m_fittedParameter[i]);
  }


  // set-up GSL container to be used with GSL simplex algorithm

  gsl_multimin_function gslSimplexContainer;
  gslSimplexContainer.n = l_data.p;  // n here refers to number of parameters
  gslSimplexContainer.f = &gsl_costFunction;
  gslSimplexContainer.params = &l_data;


  // set-up GSL least squares container

  gsl_multifit_function_fdf f;
  f.f = &gsl_f;
  f.df = &gsl_df;
  f.fdf = &gsl_fdf;
  f.n = l_data.n;
  f.p = l_data.p;
  f.params = &l_data;

  // set-up remaining GSL machinery for least squared

  const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder;
  gsl_multifit_fdfsolver *s = NULL;
  if (isDerivDefined)
  {
    s = gsl_multifit_fdfsolver_alloc(T, l_data.n, l_data.p);
    gsl_multifit_fdfsolver_set(s, &f, initFuncArg);
  }

  // set-up remaining GSL machinery to use simplex algorithm

  const gsl_multimin_fminimizer_type *simplexType = gsl_multimin_fminimizer_nmsimplex;
  gsl_multimin_fminimizer *simplexMinimizer = NULL;
  gsl_vector *simplexStepSize = NULL;
  if (!isDerivDefined)
  {
    simplexMinimizer = gsl_multimin_fminimizer_alloc(simplexType, l_data.p);
    simplexStepSize = gsl_vector_alloc(l_data.p);
    gsl_vector_set_all (simplexStepSize, 1.0);  // is this always a sensible starting step size?
    gsl_multimin_fminimizer_set(simplexMinimizer, &gslSimplexContainer, initFuncArg, simplexStepSize);
  }

  // finally do the fitting

  int iter = 0;
  int status;
  double size; // for simplex algorithm
  double finalCostFuncVal;
  double dof = static_cast<double>(l_data.n - l_data.p);  // dof stands for degrees of freedom

  // Standard least-squares used if derivative function defined otherwise simplex
  Progress prog(this,0.0,1.0,maxInterations);
  if (isDerivDefined)
  {
	  
    do
    {
      iter++;
      status = gsl_multifit_fdfsolver_iterate(s);

      if (status)  // break if error
        break;

      status = gsl_multifit_test_delta(s->dx, s->x, 1e-4, 1e-4);
	  prog.report();
    }
    while (status == GSL_CONTINUE && iter < maxInterations);

    double chi = gsl_blas_dnrm2(s->f);
    finalCostFuncVal = chi*chi / dof;

    // put final converged fitting values back into m_fittedParameter
    for (size_t i = 0, j = 0; i < nParams(); i++)
      if (l_data.active[i])
          m_fittedParameter[i] = gsl_vector_get(s->x,j++);
  }
  else
  {
    do
    {
      iter++;
      status = gsl_multimin_fminimizer_iterate(simplexMinimizer);

      if (status)  // break if error
        break;

      size = gsl_multimin_fminimizer_size(simplexMinimizer);
      status = gsl_multimin_test_size(size, 1e-2);
	  prog.report();
    }
    while (status == GSL_CONTINUE && iter < maxInterations);

    finalCostFuncVal = simplexMinimizer->fval / dof;

    // put final converged fitting values back into m_fittedParameter
    for (unsigned int i = 0, j = 0; i < m_fittedParameter.size(); i++)
      if (l_data.active[i])
          m_fittedParameter[i] = gsl_vector_get(simplexMinimizer->x,j++);
  }

  modifyFinalFittedParameters(m_fittedParameter);   // do nothing except if overwritten by derived class


  // Output summary to log file

  std::string reportOfFit = gsl_strerror(status);

  g_log.information() << "Iteration = " << iter << "\n" <<
    "Status = " << reportOfFit << "\n" <<
    "Chi^2/DoF = " << finalCostFuncVal << "\n";
  for (size_t i = 0; i < m_fittedParameter.size(); i++)
    g_log.information() << m_parameterNames[i] << " = " << m_fittedParameter[i] << "  \n";


  // also output summary to properties

  setProperty("OutputStatus", reportOfFit);
  setProperty("OutputChi2overDoF", finalCostFuncVal);
  for (size_t i = 0; i < m_fittedParameter.size(); i++)
    setProperty(m_parameterNames[i], m_fittedParameter[i]);


  std::string output = getProperty("Output");
  if (!output.empty())
  {
    // calculate covariance matrix if derivatives available

    gsl_matrix *covar(NULL);
    std::vector<double> standardDeviations;
    std::vector<double> sdExtended;
    if (isDerivDefined)    
    {
      covar = gsl_matrix_alloc (l_data.p, l_data.p);
      gsl_multifit_covar (s->J, 0.0, covar);

      int iPNotFixed = 0;
      for(size_t i=0;i<nParams();i++)
      {
        sdExtended.push_back(1.0);
        if (l_data.active[i])
        {
          sdExtended[i] = sqrt(gsl_matrix_get(covar,iPNotFixed,iPNotFixed));
          iPNotFixed++;
        }
      }
      modifyFinalFittedParameters(sdExtended);
      for(size_t i=0;i<nParams();i++)
        if (l_data.active[i])
          standardDeviations.push_back(sdExtended[i]);

      declareProperty(
        new WorkspaceProperty<API::ITableWorkspace>("OutputNormalisedCovarianceMatrix","",Direction::Output),
        "The name of the TableWorkspace in which to store the final covariance matrix" );
      setPropertyValue("OutputNormalisedCovarianceMatrix",output+"_NormalisedCovarianceMatrix");

      Mantid::API::ITableWorkspace_sptr m_covariance = Mantid::API::WorkspaceFactory::Instance().createTable("TableWorkspace");
      m_covariance->addColumn("str","Name");
      std::vector<std::string> paramThatAreFitted; // used for populating 1st "name" column
      for(size_t i=0;i<nParams();i++) 
      {
        if (l_data.active[i]) 
        {
          m_covariance->addColumn("double",m_parameterNames[i]);
          paramThatAreFitted.push_back(m_parameterNames[i]);
        }
      }

      for(size_t i=0;i<l_data.p;i++) 
      {

        Mantid::API::TableRow row = m_covariance->appendRow();
        row << paramThatAreFitted[i];
        for(size_t j=0;j<l_data.p;j++)
        {
          if (j == i)
            row << 1.0;
          else
          {
            row << 100.0*gsl_matrix_get(covar,i,j)/sqrt(gsl_matrix_get(covar,i,i)*gsl_matrix_get(covar,j,j));
          }
        }
      }

      setProperty("OutputNormalisedCovarianceMatrix",m_covariance);
    }



    declareProperty(
      new WorkspaceProperty<API::ITableWorkspace>("OutputParameters","",Direction::Output),
      "The name of the TableWorkspace in which to store the final fit parameters" );
    declareProperty(new WorkspaceProperty<MatrixWorkspace>("OutputWorkspace","",Direction::Output), 
      "Name of the output Workspace holding resulting simlated spectrum");

    setPropertyValue("OutputParameters",output+"_Parameters");
    setPropertyValue("OutputWorkspace",output+"_Workspace");

    // Save the final fit parameters in the output table workspace
    Mantid::API::ITableWorkspace_sptr m_result = Mantid::API::WorkspaceFactory::Instance().createTable("TableWorkspace");
    m_result->addColumn("str","Name");
    m_result->addColumn("double","Value");
    if (isDerivDefined) 
      m_result->addColumn("double","Error");
    Mantid::API::TableRow row = m_result->appendRow();
    row << "Chi^2/DoF" << finalCostFuncVal;

    for(size_t i=0;i<nParams();i++)
    {
      Mantid::API::TableRow row = m_result->appendRow();
      row << m_parameterNames[i] << m_fittedParameter[i];
      if (isDerivDefined && l_data.active[i]) 
      {
        // perhaps want to scale standard deviations with sqrt(finalCostFuncVal)
        row << sdExtended[i];
      }
    }
    setProperty("OutputParameters",m_result);

    // Save the fitted and simulated spectra in the output workspace
    MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace");
    int iSpec = getProperty("WorkspaceIndex");
    const MantidVec& inputX = inputWorkspace->readX(iSpec);
    const MantidVec& inputY = inputWorkspace->readY(iSpec);

    int histN = isHistogram ? 1 : 0;
    Mantid::DataObjects::Workspace2D_sptr ws = boost::dynamic_pointer_cast<Mantid::DataObjects::Workspace2D>
      (
         Mantid::API::WorkspaceFactory::Instance().create(
                     "Workspace2D",
                     3,
                     l_data.n + histN,
                     l_data.n)
      );
    ws->setTitle("");
    ws->getAxis(0)->unit() = inputWorkspace->getAxis(0)->unit();//    UnitFactory::Instance().create("TOF");

    for(int i=0;i<3;i++)
      ws->dataX(i).assign(inputX.begin()+m_minX,inputX.begin()+m_maxX+histN);

    ws->dataY(0).assign(inputY.begin()+m_minX,inputY.begin()+m_maxX);

    MantidVec& Y = ws->dataY(1);
    MantidVec& E = ws->dataY(2);


    double* lOut = new double[l_data.n];  // to capture output from call to function()
    modifyInitialFittedParameters(m_fittedParameter); // does nothing except if overwritten by derived class
    function(&m_fittedParameter[0], lOut, l_data.X, l_data.n);
    modifyInitialFittedParameters(m_fittedParameter); // reverse the effect of modifyInitialFittedParameters - if any 

    for(unsigned int i=0; i<l_data.n; i++) 
    {
      Y[i] = lOut[i]; 
      E[i] = l_data.Y[i] - Y[i];
    }

    delete [] lOut; 

    setProperty("OutputWorkspace",boost::dynamic_pointer_cast<MatrixWorkspace>(ws));

    if (isDerivDefined) 
      gsl_matrix_free(covar);
  }

  // clean up dynamically allocated gsl stuff

  if (isDerivDefined)
    gsl_multifit_fdfsolver_free(s);
  else
  {
    gsl_vector_free(simplexStepSize);
    gsl_multimin_fminimizer_free(simplexMinimizer);
  }

  delete [] l_data.X;
  delete [] l_data.sigmaData;
  delete [] l_data.forSimplexLSwrap;
  delete [] l_data.parameters;
  gsl_vector_free (initFuncArg);

  return;
}
Exemple #5
0
int
main (int argc, char **argv)
{
	struct experiment_params params;
	double dx, dy;
	double speed, angle;
	gsl_vector *solution;
	int c;
	double compute_start, delta;

	while ((c = getopt (argc, argv, "v")) != EOF) {
		switch (c) {
		case 'v':
			vflag = 1;
			break;
		default:
			usage ();
		}
	}


	memset (&params, 0, sizeof params);
	params.observed_hit[0] = 0;
	params.observed_hit[1] = 0;
	params.observed_hit[2] = 1;
	params.observed_bounce[0] = 25;
	params.observed_bounce[1] = 0;
	params.observed_bounce[2] = 0;
	params.observed_secs = 1.359;

	dx = params.observed_bounce[0] - params.observed_hit[0];
	dy = params.observed_bounce[1] - params.observed_hit[1];
	params.observed_dist = hypot (dy, dx);

	params.simulator_dimen = 4;

	params.odesys.function = sim_func;
	params.odesys.dimension = params.simulator_dimen;
	params.odesys.params = &params;

	params.stepper = gsl_odeiv_step_alloc (gsl_odeiv_step_rk8pd,
					       params.simulator_dimen);
	params.controller = gsl_odeiv_control_y_new (1e-6, 0.0);
	params.evolver = gsl_odeiv_evolve_alloc (params.simulator_dimen);
	
	params.minimizer_dimen = 2;
	params.starting_point = gsl_vector_alloc (params.minimizer_dimen);

	params.minimizer_step_sizes = gsl_vector_alloc (params.minimizer_dimen);
	params.minimizer = gsl_multimin_fminimizer_alloc
		(gsl_multimin_fminimizer_nmsimplex2, params.minimizer_dimen);

       gsl_vector_set_all (params.starting_point, 0);
       gsl_vector_set_all (params.minimizer_step_sizes, 1.0);
     
	if (0) {
		graph_error_func (&params);
	}

	compute_start = get_secs ();
	solve_by_simulation (&params);
	delta = get_secs () - compute_start;

	solution = gsl_multimin_fminimizer_x (params.minimizer);

	speed = gsl_vector_get (solution, 0);
	angle = gsl_vector_get (solution, 1);

	printf ("speed = %8.3f angle = %8.3f; compute time %.3fms\n",
		speed * METERS_PER_SEC_TO_MPH,
		RTOD (angle),
		delta * 1000);

	return (0);
}
Exemple #6
0
int lua_multimin_minimize(lua_State * L) {
    bool ssdel=false;
    double eps=0.00001;
    double tol=0.0001;
    double step_size=0.01;
    int maxiter=1000;
    bool print=false;
    array<double> * x=0;
    array<double> * ss=0;
    const gsl_multimin_fminimizer_type *Tf = 0;
    const gsl_multimin_fdfminimizer_type *Tdf = 0;


    multi_param mp;
    mp.L=L;
    mp.fdf_index=-1;

    lua_pushstring(L,"f");
    lua_gettable(L,-2);
    if(lua_isfunction(L,-1)) {
        mp.f_index=luaL_ref(L, LUA_REGISTRYINDEX);
    } else {
        luaL_error(L,"%s\n","missing function");
    }

    lua_pushstring(L,"df");
    lua_gettable(L,-2);
    if(lua_isfunction(L,-1)) {
        mp.df_index=luaL_ref(L, LUA_REGISTRYINDEX);
        Tdf= gsl_multimin_fdfminimizer_conjugate_fr;
    } else {
        lua_pop(L,1);
        Tf= gsl_multimin_fminimizer_nmsimplex2;
    }

    lua_pushstring(L,"fdf");
    lua_gettable(L,-2);
    if(lua_isfunction(L,-1)) {
        mp.fdf_index=luaL_ref(L, LUA_REGISTRYINDEX);
    } else {
        lua_pop(L,1);
        mp.fdf_index=-1;
    }

    lua_pushstring(L,"algorithm");
    lua_gettable(L,-2);
    if(lua_isstring(L,-1)) {
        if(Tf!=0) {
            if(!strcmp(lua_tostring(L,-1),"nmsimplex")) {
                Tf = gsl_multimin_fminimizer_nmsimplex;
            } else if(!strcmp(lua_tostring(L,-1),"nmsimplex2rand")) {
                Tf = gsl_multimin_fminimizer_nmsimplex2rand;
            } else if(!strcmp(lua_tostring(L,-1),"nmsimplex2")) {
                Tf = gsl_multimin_fminimizer_nmsimplex2;
            } else {
                luaL_error(L,"%s\n","invalid algorithm");
            }
        } else {
            if(!strcmp(lua_tostring(L,-1),"conjugate_pr")) {
                Tdf = gsl_multimin_fdfminimizer_conjugate_pr;
            } else if(!strcmp(lua_tostring(L,-1),"steepest_descent")) {
                Tdf = gsl_multimin_fdfminimizer_steepest_descent;
            } else if(!strcmp(lua_tostring(L,-1),"vector_bfgs")) {
                Tdf = gsl_multimin_fdfminimizer_vector_bfgs;
            } else if(!strcmp(lua_tostring(L,-1),"vector_bfgs2")) {
                Tdf = gsl_multimin_fdfminimizer_vector_bfgs2;
            } else if(!strcmp(lua_tostring(L,-1),"conjugate_fr")) {
                Tdf = gsl_multimin_fdfminimizer_conjugate_fr;
            } else {
                luaL_error(L,"%s\n","invalid algorithm");
            }
        }
    }
    lua_pop(L,1);

    lua_pushstring(L,"show_iterations");
    lua_gettable(L,-2);
    if(lua_isboolean(L,-1)) {
        print=(lua_toboolean(L,-1)==1);
    }
    lua_pop(L,1);

    lua_pushstring(L,"eps");
    lua_gettable(L,-2);
    if(lua_isnumber(L,-1)) {
        eps=lua_tonumber(L,-1);
    }
    lua_pop(L,1);

    lua_pushstring(L,"step_size");
    lua_gettable(L,-2);
    if(lua_isnumber(L,-1)) {
        step_size=lua_tonumber(L,-1);
    }
    lua_pop(L,1);

    lua_pushstring(L,"tol");
    lua_gettable(L,-2);
    if(lua_isnumber(L,-1)) {
        tol=lua_tonumber(L,-1);
    }
    lua_pop(L,1);

    lua_pushstring(L,"maxiter");
    lua_gettable(L,-2);
    if(lua_isnumber(L,-1)) {
        maxiter=(int)lua_tonumber(L,-1);
    }
    lua_pop(L,1);

    lua_pushstring(L,"starting_point");
    lua_gettable(L,-2);
    if(!lua_isuserdata(L,-1)) lua_error(L);
    if (!SWIG_IsOK(SWIG_ConvertPtr(L,-1,(void**)&x,SWIGTYPE_p_arrayT_double_t,0))){
        luaL_error(L,"%s\n","missing starting point");
    }
    lua_pop(L,1);

    if(Tf) {
        lua_pushstring(L,"step_sizes");
        lua_gettable(L,-2);
        if(lua_isuserdata(L,-1)) {
            if (!SWIG_IsOK(SWIG_ConvertPtr(L,-1,(void**)&ss,SWIGTYPE_p_arrayT_double_t,0))){
                lua_error(L);
            }
        } else {
            ssdel=true;
            ss=new array<double>(x->size());
            ss->set_all(1.0);
            if(lua_isnumber(L,-1)) {
                double v=lua_tonumber(L,-1);
                ss->set_all(v);
            }
        }
        lua_pop(L,1);
    }

    lua_pop(L,1);

    if(Tf) {
        gsl_multimin_fminimizer *s = NULL;
        gsl_vector SS, X;
        gsl_multimin_function minex_func;

        int iter = 0;
        int status;
        double size;
        int N=x->size();

        /* Starting point */
        X.size=x->size();
        X.stride=1;
        X.data=x->data();
        X.owner=0;

        /* Set initial step sizes */
        SS.size=ss->size();
        SS.stride=1;
        SS.data=ss->data();
        SS.owner=0;

        /* Initialize method and iterate */
        minex_func.n = N;
        minex_func.f = multimin_f_cb;
        minex_func.params = &mp;

        s = gsl_multimin_fminimizer_alloc (Tf, N);
        gsl_multimin_fminimizer_set (s, &minex_func, &X, &SS);
        if(print)  printf ("running algorithm '%s'\n",
                gsl_multimin_fminimizer_name (s));
        do
        {
            iter++;
            status = gsl_multimin_fminimizer_iterate(s);

            if (status)
                break;

            size = gsl_multimin_fminimizer_size (s);
            status = gsl_multimin_test_size (size, eps);

            if (status == GSL_SUCCESS)
            {
                if(print) printf ("converged to minimum at\n");
            }

            if(print) printf ("%5d f() = %12.3f size = %.9f\n",
                    iter,
                    s->fval, size);
        } while (status == GSL_CONTINUE && iter < maxiter);
        for(int i=0;i<N;++i) x->set(i,gsl_vector_get(s->x,i));
        luaL_unref(L, LUA_REGISTRYINDEX, mp.f_index);
        gsl_multimin_fminimizer_free (s);
    } else {
        gsl_multimin_fdfminimizer *s = NULL;
        gsl_vector X;
        gsl_multimin_function_fdf minex_func;

        int iter = 0;
        int status;
        double size;
        int N=x->size();

        /* Starting point */
        X.size=x->size();
        X.stride=1;
        X.data=x->data();
        X.owner=0;

        /* Initialize method and iterate */
        minex_func.n = N;
        minex_func.f = multimin_f_cb;
        minex_func.df = multimin_df_cb;
        minex_func.fdf = multimin_fdf_cb;
        minex_func.params = &mp;

        s = gsl_multimin_fdfminimizer_alloc (Tdf, N);
        gsl_multimin_fdfminimizer_set (s, &minex_func, &X, step_size, tol);
        if(print)  printf ("running algorithm '%s'\n",
                gsl_multimin_fdfminimizer_name (s));
        do
        {
            iter++;
            status = gsl_multimin_fdfminimizer_iterate(s);

            if (status)
                break;

            status = gsl_multimin_test_gradient (s->gradient, eps);

            if (status == GSL_SUCCESS)
            {
                if(print) printf ("converged to minimum at\n");
            }

            if(print) printf ("%5d f() = %12.3f\n",
                    iter,
                    s->f);
        } while (status == GSL_CONTINUE && iter < maxiter);
        for(int i=0;i<N;++i) x->set(i,gsl_vector_get(s->x,i));
        luaL_unref(L, LUA_REGISTRYINDEX, mp.f_index);
        luaL_unref(L, LUA_REGISTRYINDEX, mp.df_index);
        gsl_multimin_fdfminimizer_free (s);
    }
    if(mp.fdf_index>=0) {
        luaL_unref(L, LUA_REGISTRYINDEX, mp.fdf_index);
    }
    if(ssdel) {
        delete ss;
    }
    return 0;
}
Exemple #7
0
  /** Executes the algorithm
  *
  *  @throw runtime_error Thrown if algorithm cannot execute
  */
  void DiffractionEventCalibrateDetectors::exec()
  {
    // Try to retrieve optional properties
    const int maxIterations = getProperty("MaxIterations");
    const double peakOpt = getProperty("LocationOfPeakToOptimize");

    // Get the input workspace
    EventWorkspace_const_sptr inputW = getProperty("InputWorkspace");

     // retrieve the properties
    const std::string rb_params=getProperty("Params");

    //Get some stuff from the input workspace
    Instrument_const_sptr inst = inputW->getInstrument();

    //Build a list of Rectangular Detectors
    std::vector<boost::shared_ptr<RectangularDetector> > detList;
    // --------- Loading only one bank ----------------------------------
    std::string onebank = getProperty("BankName");
    bool doOneBank = (onebank != ""); 
    for (int i=0; i < inst->nelements(); i++)
    {
      boost::shared_ptr<RectangularDetector> det;
      boost::shared_ptr<ICompAssembly> assem;
      boost::shared_ptr<ICompAssembly> assem2;
  
      det = boost::dynamic_pointer_cast<RectangularDetector>( (*inst)[i] );
      if (det)
      {
        if (det->getName().compare(onebank) == 0) detList.push_back(det); 
        if (!doOneBank) detList.push_back(det); 
      }
      else
      {
        //Also, look in the first sub-level for RectangularDetectors (e.g. PG3).
        // We are not doing a full recursive search since that will be very long for lots of pixels.
        assem = boost::dynamic_pointer_cast<ICompAssembly>( (*inst)[i] );
        if (assem)
        {
          for (int j=0; j < assem->nelements(); j++)
          {
            det = boost::dynamic_pointer_cast<RectangularDetector>( (*assem)[j] );
            if (det)
            {
              if (det->getName().compare(onebank) == 0) detList.push_back(det); 
              if (!doOneBank) detList.push_back(det); 
  
            }
            else
            {
              //Also, look in the second sub-level for RectangularDetectors (e.g. PG3).
              // We are not doing a full recursive search since that will be very long for lots of pixels.
              assem2 = boost::dynamic_pointer_cast<ICompAssembly>( (*assem)[j] );
              if (assem2)
              {
                for (int k=0; k < assem2->nelements(); k++)
                {
                  det = boost::dynamic_pointer_cast<RectangularDetector>( (*assem2)[k] );
                  if (det)
                  {
                    if (det->getName().compare(onebank) == 0) detList.push_back(det); 
                    if (!doOneBank) detList.push_back(det); 
                  }
                }
              }
            }
          }
        }
      }
    }


    // set-up minimizer

    std::string inname = getProperty("InputWorkspace");
    std::string outname = inname+"2"; //getProperty("OutputWorkspace");

    IAlgorithm_sptr algS = createSubAlgorithm("SortEvents");
    algS->setPropertyValue("InputWorkspace",inname);
    algS->setPropertyValue("SortBy", "X Value");
    algS->executeAsSubAlg();
    inputW=algS->getProperty("InputWorkspace");

    //Write DetCal File
    double baseX,baseY,baseZ,upX,upY,upZ;

    std::string filename=getProperty("DetCalFilename");
    std::fstream outfile;
    outfile.open(filename.c_str(), std::ios::out);

    if(detList.size() > 1) 
    {
      outfile << "#\n";
      outfile << "#  Mantid Optimized .DetCal file for SNAP with TWO detector panels\n";
      outfile << "#  Old Panel, nominal size and distance at -90 degrees.\n";
      outfile << "#  New Panel, nominal size and distance at +90 degrees.\n";
      outfile << "#\n";
      outfile << "# Lengths are in centimeters.\n";
      outfile << "# Base and up give directions of unit vectors for a local\n";
      outfile << "# x,y coordinate system on the face of the detector.\n";
      outfile << "#\n";
      std::time_t current_t = DateAndTime::get_current_time().to_time_t() ;
      std::tm * current = gmtime( &current_t );
      outfile << "# "<<asctime (current) <<"\n";
      outfile << "#\n";
      outfile << "6         L1     T0_SHIFT\n";
      IObjComponent_const_sptr source = inst->getSource();
      IObjComponent_const_sptr sample = inst->getSample();
      outfile << "7  "<<source->getDistance(*sample)*100<<"            0\n";
      outfile << "4 DETNUM  NROWS  NCOLS  WIDTH   HEIGHT   DEPTH   DETD   CenterX   CenterY   CenterZ    BaseX    BaseY    BaseZ      UpX      UpY      UpZ\n";
    }

    Progress prog(this,0.0,1.0,detList.size());
    for (int det=0; det < static_cast<int>(detList.size()); det++)
    {
      std::string par[6];
      par[0]=detList[det]->getName();
      par[1]=inname;
      par[2]=outname;
      std::ostringstream strpeakOpt;
      strpeakOpt<<peakOpt;
      par[3]=strpeakOpt.str();
      par[4]=rb_params;

      // --- Create a GroupingWorkspace for this detector name ------
      CPUTimer tim;
      IAlgorithm_sptr alg2 = AlgorithmFactory::Instance().create("CreateGroupingWorkspace", 1);
      alg2->initialize();
      alg2->setPropertyValue("InputWorkspace", getPropertyValue("InputWorkspace"));
      alg2->setPropertyValue("GroupNames", detList[det]->getName());
      std::string groupWSName = "group_" + detList[det]->getName();
      alg2->setPropertyValue("OutputWorkspace", groupWSName);
      alg2->executeAsSubAlg();
      par[5] = groupWSName;
      std::cout << tim << " to CreateGroupingWorkspace" << std::endl;

      const gsl_multimin_fminimizer_type *T =
      gsl_multimin_fminimizer_nmsimplex;
      gsl_multimin_fminimizer *s = NULL;
      gsl_vector *ss, *x;
      gsl_multimin_function minex_func;

      // finally do the fitting

      int nopt = 6;
      int iter = 0;
      int status = 0;
      double size;
 
      /* Starting point */
      x = gsl_vector_alloc (nopt);
      gsl_vector_set (x, 0, 0.0);
      gsl_vector_set (x, 1, 0.0);
      gsl_vector_set (x, 2, 0.0);
      gsl_vector_set (x, 3, 0.0);
      gsl_vector_set (x, 4, 0.0);
      gsl_vector_set (x, 5, 0.0);

      /* Set initial step sizes to 0.1 */
      ss = gsl_vector_alloc (nopt);
      gsl_vector_set_all (ss, 0.1);

      /* Initialize method and iterate */
      minex_func.n = nopt;
      minex_func.f = &Mantid::Algorithms::gsl_costFunction;
      minex_func.params = &par;

      s = gsl_multimin_fminimizer_alloc (T, nopt);
      gsl_multimin_fminimizer_set (s, &minex_func, x, ss);

      do
      {
        iter++;
        status = gsl_multimin_fminimizer_iterate(s);

        if (status)
          break;

        size = gsl_multimin_fminimizer_size (s);
        status = gsl_multimin_test_size (size, 1e-2);

      }
      while (status == GSL_CONTINUE && iter < maxIterations && s->fval != -0.000 );

      // Output summary to log file
      if (s->fval != -0.000) movedetector(gsl_vector_get (s->x, 0), gsl_vector_get (s->x, 1), gsl_vector_get (s->x, 2),
         gsl_vector_get (s->x, 3), gsl_vector_get (s->x, 4), gsl_vector_get (s->x, 5), par[0], getProperty("InputWorkspace"));
      else 
      {
        gsl_vector_set (s->x, 0, 0.0);
        gsl_vector_set (s->x, 1, 0.0);
        gsl_vector_set (s->x, 2, 0.0);
        gsl_vector_set (s->x, 3, 0.0);
        gsl_vector_set (s->x, 4, 0.0);
        gsl_vector_set (s->x, 5, 0.0);
      }

      std::string reportOfDiffractionEventCalibrateDetectors = gsl_strerror(status);
      if (s->fval == -0.000) reportOfDiffractionEventCalibrateDetectors = "No events";

      g_log.information() << "Detector = " << det << "\n" <<
        "Method used = " << "Simplex" << "\n" <<
        "Iteration = " << iter << "\n" <<
        "Status = " << reportOfDiffractionEventCalibrateDetectors << "\n" <<
        "Minimize PeakLoc-" << peakOpt << " = " << s->fval << "\n";
      //Move in cm for small shifts
      g_log.information() << "Move (X)   = " << gsl_vector_get (s->x, 0)*0.01 << "  \n";
      g_log.information() << "Move (Y)   = " << gsl_vector_get (s->x, 1)*0.01 << "  \n";
      g_log.information() << "Move (Z)   = " << gsl_vector_get (s->x, 2)*0.01 << "  \n";
      g_log.information() << "Rotate (X) = " << gsl_vector_get (s->x, 3) << "  \n";
      g_log.information() << "Rotate (Y) = " << gsl_vector_get (s->x, 4) << "  \n";
      g_log.information() << "Rotate (Z) = " << gsl_vector_get (s->x, 5) << "  \n";


      Kernel::V3D CalCenter=V3D(gsl_vector_get (s->x, 0)*0.01,
        gsl_vector_get (s->x, 1)*0.01, gsl_vector_get (s->x, 2)*0.01);
      Kernel::V3D Center=detList[det]->getPos()+CalCenter;
      int pixmax = detList[det]->xpixels()-1;
      int pixmid = (detList[det]->ypixels()-1)/2;
      BoundingBox box;
      detList[det]->getAtXY(pixmax, pixmid)->getBoundingBox(box);
      baseX = box.xMax();
      baseY = box.yMax();
      baseZ = box.zMax();
      Kernel::V3D Base=V3D(baseX,baseY,baseZ)+CalCenter;
      pixmid = (detList[det]->xpixels()-1)/2;
      pixmax = detList[det]->ypixels()-1;
      detList[det]->getAtXY(pixmid, pixmax)->getBoundingBox(box);
      upX = box.xMax();
      upY = box.yMax();
      upZ = box.zMax();
      Kernel::V3D Up=V3D(upX,upY,upZ)+CalCenter;
      Base-=Center;
      Up-=Center;
      //Rotate around x
      baseX = Base[0];
      baseY = Base[1];
      baseZ = Base[2];
      double deg2rad=M_PI/180.0;
      double angle = gsl_vector_get (s->x, 3)*deg2rad;
      Base=V3D(baseX,baseY*cos(angle)-baseZ*sin(angle),
        baseY*sin(angle)+baseZ*cos(angle));
      upX = Up[0];
      upY = Up[1];
      upZ = Up[2];
      Up=V3D(upX,upY*cos(angle)-upZ*sin(angle),
        upY*sin(angle)+upZ*cos(angle));
      //Rotate around y
      baseX = Base[0];
      baseY = Base[1];
      baseZ = Base[2];
      angle = gsl_vector_get (s->x, 4)*deg2rad;
      Base=V3D(baseZ*sin(angle)+baseX*cos(angle),
        baseY,baseZ*cos(angle)-baseX*sin(angle));
      upX = Up[0];
      upY = Up[1];
      upZ = Up[2];
      Up=V3D(upZ*cos(angle)-upX*sin(angle),upY,
        upZ*sin(angle)+upX*cos(angle));
      //Rotate around z
      baseX = Base[0];
      baseY = Base[1];
      baseZ = Base[2];
      angle = gsl_vector_get (s->x, 5)*deg2rad;
      Base=V3D(baseX*cos(angle)-baseY*sin(angle),
        baseX*sin(angle)+baseY*cos(angle),baseZ);
      upX = Up[0];
      upY = Up[1];
      upZ = Up[2];
      Up=V3D(upX*cos(angle)-upY*sin(angle),
        upX*sin(angle)+upY*cos(angle),upZ);
      Base.normalize();
      Up.normalize();
      Center*=100.0;
      // << det+1  << "  " 
      outfile << "5  " 
       << detList[det]->getName().substr(4)  << "  " 
       << detList[det]->xpixels() << "  " 
       << detList[det]->ypixels() << "  " 
       << 100.0*detList[det]->xsize() << "  " 
       << 100.0*detList[det]->ysize() << "  " 
       << "0.2000" << "  " 
       << Center.norm() << "  " ;
      Center.write(outfile);
      outfile << "  ";
      Base.write(outfile);
      outfile << "  ";
      Up.write(outfile);
      outfile << "\n";

      // clean up dynamically allocated gsl stuff
      gsl_vector_free(x);
      gsl_vector_free(ss);
      gsl_multimin_fminimizer_free (s);

      // Remove the now-unneeded grouping workspace
      AnalysisDataService::Instance().remove(groupWSName);
      prog.report(detList[det]->getName());
    }

    // Closing
    outfile.close();

    return;
  }