June 2018 Update

This commit is contained in:
Ingy döt Net 2018-06-22 20:57:24 +00:00
parent ba8067c3b7
commit 22f33d4004
5278 changed files with 84726 additions and 14379 deletions

View file

@ -3,5 +3,5 @@ Lucas-Lehmer Test: for <math>p</math> an odd prime, the Mersenne number <math>2^
;Task:
Calculate all Mersenne primes up to the implementation's
maximum precision, or the 47th Mersenne prime &nbsp; (whichever comes first).
maximum precision, or the 47<sup>th</sup> Mersenne prime &nbsp; (whichever comes first).
<br><br>

View file

@ -0,0 +1,8 @@
: lucas-lehmer
1+ 2 do
4 i 2 <> * abs swap 1+ dup + 1- swap
i 1- 1 ?do dup * 2 - over mod loop 0= if ." M" i . then
loop cr
;
1 15 lucas-lehmer

View file

@ -0,0 +1,16 @@
using Primes
function getmersenneprimes(n)
t1 = time()
count = 0
i = 2
while(n > count)
if(isprime(i) && ismersenneprime(2^BigInt(i) - 1))
println("M$i, cumulative time elapsed: $(time() - t1) seconds")
count += 1
end
i += 1
end
end
getmersenneprimes(50)

View file

@ -0,0 +1,33 @@
# vectorized approach based on scalar code from primeSieve and mersenne in CRAN package `numbers`
require(gmp)
n <- 4423 # note that the sieve below assumes n > 9
# sieve the set of primes up to n
p <- seq(1, n, by = 2)
q <- length(p)
p[1] <- 2
for (k in seq(3, sqrt(n), by = 2))
if (p[(k + 1)/2] != 0)
p[seq((k * k + 1)/2, q, by = k)] <- 0
p <- p[p > 0]
cat(p[1]," special case M2 == 3\n")
p <- p[-1]
z2 <- gmp::as.bigz(2)
z4 <- z2 * z2
zp <- gmp::as.bigz(p)
zmp <- z2^zp - 1
S <- rep(z4, length(p))
for (i in 1:(p[length(p)] - 2)){
S <- gmp::mod.bigz(S * S - z2, zmp)
if( i+2 == p[1] ){
if( S[1] == 0 ){
cat( p[1], "\n")
flush.console()
}
p <- p[-1]
zmp <- zmp[-1]
S <- S[-1]
}
}

View file

