ymath.cpp 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #include "ymath.h"
  2. double Exp2(double x) {
  3. return pow(2.0, x);
  4. }
  5. float Exp2f(float x) {
  6. return powf(2.0f, x);
  7. }
  8. #ifdef _MSC_VER
  9. double Erf(double x) {
  10. static constexpr double _M_2_SQRTPI = 1.12837916709551257390;
  11. static constexpr double eps = 1.0e-7;
  12. if (fabs(x) >= 3.75)
  13. return x > 0 ? 1.0 : -1.0;
  14. double r = _M_2_SQRTPI * x;
  15. double f = r;
  16. for (int i = 1;; ++i) {
  17. r *= -x * x / i;
  18. f += r / (2 * i + 1);
  19. if (fabs(r) < eps * (2 * i + 1))
  20. break;
  21. }
  22. return f;
  23. }
  24. #endif // _MSC_VER
  25. double LogGammaImpl(double x) {
  26. static constexpr double lnSqrt2Pi = 0.91893853320467274178; // log(sqrt(2.0 * PI))
  27. static constexpr double coeff9 = 1.0 / 1188.0;
  28. static constexpr double coeff7 = -1.0 / 1680.0;
  29. static constexpr double coeff5 = 1.0 / 1260.0;
  30. static constexpr double coeff3 = -1.0 / 360.0;
  31. static constexpr double coeff1 = 1.0 / 12.0;
  32. if ((x == 1.0) || (x == 2.0)) {
  33. return 0.0; // 0! = 1
  34. }
  35. double bonus = 0.0;
  36. while (x < 3.0) {
  37. bonus -= log(x);
  38. x += 1.0;
  39. }
  40. double lnX = log(x);
  41. double sqrXInv = 1.0 / (x * x);
  42. double res = coeff9 * sqrXInv + coeff7;
  43. res = res * sqrXInv + coeff5;
  44. res = res * sqrXInv + coeff3;
  45. res = res * sqrXInv + coeff1;
  46. res /= x;
  47. res += x * lnX - x + lnSqrt2Pi - 0.5 * lnX;
  48. return res + bonus;
  49. }