예제 #1
0
void least_squares_straightline_fit(void) {
	int i, n = 4;
	double x[4] = { 1970, 1980, 1990, 2000 };
	double y[4] = { 12, 11, 14, 13 };
	double w[4] = { 0.1, 0.2, 0.3, 0.4 };

	double c0, c1, cov00, cov01, cov11, chisq;

	gsl_fit_wlinear(x, 1, w, 1, y, 1, n, &c0, &c1, &cov00, &cov01, &cov11,
			&chisq);

	printf("# best fit: Y = %g + %g X\n", c0, c1);
	printf("# covariance matrix:\n");
	printf("# [ %g, %g\n#   %g, %g]\n", cov00, cov01, cov01, cov11);
	printf("# chisq = %g\n", chisq);

	for (i = 0; i < n; i++)
		printf("data: %g %g %g\n", x[i], y[i], 1 / sqrt(w[i]));

	printf("\n");

	for (i = -30; i < 130; i++) {
		double xf = x[0] + (i / 100.0) * (x[n - 1] - x[0]);
		double yf, yf_err;

		gsl_fit_linear_est(xf, c0, c1, cov00, cov01, cov11, &yf, &yf_err);

		printf("fit: %g %g\n", xf, yf);
		printf("hi : %g %g\n", xf, yf + yf_err);
		printf("lo : %g %g\n", xf, yf - yf_err);
	}
}
예제 #2
0
파일: fit.c 프로젝트: engineyard/rb-gsl
static VALUE rb_gsl_fit_linear_est(int argc, VALUE *argv, VALUE obj)
{
  double y, yerr, x, c0, c1, c00, c01, c11;
  int status;
  size_t i;
  switch (argc) {
  case 2:
    x = NUM2DBL(argv[0]);
    if (TYPE(argv[1]) == T_ARRAY) {
      c0 = NUM2DBL(rb_ary_entry(argv[1], 0));
      c1 = NUM2DBL(rb_ary_entry(argv[1], 1));
      c00 = NUM2DBL(rb_ary_entry(argv[1], 2));
      c01 = NUM2DBL(rb_ary_entry(argv[1], 3));
      c11 = NUM2DBL(rb_ary_entry(argv[1], 4));
    } else {
      rb_raise(rb_eTypeError, "argv[1] Array expected");
    }
    break;
  case 6:
    for (i = 0; i < 6; i++) Need_Float(argv[i]);
    x = NUM2DBL(argv[0]);
    c0 = NUM2DBL(argv[1]);
    c1 = NUM2DBL(argv[2]);
    c00 = NUM2DBL(argv[3]);
    c01 = NUM2DBL(argv[4]);
    c11 = NUM2DBL(argv[5]);
    break;
  default:
    rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or 6)", argc);
  }
  status = gsl_fit_linear_est(x, c0, c1, c00, c01, c11, &y, &yerr);
  return rb_ary_new3(3, rb_float_new(y), rb_float_new(yerr), INT2FIX(status));
}
예제 #3
0
파일: gsl.c 프로젝트: xushiwei/pure-lang
pure_expr* wrap_gsl_fit_linear_est(double x, double c0, double c1,
  double cov00, double cov01, double cov11)
{
  double y, y_err;
  
  gsl_fit_linear_est(x, c0, c1, cov00, cov01, cov11, &y, &y_err);
  return pure_listl(2, pure_double(y), pure_double(y_err));
}
예제 #4
0
CAMLprim value ml_gsl_fit_linear_est(value x, value coeffs)
{
  double y,y_err;
  gsl_fit_linear_est(Double_val(x), 
		     Double_field(coeffs, 0),
		     Double_field(coeffs, 1),
		     Double_field(coeffs, 2),
		     Double_field(coeffs, 3),
		     Double_field(coeffs, 4),
		     &y, &y_err);
  return copy_two_double_arr(y, y_err);
}
예제 #5
0
void Linear::exec()
{
  // Get the input workspace
  MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace");
  // Get the spectrum to fit
  const int histNumber = getProperty("WorkspaceIndex");
  // Check validity
  if ( histNumber >= static_cast<int>(inputWorkspace->getNumberHistograms()) )
  {
    g_log.error() << "WorkspaceIndex set to an invalid value of " << histNumber << std::endl;
    throw Exception::IndexError(histNumber,inputWorkspace->getNumberHistograms(),"Linear WorkspaceIndex property");
  }

  // Get references to the data in the chosen spectrum
  const MantidVec& X = inputWorkspace->dataX(histNumber);
  const MantidVec& Y = inputWorkspace->dataY(histNumber);
  const MantidVec& E = inputWorkspace->dataE(histNumber);
  // Check if this spectrum has errors
  double errorsCount = 0.0;

  // Retrieve the Start/EndX properties, if set
  this->setRange(X,Y);
  
  const bool isHistogram = inputWorkspace->isHistogramData();
  // If the spectrum to be fitted has masked bins, we want to exclude them (even if only partially masked)
  const MatrixWorkspace::MaskList * const maskedBins = 
    ( inputWorkspace->hasMaskedBins(histNumber) ? &(inputWorkspace->maskedBins(histNumber)) : NULL );
  // Put indices of masked bins into a set for easy searching later
  std::set<size_t> maskedIndices;
  if (maskedBins)
  {
    MatrixWorkspace::MaskList::const_iterator it;
    for (it = maskedBins->begin(); it != maskedBins->end(); ++it)
      maskedIndices.insert(it->first);
  }
  
  progress(0);

  // Declare temporary vectors and reserve enough space if they're going to be used
  std::vector<double> XCen, unmaskedY, weights;
  int numPoints = m_maxX - m_minX;
  if (isHistogram) XCen.reserve(numPoints);
  if (maskedBins) unmaskedY.reserve(numPoints);
  weights.reserve(numPoints);

  for (int i = 0; i < numPoints; ++i)
  {
    // If the current bin is masked, skip it
    if ( maskedBins && maskedIndices.count(m_minX+i) ) continue;
    // Need to adjust X to centre of bin, if a histogram
    if (isHistogram) XCen.push_back( 0.5*(X[m_minX+i]+X[m_minX+i+1]) );
    // If there are masked bins present, we need to copy the unmasked Y values
    if (maskedBins) unmaskedY.push_back(Y[m_minX+i]);
    // GSL wants the errors as weights, i.e. 1/sigma^2
    // We need to be careful if E is zero because that would naively lead to an infinite weight on the point.
    // Solution taken here is to zero weight if error is zero, which typically means Y is zero
    //   (so it is effectively excluded from the fit).
    const double& currentE = E[m_minX+i];
    weights.push_back( currentE ? 1.0/(currentE*currentE) : 0.0 );
    // However, if the spectrum given has all errors of zero, then we should use the gsl function that
    //   doesn't take account of the errors.
    if ( currentE ) ++errorsCount;
  }
  progress(0.3);
  
  // If masked bins present, need to recalculate numPoints here
  if (maskedBins) numPoints = static_cast<int>(unmaskedY.size());
  // If no points left for any reason, bail out
  if (numPoints == 0)
  {
    g_log.error("No points in this range to fit");
    throw std::runtime_error("No points in this range to fit");
  }

  // Set up pointer variables to pass to gsl, pointing them to the right place
  const double * const xVals = ( isHistogram ? &XCen[0] : &X[m_minX] );
  const double * const yVals = ( maskedBins ? &unmaskedY[0] : &Y[m_minX] );

  // Call the gsl fitting function
  // The stride value of 1 reflects that fact that we want every element of our input vectors
  const int stride = 1;
  double *c0(new double),*c1(new double),*cov00(new double),*cov01(new double),*cov11(new double),*chisq(new double);
  int status;
  // Unless our spectrum has error values for vast majority of points, 
  //   call the gsl function that doesn't use errors
  if ( errorsCount/numPoints < 0.9 )
  {
    g_log.debug("Calling gsl_fit_linear (doesn't use errors in fit)");
    status = gsl_fit_linear(xVals,stride,yVals,stride,numPoints,c0,c1,cov00,cov01,cov11,chisq);
  }
  // Otherwise, call the one that does account for errors on the data points
  else
  {
    g_log.debug("Calling gsl_fit_wlinear (uses errors in fit)");
    status = gsl_fit_wlinear(xVals,stride,&weights[0],stride,yVals,stride,numPoints,c0,c1,cov00,cov01,cov11,chisq);
  }
  progress(0.8);

  // Check that the fit succeeded
  std::string fitStatus = gsl_strerror(status);
  // For some reason, a fit where c0,c1 & chisq are all infinity doesn't report as a 
  //   failure, so check explicitly.
  if ( !gsl_finite(*chisq) || !gsl_finite(*c0) || !gsl_finite(*c1) )
    fitStatus = "Fit gives infinities";
  if (fitStatus != "success") g_log.error() << "The fit failed: " << fitStatus << "\n";
  else
    g_log.information() << "The fit succeeded, giving y = " << *c0 << " + " << *c1 << "*x, with a Chi^2 of " << *chisq << "\n";
  
  // Set the fit result output properties
  setProperty("FitStatus",fitStatus);
  setProperty("FitIntercept",*c0);
  setProperty("FitSlope",*c1);
  setProperty("Cov00",*cov00);
  setProperty("Cov11",*cov11);
  setProperty("Cov01",*cov01);
  setProperty("Chi2",*chisq);
  
  // Create and fill a workspace2D with the same bins as the fitted spectrum and the value of the fit for the centre of each bin
  const size_t YSize = Y.size();
  MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create(inputWorkspace,1,X.size(),YSize);
  
  // Copy over the X bins
  outputWorkspace->dataX(0).assign(X.begin(),X.end());
  // Now loop over the spectrum and use gsl function to calculate the Y & E values for the function
  for (size_t i = 0; i < YSize; ++i)
  {
    const double x = ( isHistogram ? 0.5*(X[i]+X[i+1]) : X[i] );
    const int err = gsl_fit_linear_est(x,*c0,*c1,*cov00,*cov01,*cov11,&(outputWorkspace->dataY(0)[i]),&(outputWorkspace->dataE(0)[i]));
    if (err) g_log.warning() << "Problem in filling the output workspace: " << gsl_strerror(err) << std::endl;
  }
  setProperty("OutputWorkspace",outputWorkspace);
  progress(1);
  // Clean up
  delete c0;
  delete c1;
  delete cov00;
  delete cov01;
  delete cov11;
  delete chisq;
}
예제 #6
0
int kstfit_linear_unweighted(const double *const inArrays[], const int inArrayLens[],
                             const double inScalars[],
                             double *outArrays[], int outArrayLens[],
                             double outScalars[])
{
    int i = 0;
    int	iLength;
    int iReturn = -1;
    double* pResult[4];
    double c0 = 0.0;
    double c1 = 0.0;
    double cov00 = 0.0;
    double cov01 = 0.0;
    double cov11 = 0.0;
    double dSumSq = 0.0;
    double y;
    double yErr;

    if (inArrayLens[Y] >= 2 && inArrayLens[X] >= 2) {
        iLength = inArrayLens[Y];
        if( inArrayLens[X] < iLength ) {
            iLength = inArrayLens[X];
        }

        for( i=0; i<4; i++ ) {
            if( outArrayLens[0] != iLength ) {
                pResult[i] = (double*)realloc( outArrays[i], iLength * sizeof( double ) );
            } else {
                pResult[i] = outArrays[i];
            }
        }

        if( pResult[0] != NULL &&
                pResult[1] != NULL &&
                pResult[2] != NULL &&
                pResult[3] != NULL )
        {
            for( i=0; i<4; i++ ) {
                outArrays[i] 		= pResult[i];
                outArrayLens[i] = iLength;
            }

            if( !gsl_fit_linear( inArrays[X], 1, inArrays[Y], 1, iLength, &c0, &c1, &cov00, &cov01, &cov11, &dSumSq ) ) {

                for( i=0; i<iLength; i++ ) {
                    gsl_fit_linear_est( inArrays[X][i], c0, c1, cov00, cov01, cov11, &y, &yErr );
                    outArrays[0][i] = y;
                    outArrays[1][i] = y - yErr;
                    outArrays[2][i] = y + yErr;
                    outArrays[3][i] = inArrays[Y][i] - y;
                }

                outScalars[0] = c0;
                outScalars[1] = c1;
                outScalars[2] = cov00;
                outScalars[3] = cov01;
                outScalars[4] = cov11;
                outScalars[5] = dSumSq;

                iReturn = 0;
            }
        }
    }

    return iReturn;
}