Skip to content

Commit 28ac60d

Browse files
committed
Refactor to use a 2-3-5-7 wheel factorization
1 parent 79dc35f commit 28ac60d

File tree

3 files changed

+101
-70
lines changed

3 files changed

+101
-70
lines changed

lib/node_modules/@stdlib/math/base/assert/is-prime/lib/main.js

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
var sqrt = require( '@stdlib/math/base/special/sqrt' );
2424
var floor = require( '@stdlib/math/base/special/floor' );
2525
var FLOAT64_MAX_SAFE_INTEGER = require( '@stdlib/constants/math/float64-max-safe-integer' );
26+
var WHEEL_PRIMES = require( './wheel_primes.json' );
2627

2728

2829
// MAIN //
@@ -69,18 +70,66 @@ function isPrime( x ) {
6970
if ( x%5 === 0 ) {
7071
return false;
7172
}
72-
// Use trial division (with wheel factorization; see https://en.wikipedia.org/wiki/Wheel_factorization) to detect composite numbers, leveraging the fact that all primes greater than `30` are of the form `30k±1`...
73+
// Check whether the number is evenly divisible by `7`...
74+
if ( x%7 === 0 ) {
75+
return false;
76+
}
77+
// Check whether the number is a prime number in the wheel...
78+
if ( WHEEL_PRIMES[ x ] ) {
79+
return true;
80+
}
81+
// Use trial division (with wheel factorization; see https://en.wikipedia.org/wiki/Wheel_factorization) to detect composite numbers, leveraging the fact that all primes greater than `210` are of the form `210k±1`...
7382
N = floor( sqrt( x ) );
74-
for ( i = 7; i <= N; i += 30 ) {
83+
for ( i = 11; i <= N; i += 210 ) {
7584
if (
76-
x%i === 0 ||
77-
x%(i+4) === 0 ||
78-
x%(i+6) === 0 ||
79-
x%(i+10) === 0 ||
80-
x%(i+12) === 0 ||
81-
x%(i+16) === 0 ||
82-
x%(i+22) === 0 ||
83-
x%(i+24) === 0
85+
x%i === 0 || // 11
86+
x%(i+2) === 0 || // 13
87+
x%(i+6) === 0 || // 17
88+
x%(i+8) === 0 || // 19
89+
x%(i+12) === 0 || // 23
90+
x%(i+18) === 0 || // 29
91+
x%(i+20) === 0 || // 31
92+
x%(i+26) === 0 || // 37
93+
x%(i+30) === 0 || // 41
94+
x%(i+32) === 0 || // 43
95+
x%(i+36) === 0 || // 47
96+
x%(i+42) === 0 || // 53
97+
x%(i+48) === 0 || // 59
98+
x%(i+50) === 0 || // 61
99+
x%(i+56) === 0 || // 67
100+
x%(i+60) === 0 || // 71
101+
x%(i+62) === 0 || // 73
102+
x%(i+68) === 0 || // 79
103+
x%(i+72) === 0 || // 83
104+
x%(i+78) === 0 || // 89
105+
x%(i+86) === 0 || // 97
106+
x%(i+90) === 0 || // 101
107+
x%(i+92) === 0 || // 103
108+
x%(i+96) === 0 || // 107
109+
x%(i+98) === 0 || // 109
110+
x%(i+102) === 0 || // 113
111+
x%(i+110) === 0 || // 121 (relatively prime)
112+
x%(i+116) === 0 || // 127
113+
x%(i+120) === 0 || // 131
114+
x%(i+126) === 0 || // 137
115+
x%(i+128) === 0 || // 139
116+
x%(i+132) === 0 || // 143 (relatively prime)
117+
x%(i+138) === 0 || // 149
118+
x%(i+140) === 0 || // 151
119+
x%(i+146) === 0 || // 157
120+
x%(i+152) === 0 || // 163
121+
x%(i+156) === 0 || // 167
122+
x%(i+158) === 0 || // 169 (relatively prime)
123+
x%(i+162) === 0 || // 173
124+
x%(i+168) === 0 || // 179
125+
x%(i+170) === 0 || // 181
126+
x%(i+176) === 0 || // 187 (relatively prime)
127+
x%(i+180) === 0 || // 191
128+
x%(i+182) === 0 || // 193
129+
x%(i+186) === 0 || // 197
130+
x%(i+188) === 0 || // 199
131+
x%(i+198) === 0 || // 209 (relatively prime)
132+
x%(i+200) === 0 // 211
84133
) {
85134
return false;
86135
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"11": true,"13": true,"17": true,"19": true,"23": true,"29": true,"31": true,"37": true,"41": true,"43": true,"47": true,"53": true,"59": true,"61": true,"67": true,"71": true,"73": true,"79": true,"83": true,"89": true,"97": true,"101": true,"103": true,"107": true,"109": true,"113": true,"127": true,"131": true,"137": true,"139": true,"149": true,"151": true,"157": true,"163": true,"167": true,"173": true,"179": true,"181": true,"191": true,"193": true,"197": true,"199": true,"211": true}

lib/node_modules/@stdlib/math/base/assert/is-prime/test/test.js

Lines changed: 41 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -40,81 +40,62 @@ tape( 'main export is a function', function test( t ) {
4040

4141
tape( 'the function returns `true` if provided a prime number', function test( t ) {
4242
var N;
43+
var M;
4344
var v;
4445
var i;
4546
var j;
4647

47-
t.equal( isPrime( 2 ), true, 'returns expected value' );
48-
t.equal( isPrime( 3 ), true, 'returns expected value' );
49-
t.equal( isPrime( 5 ), true, 'returns expected value' );
50-
t.equal( isPrime( 7 ), true, 'returns expected value' );
51-
t.equal( isPrime( 11 ), true, 'returns expected value' );
52-
t.equal( isPrime( 13 ), true, 'returns expected value' );
53-
t.equal( isPrime( 17 ), true, 'returns expected value' );
54-
t.equal( isPrime( 19 ), true, 'returns expected value' );
55-
t.equal( isPrime( 23 ), true, 'returns expected value' );
56-
t.equal( isPrime( 29 ), true, 'returns expected value' );
57-
t.equal( isPrime( 31 ), true, 'returns expected value' );
58-
48+
// Test the first `M` prime numbers...
49+
M = 2e4;
50+
for ( i = 0; i < M; i++ ) {
51+
v = PRIMES[ i ];
52+
t.equal( isPrime( v ), true, 'returns true when provided '+v );
53+
}
54+
// Randomly test prime numbers chosen from the remainder of the list of known prime numbers...
5955
N = PRIMES.length - 1;
6056
for ( i = 0; i < 1e3; i++ ) {
61-
j = discreteUniform( 0, N );
57+
j = discreteUniform( M, N );
6258
v = PRIMES[ j ];
6359
t.equal( isPrime( v ), true, 'returns true when provided '+v );
6460
}
6561
t.end();
6662
});
6763

6864
tape( 'the function returns `false` if provided a composite number', function test( t ) {
69-
var values;
70-
var v;
65+
var hash;
66+
var MAX;
67+
var M;
68+
var N;
7169
var i;
70+
var j;
7271

73-
values = [
74-
4,
75-
6,
76-
8,
77-
9,
78-
10,
79-
12,
80-
14,
81-
15,
82-
16,
83-
18,
84-
20,
85-
21,
86-
22,
87-
24,
88-
25,
89-
26,
90-
27,
91-
28,
92-
30,
93-
32,
94-
33,
95-
34,
96-
35,
97-
36,
98-
38,
99-
39,
100-
40,
101-
42,
102-
44,
103-
45,
104-
46,
105-
48,
106-
49,
107-
50,
108-
51,
109-
52,
110-
54,
111-
100,
112-
3333
113-
];
114-
115-
for ( i = 0; i < values.length; i++ ) {
116-
v = values[ i ];
117-
t.equal( isPrime( v ), false, 'returns false when provided '+v );
72+
N = PRIMES.length;
73+
hash = {};
74+
for ( i = 0; i < N; i++ ) {
75+
hash[ PRIMES[i] ] = true;
76+
}
77+
// Only test odd integers, as even integers are trivially composite...
78+
M = 2e5;
79+
for ( i = 3; i < M; i += 2 ) {
80+
if ( hash[ i ] ) {
81+
continue;
82+
}
83+
t.equal( isPrime( i ), false, 'returns false when provided '+i );
84+
}
85+
// Generate random composite integers...
86+
MAX = PRIMES[ N-1 ];
87+
for ( i = 0; i < 1e3; i++ ) {
88+
// Generate an odd integer...
89+
j = discreteUniform( trunc( M/2 ), trunc( MAX/2 ) );
90+
j = (2*j) + 1;
91+
92+
// Check if the generated integer is a known prime number...
93+
if ( hash[ j ] ) {
94+
// Repeat iteration...
95+
i -= 1;
96+
continue;
97+
}
98+
t.equal( isPrime( j ), false, 'returns false when provided '+j );
11899
}
119100
t.end();
120101
});

0 commit comments

Comments
 (0)