This is an automated email from the git hooks/post-receive script.

ppm-guest pushed a commit to annotated tag v0.36
in repository libmath-prime-util-perl.

commit dff2ed6f0703bacc1cde1fae503d0f23033568b1
Author: Dana Jacobsen <d...@acm.org>
Date:   Mon Jan 13 18:33:26 2014 -0800

    LogarithmicIntegral using bignum and no-MPFR returns (1) better results, 
(2) rounded to a sane number of digits
---
 lib/Math/Prime/Util/PP.pm | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/lib/Math/Prime/Util/PP.pm b/lib/Math/Prime/Util/PP.pm
index e9a7d59..ad8db7d 100644
--- a/lib/Math/Prime/Util/PP.pm
+++ b/lib/Math/Prime/Util/PP.pm
@@ -516,7 +516,7 @@ sub jordan_totient {
   $totient = _bigint_to_int($totient) if $totient->bacmp(''.~0) <= 0;
   return $totient;
 }
-  
+
 sub euler_phi {
   my($n) = @_;
   return 0 if $n < 0;
@@ -2639,15 +2639,27 @@ sub LogarithmicIntegral {
   }
 
   $x = Math::BigFloat->new("$x") if defined $bignum::VERSION && ref($x) ne 
'Math::BigFloat';
-  my $logx = log($x);
 
   # Do divergent series here for big inputs.  Common for big pc approximations.
   # Why is this here?
   #   1) exp(log(x)) results in a lot of lost precision
   #   2) exp(x) with lots of precision turns out to be really slow, and in
   #      this case it was unnecessary.
+  my $tol = 1e-16;
+  my $xdigits = 0;
+  my $finalacc = 0;
+  if (ref($x) =~ /^Math::Big/) {
+    $xdigits = $x->accuracy || Math::BigFloat->accuracy() || 
Math::BigFloat->div_scale();
+    my $xlen = length($x->bfloor->bstr());
+    $xdigits = $xlen if $xdigits < $xlen;
+    $finalacc = $xdigits;
+    $xdigits += length(int(log(0.0+"$x"))) + 1;
+    $tol = Math::BigFloat->new(10)->bpow(-$xdigits);
+    $x->accuracy($xdigits);
+  }
+  my $logx = $xdigits ? $x->copy->blog(undef,$xdigits) : log($x);
+
   if ($x > 1e16) {
-    my $tol = 1e-20;
     my $invx = 1.0 / $logx;
     # n = 0  =>  0!/(logx)^0 = 1/1 = 1
     # n = 1  =>  1!/(logx)^1 = 1/logx
@@ -2663,13 +2675,14 @@ sub LogarithmicIntegral {
         $sum -= ($last_term/3);
         last;
       }
+      $term->bround($xdigits) if $xdigits;
     }
     my $val = $x * $invx * $sum;
+    $val->accuracy($finalacc) if $xdigits;
     return $val;
   }
   # Convergent series.
   if ($x >= 1) {
-    my $tol  = 1e-20;
     my $fact_n = 1.0;
     my $nfac = 1.0;
     my $sum  = 0.0;
@@ -2678,9 +2691,11 @@ sub LogarithmicIntegral {
       my $term = $fact_n / $n;
       $sum += $term;
       last if $term < $tol;
+      $term->bround($xdigits) if $xdigits;
     }
     my $eulerconst = (ref($x) eq 'Math::BigFloat') ? 
Math::BigFloat->new(CONST_EULER) : 0.0+CONST_EULER;
     my $val = $eulerconst + log($logx) + $sum;
+    $val->accuracy($finalacc) if $xdigits;
     return $val;
   }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-perl/packages/libmath-prime-util-perl.git

_______________________________________________
Pkg-perl-cvs-commits mailing list
Pkg-perl-cvs-commits@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-perl-cvs-commits

Reply via email to