Class: FasterPrime::PrimalityTest::APRCL
- Inherits:
-
Object
- Object
- FasterPrime::PrimalityTest::APRCL
- Defined in:
- lib/faster_prime/primality_test.rb
Overview
APRCL Primarity Test
Henry Cohen. A course in computational algebraic number theory. 9.1 The Jacobi Sum Test
Defined Under Namespace
Classes: Composite, Failed, JacobiSumTableClass, ZZeta
Class Method Summary collapse
-
.prime?(n) ⇒ Boolean
Returns true if n is prime, false otherwise.
Instance Method Summary collapse
-
#initialize(n, jacobi_sum_table: DefaultJacobiSumTable, t: nil) ⇒ APRCL
constructor
Creates an APRCL instance to test an integer that is less than bound.
-
#prime? ⇒ Boolean
Algorithm 9.1.28 (Jacobi Sum Primality test).
Constructor Details
#initialize(n, jacobi_sum_table: DefaultJacobiSumTable, t: nil) ⇒ APRCL
Creates an APRCL instance to test an integer that is less than bound
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/faster_prime/primality_test.rb', line 107 def initialize(n, jacobi_sum_table: DefaultJacobiSumTable, t: nil) # an integer in question @n = n # precompute n-1 and (n-1)/2 because n is normally big @n1 = n - 1 @n1_2 = @n1 / 2 # @eta[pk]: a set of p^k-th roots of unity @eta = {} # a cache of Jacobi sums @js = jacobi_sum_table # compute e(t) if t raise "t must be even" if t.odd? @t = t @et = compute_e(@t) raise "t is too small to test n" if @n >= @et ** 2 else @t = find_t(@n) @et = compute_e(@t) end end |
Class Method Details
.prime?(n) ⇒ Boolean
Returns true if n is prime, false otherwise.
102 103 104 |
# File 'lib/faster_prime/primality_test.rb', line 102 def self.prime?(n) new(n).prime? end |
Instance Method Details
#prime? ⇒ Boolean
Algorithm 9.1.28 (Jacobi Sum Primality test)
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/faster_prime/primality_test.rb', line 134 def prime? return false if @n <= 1 # 1. [Check GCD] g = @n.gcd(@t * @et) return g == @n && PrimalityTest.prime?(g) if g != 1 # 2. [Initialize] lp = {} PrimeFactorization.prime_factorization(@t) do |p, | lp[p] = false if p == 2 || Utils.mod_pow(@n, p - 1, p ** 2) == 1 end # 3. [Loop on characters] Utils.each_divisor(@t) do |d| q = d + 1 next unless PrimalityTest.prime?(q) PrimeFactorization.prime_factorization(d) do |p, k| # 4. [Check (*beta)] lp.delete(p) if step4(q, p, k) end end # 5. [Check conditions Lp] lp.keys.each {|p| step5(p) } # 6. [Final trial division] r = 1 1.upto(@t - 1) do r = r * @n % @et return false if @n % r == 0 && 1 < r && r < @n end return true rescue Composite return false end |