一般数体ふるい法で使うふるいの実装トライアル
一般数体ふるい法に使うふるいのプログラムを作ってみました。ただ、難しくてどう実装すればいいのかわからない計算式もあったので、できる範囲だけでの実装です。4桁くらいの小さい数までしかしっかりと動かせない感じです。
import numpy as np
import math
import random
def ugojod(a,b):
if a<0:
a*=-1
if b<0:
b*=-1
if a>b:
a,b=b,a
while a>0:
c=int(b)//int(a)
a,b=b-c*a,a
#print(a,b)
return b
def kaihei(a,sisuu):
#print(a,'a')
ns=[]
while a>0:
ns+=[a%10**sisuu]
a//=10**sisuu
#print(ns)
m=len(ns)
tm=0
c=0
ans=0
for i in range(m):
b=0
#print(c,ans,tm)
c=c*10**sisuu+ns[m-i-1]
for j in range(10):
#print(j,tm,b)
tm+=1
b+=1
if b*tm<=c:
1
else:
tm-=1
b-=1
break
#print(b)
ans=ans*10+b
c-=b*tm
tm=(tm+b)*10
#print(c,ans,'ans')
return c,ans
def xgcd(a,b):
x0,y0,x1,y1=1,0,0,1
while b!=0:
q,a,b=a//b,b,a%b
x0,x1=x1,x0-q*x1
y0,y1=y1,y0-q*y1
return a,x0,y0
def modinv2(a,m):
g,x,y=xgcd(a,m)
if g!=1:
return 'not exist'
else:
return x%m
def bezulis(baselist,amarilist):
b=baselist
a=amarilist
sh=a[0]
sab=b[0]
for i in range(1,len(b)):
go=ugojod(sab,b[i])
if go>1:
if ugojod(a[i]-sh%b[i],go)==go:
sh+=sab*(a[i]-sh%b[i])*modinv2(sab//go,b[i]//go)//go
sab*=b[i]//go
else:
continue
else:
sh+=sab*(a[i]-sh%b[i])*modinv2(sab,b[i])
sab*=b[i]
#print(sh,sab)
return sh,sab
def bekiyolists(bunkaiN,tei0,bekilist):
#bunkaiN=497
#tei=4
#beki=12
beki=len(bekilist)
bekiyolist=[0]*beki
blist=[]
tei=tei0
l=0
bekiloglist=[[]]*beki
mx=0
#print(bekilist)
for j in bekilist:
#print(j)
beki2=j
#if l%100==1:
#print(l)
i=0
listes=[]
while beki2>0:
listes.append(beki2%2)
#blist.append(beki2%2)
beki2=beki2//2
i+=1
bekiloglist[l]=listes
if mx<i:
mx=i
l+=1
#print(bekiloglist)
result=[1 ]*beki
for i in range(mx):
for j in range(beki):
if len(bekiloglist[j])>i:
#print(result[j],tei,bekiloglist[j][i],bunkaiN)
result[j]=(result[j]*tei**bekiloglist[j][i])%bunkaiN
#tei=bigprod(tei,tei)%bunkaiN
tei=(tei**2)%bunkaiN
#print(tei,'tei',bunkaiN)
bekiyolist=result
#print(result)
#print(beki,blist)
#blist.reverse()
#result=1
#for bv in blist :
#if bv==1:
#result=(result*tei)%bunkaiN
#tei=(tei*tei)%bunkaiN
#bekiyolist[k]=result
#k+=1
#print(tei,result)
return bekiyolist
def fermat(a):
c=3
if a==2 or a==3:
return True
if bekiyolists(a,2,[(a-1)])[0]==1 and bekiyolists(a,3,[(a-1)])[0]==1:
return True
return False
def millerrabin(a):
if a==2:
return True
if a>2 and a&1==0:
return False
s,t=0,a-1
while t&1==0:
s,t=s+1,t>>1
b=[2,7,61]
ret=False
for i in b:
if i>a:
break
if bekiyolists(a,i,[t])[0]==1:
#print(i,s,t,a,ret)
return True
ret= True
tt=t
for j in range(0,s):
if bekiyolists(a,i,[tt])[0]==a-1:
#print(i,s,j,tt,a,ret)
return True
ret=True
tt*=2
return ret
def heihoufind2(a,bl,pnl=[]):
pro=1
for i in range(len(bl)-3):
pro*=bl[i]
if pro>a:
bl=bl[0:i+3]
break
cl=[]
dl=[bekiyolists(bl[i],a,[(bl[i]-1)//2])[0] for i in range(len(bl))]
#print([bekiyolists(bl[i],a,[(bl[i]-1)//2])[0] for i in range(len(bl))],bl)
if len(pnl)>0:
for i in range(len(bl)):
if dl[i]==1:
cl+=[pnl[i][0]]
elif dl[i]+1==bl[i]:
cl+=[pnl[i][1]]
else:
cl+=[[]]
else:
for i in range(len(bl)):
ccl=[]
for j in range(1,bl[i]):
if bekiyolists(bl[i],j,[(bl[i]-1)//2])[0]==dl[i]:
ccl+=[j]
cl+=[ccl]
#print(cl,bl,dl,'dl')
mo=cl[0]
l=len(bl)
pro=bl[0]*bl[1%l]*bl[2%l]
d=[i for i in range(pro)if i%bl[0] in cl[0] and i%bl[1] in cl[1] and i%bl[2] in cl[2]]#+[3319]
e=[2 for i in range(len(d))]#+[2]
#print(d,e)
#print(8 in [2,4,8,10])
ret=[]
#print([bekiyolists(bl[j],274,[(bl[j]-1)//2])[0] for j in range(l)],274)
for k in range(8):
pro=bl[k%l]*bl[(k+1)%l]*bl[(k+2)%l]
dd=[]
ee=[]
fl=0
for i in range(len(d)):
if (k+2-e[i])%l==0 and d[i]%bl[(k+2)%l] in cl[(k+2)%l]:
#print(d[i],[bekiyolists(bl[j],d[i],[(bl[j]-1)//2])[0] for j in range(l)],dl)
if dl==[bekiyolists(bl[j],d[i],[(bl[j]-1)//2])[0] for j in range(l)]:
ret+=[d[i]]
fl=0
#print(xs)
if d[i]%bl[(k+2)%l] in cl[(k+2)%l]:
dd+=[d[i]]
ee+=[(e[i])%l]
pp=d[i]//pro
f=[pp*pro+(d[i]+j*bl[(k)%l]*bl[(k+1)%l])%pro for j in range(bl[(k+2)%l])]
f=list(set(f))
f=[f[j] for j in range(len(f))if f[j]%bl[(k+2)%l] in cl[(k+2)%l] and f[j]!=d[i] and f[j]<=a]
dd+=f
ee+=[(k+3)%l]*len(f)
d=dd
e=ee
f=list(set(d))
gg=[]
for i in range(len(f)):
g=[e[j] for j in range(len(e))if d[j]==f[i]]
ggg=[(k+2-g[j])%l for j in range(len(g))]
gg+=[g[ggg.index(max(ggg))]]
d=f
e=gg
#print(dd,ee,k,bl[(k+2)%l],(k-2)%l)
#print([d[j] for j in range(len(e))if e[j]==2],bl[(k+2)%l])
#print('lend',len(dd))
if fl==1:
break
if k%4==3:
dd=[]
ee=[]
fl=0
for i in range(len(d)):
if d[i] in cl[(k+3)%l] or (k+2-e[i])%l>5:
dd+=[d[i]]
ee+=[e[i]]
d=dd
e=ee
#print('lend',len(dd))
#print(ret,l)
#print(mo)
ret2=[]
if len(ret)==0:
return a,1
for i in range(len(ret)):
if a%ret[i]==0 and a>ret[i]:
if kaihei(a//ret[i],2)[0]!=0:
continue
ret2+=[ret[i]]
print(ret2)
if len(ret2)==0:
return a,1
ans=max(ret2)
return ans,a//ans
def funcchoose(a):
b=kaihei(a,2)[1]
c=[a//b**2]
c+=[(a-c[0]*b**2)//b]
c+=[a-c[0]*b**2-c[1]*b]
print(b,c)
if c[1]%2==1:
c[1]-=1
c[2]+=b
cc=[]
dx=0
if c[1]%2==0:
cc+=[1,0,c[2]-(c[1]//2)**2]
dx=b-c[1]//2
else:
cc+=[4,0,4*c[2]-(c[1])**2]
dx=2*b-c[1]
print(cc,dx)
return cc,dx
def quadquad(a,ls,lim=1000):
b=kaihei(a,2)[1]
limit=lim
if b<lim:
limit=b
e=[]
f=[]
for i in range(limit):
c=a-(b-i)**2
d=heihoufind2(c,ls)
e+=[d[0]]
f+=[d[1]]
#print(c,d)
#print(xs)
if i%100==99:
print(i)
g=e.index(min(e))
return [1,0,e[g]],b-g,kaihei(f[g],2)[1]
def soide2(xl,n):
idels=[]
alpls=[]
prils=[]
irange1=1
irange2=200
jrange=200
krange=500
prirange=80000
pri2range=2000
nidels=[]
nprils=[]
count=0
for i in range(irange1,irange2):
if i%10==9:
print('i',i)
for j in range(1,jrange):
a=xl[0]*i**2+xl[2]*j**2
if i==1 and j==1:
print(a,i,j,xl,fermat(a),millerrabin(a),([a] in prils)==False,prils)
if 1:
if 1:
bb=1
if fermat(a) and millerrabin(a) and a<prirange and( a in prils)==False:
alpls+=[bb]
#idels+=[[i,j,1,0]]
idels+=[[i,j,0,1,0]]
prils+=[a]
#count+=1
#if bekiyolists(a,bb,[a-1])[0]!=1:
# continue
kkrange=krange
if kkrange>a:
kkrange=a
l=0
for l in range(1,kkrange):
if (-xl[2]*modinv2(xl[0],a))%a==l**2%a:#check
ll=l
#count+=1
break
else:
continue
for k in range(1,krange):
kk=(-k*ll)+a#kk**2+k/ll**2==0
if (kk**2*xl[0]+k**2*xl[2])%a==0:
#count+=1
p=(kk**2*xl[0]+k**2*xl[2])//a
#print(p)
#print(i,j,k,a)
if p>=2 and fermat(p) and millerrabin(p) and p<prirange and( p in prils)==False:
bbb=1
alpls+=[bbb]
idels+=[[kk,k,0,i,j]]
prils+=[p]
count+=1
print(count,'count')
for i in range(2,pri2range):
if fermat(i) and millerrabin(i) and i not in prils:
alpls+=[0]
idels+=[[(i*modinv2(1,n))%n+xl[0],0,xl[0],1,0]]
prils+=[i]
print(count,'count')
print(idels[0:20],alpls[0:20],prils[0:20])
print(len(idels),len(alpls),len(prils))
print(len(idels))
print(list(sorted([abs(prils[k]) for k in range(len(prils))]))[0:90])
return idels,alpls,prils
def idesieve(ide,fx,n,xx,yy=1):
ils=ide[0]#[0:20]
als=ide[1]#[0:20]
pls=ide[2]#[0:20]
irange1=1
irange2=150
jrange1=2
jrange2=500
prirange=3000
#print(pls)
#print(xs)
spls=[]
anspri=[]
anspls=[]
anspair=[]
count=0
pri=[s for s in range(2,prirange)if fermat(s) and millerrabin(s)]
for i in range(irange1,irange2):
if i==0:
continue
for j in range(jrange1,jrange2):
if j==0:
continue
if ugojod(i,j)>1:
continue
c=[]
#a=i**2+j**2
a=fx[0]*i**2+fx[2]*j**2
g=[]
alp=[]
for k in range(len(pls)):
if ils[k][2]==0 and ils[k][4]==0 and a%abs(pls[k])==0 :#and (i+j*als[k])%abs(pls[k])==0:
#if a%pls[k]==0:
c+=[ils[k]]
#d*=fx[0]*ils[k][0]*yy+fx[2]*ils[k][1]*xx
g+=[pls[k]]
alp+=[als[k]]
continue
if ils[k][2]!=0 and ils[k][4]==0 and a%abs(pls[k])==0:#and (i+j*als[k])%abs(pls[k])==0:
#if a%pls[k]==0:
c+=[ils[k]]
#d*=fx[0]*ils[k][0]*yy+fx[2]*ils[k][1]*xx
g+=[pls[k]]
alp+=[als[k]]
continue
if ils[k][4]!=0 and a%abs(pls[k])==0:
#if a%pls[k]==0:
c+=[ils[k]]
g+=[pls[k]]
alp+=[als[k]]
if len(c)>0:
s=i*yy+j*xx
ss=s
prilist=[]
plslist=[]
ilslist=[]
pplslist=[]
alplist=[]
tatamils=[1]
d=1
rd=1
for k in range(len(pri)):
while s%pri[k]==0 and s!=0:
s//=pri[k]
prilist+=[pri[k]]
aa=a
for k in range(len(g)):
if g[k]>0 and c[k][2]==0 and c[k][4]==0:
while (aa)%abs(g[k])==0 and aa!=0 and abs(g[k])!=yy:
d*=c[k][0]*yy+c[k][1]*xx
ss*=yy
prilist+=[yy]
plslist+=[c[k][0]*yy+c[k][1]*xx]#[g[k]]
#aa*=yy
aa//=g[k]
#print(g[k])
#plslist+=[nor]#[g[k]]
#prilist+=[nor2]
ilslist+=[c[k]]
pplslist+=[g[k]]
#alplist+=[alp[k]]
if g[k]>0 and c[k][2]==0 and c[k][4]!=0:
while (aa)%abs(g[k])==0 and aa!=0 and abs(g[k])!=yy:
#d*=c[k][0]*c[k][3]*yy**2-c[k][1]*c[k][4]*xx**2+(-c[k][0]*c[k][4]+c[k][1]*c[k][3]*xx*yy)
d*=c[k][0]*yy+c[k][1]*xx
ss*=c[k][3]*yy+c[k][4]*xx
#ss*=yy
#ss*=c[k][3]**2*yy**2-c[k][4]**2*xx**2
prilist+=[c[k][3]*yy+c[k][4]*xx]
plslist+=[c[k][0]*yy+c[k][1]*xx]#[g[k]]
aa//=g[k]
#print(g[k])
#plslist+=[nor]#[g[k]]
#prilist+=[nor2]
ilslist+=[c[k]]
pplslist+=[g[k]]
#alplist+=[alp[k]]
if i%10==9and j==3 :#and (d-ss*rd)%n==0:
print(i,j,s,aa,d,ss,(d*aa-ss*s)%n,prilist,plslist,pplslist)
#if s==1 and aa==1 and (d-ss)%n==0 and d!=ss:
if (d*aa-ss*s)%n==0 and d*aa!=ss*s:
#print(i+j*x,i,j,x,c,d,prilist,aa)
print(d,ss,i,j,ss,a,s,aa,'ch',plslist,prilist,pplslist,ilslist)
anspri+=[prilist]
anspls+=[plslist]
anspair+=[[d*aa,ss*s]]
#print(c)
print(len(anspair))
print(len(anspri),len(anspls),len(anspair))
print('count',count)
return anspair,anspri,anspls
a=131*1031#1565912117761
b=3
c=3
d=35
bl=[i for i in range(2,500)if fermat(i) and millerrabin(i)]
qx=quadquad(a,bl,50)
print(a)
#print(fx)
print(qx)
print(kaihei(a,2))
so=soide2(qx[0],a)#qx[0]
#print(so)
#print(xs)
idesieve(so,qx[0],a,qx[1],qx[2])
苦戦の跡がたくさんありますが、何故苦戦しているかと言えば、素イデアルのノルムが小さい素イデアルを作るのが、分解したい数が大きくなるにつれて難しくなるからです。。