primes-utils 2.6.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +112 -82
- data/lib/primes/utils/version.rb +1 -1
- data/lib/primes/utils.rb +424 -377
- data/{primes-utils.gemspec → primes-utils-3.0.0.gemspec} +6 -10
- metadata +29 -15
- data/.gitignore +0 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 94c48fe22428ca617d418fe9209ed6984376f164698020b992d06896804dcc77
|
|
4
|
+
data.tar.gz: 2e4192d3531f0a0ba9c38a1daf173d747d39793b23190ff53fa9ad04445032bd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ee404d5d9945d2ba429cbc7586fdfdf3548bf4b3c09fc5930bc6416472d59761bb0aedff48d7adb1420894b270322c35183e63c495436e6186bd249ee355fd55
|
|
7
|
+
data.tar.gz: d86a64bf62aef1011a62ea1d22a68184f43ee64a5ec8bf7fe68a9d3f32aaa53ef498ce2cbbc94557a1c6bc2b868e7f970ae361abd650fdaefd5294aaf1dda218
|
data/README.md
CHANGED
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## Introduction
|
|
4
4
|
|
|
5
|
-
`primes-utils` is a Rubygem
|
|
5
|
+
`primes-utils` is a Rubygem providing a suite of extremely fast methods for testing and generating primes.
|
|
6
6
|
|
|
7
7
|
For details on the Math and Code used to implement them see:
|
|
8
8
|
|
|
9
9
|
`PRIMES-UTILS HANDBOOK`
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Available for `FREE` to read|download at:
|
|
12
|
+
|
|
13
|
+
https://www.academia.edu/19786419/PRIMES_UTILS_HANDBOOK
|
|
12
14
|
|
|
13
15
|
https://www.scribd.com/doc/266461408/Primes-Utils-Handbook
|
|
14
16
|
|
|
@@ -37,64 +39,62 @@ Then require as:
|
|
|
37
39
|
|
|
38
40
|
**prime?**
|
|
39
41
|
|
|
40
|
-
Determine if
|
|
42
|
+
Determine if an integer value is prime. Return 'true' or 'false'.
|
|
41
43
|
This replaces the `prime?` method in the `prime.rb` standard library.
|
|
44
|
+
Uses PGT residues tests, then Miller-Rabin test using `primemr?`.
|
|
42
45
|
|
|
43
46
|
```
|
|
44
47
|
101.prime? => true
|
|
45
48
|
100.prime? => false
|
|
46
|
-
-71.prime? =>
|
|
49
|
+
-71.prime? => false
|
|
47
50
|
0.prime? => false
|
|
48
51
|
1.prime? => false
|
|
49
52
|
```
|
|
50
53
|
|
|
51
|
-
**primemr?(k=
|
|
54
|
+
**primemr?(k=5)**
|
|
52
55
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
The reliability can be increased by increasing the default input parameter of k=20.
|
|
56
|
+
Optimized deterministic (over 64-bits) implementation of Miller-Rabin algorithm.
|
|
57
|
+
Default non-deterministic reliability set at k = 5, set higher if desired for very large numbers > 64-bts.
|
|
56
58
|
|
|
57
59
|
```
|
|
58
|
-
|
|
59
|
-
1111111111111111111.primemr? 50 => true
|
|
60
|
-
1111111111111111111.primemr?(50) => true
|
|
61
|
-
11111111111111111111.primemr? => false
|
|
62
|
-
-3333333333333333333.primemr? => false
|
|
63
|
-
n=10**1700; (n+469).primemr? => true
|
|
64
|
-
0.primemr? => false
|
|
65
|
-
1.primemr? => false
|
|
60
|
+
n.prime?(6)
|
|
66
61
|
```
|
|
67
62
|
|
|
68
|
-
**factors
|
|
63
|
+
**factors or prime_division**
|
|
69
64
|
|
|
70
|
-
Determine the prime factorization of
|
|
65
|
+
Determine the prime factorization of an +|- integer value.
|
|
66
|
+
Uses Unix coreutils function `factors` if available.
|
|
71
67
|
This replaces the `prime_division` method in the `prime.rb` standard library.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
Can change SP PG used on input. Acceptable primes range: [3 - 19].
|
|
68
|
+
Multiplying the factors back will produce original number.
|
|
69
|
+
Output is array of tuples of factors and exponents elements: [[p1, e1], [p2, e2],..,[pn, en]].
|
|
75
70
|
|
|
76
71
|
```
|
|
77
72
|
1111111111111111111.prime_division => [[1111111111111111111, 1]]
|
|
78
|
-
11111111111111111111.prime_division
|
|
73
|
+
11111111111111111111.prime_division => [[11, 1], [41, 1], [101, 1], [271, 1], [3541, 1], [9091, 1], [27961, 1]]
|
|
79
74
|
123456789.factors => [[3, 2], [3607, 1], [3803, 1]]
|
|
80
|
-
|
|
81
|
-
123456789.factors(17) => [[3, 2], [3607, 1], [3803, 1]]
|
|
82
|
-
-12345678.factors => [[2, 1], [3, 2], [47, 1], [14593, 1]]
|
|
75
|
+
-12345678.factors => [[-1, 1], [2, 1], [3, 2], [47, 1], [14593, 1]]
|
|
83
76
|
0.factors => []
|
|
84
77
|
1.factors => []
|
|
85
78
|
```
|
|
86
79
|
|
|
87
|
-
**
|
|
80
|
+
**factors1**
|
|
81
|
+
|
|
82
|
+
Pure Ruby version equivalent of `factor`.
|
|
83
|
+
Not as fast as `factor` for some values with multiple large prime factors.
|
|
84
|
+
Always available if OS doesn't have `factor`
|
|
85
|
+
|
|
86
|
+
**primes(start=0), primesmr(start=0)**
|
|
88
87
|
|
|
89
|
-
Return an array of
|
|
90
|
-
|
|
91
|
-
|
|
88
|
+
Return an array of prime values within the inclusive integers range `[start_num - end_num]`.
|
|
89
|
+
Input order doesn't matter if both given: `start_num.primes end_num <=> end_num.prime start_num`.
|
|
90
|
+
A single input is taken as `end_num`, and the primes <= to it are returned.
|
|
91
|
+
`primes` is generally faster, and uses SSoZ to compute the range primes.
|
|
92
|
+
`primesmr` is slower, but isn't memory limited, especially for very large numbers|ranges.
|
|
92
93
|
See `PRIMES-UTILS HANDBOOK` for details on best use practices.
|
|
93
94
|
Also see `Error Handling`.
|
|
94
95
|
|
|
95
96
|
```
|
|
96
97
|
50.primes => [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
|
|
97
|
-
50.primesf 125 => [53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113]
|
|
98
98
|
300.primes 250 => [251, 257, 263, 269, 271, 277, 281, 283, 293]
|
|
99
99
|
n=10**100; (n-250).primesmr(n+250) => []
|
|
100
100
|
541.primes.size => 100
|
|
@@ -102,19 +102,18 @@ n=10**100; (n-250).primesmr(n+250) => []
|
|
|
102
102
|
(prms = 1000000.primes(1000100)).size => 6
|
|
103
103
|
prms.size => 6
|
|
104
104
|
prms => [1000003, 1000033, 1000037, 1000039, 1000081, 1000099]
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
n=10**8; (25*n).primes -> ERROR3: not enough memory to store all primes in output array. => nil
|
|
109
|
-
0.primesf => []
|
|
110
|
-
1.primesmr => []
|
|
105
|
+
101.primes 101 => [101]
|
|
106
|
+
1.primes => []
|
|
107
|
+
0.primesmr => []
|
|
111
108
|
```
|
|
112
109
|
|
|
113
|
-
**primescnt(start=0),
|
|
110
|
+
**primescnt(start=0), primescntmr(start=0)**
|
|
114
111
|
|
|
115
|
-
Provide count of primes within the
|
|
116
|
-
|
|
117
|
-
|
|
112
|
+
Provide count of primes within the inclusive integers range `[start_num - end_num]`.
|
|
113
|
+
Input order doesn't matter if both given: `start_num.primes end_num <=> end_num.prime start_num`.
|
|
114
|
+
A single input is taken as `end_num`, and the primes count <= to it are returned.
|
|
115
|
+
`primescnt` is faster; uses SSoZ to identify|count primes from closest hashed value starting point.
|
|
116
|
+
`primescntmr` is slower, but isn't memory limited, especially for very large numbers|ranges.
|
|
118
117
|
See `PRIMES-UTILS HANDBOOK` for details on best use practices.
|
|
119
118
|
Also see `Error Handling`.
|
|
120
119
|
|
|
@@ -122,77 +121,101 @@ Also see `Error Handling`.
|
|
|
122
121
|
100001.primescnt => 9592
|
|
123
122
|
100002.primescnt => 9592
|
|
124
123
|
100003.primescnt => 9593
|
|
125
|
-
100000.
|
|
124
|
+
100000.primescntmr 100500 => 40
|
|
126
125
|
n=10**400; (n-500).primescntmr(n+500) => 1
|
|
127
|
-
-10.primescnt -50 => 11
|
|
128
|
-
n=10**20; n.primescnt n+n -> ERROR1: range size too big for available memory. => nil
|
|
129
|
-
n=10**20; n.primescnt 100 -> ERROR2: end_num too big for available memory. => nil
|
|
130
126
|
n=10**8; (25*n).primescnt => 121443371
|
|
131
|
-
0.
|
|
127
|
+
0.primescnt => 0
|
|
132
128
|
1.primescntmr => 0
|
|
129
|
+
|
|
133
130
|
```
|
|
134
131
|
|
|
135
|
-
**primenth(p=
|
|
132
|
+
**primenth(p=0) or nthprime(p=0)**
|
|
136
133
|
|
|
137
|
-
Return
|
|
134
|
+
Return value of the nth prime.
|
|
138
135
|
Default Strictly Prime (SP) Prime Generator (PG) is adaptively selected.
|
|
139
|
-
Can change SP PG used on input. Acceptable primes range: [
|
|
140
|
-
Indexed nth primes now upto
|
|
136
|
+
Can change SP PG used on input. Acceptable primes range: [5, 7].
|
|
137
|
+
Indexed nth primes now upto 7 billionth.
|
|
138
|
+
With 16GB mem can compute upto at least 35.7+ billionth prime (using `bitarray`).
|
|
139
|
+
Returns `nil` for negative nth inputs.
|
|
141
140
|
Also see `Error Handling`.
|
|
142
141
|
|
|
143
142
|
```
|
|
144
143
|
1000000.primenth => 15485863
|
|
145
144
|
1500000.nthprime => 23879519
|
|
146
145
|
2000000.nthprime 11 => 32452843
|
|
147
|
-
-500000.nthprime => 7368787
|
|
148
146
|
1122951705.nthprime => 25741879847
|
|
149
|
-
n = 10**11; n.primenth ->
|
|
150
|
-
|
|
151
|
-
|
|
147
|
+
n = 10**11; n.primenth -> #<NoMemoryError: failed to allocate memory>
|
|
148
|
+
2_123_409_000.nthprime => 50092535639
|
|
149
|
+
4_762_719_305.nthprime => 116378528093
|
|
150
|
+
0.nthprime => 0
|
|
151
|
+
1.primenth => 2
|
|
152
|
+
-1.nthprime => nil
|
|
153
|
+
```
|
|
154
|
+
**next_prime**
|
|
155
|
+
|
|
156
|
+
Return value of next prime > n. Returns `nil` for negative inputs.
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
100.next_prime => 101
|
|
160
|
+
101.next_prime => 103
|
|
161
|
+
0.next_prime => 2
|
|
162
|
+
-1.next_prime => nil
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**prev_prime**
|
|
166
|
+
|
|
167
|
+
Return value of previous prime < n > 2. Returns `nil` for n < 2 (and negatives)
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
102.pref_prime => 101
|
|
171
|
+
101.prev_prime => 97
|
|
172
|
+
3.prev_prime => 2
|
|
173
|
+
2.prev_prime => nil
|
|
174
|
+
-1.prev_prime => nil
|
|
152
175
|
```
|
|
153
176
|
|
|
154
177
|
**primes_utils**
|
|
155
178
|
|
|
156
|
-
Displays a list of all the `primes-utils` methods available for
|
|
157
|
-
Use as `
|
|
179
|
+
Displays a list of all the `primes-utils` methods available for a system.
|
|
180
|
+
Use as eg: `0.primes_utils` where input n is any `class Integer` value.
|
|
181
|
+
|
|
182
|
+
Available methods for 3.0.0.
|
|
158
183
|
|
|
159
184
|
```
|
|
160
|
-
0.primes_utils => "prime?
|
|
185
|
+
0.primes_utils => "prime? primes primesmr primescnt primescntmr primenth|nthprime factors|prime_division factors1 next_prime prev_prime primes_utils"
|
|
161
186
|
```
|
|
162
187
|
|
|
163
188
|
## Error Handling
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
`nthprime|primenth` also displays the error message `<pcnt> not enough primes, approx nth too small.`
|
|
169
|
-
(`<pcnt>` is computed count of primes) when the computed approx_nth value is < nth value (though this should never happen by design).
|
|
170
|
-
With 2.4.0 error handling was added to `primes` that catches the error and displays message `ERROR3: not enough memory to store all primes in output array.`.
|
|
171
|
-
For all errors, the return value for each method is `nil`.
|
|
189
|
+
With 3.0.0 the Rubygem `bitarray` is used to extend useable memory for `primes`, `primescnt`, and `nthprime`.
|
|
190
|
+
They use private method `sozcores2` to compute the SoZ over the ranges, and returns an array of prime residues positions.
|
|
191
|
+
If an input range exceeds system memory to create the array, it switches to using a `bitarray`.
|
|
192
|
+
This greatly extends the computable range sizes, at the expense of being slower than using system memory.
|
|
172
193
|
|
|
173
194
|
There is also the rare possibility you could get a `NoMemoryError: failed to allocate memory` for the methods
|
|
174
|
-
`
|
|
195
|
+
`primes|primesmr` if their list of numerated primes is bigger than the amount of available system memory needed to store them.
|
|
175
196
|
If those methods are used as designed these errors won't occur, so the extra code isn't justified for them.
|
|
176
197
|
If they occur you will know why now.
|
|
177
198
|
|
|
178
199
|
This behavior is referenced to MRI Ruby.
|
|
179
200
|
|
|
180
201
|
## Coding Implementations
|
|
181
|
-
The
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
The methods `primesf` and `primescntf` use the `factor` version of `prime?` and are created if it exits.
|
|
185
|
-
`factor` [5] is an extremely fast C coded factoring algorithm, part of the GNU Core Utilities package [4].
|
|
202
|
+
The method `prime_division|factors` has 2 implementations. A pure ruby implementation, and a hybrid implementation
|
|
203
|
+
using the Unix cli command `factor` [5], if available on the host OS. It's an extremely fast C coded factoring algorithm,
|
|
204
|
+
part of the GNU Core Utilities package [4].
|
|
186
205
|
|
|
187
206
|
Upon loading, the gem tests if the command `factor` exists on the host OS.
|
|
188
|
-
If so, it performs a system call to it within `
|
|
207
|
+
If so, it performs a system call to it within `prime_division|factors`, and Ruby reformats its output.
|
|
189
208
|
If not, each method uses a fast pure ruby implementation based on the Sieve of Zakiya (SoZ)[1][2][3].
|
|
190
|
-
New in 2.2.0, upon loading with Ruby 1.8 `require 'rubygems'` is invoked to enable installing gems.
|
|
191
209
|
|
|
192
|
-
|
|
210
|
+
In 3.0.0, YJIT is enabled on install; and the methods coding is optimized for Ruby >= 3.3.
|
|
211
|
+
|
|
212
|
+
All the `primes-utils` methods are `instance_methods` for `Class Integer`.
|
|
193
213
|
|
|
194
214
|
## History
|
|
195
215
|
```
|
|
216
|
+
3.0.0 – YJIT enabled for Ruby >= 3.3, added new methods: next_prime, prev_prime.
|
|
217
|
+
Uses 'bitarray' to extend memory use for methods 'nthprime', 'primes', and 'primescnt'.
|
|
218
|
+
2.7.0 – more tweaking adaptive pg selection ranges in select_pg; coded using between? instead of cover?
|
|
196
219
|
2.6.0 – much, much better adaptive pg selection algorithm used in select_pg
|
|
197
220
|
2.5.1 – corrected minor error in select_pg
|
|
198
221
|
2.5.0 – 9 more index primes under the 110-millionth in nths; fixed Ruby 1.8 incompatibility in primes;
|
|
@@ -201,9 +224,9 @@ All the `primes-utils` methods are `instance_methods` for `class Integer`.
|
|
|
201
224
|
2.4.0 – fixed error in algorithm when ks resgroup ≤ sqrt(end_num) resgroup; algorithm now split
|
|
202
225
|
arrays when start_num > sqrt(end_num) in sozcore2, whose code also signficantly optimized,
|
|
203
226
|
with API change adding pcs2start value to output parameters to use in primenth, which changed
|
|
204
|
-
to use it; ruby idiom code opt for set_start_value; consolidated pcs_to_num | pcs_to_start_num
|
|
227
|
+
to use it; ruby idiom code opt for set_start_value; consolidated pcs_to_num | pcs_to_start_num
|
|
205
228
|
functions into one new pcs_to_num, with associated changes in sozcore1|2; primes|cnt also
|
|
206
|
-
significantly faster resulting from sozcore2 changes; massive code cleanups all-arround; added
|
|
229
|
+
significantly faster resulting from sozcore2 changes; massive code cleanups all-arround; added
|
|
207
230
|
private methods select_pg (to adaptively select the pg used in primes), and array_check (used in
|
|
208
231
|
sozcore2 to catch array creation out-of-memory errors)
|
|
209
232
|
2.3.0 – primescnt now finds primes upto some integer much faster, and for much larger integers
|
|
@@ -231,12 +254,19 @@ All the `primes-utils` methods are `instance_methods` for `class Integer`.
|
|
|
231
254
|
Jabari Zakiya
|
|
232
255
|
|
|
233
256
|
## References
|
|
234
|
-
[1]https://www.scribd.com/doc/150217723/Improved-Primality-Testing-and-Factorization-in-Ruby-revised
|
|
235
|
-
|
|
236
|
-
[
|
|
237
|
-
|
|
238
|
-
[
|
|
239
|
-
|
|
257
|
+
[1] https://www.scribd.com/doc/150217723/Improved-Primality-Testing-and-Factorization-in-Ruby-revised
|
|
258
|
+
|
|
259
|
+
[2] https://www.scribd.com/doc/228155369/The-Segmented-Sieve-of-Zakiya-SSoZ
|
|
260
|
+
|
|
261
|
+
[3] https://www.scribd.com/doc/73385696/The-Sieve-of-Zakiya
|
|
262
|
+
|
|
263
|
+
[4] https://en.wikipedia.org/wiki/GNU_Core_Utilities
|
|
264
|
+
|
|
265
|
+
[5] https://en.wikipedia.org/wiki/Factor_(Unix)
|
|
266
|
+
|
|
267
|
+
[6] https://en.wikipedia.org/wiki/Miller-Rabin_primality_test
|
|
268
|
+
|
|
269
|
+
[7] https://www.academia.edu/105821370/Twin_Primes_Segmented_Sieve_of_Zakiya_SSoZ_Explained_Review_Article
|
|
240
270
|
|
|
241
271
|
## License
|
|
242
|
-
|
|
272
|
+
LGPL-2.0-or-later
|
data/lib/primes/utils/version.rb
CHANGED