GEN F2xq_ellcard(GEN a, GEN a6, GEN T) { pari_sp av = avma; long n = F2x_degree(T); GEN q = int2u(n), c; if (typ(a)==t_VECSMALL) { GEN t = F2xq_elltrace_Harley(a6, T); c = addii(q, F2xq_trace(a,T) ? addui(1,t): subui(1,t)); } else if (n==1) { long a4i = lgpol(gel(a,2)), a6i = lgpol(a6); return utoi(a4i? (a6i? 1: 5): 3); } else if (n==2) { GEN a3 = gel(a,1), a4 = gel(a,2), x = polx_F2x(T[1]), x1 = pol1_F2x(T[1]); GEN a613 = F2xq_mul(F2x_add(x1, a6),a3,T), a43= F2xq_mul(a4,a3,T); long f0= F2xq_trace(F2xq_mul(a6,a3,T),T); long f1= F2xq_trace(F2x_add(a43,a613),T); long f2= F2xq_trace(F2x_add(F2xq_mul(a43,x,T),a613),T); long f3= F2xq_trace(F2x_add(F2xq_mul(a43,F2x_add(x,x1),T),a613),T); c = utoi(9-2*(f0+f1+f2+f3)); } else { struct _F2xqE e; long m = (n+1)>>1; GEN q1 = addis(q, 1); GEN v = n==4 ? mkvec4s(13,17,21,25) : odd(n) ? mkvec3(subii(q1,int2u(m)),q1,addii(q1,int2u(m))): mkvec5(subii(q1,int2u(m+1)),subii(q1,int2u(m)),q1, addii(q1,int2u(m)),addii(q1,int2u(m+1))); e.a2=a; e.a6=a6; e.T=T; c = gen_select_order(v,(void*)&e, &F2xqE_group); if (n==4 && equaliu(c, 21)) /* Ambiguous case */ { GEN d = F2xq_powu(polx_F2x(T[1]),3,T), a3 = gel(a,1); e.a6 = F2x_add(a6,F2xq_mul(d,F2xq_sqr(a3,T),T)); /* twist */ c = subui(34, gen_select_order(mkvec2s(13,25),(void*)&e, &F2xqE_group)); } } return gerepileuptoint(av, c); }
int main(void) { GEN M,N1,N2, F1,F2,D; struct pari_thread pth[MAXTHREADS]; int numth = omp_get_max_threads(), i; /* Initialise the main PARI stack and global objects (gen_0, etc.) */ pari_init(4000000,500000); if (numth > MAXTHREADS) { numth = MAXTHREADS; omp_set_num_threads(numth); } /* Compute in the main PARI stack */ N1 = addis(int2n(256), 1); /* 2^256 + 1 */ N2 = subis(int2n(193), 1); /* 2^193 - 1 */ M = mathilbert(80); /*Allocate pari thread structures */ for (i = 1; i < numth; i++) pari_thread_alloc(&pth[i],4000000,NULL); #pragma omp parallel { int this_th = omp_get_thread_num(); if (this_th) (void)pari_thread_start(&pth[this_th]); #pragma omp sections { #pragma omp section { F1 = factor(N1); } #pragma omp section { F2 = factor(N2); } #pragma omp section { D = det(M); } } /* omp sections */ if (this_th) pari_thread_close(); } /* omp parallel */ pari_printf("F1=%Ps\nF2=%Ps\nlog(D)=%Ps\n", F1, F2, glog(D,3)); for (i = 1; i < numth; i++) pari_thread_free(&pth[i]); return 0; }
// Digit reversal GEN rev(GEN n, long B) { pari_sp av = avma; if (typ(n) != t_INT) pari_err_TYPE("rev", n); GEN m = modis(n, B); n = divis(n, B); pari_sp btop = avma, st_lim = stack_lim(btop, 1); while (signe(n)) { m = addis(mulis(m, B), smodis(n, B)); n = divis(n, B); if (low_stack(st_lim, stack_lim(btop, 1))) gerepileall(btop, 2, &m, &n); } m = gerepilecopy(av, m); return m; }
GEN gadd1e(GEN *x) { *x=typ(*x)==t_INT?addis(*x,1):gaddgs(*x,1); return *x; }
void PPCAssembler::lis(RegGPR rd, S16 simm) { addis(rd, r0, simm); }
/* d = requested degree for subfield. Return DATA, valid for given pol, S and d * If DATA != NULL, translate pol [ --> pol(X+1) ] and update DATA * 1: polynomial pol * 2: p^e (for Hensel lifts) such that p^e > max(M), * 3: Hensel lift to precision p^e of DATA[4] * 4: roots of pol in F_(p^S->lcm), * 5: number of polynomial changes (translations) * 6: Bezout coefficients associated to the S->ff[i] * 7: Hadamard bound for coefficients of h(x) such that g o h = 0 mod pol. * 8: bound M for polynomials defining subfields x PD->den * 9: *[i] = interpolation polynomial for S->ff[i] [= 1 on the first root S->firstroot[i], 0 on the others] */ static void compute_data(blockdata *B) { GEN ffL, roo, pe, p1, p2, fk, fhk, MM, maxroot, pol; primedata *S = B->S; GEN p = S->p, T = S->T, ff = S->ff, DATA = B->DATA; long i, j, l, e, N, lff = lg(ff); if (DEBUGLEVEL>1) fprintferr("Entering compute_data()\n\n"); pol = B->PD->pol; N = degpol(pol); roo = B->PD->roo; if (DATA) /* update (translate) an existing DATA */ { GEN Xm1 = gsub(pol_x[varn(pol)], gen_1); GEN TR = addis(gel(DATA,5), 1); GEN mTR = negi(TR), interp, bezoutC; gel(DATA,5) = TR; pol = translate_pol(gel(DATA,1), gen_m1); l = lg(roo); p1 = cgetg(l, t_VEC); for (i=1; i<l; i++) gel(p1,i) = gadd(TR, gel(roo,i)); roo = p1; fk = gel(DATA,4); l = lg(fk); for (i=1; i<l; i++) gel(fk,i) = gsub(Xm1, gel(fk,i)); bezoutC = gel(DATA,6); l = lg(bezoutC); interp = gel(DATA,9); for (i=1; i<l; i++) { if (degpol(interp[i]) > 0) /* do not turn pol_1[0] into gen_1 */ { p1 = translate_pol(gel(interp,i), gen_m1); gel(interp,i) = FpXX_red(p1, p); } if (degpol(bezoutC[i]) > 0) { p1 = translate_pol(gel(bezoutC,i), gen_m1); gel(bezoutC,i) = FpXX_red(p1, p); } } ff = cgetg(lff, t_VEC); /* copy, don't overwrite! */ for (i=1; i<lff; i++) gel(ff,i) = FpX_red(translate_pol((GEN)S->ff[i], mTR), p); } else { DATA = cgetg(10,t_VEC); fk = S->fk; gel(DATA,5) = gen_0; gel(DATA,6) = shallowcopy(S->bezoutC); gel(DATA,9) = shallowcopy(S->interp); } gel(DATA,1) = pol; MM = gmul2n(bound_for_coeff(B->d, roo, &maxroot), 1); gel(DATA,8) = MM; e = logint(shifti(vecmax(MM),20), p, &pe); /* overlift 2^20 [for d-1 test] */ gel(DATA,2) = pe; gel(DATA,4) = roots_from_deg1(fk); /* compute fhk = hensel_lift_fact(pol,fk,T,p,pe,e) in 2 steps * 1) lift in Zp to precision p^e */ ffL = hensel_lift_fact(pol, ff, NULL, p, pe, e); fhk = NULL; for (l=i=1; i<lff; i++) { /* 2) lift factorization of ff[i] in Qp[X] / T */ GEN F, L = gel(ffL,i); long di = degpol(L); F = cgetg(di+1, t_VEC); for (j=1; j<=di; j++) F[j] = fk[l++]; L = hensel_lift_fact(L, F, T, p, pe, e); fhk = fhk? shallowconcat(fhk, L): L; } gel(DATA,3) = roots_from_deg1(fhk); p1 = mulsr(N, gsqrt(gpowgs(utoipos(N-1),N-1),DEFAULTPREC)); p2 = gpowgs(maxroot, B->size + N*(N-1)/2); p1 = gdiv(gmul(p1,p2), gsqrt(B->PD->dis,DEFAULTPREC)); gel(DATA,7) = mulii(shifti(ceil_safe(p1), 1), B->PD->den); if (DEBUGLEVEL>1) { fprintferr("f = %Z\n",DATA[1]); fprintferr("p = %Z, lift to p^%ld\n", p, e); fprintferr("2 * Hadamard bound * ind = %Z\n",DATA[7]); fprintferr("2 * M = %Z\n",DATA[8]); } if (B->DATA) { DATA = gclone(DATA); if (isclone(B->DATA)) gunclone(B->DATA); } B->DATA = DATA; }