floor_and_ceil_functions_fourier_series.pl 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 19 November 2017
  4. # https://github.com/trizen
  5. # Floor and ceil functions, implemented using closed-form Fourier series.
  6. # See also:
  7. # https://en.wikipedia.org/wiki/Floor_and_ceiling_functions#Continuity_and_series_expansions
  8. use 5.020;
  9. use warnings;
  10. use experimental qw(signatures);
  11. use Math::AnyNum qw(:overload tau pi e log2 ilog2);
  12. sub floor ($x) {
  13. $x + (i * (log(1 - exp(tau * i * $x)) - log(exp(-tau * i * $x) * (-1 + exp(tau * i * $x))))) / tau - 1/2;
  14. }
  15. sub ceil ($x) {
  16. $x + (i * (log(1 - exp(tau * i * $x)) - log(exp(-tau * i * $x) * (-1 + exp(tau * i * $x))))) / tau + 1/2;
  17. }
  18. say floor(8.95); #=> 8
  19. say ceil(8.95); #=> 9
  20. say floor(18.3); #=> 18
  21. say ceil(18.3); #=> 19
  22. #
  23. ## Test with Vacca's formula for Euler-Mascheroni constant
  24. #
  25. # See also:
  26. # https://en.wikipedia.org/wiki/Euler%E2%80%93Mascheroni_constant#Series_expansions
  27. my $sum0 = 0.0;
  28. my $sum1 = 0.0;
  29. my $sum2 = 0.0;
  30. my $sum3 = 0.0;
  31. foreach my $n (2 .. 10000) {
  32. $sum0 += (-1)**$n * ilog2($n) / $n;
  33. $sum1 += (-1)**$n * floor(log2($n + 1/2)) / $n;
  34. $sum2 += (-1)**$n * (tau * log($n + 1/2) - log(2) * (i*log(1 - (2*$n+1)**(-(tau*i) / (log(2)))) - i*log(1 - (2*$n+1)**((tau*i) / (log(2)))) + pi)) / (pi * log(4) * $n);
  35. $sum3 += (-1)**$n * (tau * log($n) - log(2) * (i*log(1 - $n**(-(tau*i) / (log(2)))) - i*log(1 - $n**((tau*i) / (log(2)))) + pi)) / (pi * log(4) * $n);
  36. }
  37. say $sum0; #=> 0.577804596003519592136242513827950669265457764297
  38. say $sum1; #=> 0.577804596003519592136242513827950669265457764297-2.10816560532506695800025812910971220454909391515e-60i
  39. say $sum2; #=> 0.577804596003519592136242513827950669265457764297
  40. say $sum3; #=> 0.577804596003520848567920428074451834158559906352