Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
|
|
@ -0,0 +1,323 @@
|
|||
' ***********************************************
|
||||
'subject: Shanks's square form factorization:
|
||||
' ambiguous forms of discriminant 4N
|
||||
' give factors of N.
|
||||
'tested : FreeBasic 1.08.1
|
||||
|
||||
|
||||
'------------------------------------------------
|
||||
const MxN = culngint(1) shl 62
|
||||
'input maximum
|
||||
|
||||
const qx = (1 shl 5) - 1
|
||||
'queue size
|
||||
|
||||
type arg
|
||||
'squfof arguments
|
||||
as ulong m, f
|
||||
as integer vb
|
||||
end type
|
||||
|
||||
type bqf
|
||||
declare sub rho ()
|
||||
'reduce indefinite form
|
||||
declare function issq (byref r as ulong) as integer
|
||||
'return -1 if c is square, set r:= sqrt(c)
|
||||
declare sub qform (byref g as string, byval t as integer)
|
||||
'print binary quadratic form #t (a, 2b, c)
|
||||
|
||||
as ulong rN, a, b, c
|
||||
as integer vb
|
||||
end type
|
||||
|
||||
type queue
|
||||
declare sub enq (byref P as bqf)
|
||||
'enqueue P.c, P.b if appropriate
|
||||
declare function pro (byref P as bqf, byval r as ulong) as integer
|
||||
'return -1 if a proper square form is found
|
||||
|
||||
as ulong a(qx), L, m
|
||||
as integer k, t
|
||||
end type
|
||||
|
||||
'global variables
|
||||
dim shared N as ulongint
|
||||
'the number to split
|
||||
|
||||
dim shared flag as integer
|
||||
'signal to end all threads
|
||||
|
||||
dim shared as ubyte q1024(1023), q3465(3464)
|
||||
'quadratic residue tables
|
||||
|
||||
|
||||
'------------------------------------------------
|
||||
sub bqf.rho ()
|
||||
dim as ulong q, t
|
||||
swap a, c
|
||||
'residue
|
||||
q = culng(rN + b) \ a
|
||||
t = b: b = q * a - b
|
||||
'pseudo-square
|
||||
c += q * (t - b)
|
||||
end sub
|
||||
|
||||
'initialize form
|
||||
#macro rhoin(F)
|
||||
F.rho : h = F.b
|
||||
F.c = (mN - h * h) \ F.a
|
||||
#endmacro
|
||||
|
||||
function bqf.issq (byref r as ulong) as integer
|
||||
if q1024(c and 1023) andalso q3465(c mod 3465) then
|
||||
'98.6% non-squares filtered
|
||||
r = culng(sqr(c))
|
||||
if r * r = c then return -1
|
||||
end if
|
||||
issq = 0
|
||||
end function
|
||||
|
||||
sub bqf.qform (byref g as string, byval t as integer)
|
||||
if vb = 0 then exit sub
|
||||
dim as longint u = a, v = b, w = c
|
||||
if t and 1 then
|
||||
w = -w
|
||||
else
|
||||
u = -u
|
||||
end if
|
||||
v shl= 1
|
||||
print g;str(t);" = (";u;",";v;",";w;")"
|
||||
end sub
|
||||
|
||||
'------------------------------------------------
|
||||
#macro red(r, a)
|
||||
r = iif(a and 1, a, a shr 1)
|
||||
if m > 2 then
|
||||
r = iif(r mod m, r, r \ m)
|
||||
end if
|
||||
#endmacro
|
||||
|
||||
sub queue.enq (byref P as bqf)
|
||||
dim s as ulong
|
||||
red(s, P.c)
|
||||
if s < L then
|
||||
'circular queue
|
||||
k = (k + 2) and qx
|
||||
if k > t then t = k
|
||||
'enqueue P.b, P.c
|
||||
a(k) = P.b mod s
|
||||
a(k + 1) = s
|
||||
end if
|
||||
end sub
|
||||
|
||||
function queue.pro (byref P as bqf, byval r as ulong) as integer
|
||||
dim as integer i, sw
|
||||
'skip improper square forms
|
||||
for i = 0 to t step 2
|
||||
sw = (P.b - a(i)) mod r = 0
|
||||
sw and= a(i + 1) = r
|
||||
if sw then return 0
|
||||
next i
|
||||
pro = -1
|
||||
end function
|
||||
|
||||
'------------------------------------------------
|
||||
sub squfof (byval ap as any ptr)
|
||||
dim as arg ptr rp = cptr(arg ptr, ap)
|
||||
dim as ulong L2, m, r, t, f = 1
|
||||
dim as integer ix, i, j
|
||||
dim as ulongint mN, h
|
||||
'principal and ambiguous cycles
|
||||
dim as bqf P, A
|
||||
dim Q as queue
|
||||
|
||||
if (N and 1) = 0 then
|
||||
rp->f = 2 ' even N
|
||||
flag =-1: exit sub
|
||||
end if
|
||||
|
||||
h = culngint(sqr(N))
|
||||
if h * h = N then
|
||||
'N is square
|
||||
rp->f = culng(h)
|
||||
flag =-1: exit sub
|
||||
end if
|
||||
|
||||
rp->f = 1
|
||||
'multiplier
|
||||
m = rp->m
|
||||
if m > 1 then
|
||||
if (N mod m) = 0 then
|
||||
rp->f = m ' m | N
|
||||
flag =-1: exit sub
|
||||
end if
|
||||
|
||||
'check overflow m * N
|
||||
if N > (MxN \ m) then exit sub
|
||||
end if
|
||||
mN = N * m
|
||||
|
||||
r = int(sqr(mN))
|
||||
'float64 fix
|
||||
if culngint(r) * r > mN then r -= 1
|
||||
P.rN = r
|
||||
A.rN = r
|
||||
|
||||
P.vb = rp->vb
|
||||
A.vb = rp->vb
|
||||
'verbosity switch
|
||||
if P.vb then print "r = "; r
|
||||
|
||||
Q.k = -2: Q.t = -1: Q.m = m
|
||||
'Queue entry bounds
|
||||
Q.L = int(sqr(r * 2))
|
||||
L2 = Q.L * m shl 1
|
||||
|
||||
'principal form
|
||||
P.b = r: P.c = 1
|
||||
rhoin(P)
|
||||
P.qform("P", 1)
|
||||
|
||||
ix = Q.L shl 2
|
||||
for i = 2 to ix
|
||||
'search principal cycle
|
||||
|
||||
if P.c < L2 then Q.enq(P)
|
||||
|
||||
P.rho
|
||||
if (i and 1) = 0 andalso P.issq(r) then
|
||||
'square form found
|
||||
|
||||
if Q.pro(P, r) then
|
||||
|
||||
P.qform("P", i)
|
||||
'inverse square root
|
||||
A.b =-P.b: A.c = r
|
||||
rhoin(A): j = 1
|
||||
A.qform("A", j)
|
||||
|
||||
do
|
||||
'search ambiguous cycle
|
||||
t = A.b
|
||||
A.rho: j += 1
|
||||
|
||||
if A.b = t then
|
||||
'symmetry point
|
||||
A.qform("A", j)
|
||||
red(f, A.a)
|
||||
if f = 1 then exit do
|
||||
|
||||
flag = -1
|
||||
'factor found
|
||||
end if
|
||||
loop until flag
|
||||
|
||||
end if ' proper square
|
||||
end if ' square form
|
||||
|
||||
if flag then exit for
|
||||
next i
|
||||
|
||||
rp->f = f
|
||||
end sub
|
||||
|
||||
'------------------------------------------------
|
||||
data 2501
|
||||
data 12851
|
||||
data 13289
|
||||
data 75301
|
||||
data 120787
|
||||
data 967009
|
||||
data 997417
|
||||
data 7091569
|
||||
data 13290059
|
||||
data 23515517
|
||||
data 42854447
|
||||
data 223553581
|
||||
data 2027651281
|
||||
data 11111111111
|
||||
data 100895598169
|
||||
data 1002742628021
|
||||
data 60012462237239
|
||||
data 287129523414791
|
||||
data 9007199254740931
|
||||
data 11111111111111111
|
||||
data 314159265358979323
|
||||
data 384307168202281507
|
||||
data 419244183493398773
|
||||
data 658812288346769681
|
||||
data 922337203685477563
|
||||
data 1000000000000000127
|
||||
data 1152921505680588799
|
||||
data 1537228672809128917
|
||||
data 4611686018427387877
|
||||
data 0
|
||||
|
||||
'main
|
||||
'------------------------------------------------
|
||||
const tx = 4
|
||||
dim as double tim = timer
|
||||
dim h(4) as any ptr
|
||||
dim a(4) as arg
|
||||
dim as ulongint f
|
||||
dim as integer s, t
|
||||
|
||||
width 64, 30
|
||||
cls
|
||||
|
||||
'tabulate quadratic residues
|
||||
for t = 0 to 1540
|
||||
s = t * t
|
||||
q1024(s and 1023) =-1
|
||||
q3465(s mod 3465) =-1
|
||||
next t
|
||||
|
||||
a(0).vb = 0
|
||||
'set one verbosity switch only
|
||||
|
||||
a(0).m = 1
|
||||
'multipliers
|
||||
a(1).m = 3
|
||||
a(2).m = 5
|
||||
a(3).m = 7
|
||||
a(4).m = 11
|
||||
|
||||
do
|
||||
print
|
||||
|
||||
do : read N
|
||||
loop until N < MxN
|
||||
if N < 2 then exit do
|
||||
|
||||
print "N = "; N
|
||||
|
||||
flag = 0
|
||||
|
||||
for t = 1 to tx + 1 step 2
|
||||
if t < tx then
|
||||
h(t) = threadcreate(@squfof, @a(t))
|
||||
end if
|
||||
|
||||
squfof(@a(t - 1))
|
||||
f = a(t - 1).f
|
||||
|
||||
if t < tx then
|
||||
threadwait(h(t))
|
||||
if f = 1 then f = a(t).f
|
||||
end if
|
||||
|
||||
if f > 1 then exit for
|
||||
next t
|
||||
|
||||
'assert
|
||||
if N mod f then f = 1
|
||||
|
||||
if f = 1 then
|
||||
print "fail"
|
||||
else
|
||||
print "f = ";f;" N/f = ";N \ f
|
||||
end if
|
||||
loop
|
||||
|
||||
print "total time:"; csng(timer - tim); " s"
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue