Testing latest pari + WASM + node.js... and it works?! Wow.
License: GPL3
ubuntu2004
/* Copyright (C) 2000 The PARI group.12This file is part of the PARI/GP package.34PARI/GP is free software; you can redistribute it and/or modify it under the5terms of the GNU General Public License as published by the Free Software6Foundation; either version 2 of the License, or (at your option) any later7version. It is distributed in the hope that it will be useful, but WITHOUT8ANY WARRANTY WHATSOEVER.910Check the License for details. You should have received a copy of it, along11with the package; see the file 'COPYING'. If not, write to the Free Software12Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */1314#include "pari.h"15#include "paripriv.h"1617#define DEBUGLEVEL DEBUGLEVEL_polgalois1819/**************************************************************/20/* Galois group for degree in [8, 11] */21/**************************************************************/2223#define NMAX 11 /* maximum degree */2425typedef GEN PERM;26typedef PERM *GROUP;27typedef struct {28PERM *a;29long nm, nv;30} resolv; /* resolvent */3132typedef struct {33long pr, prmax, N;34GEN p, r, coef;35} buildroot;3637static long isin_G_H(buildroot *BR, long n1, long n2);3839/* k-1 entries filled so far40* m = maximal allowed value, n = sum to reach with remaining elements */41static void42do_par(GEN T, long k, long n, long m, long *par_vec)43{44long i;45if (n <= 0)46{47GEN t = cgetg(k, t_VECSMALL);48for (i=1; i<k; i++) t[i] = par_vec[i];49gel(T, ++T[0]) = t; return;50}51if (n < m) m = n;52for (i=1; i<=m; i++) { par_vec[k] = i; do_par(T, k+1, n-i, i, par_vec); }53}5455/* compute the partitions of n, as decreasing t_VECSMALLs */56static GEN57partitions_galois(long n)58{59pari_sp av;60long i, p;61GEN T, par_vec;6263switch(n) /* optimized for galoismoduloX ... */64{65case 8: p = 22; break;66case 9: p = 30; break;67case 10:p = 42; break;68default:69if (n < 0) pari_err_TYPE("partitions_galois", stoi(n));70av = avma; p = itos( numbpart(stoi(n)) ); set_avma(av); break;71}72T = new_chunk(p + 1); T[0] = 0;73par_vec = cgetg(n+1, t_VECSMALL); /* not Garbage Collected later */74do_par(T,1,n,n,par_vec);75if (DEBUGLEVEL > 7)76{77err_printf("Partitions of %ld (%ld)\n",n, p);78for (i=1; i<=p; i++) err_printf("i = %ld: %Ps\n",i,gel(T,i));79}80T[0] = evallg(p + 1) | evaltyp(t_VEC); return T;81}8283/* affect to the permutation x the N arguments that follow */84static void85_aff(long N, PERM x,...)86{87va_list args; long i;88va_start(args,x); for (i=1; i<=N; i++) x[i] = va_arg(args,int);89va_end(args);90}9192/* return an array of length |len| from the arguments (for galoismodulo) */93static GEN94_gr(long len,...)95{96va_list args;97long i, l = labs(len);98GEN x = new_chunk(l+1);99100va_start(args,len); x[0] = len;101for (i=1; i<=l; i++) x[i] = va_arg(args,int);102va_end(args); return x;103}104105/* return a VECSMALL of length l from the arguments (for galoismodulo11) */106static GEN107_typ(long l,...)108{109va_list args;110long i;111GEN x = cgetg(l+1, t_VECSMALL);112113va_start(args,l);114for (i=1; i<=l; i++) x[i] = va_arg(args,int);115va_end(args); return x;116}117118/* create a permutation with the N arguments of the function */119static PERM120_cr(long N, long a,...)121{122va_list args;123long i;124GEN x = new_chunk(NMAX+1);125va_start(args, a); x[0] = N; x[1] = a;126for (i=2; i<=N; i++) x[i] = va_arg(args,int);127va_end(args); return x;128}129130static PERM131permmul(PERM s1, PERM s2)132{133long i, n1 = s1[0];134PERM s3 = (PERM)stack_malloc((n1+1) * sizeof(long));135for (i=1; i<=n1; i++) s3[i] = s1[s2[i]];136s3[0] = n1; return s3;137}138139static void140printperm(PERM perm)141{142long i, n = perm[0];143err_printf("(");144for (i=1; i<=n; i++) err_printf(" %d",perm[i]);145err_printf(" )\n");146}147148static int149raye(long *g, long num)150{151long i, nb = labs(g[0]);152for (i=1; i<=nb; i++)153if (g[i] == num) return 0;154return 1;155}156157/* we can never determine the group completely in there */158static long159rayergroup11(long EVEN, long num, long *gr)160{161long r = 0;162163if (EVEN)164switch(num)165{166case 2: case 5:167if (gr[3]) { gr[3]=0; r++; }168case 3: case 6: case 7:169if (gr[2]) { gr[2]=0; r++; }170case 4:171if (gr[1]) { gr[1]=0; r++; }172}173else174switch(num)175{176case 2: case 3:177if (gr[1]) { gr[1]=0; r++; }178}179return r;180}181182static long183rayergroup(long EVEN, long **GR, long num, long *gr)184{185long i,nbgr,r;186187if (!GR) return rayergroup11(EVEN,num,gr);188nbgr = lg(GR); r = 0 ;189if (EVEN)190{191for (i=1; i<nbgr; i++)192if (gr[i] && GR[i][0] < 0 && raye(GR[i],num)) { gr[i]=0; r++; }193}194else195{196for (i=1; i<nbgr; i++)197if (gr[i] && GR[i][0] > 0 && raye(GR[i],num)) { gr[i]=0; r++; }198}199return r;200}201202static long203galmodp(long EVEN, GEN pol, GEN dpol, GEN TYP, long *gr, long **GR)204{205long i,k,l,n,nbremain;206GEN p1, dtyp;207forprime_t T;208209switch(degpol(pol))210{211case 8: nbremain = EVEN? 28: 22; break;212case 9: nbremain = EVEN? 18: 16; break;213case 10: nbremain = EVEN? 12: 33; break;214default: nbremain = EVEN? 5: 3; break; /* case 11 */215}216217u_forprime_init(&T, 2, ULONG_MAX);218dtyp = new_chunk(NMAX+1);219k = gr[0]; for (i=1; i<k; i++) gr[i]=1;220for (k=1; k<15; k++)221{222ulong p = u_forprime_next(&T);223if (!umodiu(dpol,p)) continue; /* p divides dpol */224225p1 = gel(Flx_degfact(ZX_to_Flx(pol,p),p),1);226l = lg(p1);227dtyp[0] = evaltyp(t_VECSMALL)|evallg(l);228for (i=1; i<l; i++) dtyp[i] = p1[l-i]; /* decreasing order */229n = RgV_isin(TYP, dtyp);230if (!n) return 1; /* only for N=11 */231nbremain -= rayergroup(EVEN,GR,n,gr);232if (nbremain==1) return 1;233}234return 0;235}236237static void238preci(GEN o, long p)239{240long i, l = lg(o);241for (i=1; i<l; i++)242{243GEN x = gel(o,i);244if (typ(x)==t_COMPLEX) { setprec(gel(x,1),p); setprec(gel(x,2),p); } else setprec(x,p);245}246}247static void248fixprec(buildroot *BR)249{250GEN r = BR->r;251long i, l = lg(r), p = BR->pr;252253if (p > BR->prmax) pari_err_BUG("fixprex [precision too large]");254for (i = 1; i < l; i++) preci(gel(r,i), p);255}256257static long258getpreci(buildroot *BR)259{260GEN x = gmael(BR->r,1,1);261return (typ(x)==t_COMPLEX)? realprec(gel(x,1)): realprec(x);262}263264#define setcard_obj(x,n) ((x)[0] = (PERM)(n))265#define getcard_obj(x) ((long)((x)[0]))266267/* allocate a list of m arrays of length n (index 0 is codeword) */268static PERM *269alloc_pobj(long n, long m)270{271long i;272PERM *g = (PERM*) stack_malloc( (m+1)*sizeof(PERM) + (n+1)*m * sizeof(long) );273PERM gpt = (PERM) (g + (m+1));274275for (i=1; i<=m; i++) { g[i] = gpt; gpt += (n+1); }276setcard_obj(g, m); return g;277}278279static GROUP280allocgroup(long n, long card)281{282GROUP gr = alloc_pobj(n,card);283long i;284285for (i=1; i<=card; i++) gr[i][0] = n;286return gr;287}288289static pariFILE *290galopen(const char *pre, long n, long n1, long n2)291{292pari_sp av = avma;293char *s = stack_malloc(strlen(pari_datadir) + 3 + 4 * 20 + 1 + 3);294pariFILE *f;295296(void)sprintf(s, "%s/galdata/%s%ld_%ld_%ld", pari_datadir, pre, n, n1, n2);297f = pari_fopengz(s);298if (!f) pari_err_FILE("galois file",s);299set_avma(av); return f;300}301302static char303bin(char c)304{305if (c>='0' && c<='9') c -= '0';306else if (c>='A' && c<='Z') c -= 'A'-10;307else if (c>='a' && c<='z') c -= 'a'-36;308else pari_err_TYPE("bin [not alphanumeric]", stoi(c));309return c;310}311312#define BUFFS 512313/* fill in g[i][j] (i<=n, j<=m) with (buffered) data from f->file */314static void315read_obj(PERM *g, pariFILE *f, long n, long m)316{317long i, j, k, N = m*n;318char *ch = stack_malloc(N);319pari_fread_chars(ch, N, f->file);320for (k = 0, i = 1; i <= n; i++)321for (j = 1; j <= m; j++,k++) g[i][j] = bin(ch[k]);322pari_fclose(f);323}324#undef BUFFS325326/* the first 8 bytes contain size data (possibly padded with \0) */327static GROUP328lirecoset(long n1, long n2, long n)329{330GROUP gr;331char c, ch[8];332long m, cardgr;333pariFILE *f = galopen("COS", n, n1, n2);334pari_fread_chars(&c, 1, f->file); m=bin(c);335pari_fread_chars(&c, 1, f->file);336pari_fread_chars(ch, 6, f->file); cardgr=atol(ch);337gr=allocgroup(m,cardgr);338read_obj(gr, f,cardgr,m); return gr;339}340341static void342lireresolv(long n1, long n2, long n, resolv *R)343{344char ch[5];345long nm, nv;346pariFILE *f = galopen("RES", n, n1, n2);347pari_fread_chars(ch,5,f->file); nm = atol(ch);348pari_fread_chars(ch,3,f->file); nv = atol(ch);349R->a = alloc_pobj(nv,nm);350read_obj(R->a, f,nm,nv);351R->nm = nm;352R->nv = nv;353}354355static int356cmp_re(GEN x, GEN y)357{358if (typ(x) != t_COMPLEX) return -1;359if (typ(y) != t_COMPLEX) return 1; /* t_REALS are smallest */360return gcmp(gel(x,1), gel(y,1));361}362363/* multiply the r o bb. Sort first to detect pairs of conjugate */364static GEN365Monomial(GEN r, PERM bb, long nbv)366{367GEN t, R = cgetg(nbv + 1, t_VEC);368long i, s = 1;369370for (i = 1; i <= nbv; i++)371{372t = gel(r,bb[i]);373if (typ(t) == t_COMPLEX && signe(gel(t,1)) < 0) { s = -s; t = gneg(t); }374gel(R,i) = t;375}376if (nbv > 2)377gen_sort_inplace(R, (void*)&cmp_re, cmp_nodata, NULL);378else if (nbv == 2 && typ(gel(R,2)) != t_COMPLEX)379swap(gel(R,1), gel(R,2));380t = NULL;381for (i=1; i<=nbv; i++)382{383GEN c = gel(R,i);384if (typ(c) == t_COMPLEX && i < nbv)385{ /* detect conjugates */386GEN n = gel(R,++i);387if (!abscmprr(gel(n,1), gel(c,1))388&& !abscmprr(gel(n,2), gel(c,2))389&& signe(gel(c,2)) != signe(gel(n,2)))390c = addrr(sqrr(gel(c,1)), sqrr(gel(c,2)));391else392c = gmul(c,n);393}394t = t? gmul(t, c): c;395}396if (s < 0) t = gneg(t);397return t;398}399400/* sum(i = 1, R->nm, Monomial(r, R->a[i], R->nv)). Sort real / imaginary part401* separately by increasing absolute values, to increase stability */402static GEN403gpolynomial(GEN r, resolv *R)404{405GEN RE = cgetg(R->nm+1, t_VEC), IM = cgetg(R->nm+1, t_VEC), re, im;406long i, k;407for (i = k = 1; i <= R->nm; i++)408{409GEN m = Monomial(r,R->a[i], R->nv);410if (typ(m) == t_REAL)411gel(RE, i) = m;412else {413gel(RE, i) = gel(m,1);414gel(IM, k++) = gel(m,2);415}416}417setlg(IM, k);418gen_sort_inplace(RE, (void*)&abscmprr, cmp_nodata, NULL);419gen_sort_inplace(IM, (void*)&abscmprr, cmp_nodata, NULL);420re = gel(RE,1);421for (i = 2; i <= R->nm; i++) re = addrr(re, gel(RE,i));422if (k == 1) return re;423im = gel(IM,1);424for (i = 2; i < k; i++) im = addrr(im, gel(IM,i));425return mkcomplex(re, im);426}427428static void429zaux1(GEN *z, GEN *r)430{431GEN p2,p1;432p2=gsub(r[1], gadd(r[2],r[5]));433p2=gmul(p2, gsub(r[2],r[5]));434p1=gmul(p2,r[1]);435p2=gsub(r[3],gadd(r[2],r[4]));436p2=gmul(p2,gsub(r[4],r[2]));437p1=gadd(p1,gmul(p2,r[3]));438p2=gmul(r[5],gsub(r[4],r[5]));439z[1]=gadd(p1,gmul(p2,r[4]));440441p2=gsub(r[1],gadd(r[3],r[4]));442p2=gmul(p2,gsub(r[3],r[4]));443p1=gmul(p2,r[1]);444p2=gsub(r[5],gadd(r[3],r[2]));445p2=gmul(p2,gsub(r[2],r[3]));446p1=gadd(p1,gmul(p2,r[5]));447p2=gmul(r[4],gsub(r[2],r[4]));448z[2]=gadd(p1,gmul(p2,r[2]));449}450451static void452zaux(GEN *z, GEN *r)453{454zaux1(z, r); zaux1(z+2, r+5);455}456457static GEN458gpoly(GEN rr, long n1, long n2)459{460const long N = lg(rr)-1;461GEN p1,p2,z[6], *r = (GEN*)rr; /* syntaxic kludge */462long i,j;463464if (N==8)465{466if (n1==47 && n2==46)467{468p1=gsub(r[3],r[4]);469for (i=1; i<3; i++) for (j=i+1; j<5; j++) p1 = gmul(p1,gsub(r[i],r[j]));470for (i=5; i<8; i++) for (j=i+1; j<9; j++) p1 = gmul(p1,gsub(r[i],r[j]));471p2=r[1];472for (i=2; i<5; i++) p2=gadd(p2,r[i]);473for (i=5; i<9; i++) p2=gsub(p2,r[i]);474}475else /* n1==44 && n2==40 */476{477for (i=1; i<5; i++) z[i] = gadd(r[2*i-1],r[2*i]);478p1 = gsub(r[1],r[2]);479for (i=2; i<5; i++) p1 = gmul(p1,gsub(r[2*i-1],r[2*i]));480p2=gsub(z[3],z[4]);481for (i=1; i<3; i++) for (j=i+1; j<5; j++) p2 = gmul(p2,gsub(z[i],z[j]));482}483return gmul(p1,p2);484}485486if (N==9)487{488if (n1==31 && n2==29)489{490p1=gsub(r[2],r[3]);491for (j=2; j<4; j++) p1 = gmul(p1,gsub(r[1],r[j]));492for (i=4; i<6; i++) for (j=i+1; j<7; j++) p1 = gmul(p1,gsub(r[i],r[j]));493p2 = gsub(r[8],r[9]);494for (j=8; j<10; j++) p2 = gmul(p2,gsub(r[7],r[j]));495}496else /* ((n1==34 && n2==31) || (n1=33 && n2==30)) */497{498p1=r[1]; for (i=2; i<4; i++) p1=gadd(p1,r[i]);499p2=r[4]; for (i=5; i<7; i++) p2=gadd(p2,r[i]);500p1=gmul(p1,p2);501p2=r[7]; for (i=8; i<10; i++) p2=gadd(p2,r[i]);502}503return gmul(p1,p2);504}505506if (N==10)507{508if ((n1==45 && n2==43) || (n1==44 && n2==42))509{510p1=r[1]; for (i=2; i<6; i++) p1=gadd(p1,r[i]);511p2=r[6]; for (i=7; i<11; i++) p2=gadd(p2,r[i]);512return gmul(p1,p2);513}514else if ((n1==45 && n2==39) || (n1==44 && n2==37))515{516p1 = gadd(r[1],r[2]);517for (i=2; i<6; i++) p1 = gmul(p1,gadd(r[2*i-1],r[2*i]));518return p1;519}520else if ((n1==43 && n2==41) || (n1==33 && n2==27))521{522p1=gsub(r[4],r[5]);523for (i=1; i<4; i++) for (j=i+1; j<6; j++) p1=gmul(p1,gsub(r[i],r[j]));524p2=gsub(r[9],r[10]);525for (i=6; i<9; i++) for (j=i+1; j<11; j++) p2=gmul(p2,gsub(r[i],r[j]));526return gmul(p1,p2);527}528else if ((n1==43 && n2==33) || (n1==42 && n2==28) || (n1==41 && n2==27)529|| (n1==40 && n2==21))530{531p2=gadd(r[2],r[5]);532p2=gsub(p2,gadd(r[3],r[4]));533p1=gmul(p2,r[1]);534p2=gsub(r[3],gadd(r[4],r[5]));535p1=gadd(p1,gmul(p2,r[2]));536p2=gsub(r[4],r[5]);537p1=gadd(p1,gmul(p2,r[3]));538z[1]=gadd(p1,gmul(r[4],r[5]));539540p2=gadd(r[7],r[10]);541p2=gsub(p2,gadd(r[8],r[9]));542p1=gmul(p2,r[6]);543p2=gsub(r[8],gadd(r[9],r[10]));544p1=gadd(p1,gmul(p2,r[7]));545p2=gsub(r[9],r[10]);546p1=gadd(p1,gmul(p2,r[8]));547z[2]=gadd(p1,gmul(r[9],r[10]));548return gadd(gsqr(z[1]), gsqr(z[2]));549}550else if (n1==41 && n2==40)551{552p1=gsub(r[4],r[5]);553for (i=1; i<4; i++) for (j=i+1; j<6; j++) p1 = gmul(p1,gsub(r[i],r[j]));554p2=gsub(r[9],r[10]);555for (i=6; i<9; i++) for (j=i+1; j<11; j++) p2 = gmul(p2,gsub(r[i],r[j]));556return gadd(p1,p2);557}558else if ((n1==41 && n2==22) || (n1==40 && n2==11) || (n1==17 && n2==5)559|| (n1==10 && n2==4) || (n1==9 && n2==3) || (n1==6 && n2==1))560{561p1=gadd(r[1],r[6]);562for (i=2; i<6; i++) p1=gmul(p1,gadd(r[i],r[i+5]));563return p1;564}565else if ((n1==39 && n2==38) || (n1==29 && n2==25))566{567for (i=1; i<6; i++) z[i]=gadd(r[2*i-1],r[2*i]);568p1=gsub(r[1],r[2]);569for (i=2; i<6; i++) p1=gmul(p1,gsub(r[2*i-1],r[2*i]));570p2=gsub(z[4],z[5]);571for (i=1; i<4; i++) for (j=i+1; j<6; j++) p2=gmul(p2,gsub(z[i],z[j]));572return gmul(p1,p2);573}574else if ((n1==39 && n2==36) || (n1==37 && n2==34) || (n1==29 && n2==23)575|| (n1==24 && n2==15))576{577for (i=1; i<6; i++) z[i]=gadd(r[2*i-1],r[2*i]);578p1=gsub(z[4],z[5]); p2=gmul(gsub(z[3],z[4]),gsub(z[3],z[5]));579for (i=1; i<3; i++) for (j=i+1; j<6; j++) p2=gmul(p2,gsub(z[i],z[j]));580return gmul(p1,p2);581}582else if ((n1==39 && n2==29) || (n1==38 && n2==25) || (n1==37 && n2==24)583|| (n1==36 && n2==23) || (n1==34 && n2==15))584{585for (i=1; i<6; i++) z[i]=gadd(r[2*i-1],r[2*i]);586p2=gadd(z[2],z[5]);587p2=gsub(p2,gadd(z[3],z[4]));588p1=gmul(p2,z[1]);589p2=gsub(z[3],gadd(z[4],z[5]));590p1=gadd(p1,gmul(p2,z[2]));591p2=gsub(z[4],z[5]);592p1=gadd(p1,gmul(p2,z[3]));593p1=gadd(p1,gmul(z[4],z[5]));594return gsqr(p1);595}596else if ((n1==39 && n2==22) || (n1==38 && n2==12) || (n1==36 && n2==11)597|| (n1==29 && n2== 5) || (n1==25 && n2== 4) || (n1==23 && n2== 3)598|| (n1==16 && n2== 2) || (n1==14 && n2== 1))599{600p1=r[1]; for (i=2; i<6; i++) p1=gadd(p1,r[2*i-1]);601p2=r[2]; for (i=2; i<6; i++) p2=gadd(p2,r[2*i]);602return gmul(p1,p2);603}604else if (n1==28 && n2==18)605{606zaux(z, r);607p1=gmul(z[1],gsub(z[3],z[4]));608p2=gmul(z[2],gadd(z[3],z[4])); return gadd(p1,p2);609}610else if (n1==27 && n2==20)611{612zaux(z, r); p1=gmul(z[1],z[3]); p2=gmul(z[2],z[4]);613p1 = gsub(p1,p2); p2=r[1];614for (i=2; i<6 ; i++) p2=gadd(p2,r[i]);615for ( ; i<11; i++) p2=gsub(p2,r[i]);616return gmul(p1,p2);617}618else if (n1==27 && n2==19)619{620zaux(z, r); p1=gmul(z[1],z[3]); p2=gmul(z[2],z[4]);621return gsub(p1,p2);622}623else if ((n1==27 && n2==17) || (n1==21 && n2==9))624{625zaux(z, r); p1=gmul(z[1],z[3]); p2=gmul(z[2],z[4]);626return gadd(p1,p2);627}628else if (n1==23 && n2==16)629{630for (i=1; i<6; i++) z[i]=gadd(r[2*i-1],r[2*i]);631p1=gsub(z[1],gadd(z[2],z[5])); p1=gmul(p1,gsub(z[2],z[5]));632p2=gmul(p1,z[1]); p1=gsub(z[3],gadd(z[2],z[4]));633p1=gmul( p1,gsub(z[4],z[2])); p2=gadd(p2,gmul(p1,z[3]));634p1=gmul(z[5],gsub(z[4],z[5])); p2=gadd(p2,gmul(p1,z[4]));635p1=gsub(r[1],r[2]);636for (i=2; i<6; i++) p1=gmul(p1,gsub(r[2*i-1],r[2*i]));637return gmul(p1,p2);638}639else if (n1==22 && n2==12)640{641for (i=1; i<6; i++) z[i]=gadd(r[i],r[i+5]);642p1=gsub(r[1],r[6]);643for (i=2; i<6; i++) p1=gmul(p1,gsub(r[i],r[i+5]));644p2=gsub(z[4],z[5]);645for (i=1; i<4; i++) for (j=i+1; j<6; j++) p2=gmul(p2,gsub(z[i],z[j]));646return gmul(p1,p2);647}648else if ((n1==22 && n2==11) || (n1==5 && n2==3))649{650for (i=1; i<6; i++) z[i]=gadd(r[i],r[i+5]);651p1=gsub(z[4],z[5]); p2=gmul(gsub(z[3],z[4]),gsub(z[3],z[5]));652for (i=1; i<3; i++) for (j=i+1; j<6; j++) p2=gmul(p2,gsub(z[i],z[j]));653return gmul(p1,p2);654}655else if ((n1==22 && n2==5) || (n1==12 && n2==4) || (n1==11 && n2==3))656{657for (i=1; i<6; i++) z[i]=gadd(r[i],r[i+5]);658p2=gadd(z[2],z[5]); p2=gsub(p2,gadd(z[3],z[4])); p1=gmul(p2,z[1]);659p2=gsub(z[3],gadd(z[4],z[5])); p1=gadd(p1,gmul(p2,z[2]));660p2=gsub(z[4],z[5]);661p1=gadd(p1,gmul(p2,z[3])); p1=gadd(p1,gmul(z[4],z[5]));662return gsqr(p1);663}664else if (n1==21 && n2==10)665{666zaux(z, r); p1=gmul(z[1],z[4]); p2=gmul(z[2],z[3]);667return gsub(p1,p2);668}669}670pari_err_TYPE("gpoly [undefined invariant polynomial]", mkvecsmall2(n1,n2));671return NULL; /* LCOV_EXCL_LINE */672}673674/* a is a t_VECSMALL representing a polynomial */675static GEN676new_pol(long N, GEN r, GEN a)677{678long i, j, l = lg(a);679GEN x, z, v = cgetg(N+1, t_VEC);680for (i=1; i<=N; i++)681{682z = gel(r,i); x = gaddsg(a[2], z);683for (j = 3; j < l; j++) x = gaddsg(a[j], gmul(z,x));684gel(v,i) = x;685}686return gclone(v);687}688689/* BR->r[l], BR->coef[l] hold data related to Tschirnausen transform of690* degree l - 1 */691static void692tschirn(buildroot *BR)693{694long i, k, v = varn(BR->p), l = lg(BR->r);695GEN a, h, r;696697if (l >= BR->N) pari_err_BUG("tschirn");698if (DEBUGLEVEL)699err_printf("\n$$$$$ Tschirnhaus transformation of degree %ld: $$$$$\n",l-1);700701a = gel(BR->coef,l); /* fill with random polynomial of degree <= l-1 */702do703{704a[1]=0;705for (i=2; i < l+2; i++) a[i] = random_bits(3) + 1;706h = Flx_to_ZX(Flx_renormalize(a,l+2));707} while (degpol(h) <= 0 || !ZX_is_squarefree(h));708setvarn(h, v); k = 0;709(void)ZXQ_charpoly_sqf(BR->p, h, &k, v);710a[2] += k;711712r = gel(BR->r,1);713preci(r, BR->prmax); /* max accuracy original roots */714vectrunc_append(BR->r, new_pol(BR->N, r, a));715fixprec(BR); /* restore accuracy */716}717718static GEN719sortroots(GEN newr, GEN oldr)720{721long e, e0, i, j, k, l = lg(newr);722GEN r = cgetg(l, t_VEC), z = cgetg(l, t_VEC), t = const_vecsmall(l-1, 1);723k = 0; /* gcc -Wall */724for (i=1; i<l; i++)725{726e0 = EXPOBITS;727for (j=1; j<l; j++)728if (t[j])729{730e = gexpo(gsub(gel(oldr,i), gel(newr,j)));731if (e < e0) { e0 = e; k = j; }732}733gel(z,i) = gel(newr,k); t[k] = 0;734}735for (i=1; i<l; i++) gel(r,i) = gel(z,i);736return r;737}738739static void740delete_roots(buildroot *BR)741{742GEN r = BR->r;743long i, l = lg(r);744for (i = 1; i < l; i++) gunclone(gel(r,i));745setlg(r, 1);746}747748/* increase the roots accuracy */749static void750moreprec(buildroot *BR)751{752long d = BR->pr - BR->prmax;753if (d > 0)754{ /* recompute roots */755pari_sp av = avma;756long l = lg(BR->r);757GEN ro;758759if (d < BIGDEFAULTPREC-2) d = BIGDEFAULTPREC-2;760BR->prmax = maxss(BR->prmax+d, (long)(BR->prmax * 1.2));761if (DEBUGLEVEL) err_printf("$$$$$ New prec = %ld\n",BR->prmax);762ro = sortroots(QX_complex_roots(BR->p,BR->prmax), gel(BR->r,1));763delete_roots(BR);764vectrunc_append(BR->r, gclone(ro));765for (d = 2; d < l; d++)766vectrunc_append(BR->r, new_pol(BR->N, ro, gel(BR->coef,d)));767set_avma(av);768}769fixprec(BR);770}771772/* determine "sufficient" extra bit-precision such that we may decide773* (heuristic) whether z is an integer. */774static GEN775get_ro(long N, GEN rr, PERM S1, PERM S2, resolv *R)776{777GEN r = cgetg(N+1, t_VEC);778long i;779for (i=1; i<=N; i++) r[i] = rr[ S1[S2[i] ] ];780return R->a? gpolynomial(r, R): gpoly(r,R->nm,R->nv);781}782/* typ(z) = t_REAL, return zi = t_INT approximation */783static long784sufprec_r(GEN z)785{786long p = bit_prec(z);787/* bit accuracy of fractional part large enough ? */788return ( p - expo(z) > maxss(3*32, (long)0.2*p) );789}790/* typ(z) = t_REAL or t_COMPLEX, return zi = t_INT approximation */791static long792sufprec(GEN z)793{794if (typ(z) == t_REAL)795return sufprec_r(z);796else797return sufprec_r(gel(z,2)) && sufprec_r(gel(z,1));798}799800static GEN801get_ro_perm(PERM S1, PERM S2, long d, resolv *R, buildroot *BR)802{803GEN ro, roi;804long e;805for (;;)806{807ro = get_ro(BR->N, gel(BR->r, d), S1,S2,R); roi = grndtoi(ro, &e);808if (e < 0)809{810if (e < -64 || sufprec(ro)) break;811e = 0;812}813BR->pr += nbits2extraprec(e + 10);814moreprec(BR);815}816if (e > -10 || typ(roi) == t_COMPLEX) return NULL;817/* compute with 128 more bits */818BR->pr += MEDDEFAULTPREC-2;819moreprec(BR);820ro = get_ro(BR->N, gel(BR->r, d), S1,S2,R);821BR->pr -= MEDDEFAULTPREC-2;822fixprec(BR);823/* ro closer to roi (32 more bits) ? */824return (gexpo(gsub(ro, roi)) < e - 32) ? roi: NULL;825}826827static void828dbg_rac(long nri,long nbracint,long numi[],GEN racint[],long multi[])829{830long k;831err_printf("\t# rational integer roots = %ld:",nbracint-nri);832for (k = nri+1; k <= nbracint; k++) err_printf(" %ld^%ld", numi[k], multi[k]);833err_printf("\n");834for (k = nri+1; k <= nbracint; k++) err_printf("\t%2ld: %Ps\n", numi[k], racint[k]);835}836837#define M 2521838/* return NULL if not included, the permutation of the roots otherwise */839static PERM840check_isin(buildroot *BR, resolv *R, GROUP tau, GROUP ss)841{842long nogr, nocos, init, i, j, k, l, d;843pari_sp av1 = avma, av2;844long nbgr,nbcos,nbracint,nbrac,lastnbri,lastnbrm;845long numi[M],numj[M],lastnum[M],multi[M],norac[M],lastnor[M];846GEN racint[M], roint;847848if (getpreci(BR) != BR->pr) fixprec(BR);849nbcos = getcard_obj(ss);850nbgr = getcard_obj(tau);851lastnbri = lastnbrm = -1; nbracint = nbrac = 0; /* gcc -Wall*/852for (nogr=1; nogr<=nbgr; nogr++)853{854PERM T = tau[nogr];855if (DEBUGLEVEL) err_printf(" ----> Group # %ld/%ld:\n",nogr,nbgr);856init = 0; d = 1;857for (;;)858{859if (!init)860{861av2 = avma; nbrac = nbracint = 0;862for (nocos=1; nocos<=nbcos; nocos++, set_avma(av2))863{864roint = get_ro_perm(T, ss[nocos], d, R, BR);865if (!roint) continue;866867nbrac++;868if (nbrac >= M)869{870pari_warn(warner, "more than %ld rational integer roots\n", M);871set_avma(av1); goto NEXT;872}873for (j=1; j<=nbracint; j++)874if (equalii(roint,racint[j])) { multi[j]++; break; }875if (j > nbracint)876{877nbracint = j; multi[j] = 1; numi[j] = nocos;878racint[j] = gerepileuptoint(av2,roint); av2 = avma;879}880numj[nbrac] = nocos; norac[nbrac] = j;881}882if (DEBUGLEVEL) dbg_rac(0,nbracint,numi,racint,multi);883for (i=1; i<=nbracint; i++)884if (multi[i]==1) return permmul(T, ss[numi[i]]);885init = 1;886}887else888{889nbrac = nbracint = 0;890for (l=1; l<=lastnbri; l++, set_avma(av1))891{892long nri = nbracint;893av2 = avma;894for (k=1; k<=lastnbrm; k++)895if (lastnor[k]==l)896{897nocos = lastnum[k];898roint = get_ro_perm(T, ss[nocos], d, R, BR);899if (!roint) { set_avma(av2); continue; }900901nbrac++;902for (j=nri+1; j<=nbracint; j++)903if (equalii(roint,racint[j])) { multi[j]++; break; }904if (j > nbracint)905{906nbracint = j; multi[j] = 1; numi[j] = nocos;907racint[j] = gerepileuptoint(av2,roint); av2=avma;908}909numj[nbrac] = nocos; norac[nbrac] = j;910}911if (DEBUGLEVEL) dbg_rac(nri,nbracint,numi,racint,multi);912for (i=nri+1; i<=nbracint; i++)913if (multi[i]==1) return permmul(T, ss[numi[i]]);914}915}916set_avma(av1); if (!nbracint) break;917918lastnbri = nbracint; lastnbrm = nbrac;919for (j=1; j<=nbrac; j++) { lastnum[j] = numj[j]; lastnor[j] = norac[j]; }920921NEXT:922if (DEBUGLEVEL) {923err_printf(" all integer roots are double roots\n");924err_printf(" Working with polynomial #%ld:\n", d+1);925}926if (++d >= lg(BR->r)) tschirn(BR);927}928}929return NULL;930}931#undef M932933/* DEGREE 8 */934static long935galoisprim8(long EVEN, buildroot *BR)936{937long rep;938939rep=isin_G_H(BR,50,43);940if (rep) return EVEN? 37: 43;941if (!EVEN) return 50;942rep=isin_G_H(BR,49,48);943if (!rep) return 49;944rep=isin_G_H(BR,48,36);945if (!rep) return 48;946rep=isin_G_H(BR,36,25);947return rep? 25: 36;948}949950static long951galoisimpodd8(buildroot *BR, long nh)952{953long rep;954if (nh!=47) goto IMPODD_8_6;955rep=isin_G_H(BR,47,46);956if (!rep) goto IMPODD_8_5;957rep=isin_G_H(BR,46,28);958if (rep) goto IMPODD_8_7; else return 46;959960IMPODD_8_5:961rep=isin_G_H(BR,47,35);962if (rep) goto IMPODD_8_9; else return 47;963964IMPODD_8_6:965rep=isin_G_H(BR,44,40);966if (rep) goto IMPODD_8_10; else goto IMPODD_8_11;967968IMPODD_8_7:969rep=isin_G_H(BR,28,21);970if (rep) return 21; else goto IMPODD_8_33;971972IMPODD_8_9:973rep=isin_G_H(BR,35,31);974if (rep) goto IMPODD_8_13; else goto IMPODD_8_14;975976IMPODD_8_10:977rep=isin_G_H(BR,40,26);978if (rep) goto IMPODD_8_15; else goto IMPODD_8_16;979980IMPODD_8_11:981rep=isin_G_H(BR,44,38);982if (rep) goto IMPODD_8_17; else goto IMPODD_8_18;983984IMPODD_8_12:985rep=isin_G_H(BR,16,7);986if (rep) goto IMPODD_8_19; else return 16;987988IMPODD_8_13:989rep=isin_G_H(BR,31,21);990return rep? 21: 31;991992IMPODD_8_14:993rep=isin_G_H(BR,35,30);994if (rep) goto IMPODD_8_34; else goto IMPODD_8_20;995996IMPODD_8_15:997rep=isin_G_H(BR,26,16);998if (rep) goto IMPODD_8_12; else goto IMPODD_8_21;9991000IMPODD_8_16:1001rep=isin_G_H(BR,40,23);1002if (rep) goto IMPODD_8_22; else return 40;10031004IMPODD_8_17:1005rep=isin_G_H(BR,38,31);1006if (rep) goto IMPODD_8_13; else return 38;10071008IMPODD_8_18:1009rep=isin_G_H(BR,44,35);1010if (rep) goto IMPODD_8_9; else return 44;10111012IMPODD_8_19:1013rep=isin_G_H(BR,7,1);1014return rep? 1: 7;10151016IMPODD_8_20:1017rep=isin_G_H(BR,35,28);1018if (rep) goto IMPODD_8_7; else goto IMPODD_8_23;10191020IMPODD_8_21:1021rep=isin_G_H(BR,26,17);1022if (rep) goto IMPODD_8_24; else goto IMPODD_8_25;10231024IMPODD_8_22:1025rep=isin_G_H(BR,23,8);1026if (rep) goto IMPODD_8_26; else return 23;10271028IMPODD_8_23:1029rep=isin_G_H(BR,35,27);1030if (rep) goto IMPODD_8_27; else goto IMPODD_8_28;10311032IMPODD_8_24:1033rep=isin_G_H(BR,17,7);1034if (rep) goto IMPODD_8_19; else return 17;10351036IMPODD_8_25:1037rep=isin_G_H(BR,26,15);1038if (rep) goto IMPODD_8_29; else return 26;10391040IMPODD_8_26:1041rep=isin_G_H(BR,8,1);1042return rep? 1: 8;10431044IMPODD_8_27:1045rep=isin_G_H(BR,27,16);1046if (rep) goto IMPODD_8_12; else return 27;10471048IMPODD_8_28:1049rep=isin_G_H(BR,35,26);1050if (rep) goto IMPODD_8_15; else return 35;10511052IMPODD_8_29:1053rep=isin_G_H(BR,15,7);1054if (rep) goto IMPODD_8_19;1055rep=isin_G_H(BR,15,6);1056if (!rep) goto IMPODD_8_32;1057rep=isin_G_H(BR,6,1);1058return rep? 1: 6;10591060IMPODD_8_32:1061rep=isin_G_H(BR,15,8);1062if (rep) goto IMPODD_8_26; else return 15;10631064IMPODD_8_33:1065rep=isin_G_H(BR,28,16);1066if (rep) goto IMPODD_8_12; else return 28;10671068IMPODD_8_34:1069rep=isin_G_H(BR,30,21);1070return rep? 21: 30;1071}10721073static long1074galoisimpeven8(buildroot *BR, long nh)1075{1076long rep;1077if (nh!=45) goto IMPEVEN_8_6;1078rep=isin_G_H(BR,45,42);1079if (!rep) goto IMPEVEN_8_5;1080rep=isin_G_H(BR,42,34);1081if (rep) goto IMPEVEN_8_7; else goto IMPEVEN_8_8;10821083IMPEVEN_8_5:1084rep=isin_G_H(BR,45,41);1085if (rep) goto IMPEVEN_8_9; else return 45;10861087IMPEVEN_8_6:1088rep=isin_G_H(BR,39,32);1089if (rep) goto IMPEVEN_8_10; else goto IMPEVEN_8_11;10901091IMPEVEN_8_7:1092rep=isin_G_H(BR,34,18);1093if (rep) goto IMPEVEN_8_21; else goto IMPEVEN_8_45;10941095IMPEVEN_8_8:1096rep=isin_G_H(BR,42,33);1097if (rep) goto IMPEVEN_8_14; else return 42;10981099IMPEVEN_8_9:1100rep=isin_G_H(BR,41,34);1101if (rep) goto IMPEVEN_8_7; else goto IMPEVEN_8_15;11021103IMPEVEN_8_10:1104rep=isin_G_H(BR,32,22);1105if (rep) goto IMPEVEN_8_16; else goto IMPEVEN_8_17;11061107IMPEVEN_8_11:1108rep=isin_G_H(BR,39,29);1109if (rep) goto IMPEVEN_8_18; else goto IMPEVEN_8_19;11101111IMPEVEN_8_12:1112rep=isin_G_H(BR,14,4);1113return rep? 4: 14;11141115IMPEVEN_8_14:1116rep=isin_G_H(BR,33,18);1117if (rep) goto IMPEVEN_8_21; else goto IMPEVEN_8_22;11181119IMPEVEN_8_15:1120rep=isin_G_H(BR,41,33);1121if (rep) goto IMPEVEN_8_14; else goto IMPEVEN_8_23;11221123IMPEVEN_8_16:1124rep=isin_G_H(BR,22,11);1125if (rep) goto IMPEVEN_8_24; else goto IMPEVEN_8_25;11261127IMPEVEN_8_17:1128rep=isin_G_H(BR,32,13);1129if (rep) goto IMPEVEN_8_26; else goto IMPEVEN_8_27;11301131IMPEVEN_8_18:1132rep=isin_G_H(BR,29,22);1133if (rep) goto IMPEVEN_8_16; else goto IMPEVEN_8_28;11341135IMPEVEN_8_19:1136rep=isin_G_H(BR,39,24);1137if (rep) goto IMPEVEN_8_29; else return 39;11381139IMPEVEN_8_20:1140rep=isin_G_H(BR,9,4);1141if (rep) return 4; else goto IMPEVEN_8_30;11421143IMPEVEN_8_21:1144rep=isin_G_H(BR,18,10);1145if (rep) goto IMPEVEN_8_31; else goto IMPEVEN_8_32;11461147IMPEVEN_8_22:1148rep=isin_G_H(BR,33,13);1149if (rep) goto IMPEVEN_8_26; else return 33;11501151IMPEVEN_8_23:1152rep=isin_G_H(BR,41,29);1153if (rep) goto IMPEVEN_8_18; else goto IMPEVEN_8_33;11541155IMPEVEN_8_24:1156rep=isin_G_H(BR,11,5);1157if (rep) return 5; else goto IMPEVEN_8_34;11581159IMPEVEN_8_25:1160rep=isin_G_H(BR,22,9);1161if (rep) goto IMPEVEN_8_20; else return 22;11621163IMPEVEN_8_26:1164rep=isin_G_H(BR,13,3);1165return rep? 3: 13;11661167IMPEVEN_8_27:1168rep=isin_G_H(BR,32,12);1169if (rep) goto IMPEVEN_8_35; else return 32;11701171IMPEVEN_8_28:1172rep=isin_G_H(BR,29,20);1173if (rep) goto IMPEVEN_8_36; else goto IMPEVEN_8_37;11741175IMPEVEN_8_29:1176rep=isin_G_H(BR,24,14);1177if (rep) goto IMPEVEN_8_12; else goto IMPEVEN_8_38;11781179IMPEVEN_8_30:1180rep=isin_G_H(BR,9,3);1181if (rep) return 3; else goto IMPEVEN_8_39;11821183IMPEVEN_8_31:1184rep=isin_G_H(BR,10,2);1185return rep? 2: 10;11861187IMPEVEN_8_32:1188rep=isin_G_H(BR,18,9);1189if (rep) goto IMPEVEN_8_20; else return 18;11901191IMPEVEN_8_33:1192rep=isin_G_H(BR,41,24);1193if (rep) goto IMPEVEN_8_29; else return 41;11941195IMPEVEN_8_34:1196rep=isin_G_H(BR,11,4);1197if (rep) return 4; else goto IMPEVEN_8_44;11981199IMPEVEN_8_35:1200rep=isin_G_H(BR,12,5);1201return rep? 5: 12;12021203IMPEVEN_8_36:1204rep=isin_G_H(BR,20,10);1205if (rep) goto IMPEVEN_8_31; else return 20;12061207IMPEVEN_8_37:1208rep=isin_G_H(BR,29,19);1209if (rep) goto IMPEVEN_8_40; else goto IMPEVEN_8_41;12101211IMPEVEN_8_38:1212rep=isin_G_H(BR,24,13);1213if (rep) goto IMPEVEN_8_26; else goto IMPEVEN_8_42;12141215IMPEVEN_8_39:1216rep=isin_G_H(BR,9,2);1217return rep? 2: 9;12181219IMPEVEN_8_40:1220rep=isin_G_H(BR,19,10);1221if (rep) goto IMPEVEN_8_31; else goto IMPEVEN_8_43;12221223IMPEVEN_8_41:1224rep=isin_G_H(BR,29,18);1225if (rep) goto IMPEVEN_8_21; else return 29;12261227IMPEVEN_8_42:1228rep=isin_G_H(BR,24,9);1229if (rep) goto IMPEVEN_8_20; else return 24;12301231IMPEVEN_8_43:1232rep=isin_G_H(BR,19,9);1233if (rep) goto IMPEVEN_8_20; else return 19;12341235IMPEVEN_8_44:1236rep=isin_G_H(BR,11,2);1237return rep? 2: 11;12381239IMPEVEN_8_45:1240rep=isin_G_H(BR,34,14);1241if (rep) goto IMPEVEN_8_12; else return 34;1242}12431244static long1245closure8(long EVEN, buildroot *BR)1246{1247long rep;12481249if (!EVEN)1250{1251rep=isin_G_H(BR,50,47);1252if (rep) return galoisimpodd8(BR,47);1253rep=isin_G_H(BR,50,44);1254if (rep) return galoisimpodd8(BR,44);1255}1256else1257{1258rep=isin_G_H(BR,49,45);1259if (rep) return galoisimpeven8(BR,45);1260rep=isin_G_H(BR,49,39);1261if (rep) return galoisimpeven8(BR,39);1262}1263return galoisprim8(EVEN, BR);1264}12651266static GROUP1267initgroup(long n, long nbgr)1268{1269GROUP t = allocgroup(n,nbgr);1270PERM ID = t[1];1271long i;1272for (i = 1; i <= n; i++) ID[i] = i;1273return t;1274}12751276static PERM1277data8(long N, long n1, long n2, GROUP *t)1278{1279switch(n1)1280{1281case 7: if (n2!=1) break;1282*t=initgroup(N,2);1283_aff(N, (*t)[2], 1, 2, 3, 4, 6, 5, 8, 7);1284return (*t)[1];1285case 9: if (n2!=4) break;1286*t=initgroup(N,2);1287_aff(N, (*t)[2], 1, 2, 4, 3, 5, 6, 8, 7);1288return (*t)[1];1289case 10: if (n2!=2) break;1290*t=initgroup(N,2);1291_aff(N, (*t)[2], 1, 2, 3, 4, 6, 5, 8, 7);1292return (*t)[1];1293case 11:1294switch(n2)1295{1296case 2:1297*t=initgroup(N,2);1298_aff(N, (*t)[2], 1, 2, 5, 6, 3, 4, 8, 7);1299return _cr(N, 1, 3, 5, 8, 2, 4, 6, 7);1300case 4:1301*t=initgroup(N,1);1302return _cr(N, 1, 3, 7, 5, 2, 4, 8, 6);1303}break;1304case 14: if (n2!=4) break;1305*t=initgroup(N,1);1306return _cr(N, 1, 2, 4, 3, 5, 6, 8, 7);1307case 15: if (n2!=6 && n2!=8) break;1308*t=initgroup(N,2);1309_aff(N, (*t)[2], 1, 2, 3, 4, 6, 5, 8, 7);1310return (*t)[1];1311case 16: if (n2!=7) break;1312*t=initgroup(N,2);1313_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 8, 7);1314return (*t)[1];1315case 18:1316switch(n2)1317{1318case 9: *t=initgroup(N,3);1319_aff(N, (*t)[2], 1, 5, 3, 7, 2, 6, 4, 8);1320_aff(N, (*t)[3], 1, 2, 3, 4, 6, 5, 8, 7);1321return (*t)[1];1322case 10: *t=initgroup(N,3);1323_aff(N, (*t)[2], 1, 6, 3, 8, 2, 5, 4, 7);1324_aff(N, (*t)[3], 1, 5, 3, 7, 2, 6, 4, 8);1325return (*t)[1];1326}break;1327case 19: if (n2!=9) break;1328*t=initgroup(N,1);1329return _cr(N, 1, 5, 3, 8, 2, 6, 4, 7);1330case 20: if (n2!=10) break;1331*t=initgroup(N,2);1332_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 8, 7);1333return (*t)[1];1334case 22:1335switch(n2)1336{1337case 9: *t=initgroup(N,6);1338_aff(N, (*t)[2], 1, 2, 7, 8, 3, 4, 6, 5);1339_aff(N, (*t)[3], 1, 2, 7, 8, 3, 4, 5, 6);1340_aff(N, (*t)[4], 1, 2, 5, 6, 3, 4, 8, 7);1341_aff(N, (*t)[5], 1, 2, 5, 6, 3, 4, 7, 8);1342_aff(N, (*t)[6], 1, 2, 3, 4, 5, 6, 8, 7);1343return _cr(N, 1, 3, 5, 7, 2, 4, 6, 8);1344case 11: *t=initgroup(N,6);1345_aff(N, (*t)[2], 1, 2, 5, 6, 7, 8, 4, 3);1346_aff(N, (*t)[3], 1, 2, 5, 6, 7, 8, 3, 4);1347_aff(N, (*t)[4], 1, 2, 3, 4, 7, 8, 6, 5);1348_aff(N, (*t)[5], 1, 2, 3, 4, 7, 8, 5, 6);1349_aff(N, (*t)[6], 1, 2, 3, 4, 5, 6, 8, 7);1350return (*t)[1];1351}break;1352case 23: if (n2!=8) break;1353*t=initgroup(N,1);1354return _cr(N, 1, 2, 3, 4, 6, 5, 8, 7);1355case 26: if (n2!=15 && n2!=17) break;1356*t=initgroup(N,2);1357_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 8, 7);1358return (*t)[1];1359case 28: if (n2!=21) break;1360*t=initgroup(N,1);1361return _cr(N, 1, 2, 3, 4, 7, 8, 5, 6);1362case 29: if (n2!=18 && n2!=19) break;1363*t=initgroup(N,2);1364_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 8, 7);1365return (*t)[1];1366case 30: if (n2!=21) break;1367*t=initgroup(N,1);1368return _cr(N, 1, 2, 3, 4, 7, 8, 5, 6);1369case 31: if (n2!=21) break;1370*t=initgroup(N,3);1371_aff(N, (*t)[2], 1, 2, 3, 4, 7, 8, 5, 6);1372_aff(N, (*t)[3], 1, 2, 5, 6, 7, 8, 3, 4);1373return (*t)[1];1374case 32: if (n2!=12 && n2!=13) break;1375*t=initgroup(N,2);1376_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 8, 7);1377return (*t)[1];1378case 33:1379switch(n2)1380{1381case 13: *t=initgroup(N,1);1382return _cr(N, 1, 5, 2, 6, 3, 7, 4, 8);1383case 18: *t=initgroup(N,1);1384return _cr(N, 1, 2, 5, 6, 3, 4, 7, 8);1385}break;1386case 34:1387switch(n2)1388{1389case 14: *t=initgroup(N,3);1390_aff(N, (*t)[2], 1, 2, 3, 4, 5, 8, 6, 7);1391_aff(N, (*t)[3], 1, 2, 3, 4, 5, 7, 8, 6);1392return _cr(N, 1, 5, 2, 6, 3, 7, 4, 8);1393case 18: *t=initgroup(N,1);1394return _cr(N, 1, 2, 5, 6, 3, 4, 8, 7);1395}break;1396case 39: if (n2!=24) break;1397*t=initgroup(N,2);1398_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 8, 7);1399return (*t)[1];1400case 40: if (n2!=23) break;1401*t=initgroup(N,2);1402_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 8, 7);1403return (*t)[1];1404case 41:1405switch(n2)1406{1407case 24: *t=initgroup(N,1);1408return _cr(N, 1, 5, 2, 6, 3, 7, 4, 8);1409case 29: *t=initgroup(N,1);1410return _cr(N, 1, 2, 5, 6, 3, 4, 7, 8);1411}break;1412case 42: if (n2!=34) break;1413*t=initgroup(N,1);1414return _cr(N, 1, 2, 3, 4, 5, 6, 8, 7);1415case 45: if (n2!=41 && n2!=42) break;1416*t=initgroup(N,2);1417_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 8, 7);1418return (*t)[1];1419case 46: if (n2!=28) break;1420*t=initgroup(N,1);1421return _cr(N, 1, 2, 5, 6, 3, 4, 7, 8);1422case 47: if (n2!=35) break;1423*t=initgroup(N,1);1424return _cr(N, 1, 2, 5, 6, 3, 4, 7, 8);1425case 49: if (n2!=48) break;1426*t=initgroup(N,2);1427_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 8, 7);1428return (*t)[1];1429}1430*t=initgroup(N,1); return (*t)[1];1431}14321433static long1434galoismodulo8(long EVEN, GEN pol, GEN dpol)1435{1436long res, gr[51];1437pari_sp av = avma;1438long **GR = (long**)cgeti(49);1439GEN TYP = partitions_galois(8);14401441/* List of possible types in group j: GR[j][0] = #GR[j] if1442* the group is odd, - #GR[j] if even */1443GR[ 1]= _gr( 4, 1,5,15,22);1444GR[ 2]= _gr( -3, 1,5,15);1445GR[ 3]= _gr( -2, 1,5);1446GR[ 4]= _gr( -3, 1,5,15);1447GR[ 5]= _gr( -3, 1,5,15);1448GR[ 6]= _gr( 5, 1,4,5,15,22);1449GR[ 7]= _gr( 5, 1,3,5,15,22);1450GR[ 8]= _gr( 5, 1,4,5,15,22);1451GR[ 9]= _gr( -4, 1,3,5,15);1452GR[10]= _gr( -4, 1,3,5,15);1453GR[11]= _gr( -4, 1,3,5,15);1454GR[12]= _gr( -5, 1,5,9,15,20);1455GR[13]= _gr( -4, 1,5,9,20);1456GR[14]= _gr( -4, 1,5,9,15);1457GR[15]= _gr( 6, 1,3,4,5,15,22);1458GR[16]= _gr( 5, 1,3,5,15,22);1459GR[17]= _gr( 7, 1,3,5,11,13,15,22);1460GR[18]= _gr( -4, 1,3,5,15);1461GR[19]= _gr( -5, 1,3,5,12,15);1462GR[20]= _gr( -4, 1,3,5,15);1463GR[21]= _gr( 5, 1,3,5,13,15);1464GR[22]= _gr( -4, 1,3,5,15);1465GR[23]= _gr( 7, 1,4,5,9,15,20,22);1466GR[24]= _gr( -6, 1,3,5,9,15,20);1467GR[25]= _gr( -3, 1,5,21);1468GR[26]= _gr( 8, 1,3,4,5,11,13,15,22);1469GR[27]= _gr( 8, 1,2,3,4,5,13,15,22);1470GR[28]= _gr( 7, 1,3,5,12,13,15,22);1471GR[29]= _gr( -5, 1,3,5,12,15);1472GR[30]= _gr( 7, 1,3,4,5,11,13,15);1473GR[31]= _gr( 7, 1,2,3,4,5,13,15);1474GR[32]= _gr( -6, 1,3,5,9,15,20);1475GR[33]= _gr( -6, 1,3,5,9,15,20);1476GR[34]= _gr( -5, 1,3,5,9,15);1477GR[35]= _gr( 10, 1,2,3,4,5,11,12,13,15,22);1478GR[36]= _gr( -5, 1,5,9,20,21);1479GR[37]= _gr( -5, 1,5,9,15,21);1480GR[38]= _gr( 11, 1,2,3,4,5,9,10,13,15,19,20);1481GR[39]= _gr( -7, 1,3,5,9,12,15,20);1482GR[40]= _gr( 10, 1,3,4,5,9,11,13,15,20,22);1483GR[41]= _gr( -7, 1,3,5,9,12,15,20);1484GR[42]= _gr( -8, 1,3,5,6,8,9,15,20);1485GR[43]= _gr( 8, 1,4,5,9,15,19,21,22);1486GR[44]= _gr( 14, 1,2,3,4,5,9,10,11,12,13,15,19,20,22);1487GR[45]= _gr( -9, 1,3,5,6,8,9,12,15,20);1488GR[46]= _gr( 10, 1,3,5,6,8,9,12,13,15,22);1489GR[47]= _gr( 16, 1,2,3,4,5,6,7,8,9,11,12,13,14,15,20,22);1490GR[48]= _gr( -8, 1,3,5,9,12,15,20,21);1491gr[0]=51; res = galmodp(EVEN,pol,dpol,TYP,gr,GR);1492return gc_long(av, res? (EVEN? 49: 50): 0);1493}14941495/* DEGREE 9 */1496static long1497galoisprim9(long EVEN, buildroot *BR)1498{1499long rep;15001501if (!EVEN)1502{1503rep=isin_G_H(BR,34,26);1504if (!rep) return 34;1505rep=isin_G_H(BR,26,19);1506if (!rep) return 26;1507rep=isin_G_H(BR,19,16);1508if (rep) return 16;1509rep=isin_G_H(BR,19,15);1510return rep? 15: 19;1511}1512rep=isin_G_H(BR,33,32);1513if (!rep) goto PRIM_9_7;1514rep=isin_G_H(BR,32,27);1515return rep? 27: 32;15161517PRIM_9_7:1518rep=isin_G_H(BR,33,23);1519if (!rep) return 33;1520rep=isin_G_H(BR,23,14);1521if (!rep) return 23;1522rep=isin_G_H(BR,14,9);1523return rep? 9: 14;1524}15251526static long1527galoisimpodd9(buildroot *BR)1528{1529long rep;15301531rep=isin_G_H(BR,31,29);1532if (!rep) goto IMPODD_9_5;1533rep=isin_G_H(BR,29,20);1534if (!rep) return 29;1535IMPODD_9_3:1536rep=isin_G_H(BR,20,12);1537if (!rep) return 20;1538IMPODD_9_4:1539rep=isin_G_H(BR,12,4);1540return rep? 4: 12;15411542IMPODD_9_5:1543rep=isin_G_H(BR,31,28);1544if (!rep) goto IMPODD_9_9;1545rep=isin_G_H(BR,28,22);1546if (!rep) return 28;1547IMPODD_9_7:1548rep=isin_G_H(BR,22,13);1549if (!rep) return 22;1550IMPODD_9_8:1551rep=isin_G_H(BR,13,4);1552return rep? 4: 13;15531554IMPODD_9_9:1555rep=isin_G_H(BR,31,24);1556if (!rep) return 31;1557rep=isin_G_H(BR,24,22);1558if (rep) goto IMPODD_9_7;1559rep=isin_G_H(BR,24,20);1560if (rep) goto IMPODD_9_3;1561rep=isin_G_H(BR,24,18);1562if (!rep) return 24;1563rep=isin_G_H(BR,18,13);1564if (rep) goto IMPODD_9_8;1565rep=isin_G_H(BR,18,12);1566if (rep) goto IMPODD_9_4;1567rep=isin_G_H(BR,18,8);1568if (!rep) return 18;1569rep=isin_G_H(BR,8,4);1570return rep? 4: 8;1571}15721573static long1574galoisimpeven9(buildroot *BR)1575{1576long rep;15771578rep=isin_G_H(BR,30,25);1579if (!rep) goto IMPEVEN_9_7;1580rep=isin_G_H(BR,25,17);1581if (!rep) return 25;1582IMPEVEN_9_3:1583rep=isin_G_H(BR,17,7);1584if (!rep) goto IMPEVEN_9_5;1585IMPEVEN_9_4:1586rep=isin_G_H(BR,7,2);1587return rep? 2: 7;15881589IMPEVEN_9_5:1590rep=isin_G_H(BR,17,6);1591if (!rep) return 17;1592IMPEVEN_9_6:1593rep=isin_G_H(BR,6,1);1594return rep? 1: 6;15951596IMPEVEN_9_7:1597rep=isin_G_H(BR,30,21);1598if (!rep) return 30;1599rep=isin_G_H(BR,21,17);1600if (rep) goto IMPEVEN_9_3;1601rep=isin_G_H(BR,21,11);1602if (!rep) goto IMPEVEN_9_13;1603rep=isin_G_H(BR,11,7);1604if (rep) goto IMPEVEN_9_4;1605rep=isin_G_H(BR,11,5);1606if (!rep) return 11;1607rep=isin_G_H(BR,5,2);1608return rep? 2: 5;16091610IMPEVEN_9_13:1611rep=isin_G_H(BR,21,10);1612if (!rep) return 21;1613rep=isin_G_H(BR,10,6);1614if (rep) goto IMPEVEN_9_6;1615rep=isin_G_H(BR,10,3);1616if (!rep) return 10;1617rep=isin_G_H(BR,3,1);1618return rep? 1: 3;1619}16201621static long1622closure9(long EVEN, buildroot *BR)1623{1624long rep;1625if (!EVEN)1626{1627rep=isin_G_H(BR,34,31);1628if (rep) return galoisimpodd9(BR);1629}1630else1631{1632rep=isin_G_H(BR,33,30);1633if (rep) return galoisimpeven9(BR);1634}1635return galoisprim9(EVEN, BR);1636}16371638static PERM1639data9(long N, long n1, long n2, GROUP *t)1640{1641switch(n1)1642{1643case 6: if (n2!=1) break;1644*t=initgroup(N,3);1645_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 8, 9, 7);1646_aff(N, (*t)[3], 1, 2, 3, 4, 5, 6, 9, 7, 8);1647return (*t)[1];1648case 7: if (n2!=2) break;1649*t=initgroup(N,3);1650_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 8, 9, 7);1651_aff(N, (*t)[3], 1, 2, 3, 4, 5, 6, 9, 7, 8);1652return (*t)[1];1653case 8: if (n2!=4) break;1654*t=initgroup(N,2);1655_aff(N, (*t)[2], 1, 4, 7, 2, 5, 8, 3, 6, 9);1656return (*t)[1];1657case 12: if (n2!=4) break;1658*t=initgroup(N,3);1659_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 8, 9, 7);1660_aff(N, (*t)[3], 1, 2, 3, 4, 5, 6, 9, 7, 8);1661return (*t)[1];1662case 13: if (n2!=4) break;1663*t=initgroup(N,1);1664return _cr(N, 1, 4, 7, 2, 5, 8, 3, 6, 9);1665case 14: if (n2!=9) break;1666*t=initgroup(N,3);1667_aff(N, (*t)[2], 1, 2, 3, 5, 6, 4, 9, 7, 8);1668_aff(N, (*t)[3], 1, 2, 3, 6, 4, 5, 8, 9, 7);1669return (*t)[1];1670case 17: if (n2!=6) break;1671*t=initgroup(N,2);1672_aff(N, (*t)[2], 1, 2, 3, 7, 8, 9, 4, 5, 6);1673return (*t)[1];1674case 21: if (n2!=10) break;1675*t=initgroup(N,2);1676_aff(N, (*t)[2], 1, 2, 3, 7, 8, 9, 4, 5, 6);1677return (*t)[1];1678case 33: if (n2!=32) break;1679*t=initgroup(N,2);1680_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 7, 9, 8);1681return (*t)[1];1682}1683*t=initgroup(N,1); return (*t)[1];1684}16851686static long1687galoismodulo9(long EVEN, GEN pol, GEN dpol)1688{1689long res, gr[35];1690pari_sp av = avma;1691long **GR = (long**) cgeti(33);1692GEN TYP = partitions_galois(9);16931694/* 42 TYPES ORDONNES CROISSANT (T[1],...,T[30])*/16951696GR[ 1]= _gr( -3, 1,12,30);1697GR[ 2]= _gr( -2, 1,12);1698GR[ 3]= _gr( -4, 1,5,12,30);1699GR[ 4]= _gr( 4, 1,4,12,26);1700GR[ 5]= _gr( -3, 1,5,12);1701GR[ 6]= _gr( -4, 1,10,12,30);1702GR[ 7]= _gr( -3, 1,10,12);1703GR[ 8]= _gr( 5, 1,4,5,12,26);1704GR[ 9]= _gr( -4, 1,5,12,18);1705GR[10]= _gr( -6, 1,5,10,12,25,30);1706GR[11]= _gr( -5, 1,5,10,12,25);1707GR[12]= _gr( 5, 1,4,10,12,26);1708GR[13]= _gr( 5, 1,4,10,12,26);1709GR[14]= _gr( -4, 1,5,12,18);1710GR[15]= _gr( 5, 1,5,12,18,29);1711GR[16]= _gr( 6, 1,4,5,12,18,26);1712GR[17]= _gr( -5, 1,6,10,12,30);1713GR[18]= _gr( 7, 1,4,5,10,12,25,26);1714GR[19]= _gr( 7, 1,4,5,12,18,26,29);1715GR[20]= _gr( 9, 1,4,6,9,10,12,24,26,30);1716GR[21]= _gr( -7, 1,5,6,10,12,25,30);1717GR[22]= _gr( 7, 1,4,6,10,12,26,30);1718GR[23]= _gr( -6, 1,5,10,12,18,25);1719GR[24]= _gr( 11, 1,4,5,6,9,10,12,24,25,26,30);1720GR[25]= _gr( -7, 1,3,6,8,10,12,30);1721GR[26]= _gr( 9, 1,4,5,10,12,18,25,26,29);1722GR[27]= _gr( -5, 1,5,12,27,30);1723GR[28]= _gr( 12, 1,2,3,4,6,7,8,10,11,12,26,30);1724GR[29]= _gr( 12, 1,3,4,6,8,9,10,12,15,24,26,30);1725GR[30]= _gr(-11, 1,3,5,6,8,10,12,14,17,25,30);1726GR[31]= _gr( 19, 1,2,3,4,5,6,7,8,9,10,11,12,14,15,17,24,25,26,30);1727GR[32]= _gr( -7, 1,5,10,12,25,27,30);17281729gr[0]=35; res = galmodp(EVEN,pol,dpol,TYP,gr,GR);1730set_avma(av); if (!res) return 0;1731return EVEN? 33: 34;1732}17331734/* DEGREE 10 */1735static long1736galoisprim10(long EVEN, buildroot *BR)1737{1738long rep;1739if (EVEN)1740{1741rep=isin_G_H(BR,44,31);1742if (!rep) return 44;1743rep=isin_G_H(BR,31,26);1744if (!rep) return 31;1745rep=isin_G_H(BR,26,7);1746return rep? 7: 26;1747}1748else1749{1750rep=isin_G_H(BR,45,35);1751if (!rep) return 45;1752rep=isin_G_H(BR,35,32);1753if (!rep) goto PRIM_10_7;1754rep=isin_G_H(BR,32,13);1755return rep? 13: 32;17561757PRIM_10_7:1758rep=isin_G_H(BR,35,30);1759return rep? 30: 35;1760}1761}17621763static long1764galoisimpeven10(buildroot *BR, long nogr)1765{1766long rep;1767if (nogr==42)1768{1769rep=isin_G_H(BR,42,28);1770if (!rep) return 42;1771rep=isin_G_H(BR,28,18);1772return rep? 18: 28;1773}1774else1775{1776rep=isin_G_H(BR,37,34);1777if (!rep) goto IMPEVEN_10_5;1778rep=isin_G_H(BR,34,15);1779if (rep) goto IMPEVEN_10_7; else return 34;17801781IMPEVEN_10_5:1782rep=isin_G_H(BR,37,24);1783if (!rep) return 37;1784rep=isin_G_H(BR,24,15);1785if (!rep) return 24;1786IMPEVEN_10_7:1787rep=isin_G_H(BR,15,8);1788return rep? 8: 15;1789}1790}17911792static long1793galoisimpodd10(buildroot *BR, long nogr)1794{1795long rep;1796if (nogr==43)1797{1798rep=isin_G_H(BR,43,41);1799if (!rep) goto IMPODD_10_3;1800rep=isin_G_H(BR,41,40);1801if (rep) goto IMPODD_10_4; else goto IMPODD_10_5;18021803IMPODD_10_3:1804rep=isin_G_H(BR,43,33);1805if (rep) goto IMPODD_10_6; else return 43;18061807IMPODD_10_4:1808rep=isin_G_H(BR,40,21);1809if (rep) goto IMPODD_10_7; else goto IMPODD_10_8;18101811IMPODD_10_5:1812rep=isin_G_H(BR,41,27);1813if (rep) goto IMPODD_10_9; else goto IMPODD_10_10;18141815IMPODD_10_6:1816rep=isin_G_H(BR,33,27);1817if (rep) goto IMPODD_10_9; else return 33;18181819IMPODD_10_7:1820rep=isin_G_H(BR,21,10);1821if (rep) goto IMPODD_10_12; else goto IMPODD_10_13;18221823IMPODD_10_8:1824rep=isin_G_H(BR,40,12);1825if (rep) goto IMPODD_10_14; else goto IMPODD_10_15;18261827IMPODD_10_9:1828rep=isin_G_H(BR,27,21);1829if (rep) goto IMPODD_10_7; else goto IMPODD_10_16;18301831IMPODD_10_10:1832rep=isin_G_H(BR,41,22);1833if (!rep) return 41;1834rep=isin_G_H(BR,22,12);1835if (rep) goto IMPODD_10_14; else goto IMPODD_10_18;18361837IMPODD_10_12:1838rep=isin_G_H(BR,10,4);1839return rep? 4: 10;18401841IMPODD_10_13:1842rep=isin_G_H(BR,21,9);1843if (rep) goto IMPODD_10_19; else return 21;1844IMPODD_10_14:1845rep=isin_G_H(BR,12,4);1846return rep? 4: 12;18471848IMPODD_10_15:1849rep=isin_G_H(BR,40,11);1850if (rep) goto IMPODD_10_20; else return 40;1851IMPODD_10_16:1852rep=isin_G_H(BR,27,20);1853if (!rep) goto IMPODD_10_21;1854rep=isin_G_H(BR,20,10);1855if (rep) goto IMPODD_10_12; return 20;18561857IMPODD_10_18:1858rep=isin_G_H(BR,22,11);1859if (rep) goto IMPODD_10_20; else goto IMPODD_10_23;18601861IMPODD_10_19:1862rep=isin_G_H(BR,9,6);1863if (rep) goto IMPODD_10_24; else goto IMPODD_10_25;18641865IMPODD_10_20:1866rep=isin_G_H(BR,11,3);1867if (rep) goto IMPODD_10_26; else return 11;18681869IMPODD_10_21:1870rep=isin_G_H(BR,27,19);1871if (rep) goto IMPODD_10_27;1872rep=isin_G_H(BR,27,17);1873if (rep) goto IMPODD_10_28; else return 27;18741875IMPODD_10_23:1876rep=isin_G_H(BR,22,5);1877if (rep) goto IMPODD_10_29; else return 22;18781879IMPODD_10_24:1880rep=isin_G_H(BR,6,2);1881if (rep) return 2; else goto IMPODD_10_30;18821883IMPODD_10_25:1884rep=isin_G_H(BR,9,3);1885if (!rep) return 9;1886IMPODD_10_26:1887rep=isin_G_H(BR,3,2);1888if (rep) return 2; else goto IMPODD_10_31;18891890IMPODD_10_27:1891rep=isin_G_H(BR,19,9);1892if (rep) goto IMPODD_10_19; else return 19;18931894IMPODD_10_28:1895rep=isin_G_H(BR,17,10);1896if (rep) goto IMPODD_10_12; else goto IMPODD_10_32;18971898IMPODD_10_29:1899rep=isin_G_H(BR,5,4);1900if (rep) return 4; else goto IMPODD_10_33;19011902IMPODD_10_30:1903rep=isin_G_H(BR,6,1);1904return rep? 1: 6;19051906IMPODD_10_31:1907rep=isin_G_H(BR,3,1);1908return rep? 1: 3;19091910IMPODD_10_32:1911rep=isin_G_H(BR,17,9);1912if (rep) goto IMPODD_10_19; else goto IMPODD_10_60;19131914IMPODD_10_33:1915rep=isin_G_H(BR,5,3);1916if (rep) goto IMPODD_10_26; else return 5;19171918IMPODD_10_60:1919rep=isin_G_H(BR,17,5);1920if (rep) goto IMPODD_10_29; else return 17;1921}1922else1923{1924rep=isin_G_H(BR,39,38);1925if (!rep) goto IMPODD_10_36;1926rep=isin_G_H(BR,38,25);1927if (rep) goto IMPODD_10_37; else goto IMPODD_10_38;19281929IMPODD_10_36:1930rep=isin_G_H(BR,39,36);1931if (rep) goto IMPODD_10_39; else goto IMPODD_10_40;19321933IMPODD_10_37:1934rep=isin_G_H(BR,25,4);1935return rep? 4: 25;19361937IMPODD_10_38:1938rep=isin_G_H(BR,38,12);1939if (rep) goto IMPODD_10_41; else return 38;19401941IMPODD_10_39:1942rep=isin_G_H(BR,36,23);1943if (rep) goto IMPODD_10_42; else goto IMPODD_10_43;19441945IMPODD_10_40:1946rep=isin_G_H(BR,39,29);1947if (rep) goto IMPODD_10_44; else goto IMPODD_10_45;19481949IMPODD_10_41:1950rep=isin_G_H(BR,12,4);1951return rep? 4: 12;19521953IMPODD_10_42:1954rep=isin_G_H(BR,23,16);1955if (rep) goto IMPODD_10_46; else goto IMPODD_10_47;19561957IMPODD_10_43:1958rep=isin_G_H(BR,36,11);1959if (rep) goto IMPODD_10_48; else return 36;19601961IMPODD_10_44:1962rep=isin_G_H(BR,29,25);1963if (rep) goto IMPODD_10_37; else goto IMPODD_10_49;19641965IMPODD_10_45:1966rep=isin_G_H(BR,39,22);1967if (rep) goto IMPODD_10_50; else return 39;19681969IMPODD_10_46:1970rep=isin_G_H(BR,16,2);1971return rep? 2: 16;19721973IMPODD_10_47:1974rep=isin_G_H(BR,23,14);1975if (rep) goto IMPODD_10_51; else goto IMPODD_10_52;19761977IMPODD_10_48:1978rep=isin_G_H(BR,11,3);1979if (rep) goto IMPODD_10_53; else return 11;19801981IMPODD_10_49:1982rep=isin_G_H(BR,29,23);1983if (rep) goto IMPODD_10_42; else goto IMPODD_10_54;19841985IMPODD_10_50:1986rep=isin_G_H(BR,22,12);1987if (rep) goto IMPODD_10_41; else goto IMPODD_10_55;19881989IMPODD_10_51:1990rep=isin_G_H(BR,14,1);1991return rep? 1: 14;19921993IMPODD_10_52:1994rep=isin_G_H(BR,23,3);1995if (!rep) return 23;1996IMPODD_10_53:1997rep=isin_G_H(BR,3,2);1998if (rep) return 2; else goto IMPODD_10_57;19992000IMPODD_10_54:2001rep=isin_G_H(BR,29,5);2002if (rep) goto IMPODD_10_58; else return 29;20032004IMPODD_10_55:2005rep=isin_G_H(BR,22,11);2006if (rep) goto IMPODD_10_48;2007rep=isin_G_H(BR,22,5);2008if (rep) goto IMPODD_10_58; else return 22;20092010IMPODD_10_57:2011rep=isin_G_H(BR,3,1);2012return rep? 1: 3;20132014IMPODD_10_58:2015rep=isin_G_H(BR,5,4);2016if (rep) return 4;2017rep=isin_G_H(BR,5,3);2018if (rep) goto IMPODD_10_53; else return 5;2019}2020}20212022static long2023closure10(long EVEN, buildroot *BR)2024{2025long rep;2026if (EVEN)2027{2028rep=isin_G_H(BR,44,42);2029if (rep) return galoisimpeven10(BR,42);2030rep=isin_G_H(BR,44,37);2031if (rep) return galoisimpeven10(BR,37);2032}2033else2034{2035rep=isin_G_H(BR,45,43);2036if (rep) return galoisimpodd10(BR,43);2037rep=isin_G_H(BR,45,39);2038if (rep) return galoisimpodd10(BR,39);2039}2040return galoisprim10(EVEN, BR);2041}20422043static PERM2044data10(long N, long n1,long n2,GROUP *t)2045{2046switch(n1)2047{2048case 6: if (n2!=2) break;2049*t=initgroup(N,1);2050return _cr(N, 1, 2, 3, 4, 5, 6, 10, 9, 8, 7);2051case 9: if (n2!=3 && n2!=6) break;2052*t=initgroup(N,2);2053_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 10, 9, 8, 7);2054return (*t)[1];2055case 10: *t=initgroup(N,2);2056_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 10, 9, 8, 7);2057return (*t)[1];2058case 14: case 16:*t=initgroup(N,1);2059return _cr(N, 1, 3, 5, 7, 9, 2, 4, 6, 8, 10);2060case 17: if (n2!=5) break;2061*t=initgroup(N,2);2062_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 10, 9, 8, 7);2063return (*t)[1];2064case 19: case 20: *t=initgroup(N,2);2065_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 8, 10, 7, 9);2066return (*t)[1];2067case 21: if (n2!=10) break;2068*t=initgroup(N,1);2069return _cr(N, 1, 2, 3, 4, 5, 6, 8, 10, 7, 9);2070case 23: if (n2!=3) break;2071*t=initgroup(N,1);2072return _cr(N, 1, 3, 5, 7, 9, 2, 4, 6, 8, 10);2073case 25: *t=initgroup(N,1);2074return _cr(N, 1, 3, 5, 7, 9, 2, 4, 6, 8, 10);2075case 26: *t=initgroup(N,2);2076_aff(N, (*t)[2], 1, 2, 4, 9, 6, 8, 10, 3, 7, 5);2077return _cr(N, 1, 2, 3, 10, 6, 5, 7, 4, 8, 9);2078case 27: if (n2!=17 && n2!=21) break;2079*t=initgroup(N,2);2080_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 8, 10, 7, 9);2081return (*t)[1];2082case 28: *t=initgroup(N,2);2083_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 8, 10, 7, 9);2084return (*t)[1];2085case 29: if (n2!=5) break;2086*t=initgroup(N,1);2087return _cr(N, 1, 3, 5, 7, 9, 2, 4, 6, 8, 10);2088case 32: *t=initgroup(N,2);2089_aff(N, (*t)[2], 1, 2, 4, 9, 6, 8, 10, 3, 7, 5);2090return _cr(N, 1, 2, 3, 10, 6, 5, 7, 4, 8, 9);2091case 36: if (n2!=11) break;2092*t=initgroup(N,1);2093return _cr(N, 1, 3, 5, 7, 9, 2, 4, 6, 8, 10);2094case 38: if (n2!=12) break;2095*t=initgroup(N,1);2096return _cr(N, 1, 3, 5, 7, 9, 2, 4, 6, 8, 10);2097case 39: if (n2!=22) break;2098*t=initgroup(N,1);2099return _cr(N, 1, 3, 5, 7, 9, 2, 4, 6, 8, 10);2100case 40: if (n2!=12) break;2101*t=initgroup(N,1);2102return _cr(N, 1, 2, 3, 4, 5, 6, 7, 8, 10, 9);2103case 41: if (n2!=22 && n2!=40) break;2104*t=initgroup(N,2);2105_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 7, 8, 10, 9);2106return (*t)[1];2107}2108*t=initgroup(N,1); return (*t)[1];2109}21102111static long2112galoismodulo10(long EVEN, GEN pol, GEN dpol)2113{2114long res, gr[46];2115pari_sp av = avma;2116long **GR = (long**) cgeti(45);2117GEN TYP = partitions_galois(10);21182119GR[ 1]= _gr( 4, 1,6,30,42);2120GR[ 2]= _gr( 3, 1,6,30);2121GR[ 3]= _gr( 5, 1,5,6,30,42);2122GR[ 4]= _gr( 4, 1,5,23,30);2123GR[ 5]= _gr( 7, 1,5,6,22,23,30,42);2124GR[ 6]= _gr( 5, 1,6,24,30,42);2125GR[ 7]= _gr( -4, 1,5,14,30);2126GR[ 8]= _gr( -4, 1,3,5,30);2127GR[ 9]= _gr( 6, 1,5,6,24,30,42);2128GR[10]= _gr( 5, 1,5,23,24,30);2129GR[11]= _gr( 7, 1,5,6,11,30,33,42);2130GR[12]= _gr( 7, 1,5,6,11,23,30,33);2131GR[13]= _gr( 7, 1,4,5,14,23,30,34);2132GR[14]= _gr( 8, 1,2,3,4,5,6,30,42);2133GR[15]= _gr( -6, 1,3,5,18,22,30);2134GR[16]= _gr( 7, 1,3,5,6,17,23,30);2135GR[17]= _gr( 8, 1,5,6,22,23,24,30,42);2136GR[18]= _gr( -6, 1,5,22,24,30,40);2137GR[19]= _gr( 7, 1,5,6,22,24,30,42);2138GR[20]= _gr( 6, 1,5,22,23,24,30);2139GR[21]= _gr( 9, 1,3,5,6,23,24,26,30,42);2140GR[22]= _gr( 11, 1,3,5,6,11,13,22,23,30,33,42);2141GR[23]= _gr( 12, 1,2,3,4,5,6,17,18,22,23,30,42);2142GR[24]= _gr( -7, 1,3,5,18,22,30,40);2143GR[25]= _gr( 8, 1,3,5,18,22,23,30,39);2144GR[26]= _gr( -5, 1,5,14,22,30);2145GR[27]= _gr( 10, 1,3,5,6,22,23,24,26,30,42);2146GR[28]= _gr( -8, 1,3,5,22,24,26,30,40);2147GR[29]= _gr( 14, 1,2,3,4,5,6,17,18,22,23,30,39,40,42);2148GR[30]= _gr( 8, 1,5,6,14,22,30,39,42);2149GR[31]= _gr( -6, 1,5,14,22,30,40);2150GR[32]= _gr( 8, 1,4,5,14,22,23,30,34);2151GR[33]= _gr( 14, 1,3,5,6,15,17,22,23,24,26,29,30,40,42);2152GR[34]= _gr( -9, 1,3,5,11,13,18,22,30,32);2153GR[35]= _gr( 12, 1,4,5,6,14,22,23,30,34,39,40,42);2154GR[36]= _gr( 18, 1,2,3,4,5,6,11,12,13,17,18,22,23,30,31,32,33,42);2155GR[37]= _gr(-12, 1,3,5,11,13,16,18,22,30,32,35,40);2156GR[38]= _gr( 18, 1,3,4,5,6,11,13,15,17,18,21,22,23,30,32,33,35,39);2157GR[39]= _gr( 24, 1,2,3,4,5,6,11,12,13,15,16,17,18,21,22,23,30,31,32,33,35,39,40,42);2158GR[40]= _gr( 14, 1,3,5,6,7,9,11,23,24,26,27,30,33,42);2159GR[41]= _gr( 18, 1,3,5,6,7,9,11,13,16,20,22,23,24,26,27,30,33,42);2160GR[42]= _gr(-17, 1,3,5,7,9,11,13,16,18,20,22,24,26,27,30,35,40);2161GR[43]= _gr( 32, 1,2,3,4,5,6,7,8,9,10,11,12,13,15,16,17,18,19,20,22,23,24,25,26,27,28,29,30,33,35,40,42);2162GR[44]= _gr(-22, 1,3,5,7,9,11,13,14,16,18,20,22,24,26,27,30,32,35,36,38,40,41);2163gr[0]=46; res = galmodp(EVEN,pol,dpol,TYP,gr,GR);2164return gc_long(av, res? (EVEN? 44:45): 0);2165}21662167/* DEGREE 11 */2168static long2169closure11(long EVEN, buildroot *BR)2170{2171long rep;2172if (EVEN)2173{2174rep=isin_G_H(BR,7,6);2175if (!rep) return 7;2176rep=isin_G_H(BR,6,5);2177if (!rep) return 6;2178rep=isin_G_H(BR,5,3);2179if (!rep) return 5;2180rep=isin_G_H(BR,3,1);2181return rep? 1: 3;2182}2183else2184{2185GEN h = BR->p, r = compositum(h, h);2186r = gel(r,lg(r)-1);2187if (degpol(r) == 22) return 2; /* D11 */2188h = leafcopy(h); setvarn(h, fetch_var());2189setvarn(r, 0); r = nffactor(h, r);2190/* S11 (P10*P10*P90) or F_110[11] (11 factors of degree 10) */2191(void)delete_var();2192return (lgcols(r)-1 == 11)? 4: 8;2193}2194}21952196static PERM2197data11(long N, long n1, GROUP *t)2198{2199switch(n1)2200{2201case 5: *t=initgroup(N,1);2202return _cr(N, 1, 2, 3, 7, 8, 6, 11, 5, 9, 4, 10);2203case 6: *t=initgroup(N,1);2204return _cr(N, 1, 2, 3, 4, 6, 10, 11, 9, 7, 5, 8);2205case 7: *t=initgroup(N,2);2206_aff(N, (*t)[2], 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 10);2207return (*t)[1];2208}2209*t=initgroup(N,1); return (*t)[1];2210}22112212static long2213galoismodulo11(long EVEN, GEN pol, GEN dpol)2214{2215long res, gr[6] = {0, 1, 1, 1, 1, 1};2216pari_sp av = avma;2217GEN TYP = cgetg(EVEN? 9: 6, t_VEC);22182219gel(TYP,1) = _typ(1, 11);2220if (EVEN)2221{2222gel(TYP,2) = _typ(3, 8,2,1);2223gel(TYP,3) = _typ(3, 6,3,2);2224gel(TYP,4) = _typ(3, 5,5,1);2225gel(TYP,5) = _typ(5, 4,4,1,1,1);2226gel(TYP,6) = _typ(5, 3,3,3,1,1);2227gel(TYP,7) = _typ(7, 2,2,2,2,1,1,1);2228gel(TYP,8) = _typ(11, 1,1,1,1,1,1,1,1,1,1,1);2229}2230else2231{2232gel(TYP,2) = _typ(2, 10,1);2233gel(TYP,3) = _typ(3, 5,5,1);2234gel(TYP,4) = _typ(6, 2,2,2,2,2,1);2235gel(TYP,5) = _typ(11, 1,1,1,1,1,1,1,1,1,1,1);2236}2237res = galmodp(EVEN,pol,dpol,TYP,gr,NULL);2238return gc_long(av, res? (EVEN? 7: 8): 0);2239}22402241static void2242init_isin(long N, long n1, long n2, GROUP *tau, PERM *s0, resolv *R)2243{2244int fl = 1;2245if (DEBUGLEVEL) err_printf("\n*** Entering isin_%ld_G_H_(%ld,%ld)\n",N,n1,n2);2246switch(N)2247{2248case 8:2249if ((n1==47 && n2==46) || (n1==44 && n2==40)) fl=0;2250*s0=data8(N, n1,n2,tau); break;2251case 9:2252if ((n1==31 && n2==29) || (n1==34 && n2==31) || (n1==33 && n2==30)) fl=0;2253*s0=data9(N,n1,n2,tau); break;2254case 10:2255if ((n1==45 && (n2==43||n2==39))2256|| (n1==44 && (n2==42||n2==37))2257|| (n1==43 && (n2==41||n2==33))2258|| (n1==42 && n2==28)2259|| (n1==41 && (n2==40||n2==27||n2==22))2260|| (n1==40 && (n2==21||n2==11))2261|| (n1==39 && (n2==38||n2==36||n2==29||n2==22))2262|| (n1==38 && (n2==25||n2==12))2263|| (n1==37 && (n2==34||n2==24))2264|| (n1==36 && (n2==23||n2==11))2265|| (n1==34 && n2==15)2266|| (n1==33 && n2==27)2267|| (n1==29 && (n2==25||n2==23||n2==5))2268|| (n1==28 && n2==18)2269|| (n1==27 && (n2==20||n2==19||n2==17))2270|| (n1==25 && n2==4)2271|| (n1==24 && n2==15)2272|| (n1==23 && (n2==16||n2==3))2273|| (n1==22 && (n2==12||n2==11||n2==5))2274|| (n1==21 && (n2==10||n2==9))2275|| (n1==17 && n2==5)2276|| (n1==16 && n2==2)2277|| (n1==14 && n2==1)2278|| (n1==12 && n2==4)2279|| (n1==11 && n2==3)2280|| (n1==10 && n2==4)2281|| (n1== 9 && n2==3)2282|| (n1== 6 && n2==1)2283|| (n1== 5 && n2==3)) fl = 0;2284*s0=data10(N,n1,n2,tau); break;2285default: /* case 11: */2286*s0=data11(N,n1,tau); break;2287}2288if (fl) lireresolv(n1,n2,N,R); else { R->a = NULL; R->nm = n1; R->nv = n2; }2289}22902291static long2292isin_G_H(buildroot *BR, long n1, long n2)2293{2294pari_sp av = avma;2295const long N = BR->N;2296PERM s0, ww;2297GROUP tau, ss = lirecoset(n1,n2,N);2298resolv R;22992300init_isin(N,n1,n2, &tau, &s0, &R);2301ww = check_isin(BR, &R, tau, ss);2302if (ww)2303{2304GEN z = cgetg(N+1, t_VEC);2305long i, j, l = lg(BR->r);2306s0 = permmul(ww, s0);2307if (DEBUGLEVEL)2308{2309err_printf("\n Output of isin_%ld_G_H(%ld,%ld): %ld",N,n1,n2,n2);2310err_printf("\n Reordering of the roots: "); printperm(s0);2311}2312for (i = 1; i < l; i++)2313{2314GEN p1 = gel(BR->r,i);2315for (j=1; j<=N; j++) gel(z,j) = gel(p1,s0[j]);2316for (j=1; j<=N; j++) gel(p1,j) = gel(z,j);2317}2318return gc_long(av, n2);2319}2320if (DEBUGLEVEL)2321err_printf(" Output of isin_%ld_G_H(%ld,%ld): not included.\n",N,n1,n2);2322return gc_long(av, 0);2323}23242325static GEN2326polgaloisnamesbig(long n, long k)2327{2328pari_sp av = avma;2329char *s = stack_malloc(strlen(pari_datadir) + 13 + 20 + 3);2330pariFILE *f;2331GEN V;23322333(void)sprintf(s, "%s/galdata/NAM%ld", pari_datadir, n);2334f = pari_fopengz(s);2335V = f? gp_read_stream(f->file): NULL;2336if (!V || typ(V)!=t_VEC || k>=lg(V)) pari_err_FILE("galois file %s",s);2337pari_fclose(f);2338return gerepilecopy(av, gel(V,k));2339}23402341/* pol a monic ZX */2342static GEN2343galoisbig(GEN pol, long prec)2344{2345pari_sp av = avma;2346const long *tab;2347const long tab8[]={0,23488,8,8,8,8,16,16,16,16,16, 16,24,24,24,32,32,32,32,32,32,234932,32,48,48,56,64,64,64,64,64, 64,96,96,96,128,168,168,192,192,192,2350192,288,336,384,576,576,1152,1344,20160,40320};2351const long tab9[]={0,23529,9,18,18,18,27,27,36,36,54, 54,54,54,72,72,72,81,108,144,162,2353162,162,216,324,324,432,504,648,648,648, 1296,1512,181440,362880};2354const long tab10[]={0,235510,10,20,20,40,50,60,80,100,100, 120,120,120,160,160,160,200,200,200,200,2356200,240,320,320,320,360,400,400,640,720, 720,720,800,960,1440,23571920,1920,1920,3840,7200,14400,14400,28800,1814400,3628800};2358const long tab11[]={0, 11,22,55,110,660,7920,19958400,39916800};2359GEN res, dpol = ZX_disc(pol);2360long t = 0, N = degpol(pol), EVEN = Z_issquare(dpol);23612362if (DEBUGLEVEL)2363{2364err_printf("Galoisbig: polynomial #1 = %Ps\n", pol);2365err_printf("%s group\n", EVEN? "EVEN": "ODD");2366}2367switch(N)2368{2369case 8: t = galoismodulo8(EVEN,pol,dpol); tab=tab8; break;2370case 9: t = galoismodulo9(EVEN,pol,dpol); tab=tab9; break;2371case 10:t = galoismodulo10(EVEN,pol,dpol); tab=tab10; break;2372case 11:t = galoismodulo11(EVEN,pol,dpol); tab=tab11; break;2373default: pari_err_IMPL("galois in degree > 11");2374return NULL; /* LCOV_EXCL_LINE */2375}2376if (!t)2377{2378buildroot BR;2379long i;2380GEN r, z = cgetg(N + 1, t_VEC);2381for (i = 1; i <= N; i++)2382{2383GEN v = cgetg(i+2,t_VECSMALL);2384gel(z,i) = v; v[1] = 0;2385}2386BR.coef = z;2387BR.p = pol;2388BR.pr = prec + nbits2extraprec((long)fujiwara_bound(pol));2389BR.prmax = BR.pr + BIGDEFAULTPREC-2;2390BR.N = N;2391BR.r = vectrunc_init(N+1);2392r = gclone ( QX_complex_roots(BR.p, BR.prmax) );2393vectrunc_append(BR.r, r); preci(r, BR.pr);2394switch(N)2395{2396case 8: t = closure8(EVEN, &BR); break;2397case 9: t = closure9(EVEN, &BR); break;2398case 10: t = closure10(EVEN, &BR); break;2399case 11: t = closure11(EVEN, &BR); break;2400}2401for (i = 1; i < lg(BR.r); i++) gunclone(gel(BR.r,i));2402}2403set_avma(av);2404res = cgetg(5,t_VEC);2405gel(res,1) = stoi(tab[t]);2406gel(res,2) = stoi(EVEN? 1: -1);2407gel(res,3) = stoi(t);2408gel(res,4) = polgaloisnamesbig(N,t);2409return res;2410}24112412/**************************************************************/2413/* Galois group for degree <= 7 */2414/**************************************************************/24152416/* exchange elements i and j in vector x */2417static GEN2418transroot(GEN x, int i, int j)2419{ x = leafcopy(x); swap(gel(x,i), gel(x,j)); return x; }24202421/* x1*x2^2 + x2*x3^2 + x3*x4^2 + x4*x1^2 */2422static GEN2423F4(GEN x)2424{2425return gadd(2426gmul(gel(x,1), gadd(gsqr(gel(x,2)), gmul(gel(x,4),gel(x,1)))),2427gmul(gel(x,3), gadd(gsqr(gel(x,4)), gmul(gel(x,2),gel(x,3)))));2428}24292430static GEN2431roots_to_ZX(GEN z, long *e)2432{2433GEN a = roots_to_pol(z,0);2434GEN b = grndtoi(real_i(a),e);2435long e1 = gexpo(imag_i(a));2436if (e1 > *e) *e = e1;2437return b;2438}24392440static GEN2441polgaloisnames(long a, long b)2442{2443const char * const t[]={"S1", "S2", "A3", "S3",2444"C(4) = 4", "E(4) = 2[x]2", "D(4)", "A4", "S4",2445"C(5) = 5", "D(5) = 5:2", "F(5) = 5:4", "A5", "S5",2446"C(6) = 6 = 3[x]2", "D_6(6) = [3]2", "D(6) = S(3)[x]2",2447"A_4(6) = [2^2]3", "F_18(6) = [3^2]2 = 3 wr 2",2448"2A_4(6) = [2^3]3 = 2 wr 3", "S_4(6d) = [2^2]S(3)",2449"S_4(6c) = 1/2[2^3]S(3)", "F_18(6):2 = [1/2.S(3)^2]2",2450"F_36(6) = 1/2[S(3)^2]2", "2S_4(6) = [2^3]S(3) = 2 wr S(3)",2451"L(6) = PSL(2,5) = A_5(6)", "F_36(6):2 = [S(3)^2]2 = S(3) wr 2",2452"L(6):2 = PGL(2,5) = S_5(6)", "A6", "S6",2453"C(7) = 7", "D(7) = 7:2", "F_21(7) = 7:3", "F_42(7) = 7:6",2454"L(7) = L(3,2)", "A7", "S7"};24552456const long idx[]={0,1,2,4,9,14,30};2457return strtoGENstr(t[idx[a-1]+b-1]);2458}24592460static GEN2461galois_res(long d, long n, long s, long k)2462{2463GEN z = cgetg(5,t_VEC);2464long kk;2465if (new_galois_format)2466kk = k;2467else2468kk = (d == 6 && (k==6 || k==2))? 2: 1;2469gel(z,1) = stoi(n);2470gel(z,2) = stoi(s);2471gel(z,3) = stoi(kk);2472gel(z,4) = polgaloisnames(d,k);2473return z;2474}24752476GEN2477polgalois(GEN x, long prec)2478{2479pari_sp av = avma, av1;2480long i,j,k,n,f,l,l2,e,e1,pr,ind;2481GEN x1,p1,p2,p3,p4,p5,w,z,ee;2482const int ind5[20]={2,5,3,4, 1,3,4,5, 1,5,2,4, 1,2,3,5, 1,4,2,3};2483const int ind6[60]={3,5,4,6, 2,6,4,5, 2,3,5,6, 2,4,3,6, 2,5,3,4,24841,4,5,6, 1,5,3,6, 1,6,3,4, 1,3,4,5, 1,6,2,5,24851,2,4,6, 1,5,2,4, 1,3,2,6, 1,2,3,5, 1,4,2,3};2486if (typ(x)!=t_POL) pari_err_TYPE("galois",x);2487n=degpol(x);2488if (n>11) pari_err_IMPL("galois of degree higher than 11");2489x = Q_primpart(x);2490RgX_check_ZX(x, "galois");2491if (!ZX_is_irred(x)) pari_err_IRREDPOL("galois",x);24922493if (n<4)2494{2495if (n == 1) { set_avma(av); return galois_res(n,1, 1,1); }2496if (n == 2) { set_avma(av); return galois_res(n,2,-1,1); }2497/* n = 3 */2498f = Z_issquare(ZX_disc(x));2499set_avma(av);2500return f? galois_res(n,3,1,1):2501galois_res(n,6,-1,2);2502}2503x1 = x = ZX_Q_normalize(x,NULL); av1=avma;2504if (n > 7) return galoisbig(x, prec);2505for(;;)2506{2507double fb = fujiwara_bound(x);2508switch(n)2509{2510case 4: z = cgetg(7,t_VEC);2511prec = nbits2prec((long)(fb*18.) + 64);2512for(;;)2513{2514p1=QX_complex_roots(x,prec);2515gel(z,1) = F4(p1);2516gel(z,2) = F4(transroot(p1,1,2));2517gel(z,3) = F4(transroot(p1,1,3));2518gel(z,4) = F4(transroot(p1,1,4));2519gel(z,5) = F4(transroot(p1,2,3));2520gel(z,6) = F4(transroot(p1,3,4));2521p5 = roots_to_ZX(z, &e); if (e <= -10) break;2522prec = precdbl(prec);2523}2524if (!ZX_is_squarefree(p5)) goto tchi;2525p2 = gel(ZX_factor(p5),1);2526switch(lg(p2)-1)2527{2528case 1: f = Z_issquare(ZX_disc(x)); set_avma(av);2529return f? galois_res(n,12,1,4): galois_res(n,24,-1,5);25302531case 2: set_avma(av); return galois_res(n,8,-1,3);25322533case 3: set_avma(av);2534return (degpol(gel(p2,1))==2)? galois_res(n,4,1,2)2535: galois_res(n,4,-1,1);25362537default: pari_err_BUG("galois (bug1)");2538}25392540case 5: z = cgetg(7,t_VEC);2541ee= cgetg(7,t_VECSMALL);2542w = cgetg(7,t_VECSMALL);2543prec = nbits2prec((long)(fb*21.) + 64);2544for(;;)2545{2546for(;;)2547{2548p1=QX_complex_roots(x,prec);2549for (l=1; l<=6; l++)2550{2551p2=(l==1)?p1: ((l<6)?transroot(p1,1,l): transroot(p1,2,5));2552p3=gen_0;2553for (k=0,i=1; i<=5; i++,k+=4)2554{2555p5 = gadd(gmul(gel(p2,ind5[k]),gel(p2,ind5[k+1])),2556gmul(gel(p2,ind5[k+2]),gel(p2,ind5[k+3])));2557p3 = gadd(p3, gmul(gsqr(gel(p2,i)),p5));2558}2559gel(w,l) = grndtoi(real_i(p3),&e);2560e1 = gexpo(imag_i(p3)); if (e1>e) e=e1;2561ee[l]=e; gel(z,l) = p3;2562}2563p5 = roots_to_ZX(z, &e); if (e <= -10) break;2564prec = precdbl(prec);2565}2566if (!ZX_is_squarefree(p5)) goto tchi;2567p3=gel(ZX_factor(p5),1);2568f=Z_issquare(ZX_disc(x));2569if (lg(p3)-1==1)2570{2571set_avma(av);2572return f? galois_res(n,60,1,4): galois_res(n,120,-1,5);2573}2574if (!f) { set_avma(av); return galois_res(n,20,-1,3); }25752576pr = - (prec2nbits(prec) >> 1);2577for (l=1; l<=6; l++)2578if (ee[l] <= pr && gequal0(poleval(p5,gel(w,l)))) break;2579if (l>6) pari_err_BUG("galois (bug4)");2580p2=(l==6)? transroot(p1,2,5):transroot(p1,1,l);2581p3=gen_0;2582for (i=1; i<=5; i++)2583{2584j = (i == 5)? 1: i+1;2585p3 = gadd(p3,gmul(gmul(gel(p2,i),gel(p2,j)),2586gsub(gel(p2,j),gel(p2,i))));2587}2588p5=gsqr(p3); p4=grndtoi(real_i(p5),&e);2589e1 = gexpo(imag_i(p5)); if (e1>e) e=e1;2590if (e <= -10)2591{2592if (gequal0(p4)) goto tchi;2593f = Z_issquare(p4); set_avma(av);2594return f? galois_res(n,5,1,1): galois_res(n,10,1,2);2595}2596prec = precdbl(prec);2597}25982599case 6: z = cgetg(7, t_VEC);2600prec = nbits2prec((long) (fb * 42) + 64);2601for(;;)2602{2603for(;;)2604{2605p1=QX_complex_roots(x,prec);2606for (l=1; l<=6; l++)2607{2608p2=(l==1)?p1:transroot(p1,1,l);2609p3=gen_0; k=0;2610for (i=1; i<=5; i++) for (j=i+1; j<=6; j++)2611{2612p5=gadd(gmul(gel(p2,ind6[k]),gel(p2,ind6[k+1])),2613gmul(gel(p2,ind6[k+2]),gel(p2,ind6[k+3])));2614p3=gadd(p3,gmul(gsqr(gmul(gel(p2,i),gel(p2,j))),p5));2615k += 4;2616}2617gel(z,l) = p3;2618}2619p5 = roots_to_ZX(z, &e); if (e <= -10) break;2620prec = precdbl(prec);2621}2622if (!ZX_is_squarefree(p5)) goto tchi;2623p2=gel(ZX_factor(p5),1);2624switch(lg(p2)-1)2625{2626case 1:2627z = cgetg(11,t_VEC); ind=0;2628p3=gadd(gmul(gmul(gel(p1,1),gel(p1,2)),gel(p1,3)),2629gmul(gmul(gel(p1,4),gel(p1,5)),gel(p1,6)));2630gel(z,++ind) = p3;2631for (i=1; i<=3; i++)2632for (j=4; j<=6; j++)2633{2634p2=transroot(p1,i,j);2635p3=gadd(gmul(gmul(gel(p2,1),gel(p2,2)),gel(p2,3)),2636gmul(gmul(gel(p2,4),gel(p2,5)),gel(p2,6)));2637gel(z,++ind) = p3;2638}2639p5 = roots_to_ZX(z, &e);2640if (e <= -10)2641{2642if (!ZX_is_squarefree(p5)) goto tchi;2643p2 = gel(ZX_factor(p5),1);2644f = Z_issquare(ZX_disc(x));2645set_avma(av);2646if (lg(p2)-1==1)2647return f? galois_res(n,360,1,15): galois_res(n,720,-1,16);2648else2649return f? galois_res(n,36,1,10): galois_res(n,72,-1,13);2650}2651prec = precdbl(prec); break;26522653case 2: l2=degpol(gel(p2,1)); if (l2>3) l2=6-l2;2654switch(l2)2655{2656case 1: f = Z_issquare(ZX_disc(x));2657set_avma(av);2658return f? galois_res(n,60,1,12): galois_res(n,120,-1,14);2659case 2: f = Z_issquare(ZX_disc(x));2660if (f) { set_avma(av); return galois_res(n,24,1,7); }2661p3 = (degpol(gel(p2,1))==2)? gel(p2,2): gel(p2,1);2662f = Z_issquare(ZX_disc(p3));2663set_avma(av);2664return f? galois_res(n,24,-1,6): galois_res(n,48,-1,11);2665case 3: f = Z_issquare(ZX_disc(gel(p2,1)))2666|| Z_issquare(ZX_disc(gel(p2,2)));2667set_avma(av);2668return f? galois_res(n,18,-1,5): galois_res(n,36,-1,9);2669}2670case 3:2671for (l2=1; l2<=3; l2++)2672if (degpol(gel(p2,l2)) >= 3) p3 = gel(p2,l2);2673if (degpol(p3) == 3)2674{2675f = Z_issquare(ZX_disc(p3)); set_avma(av);2676return f? galois_res(n,6,-1,1): galois_res(n,12,-1,3);2677}2678else2679{2680f = Z_issquare(ZX_disc(x)); set_avma(av);2681return f? galois_res(n,12,1,4): galois_res(n,24,-1,8);2682}2683case 4: set_avma(av); return galois_res(n,6,-1,2);2684default: pari_err_BUG("galois (bug3)");2685}2686}26872688case 7: z = cgetg(36,t_VEC);2689prec = nbits2prec((long)(fb*7.) + 64);2690for(;;)2691{2692ind = 0; p1=QX_complex_roots(x,prec);2693for (i=1; i<=5; i++)2694for (j=i+1; j<=6; j++)2695{2696GEN t = gadd(gel(p1,i),gel(p1,j));2697for (k=j+1; k<=7; k++) gel(z,++ind) = gadd(t, gel(p1,k));2698}2699p5 = roots_to_ZX(z, &e); if (e <= -10) break;2700prec = precdbl(prec);2701}2702if (!ZX_is_squarefree(p5)) goto tchi;2703p2=gel(ZX_factor(p5),1);2704switch(lg(p2)-1)2705{2706case 1: f = Z_issquare(ZX_disc(x)); set_avma(av);2707return f? galois_res(n,2520,1,6): galois_res(n,5040,-1,7);2708case 2: f = degpol(gel(p2,1)); set_avma(av);2709return (f==7 || f==28)? galois_res(n,168,1,5): galois_res(n,42,-1,4);2710case 3: set_avma(av); return galois_res(n,21,1,3);2711case 4: set_avma(av); return galois_res(n,14,-1,2);2712case 5: set_avma(av); return galois_res(n,7,1,1);2713default: pari_err_BUG("galois (bug2)");2714}2715}2716tchi: set_avma(av1); x = tschirnhaus(x1);2717}2718}271927202721