version 1.2, 2002/07/25 08:06:07 |
version 1.3, 2002/09/11 07:26:50 |
Line 13 Check the License for details. You should have receive |
|
Line 13 Check the License for details. You should have receive |
|
with the package; see the file 'COPYING'. If not, write to the Free Software |
with the package; see the file 'COPYING'. If not, write to the Free Software |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
|
|
|
#include "pari.h" |
|
extern GEN bezout_lift_fact(GEN T, GEN Tmod, GEN p, long e); |
|
extern GEN respm(GEN x,GEN y,GEN pm); |
|
extern GEN ZX_disc_all(GEN,long); |
|
extern GEN polratlift(GEN P, GEN mod, GEN amax, GEN bmax, GEN denom); |
|
extern GEN znstar_hnf_elts(GEN Z, GEN H); |
|
extern long ZX_get_prec(GEN x); |
|
|
/*************************************************************************/ |
/*************************************************************************/ |
/** **/ |
/** **/ |
/** GALOIS CONJUGATES **/ |
/** GALOIS CONJUGATES **/ |
/** **/ |
/** **/ |
/*************************************************************************/ |
/*************************************************************************/ |
#include "pari.h" |
|
#define mylogint(x,y) logint((x),(y),NULL) |
|
GEN |
GEN |
galoisconj(GEN nf) |
galoisconj(GEN nf) |
{ |
{ |
GEN x, y, z; |
GEN x, y, z; |
long i, lz, v, av = avma; |
long i, lz, v; |
|
gpmem_t av = avma; |
nf = checknf(nf); |
nf = checknf(nf); |
x = (GEN) nf[1]; |
x = (GEN) nf[1]; |
v = varn(x); |
v = varn(x); |
Line 51 galoisconj(GEN nf) |
|
Line 59 galoisconj(GEN nf) |
|
GEN |
GEN |
galoisconj2pol(GEN x, long nbmax, long prec) |
galoisconj2pol(GEN x, long nbmax, long prec) |
{ |
{ |
long av = avma, i, n, v, nbauto; |
long i, n, v, nbauto; |
|
gpmem_t av = avma; |
GEN y, w, polr, p1, p2; |
GEN y, w, polr, p1, p2; |
n = degpol(x); |
n = degpol(x); |
if (n <= 0) |
if (n <= 0) |
Line 92 galoisconj2pol(GEN x, long nbmax, long prec) |
|
Line 101 galoisconj2pol(GEN x, long nbmax, long prec) |
|
GEN |
GEN |
galoisconj2(GEN nf, long nbmax, long prec) |
galoisconj2(GEN nf, long nbmax, long prec) |
{ |
{ |
long av = avma, i, j, n, r1, ru, nbauto; |
long i, j, n, r1, ru, nbauto; |
|
gpmem_t av = avma; |
GEN x, y, w, polr, p1, p2; |
GEN x, y, w, polr, p1, p2; |
if (typ(nf) == t_POL) |
if (typ(nf) == t_POL) |
return galoisconj2pol(nf, nbmax, prec); |
return galoisconj2pol(nf, nbmax, prec); |
Line 156 galoisconj2(GEN nf, long nbmax, long prec) |
|
Line 166 galoisconj2(GEN nf, long nbmax, long prec) |
|
7: memory |
7: memory |
9: complete detail |
9: complete detail |
*/ |
*/ |
/* retourne la permutation identite */ |
|
|
/* DP = multiple of disc(P) or NULL |
|
* Return a multiple of the denominator of an algebraic integer (in Q[X]/(P)) |
|
* when expressed in terms of the power basis */ |
GEN |
GEN |
permidentity(long l) |
indexpartial(GEN P, GEN DP) |
{ |
{ |
GEN perm; |
gpmem_t av = avma; |
int i; |
long i, nb; |
perm = cgetg(l + 1, t_VECSMALL); |
GEN fa, p1, res = gun, dP; |
for (i = 1; i <= l; i++) |
pari_timer T; |
perm[i] = i; |
|
return perm; |
|
} |
|
|
|
GEN vandermondeinverseprepold(GEN T, GEN L) |
dP = derivpol(P); |
{ |
if(DEBUGLEVEL>=5) (void)TIMER(&T); |
int i, n = lg(L); |
if(!DP) DP = ZX_disc(P); |
GEN V, dT; |
DP = mpabs(DP); |
dT = derivpol(T); |
if(DEBUGLEVEL>=5) msgTIMER(&T,"IndexPartial: discriminant"); |
V = cgetg(n, t_VEC); |
fa = auxdecomp(DP, 0); |
for (i = 1; i < n; i++) |
if(DEBUGLEVEL>=5) msgTIMER(&T,"IndexPartial: factorization"); |
V[i] = (long) poleval(dT, (GEN) L[i]); |
nb = lg(fa[1]); |
return V; |
for (i = 1; i < nb; i++) |
|
{ |
|
GEN p=gmael(fa,1,i); |
|
GEN e=gmael(fa,2,i); |
|
p1 = powgi(p,shifti(e,-1)); |
|
if ( i==nb-1 ) |
|
{ |
|
if ( mod2(e) && !isprime(p) ) |
|
p1 = mulii(p1,p); |
|
} |
|
else if ( cmpis(e,4)>=0 ) |
|
{ |
|
if(DEBUGLEVEL>=5) fprintferr("IndexPartial: factor %Z ",p1); |
|
p1 = mppgcd(p1, respm(P,dP,p1)); |
|
if(DEBUGLEVEL>=5) |
|
{ |
|
fprintferr("--> %Z : ",p1); |
|
msgTIMER(&T,""); |
|
} |
|
} |
|
res=mulii(res,p1); |
|
} |
|
return gerepileupto(av,res); |
} |
} |
|
|
GEN vandermondeinverseprep(GEN T, GEN L) |
GEN |
|
vandermondeinverseprep(GEN L) |
{ |
{ |
int i, j, n = lg(L); |
int i, j, n = lg(L); |
GEN V; |
GEN V; |
V = cgetg(n, t_VEC); |
V = cgetg(n, t_VEC); |
for (i = 1; i < n; i++) |
for (i = 1; i < n; i++) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
GEN W=cgetg(n,t_VEC); |
GEN W=cgetg(n,t_VEC); |
for (j = 1; j < n; j++) |
for (j = 1; j < n; j++) |
if (i==j) |
if (i==j) |
Line 202 GEN vandermondeinverseprep(GEN T, GEN L) |
|
Line 235 GEN vandermondeinverseprep(GEN T, GEN L) |
|
GEN |
GEN |
vandermondeinverse(GEN L, GEN T, GEN den, GEN prep) |
vandermondeinverse(GEN L, GEN T, GEN den, GEN prep) |
{ |
{ |
ulong ltop = avma, lbot; |
gpmem_t ltop = avma; |
int i, j, n = lg(L); |
int i, n = lg(L)-1; |
long x = varn(T); |
long x = varn(T); |
GEN M, P; |
GEN M, P; |
if (!prep) |
if (!prep) |
prep=vandermondeinverseprep(T,L); |
prep = vandermondeinverseprep(L); |
M = cgetg(n, t_MAT); |
M = cgetg(n+1, t_MAT); |
for (i = 1; i < n; i++) |
for (i = 1; i <= n; i++) |
{ |
{ |
M[i] = lgetg(n, t_COL); |
|
P = gdiv(gdeuc(T, gsub(polx[x], (GEN) L[i])), (GEN) prep[i]); |
P = gdiv(gdeuc(T, gsub(polx[x], (GEN) L[i])), (GEN) prep[i]); |
for (j = 1; j < n; j++) |
M[i] = (long)pol_to_vec(P,n); |
((GEN *) M)[i][j] = P[1 + j]; |
|
} |
} |
lbot = avma; |
return gerepileupto(ltop, gmul(den, M)); |
M = gmul(den, M); |
|
return gerepile(ltop, lbot, M); |
|
} |
} |
|
|
/* Calcule les bornes sur les coefficients a chercher */ |
/* Calcule les bornes sur les coefficients a chercher */ |
Line 234 struct galois_borne |
|
Line 263 struct galois_borne |
|
}; |
}; |
|
|
|
|
GEN indexpartial(GEN,GEN); |
|
GEN ZX_disc_all(GEN,long); |
|
|
|
GEN |
GEN |
galoisborne(GEN T, GEN dn, struct galois_borne *gb, long ppp) |
initgaloisborne(GEN T, GEN dn, long prec, GEN *ptL, GEN *ptprep, GEN *ptdis) |
{ |
{ |
ulong ltop = avma, av2; |
int i, n = degpol(T); |
GEN borne, borneroots, borneabs; |
GEN L, z, prep, den; |
int i, j; |
pari_timer ti; |
int n; |
|
GEN L, M, z, prep, den; |
if (DEBUGLEVEL>=4) (void)TIMER(&ti); |
long prec; |
|
n = degpol(T); |
|
prec = 1; |
|
for (i = 2; i < lgef(T); i++) |
|
if (lg(T[i]) > prec) |
|
prec = lg(T[i]); |
|
/*prec++;*/ |
|
if (DEBUGLEVEL>=4) gentimer(3); |
|
L = roots(T, prec); |
L = roots(T, prec); |
if (DEBUGLEVEL>=4) genmsgtimer(3,"roots"); |
if (DEBUGLEVEL>=4) msgTIMER(&ti,"roots"); |
for (i = 1; i <= n; i++) |
for (i = 1; i <= n; i++) |
{ |
{ |
z = (GEN) L[i]; |
z = (GEN) L[i]; |
if (signe(z[2])) |
if (signe(z[2])) break; |
break; |
|
L[i] = z[1]; |
L[i] = z[1]; |
} |
} |
if (DEBUGLEVEL>=4) gentimer(3); |
if (DEBUGLEVEL>=4) (void)TIMER(&ti); |
prep=vandermondeinverseprep(T, L); |
prep = vandermondeinverseprep(L); |
if (!dn) |
if (!dn) |
{ |
{ |
GEN res = divide_conquer_prod(gabs(prep,prec), mpmul); |
GEN dis, res = divide_conquer_prod(gabs(prep,prec), mpmul); |
GEN dis; |
|
disable_dbg(0); |
disable_dbg(0); |
dis = ZX_disc_all(T, 1+mylogint(res,gdeux)); |
dis = ZX_disc_all(T, 1+logint(res,gdeux,NULL)); |
disable_dbg(-1); |
disable_dbg(-1); |
den = gclone(indexpartial(T,dis)); |
den = indexpartial(T,dis); |
|
if (ptdis) *ptdis = dis; |
} |
} |
else |
else |
den=dn; |
den = dn; |
M = vandermondeinverse(L, gmul(T, realun(prec)), den, prep); |
if (ptprep) *ptprep = prep; |
if (DEBUGLEVEL>=4) genmsgtimer(3,"vandermondeinverse"); |
*ptL = L; return den; |
borne = realzero(prec); |
} |
for (i = 1; i <= n; i++) |
|
|
/* ||| M ||| with respect to || x ||_oo. Assume M square t_MAT */ |
|
GEN |
|
matrixnorm(GEN M, long prec) |
|
{ |
|
long i,j, n = lg(M); |
|
GEN B = realzero(prec); |
|
|
|
for (i = 1; i < n; i++) |
{ |
{ |
z = gzero; |
GEN z = gabs(gcoeff(M,i,1), prec); |
for (j = 1; j <= n; j++) |
for (j = 2; j < n; j++) |
z = gadd(z, gabs(gcoeff(M,i,j), prec)); |
z = gadd(z, gabs(gcoeff(M,i,j), prec)); |
if (gcmp(z, borne) > 0) |
if (gcmp(z, B) > 0) B = z; |
borne = z; |
|
} |
} |
borneroots = realzero(prec); |
return B; |
for (i = 1; i <= n; i++) |
} |
|
|
|
/* L a t_VEC/t_COL, return ||L||_oo */ |
|
GEN |
|
supnorm(GEN L, long prec) |
|
{ |
|
long i, n = lg(L); |
|
GEN z, B; |
|
|
|
if (n == 1) return realzero(prec); |
|
B = gabs((GEN)L[1], prec); |
|
for (i = 2; i < n; i++) |
{ |
{ |
z = gabs((GEN) L[i], prec); |
z = gabs((GEN)L[i], prec); |
if (gcmp(z, borneroots) > 0) |
if (gcmp(z, B) > 0) B = z; |
borneroots = z; |
|
} |
} |
|
return B; |
|
} |
|
|
|
GEN |
|
galoisborne(GEN T, GEN dn, struct galois_borne *gb, long ppp) |
|
{ |
|
gpmem_t ltop = avma, av2; |
|
GEN borne, borneroots, borneabs; |
|
int n; |
|
GEN L, M, prep, den; |
|
long prec; |
|
pari_timer ti; |
|
|
|
prec = ZX_get_prec(T); |
|
den = initgaloisborne(T,dn,prec, &L,&prep,NULL); |
|
if (!dn) den = gclone(den); |
|
if (DEBUGLEVEL>=4) TIMERstart(&ti); |
|
M = vandermondeinverse(L, gmul(T, realun(prec)), den, prep); |
|
if (DEBUGLEVEL>=4) msgTIMER(&ti,"vandermondeinverse"); |
|
borne = matrixnorm(M, prec); |
|
borneroots = supnorm(L, prec); |
|
n = degpol(T); |
borneabs = addsr(1, gmulsg(n, gpowgs(borneroots, n/ppp))); |
borneabs = addsr(1, gmulsg(n, gpowgs(borneroots, n/ppp))); |
/*if (ppp == 1) |
/*if (ppp == 1) |
borneabs = addsr(1, gmulsg(n, gpowgs(borneabs, 2)));*/ |
borneabs = addsr(1, gmulsg(n, gpowgs(borneabs, 2)));*/ |
borneroots = addsr(1, gmul(borne, borneroots)); |
borneroots = addsr(1, gmul(borne, borneroots)); |
av2 = avma; |
av2 = avma; |
/*We use d-1 test, so we must overlift to 2^BITS_IN_LONG*/ |
/*We use d-1 test, so we must overlift to 2^BITS_IN_LONG*/ |
gb->valsol = mylogint(gmul2n(borneroots,2+BITS_IN_LONG), gb->l); |
gb->valsol = logint(gmul2n(borneroots,2+BITS_IN_LONG), gb->l,NULL); |
gb->valabs = mylogint(gmul2n(borneabs,2), gb->l); |
gb->valabs = logint(gmul2n(borneabs,2), gb->l,NULL); |
gb->valabs = max(gb->valsol,gb->valabs); |
gb->valabs = max(gb->valsol, gb->valabs); |
if (DEBUGLEVEL >= 4) |
if (DEBUGLEVEL >= 4) |
fprintferr("GaloisConj:val1=%ld val2=%ld\n", gb->valsol, gb->valabs); |
fprintferr("GaloisConj:val1=%ld val2=%ld\n", gb->valsol, gb->valabs); |
avma = av2; |
avma = av2; |
gb->bornesol = gerepileupto(ltop, ceil_safe(borneroots)); |
gb->bornesol = gerepileupto(ltop, ceil_safe(mulrs(borneroots,2))); |
if (DEBUGLEVEL >= 9) |
if (DEBUGLEVEL >= 9) |
fprintferr("GaloisConj: Bound %Z\n",borneroots); |
fprintferr("GaloisConj: Bound %Z\n",borneroots); |
gb->ladicsol = gpowgs(gb->l, gb->valsol); |
gb->ladicsol = gpowgs(gb->l, gb->valsol); |
gb->ladicabs = gpowgs(gb->l, gb->valabs); |
gb->ladicabs = gpowgs(gb->l, gb->valabs); |
gb->lbornesol = subii(gb->ladicsol,gb->bornesol); |
gb->lbornesol = subii(gb->ladicsol,gb->bornesol); |
if (!dn) |
if (!dn) { dn = icopy(den); gunclone(den); } |
{ |
|
dn=forcecopy(den); |
|
gunclone(den); |
|
} |
|
return dn; |
return dn; |
} |
} |
|
|
Line 334 struct galois_lift |
|
Line 386 struct galois_lift |
|
/* Initialise la structure galois_lift */ |
/* Initialise la structure galois_lift */ |
GEN makeLden(GEN L,GEN den, struct galois_borne *gb) |
GEN makeLden(GEN L,GEN den, struct galois_borne *gb) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
long i,l=lg(L); |
long i,l=lg(L); |
GEN Lden; |
GEN Lden; |
Lden=cgetg(l,t_VEC); |
Lden=cgetg(l,t_VEC); |
Line 347 GEN makeLden(GEN L,GEN den, struct galois_borne *gb) |
|
Line 399 GEN makeLden(GEN L,GEN den, struct galois_borne *gb) |
|
void |
void |
initlift(GEN T, GEN den, GEN p, GEN L, GEN Lden, struct galois_borne *gb, struct galois_lift *gl) |
initlift(GEN T, GEN den, GEN p, GEN L, GEN Lden, struct galois_borne *gb, struct galois_lift *gl) |
{ |
{ |
ulong ltop, lbot; |
gpmem_t ltop, lbot; |
gl->gb=gb; |
gl->gb=gb; |
gl->T = T; |
gl->T = T; |
gl->den = den; |
gl->den = den; |
Line 355 initlift(GEN T, GEN den, GEN p, GEN L, GEN Lden, struc |
|
Line 407 initlift(GEN T, GEN den, GEN p, GEN L, GEN Lden, struc |
|
gl->L = L; |
gl->L = L; |
gl->Lden = Lden; |
gl->Lden = Lden; |
ltop = avma; |
ltop = avma; |
gl->e = mylogint(gmul2n(gb->bornesol, 2+BITS_IN_LONG),p); |
gl->e = logint(gmul2n(gb->bornesol, 2+BITS_IN_LONG),p,NULL); |
gl->e = max(2,gl->e); |
gl->e = max(2,gl->e); |
lbot = avma; |
lbot = avma; |
gl->Q = gpowgs(p, gl->e); |
gl->Q = gpowgs(p, gl->e); |
gl->Q = gerepile(ltop, lbot, gl->Q); |
gl->Q = gerepile(ltop, lbot, gl->Q); |
gl->TQ = FpX_red(T,gl->Q); |
gl->TQ = FpX_red(T,gl->Q); |
} |
} |
#if 0 |
|
/* |
|
* T est le polynome \sum t_i*X^i S est un Polmod T |
|
* Retourne un vecteur Spow |
|
* verifiant la condition: i>=1 et t_i!=0 ==> Spow[i]=S^(i-1)*t_i |
|
* Essaie d'etre efficace sur les polynomes lacunaires |
|
*/ |
|
GEN |
|
compoTS(GEN T, GEN S, GEN Q, GEN mod) |
|
{ |
|
GEN Spow; |
|
int i; |
|
Spow = cgetg(lgef(T) - 2, t_VEC); |
|
for (i = 3; i < lg(Spow); i++) |
|
Spow[i] = 0; |
|
Spow[1] = (long) polun[varn(S)]; |
|
Spow[2] = (long) S; |
|
for (i = 2; i < lg(Spow) - 1; i++) |
|
{ |
|
if (signe((GEN) T[i + 3])) |
|
for (;;) |
|
{ |
|
int k, l; |
|
for (k = 1; k <= (i >> 1); k++) |
|
if (Spow[k + 1] && Spow[i - k + 1]) |
|
break; |
|
if ((k << 1) < i) |
|
{ |
|
Spow[i + 1] = (long) FpXQ_mul((GEN) Spow[k + 1], (GEN) Spow[i - k + 1],Q,mod); |
|
break; |
|
} |
|
else if ((k << 1) == i) |
|
{ |
|
Spow[i + 1] = (long) FpXQ_sqr((GEN) Spow[k + 1],Q,mod); |
|
break; |
|
} |
|
for (k = i - 1; k > 0; k--) |
|
if (Spow[k + 1]) |
|
break; |
|
if ((k << 1) < i) |
|
{ |
|
Spow[(k << 1) + 1] = (long) FpXQ_sqr((GEN) Spow[k + 1],Q,mod); |
|
continue; |
|
} |
|
for (l = i - k; l > 0; l--) |
|
if (Spow[l + 1]) |
|
break; |
|
if (Spow[i - l - k + 1]) |
|
Spow[i - k + 1] = (long) FpXQ_mul((GEN) Spow[i - l - k + 1], (GEN) Spow[l + 1],Q,mod); |
|
else |
|
Spow[l + k + 1] = (long) FpXQ_mul((GEN) Spow[k + 1], (GEN) Spow[l + 1],Q,mod); |
|
} |
|
} |
|
for (i = 1; i < lg(Spow); i++) |
|
if (signe((GEN) T[i + 2])) |
|
Spow[i] = (long) FpX_Fp_mul((GEN) Spow[i], (GEN) T[i + 2],mod); |
|
return Spow; |
|
} |
|
|
|
/* |
/* |
* Calcule T(S) a l'aide du vecteur Spow |
|
*/ |
|
static GEN |
|
calcTS(GEN Spow, GEN P, GEN S, GEN Q, GEN mod) |
|
{ |
|
GEN res = gzero; |
|
int i; |
|
for (i = 1; i < lg(Spow); i++) |
|
if (signe((GEN) P[i + 2])) |
|
res = FpX_add(res, (GEN) Spow[i],NULL); |
|
res = FpXQ_mul(res,S,Q,mod); |
|
res=FpX_Fp_add(res,(GEN)P[2],mod); |
|
return res; |
|
} |
|
|
|
/* |
|
* Calcule T'(S) a l'aide du vecteur Spow |
|
*/ |
|
static GEN |
|
calcderivTS(GEN Spow, GEN P, GEN mod) |
|
{ |
|
GEN res = gzero; |
|
int i; |
|
for (i = 1; i < lg(Spow); i++) |
|
if (signe((GEN) P[i + 2])) |
|
res = FpX_add(res, FpX_Fp_mul((GEN) Spow[i], stoi(i),mod),NULL); |
|
return FpX_red(res,mod); |
|
} |
|
#endif |
|
/* |
|
* Verifie que f est une solution presque surement et calcule sa permutation |
* Verifie que f est une solution presque surement et calcule sa permutation |
*/ |
*/ |
static int |
static int |
poltopermtest(GEN f, struct galois_lift *gl, GEN pf) |
poltopermtest(GEN f, struct galois_lift *gl, GEN pf) |
{ |
{ |
ulong ltop; |
gpmem_t ltop; |
GEN fx, fp; |
GEN fx, fp; |
long i, j,ll; |
long i, j,ll; |
for (i = 2; i< lgef(f); i++) |
for (i = 2; i< lgef(f); i++) |
Line 466 poltopermtest(GEN f, struct galois_lift *gl, GEN pf) |
|
Line 430 poltopermtest(GEN f, struct galois_lift *gl, GEN pf) |
|
{ |
{ |
if (DEBUGLEVEL>=4) |
if (DEBUGLEVEL>=4) |
fprintferr("GaloisConj: Solution too large, discard it.\n"); |
fprintferr("GaloisConj: Solution too large, discard it.\n"); |
|
if (DEBUGLEVEL>=8) |
|
fprintferr("f=%Z\n borne=%Z\n l-borne=%Z\n",f,gl->gb->bornesol,gl->gb->lbornesol); |
return 0; |
return 0; |
} |
} |
ll=lg(gl->L); |
ll=lg(gl->L); |
Line 492 poltopermtest(GEN f, struct galois_lift *gl, GEN pf) |
|
Line 458 poltopermtest(GEN f, struct galois_lift *gl, GEN pf) |
|
return 1; |
return 1; |
} |
} |
|
|
GEN polratlift(GEN P, GEN mod, GEN amax, GEN bmax, GEN denom); |
|
|
|
/* |
/* |
* Soit P un polynome de \ZZ[X] , p un nombre premier , S\in\FF_p[X]/(Q) tel |
* Soit P un polynome de \ZZ[X] , p un nombre premier , S\in\FF_p[X]/(Q) tel |
* que P(S)=0 [p,Q] Relever S en S_0 tel que P(S_0)=0 [p^e,Q] |
* que P(S)=0 [p,Q] Relever S en S_0 tel que P(S_0)=0 [p^e,Q] |
Line 501 GEN polratlift(GEN P, GEN mod, GEN amax, GEN bmax, GEN |
|
Line 465 GEN polratlift(GEN P, GEN mod, GEN amax, GEN bmax, GEN |
|
*/ |
*/ |
static long monoratlift(GEN S, GEN q, GEN qm1old,struct galois_lift *gl, GEN frob) |
static long monoratlift(GEN S, GEN q, GEN qm1old,struct galois_lift *gl, GEN frob) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
GEN tlift = polratlift(S,q,qm1old,qm1old,gl->den); |
GEN tlift = polratlift(S,q,qm1old,qm1old,gl->den); |
if (tlift) |
if (tlift) |
{ |
{ |
Line 525 static long monoratlift(GEN S, GEN q, GEN qm1old,struc |
|
Line 489 static long monoratlift(GEN S, GEN q, GEN qm1old,struc |
|
GEN |
GEN |
monomorphismratlift(GEN P, GEN S, struct galois_lift *gl, GEN frob) |
monomorphismratlift(GEN P, GEN S, struct galois_lift *gl, GEN frob) |
{ |
{ |
ulong ltop, lbot; |
gpmem_t ltop, lbot; |
long rt; |
long rt; |
GEN Q=gl->T, p=gl->p; |
GEN Q=gl->T, p=gl->p; |
long e=gl->e, level=1; |
long e=gl->e, level=1; |
Line 534 monomorphismratlift(GEN P, GEN S, struct galois_lift * |
|
Line 498 monomorphismratlift(GEN P, GEN S, struct galois_lift * |
|
GEN W, Pr, Qr, Sr, Wr = gzero, Prold, Qrold, Spow; |
GEN W, Pr, Qr, Sr, Wr = gzero, Prold, Qrold, Spow; |
long i,nb,mask; |
long i,nb,mask; |
GEN *gptr[2]; |
GEN *gptr[2]; |
if (DEBUGLEVEL == 1) |
if (DEBUGLEVEL == 1) (void)timer2(); |
timer2(); |
|
x = varn(P); |
x = varn(P); |
rt = brent_kung_optpow(degpol(Q),1); |
rt = brent_kung_optpow(degpol(Q),1); |
q = p; qm1 = gun; /*during the run, we have p*qm1=q*/ |
q = p; qm1 = gun; /*during the run, we have p*qm1=q*/ |
Line 554 monomorphismratlift(GEN P, GEN S, struct galois_lift * |
|
Line 517 monomorphismratlift(GEN P, GEN S, struct galois_lift * |
|
if (DEBUGLEVEL>=2) |
if (DEBUGLEVEL>=2) |
{ |
{ |
level=(level<<1)-((mask>>i)&1); |
level=(level<<1)-((mask>>i)&1); |
timer2(); |
(void)timer2(); |
} |
} |
qm1 = (mask&(1<<i))?sqri(qm1):mulii(qm1, q); |
qm1 = (mask&(1<<i))?sqri(qm1):mulii(qm1, q); |
q = mulii(qm1, p); |
q = mulii(qm1, p); |
Line 562 monomorphismratlift(GEN P, GEN S, struct galois_lift * |
|
Line 525 monomorphismratlift(GEN P, GEN S, struct galois_lift * |
|
Qr = (P==Q)?Pr:FpX_red(Q, q);/*A little speed up for automorphismlift*/ |
Qr = (P==Q)?Pr:FpX_red(Q, q);/*A little speed up for automorphismlift*/ |
ltop = avma; |
ltop = avma; |
Sr = S; |
Sr = S; |
/*Spow = compoTS(Pr, Sr, Qr, q);*/ |
|
Spow = FpXQ_powers(Sr, rt, Qr, q); |
Spow = FpXQ_powers(Sr, rt, Qr, q); |
|
|
if (i) |
if (i) |
{ |
{ |
/*W = FpXQ_mul(Wr, calcderivTS(Spow, Prold,qold), Qrold, qold);*/ |
|
W = FpXQ_mul(Wr, FpX_FpXQV_compo(deriv(Pr,-1),FpXV_red(Spow,qold),Qrold,qold), Qrold, qold); |
W = FpXQ_mul(Wr, FpX_FpXQV_compo(deriv(Pr,-1),FpXV_red(Spow,qold),Qrold,qold), Qrold, qold); |
W = FpX_neg(W, qold); |
W = FpX_neg(W, qold); |
W = FpX_Fp_add(W, gdeux, qold); |
W = FpX_Fp_add(W, gdeux, qold); |
W = FpXQ_mul(Wr, W, Qrold, qold); |
W = FpXQ_mul(Wr, W, Qrold, qold); |
} |
} |
Wr = W; |
Wr = W; |
/*S = FpXQ_mul(Wr, calcTS(Spow, Pr, Sr, Qr, q),Qr,q);*/ |
|
S = FpXQ_mul(Wr, FpX_FpXQV_compo(Pr, Spow, Qr, q),Qr,q); |
S = FpXQ_mul(Wr, FpX_FpXQV_compo(Pr, Spow, Qr, q),Qr,q); |
S = FpX_sub(Sr, S, NULL); |
S = FpX_sub(Sr, S, NULL); |
lbot = avma; |
lbot = avma; |
Line 621 struct galois_testlift |
|
Line 581 struct galois_testlift |
|
GEN C; |
GEN C; |
GEN Cd; |
GEN Cd; |
}; |
}; |
GEN bezout_lift_fact(GEN T, GEN Tmod, GEN p, long e); |
|
static GEN |
static GEN |
galoisdolift(struct galois_lift *gl, GEN frob) |
galoisdolift(struct galois_lift *gl, GEN frob) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
long v = varn(gl->T); |
long v = varn(gl->T); |
GEN Tp = FpX_red(gl->T, gl->p); |
GEN Tp = FpX_red(gl->T, gl->p); |
GEN S = FpXQ_pow(polx[v],gl->p, Tp,gl->p); |
GEN S = FpXQ_pow(polx[v],gl->p, Tp,gl->p); |
Line 647 inittestlift( GEN plift, GEN Tmod, struct galois_lift |
|
Line 606 inittestlift( GEN plift, GEN Tmod, struct galois_lift |
|
gt->pauto[2] = (long) gcopy(plift); |
gt->pauto[2] = (long) gcopy(plift); |
if (gt->f > 2) |
if (gt->f > 2) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
int i; |
int i; |
long nautpow=brent_kung_optpow(gt->n-1,gt->f-2); |
long nautpow=brent_kung_optpow(gt->n-1,gt->f-2); |
GEN autpow; |
GEN autpow; |
if (DEBUGLEVEL >= 1) timer2(); |
if (DEBUGLEVEL >= 1) (void)timer2(); |
autpow = FpXQ_powers(plift,nautpow,gl->TQ,gl->Q); |
autpow = FpXQ_powers(plift,nautpow,gl->TQ,gl->Q); |
for (i = 3; i <= gt->f; i++) |
for (i = 3; i <= gt->f; i++) |
gt->pauto[i] = (long) FpX_FpXQV_compo((GEN)gt->pauto[i-1],autpow,gl->TQ,gl->Q); |
gt->pauto[i] = (long) FpX_FpXQV_compo((GEN)gt->pauto[i-1],autpow,gl->TQ,gl->Q); |
Line 663 inittestlift( GEN plift, GEN Tmod, struct galois_lift |
|
Line 622 inittestlift( GEN plift, GEN Tmod, struct galois_lift |
|
|
|
long intheadlong(GEN x, GEN mod) |
long intheadlong(GEN x, GEN mod) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
GEN r; |
GEN r; |
int s; |
int s; |
long res; |
long res; |
|
|
frobeniusliftall(GEN sg, long el, GEN *psi, struct galois_lift *gl, |
frobeniusliftall(GEN sg, long el, GEN *psi, struct galois_lift *gl, |
struct galois_testlift *gt, GEN frob) |
struct galois_testlift *gt, GEN frob) |
{ |
{ |
ulong ltop = avma, av, ltop2; |
gpmem_t av, ltop2, ltop = avma; |
long d, z, m, c, n, ord; |
long d, z, m, c, n, ord; |
int i, j, k; |
int i, j, k; |
GEN pf, u, v; |
GEN pf, u, v; |
GEN C, Cd; |
GEN C, Cd, sgi, cache; |
long Z, Zv; |
long Z, c_idx=gt->g-1; |
long stop=0; |
long stop=0,hop=0; |
GEN NN,NQ,NR; |
GEN NN,NQ,NR; |
long N1,N2,R1,Ni; |
long N1,N2,R1,Ni; |
m = gt->g; |
m = gt->g; |
ord = gt->f; |
ord = gt->f; |
n = lg(gl->L) - 1; |
n = lg(gl->L) - 1; |
Line 722 frobeniusliftall(GEN sg, long el, GEN *psi, struct gal |
|
Line 681 frobeniusliftall(GEN sg, long el, GEN *psi, struct gal |
|
NQ=dvmdis(NN,N1,&NR); |
NQ=dvmdis(NN,N1,&NR); |
if (cmpis(NQ,1000000000)>0) |
if (cmpis(NQ,1000000000)>0) |
{ |
{ |
err(warner,"Combinatorics too hard : would need %Z tests!\n \ |
err(warner,"Combinatorics too hard : would need %Z tests!\n" |
I will skip it,but it may induce galoisinit to loop",NN); |
"I will skip it,but it may induce galoisinit to loop",NN); |
avma = ltop; |
avma = ltop; |
*psi = NULL; |
*psi = NULL; |
return 0; |
return 0; |
Line 732 frobeniusliftall(GEN sg, long el, GEN *psi, struct gal |
|
Line 691 frobeniusliftall(GEN sg, long el, GEN *psi, struct gal |
|
if (DEBUGLEVEL>=4) |
if (DEBUGLEVEL>=4) |
{ |
{ |
stop=N1/20; |
stop=N1/20; |
timer2(); |
(void)timer2(); |
} |
} |
avma = ltop2; |
avma = ltop2; |
C=gt->C; |
C=gt->C; |
Cd=gt->Cd; |
Cd=gt->Cd; |
v = FpX_Fp_mul(FpXQ_mul((GEN)gt->pauto[1+el%ord], (GEN) |
v = FpX_Fp_mul(FpXQ_mul((GEN)gt->pauto[1+el%ord], (GEN) |
gt->bezoutcoeff[m],gl->TQ,gl->Q),gl->den,gl->Q); |
gt->bezoutcoeff[m],gl->TQ,gl->Q),gl->den,gl->Q); |
Zv=polheadlong(v,0,gl->Q); |
sgi=cgetg(lg(sg),t_VECSMALL); |
|
for(i=1;i<lg(sgi);i++) |
|
sgi[i]=(el*sg[i])%ord + 1; |
|
cache=cgetg(m+1,t_VECSMALL); |
|
cache[m]=polheadlong(v,1,gl->Q); |
|
Z=polheadlong(v,2,gl->Q); |
for (i = 1; i < m; i++) |
for (i = 1; i < m; i++) |
pf[i] = 1 + i / d; |
pf[i] = 1 + i / d; |
av = avma; |
av = avma; |
for (Ni = 0, i = 0; ;i++) |
for (Ni = 0, i = 0; ;i++) |
{ |
{ |
Z=Zv; |
for (j = c_idx ; j > 0; j--) |
for (j = 1; j < m; j++) |
|
{ |
{ |
long h; |
long h; |
h=(el*sg[pf[j]])%ord + 1; |
h=sgi[pf[j]]; |
if (!mael(C,h,j)) |
if (!mael(C,h,j)) |
{ |
{ |
ulong av3=avma; |
gpmem_t av3=avma; |
GEN r; |
GEN r; |
r=FpX_Fp_mul(FpXQ_mul((GEN) gt->pauto[h], |
r=FpX_Fp_mul(FpXQ_mul((GEN) gt->pauto[h], |
(GEN) gt->bezoutcoeff[j],gl->TQ,gl->Q),gl->den,gl->Q); |
(GEN) gt->bezoutcoeff[j],gl->TQ,gl->Q),gl->den,gl->Q); |
mael(C,h,j) = lclone(r); |
mael(C,h,j) = lclone(r); |
mael(Cd,h,j) = polheadlong(r,0,gl->Q); |
mael(Cd,h,j) = polheadlong(r,1,gl->Q); |
avma=av3; |
avma=av3; |
} |
} |
Z += mael(Cd,h,j); |
cache[j]=cache[j+1]+mael(Cd,h,j); |
} |
} |
if (labs(Z)<=n ) |
if (labs(cache[1])<=n ) |
{ |
{ |
Z=polheadlong(v,1,gl->Q); |
long ZZ=Z; |
for (j = 1; j < m; j++) |
for (j = 1; j < m; j++) |
Z += polheadlong(gmael(C,(el*sg[pf[j]])%ord + 1,j),1,gl->Q); |
ZZ += polheadlong(gmael(C,sgi[pf[j]],j),2,gl->Q); |
if (labs(Z)<=n ) |
if (labs(ZZ)<=n ) |
{ |
{ |
u = v; |
u = v; |
for (j = 1; j < m; j++) |
for (j = 1; j < m; j++) |
u = FpX_add(u, gmael(C,1+(el*sg[pf[j]])%ord,j),NULL); |
u = FpX_add(u, gmael(C,sgi[pf[j]],j),NULL); |
u = FpX_center(FpX_red(u, gl->Q), gl->Q); |
u = FpX_center(FpX_red(u, gl->Q), gl->Q); |
if (poltopermtest(u, gl, frob)) |
if (poltopermtest(u, gl, frob)) |
{ |
{ |
if (DEBUGLEVEL >= 4 ) |
if (DEBUGLEVEL >= 4 ) |
|
{ |
msgtimer(""); |
msgtimer(""); |
|
fprintferr("GaloisConj: %d hops on %Z tests\n",hop,addis(mulss(Ni,N1),i)); |
|
} |
avma = ltop2; |
avma = ltop2; |
return 1; |
return 1; |
} |
} |
|
else if (DEBUGLEVEL >= 4 ) |
|
fprintferr("M"); |
} |
} |
|
else hop++; |
} |
} |
if (DEBUGLEVEL >= 4 && i==stop) |
if (DEBUGLEVEL >= 4 && i==stop) |
{ |
{ |
Line 799 frobeniusliftall(GEN sg, long el, GEN *psi, struct gal |
|
Line 768 frobeniusliftall(GEN sg, long el, GEN *psi, struct gal |
|
if (DEBUGLEVEL>=4) |
if (DEBUGLEVEL>=4) |
{ |
{ |
stop=N1/20; |
stop=N1/20; |
timer2(); |
(void)timer2(); |
} |
} |
} |
} |
for (j = 2; j < m && pf[j - 1] >= pf[j]; j++); |
for (j = 2; j < m && pf[j - 1] >= pf[j]; j++); |
Line 813 frobeniusliftall(GEN sg, long el, GEN *psi, struct gal |
|
Line 782 frobeniusliftall(GEN sg, long el, GEN *psi, struct gal |
|
z = pf[j]; |
z = pf[j]; |
pf[j] = pf[k]; |
pf[j] = pf[k]; |
pf[k] = z; |
pf[k] = z; |
|
c_idx=j; |
} |
} |
|
if (DEBUGLEVEL>=4) |
|
fprintferr("GaloisConj: not found, %d hops \n",hop); |
avma = ltop; |
avma = ltop; |
*psi = NULL; |
*psi = NULL; |
return 0; |
return 0; |
} |
} |
/* |
|
* applique une permutation t a un vecteur s sans duplication |
|
* Propre si s est un VECSMALL |
|
*/ |
|
static GEN |
|
permapply(GEN s, GEN t) |
|
{ |
|
GEN u; |
|
int i; |
|
if (lg(s) < lg(t)) |
|
err(talker, "First permutation shorter than second in permapply"); |
|
u = cgetg(lg(s), typ(s)); |
|
for (i = 1; i < lg(s); i++) |
|
u[i] = s[t[i]]; |
|
return u; |
|
} |
|
|
|
/* |
/* |
* alloue une ardoise pour n entiers de longueurs pour les test de |
* alloue une ardoise pour n entiers de longueurs pour les test de |
Line 870 struct galois_test |
|
Line 826 struct galois_test |
|
static GEN |
static GEN |
Vmatrix(long n, struct galois_test *td) |
Vmatrix(long n, struct galois_test *td) |
{ |
{ |
ulong ltop = avma, lbot; |
gpmem_t lbot, ltop = avma; |
GEN V; |
GEN V; |
long i; |
long i; |
V = cgetg(lg(td->L), t_VEC); |
V = cgetg(lg(td->L), t_VEC); |
Line 888 Vmatrix(long n, struct galois_test *td) |
|
Line 844 Vmatrix(long n, struct galois_test *td) |
|
static void |
static void |
inittest(GEN L, GEN M, GEN borne, GEN ladic, struct galois_test *td) |
inittest(GEN L, GEN M, GEN borne, GEN ladic, struct galois_test *td) |
{ |
{ |
ulong ltop; |
gpmem_t ltop; |
long i; |
long i; |
int n = lg(L) - 1; |
int n = lg(L) - 1; |
if (DEBUGLEVEL >= 8) |
if (DEBUGLEVEL >= 8) |
Line 909 inittest(GEN L, GEN M, GEN borne, GEN ladic, struct ga |
|
Line 865 inittest(GEN L, GEN M, GEN borne, GEN ladic, struct ga |
|
ltop = avma; |
ltop = avma; |
td->PV[td->ordre[n]] = (long) gclone(Vmatrix(td->ordre[n], td)); |
td->PV[td->ordre[n]] = (long) gclone(Vmatrix(td->ordre[n], td)); |
avma = ltop; |
avma = ltop; |
td->TM = gtrans(M); |
td->TM = gtrans_i(M); |
settyp(td->TM, t_VEC); |
settyp(td->TM, t_VEC); |
for (i = 1; i < lg(td->TM); i++) |
for (i = 1; i < lg(td->TM); i++) |
settyp(td->TM[i], t_VEC); |
settyp(td->TM[i], t_VEC); |
|
|
padicisint(GEN P, struct galois_test *td) |
padicisint(GEN P, struct galois_test *td) |
{ |
{ |
long r; |
long r; |
ulong ltop = avma; |
gpmem_t ltop = avma; |
GEN U; |
GEN U; |
/*if (typ(P) != t_INT) err(typeer, "padicisint");*/ |
/*if (typ(P) != t_INT) err(typeer, "padicisint");*/ |
U = modii(P, td->ladic); |
U = modii(P, td->ladic); |
Line 957 padicisint(GEN P, struct galois_test *td) |
|
Line 913 padicisint(GEN P, struct galois_test *td) |
|
static long |
static long |
verifietest(GEN pf, struct galois_test *td) |
verifietest(GEN pf, struct galois_test *td) |
{ |
{ |
ulong av = avma; |
gpmem_t av = avma; |
GEN P, V; |
GEN P, V; |
int i, j; |
int i, j; |
int n = lg(td->L) - 1; |
int n = lg(td->L) - 1; |
if (DEBUGLEVEL >= 8) |
if (DEBUGLEVEL >= 8) |
fprintferr("GaloisConj:Entree Verifie Test\n"); |
fprintferr("GaloisConj:Entree Verifie Test\n"); |
P = permapply(td->L, pf); |
P = perm_mul(td->L, pf); |
for (i = 1; i < n; i++) |
for (i = 1; i < n; i++) |
{ |
{ |
long ord; |
long ord; |
|
|
testpermutation(GEN F, GEN B, long s, long t, long cut, |
testpermutation(GEN F, GEN B, long s, long t, long cut, |
struct galois_test *td) |
struct galois_test *td) |
{ |
{ |
ulong av, avm = avma; |
gpmem_t av, avm = avma; |
int a, b, c, d, n; |
int a, b, c, d, n; |
GEN pf, x, ar, y, *G; |
GEN pf, x, ar, y, *G; |
int p1, p2, p3, p4, p5, p6; |
int p1, p2, p3, p4, p5, p6; |
Line 1036 testpermutation(GEN F, GEN B, long s, long t, long cut |
|
Line 992 testpermutation(GEN F, GEN B, long s, long t, long cut |
|
long i, j, cx, hop = 0, start = 0; |
long i, j, cx, hop = 0, start = 0; |
GEN W, NN, NQ, NR; |
GEN W, NN, NQ, NR; |
long V; |
long V; |
if (DEBUGLEVEL >= 1) |
if (DEBUGLEVEL >= 1) (void)timer2(); |
timer2(); |
|
a = lg(F) - 1; |
a = lg(F) - 1; |
b = lg(F[1]) - 1; |
b = lg(F[1]) - 1; |
c = lg(B) - 1; |
c = lg(B) - 1; |
Line 1071 testpermutation(GEN F, GEN B, long s, long t, long cut |
|
Line 1026 testpermutation(GEN F, GEN B, long s, long t, long cut |
|
{ |
{ |
avma=avm; |
avma=avm; |
err(warner,"Combinatorics too hard : would need %Z tests!\n I'll skip it but you will get a partial result...",NN); |
err(warner,"Combinatorics too hard : would need %Z tests!\n I'll skip it but you will get a partial result...",NN); |
return permidentity(n); |
return perm_identity(n); |
} |
} |
N2=itos(NQ); R1=itos(NR); |
N2=itos(NQ); R1=itos(NR); |
for (l2 = 0; l2 <= N2; l2++) |
for (l2 = 0; l2 <= N2; l2++) |
Line 1195 testpermutation(GEN F, GEN B, long s, long t, long cut |
|
Line 1150 testpermutation(GEN F, GEN B, long s, long t, long cut |
|
avma = avm; |
avma = avm; |
return gzero; |
return gzero; |
} |
} |
/* Compute generators for the subgroup of (Z/nZ)* given in HNF. |
|
* I apologize for the following spec: |
|
* If zns=znstar(2) then |
|
* zn2=gtovecsmall((GEN)zns[2]); |
|
* zn3=lift((GEN)zns[3]); |
|
* gen and ord : VECSMALL of length lg(zn3). |
|
* the result is in gen. |
|
* ord contains the relatives orders of the generators. |
|
*/ |
|
GEN hnftogeneratorslist(long n, GEN zn2, GEN zn3, GEN lss, GEN gen, GEN ord) |
|
{ |
|
ulong ltop=avma; |
|
int j,h; |
|
GEN m=stoi(n); |
|
for (j = 1; j < lg(gen); j++) |
|
{ |
|
gen[j] = 1; |
|
for (h = 1; h < lg(lss); h++) |
|
gen[j] = mulssmod(gen[j], itos(powmodulo((GEN)zn3[h],gmael(lss,j,h),m)),n); |
|
ord[j] = zn2[j] / itos(gmael(lss,j,j)); |
|
} |
|
avma=ltop; |
|
return gen; |
|
} |
|
/*in place sort. Return V for convenience only*/ |
|
GEN sortvecsmall(GEN V) |
|
{ |
|
long i,j,k,l,m; |
|
for(l=1;l<lg(V);l<<=1) |
|
for(j=1;(j>>1)<lg(V);j+=l<<1) |
|
for(k=j+l,i=j; i<k && k<j+(l<<1) && k<lg(V);) |
|
if (V[i]>V[k]) |
|
{ |
|
long z=V[k]; |
|
for (m=k;m>i;m--) |
|
V[m]=V[m-1]; |
|
V[i]=z; |
|
k++; |
|
} |
|
else |
|
i++; |
|
return V ; |
|
} |
|
GEN uniqvecsmall(GEN V) |
|
{ |
|
ulong ltop=avma; |
|
GEN W; |
|
long i,j; |
|
if ( lg(V) == 1 ) return gcopy(V); |
|
W=cgetg(lg(V),t_VECSMALL); |
|
W[1]=V[1]; |
|
for(i=2,j=1;i<lg(V);i++) |
|
if (V[i]!=W[j]) |
|
W[++j]=V[i]; |
|
setlg(W,j+1); |
|
return gerepileupto(ltop,W); |
|
} |
|
int pari_compare_lg(GEN x, GEN y) |
int pari_compare_lg(GEN x, GEN y) |
{ |
{ |
return lg(x)-lg(y); |
return lg(x)-lg(y); |
} |
} |
/* Compute the elements of the subgroup of (Z/nZ)* given in HNF. |
|
* I apologize for the following spec: |
|
* If zns=znstar(2) then |
|
* zn2=gtovecsmall((GEN)zns[2]); |
|
* zn3=lift((GEN)zns[3]); |
|
* card=cardinal of the subgroup(i.e phi(n)/det(lss)) |
|
*/ |
|
GEN |
|
hnftoelementslist(long n, GEN zn2, GEN zn3, GEN lss, long card) |
|
{ |
|
ulong ltop; |
|
GEN sg, gen, ord; |
|
int k, j, l; |
|
sg = cgetg(1 + card, t_VECSMALL); |
|
ltop=avma; |
|
gen = cgetg(lg(zn3), t_VECSMALL); |
|
ord = cgetg(lg(zn3), t_VECSMALL); |
|
sg[1] = 1; |
|
hnftogeneratorslist(n,zn2,zn3,lss,gen,ord); |
|
for (j = 1, l = 1; j < lg(gen); j++) |
|
{ |
|
int c = l * (ord[j] - 1); |
|
for (k = 1; k <= c; k++) /* I like it */ |
|
sg[++l] = mulssmod(sg[k], gen[j], n); |
|
} |
|
sortvecsmall(sg); |
|
avma=ltop; |
|
return sg; |
|
} |
|
|
|
/* |
/* |
* Calcule la liste des sous groupes de \ZZ/m\ZZ d'ordre divisant p et |
* Calcule la liste des sous groupes de (\ZZ/m\ZZ)^* d'ordre divisant p et |
* retourne la liste de leurs elements |
* retourne la liste de leurs elements |
*/ |
*/ |
GEN |
GEN |
listsousgroupes(long m, long p) |
listsousgroupes(long m, long p) |
{ |
{ |
ulong ltop = avma; |
gpmem_t ltop = avma; |
GEN zns, lss, sg, res, zn2, zn3; |
GEN zn, zns, lss, sg, res; |
int k, card, i, phi; |
int k, card, i, phi; |
if (m == 2) |
if (m == 2) |
{ |
{ |
Line 1304 listsousgroupes(long m, long p) |
|
Line 1173 listsousgroupes(long m, long p) |
|
sg[1] = 1; |
sg[1] = 1; |
return res; |
return res; |
} |
} |
zns = znstar(stoi(m)); |
zn = znstar(stoi(m)); |
phi = itos((GEN) zns[1]); |
phi = itos((GEN) zn[1]); |
zn2 = gtovecsmall((GEN)zns[2]); |
zns = znstar_small(zn); |
zn3 = lift((GEN)zns[3]); |
lss = subgrouplist((GEN) zn[2], NULL); |
lss = subgrouplist((GEN) zns[2], 0); |
|
res = cgetg(lg(lss), t_VEC); |
res = cgetg(lg(lss), t_VEC); |
for (k = 1, i = lg(lss) - 1; i >= 1; i--) |
for (k = 1, i = lg(lss) - 1; i >= 1; i--) |
{ |
{ |
long av; |
gpmem_t av; |
av = avma; |
av = avma; |
card = phi / itos(det((GEN) lss[i])); |
card = phi / itos(det((GEN) lss[i])); |
avma = av; |
avma = av; |
if (p % card == 0) |
if (p % card == 0) |
res[k++] = (long) hnftoelementslist(m,zn2,zn3,(GEN)lss[i],card); |
res[k++] = (long) znstar_hnf_elts(zns,(GEN)lss[i]); |
} |
} |
setlg(res,k); |
setlg(res,k); |
res=gen_sort(res,0,&pari_compare_lg); |
res=gen_sort(res,0,&pari_compare_lg); |
return gerepileupto(ltop,res); |
return gerepileupto(ltop,res); |
} |
} |
|
|
/* Compute the orbits decomposition of a permutation |
|
* or of a set of permutations given by a vector. |
|
* v must not be an empty vector, becaude there is no way then |
|
* to tell the length of the permutation. |
|
*/ |
|
|
|
GEN |
GEN |
permorbite(GEN v) |
|
{ |
|
ulong ltop = avma, lbot; |
|
int i, j, k, l, m, n, o, p, flag; |
|
GEN bit, cycle, cy, u; |
|
if (typ(v) == t_VECSMALL) |
|
{ |
|
u = cgetg(2, t_VEC); |
|
u[1] = (long) v; |
|
v = u; |
|
} |
|
n = lg(v[1]); |
|
cycle = cgetg(n, t_VEC); |
|
bit = cgetg(n, t_VECSMALL); |
|
for (i = 1; i < n; i++) |
|
bit[i] = 0; |
|
for (k = 1, l = 1; k < n;) |
|
{ |
|
for (j = 1; bit[j]; j++); |
|
cy = cgetg(n, t_VECSMALL); |
|
m = 1; |
|
cy[m++] = j; |
|
bit[j] = 1; |
|
k++; |
|
do |
|
{ |
|
flag = 0; |
|
for (o = 1; o < lg(v); o++) |
|
{ |
|
for (p = 1; p < m; p++) /* m varie! */ |
|
{ |
|
j = ((long **) v)[o][cy[p]]; |
|
if (!bit[j]) |
|
{ |
|
flag = 1; |
|
bit[j] = 1; |
|
k++; |
|
cy[m++] = j; |
|
} |
|
} |
|
} |
|
} |
|
while (flag); |
|
setlg(cy, m); |
|
cycle[l++] = (long) cy; |
|
} |
|
setlg(cycle, l); |
|
lbot = avma; |
|
cycle = gcopy(cycle); |
|
return gerepile(ltop, lbot, cycle); |
|
} |
|
|
|
GEN |
|
fixedfieldpolsigma(GEN sigma, GEN p, GEN Tp, GEN sym, GEN deg, long g) |
fixedfieldpolsigma(GEN sigma, GEN p, GEN Tp, GEN sym, GEN deg, long g) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
long i, j, npows; |
long i, j, npows; |
GEN s, f, pows; |
GEN s, f, pows; |
sigma=lift(gmul(sigma,gmodulsg(1,p))); |
sigma=lift(gmul(sigma,gmodulsg(1,p))); |
Line 1418 fixedfieldfactmod(GEN Sp, GEN p, GEN Tmod) |
|
Line 1227 fixedfieldfactmod(GEN Sp, GEN p, GEN Tmod) |
|
long l=lg(Tmod); |
long l=lg(Tmod); |
GEN F=cgetg(l,t_VEC); |
GEN F=cgetg(l,t_VEC); |
for(i=1;i<l;i++) |
for(i=1;i<l;i++) |
F[i]=(long)FpXQ_minpoly(Sp, (GEN) Tmod[i],p); |
F[i]=(long)FpXQ_minpoly(FpX_res(Sp,(GEN) Tmod[i],p), (GEN) Tmod[i],p); |
return F; |
return F; |
} |
} |
|
|
GEN |
GEN |
fixedfieldnewtonsumaut(GEN sigma, GEN p, GEN Tp, GEN e, long g) |
fixedfieldnewtonsumaut(GEN sigma, GEN p, GEN Tp, GEN e, long g) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
long i; |
long i; |
GEN s,f,V; |
GEN s,f,V; |
long rt; |
long rt; |
Line 1453 fixedfieldnewtonsum(GEN O, GEN L, GEN mod, GEN e) |
|
Line 1262 fixedfieldnewtonsum(GEN O, GEN L, GEN mod, GEN e) |
|
PL=cgetg(lg(O), t_COL); |
PL=cgetg(lg(O), t_COL); |
for(i=1; i<=f; i++) |
for(i=1; i<=f; i++) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
GEN s=gzero; |
GEN s=gzero; |
for(j=1; j<=g; j++) |
for(j=1; j<=g; j++) |
s=addii(s,powmodulo((GEN)L[mael(O,i,j)],e,mod)); |
s=addii(s,powmodulo((GEN)L[mael(O,i,j)],e,mod)); |
Line 1465 fixedfieldnewtonsum(GEN O, GEN L, GEN mod, GEN e) |
|
Line 1274 fixedfieldnewtonsum(GEN O, GEN L, GEN mod, GEN e) |
|
GEN |
GEN |
fixedfieldpol(GEN O, GEN L, GEN mod, GEN sym, GEN deg) |
fixedfieldpol(GEN O, GEN L, GEN mod, GEN sym, GEN deg) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
long i; |
long i; |
GEN S=gzero; |
GEN S=gzero; |
for(i=1;i<lg(sym);i++) |
for(i=1;i<lg(sym);i++) |
Line 1531 fixedfieldsurmer(GEN O, GEN L, GEN mod, GEN l, GEN p, |
|
Line 1340 fixedfieldsurmer(GEN O, GEN L, GEN mod, GEN l, GEN p, |
|
long k; |
long k; |
if (fixedfieldtest(V)) |
if (fixedfieldtest(V)) |
{ |
{ |
ulong av=avma; |
gpmem_t av=avma; |
GEN s=fixedfieldpol(O,L,mod,S,deg); |
GEN s=fixedfieldpol(O,L,mod,S,deg); |
GEN P=FpV_roots_to_pol(s,mod,v); |
GEN P=FpV_roots_to_pol(s,mod,v); |
P=FpX_center(P,mod); |
P=FpX_center(P,mod); |
Line 1567 fixedfieldsurmer(GEN O, GEN L, GEN mod, GEN l, GEN p, |
|
Line 1376 fixedfieldsurmer(GEN O, GEN L, GEN mod, GEN l, GEN p, |
|
GEN |
GEN |
fixedfieldsympol(GEN O, GEN L, GEN mod, GEN l, GEN p, GEN S, GEN deg, long v) |
fixedfieldsympol(GEN O, GEN L, GEN mod, GEN l, GEN p, GEN S, GEN deg, long v) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
GEN V=NULL; |
GEN V=NULL; |
GEN LN=cgetg(lg(L),t_VEC); |
GEN LN=cgetg(lg(L),t_VEC); |
GEN Ll=FpV_red(L,l); |
GEN Ll=FpV_red(L,l); |
Line 1624 fixedfieldinclusion(GEN O, GEN PL) |
|
Line 1433 fixedfieldinclusion(GEN O, GEN PL) |
|
GEN |
GEN |
vandermondeinversemod(GEN L, GEN T, GEN den, GEN mod) |
vandermondeinversemod(GEN L, GEN T, GEN den, GEN mod) |
{ |
{ |
ulong av; |
gpmem_t av; |
int i, j, n = lg(L); |
int i, j, n = lg(L); |
long x = varn(T); |
long x = varn(T); |
GEN M, P, Tp; |
GEN M, P, Tp; |
Line 1651 vandermondeinversemod(GEN L, GEN T, GEN den, GEN mod) |
|
Line 1460 vandermondeinversemod(GEN L, GEN T, GEN den, GEN mod) |
|
static GEN |
static GEN |
vectopol(GEN v, GEN M, GEN den , GEN mod, long x) |
vectopol(GEN v, GEN M, GEN den , GEN mod, long x) |
{ |
{ |
long n = lg(v),i,k,av; |
long n = lg(v), i, k; |
|
gpmem_t av; |
GEN z = cgetg(n+1,t_POL),p1,p2,mod2; |
GEN z = cgetg(n+1,t_POL),p1,p2,mod2; |
av=avma; |
av=avma; |
mod2=gclone(shifti(mod,-1));/*clone*/ |
mod2=gclone(shifti(mod,-1));/*clone*/ |
Line 1677 vectopol(GEN v, GEN M, GEN den , GEN mod, long x) |
|
Line 1487 vectopol(GEN v, GEN M, GEN den , GEN mod, long x) |
|
static GEN |
static GEN |
permtopol(GEN p, GEN L, GEN M, GEN den, GEN mod, long x) |
permtopol(GEN p, GEN L, GEN M, GEN den, GEN mod, long x) |
{ |
{ |
long n = lg(L),i,k,av; |
long n = lg(L), i, k; |
|
gpmem_t av; |
GEN z = cgetg(n+1,t_POL),p1,p2,mod2; |
GEN z = cgetg(n+1,t_POL),p1,p2,mod2; |
if (lg(p) != n) err(talker,"incorrect permutation in permtopol"); |
if (lg(p) != n) err(talker,"incorrect permutation in permtopol"); |
av=avma; |
av=avma; |
Line 1714 galoisgrouptopol( GEN res, GEN L, GEN M, GEN den, GEN |
|
Line 1525 galoisgrouptopol( GEN res, GEN L, GEN M, GEN den, GEN |
|
} |
} |
return aut; |
return aut; |
} |
} |
/* No more used and ugly. |
|
* However adding corepartial to GP seem a good idea. |
|
* |
|
* factorise partiellement n sous la forme n=d*u*f^2 ou d est un |
|
* discriminant fondamental et u n'est pas un carre parfait et |
|
* retourne u*f |
|
* Note: Parfois d n'est pas un discriminant (congru a 3 mod 4). |
|
* Cela se produit si u est congrue a 3 mod 4. |
|
*/ |
|
GEN |
|
corediscpartial(GEN n) |
|
{ |
|
ulong av = avma; |
|
long i,r,s; |
|
GEN fa, p1, p2, p3, res = gun, res2 = gun, res3=gun; |
|
/*d=res,f=res2,u=res3*/ |
|
if (gcmp1(n)) |
|
return gun; |
|
fa = auxdecomp(n, 0); |
|
p1 = (GEN) fa[1]; |
|
p2 = (GEN) fa[2]; |
|
for (i = 1; i < lg(p1) - 1; i++) |
|
{ |
|
p3 = (GEN) p2[i]; |
|
if (mod2(p3)) |
|
res = mulii(res, (GEN) p1[i]); |
|
if (!gcmp1(p3)) |
|
res2 = mulii(res2, gpow((GEN) p1[i], shifti(p3, -1), 0)); |
|
} |
|
p3 = (GEN) p2[i]; |
|
if (mod2(p3)) /* impaire: verifions */ |
|
{ |
|
if (!gcmp1(p3)) |
|
res2 = mulii(res2, gpow((GEN) p1[i], shifti(p3, -1), 0)); |
|
if (isprime((GEN) p1[i])) |
|
res = mulii(res, (GEN) p1[i]); |
|
else |
|
res3 = (GEN)p1[i]; |
|
} |
|
else /* paire:OK */ |
|
res2 = mulii(res2, gpow((GEN) p1[i], shifti(p3, -1), 0)); |
|
r = mod4(res); |
|
if (signe(res) < 0) |
|
r = 4 - r; |
|
s = mod4(res3);/*res2 est >0*/ |
|
if (r == 3 && s!=3) |
|
/*d est n'est pas un discriminant mais res2 l'est: corrige*/ |
|
res2 = gmul2n((GEN) res2, -1); |
|
return gerepileupto(av,gmul(res2,res3)); |
|
} |
|
GEN respm(GEN x,GEN y,GEN pm); |
|
GEN ZX_disc(GEN x); |
|
|
|
GEN |
|
indexpartial(GEN P, GEN DP) |
|
{ |
|
ulong av = avma; |
|
long i, nb; |
|
GEN fa, p1, res = gun, dP; |
|
dP = derivpol(P); |
|
if(DEBUGLEVEL>=5) gentimer(3); |
|
if(!DP) DP = ZX_disc(P); |
|
DP = mpabs(DP); |
|
if(DEBUGLEVEL>=5) genmsgtimer(3,"IndexPartial: discriminant"); |
|
fa = auxdecomp(DP, 0); |
|
if(DEBUGLEVEL>=5) genmsgtimer(3,"IndexPartial: factorization"); |
|
nb = lg(fa[1]); |
|
for (i = 1; i < nb; i++) |
|
{ |
|
GEN p=gmael(fa,1,i); |
|
GEN e=gmael(fa,2,i); |
|
p1 = powgi(p,shifti(e,-1)); |
|
if ( i==nb-1 ) |
|
{ |
|
if ( mod2(e) && !isprime(p) ) |
|
p1 = mulii(p1,p); |
|
} |
|
else if ( cmpis(e,4)>=0 ) |
|
{ |
|
if(DEBUGLEVEL>=5) fprintferr("IndexPartial: factor %Z ",p1); |
|
p1 = mppgcd(p1, respm(P,dP,p1)); |
|
if(DEBUGLEVEL>=5) |
|
{ |
|
fprintferr("--> %Z : ",p1); |
|
genmsgtimer(3,""); |
|
} |
|
} |
|
res=mulii(res,p1); |
|
} |
|
return gerepileupto(av,res); |
|
} |
|
|
|
/* Calcule la puissance exp d'une permutation decompose en cycle */ |
|
GEN |
|
permcyclepow(GEN O, long exp) |
|
{ |
|
int j, k, n; |
|
GEN p; |
|
for (n = 0, j = 1; j < lg(O); j++) |
|
n += lg(O[j]) - 1; |
|
p = cgetg(n + 1, t_VECSMALL); |
|
for (j = 1; j < lg(O); j++) |
|
{ |
|
n = lg(O[j]) - 1; |
|
for (k = 1; k <= n; k++) |
|
p[mael(O,j,k)] = mael(O,j,1 + (k + exp - 1) % n); |
|
} |
|
return p; |
|
} |
|
|
|
/* |
/* |
* Casse l'orbite O en sous-orbite d'ordre premier correspondant a des |
* Casse l'orbite O en sous-orbite d'ordre premier correspondant a des |
* puissance de l'element |
* puissance de l'element |
Line 1831 permcyclepow(GEN O, long exp) |
|
Line 1533 permcyclepow(GEN O, long exp) |
|
GEN |
GEN |
splitorbite(GEN O) |
splitorbite(GEN O) |
{ |
{ |
ulong ltop = avma, lbot; |
gpmem_t lbot, ltop = avma; |
int i, n; |
int i, n; |
GEN F, fc, res; |
GEN fc, res; |
n = lg(O[1]) - 1; |
n = lg(O[1]) - 1; |
F = factor(stoi(n)); |
fc = decomp_primary_small(n); |
fc = cgetg(lg(F[1]), t_VECSMALL); |
|
for (i = 1; i < lg(fc); i++) |
|
fc[i] = itos(powgi(gmael(F,1,i), gmael(F,2,i))); |
|
lbot = avma; |
lbot = avma; |
res = cgetg(3, t_VEC); |
res = cgetg(3, t_VEC); |
res[1] = lgetg(lg(fc), t_VEC); |
res[1] = lgetg(lg(fc), t_VEC); |
res[2] = lgetg(lg(fc), t_VECSMALL); |
res[2] = lgetg(lg(fc), t_VECSMALL); |
for (i = 1; i < lg(fc); i++) |
for (i = 1; i < lg(fc); i++) |
{ |
{ |
((GEN **) res)[1][lg(fc) - i] = permcyclepow(O, n / fc[i]); |
mael(res,1,lg(fc) - i) = (long)cyc_powtoperm(O, n / fc[i]); |
((GEN *) res)[2][lg(fc) - i] = fc[i]; |
mael(res,2,lg(fc) - i) = fc[i]; |
} |
} |
if ( DEBUGLEVEL>=4 ) |
if ( DEBUGLEVEL>=4 ) |
fprintferr("GaloisConj:splitorbite: %Z\n",res); |
fprintferr("GaloisConj:splitorbite: %Z\n",res); |
Line 1863 splitorbite(GEN O) |
|
Line 1562 splitorbite(GEN O) |
|
* modulo l ppp: plus petit diviseur premier du degre de T. primepointer: |
* modulo l ppp: plus petit diviseur premier du degre de T. primepointer: |
* permet de calculer les premiers suivant p. |
* permet de calculer les premiers suivant p. |
*/ |
*/ |
|
enum ga_code {ga_all_normal=1,ga_ext_2=2,ga_non_wss=4}; |
struct galois_analysis |
struct galois_analysis |
{ |
{ |
long p; |
long p; |
Line 1871 struct galois_analysis |
|
Line 1571 struct galois_analysis |
|
long l; |
long l; |
long ppp; |
long ppp; |
long p4; |
long p4; |
enum {ga_all_normal=1,ga_ext_2=2,ga_non_wss=4} group; |
enum ga_code group; |
byteptr primepointer; |
byteptr primepointer; |
}; |
}; |
void |
void |
galoisanalysis(GEN T, struct galois_analysis *ga, long calcul_l, long karma_type) |
galoisanalysis(GEN T, struct galois_analysis *ga, long calcul_l, long karma_type) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
long n,p; |
long n,p; |
long i; |
long i; |
enum {k_amoeba=0,k_snake=1,k_fish=2,k_bird=4,k_rodent=6,k_dog=8,k_human=9,k_cat=12} karma; |
enum k_code {k_amoeba=0,k_snake=1,k_fish=2,k_bird=4,k_rodent=6,k_dog=8,k_human=9,k_cat=12} karma; |
long group,linf; |
long group,linf; |
/*TODO: complete the table to at least 200*/ |
/*TODO: complete the table to at least 200*/ |
const int prim_nonss_orders[]={36,48,56,60,72,75,80,96,108,120,132,0}; |
const int prim_nonss_orders[]={36,48,56,60,72,75,80,96,108,120,132,0}; |
GEN F,Fp,Fe,Fpe,O; |
GEN F,Fp,Fe,Fpe,O; |
long np; |
long min_prime,np; |
long order,phi_order; |
long order,phi_order; |
long plift,nbmax,nbtest,deg; |
long plift,nbmax,nbtest,deg; |
byteptr primepointer,pp; |
byteptr primepointer,pp; |
if (DEBUGLEVEL >= 1) |
|
timer2(); |
if (!ZX_is_squarefree(T)) |
|
err(talker, "Polynomial not squarefree in galoisinit"); |
|
if (DEBUGLEVEL >= 1) (void)timer2(); |
n = degpol(T); |
n = degpol(T); |
if (!karma_type) karma_type=n; |
if (!karma_type) karma_type=n; |
else err(warner,"entering black magic computation"); |
else err(warner,"entering black magic computation"); |
Line 1939 galoisanalysis(GEN T, struct galois_analysis *ga, long |
|
Line 1641 galoisanalysis(GEN T, struct galois_analysis *ga, long |
|
break; |
break; |
} |
} |
/*Now, we study the orders of the Frobenius elements*/ |
/*Now, we study the orders of the Frobenius elements*/ |
|
min_prime=n*max((long)(BITS_IN_LONG-bfffo(n)-4),2); |
plift = 0; |
plift = 0; |
nbmax = 8+(n>>1); |
nbmax = 8+(n>>1); |
nbtest = 0; karma = k_amoeba; |
nbtest = 0; karma = k_amoeba; |
Line 1950 galoisanalysis(GEN T, struct galois_analysis *ga, long |
|
Line 1653 galoisanalysis(GEN T, struct galois_analysis *ga, long |
|
|| ((group&ga_non_wss) && order == Fp[np])) |
|| ((group&ga_non_wss) && order == Fp[np])) |
&& (nbtest < 3 * nbmax || !(group&ga_non_wss)) ;) |
&& (nbtest < 3 * nbmax || !(group&ga_non_wss)) ;) |
{ |
{ |
ulong av; |
gpmem_t av; |
long prime_incr; |
|
GEN ip,FS,p1; |
GEN ip,FS,p1; |
long o,norm_o=1; |
long o,norm_o=1; |
prime_incr = *primepointer++; |
|
if (!prime_incr) |
NEXT_PRIME_VIADIFF_CHECK(p,primepointer); |
err(primer1); |
|
p += prime_incr; |
|
/*discard small primes*/ |
/*discard small primes*/ |
if (p <= (n << 1)) |
if (p <= min_prime) |
continue; |
continue; |
ip=stoi(p); |
ip=stoi(p); |
if (!FpX_is_squarefree(T,ip)) |
if (!FpX_is_squarefree(T,ip)) |
Line 2011 galoisanalysis(GEN T, struct galois_analysis *ga, long |
|
Line 1711 galoisanalysis(GEN T, struct galois_analysis *ga, long |
|
deg = norm_o; |
deg = norm_o; |
order = o; |
order = o; |
plift = p; |
plift = p; |
karma=cgcd(p-1,karma_type); |
karma=(enum k_code)cgcd(p-1,karma_type); |
pp = primepointer; |
pp = primepointer; |
group |= ga_all_normal; |
group |= ga_all_normal; |
} |
} |
Line 2021 galoisanalysis(GEN T, struct galois_analysis *ga, long |
|
Line 1721 galoisanalysis(GEN T, struct galois_analysis *ga, long |
|
{ |
{ |
order = o; |
order = o; |
plift = p; |
plift = p; |
karma=cgcd(p-1,karma_type); |
karma=(enum k_code)cgcd(p-1,karma_type); |
pp = primepointer; |
pp = primepointer; |
} |
} |
} |
} |
Line 2042 galoisanalysis(GEN T, struct galois_analysis *ga, long |
|
Line 1742 galoisanalysis(GEN T, struct galois_analysis *ga, long |
|
linf=n; |
linf=n; |
if (calcul_l && O[1]<=linf) |
if (calcul_l && O[1]<=linf) |
{ |
{ |
ulong av; |
gpmem_t av; |
long prime_incr; |
|
long l=0; |
long l=0; |
/*we need a totally splited prime l*/ |
/*we need a totally splited prime l*/ |
av = avma; |
av = avma; |
while (l == 0) |
while (l == 0) |
{ |
{ |
long nb; |
long nb; |
prime_incr = *primepointer++; |
|
if (!prime_incr) |
NEXT_PRIME_VIADIFF_CHECK(p,primepointer); |
err(primer1); |
|
p += prime_incr; |
|
if (p<=linf) continue; |
if (p<=linf) continue; |
nb=FpX_nbroots(T,stoi(p)); |
nb=FpX_nbroots(T,stoi(p)); |
if (nb == n) |
if (nb == n) |
Line 2072 galoisanalysis(GEN T, struct galois_analysis *ga, long |
|
Line 1769 galoisanalysis(GEN T, struct galois_analysis *ga, long |
|
O[1]=l; |
O[1]=l; |
} |
} |
ga->p = plift; |
ga->p = plift; |
ga->group = group; |
ga->group = (enum ga_code)group; |
ga->deg = deg; |
ga->deg = deg; |
ga->ord = order; |
ga->ord = order; |
ga->l = O[1]; |
ga->l = O[1]; |
Line 2091 galoisanalysis(GEN T, struct galois_analysis *ga, long |
|
Line 1788 galoisanalysis(GEN T, struct galois_analysis *ga, long |
|
GEN |
GEN |
a4galoisgen(GEN T, struct galois_test *td) |
a4galoisgen(GEN T, struct galois_test *td) |
{ |
{ |
ulong ltop = avma, av, av2; |
gpmem_t ltop = avma, av, av2; |
long i, j, k; |
long i, j, k; |
long n; |
long n; |
long N, hop = 0; |
long N, hop = 0; |
Line 2354 a4galoisgen(GEN T, struct galois_test *td) |
|
Line 2051 a4galoisgen(GEN T, struct galois_test *td) |
|
orb[2] = (long) pfu; |
orb[2] = (long) pfu; |
if (DEBUGLEVEL >= 4) |
if (DEBUGLEVEL >= 4) |
fprintferr("A4GaloisConj:orb=%Z \n", orb); |
fprintferr("A4GaloisConj:orb=%Z \n", orb); |
O = (long**)permorbite(orb); |
O = (long**) vecperm_orbits(orb, 12); |
if (DEBUGLEVEL >= 4) |
if (DEBUGLEVEL >= 4) |
fprintferr("A4GaloisConj:O=%Z \n", O); |
fprintferr("A4GaloisConj:O=%Z \n", O); |
av2 = avma; |
av2 = avma; |
Line 2437 s4makelift(GEN u, struct galois_lift *gl, GEN liftpow) |
|
Line 2134 s4makelift(GEN u, struct galois_lift *gl, GEN liftpow) |
|
static long |
static long |
s4test(GEN u, GEN liftpow, struct galois_lift *gl, GEN phi) |
s4test(GEN u, GEN liftpow, struct galois_lift *gl, GEN phi) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
GEN res; |
GEN res; |
int bl,i,d = lgef(u)-2; |
int bl,i,d = lgef(u)-2; |
if (DEBUGLEVEL >= 6) |
if (DEBUGLEVEL >= 6) (void)timer2(); |
timer2(); |
|
if ( !d ) return 0; |
if ( !d ) return 0; |
res=(GEN)u[2]; |
res=(GEN)u[2]; |
for (i = 1; i < d; i++) |
for (i = 1; i < d; i++) |
Line 2473 s4test(GEN u, GEN liftpow, struct galois_lift *gl, GEN |
|
Line 2169 s4test(GEN u, GEN liftpow, struct galois_lift *gl, GEN |
|
static GEN |
static GEN |
s4releveauto(GEN misom,GEN Tmod,GEN Tp,GEN p,long a1,long a2,long a3,long a4,long a5,long a6) |
s4releveauto(GEN misom,GEN Tmod,GEN Tp,GEN p,long a1,long a2,long a3,long a4,long a5,long a6) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
GEN u1,u2,u3,u4,u5; |
GEN u1,u2,u3,u4,u5; |
GEN pu1,pu2,pu3,pu4; |
GEN pu1,pu2,pu3,pu4; |
pu1=FpX_mul( (GEN) Tmod[a2], (GEN) Tmod[a1],p); |
pu1=FpX_mul( (GEN) Tmod[a2], (GEN) Tmod[a1],p); |
|
|
s4galoisgen(struct galois_lift *gl) |
s4galoisgen(struct galois_lift *gl) |
{ |
{ |
struct galois_testlift gt; |
struct galois_testlift gt; |
ulong ltop = avma, av, ltop2; |
gpmem_t av, ltop2, ltop = avma; |
GEN Tmod, isom, isominv, misom; |
GEN Tmod, isom, isominv, misom; |
int i, j; |
int i, j; |
GEN sg; |
GEN sg; |
Line 2554 s4galoisgen(struct galois_lift *gl) |
|
Line 2250 s4galoisgen(struct galois_lift *gl) |
|
av = avma; |
av = avma; |
for (i = 0; i < 3; i++) |
for (i = 0; i < 3; i++) |
{ |
{ |
ulong av2; |
gpmem_t av2, avm1, avm2; |
GEN u; |
GEN u; |
int j1, j2, j3; |
int j1, j2, j3; |
ulong avm1, avm2; |
|
GEN u1, u2, u3; |
GEN u1, u2, u3; |
if (i) |
if (i) |
{ |
{ |
|
|
avma = av; |
avma = av; |
for (j = 1; j <= 3; j++) |
for (j = 1; j <= 3; j++) |
{ |
{ |
ulong av2; |
gpmem_t av2; |
GEN u; |
GEN u; |
int w, l; |
int w, l; |
int z; |
int z; |
|
|
av2 = avma; |
av2 = avma; |
for (w = 0; w < 4; w += 2) |
for (w = 0; w < 4; w += 2) |
{ |
{ |
|
gpmem_t av3; |
GEN uu; |
GEN uu; |
long av3; |
|
pj[6] = (w + pj[3]) & 3; |
pj[6] = (w + pj[3]) & 3; |
uu =FpX_add(FpXQ_mul((GEN) bezoutcoeff[sg[5]], |
uu =FpX_add(FpXQ_mul((GEN) bezoutcoeff[sg[5]], |
(GEN) pauto[(pj[6] & 3) + 1],TQ,Q), |
(GEN) pauto[(pj[6] & 3) + 1],TQ,Q), |
|
|
{ |
{ |
int abc, abcdef; |
int abc, abcdef; |
GEN u; |
GEN u; |
ulong av2; |
gpmem_t av2; |
abc = (pj[1] + pj[2] + pj[3]) & 3; |
abc = (pj[1] + pj[2] + pj[3]) & 3; |
abcdef = (((abc + pj[4] + pj[5] - pj[6]) & 3) >> 1); |
abcdef = (((abc + pj[4] + pj[5] - pj[6]) & 3) >> 1); |
u = s4releveauto(misom,Tmod,Tp,p,sg[1],sg[4],sg[2],sg[5],sg[3],sg[6]); |
u = s4releveauto(misom,Tmod,Tp,p,sg[1],sg[4],sg[2],sg[5],sg[3],sg[6]); |
Line 2744 struct galois_frobenius |
|
Line 2439 struct galois_frobenius |
|
static GEN |
static GEN |
galoisfindgroups(GEN lo, GEN sg, long f) |
galoisfindgroups(GEN lo, GEN sg, long f) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
GEN V,W; |
GEN V,W; |
long i,j,k; |
long i,j,k; |
V=cgetg(lg(lo),t_VEC); |
V=cgetg(lg(lo),t_VEC); |
for(j=1,i=1;i<lg(lo);i++) |
for(j=1,i=1;i<lg(lo);i++) |
{ |
{ |
ulong av=avma; |
gpmem_t av=avma; |
GEN U; |
GEN U; |
W=cgetg(lg(lo[i]),t_VECSMALL); |
W=cgetg(lg(lo[i]),t_VECSMALL); |
for(k=1;k<lg(lo[i]);k++) |
for(k=1;k<lg(lo[i]);k++) |
W[k]=mael(lo,i,k)%f; |
W[k]=mael(lo,i,k)%f; |
sortvecsmall(W); |
vecsmall_sort(W); |
U=uniqvecsmall(W); |
U=vecsmall_uniq(W); |
if (gegal(U, sg)) |
if (gegal(U, sg)) |
{ |
{ |
cgiv(U); |
cgiv(U); |
Line 2773 galoisfindgroups(GEN lo, GEN sg, long f) |
|
Line 2468 galoisfindgroups(GEN lo, GEN sg, long f) |
|
static long |
static long |
galoisfrobeniustest(GEN aut, struct galois_lift *gl, GEN frob) |
galoisfrobeniustest(GEN aut, struct galois_lift *gl, GEN frob) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop = avma; |
GEN tlift = FpX_center(FpX_Fp_mul(aut,gl->den,gl->Q), gl->Q); |
GEN tlift = FpX_center(FpX_Fp_mul(aut,gl->den,gl->Q), gl->Q); |
long res=poltopermtest(tlift, gl, frob); |
long res = poltopermtest(tlift, gl, frob); |
avma=ltop; |
avma = ltop; |
return res; |
return res; |
} |
} |
|
|
static GEN |
static GEN |
galoismakepsiab(long g) |
|
{ |
|
GEN psi=cgetg(g+1,t_VECSMALL); |
|
long i; |
|
for (i = 1; i <= g; i++) |
|
psi[i] = 1; |
|
return psi; |
|
} |
|
|
|
static GEN |
|
galoismakepsi(long g, GEN sg, GEN pf) |
galoismakepsi(long g, GEN sg, GEN pf) |
{ |
{ |
GEN psi=cgetg(g+1,t_VECSMALL); |
GEN psi=cgetg(g+1,t_VECSMALL); |
Line 2802 galoismakepsi(long g, GEN sg, GEN pf) |
|
Line 2487 galoismakepsi(long g, GEN sg, GEN pf) |
|
} |
} |
|
|
static GEN |
static GEN |
galoisfrobeniuslift(GEN T, GEN den, GEN L, GEN Lden, long gmask, |
galoisfrobeniuslift(GEN T, GEN den, GEN L, GEN Lden, |
struct galois_frobenius *gf, struct galois_borne *gb) |
struct galois_frobenius *gf, struct galois_borne *gb) |
{ |
{ |
ulong ltop=avma,av2; |
gpmem_t ltop=avma, av2; |
struct galois_testlift gt; |
struct galois_testlift gt; |
struct galois_lift gl; |
struct galois_lift gl; |
GEN res; |
GEN res; |
Line 2816 galoisfrobeniuslift(GEN T, GEN den, GEN L, GEN Lden, |
|
Line 2501 galoisfrobeniuslift(GEN T, GEN den, GEN L, GEN Lden, |
|
if (DEBUGLEVEL >= 4) |
if (DEBUGLEVEL >= 4) |
fprintferr("GaloisConj:p=%ld deg=%ld fp=%ld\n", gf->p, deg, gf->fp); |
fprintferr("GaloisConj:p=%ld deg=%ld fp=%ld\n", gf->p, deg, gf->fp); |
res = cgetg(lg(L), t_VECSMALL); |
res = cgetg(lg(L), t_VECSMALL); |
gf->psi = galoismakepsiab(g); |
gf->psi = vecsmall_const(g,1); |
av2=avma; |
av2=avma; |
initlift(T, den, ip, L, Lden, gb, &gl); |
initlift(T, den, ip, L, Lden, gb, &gl); |
aut = galoisdolift(&gl, res); |
aut = galoisdolift(&gl, res); |
Line 2842 galoisfrobeniuslift(GEN T, GEN den, GEN L, GEN Lden, |
|
Line 2527 galoisfrobeniuslift(GEN T, GEN den, GEN L, GEN Lden, |
|
frob = cgetg(lg(L), t_VECSMALL); |
frob = cgetg(lg(L), t_VECSMALL); |
for(k=lg(Fp)-1;k>=1;k--) |
for(k=lg(Fp)-1;k>=1;k--) |
{ |
{ |
long btop=avma; |
gpmem_t btop=avma; |
GEN psi=NULL,fres=NULL,sg; |
GEN psi=NULL,fres=NULL,sg; |
long el=gf->fp, dg=1, dgf=1; |
long el=gf->fp, dg=1, dgf=1; |
long e,pr; |
long e,pr; |
sg=permidentity(1); |
sg=perm_identity(1); |
for(e=1;e<=Fe[k];e++) |
for(e=1;e<=Fe[k];e++) |
{ |
{ |
long l; |
long l; |
Line 2858 galoisfrobeniuslift(GEN T, GEN den, GEN L, GEN Lden, |
|
Line 2543 galoisfrobeniuslift(GEN T, GEN den, GEN L, GEN Lden, |
|
if (galoisfrobeniustest((GEN)gt.pauto[el+1],&gl,frob)) |
if (galoisfrobeniustest((GEN)gt.pauto[el+1],&gl,frob)) |
{ |
{ |
dgf = dg; |
dgf = dg; |
psi = galoismakepsiab(g); |
psi = vecsmall_const(g,1); |
fres= gcopy(frob); |
fres= gcopy(frob); |
continue; |
continue; |
} |
} |
Line 2891 galoisfrobeniuslift(GEN T, GEN den, GEN L, GEN Lden, |
|
Line 2576 galoisfrobeniuslift(GEN T, GEN den, GEN L, GEN Lden, |
|
} |
} |
else |
else |
{ |
{ |
GEN cp=permapply(res,fres); |
GEN cp=perm_mul(res,fres); |
for(i=1;i<lg(res);i++) res[i]=cp[i]; |
for(i=1;i<lg(res);i++) res[i]=cp[i]; |
for(i=1;i<lg(psi);i++) gf->psi[i]=(dgf*gf->psi[i]+deg*psi[i])%pr; |
for(i=1;i<lg(psi);i++) gf->psi[i]=(dgf*gf->psi[i]+deg*psi[i])%pr; |
} |
} |
Line 2913 galoisfrobeniuslift(GEN T, GEN den, GEN L, GEN Lden, |
|
Line 2598 galoisfrobeniuslift(GEN T, GEN den, GEN L, GEN Lden, |
|
{ |
{ |
/*We need to normalise result so that psi[g]=1*/ |
/*We need to normalise result so that psi[g]=1*/ |
long im=itos(mpinvmod(stoi(gf->psi[g]),stoi(gf->fp))); |
long im=itos(mpinvmod(stoi(gf->psi[g]),stoi(gf->fp))); |
GEN cp=permcyclepow(permorbite(res), im); |
GEN cp=perm_pow(res, im); |
for(i=1;i<lg(res);i++) res[i]=cp[i]; |
for(i=1;i<lg(res);i++) res[i]=cp[i]; |
for(i=1;i<lg(gf->psi);i++) gf->psi[i]=mulssmod(im,gf->psi[i],gf->fp); |
for(i=1;i<lg(gf->psi);i++) gf->psi[i]=mulssmod(im,gf->psi[i],gf->fp); |
avma=av2; |
avma=av2; |
Line 2923 galoisfrobeniuslift(GEN T, GEN den, GEN L, GEN Lden, |
|
Line 2608 galoisfrobeniuslift(GEN T, GEN den, GEN L, GEN Lden, |
|
} |
} |
|
|
static GEN |
static GEN |
galoisfindfrobenius(GEN T, GEN L, GEN M, GEN den, struct galois_frobenius *gf, |
galoisfindfrobenius(GEN T, GEN L, GEN den, struct galois_frobenius *gf, |
struct galois_borne *gb, const struct galois_analysis *ga) |
struct galois_borne *gb, const struct galois_analysis *ga) |
{ |
{ |
ulong ltop=avma,lbot; |
gpmem_t lbot, ltop=avma; |
long try=0; |
long Try=0; |
long n = degpol(T), deg, gmask; |
long n = degpol(T), deg, gmask; |
byteptr primepointer = ga->primepointer; |
byteptr primepointer = ga->primepointer; |
GEN Lden,frob; |
GEN Lden,frob; |
Line 2936 galoisfindfrobenius(GEN T, GEN L, GEN M, GEN den, stru |
|
Line 2621 galoisfindfrobenius(GEN T, GEN L, GEN M, GEN den, stru |
|
gmask=(ga->group&ga_ext_2)?3:1; |
gmask=(ga->group&ga_ext_2)?3:1; |
for (;;) |
for (;;) |
{ |
{ |
ulong av = avma; |
gpmem_t av = avma; |
long isram; |
long isram; |
long i,c; |
long i; |
GEN ip,Tmod; |
GEN ip,Tmod; |
ip = stoi(gf->p); |
ip = stoi(gf->p); |
Tmod = lift((GEN) factmod(T, ip)); |
Tmod = lift((GEN) factmod(T, ip)); |
Line 2959 galoisfindfrobenius(GEN T, GEN L, GEN M, GEN den, stru |
|
Line 2644 galoisfindfrobenius(GEN T, GEN L, GEN M, GEN den, stru |
|
gf->Tmod=gcopy((GEN)Tmod[1]); |
gf->Tmod=gcopy((GEN)Tmod[1]); |
if ( ((gmask&1) && gf->fp % deg == 0) || ((gmask&2) && gf->fp % 2== 0) ) |
if ( ((gmask&1) && gf->fp % deg == 0) || ((gmask&2) && gf->fp % 2== 0) ) |
{ |
{ |
frob=galoisfrobeniuslift(T, den, L, Lden, gmask, gf, gb); |
frob=galoisfrobeniuslift(T, den, L, Lden, gf, gb); |
if (frob) |
if (frob) |
{ |
{ |
GEN *gptr[3]; |
GEN *gptr[3]; |
Line 2978 galoisfindfrobenius(GEN T, GEN L, GEN M, GEN den, stru |
|
Line 2663 galoisfindfrobenius(GEN T, GEN L, GEN M, GEN den, stru |
|
avma = ltop; |
avma = ltop; |
return NULL; |
return NULL; |
} |
} |
try++; |
Try++; |
if ( (ga->group&ga_non_wss) && try > n ) |
if ( (ga->group&ga_non_wss) && Try > n ) |
err(warner, "galoisconj _may_ hang up for this polynomial"); |
err(warner, "galoisconj _may_ hang up for this polynomial"); |
} |
} |
} |
} |
c = *primepointer++; |
NEXT_PRIME_VIADIFF_CHECK(gf->p, primepointer); |
if (!c) |
|
err(primer1); |
|
gf->p += c; |
|
if (DEBUGLEVEL >= 4) |
if (DEBUGLEVEL >= 4) |
fprintferr("GaloisConj:next p=%ld\n", gf->p); |
fprintferr("GaloisConj:next p=%ld\n", gf->p); |
avma = av; |
avma = av; |
Line 2995 galoisfindfrobenius(GEN T, GEN L, GEN M, GEN den, stru |
|
Line 2677 galoisfindfrobenius(GEN T, GEN L, GEN M, GEN den, stru |
|
|
|
GEN |
GEN |
galoisgen(GEN T, GEN L, GEN M, GEN den, struct galois_borne *gb, |
galoisgen(GEN T, GEN L, GEN M, GEN den, struct galois_borne *gb, |
|
const struct galois_analysis *ga); |
|
static GEN |
|
galoisgenfixedfield(GEN Tp, GEN Pmod, GEN V, GEN ip, struct galois_borne *gb, GEN Pg) |
|
{ |
|
gpmem_t ltop=avma; |
|
GEN P, PL, Pden, PM, Pp, Pladicabs; |
|
GEN tau, PG; |
|
long g,gp; |
|
long x=varn(Tp); |
|
P=(GEN)V[2]; |
|
PL=(GEN)V[1]; |
|
gp=lg(Pmod)-1; |
|
Pp = FpX_red(P,ip); |
|
if (DEBUGLEVEL>=6) |
|
fprintferr("GaloisConj: Fixed field %Z\n",P); |
|
if (degpol(P)==2) |
|
{ |
|
PG=cgetg(3,t_VEC); |
|
PG[1]=lgetg(2,t_VEC); |
|
PG[2]=lgetg(2,t_VECSMALL); |
|
mael(PG,1,1)=lgetg(3,t_VECSMALL); |
|
mael(PG,2,1)=2; |
|
mael3(PG,1,1,1)=2; |
|
mael3(PG,1,1,2)=1; |
|
tau=deg1pol(stoi(-1),negi((GEN)P[3]),x); |
|
tau = lift(gmul(tau,gmodulcp(gun,ip))); |
|
tau = FpX_FpXQ_compo((GEN) Pmod[gp], tau,Pp,ip); |
|
tau = FpX_gcd(Pp, tau,ip); |
|
tau = FpX_Fp_mul(tau,mpinvmod((GEN) tau[lgef(tau) - 1],ip),ip); |
|
for (g = 1; g <= gp; g++) |
|
if (gegal(tau, (GEN) Pmod[g])) |
|
break; |
|
if (g == lg(Pmod)) |
|
return NULL; |
|
Pg[1]=g; |
|
} |
|
else |
|
{ |
|
struct galois_analysis Pga; |
|
struct galois_borne Pgb; |
|
long j; |
|
galoisanalysis(P, &Pga, 0, 0); |
|
if (Pga.deg == 0) |
|
return NULL; /* Avoid computing the discriminant */ |
|
Pgb.l = gb->l; |
|
Pden = galoisborne(P, NULL, &Pgb, Pga.ppp); |
|
Pladicabs=Pgb.ladicabs; |
|
if (Pgb.valabs > gb->valabs) |
|
{ |
|
if (DEBUGLEVEL>=4) |
|
fprintferr("GaloisConj:increase prec of p-adic roots of %ld.\n" |
|
,Pgb.valabs-gb->valabs); |
|
PL = rootpadicliftroots(P,PL,gb->l,Pgb.valabs); |
|
} |
|
PM = vandermondeinversemod(PL, P, Pden, Pgb.ladicabs); |
|
PG = galoisgen(P, PL, PM, Pden, &Pgb, &Pga); |
|
if (PG == gzero) return NULL; |
|
for (j = 1; j < lg(PG[1]); j++) |
|
{ |
|
gpmem_t btop=avma; |
|
tau = permtopol(gmael(PG,1,j), PL, PM, Pden, Pladicabs, x); |
|
tau = lift(gmul(tau,gmodulcp(gun,ip))); |
|
tau = FpX_FpXQ_compo((GEN) Pmod[gp], tau,Pp,ip); |
|
tau = FpX_gcd(Pp, tau,ip); |
|
tau = FpX_Fp_mul(tau,mpinvmod((GEN) tau[lgef(tau) - 1],ip),ip); |
|
for (g = 1; g < lg(Pmod); g++) |
|
if (gegal(tau, (GEN) Pmod[g])) |
|
break; |
|
if (g == lg(Pmod)) |
|
return NULL; |
|
avma=btop; |
|
Pg[j]=g; |
|
} |
|
} |
|
return gerepilecopy(ltop,PG); |
|
} |
|
|
|
GEN |
|
galoisgen(GEN T, GEN L, GEN M, GEN den, struct galois_borne *gb, |
const struct galois_analysis *ga) |
const struct galois_analysis *ga) |
{ |
{ |
struct galois_test td; |
struct galois_test td; |
struct galois_frobenius gf; |
struct galois_frobenius gf; |
ulong ltop = avma, lbot, ltop2; |
gpmem_t lbot, ltop2, ltop = avma; |
long n, p, deg; |
long n, p, deg; |
long fp,gp; |
long fp; |
long x; |
long x; |
int i, j; |
int i, j; |
GEN Lden, sigma; |
GEN Lden, sigma; |
GEN Tmod, res, pf = gzero, split, ip; |
GEN Tmod, res, pf = gzero, split, ip; |
GEN frob; |
GEN frob; |
GEN O; |
GEN O; |
GEN P, PG, PL, Pden, PM, Pmod, Pp, Pladicabs; |
GEN PG, Pg; |
n = degpol(T); |
n = degpol(T); |
if (!ga->deg) |
if (!ga->deg) |
return gzero; |
return gzero; |
Line 3017 galoisgen(GEN T, GEN L, GEN M, GEN den, struct galois_ |
|
Line 2778 galoisgen(GEN T, GEN L, GEN M, GEN den, struct galois_ |
|
fprintferr("GaloisConj:denominator:%Z\n", den); |
fprintferr("GaloisConj:denominator:%Z\n", den); |
if (n == 12 && ga->ord==3) /* A4 is very probable,so test it first */ |
if (n == 12 && ga->ord==3) /* A4 is very probable,so test it first */ |
{ |
{ |
long av = avma; |
gpmem_t av = avma; |
if (DEBUGLEVEL >= 4) |
if (DEBUGLEVEL >= 4) |
fprintferr("GaloisConj:Testing A4 first\n"); |
fprintferr("GaloisConj:Testing A4 first\n"); |
inittest(L, M, gb->bornesol, gb->ladicsol, &td); |
inittest(L, M, gb->bornesol, gb->ladicsol, &td); |
Line 3030 galoisgen(GEN T, GEN L, GEN M, GEN den, struct galois_ |
|
Line 2791 galoisgen(GEN T, GEN L, GEN M, GEN den, struct galois_ |
|
} |
} |
if (n == 24 && ga->ord==3) /* S4 is very probable,so test it first */ |
if (n == 24 && ga->ord==3) /* S4 is very probable,so test it first */ |
{ |
{ |
long av = avma; |
gpmem_t av = avma; |
struct galois_lift gl; |
struct galois_lift gl; |
if (DEBUGLEVEL >= 4) |
if (DEBUGLEVEL >= 4) |
fprintferr("GaloisConj:Testing S4 first\n"); |
fprintferr("GaloisConj:Testing S4 first\n"); |
Line 3042 galoisgen(GEN T, GEN L, GEN M, GEN den, struct galois_ |
|
Line 2803 galoisgen(GEN T, GEN L, GEN M, GEN den, struct galois_ |
|
return gerepile(ltop, lbot, PG); |
return gerepile(ltop, lbot, PG); |
avma = av; |
avma = av; |
} |
} |
frob=galoisfindfrobenius(T, L, M, den, &gf, gb, ga); |
frob=galoisfindfrobenius(T, L, den, &gf, gb, ga); |
if (!frob) |
if (!frob) |
{ |
{ |
ltop=avma; |
ltop=avma; |
return gzero; |
return gzero; |
} |
} |
p=gf.p;deg=gf.deg; |
p=gf.p; |
ip=stoi(p); |
ip=stoi(p); |
Tmod=gf.Tmod; |
Tmod=gf.Tmod; |
fp=gf.fp; gp=n/fp; |
fp=gf.fp; |
O = permorbite(frob); |
O = perm_cycles(frob); |
split = splitorbite(O); |
split = splitorbite(O); |
deg=lg(O[1])-1; |
deg=lg(O[1])-1; |
sigma = permtopol(frob, L, M, den, gb->ladicabs, x); |
sigma = permtopol(frob, L, M, den, gb->ladicabs, x); |
Line 3073 galoisgen(GEN T, GEN L, GEN M, GEN den, struct galois_ |
|
Line 2834 galoisgen(GEN T, GEN L, GEN M, GEN den, struct galois_ |
|
} |
} |
if (DEBUGLEVEL >= 9) |
if (DEBUGLEVEL >= 9) |
fprintferr("GaloisConj:Frobenius:%Z\n", sigma); |
fprintferr("GaloisConj:Frobenius:%Z\n", sigma); |
|
Pg=cgetg(lg(O),t_VECSMALL); |
{ |
{ |
GEN V, Tp, Sp, sym, dg; |
gpmem_t btop=avma; |
|
GEN V, sym, dg, Tp, Sp, Pmod; |
sym=cgetg(lg(L),t_VECSMALL); |
sym=cgetg(lg(L),t_VECSMALL); |
dg=cgetg(lg(L),t_VECSMALL); |
dg=cgetg(lg(L),t_VECSMALL); |
V = fixedfieldsympol(O, L, gb->ladicabs, gb->l, ip, sym, dg, x); |
V = fixedfieldsympol(O, L, gb->ladicabs, gb->l, ip, sym, dg, x); |
P=(GEN)V[2]; |
|
PL=(GEN)V[1]; |
|
Tp = FpX_red(T,ip); |
Tp = FpX_red(T,ip); |
Sp = fixedfieldpolsigma(sigma,ip,Tp,sym,dg,deg); |
Sp = fixedfieldpolsigma(sigma,ip,Tp,sym,dg,deg); |
Pmod = fixedfieldfactmod(Sp,ip,Tmod); |
Pmod = fixedfieldfactmod(Sp,ip,Tmod); |
Pp = FpX_red(P,ip); |
PG=galoisgenfixedfield(Tp, Pmod, V, ip, gb, Pg); |
if (DEBUGLEVEL >= 4) |
if (PG == NULL) |
{ |
{ |
fprintferr("GaloisConj:P=%Z \n", P); |
avma = ltop; |
fprintferr("GaloisConj:psi=%Z\n", gf.psi); |
return gzero; |
fprintferr("GaloisConj:Sp=%Z\n", Sp); |
|
fprintferr("GaloisConj:Pmod=%Z\n", Pmod); |
|
fprintferr("GaloisConj:Tmod=%Z\n", Tmod); |
|
} |
} |
if ( n == (deg<<1)) |
if (DEBUGLEVEL >= 4) |
{ |
fprintferr("GaloisConj:Back to Earth:%Z\n", PG); |
PG=cgetg(3,t_VEC); |
PG=gerepileupto(btop, PG); |
PG[1]=lgetg(2,t_VEC); |
|
PG[2]=lgetg(2,t_VECSMALL); |
|
mael(PG,1,1)=lgetg(3,t_VECSMALL); |
|
mael(PG,2,1)=2; |
|
mael3(PG,1,1,1)=2; |
|
mael3(PG,1,1,2)=1; |
|
Pden=NULL; PM=NULL; Pladicabs=NULL;/*make KB happy*/ |
|
} |
|
else |
|
{ |
|
struct galois_analysis Pga; |
|
struct galois_borne Pgb; |
|
galoisanalysis(P, &Pga, 0, 0); |
|
if (Pga.deg == 0) |
|
{ |
|
avma = ltop; |
|
return gzero; /* Avoid computing the discriminant */ |
|
} |
|
Pgb.l = gb->l; |
|
Pden = galoisborne(P, NULL, &Pgb, Pga.ppp); |
|
Pladicabs=Pgb.ladicabs; |
|
if (Pgb.valabs > gb->valabs) |
|
{ |
|
if (DEBUGLEVEL>=4) |
|
fprintferr("GaloisConj:increase prec of p-adic roots of %ld.\n" |
|
,Pgb.valabs-gb->valabs); |
|
PL = rootpadicliftroots(P,PL,gb->l,Pgb.valabs); |
|
} |
|
PM = vandermondeinversemod(PL, P, Pden, Pgb.ladicabs); |
|
PG = galoisgen(P, PL, PM, Pden, &Pgb, &Pga); |
|
} |
|
} |
} |
if (DEBUGLEVEL >= 4) |
|
fprintferr("GaloisConj:Retour sur Terre:%Z\n", PG); |
|
if (PG == gzero) |
|
{ |
|
avma = ltop; |
|
return gzero; |
|
} |
|
inittest(L, M, gb->bornesol, gb->ladicsol, &td); |
inittest(L, M, gb->bornesol, gb->ladicsol, &td); |
lbot = avma; |
lbot = avma; |
res = cgetg(3, t_VEC); |
res = cgetg(3, t_VEC); |
Line 3149 galoisgen(GEN T, GEN L, GEN M, GEN den, struct galois_ |
|
Line 2869 galoisgen(GEN T, GEN L, GEN M, GEN den, struct galois_ |
|
ltop2 = avma; |
ltop2 = avma; |
for (j = 1; j < lg(PG[1]); j++) |
for (j = 1; j < lg(PG[1]); j++) |
{ |
{ |
GEN B, tau; |
GEN B; |
long t, g; |
long t; |
long w, sr, dss; |
long w, sr, dss; |
if (DEBUGLEVEL >= 6) |
if (DEBUGLEVEL >= 6) |
fprintferr("GaloisConj:G[%d]=%Z d'ordre relatif %d\n", j, |
fprintferr("GaloisConj:G[%d]=%Z d'ordre relatif %d\n", j, |
((GEN **) PG)[1][j], ((long **) PG)[2][j]); |
((GEN **) PG)[1][j], ((long **) PG)[2][j]); |
B = permorbite(((GEN **) PG)[1][j]); |
B = perm_cycles(gmael(PG,1,j)); |
if (DEBUGLEVEL >= 6) |
if (DEBUGLEVEL >= 6) |
fprintferr("GaloisConj:B=%Z\n", B); |
fprintferr("GaloisConj:B=%Z\n", B); |
if (n == (deg<<1)) |
w = gf.psi[Pg[j]]; |
tau=deg1pol(stoi(-1),negi((GEN)P[3]),x); |
|
else |
|
tau = permtopol(gmael(PG,1,j), PL, PM, Pden, Pladicabs, x); |
|
if (DEBUGLEVEL >= 9) |
|
fprintferr("GaloisConj:Paut=%Z\n", tau); |
|
/*tau not in Z[X]*/ |
|
tau = lift(gmul(tau,gmodulcp(gun,ip))); |
|
tau = FpX_FpXQ_compo((GEN) Pmod[gp], tau,Pp,ip); |
|
tau = FpX_gcd(Pp, tau,ip); |
|
/*normalize gcd*/ |
|
tau = FpX_Fp_mul(tau,mpinvmod((GEN) tau[lgef(tau) - 1],ip),ip); |
|
if (DEBUGLEVEL >= 6) |
|
fprintferr("GaloisConj:tau=%Z\n", tau); |
|
for (g = 1; g < lg(Pmod); g++) |
|
if (gegal(tau, (GEN) Pmod[g])) |
|
break; |
|
if (DEBUGLEVEL >= 6) |
|
fprintferr("GaloisConj:g=%ld\n", g); |
|
if (g == lg(Pmod)) |
|
{ |
|
freetest(&td); |
|
avma = ltop; |
|
return gzero; |
|
} |
|
w = gf.psi[g]; |
|
dss = deg / cgcd(deg, w - 1); |
dss = deg / cgcd(deg, w - 1); |
sr = 1; |
sr = 1; |
for (i = 1; i < lg(B[1]) - 1; i++) |
for (i = 1; i < lg(B[1]) - 1; i++) |
Line 3226 galoisgen(GEN T, GEN L, GEN M, GEN den, struct galois_ |
|
Line 2921 galoisgen(GEN T, GEN L, GEN M, GEN den, struct galois_ |
|
GEN |
GEN |
galoisconj4(GEN T, GEN den, long flag, long karma) |
galoisconj4(GEN T, GEN den, long flag, long karma) |
{ |
{ |
ulong ltop = avma; |
gpmem_t ltop = avma; |
GEN G, L, M, res, aut, grp=NULL;/*keep gcc happy on the wall*/ |
GEN G, L, M, res, aut, grp=NULL;/*keep gcc happy on the wall*/ |
struct galois_analysis ga; |
struct galois_analysis ga; |
struct galois_borne gb; |
struct galois_borne gb; |
Line 3234 galoisconj4(GEN T, GEN den, long flag, long karma) |
|
Line 2929 galoisconj4(GEN T, GEN den, long flag, long karma) |
|
if (typ(T) != t_POL) |
if (typ(T) != t_POL) |
{ |
{ |
T = checknf(T); |
T = checknf(T); |
if (!den) |
if (!den) den = Q_denom((GEN)T[7]); |
den = gcoeff((GEN) T[8], degpol(T[1]), degpol(T[1])); |
|
T = (GEN) T[1]; |
T = (GEN) T[1]; |
} |
} |
n = degpol(T); |
n = degpol(T); |
Line 3274 galoisconj4(GEN T, GEN den, long flag, long karma) |
|
Line 2968 galoisconj4(GEN T, GEN den, long flag, long karma) |
|
den = absi(den); |
den = absi(den); |
} |
} |
gb.l = stoi(ga.l); |
gb.l = stoi(ga.l); |
if (DEBUGLEVEL >= 1) |
if (DEBUGLEVEL >= 1) (void)timer2(); |
timer2(); |
|
den = galoisborne(T, den, &gb, ga.ppp); |
den = galoisborne(T, den, &gb, ga.ppp); |
if (DEBUGLEVEL >= 1) |
if (DEBUGLEVEL >= 1) |
msgtimer("galoisborne()"); |
msgtimer("galoisborne()"); |
Line 3300 galoisconj4(GEN T, GEN den, long flag, long karma) |
|
Line 2993 galoisconj4(GEN T, GEN den, long flag, long karma) |
|
avma = ltop; |
avma = ltop; |
return gzero; |
return gzero; |
} |
} |
if (DEBUGLEVEL >= 1) |
if (DEBUGLEVEL >= 1) (void)timer2(); |
timer2(); |
|
if (flag) |
if (flag) |
{ |
{ |
grp = cgetg(9, t_VEC); |
grp = cgetg(9, t_VEC); |
Line 3317 galoisconj4(GEN T, GEN den, long flag, long karma) |
|
Line 3009 galoisconj4(GEN T, GEN den, long flag, long karma) |
|
grp[8] = (long) gcopy((GEN) G[2]); |
grp[8] = (long) gcopy((GEN) G[2]); |
} |
} |
res = cgetg(n + 1, t_VEC); |
res = cgetg(n + 1, t_VEC); |
res[1] = (long) permidentity(n); |
res[1] = (long) perm_identity(n); |
k = 1; |
k = 1; |
for (i = 1; i < lg(G[1]); i++) |
for (i = 1; i < lg(G[1]); i++) |
{ |
{ |
int c = k * (((long **) G)[2][i] - 1); |
int c = k * (((long **) G)[2][i] - 1); |
for (j = 1; j <= c; j++) /* I like it */ |
for (j = 1; j <= c; j++) /* I like it */ |
res[++k] = (long) permapply((GEN) res[j], ((GEN **) G)[1][i]); |
res[++k] = (long) perm_mul((GEN) res[j], ((GEN **) G)[1][i]); |
} |
} |
if (flag) |
if (flag) |
{ |
{ |
Line 3333 galoisconj4(GEN T, GEN den, long flag, long karma) |
|
Line 3025 galoisconj4(GEN T, GEN den, long flag, long karma) |
|
aut = galoisgrouptopol(res,L,M,den,gb.ladicsol, varn(T)); |
aut = galoisgrouptopol(res,L,M,den,gb.ladicsol, varn(T)); |
if (DEBUGLEVEL >= 1) |
if (DEBUGLEVEL >= 1) |
msgtimer("Calcul polynomes"); |
msgtimer("Calcul polynomes"); |
return gerepileupto(ltop, aut); |
return gerepileupto(ltop, gen_sort(aut, 0, cmp_pol)); |
} |
} |
|
|
/* Calcule le nombre d'automorphisme de T avec forte probabilité */ |
/* Calcule le nombre d'automorphisme de T avec forte probabilité */ |
Line 3341 galoisconj4(GEN T, GEN den, long flag, long karma) |
|
Line 3033 galoisconj4(GEN T, GEN den, long flag, long karma) |
|
long |
long |
numberofconjugates(GEN T, long pdepart) |
numberofconjugates(GEN T, long pdepart) |
{ |
{ |
ulong ltop = avma, ltop2; |
gpmem_t ltop2, ltop = avma; |
long n, p, nbmax, nbtest; |
long n, p, nbmax, nbtest; |
long card; |
long card; |
byteptr primepointer; |
byteptr primepointer; |
Line 3357 numberofconjugates(GEN T, long pdepart) |
|
Line 3049 numberofconjugates(GEN T, long pdepart) |
|
ltop2 = avma; |
ltop2 = avma; |
for (p = 0, primepointer = diffptr; nbtest < nbmax && card > 1;) |
for (p = 0, primepointer = diffptr; nbtest < nbmax && card > 1;) |
{ |
{ |
long s, c; |
long s; |
long isram; |
long isram; |
GEN S; |
GEN S; |
c = *primepointer++; |
|
if (!c) |
NEXT_PRIME_VIADIFF_CHECK(p,primepointer); |
err(primer1); |
|
p += c; |
|
if (p < pdepart) |
if (p < pdepart) |
continue; |
continue; |
S = (GEN) simplefactmod(T, stoi(p)); |
S = (GEN) simplefactmod(T, stoi(p)); |
Line 3397 numberofconjugates(GEN T, long pdepart) |
|
Line 3087 numberofconjugates(GEN T, long pdepart) |
|
GEN |
GEN |
galoisconj0(GEN nf, long flag, GEN d, long prec) |
galoisconj0(GEN nf, long flag, GEN d, long prec) |
{ |
{ |
ulong ltop; |
gpmem_t ltop; |
GEN G, T; |
GEN G, T; |
long card; |
long card; |
if (typ(nf) != t_POL) |
if (typ(nf) != t_POL) |
Line 3457 galoisconj0(GEN nf, long flag, GEN d, long prec) |
|
Line 3147 galoisconj0(GEN nf, long flag, GEN d, long prec) |
|
long |
long |
isomborne(GEN P, GEN den, GEN p) |
isomborne(GEN P, GEN den, GEN p) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
struct galois_borne gb; |
struct galois_borne gb; |
gb.l=p; |
gb.l=p; |
galoisborne(P,den,&gb,degpol(P)); |
(void)galoisborne(P,den,&gb,degpol(P)); |
avma=ltop; |
avma=ltop; |
return gb.valsol; |
return gb.valsol; |
} |
} |
Line 3522 galoiscosets(GEN O, GEN perm) |
|
Line 3212 galoiscosets(GEN O, GEN perm) |
|
long i,j,k,u; |
long i,j,k,u; |
long o = lg(O)-1, f = lg(O[1])-1; |
long o = lg(O)-1, f = lg(O[1])-1; |
GEN C = cgetg(lg(O),t_VECSMALL); |
GEN C = cgetg(lg(O),t_VECSMALL); |
ulong av=avma; |
gpmem_t av=avma; |
GEN RC=cgetg(lg(perm),t_VECSMALL); |
GEN RC=cgetg(lg(perm),t_VECSMALL); |
for(i=1;i<lg(RC);i++) |
for(i=1;i<lg(RC);i++) |
RC[i]=0; |
RC[i]=0; |
|
|
fixedfieldfactor(GEN L, GEN O, GEN perm, GEN M, GEN den, GEN mod, |
fixedfieldfactor(GEN L, GEN O, GEN perm, GEN M, GEN den, GEN mod, |
long x,long y) |
long x,long y) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
GEN F,G,V,res,cosets; |
GEN F,G,V,res,cosets; |
int i, j, k; |
int i, j, k; |
F=cgetg(lg(O[1])+1,t_COL); |
F=cgetg(lg(O[1])+1,t_COL); |
Line 3564 fixedfieldfactor(GEN L, GEN O, GEN perm, GEN M, GEN de |
|
Line 3254 fixedfieldfactor(GEN L, GEN O, GEN perm, GEN M, GEN de |
|
res=cgetg(lg(O),t_VEC); |
res=cgetg(lg(O),t_VEC); |
for (i = 1; i < lg(O); i++) |
for (i = 1; i < lg(O); i++) |
{ |
{ |
ulong av=avma; |
gpmem_t av=avma; |
long ii,jj; |
long ii,jj; |
GEN G=cgetg(lg(O),t_VEC); |
GEN G=cgetg(lg(O),t_VEC); |
for (ii = 1; ii < lg(O); ii++) |
for (ii = 1; ii < lg(O); ii++) |
Line 3588 fixedfieldfactor(GEN L, GEN O, GEN perm, GEN M, GEN de |
|
Line 3278 fixedfieldfactor(GEN L, GEN O, GEN perm, GEN M, GEN de |
|
GEN |
GEN |
galoisfixedfield(GEN gal, GEN perm, long flag, long y) |
galoisfixedfield(GEN gal, GEN perm, long flag, long y) |
{ |
{ |
ulong ltop = avma, lbot; |
gpmem_t lbot, ltop = avma; |
GEN L, P, S, PL, O, res, mod; |
GEN L, P, S, PL, O, res, mod; |
long x, n; |
long x, n; |
int i; |
int i; |
Line 3600 galoisfixedfield(GEN gal, GEN perm, long flag, long y) |
|
Line 3290 galoisfixedfield(GEN gal, GEN perm, long flag, long y) |
|
err(flagerr, "galoisfixedfield"); |
err(flagerr, "galoisfixedfield"); |
if (typ(perm) == t_VEC) |
if (typ(perm) == t_VEC) |
{ |
{ |
if (lg(perm)==1) |
for (i = 1; i < lg(perm); i++) |
perm=permidentity(n); |
if (typ(perm[i]) != t_VECSMALL || lg(perm[i])!=n+1) |
else |
err(typeer, "galoisfixedfield"); |
for (i = 1; i < lg(perm); i++) |
O = vecperm_orbits(perm, n); |
if (typ(perm[i]) != t_VECSMALL || lg(perm[i])!=n+1) |
|
err(typeer, "galoisfixedfield"); |
|
} |
} |
else if (typ(perm) != t_VECSMALL || lg(perm)!=n+1 ) |
else if (typ(perm) != t_VECSMALL || lg(perm)!=n+1 ) |
|
{ |
err(typeer, "galoisfixedfield"); |
err(typeer, "galoisfixedfield"); |
O = permorbite(perm); |
return NULL; /* not reached */ |
|
} |
|
else |
|
O = perm_cycles(perm); |
{ |
{ |
GEN sym=cgetg(lg(L),t_VECSMALL); |
GEN sym=cgetg(lg(L),t_VECSMALL); |
GEN dg=cgetg(lg(L),t_VECSMALL); |
GEN dg=cgetg(lg(L),t_VECSMALL); |
Line 3640 galoisfixedfield(GEN gal, GEN perm, long flag, long y) |
|
Line 3332 galoisfixedfield(GEN gal, GEN perm, long flag, long y) |
|
Pden = galoisborne(P, NULL, &Pgb, 1); |
Pden = galoisborne(P, NULL, &Pgb, 1); |
if (Pgb.valabs > val) |
if (Pgb.valabs > val) |
{ |
{ |
if (DEBUGLEVEL>=4) |
if (DEBUGLEVEL>=4) |
fprintferr("GaloisConj:increase prec of p-adic roots of %ld.\n" |
fprintferr("GaloisConj:increase prec of p-adic roots of %ld.\n" |
,Pgb.valabs-val); |
,Pgb.valabs-val); |
PL = rootpadicliftroots(P,PL,Pgb.l,Pgb.valabs); |
PL = rootpadicliftroots(P,PL,Pgb.l,Pgb.valabs); |
L = rootpadicliftroots((GEN) gal[1],L,Pgb.l,Pgb.valabs); |
L = rootpadicliftroots((GEN) gal[1],L,Pgb.l,Pgb.valabs); |
mod = Pgb.ladicabs; |
mod = Pgb.ladicabs; |
} |
} |
} |
} |
PM = vandermondeinversemod(PL, P, Pden, mod); |
PM = vandermondeinversemod(PL, P, Pden, mod); |
Line 3658 galoisfixedfield(GEN gal, GEN perm, long flag, long y) |
|
Line 3350 galoisfixedfield(GEN gal, GEN perm, long flag, long y) |
|
res[1] = (long) gcopy(P); |
res[1] = (long) gcopy(P); |
res[2] = (long) gmodulcp(S, (GEN) gal[1]); |
res[2] = (long) gmodulcp(S, (GEN) gal[1]); |
res[3] = (long) fixedfieldfactor(L,O,(GEN)gal[6], |
res[3] = (long) fixedfieldfactor(L,O,(GEN)gal[6], |
PM,Pden,mod,x,y); |
PM,Pden,mod,x,y); |
return gerepile(ltop, lbot, res); |
return gerepile(ltop, lbot, res); |
} |
} |
} |
} |
Line 3667 galoisfixedfield(GEN gal, GEN perm, long flag, long y) |
|
Line 3359 galoisfixedfield(GEN gal, GEN perm, long flag, long y) |
|
long |
long |
galoistestabelian(GEN gal) |
galoistestabelian(GEN gal) |
{ |
{ |
ulong ltop=avma; |
gpmem_t ltop=avma; |
long i,j; |
GEN G; |
|
long test; |
gal = checkgal(gal); |
gal = checkgal(gal); |
for(i=2;i<lg(gal[7]);i++) |
G=cgetg(3,t_VEC); |
for(j=1;j<i;j++) |
G[1]=gal[7]; |
{ |
G[2]=gal[8]; |
long test=gegal(permapply(gmael(gal,7,i),gmael(gal,7,j)), |
test=group_isabelian(G); |
permapply(gmael(gal,7,j),gmael(gal,7,i))); |
avma=ltop; |
avma=ltop; |
return test; |
if (!test) return 0; |
|
} |
|
return 1; |
|
} |
} |
|
|
GEN galoisisabelian(GEN gal, long flag) |
GEN galoisisabelian(GEN gal, long flag) |
{ |
{ |
long i, j; |
long i, j; |
long test, n=lg(gal[7]); |
long test, n; |
GEN M; |
GEN M; |
gal = checkgal(gal); |
gal = checkgal(gal); |
test=galoistestabelian(gal); |
test=galoistestabelian(gal); |
if (!test) return gzero; |
if (!test) return gzero; |
if (flag==1) return gun; |
if (flag==1) return gun; |
if (flag) err(flagerr,"galoisisabelian"); |
if (flag) err(flagerr,"galoisisabelian"); |
|
n=lg(gal[7]); |
M=cgetg(n,t_MAT); |
M=cgetg(n,t_MAT); |
for(i=1;i<n;i++) |
for(i=1;i<n;i++) |
{ |
{ |
ulong btop; |
gpmem_t btop; |
GEN P; |
GEN P; |
long k; |
long k; |
M[i]=lgetg(n,t_COL); |
M[i]=lgetg(n,t_COL); |
btop=avma; |
btop=avma; |
P=permcyclepow(permorbite(gmael(gal,7,i)),mael(gal,8,i)); |
P=perm_pow(gmael(gal,7,i),mael(gal,8,i)); |
for(j=1;j<lg(gal[6]);j++) |
for(j=1;j<lg(gal[6]);j++) |
if (gegal(P,gmael(gal,6,j))) |
if (gegal(P,gmael(gal,6,j))) |
break; |
break; |
Line 3717 GEN galoisisabelian(GEN gal, long flag) |
|
Line 3408 GEN galoisisabelian(GEN gal, long flag) |
|
} |
} |
return M; |
return M; |
} |
} |
/* Calcule les orbites d'un sous-groupe de Z/nZ donne par un |
GEN galoissubgroups(GEN G) |
* generateur ou d'un ensemble de generateur donne par un vecteur. |
|
*/ |
|
GEN |
|
subgroupcoset(long n, GEN v) |
|
{ |
{ |
ulong ltop = avma, lbot; |
gpmem_t ltop=avma; |
int i, j, k = 1, l, m, o, p, flag; |
GEN H; |
GEN bit, cycle, cy; |
G = checkgal(G); |
cycle = cgetg(n, t_VEC); |
H=cgetg(3,t_VEC); |
bit = cgetg(n, t_VECSMALL); |
H[1]=G[7]; |
for (i = 1; i < n; i++) |
H[2]=G[8]; |
if (cgcd(i,n)==1) |
return gerepileupto(ltop,group_subgroups(H)); |
bit[i] = 0; |
|
else |
|
{ |
|
bit[i] = -1; |
|
k++; |
|
} |
|
for (l = 1; k < n;) |
|
{ |
|
for (j = 1; bit[j]; j++); |
|
cy = cgetg(n, t_VECSMALL); |
|
m = 1; |
|
cy[m++] = j; |
|
bit[j] = 1; |
|
k++; |
|
do |
|
{ |
|
flag = 0; |
|
for (o = 1; o < lg(v); o++) |
|
{ |
|
for (p = 1; p < m; p++) /* m varie! */ |
|
{ |
|
j = mulssmod(v[o],cy[p],n); |
|
if (!bit[j]) |
|
{ |
|
flag = 1; |
|
bit[j] = 1; |
|
k++; |
|
cy[m++] = j; |
|
} |
|
} |
|
} |
|
} |
|
while (flag); |
|
setlg(cy, m); |
|
cycle[l++] = (long) cy; |
|
} |
|
setlg(cycle, l); |
|
lbot = avma; |
|
cycle = gcopy(cycle); |
|
return gerepile(ltop, lbot, cycle); |
|
} |
} |
/* Calcule les elements d'un sous-groupe H de Z/nZ donne par un |
|
* generateur ou d'un ensemble de generateur donne par un vecteur (v). |
|
* |
|
* cy liste des elements VECSMALL de longueur au moins card H. |
|
* bit bitmap des elements VECSMALL de longueur au moins n. |
|
* retourne le nombre d'elements+1 |
|
*/ |
|
long |
|
sousgroupeelem(long n, GEN v, GEN cy, GEN bit) |
|
{ |
|
int j, m, o, p, flag; |
|
for(j=1;j<n;j++) |
|
bit[j]=0; |
|
m = 1; |
|
bit[m] = 1; |
|
cy[m++] = 1; |
|
do |
|
{ |
|
flag = 0; |
|
for (o = 1; o < lg(v); o++) |
|
{ |
|
for (p = 1; p < m; p++) /* m varie! */ |
|
{ |
|
j = mulssmod(v[o],cy[p],n); |
|
if (!bit[j]) |
|
{ |
|
flag = 1; |
|
bit[j] = 1; |
|
cy[m++] = j; |
|
} |
|
} |
|
} |
|
} |
|
while (flag); |
|
return m; |
|
} |
|
/* n,v comme precedemment. |
|
* Calcule le conducteur et retourne le nouveau groupe de congruence dans V |
|
* V doit etre un t_VECSMALL de taille n+1 au moins. |
|
*/ |
|
long znconductor(long n, GEN v, GEN V) |
|
{ |
|
ulong ltop; |
|
int i,j; |
|
long m; |
|
GEN F,W; |
|
W = cgetg(n, t_VECSMALL); |
|
ltop=avma; |
|
m = sousgroupeelem(n,v,V,W); |
|
setlg(V,m); |
|
if (DEBUGLEVEL>=6) |
|
fprintferr("SubCyclo:elements:%Z\n",V); |
|
F = factor(stoi(n)); |
|
for(i=lg((GEN)F[1])-1;i>0;i--) |
|
{ |
|
long p,e,q; |
|
p=itos(gcoeff(F,i,1)); |
|
e=itos(gcoeff(F,i,2)); |
|
if (DEBUGLEVEL>=4) |
|
fprintferr("SubCyclo:testing %ld^%ld\n",p,e); |
|
while (e>=1) |
|
{ |
|
int z = 1; |
|
q=n/p; |
|
for(j=1;j<p;j++) |
|
{ |
|
z += q; |
|
if (!W[z] && z%p) break; |
|
} |
|
if (j<p) |
|
{ |
|
if (DEBUGLEVEL>=4) |
|
fprintferr("SubCyclo:%ld not found\n",z); |
|
break; |
|
} |
|
e--; |
|
n=q; |
|
if (DEBUGLEVEL>=4) |
|
fprintferr("SubCyclo:new conductor:%ld\n",n); |
|
m=sousgroupeelem(n,v,V,W); |
|
setlg(V,m); |
|
if (DEBUGLEVEL>=6) |
|
fprintferr("SubCyclo:elements:%Z\n",V); |
|
} |
|
} |
|
if (DEBUGLEVEL>=6) |
|
fprintferr("SubCyclo:conductor:%ld\n",n); |
|
avma=ltop; |
|
return n; |
|
} |
|
|
|
static GEN gscycloconductor(GEN g, long n, long flag) |
GEN galoissubfields(GEN G, long flag, long v) |
{ |
{ |
if (flag==2) |
gpmem_t ltop=avma; |
{ |
|
GEN V=cgetg(3,t_VEC); |
|
V[1]=lcopy(g); |
|
V[2]=lstoi(n); |
|
return V; |
|
} |
|
return g; |
|
} |
|
static GEN |
|
lift_check_modulus(GEN H, GEN n) |
|
{ |
|
long t=typ(H), l=lg(H); |
|
long i; |
long i; |
GEN V; |
GEN L = galoissubgroups(G); |
switch(t) |
long l2 = lg(L); |
{ |
GEN p3 = cgetg(l2, t_VEC); |
case t_INTMOD: |
for (i = 1; i < l2; ++i) |
if (cmpii(n,(GEN)H[1])) |
p3[i] = (long) galoisfixedfield(G, gmael(L,i,1), flag, v); |
err(talker,"wrong modulus in galoissubcyclo"); |
return gerepileupto(ltop,p3); |
H = (GEN)H[2]; |
|
case t_INT: |
|
if (!is_pm1(mppgcd(H,n))) |
|
err(talker,"generators must be prime to conductor in galoissubcyclo"); |
|
return modii(H,n); |
|
case t_VEC: case t_COL: |
|
V=cgetg(l,t); |
|
for(i=1;i<l;i++) |
|
V[i] = (long)lift_check_modulus((GEN)H[i],n); |
|
return V; |
|
case t_VECSMALL: |
|
return H; |
|
} |
|
err(talker,"wrong type in galoissubcyclo"); |
|
return NULL;/*not reached*/ |
|
} |
} |
|
|
GEN |
|
galoissubcyclo(long n, GEN H, GEN Z, long v, long flag) |
|
{ |
|
ulong ltop=avma,av; |
|
GEN l,borne,le,powz,z,V; |
|
long i; |
|
long e,val; |
|
long u,o,j; |
|
GEN O,g; |
|
if (flag<0 || flag>2) err(flagerr,"galoisubcyclo"); |
|
if ( v==-1 ) v=0; |
|
if ( n<1 ) err(arither2); |
|
if ( n>=VERYBIGINT) |
|
err(impl,"galoissubcyclo for huge conductor"); |
|
if ( typ(H)==t_MAT ) |
|
{ |
|
GEN zn2, zn3, gen, ord; |
|
if (lg(H) == 1 || lg(H) != lg(H[1])) |
|
err(talker,"not a HNF matrix in galoissubcyclo"); |
|
if (!Z) |
|
Z=znstar(stoi(n)); |
|
else if (typ(Z)!=t_VEC || lg(Z)!=4) |
|
err(talker,"Optionnal parameter must be as output by znstar in galoissubcyclo"); |
|
zn2 = gtovecsmall((GEN)Z[2]); |
|
zn3 = lift((GEN)Z[3]); |
|
if ( lg(zn2) != lg(H) || lg(zn3) != lg(H)) |
|
err(talker,"Matrix of wrong dimensions in galoissubcyclo"); |
|
gen = cgetg(lg(zn3), t_VECSMALL); |
|
ord = cgetg(lg(zn3), t_VECSMALL); |
|
hnftogeneratorslist(n,zn2,zn3,H,gen,ord); |
|
H=gen; |
|
} |
|
else |
|
{ |
|
H=lift_check_modulus(H,stoi(n)); |
|
H=gtovecsmall(H); |
|
for (i=1;i<lg(H);i++) |
|
if (H[i]<0) |
|
H[i]=mulssmod(-H[i],n-1,n); |
|
/*Should check components are prime to n, but it is costly*/ |
|
} |
|
V = cgetg(n, t_VECSMALL); |
|
if (DEBUGLEVEL >= 1) |
|
timer2(); |
|
n = znconductor(n,H,V); |
|
if (flag==1) {avma=ltop;return stoi(n);} |
|
if (DEBUGLEVEL >= 1) |
|
msgtimer("znconductor."); |
|
H = V; |
|
O = subgroupcoset(n,H); |
|
if (DEBUGLEVEL >= 1) |
|
msgtimer("subgroupcoset."); |
|
if (DEBUGLEVEL >= 6) |
|
fprintferr("Subcyclo: orbit=%Z\n",O); |
|
if (lg(O)==1 || lg(O[1])==2) |
|
{ |
|
avma=ltop; |
|
return gscycloconductor(cyclo(n,v),n,flag); |
|
} |
|
u=lg(O)-1;o=lg(O[1])-1; |
|
if (DEBUGLEVEL >= 4) |
|
fprintferr("Subcyclo: %ld orbits with %ld elements each\n",u,o); |
|
l=stoi(n+1);e=1; |
|
while(!isprime(l)) |
|
{ |
|
l=addis(l,n); |
|
e++; |
|
} |
|
if (DEBUGLEVEL >= 4) |
|
fprintferr("Subcyclo: prime l=%Z\n",l); |
|
av=avma; |
|
/*Borne utilise': |
|
Vecmax(Vec((x+o)^u)=max{binome(u,i)*o^i ;1<=i<=u} |
|
*/ |
|
i=u-(1+u)/(1+o); |
|
borne=mulii(binome(stoi(u),i),gpowgs(stoi(o),i)); |
|
if (DEBUGLEVEL >= 4) |
|
fprintferr("Subcyclo: borne=%Z\n",borne); |
|
val=mylogint(shifti(borne,1),l); |
|
avma=av; |
|
if (DEBUGLEVEL >= 4) |
|
fprintferr("Subcyclo: val=%ld\n",val); |
|
le=gpowgs(l,val); |
|
z=lift(gpowgs(gener(l),e)); |
|
z=padicsqrtnlift(gun,stoi(n),z,l,val); |
|
if (DEBUGLEVEL >= 1) |
|
msgtimer("padicsqrtnlift."); |
|
powz = cgetg(n,t_VEC); powz[1] = (long)z; |
|
for (i=2; i<n; i++) powz[i] = lmodii(mulii(z,(GEN)powz[i-1]),le); |
|
if (DEBUGLEVEL >= 1) |
|
msgtimer("computing roots."); |
|
g=cgetg(u+1,t_VEC); |
|
for(i=1;i<=u;i++) |
|
{ |
|
GEN s; |
|
s=gzero; |
|
for(j=1;j<=o;j++) |
|
s=addii(s,(GEN)powz[mael(O,i,j)]); |
|
g[i]=(long)modii(negi(s),le); |
|
} |
|
if (DEBUGLEVEL >= 1) |
|
msgtimer("computing new roots."); |
|
g=FpV_roots_to_pol(g,le,v); |
|
if (DEBUGLEVEL >= 1) |
|
msgtimer("computing products."); |
|
g=FpX_center(g,le); |
|
return gerepileupto(ltop,gscycloconductor(g,n,flag)); |
|
} |
|