コード例 #1
0
int
gsl_sf_lambert_Wm1_e(double x, gsl_sf_result * result)
{
  if(x > 0.0) {
    return gsl_sf_lambert_W0_e(x, result);
  }
  else if(x == 0.0) {
    result->val = 0.0;
    result->err = 0.0;
    return GSL_SUCCESS;
  }
  else {
    static const unsigned int MAX_ITERS = 32;
    const double one_over_E = 1.0/M_E;
    const double q = x + one_over_E;
    double w;

    if (q < 0.0) {
      /* As in the W0 branch above, return some reasonable answer anyway. */
      result->val = -1.0; 
      result->err =  sqrt(-q);
      return GSL_EDOM;
    }

    if(x < -1.0e-6) {
      /* Obtain initial approximation from series about q = 0,
       * as long as we're not very close to x = 0.
       * Use full series and try to bail out if q is too small,
       * since the Halley iteration has bad convergence properties
       * in finite arithmetic for q very small, because the
       * increment alternates and p is near zero.
       */
      const double r = -sqrt(q);
      w = series_eval(r);
      if(q < 3.0e-3) {
        /* this approximation is good enough */
        result->val = w;
        result->err = 5.0 * GSL_DBL_EPSILON * fabs(w);
        return GSL_SUCCESS;
      }
    }
    else {
      /* Obtain initial approximation from asymptotic near zero. */
      const double L_1 = log(-x);
      const double L_2 = log(-L_1);
      w = L_1 - L_2 + L_2/L_1;
    }

    return halley_iteration(x, w, MAX_ITERS, result);
  }
}
コード例 #2
0
double gsl_sf_lambert_W0(double x)
{
  EVAL_RESULT(gsl_sf_lambert_W0_e(x, &result));
}
コード例 #3
0
ファイル: flim.cpp プロジェクト: doobwa/Rflim
  double optimizeLambda(unsigned int x, unsigned int y) {
#ifdef NEW_WAY
    double A = getComputedExpectation(x, y) * exp(-lambda_(x, y));
    double B = 2 * beta2_;
    double C = empirical_pair_(x, y) - beta1_;
#else
    double A = getComputedExpectation(x, y);
    double B = 2 * beta2_;
    double C = empirical_pair_(x, y) - beta1_ - 2 * beta2_ * lambda_(x, y);
#endif

// #define DEBUGGING_NOISE
#ifdef  DEBUGGING_NOISE
    if (empirical_pair_(x, y) > 0 && rand() < RAND_MAX / 1000) {
      double overcount_x = lambda_(x,y) * singleton_expectation_[y];
      double overcount_y = lambda_(x,y) * singleton_expectation_[x];
    
      double p10 = q_lambda_[x] + kappa_[x] - overcount_x;
      double p01 = q_lambda_[y] + kappa_[y] - overcount_y;

      double p11 = estimates_(x,y) - overcount_x - overcount_y;

      std::cout << getComputedExpectation(x, y) << " "
                << empirical_pair_(x, y) << " " 
                << kappa_[x] << " " 
                << kappa_[y] << " "
                << lambda_(x,y) << " " 
                << x << " " << y << " "
                << q_lambda_[x] << " "
                << q_lambda_[y] << " "
                << estimates_(x,y) << " "
                << overcount_x << " " << overcount_y << " "
                << p10 << " " << p01 << " " << p11 << " "
                << std::endl;
    }
#endif

    double delta1 = 0;
    double delta2 = 0;
    if (beta2_ == 0) {
      delta1 = log(C / A);
    } else {
      gsl_sf_result result;
      gsl_sf_lambert_W0_e(A / B * exp(C / B), &result);
      delta1 = C/B - result.val;
    }

    C += 2 * beta1_;
    if (beta2_ == 0) {
      delta2 = log(C / A);
    } else {
      gsl_sf_result result;
      gsl_sf_lambert_W0_e(A / B * exp(C / B), &result);
      delta2 = C/B - result.val;
    }

    double new_lambda = lambda_(x,y);
    if (new_lambda + delta1 >= 0) {
      new_lambda += delta1;
    } else if (new_lambda + delta2 <= 0) {
      new_lambda += delta2;
    } else {
      new_lambda = 0;
    }

    double delta = fabs(new_lambda - lambda_(x,y));
    if (delta - delta != 0) {
      delta = 0.0;
    }

    lambda_(x,y) = new_lambda;
    lambda_(y,x) = new_lambda;
    return delta;
  }
コード例 #4
0
ファイル: Lambert.c プロジェクト: codahale/ruby-gsl
static VALUE Lambert_W0_e(VALUE self, VALUE x) {
  int ret;
  gsl_sf_result r;
  ret = gsl_sf_lambert_W0_e(NUM2DBL(x), &r);
  return RESULT(&r);
}