Exemplo n.º 1
0
   void BackToBackExponential::function1D(double* out, const double* xValues, const size_t nData)const
   {
     /*
       const double& I = getParameter("I");
       const double& a = getParameter("A");
       const double& b = getParameter("B");
       const double& x0 = getParameter("X0");
       const double& s = getParameter("S");
     */
 
     const double I = getParameter(0);
     const double a = getParameter(1);
     const double b = getParameter(2);
     const double x0 = getParameter(3);
     const double s = getParameter(4);
 
     // find the reasonable extent of the peak ~100 fwhm
     double extent = expWidth();
     if ( s > extent ) extent = s;
     extent *= 100;
 
     double s2 = s*s;
     double normFactor = a * b / (a + b) / 2;
     //Needed for IntegratePeaksMD for cylinder profile fitted with b=0
     if (normFactor == 0.0) normFactor = 1.0;
     for (size_t i = 0; i < nData; i++) {
       double diff=xValues[i]-x0;
       if ( fabs(diff) < extent )
        {
         double val = 0.0;
         double arg1 = a/2*(a*s2+2*diff);
         val += exp(  arg1 + gsl_sf_log_erfc((a*s2+diff)/sqrt(2*s2)) ); //prevent overflow
         double arg2 = b/2*(b*s2-2*diff);
         val += exp( arg2 + gsl_sf_log_erfc((b*s2-diff)/sqrt(2*s2)) ); //prevent overflow
         out[i] = I*val*normFactor;
        }
       else
         out[i] = 0.0;
      }
    }
Exemplo n.º 2
0
void IkedaCarpenterPV::functionLocal(double *out, const double *xValues,
                                     const size_t nData) const {
  const double I = getParameter("I");
  const double alpha0 = getParameter("Alpha0");
  const double alpha1 = getParameter("Alpha1");
  const double beta0 = getParameter("Beta0");
  const double kappa = getParameter("Kappa");
  const double voigtsigmaSquared = getParameter("SigmaSquared");
  const double voigtgamma = getParameter("Gamma");
  const double X0 = getParameter("X0");

  // cal pseudo voigt sigmaSq and gamma and eta
  double gamma = 1.0; // dummy initialization
  double eta = 0.5;   // dummy initialization
  convertVoigtToPseudo(voigtsigmaSquared, voigtgamma, gamma, eta);
  double sigmaSquared = gamma * gamma / (8.0 * M_LN2); // pseudo voigt sigma^2

  const double beta = 1 / beta0;

  // equations taken from Fullprof manual

  const double k = 0.05;

  // Not entirely sure what to do if sigmaSquared ever negative
  // for now just post a warning
  double someConst = std::numeric_limits<double>::max() / 100.0;
  if (sigmaSquared > 0)
    someConst = 1 / sqrt(2.0 * sigmaSquared);
  else if (sigmaSquared < 0) {
    g_log.warning() << "sigmaSquared negative in functionLocal.\n";
  }

  // update wavelength vector
  calWavelengthAtEachDataPoint(xValues, nData);

  for (size_t i = 0; i < nData; i++) {
    double diff = xValues[i] - X0;

    double R = exp(-81.799 / (m_waveLength[i] * m_waveLength[i] * kappa));
    double alpha = 1.0 / (alpha0 + m_waveLength[i] * alpha1);

    double a_minus = alpha * (1 - k);
    double a_plus = alpha * (1 + k);
    double x = a_minus - beta;
    double y = alpha - beta;
    double z = a_plus - beta;

    double Nu = 1 - R * a_minus / x;
    double Nv = 1 - R * a_plus / z;
    double Ns = -2 * (1 - R * alpha / y);
    double Nr = 2 * R * alpha * alpha * beta * k * k / (x * y * z);

    double u = a_minus * (a_minus * sigmaSquared - 2 * diff) / 2.0;
    double v = a_plus * (a_plus * sigmaSquared - 2 * diff) / 2.0;
    double s = alpha * (alpha * sigmaSquared - 2 * diff) / 2.0;
    double r = beta * (beta * sigmaSquared - 2 * diff) / 2.0;

    double yu = (a_minus * sigmaSquared - diff) * someConst;
    double yv = (a_plus * sigmaSquared - diff) * someConst;
    double ys = (alpha * sigmaSquared - diff) * someConst;
    double yr = (beta * sigmaSquared - diff) * someConst;

    std::complex<double> zs =
        std::complex<double>(-alpha * diff, 0.5 * alpha * gamma);
    std::complex<double> zu = (1 - k) * zs;
    std::complex<double> zv = (1 - k) * zs;
    std::complex<double> zr =
        std::complex<double>(-beta * diff, 0.5 * beta * gamma);

    double N = 0.25 * alpha * (1 - k * k) / (k * k);

    out[i] = I * N * ((1 - eta) * (Nu * exp(u + gsl_sf_log_erfc(yu)) +
                                   Nv * exp(v + gsl_sf_log_erfc(yv)) +
                                   Ns * exp(s + gsl_sf_log_erfc(ys)) +
                                   Nr * exp(r + gsl_sf_log_erfc(yr))) -
                      eta * 2.0 / M_PI * (Nu * exponentialIntegral(zu).imag() +
                                          Nv * exponentialIntegral(zv).imag() +
                                          Ns * exponentialIntegral(zs).imag() +
                                          Nr * exponentialIntegral(zr).imag()));
  }
}
Exemplo n.º 3
0
static VALUE Error_log_erfc(VALUE self, VALUE x) {
  return rb_float_new(gsl_sf_log_erfc(NUM2DBL(x)));
}