@ -1,58 +1,54 @@
/*REXX program uses the Lucas─Lehmer primality test for prime powers of two.*/
trace i
parse arg limit . /*get optional arguments from the C.L. */
if limit=='' then limit=1000 /*No argument? Then assume the default*/
list= /*placeholder for the results. */
/* [↓] only process up to the LIMIT, */
do j=1 by 2 to limit /*there're only so many hours in a day.*/
power=j + (j==1) /*POWER ≡ J except for when J=1. */
if \isPrime(power) then iterate /*if POWER isn't prime, then ignore it.*/
$=Lucas_Lehmer2(power) /*did it pass the Lucas─Lehmer2 test? */
if $\=='' then list=list $ /*Did the # pass? Then add to the list.*/
end /*j*/
list=space(list) /*elide all extraneous blanks from list*/
say; say center('list',60-3,"") /*show a fancy─dancy header (title). */
say
do k=1 for words(list) /*show entries in list, one per line. */
say right(word(list,k),30) /*right─justify 'em to look pretty&nice*/
end /*k*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────ISPRIME subroutine────────────────────────*/
isPrime: procedure; parse arg x /*get number to be tested.*/
if x<17 then return wordpos(x,'2 3 5 7 11 13')\==0 /*test for special cases. */
if x//2==0 then return 0 /*is it even? Then not prime.*/
if x//3==0 then return 0 /*divisible by three? " " " */
if right(x,1)==5 then return 0 /*right-most dig ≡ 5? " " " */
if x//7==0 then return 0 /*divisible by seven? " " " */
do j=11 by 6 until j*j>x /*ensures that J isn't divisible by 3. */
if x// j ==0 then return 0 /*is it divisible by J ? */
if x//(j+2)==0 then return 0 /* " " " " J+2 ? ___ */
end /*j*/ /* [↑] perform loop through √ x */
return 1 /*indicate the number X is prime. */
/*──────────────────────────────────LUCAS_LEHMER2 subroutine──────────────────*/
Lucas_Lehmer2: procedure; parse arg ? /*Lucas─Lehmer test on 2**? - 1 */
numeric form /*ensure the correct REXX number form. */
if ?==2 then s=0 /*handle special case for an even prime*/
else s=4
q=2**? /*╔═══════════════════════════════════════════════════════════════╗
Compute a power of two, using only 9 decimal digits. DIGITs
of 1 million could be used, but that really gums up the whole
works. So, we start with the default of 9 digits, find the
ten's exponent in the product (2**?), double it, and then add
6. 2 is all that's needed, but 6 is a lot safer.
The doubling is for the squaring of S (below, for s*s).
*/
if pos('E',q)\==0 then do /*the number in exponential notation? */
parse var q 'E' tenpow
numeric digits tenpow*2 + 6
end
else numeric digits digits()*2 + 6 /* 9*2 + 6 */
q=2**?-1
do ?-2 /*apply, rinse, repeat ··· */
s=(s*s-2) // q /*remainder in REXX is: // */
end /* [↑] compute the real McCoy. */
if s\==0 then return '' /*return nuttin' if number isn't prime.*/
return 'M'? /*return a "modified" (prime) number. */
/*REXX pgm uses the Lucas─Lehmer primality test for prime powers of 2 (Mersenne primes)*/
@.=0; @.2=1; @.3=1; @.5=1; @.7=1; @.11=1; @.13=1 /*a partial list of some low primes. */
!.=@.; !.0=1; !.2=1; !.4=1; !.5=1; !.6=1; !.8=1 /*#'s with these last digs aren't prime*/
parse arg limit . /*obtain optional arguments from the CL*/
if limit=='' then limit= 200 /*Not specified? Then use the default.*/
say center('Mersenne prime index list',70-3,"") /*show a fancy─dancy header (or title).*/
say right('M'2, 25) " [1 decimal digit]" /*left─justify them to align&look nice.*/
/* [►] note that J==1 is a special case*/
do j=1 by 2 to limit /*there're only so many hours in a day.*/
power=j + (j==1) /*POWER ≡ J except for when J=1. */
if \isPrime(power) then iterate /*if POWER isn't prime, then ignore it.*/
$=LL2(power) /*perform the Lucas─Lehmer 2 (LL2) test*/
if $=='' then iterate /*Did it flunk LL2? Then skip this #.*/
say right($, 25) MPsize /*left─justify them to align&look nice.*/
end /*j*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
isPrime: procedure expose !. @.; parse arg x '' -1 z /*get # to be tested & last digit*/
if @.x then return 1 /*is X already found to be prime? */
if !.z then return 0 /*is last decimal digit even or a five?*/
if x//3==0 then return 0 /*divisible by three? " " " */
if x//7==0 then return 0 /*divisible by seven? " " " */
do j=11 by 6 until j*j > x /*ensures that J isn't divisible by 3. */
if x// j ==0 then return 0 /*is it divisible by J ? */
if x// (j+2)==0 then return 0 /* " " " " J+2 ? ___ */
end /*j*/ /* [↑] perform loop through √ x */
@.j=1; return 1 /*indicate number X and J are prime.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
LL2: procedure expose MPsize; parse arg ? /*Lucas─Lehmer test on 2**? - 1 */
if ?==2 then s=0 /*handle special case for an even prime*/
else s=4
numeric form; q= 2**? /*ensure correct form for REXX numbers.*/
/*╔══════════════════════════════════════════════════════════════════════════════════╗
Compute a power of two, using only 9 decimal digits. DIGITs of 1 million could
be used, but that really slows up computations. So, we start with the default
of 9 digits, and then find the ten's exponent in the product (2**?), double
it, and then add six. {Two is all that's needed, but six is a lot safer.}
The doubling is for the squaring of S (below, for s*s).
*/
if pos('E', q)\==0 then do /*is number in exponential notation ? */
parse var q 'E' tenPow /*get the exponent.*/
numeric digits tenPow * 2 + 6 /*expand precision.*/
end /*REXX used dec FP.*/
else numeric digits digits() * 2 + 6 /*use 9*2 + 6 digs.*/
q=2**? - 1; r=q//8 /*obtain Q modulus eight. */
if r==1 | r==7 then nop; else return '' /*before crunching, do a simple test. */
do ?-2; s= (s*s -2) // q /*lather, rinse, repeat ··· */
end /* [↑] compute and test for a MP. */
if s\==0 then return '' /*Not a Mersenne prime? Return a null.*/
sz=length(q) /*obtain number of decimal digs in MP. */
MPsize=' ['sz "decimal digit"s(sz)']' /*define a literal to display after MP.*/
return 'M'? /*return "modified" # (Mersenne index).*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
s: if arg(1)==1 then return arg(3); return word(arg(2) 's', 1) /*simple pluralizer*/

View file

@ -0,0 +1,53 @@
extern crate rug;
extern crate primal;
use rug::Integer;
use rug::ops::Pow;
use std::thread::spawn;
fn is_mersenne (p : usize) {
let p = p as u32;
let mut m = Integer::from(1);
m = m << p;
m = Integer::from(&m - 1);
let mut flag1 = false;
for k in 1..10_000 {
let mut flag2 = false;
let mut div : u32 = 2*k*p + 1;
if &div >= &m {break; }
for j in [3,5,7,11,13,17,19,23,29,31,37].iter() {
if div % j == 0 {
flag2 = true;
break;
}
}
if flag2 == true {continue;}
if div % 8 != 1 && div % 8 != 7 { continue; }
if m.is_divisible_u(div) {
flag1 = true;
break;
}
}
if flag1 == true {return ()}
let mut s = Integer::from(4);
let two = Integer::from(2);
for _i in 2..p {
let mut sqr = s.pow(2);
s = Integer::from(&Integer::from(&sqr & &m) + &Integer::from(&sqr >> p));
if &s >= &m {s = s - &m}
s = Integer::from(&s - &two);
}
if s == 0 {println!("Mersenne : {}",p);}
}
fn main () {
println!("Mersenne : 2");
let limit = 11_214;
let mut thread_handles = vec![];
for p in primal::Primes::all().take_while(|p| *p < limit) {
thread_handles.push(spawn(move || is_mersenne(p)));
}
for handle in thread_handles {
handle.join().unwrap();
}
}