gauss_logarithm_approx.sf 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. #!/usr/bin/ruby
  2. # Approximation for the natural logarithm of a given
  3. # number, using a formula due to Carl Friedrich Gauss.
  4. # The formula is:
  5. # log(x) ≈ π / (2 * M(1, 2^(2-P) / x)) - P * log(2)
  6. # See also:
  7. # https://en.wikipedia.org/wiki/Logarithm#Arithmetic.E2.80.93geometric_mean_approximation
  8. define π = Num.pi
  9. define log2 = log(2)
  10. func M(a, g, p) { # p < 0
  11. loop {
  12. var a1 = ((a+g)/2)
  13. var g1 = sqrt(a*g)
  14. if (approx_eq(a, a1, p) && approx_eq(g, g1, p)) {
  15. return a
  16. }
  17. (a, g) = (a1, g1)
  18. }
  19. }
  20. func gauss_log(x, p) {
  21. π / 2*M(1, 2**(2-p) / x, -p) - p*log2
  22. }
  23. say gauss_log( 2, 100) # 0.69314718055994530941723212145817656807550013436026
  24. say gauss_log( -2, 100) # 0.69314718055994363166115731719424653785695888288578-3.14159265358979323846264338327950288419716939937511i
  25. say gauss_log( -2.34, 100) # 0.85015092936960838246915232323588813675500496603394-3.14159265358979323846264338327950288419716939937511i
  26. say gauss_log( 3 + 4i, 100) # 1.60943791243409869684468452896225760930706010279404+0.92729521800161223242851246292242880405707410857224i
  27. say gauss_log(-42 - 23i, 100) # 3.86880814142895054249561036425701508230238930773225-2.64057926678620379072688927950864468829687609303423i