This is an automated email from the git hooks/post-receive script. ppm-guest pushed a commit to annotated tag v0.25 in repository libmath-prime-util-perl.
commit 49b8d462c71d4164ede320b8b73ad0c9306c259a Author: Dana Jacobsen <d...@acm.org> Date: Mon Mar 11 17:14:03 2013 -0700 Speed up p-1 stage 2 --- Changes | 5 +++++ XS.xs | 2 +- factor.c | 33 +++++++++++++++++++-------------- factor.h | 5 ++++- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/Changes b/Changes index 84b92de..71c04c9 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,10 @@ Revision history for Perl extension Math::Prime::Util. +0.25 xx March 2013 + + - Speed up p-1 stage 2 factoring. This makes factor() about 20% faster + for 19 digit semiprimes. + 0.24 10 March 2013 - Fix compilation with old pre-C99 strict compilers (decl after statement). diff --git a/XS.xs b/XS.xs index af95cde..5f2f42d 100644 --- a/XS.xs +++ b/XS.xs @@ -280,7 +280,7 @@ rsqufof_factor(IN UV n, IN UV maxrounds = 4*1024*1024) void pbrent_factor(IN UV n, IN UV maxrounds = 4*1024*1024) PPCODE: - SIMPLE_FACTOR(pbrent_factor, n, maxrounds); + SIMPLE_FACTOR(pbrent_factor_a1, n, maxrounds); void prho_factor(IN UV n, IN UV maxrounds = 4*1024*1024) diff --git a/factor.c b/factor.c index 0909779..75e496b 100644 --- a/factor.c +++ b/factor.c @@ -46,27 +46,27 @@ int factor(UV n, UV *factors) while ( (n >= (tlim*tlim)) && (!_XS_is_prime(n)) ) { int split_success = 0; /* Adjust the number of rounds based on the number size */ - UV br_rounds = ((n>>29) < 100000) ? 1500 : 1500; - UV sq_rounds = 80000; /* 20k 91%, 40k 98%, 80k 99.9%, 120k 99.99% */ + UV const br_rounds = ((n>>29) < 100000) ? 1500 : 1500; + UV const sq_rounds = 80000; /* 20k 91%, 40k 98%, 80k 99.9%, 120k 99.99% */ /* About 94% of random inputs are factored with this pbrent call */ if (!split_success) { - split_success = pbrent_factor(n, tofac_stack+ntofac, br_rounds)-1; + split_success = pbrent_factor(n, tofac_stack+ntofac, br_rounds, 3)-1; if (verbose) { if (split_success) printf("pbrent 1: %"UVuf" %"UVuf"\n", tofac_stack[ntofac], tofac_stack[ntofac+1]); else printf("pbrent 0\n"); } } /* SQUFOF with these parameters gets 95% of what's left. */ if (!split_success && n < (UV_MAX>>3)) { split_success = racing_squfof_factor(n,tofac_stack+ntofac, sq_rounds)-1; - if (verbose) printf("squfof %d\n", split_success); + if (verbose) printf("rsqufof %d\n", split_success); } /* Perhaps prho using different parameters will find it */ if (!split_success) { - split_success = prho_factor(n, tofac_stack+ntofac, 800)-1; - if (verbose) printf("prho %d\n", split_success); + split_success = pbrent_factor(n, tofac_stack+ntofac, 800, 5)-1; + if (verbose) printf("pbrent5 %d\n", split_success); } /* This p-1 gets about 2/3 of what makes it through the above */ if (!split_success) { - split_success = pminus1_factor(n, tofac_stack+ntofac, 4000, 40000)-1; + split_success = pminus1_factor(n, tofac_stack+ntofac, 4000, 80000)-1; if (verbose) printf("pminus1 %d\n", split_success); } /* Some rounds of HOLF, good for close to perfect squares */ @@ -76,7 +76,7 @@ int factor(UV n, UV *factors) } /* Less than 0.1% of random inputs make it here */ if (!split_success) { - split_success = prho_factor(n, tofac_stack+ntofac, 256*1024)-1; + split_success = pbrent_factor(n, tofac_stack+ntofac, 256*1024, 7)-1; if (verbose) printf("long prho %d\n", split_success); } @@ -515,12 +515,11 @@ int holf_factor(UV n, UV *factors, UV rounds) /* Pollard / Brent. Brent's modifications to Pollard's Rho. Maybe faster. */ -int pbrent_factor(UV n, UV *factors, UV rounds) +int pbrent_factor(UV n, UV *factors, UV rounds, UV a) { UV f, i, r; UV Xi = 2; UV Xm = 2; - UV a = 1; const UV inner = 64; MPUassert( (n >= 3) && ((n%2) != 0) , "bad n in pbrent_factor"); @@ -682,7 +681,8 @@ int pminus1_factor(UV n, UV *factors, UV B1, UV B2) } /* STAGE 2 */ - if (f == 1 && B2 > B1) { + if (f == 1 && B2 > B1 && q >= 5) { + const unsigned char* sieve; UV bm = a; UV b = 1; UV bmdiff; @@ -699,10 +699,14 @@ int pminus1_factor(UV n, UV *factors, UV B1, UV B2) a = powmod(a, q, n); j = 1; - while (q <= B2) { + if (get_prime_cache(B2, &sieve) < B2) { + release_prime_cache(sieve); + croak("Could not generate sieve for %"UVuf, B2); + } + START_DO_FOR_EACH_SIEVE_PRIME( sieve, q+1, B2 ) { UV lastq = q; UV qdiff; - q = _XS_next_prime(q); + q = p; /* compute a^q = a^lastq * a^(q-lastq) */ qdiff = (q - lastq) / 2 - 1; if (qdiff >= 111) { @@ -725,7 +729,8 @@ int pminus1_factor(UV n, UV *factors, UV B1, UV B2) if (f != 1) break; } - } + } END_DO_FOR_EACH_SIEVE_PRIME + release_prime_cache(sieve); f = gcd_ui(b, n); } if ( (f != 1) && (f != n) ) { diff --git a/factor.h b/factor.h index a13b52e..cff4851 100644 --- a/factor.h +++ b/factor.h @@ -16,7 +16,10 @@ extern int holf_factor(UV n, UV *factors, UV rounds); extern int squfof_factor(UV n, UV *factors, UV rounds); extern int racing_squfof_factor(UV n, UV *factors, UV rounds); -extern int pbrent_factor(UV n, UV *factors, UV maxrounds); + +extern int pbrent_factor(UV n, UV *factors, UV maxrounds, UV a); +static int pbrent_factor_a1(UV n, UV *factors, UV maxrounds) + { return pbrent_factor(n, factors, maxrounds, 1); } extern int prho_factor(UV n, UV *factors, UV maxrounds); -- 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