primes-utils 3.0.4 → 3.0.5
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 +4 -4
- data/README.md +35 -39
- data/lib/primes/utils/version.rb +1 -1
- data/lib/primes/utils.rb +30 -29
- data/primes-utils-3.0.0.gemspec +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4389a00aebe98cc43fc901200e8eebdf0ad704f17ce590aafa47b2fe6eadb4e1
|
|
4
|
+
data.tar.gz: af97630fb433b113734d2d04d68c7f24490373a0aec2e57f411383dccfab53e9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 92a9e70b078633b8570ad87057ec006ed3b45c9d9884f01cac28718a24dbf4479fd1429ea9b6d0074f4e8c543fdcf4b1ea912b244bccfe707e78ad1101cc35b7
|
|
7
|
+
data.tar.gz: 2f1d16062ce8618e22a9c1c1f3b790a3817199400e775d7ad0b0071ace4cfdb96bbd1d4047847316f34398b117f01187f54f48614a5edcaef55cc88cf891fcac
|
data/README.md
CHANGED
|
@@ -12,9 +12,6 @@ Available for `FREE` to read|download at:
|
|
|
12
12
|
|
|
13
13
|
https://www.academia.edu/19786419/PRIMES_UTILS_HANDBOOK
|
|
14
14
|
|
|
15
|
-
https://www.scribd.com/doc/266461408/Primes-Utils-Handbook
|
|
16
|
-
|
|
17
|
-
|
|
18
15
|
## Installation
|
|
19
16
|
|
|
20
17
|
Add this line to your application's Gemfile:
|
|
@@ -39,8 +36,8 @@ Then require as:
|
|
|
39
36
|
|
|
40
37
|
**prime?**
|
|
41
38
|
|
|
42
|
-
Determine if an integer value is prime
|
|
43
|
-
This replaces the `prime?` method in the `prime.rb` standard library.
|
|
39
|
+
Determine if an integer value is prime, and return `true` or `false`.
|
|
40
|
+
This replaces the `prime?` method in the `prime.rb` standard library.
|
|
44
41
|
Uses PGT residues tests, then Miller-Rabin test using `primemr?`.
|
|
45
42
|
|
|
46
43
|
```
|
|
@@ -53,7 +50,7 @@ Uses PGT residues tests, then Miller-Rabin test using `primemr?`.
|
|
|
53
50
|
|
|
54
51
|
**primemr?(k=5)**
|
|
55
52
|
|
|
56
|
-
Optimized deterministic (over 64-bits) implementation of Miller-Rabin algorithm.
|
|
53
|
+
Optimized deterministic (over 64-bits) implementation of Miller-Rabin algorithm.
|
|
57
54
|
Default non-deterministic reliability set at k = 5, set higher if desired for very large numbers > 64-bts.
|
|
58
55
|
|
|
59
56
|
```
|
|
@@ -62,10 +59,10 @@ n.prime?(6)
|
|
|
62
59
|
|
|
63
60
|
**factors or prime_division**
|
|
64
61
|
|
|
65
|
-
Determine the prime factorization of an +|- integer value.
|
|
66
|
-
Uses Unix coreutils function `
|
|
67
|
-
This replaces the `prime_division` method in the `prime.rb` standard library.
|
|
68
|
-
Multiplying the factors back will produce original number.
|
|
62
|
+
Determine the prime factorization of an +|- integer value.
|
|
63
|
+
Uses Unix coreutils function `factor` if available.
|
|
64
|
+
This replaces the `prime_division` method in the `prime.rb` standard library.
|
|
65
|
+
Multiplying the factors back will produce original number.
|
|
69
66
|
Output is array of tuples of factors and exponents elements: [[p1, e1], [p2, e2],..,[pn, en]].
|
|
70
67
|
|
|
71
68
|
```
|
|
@@ -79,28 +76,27 @@ Output is array of tuples of factors and exponents elements: [[p1, e1], [p2, e2]
|
|
|
79
76
|
|
|
80
77
|
**factors1**
|
|
81
78
|
|
|
82
|
-
Pure Ruby version equivalent of `
|
|
83
|
-
Not as fast as `
|
|
84
|
-
Always available if OS doesn't have `factor
|
|
79
|
+
Pure Ruby version equivalent of `factors`.
|
|
80
|
+
Not as fast as `factors` for some values with multiple large prime factors.
|
|
81
|
+
Always available if OS doesn't have coreutils `factor`.
|
|
85
82
|
|
|
86
83
|
**primes(start=0), primesmr(start=0)**
|
|
87
84
|
|
|
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
|
|
92
|
-
`primesmr` is slower, but isn't memory limited, especially for very large numbers|ranges.
|
|
93
|
-
See `PRIMES-UTILS HANDBOOK` for details on best use practices.
|
|
85
|
+
Return an array of prime values within the inclusive integers range `[start_num - end_num]`.
|
|
86
|
+
Input order doesn't matter if both given: `start_num.primes end_num <=> end_num.prime start_num`.
|
|
87
|
+
A single input is taken as `end_num`, and the primes <= to it are returned.
|
|
88
|
+
`primes` is generally faster, and uses SoZ to compute the range primes.
|
|
89
|
+
`primesmr` is slower, but isn't memory limited, especially for very large numbers|ranges.
|
|
90
|
+
See `PRIMES-UTILS HANDBOOK` for details on best use practices.
|
|
94
91
|
Also see `Error Handling`.
|
|
95
92
|
|
|
96
93
|
```
|
|
97
94
|
50.primes => [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
|
|
98
|
-
300.
|
|
95
|
+
300.primesmr 250 => [251, 257, 263, 269, 271, 277, 281, 283, 293]
|
|
99
96
|
n=10**100; (n-250).primesmr(n+250) => []
|
|
100
97
|
541.primes.size => 100
|
|
101
98
|
1000.primes(5000).size => 501
|
|
102
99
|
(prms = 1000000.primes(1000100)).size => 6
|
|
103
|
-
prms.size => 6
|
|
104
100
|
prms => [1000003, 1000033, 1000037, 1000039, 1000081, 1000099]
|
|
105
101
|
101.primes 101 => [101]
|
|
106
102
|
1.primes => []
|
|
@@ -109,11 +105,11 @@ prms => [1000003, 1000033, 1000037, 1000039, 1000081, 1000099]
|
|
|
109
105
|
|
|
110
106
|
**primescnt(start=0), primescntmr(start=0)**
|
|
111
107
|
|
|
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
|
|
116
|
-
`primescntmr` is slower, but isn't memory limited, especially for very large numbers|ranges.
|
|
108
|
+
Provide count of primes within the inclusive integers range `[start_num - end_num]`.
|
|
109
|
+
Input order doesn't matter if both given: `start_num.primes end_num <=> end_num.prime start_num`.
|
|
110
|
+
A single input is taken as `end_num`, and the primes count <= to it are returned.
|
|
111
|
+
`primescnt` is faster; uses SoZ to identify|count primes from closest hashed value starting point.
|
|
112
|
+
`primescntmr` is slower, but isn't memory limited, especially for very large numbers|ranges.
|
|
117
113
|
See `PRIMES-UTILS HANDBOOK` for details on best use practices.
|
|
118
114
|
Also see `Error Handling`.
|
|
119
115
|
|
|
@@ -130,24 +126,24 @@ n=10**8; (25*n).primescnt => 121443371
|
|
|
130
126
|
|
|
131
127
|
**primenth(p=0) or nthprime(p=0)**
|
|
132
128
|
|
|
133
|
-
Return value of the nth prime.
|
|
134
|
-
Default Strictly Prime (SP) Prime Generator (PG) is adaptively selected.
|
|
135
|
-
Can change SP PG used on input.
|
|
136
|
-
Indexed nth primes now
|
|
137
|
-
With 16GB mem can compute
|
|
138
|
-
Returns `nil` for negative nth inputs.
|
|
139
|
-
Also see `Error Handling`.
|
|
129
|
+
Return value of the nth prime.
|
|
130
|
+
Default Strictly Prime (SP) Prime Generator (PG) is adaptively selected.
|
|
131
|
+
Can change SP PG used on input. Default is 7. (Usable are 5, 7, 11, but normally just use default.)
|
|
132
|
+
Indexed nth primes now up to 7 billionth.
|
|
133
|
+
With 16GB mem can compute up to about 30.7+ billionth prime (using `bitarray`).
|
|
134
|
+
Returns `nil` for negative nth inputs. Also see `Error Handling`.
|
|
140
135
|
|
|
141
136
|
```
|
|
142
137
|
1000000.primenth => 15485863
|
|
143
138
|
1500000.nthprime => 23879519
|
|
144
|
-
2000000.nthprime
|
|
139
|
+
2000000.nthprime(7) => 32452843
|
|
145
140
|
1122951705.nthprime => 25741879847
|
|
146
141
|
n = 10**11; n.primenth -> #<NoMemoryError: failed to allocate memory>
|
|
147
142
|
2_123_409_000.nthprime => 50092535639
|
|
148
143
|
4_762_719_305.nthprime => 116378528093
|
|
149
|
-
|
|
144
|
+
7_123_456_789.nthprime => 177058934933
|
|
150
145
|
1.primenth => 2
|
|
146
|
+
0.nthprime => nil
|
|
151
147
|
-1.nthprime => nil
|
|
152
148
|
```
|
|
153
149
|
**next_prime**
|
|
@@ -175,7 +171,7 @@ Return value of previous prime < n > 2. Returns `nil` for n < 2 (and negatives)
|
|
|
175
171
|
|
|
176
172
|
**primes_utils**
|
|
177
173
|
|
|
178
|
-
Displays a list of all the `primes-utils` methods available for a system.
|
|
174
|
+
Displays a list of all the `primes-utils` methods available for a system.
|
|
179
175
|
Use as eg: `0.primes_utils` where input n is any `class Integer` value.
|
|
180
176
|
|
|
181
177
|
Available methods for 3.0.0.
|
|
@@ -187,7 +183,7 @@ Available methods for 3.0.0.
|
|
|
187
183
|
## Error Handling
|
|
188
184
|
With 3.0.0 the Rubygem `bitarray` is used to extend useable memory for `primes`, `primescnt`, and `nthprime`.
|
|
189
185
|
They use private method `sozcores2` to compute the SoZ over the ranges, and returns an array of prime residues positions.
|
|
190
|
-
If an input range exceeds system memory to create the array, it switches to using a `bitarray`.
|
|
186
|
+
If an input range exceeds system memory to create the array, it switches to using a `bitarray`.
|
|
191
187
|
This greatly extends the computable range sizes, at the expense of being slower than using system memory.
|
|
192
188
|
|
|
193
189
|
There is also the rare possibility you could get a `NoMemoryError: failed to allocate memory` for the methods
|
|
@@ -212,7 +208,7 @@ All the `primes-utils` methods are `instance_methods` for `Class Integer`.
|
|
|
212
208
|
|
|
213
209
|
## History
|
|
214
210
|
```
|
|
215
|
-
3.0.
|
|
211
|
+
3.0.5 – YJIT enabled for Ruby >= 3.3, added new methods: next_prime, prev_prime.
|
|
216
212
|
Uses 'bitarray' to extend memory use for methods 'nthprime', 'primes', and 'primescnt'.
|
|
217
213
|
2.7.0 – more tweaking adaptive pg selection ranges in select_pg; coded using between? instead of cover?
|
|
218
214
|
2.6.0 – much, much better adaptive pg selection algorithm used in select_pg
|
|
@@ -228,7 +224,7 @@ All the `primes-utils` methods are `instance_methods` for `Class Integer`.
|
|
|
228
224
|
significantly faster resulting from sozcore2 changes; massive code cleanups all-arround; added
|
|
229
225
|
private methods select_pg (to adaptively select the pg used in primes), and array_check (used in
|
|
230
226
|
sozcore2 to catch array creation out-of-memory errors)
|
|
231
|
-
2.3.0 – primescnt now finds primes
|
|
227
|
+
2.3.0 – primescnt now finds primes up to some integer much faster, and for much larger integers
|
|
232
228
|
increased index nth primes to over 2 billionth; used in nthprime|primenth and primescnt
|
|
233
229
|
2.2.0 – for sozcore2: refactored to include more common code; changed output api; added memory
|
|
234
230
|
error messages when prms and prms_range arrays creation fails; for primenth: used new
|
data/lib/primes/utils/version.rb
CHANGED
data/lib/primes/utils.rb
CHANGED
|
@@ -64,8 +64,8 @@ module Primes
|
|
|
64
64
|
# Adaptively selects best SP PG, unless valid input PG given at runtime
|
|
65
65
|
def primenth(p = 0)
|
|
66
66
|
return nil if (n = self) < 1
|
|
67
|
-
seeds =
|
|
68
|
-
return
|
|
67
|
+
seeds = PRIMES
|
|
68
|
+
return seeds[n - 1] if n <= seeds.size
|
|
69
69
|
|
|
70
70
|
start_num, nth, nthflag = set_start_value(n, true)
|
|
71
71
|
return start_num if nthflag # output nthprime value if n a ref prime key
|
|
@@ -326,7 +326,7 @@ module Primes
|
|
|
326
326
|
def sozcore2(end_num, start_num, modpg)
|
|
327
327
|
residues = make_residues(modpg); rescnt = residues.size
|
|
328
328
|
maxpcs, pcs2start, rs, modks, pcs_range = pcs_to_nums(end_num, start_num, residues)
|
|
329
|
-
sqrtN = Integer.sqrt(end_num)
|
|
329
|
+
sqrtN, inputs_range = Integer.sqrt(end_num), end_num - start_num
|
|
330
330
|
pcs2sqrtN, _ = pcs_to_nums(sqrtN, 0, residues) # num pcs <= sqrtN
|
|
331
331
|
|
|
332
332
|
m = pcs2start # index to start retrieving primes in prms array
|
|
@@ -346,7 +346,7 @@ module Primes
|
|
|
346
346
|
prm_r = residues[i % rescnt] # save its residue value
|
|
347
347
|
prime = modpg*(k=i/rescnt)+prm_r # numerate its value; set k resgroup value
|
|
348
348
|
rem = start_num % prime # prime's distance to start_num
|
|
349
|
-
next unless (prime - rem <=
|
|
349
|
+
next unless (prime - rem <= inputs_range) || rem == 0 # skip prime mults not in range
|
|
350
350
|
prmstep = prime * rescnt # compute its primestep
|
|
351
351
|
residues.each do |ri| # find|mark its multiples
|
|
352
352
|
# convert (prime * (modk + ri)) pc value to its address in prms
|
|
@@ -368,6 +368,32 @@ module Primes
|
|
|
368
368
|
(n * (log_n + a) + 3).to_i
|
|
369
369
|
end
|
|
370
370
|
|
|
371
|
+
def select_pg(end_num, start_num) # adaptively select PG
|
|
372
|
+
range = end_num - start_num
|
|
373
|
+
pg = 5
|
|
374
|
+
if start_num <= Integer.sqrt(end_num) # for one array of primes upto N
|
|
375
|
+
pg = 7 if end_num > 50 * 10**4
|
|
376
|
+
pg = 11 if end_num > 305 * 10**5
|
|
377
|
+
else # for split array cases
|
|
378
|
+
pg = 7 if (range.between?(10**6, 10**7 - 1) && start_num < 10**8) ||
|
|
379
|
+
(range.between?(10**7, 10**8 - 1) && start_num < 46 * 10**8) ||
|
|
380
|
+
(range.between?(10**8, 10**9 - 1) && start_num < 16 * 10**10) ||
|
|
381
|
+
(range >= 10**9 && start_num < 26 * 10**12)
|
|
382
|
+
pg = 11 if (range.between?(10**8, 10**9 - 1) && start_num < 55 * 10**7) ||
|
|
383
|
+
(range >= 10**9 && start_num < 45 * 10**9)
|
|
384
|
+
end
|
|
385
|
+
primes = [2, 3, 5, 7, 11, 13].select! { |p| p <= pg }
|
|
386
|
+
[primes, primes.reduce(:*)] # [base primes, mod] for PG
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
def array_check(len) # for out-of-memory errors on primes array creation
|
|
390
|
+
begin
|
|
391
|
+
Array.new(len, 0) # use Array when enough mem for given length
|
|
392
|
+
rescue Exception
|
|
393
|
+
return BitArray.new(len) # use BitArray when memory-error for Array
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
|
|
371
397
|
# Find largest index nthprime|val <= n; return [start_num, nth, f/t]
|
|
372
398
|
def set_start_value(n, hshflag)
|
|
373
399
|
if hshflag
|
|
@@ -488,31 +514,6 @@ module Primes
|
|
|
488
514
|
6_625_000_000 =>164_167_763_329, 6_750_000_000 => 167_397_013_051,
|
|
489
515
|
6_875_000_000 =>170_628_613_009, 7_000_000_000 => 173_862_636_221 }
|
|
490
516
|
end
|
|
491
|
-
|
|
492
|
-
def select_pg(end_num, start_num) # adaptively select PG
|
|
493
|
-
range = end_num - start_num
|
|
494
|
-
pg = 5
|
|
495
|
-
if start_num <= Integer.sqrt(end_num) # for one array of primes upto N
|
|
496
|
-
pg = 7 if end_num > 50 * 10**4
|
|
497
|
-
pg = 11 if end_num > 305 * 10**5
|
|
498
|
-
else # for split array cases
|
|
499
|
-
pg = 7 if (range.between?(10**6, 10**7 - 1) && start_num < 10**8) ||
|
|
500
|
-
(range.between?(10**7, 10**8 - 1) && start_num < 46 * 10**8) ||
|
|
501
|
-
(range.between?(10**8, 10**9 - 1) && start_num < 16 * 10**10) ||
|
|
502
|
-
(range >= 10**9 && start_num < 26 * 10**12)
|
|
503
|
-
pg = 11 if (range.between?(10**8, 10**9 - 1) && start_num < 55 * 10**7) ||
|
|
504
|
-
(range >= 10**9 && start_num < 45 * 10**9)
|
|
505
|
-
end
|
|
506
|
-
primes = [2, 3, 5, 7, 11, 13].select! { |p| p <= pg }
|
|
507
|
-
[primes, primes.reduce(:*)] # [base primes, mod] for PG
|
|
508
|
-
end
|
|
509
|
-
|
|
510
|
-
def array_check(len) # for out-of-memory errors on primes array creation
|
|
511
|
-
begin
|
|
512
|
-
Array.new(len, 0) # use Array when enough mem for given length
|
|
513
|
-
rescue Exception
|
|
514
|
-
return BitArray.new(len) # use BitArray when memory-error for Array
|
|
515
|
-
end end
|
|
516
517
|
end
|
|
517
518
|
end
|
|
518
519
|
|
data/primes-utils-3.0.0.gemspec
CHANGED
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
|
17
17
|
spec.files = FileList['lib/primes/utils.rb', 'lib/primes/utils/*.rb','bin/*', 'README.md', 'Gemfile', 'Rakefile', 'CODE_OF_CONDUCT.md', 'primes-utils-3.0.0.gemspec']
|
|
18
18
|
spec.require_paths = ["lib"]
|
|
19
19
|
spec.license = "LGPL-2.0-or-later"
|
|
20
|
-
spec.required_ruby_version = ">= 3.0.
|
|
20
|
+
spec.required_ruby_version = ">= 3.0.0"
|
|
21
21
|
|
|
22
22
|
spec.add_dependency "bitarray", "~> 1.3", ">= 1.3.1"
|
|
23
23
|
spec.add_development_dependency "bundler", "~> 1.9"
|