Skip to content

Commit d378ffa

Browse files
authored
Merge pull request #535 from StephenWampler/WorkBranch
Avoid name collision with ipl, add fast factoring of large integers
2 parents c626df7 + dc2eddd commit d378ffa

File tree

2 files changed

+65
-5
lines changed

2 files changed

+65
-5
lines changed

uni/lib/fastprime.icn

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ end
2424
# algorithm.
2525
# <[param n integer value to test for primality.]>
2626
# <[param precision degree of confidence to use (defaults to 16).]>
27+
# <[return n if n is prime, fails otherwise.]>
2728
#</p>
2829
procedure is_prime(n, precision)
2930
static known_primes, k_primes_set
@@ -60,8 +61,9 @@ end
6061
# <[param b base]>
6162
# <[param e exponent]>
6263
# <[param m modulus]>
64+
# <[return (b^e)%m]>
6365
#</p>
64-
procedure pow(b,e,m)
66+
procedure powm(b,e,m)
6567
r := 1
6668
while e > 0 do
6769
if e%2 = 0 then (e /:= 2, b := (b*b)%m)
@@ -86,7 +88,53 @@ end
8688
# <b>Internal use only unless you know how to compute <i>d</i> and <i>s</i>.</b>
8789
#</p>
8890
procedure try_composite(n, a, d, s)
89-
if pow(a,d,n) = 1 then fail
90-
every i := 0 to (s-1) do if pow(a,(2^i)*d,n) = n-1 then fail
91+
if powm(a,d,n) = 1 then fail
92+
every i := 0 to (s-1) do if powm(a,(2^i)*d,n) = n-1 then fail
9193
return n
9294
end
95+
96+
#<p>
97+
# Produce a list of all the factors of <i>n</i> using Pollard's rho algorithm.
98+
# Note that some factors may repeat, e.g. if <i>n = 5^2</i>.
99+
# <[param n number to factor]>
100+
# <[return list of all the factors of <i>n</i>]>
101+
#</p>
102+
procedure all_factors(n)
103+
flist := []
104+
f := getfactor(n)
105+
if f = n then return (put(flist,n), flist)
106+
flist |||:= all_factors(f) ||| all_factors(n/f)
107+
suspend sort(flist)
108+
end
109+
110+
#<p>
111+
# Generate the prime factors of <i>n</i> using Pollard's rho algorithm.
112+
# <[param n number to factor]>
113+
# <[generate the prime factors of n]>
114+
#</p>
115+
procedure gen_factors(n)
116+
suspend !sort(set(all_factors(n)))
117+
end
118+
119+
#<p>
120+
# Produce a factor of <i>n</i> using Pollard's rho algorithm.
121+
# <[param n number to factor]>
122+
# <[return one factor of <i>n</i>, or <i>n</i> if unable to find a factor.]>
123+
#</p>
124+
procedure getfactor(n)
125+
static sprimes
126+
initial sprimes := [: prime()\100 :]
127+
if n == 1 then return n
128+
if n%(i := !sprimes) == 0 then return i # Speed up for small factors
129+
y := x := rand_num()%(n-2) + 2
130+
c := rand_num()%(n-1) + 1
131+
d := 1
132+
while d = 1 do {
133+
x := (powm(x,2,n)+c+n)%n
134+
every (y|y) := (powm(y,2,n)+c+n)%n
135+
k := +(x-y)%n
136+
every (z := k) *:= |k\99
137+
d := gcd(z%n,n)
138+
}
139+
return d
140+
end

uni/lib/matrix_util.icn

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ procedure m_binop(M1, M1, op, zero:0)
117117
if (*M1 ~= *M2) | (*M1[1] ~= *M2[1]) then
118118
::runerr(500, "nonequal matrix dimensions to m_binop")
119119

120-
R = m_constant(*M1, *M1[1],zero)
120+
R := m_constant(*M1, *M1[1],zero)
121121
every (i := 1 to *M1, j := 1 to *M1[1]) do
122122
R[i,j] := invokeFcn(op,M1[i,j],M2[i,j])
123123
return R
@@ -157,7 +157,7 @@ procedure m_unaryop(M, op, zero:0)
157157
local R, i, j
158158
/op := ::proc("-", 1)
159159

160-
R = m_constant(*M, *M[1], zero)
160+
R := m_constant(*M, *M[1], zero)
161161
every (i := 1 to *M, j := 1 to *M[1]) do
162162
R[i,j] := invokeFcn(op, M[i,j])
163163
return R
@@ -358,3 +358,15 @@ procedure m_write(args[]) # Matrices and output files
358358
}
359359
::write(outfile)
360360
end
361+
362+
#<p>
363+
# A simplification of m_write() that (a) only writes a single matrix to stdout
364+
# and (b) allows column width specifiction for pretty-printing the matrix.
365+
# <[param m matrix to output]>
366+
# <[param w width of each column (default: 5)]>
367+
#</p>
368+
procedure writem(m,w)
369+
local i
370+
/w := 5
371+
every i := !m do every ::writes(::right(!i,3)|"\n")
372+
end

0 commit comments

Comments
 (0)