コード例 #1
0
ファイル: nffactor.c プロジェクト: BENGMN/soen490
/* Warning: return L->topowden * (best lift) */
static GEN
nf_bestlift_to_pol(GEN elt, GEN bound, nflift_t *L)
{
  pari_sp av = avma;
  GEN v, u = nf_bestlift(elt,bound,L);
  if (!u) return NULL;
  v = gclone(u); avma = av;
  u = gmul(L->topow, v); 
  gunclone(v); return u;
}
コード例 #2
0
ファイル: concat.c プロジェクト: jkeuffer/pari
/* assume A or B is a t_LIST */
static GEN
listconcat(GEN A, GEN B)
{
  long i, l1, lx;
  GEN L, z, L1, L2;

  if (typ(A) != t_LIST) {
    if (list_typ(B)!=t_LIST_RAW) pari_err_TYPE("listconcat",B);
    L2 = list_data(B);
    if (!L2) return mklistcopy(A);
    lx = lg(L2) + 1;
    z = listcreate();
    list_data(z) = L = cgetg(lx, t_VEC);
    for (i = 2; i < lx; i++) gel(L,i) = gcopy(gel(L2,i-1));
    gel(L,1) = gcopy(A); return z;
  } else if (typ(B) != t_LIST) {
    if (list_typ(A)!=t_LIST_RAW) pari_err_TYPE("listconcat",A);
    L1 = list_data(A);
    if (!L1) return mklistcopy(B);
    lx = lg(L1) + 1;
    z = listcreate();
    list_data(z) = L = cgetg(lx, t_VEC);
    for (i = 1; i < lx-1; i++) gel(L,i) = gcopy(gel(L1,i));
    gel(L,i) = gcopy(B); return z;
  }
  /* A, B both t_LISTs */
  if (list_typ(A)!=t_LIST_RAW) pari_err_TYPE("listconcat",A);
  if (list_typ(B)!=t_LIST_RAW) pari_err_TYPE("listconcat",B);
  L1 = list_data(A); if (!L1) return listcopy(B);
  L2 = list_data(B); if (!L2) return listcopy(A);

  l1 = lg(L1);
  lx = l1-1 + lg(L2);
  z = cgetg(3, t_LIST);
  z[1] = 0UL;
  list_data(z) = L = cgetg(lx, t_VEC);
  L2 -= l1-1;
  for (i=1; i<l1; i++) gel(L,i) = gclone(gel(L1,i));
  for (   ; i<lx; i++) gel(L,i) = gclone(gel(L2,i));
  return z;
}
コード例 #3
0
ファイル: subfield.c プロジェクト: BENGMN/soen490
/* L list of current subfields, test whether potential block D is a block,
 * if so, append corresponding subfield */
static GEN
test_block(blockdata *B, GEN L, GEN D)
{
  pari_sp av = avma;
  GEN sub = subfield(D, B);
  if (sub) {
    GEN old = L;
    L = gclone( L? shallowconcat(L, sub): sub );
    if (old) gunclone(old);
  }
  avma = av; return L;
}
コード例 #4
0
ファイル: ut_slice.c プロジェクト: awakecoding/COS
void
ut_slice(void)
{
  useclass(Slice);

  UTEST_START("Slice")

    // equality and default args
    UTEST( Slice_isEqual(atSlice(10)  , atSlice(0,10, 1))  );
    UTEST( Slice_isEqual(atSlice(0,10), atSlice(0,10, 1))  );
    UTEST(!Slice_isEqual(atSlice(0,10), atSlice(0,10,-1))  );
    UTEST( Slice_isEqual(atSlice(0,10), atSlice(0,10, 0))  );

    UTEST( gisEqual(aSlice(10)  , aSlice(0,10, 1)) == True  );
    UTEST( gisEqual(aSlice(0,10), aSlice(0,10, 1)) == True  );
    UTEST( gisEqual(aSlice(0,10), aSlice(0,10,-1)) == False );

    // new vs auto
    UTEST( isEq(gnewSlc(Slice, 0, 10, 1), aSlice(0,10,1)) );
    UTEST(!isEq(gnewSlc(Slice, 0, 10, 1), aSlice(0,10,-1)) );

    // clone vs auto
    UTEST( isEq(gclone(aSlice(10)), aSlice(10)) );
    UTEST( isEq(gclone(aSlice(0,10)), aSlice(0,10)) );
    UTEST( isEq(gclone(aSlice(0,10,-1)), aSlice(0,10,-1)) );
    
    // eval
    UTEST( Slice_eval(atSlice(10),0) == 0 );
    UTEST( Slice_eval(atSlice(10),1) == 1 );
    UTEST( Slice_eval(atSlice(10),10) == 10 );
    UTEST( Slice_eval(atSlice(1,10),0) == 1 );
    UTEST( Slice_eval(atSlice(1,10),1) == 2 );
    UTEST( Slice_eval(atSlice(1,10),10) == 11 );
    UTEST( Slice_eval(atSlice(1,10,2),0) == 1 );
    UTEST( Slice_eval(atSlice(1,10,2),1) == 3 );
    UTEST( Slice_eval(atSlice(1,10,2),10) == 21 );
    UTEST( Slice_eval(atSlice(10,1,-2),0) == 10 );
    UTEST( Slice_eval(atSlice(10,1,-2),1) == 8 );
    UTEST( Slice_eval(atSlice(10,1,-2),10) == -10 );

    // first
    UTEST( Slice_first(atSlice(10)) == 0 );
    UTEST( Slice_first(atSlice(1,10)) == 1 );
    UTEST( Slice_first(atSlice(-1,10)) == (U32)-1 );
    UTEST( Slice_first(atSlice(-1,-10)) == (U32)-1 );

    // last
    UTEST( Slice_last(atSlice(10)) == 9 );
    UTEST( Slice_last(atSlice(1,10)) == 10 );
    UTEST( Slice_last(atSlice(1,10,2)) == 19 );
    UTEST( Slice_last(atSlice(0,-10)) == (U32)-11 );
    UTEST( Slice_last(atSlice(-1,-10)) == (U32)-12 );

    // size
    UTEST( Slice_size(atSlice(0,9,1)) == 9 );
    UTEST( Slice_size(atSlice(1,10,1)) == 10 );
    UTEST( Slice_size(atSlice(1,10,2)) == 10 );
    UTEST( Slice_size(atSlice(1,10,3)) == 10 );
    UTEST( Slice_size(atSlice(1,9,3)) == 9 );

    UTEST( Slice_size(atSlice(9,0,-1)) == 0 );
    UTEST( Slice_size(atSlice(10,1,-1)) == 1 );
    UTEST( Slice_size(atSlice(10,1,-2)) == 1 );
    UTEST( Slice_size(atSlice(10,1,-3)) == 1 );
    UTEST( Slice_size(atSlice(9,1,-3)) == 1 );

    // slice vs range
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,1,1), 0), atSlice(-1,3,1)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,1,2), 0), atSlice(-1,2,2)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,5,3), 0), atSlice(-1,3,3)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,4,3), 0), atSlice(-1,2,3)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange( 1,5,3), 0), atSlice( 1,2,3)) );

    UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,0,-1), 0), atSlice(9,10,-1)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,1,-2), 0), atSlice(9,5,-2)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,0,-3), 0), atSlice(9,4,-3)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,3,-3), 0), atSlice(9,3,-3)) );

    UTEST( eq(Slice_fromRange(atSlice(0), atRange(0,9,1) , 0), atSlice(0,10,1)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(1,10,1), 0), atSlice(1,10,1)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(1,9,2) , 0), atSlice(1,5,2)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(1,10,3), 0), atSlice(1,4,3)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(1,7,3) , 0), atSlice(1,3,3)) );

    UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,0,-1) , 0), atSlice(9,10,-1)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(10,1,-1), 0), atSlice(10,10,-1)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(10,2,-2), 0), atSlice(10,5,-2)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(10,1,-3), 0), atSlice(10,4,-3)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(9,3,-3) , 0), atSlice(9,3,-3)) );

    UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,-10,-1), 0), atSlice(-1,10,-1)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,-9,-2) , 0), atSlice(-1,5,-2)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,-10,-3), 0), atSlice(-1,4,-3)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(-1,-7,-3) , 0), atSlice(-1,3,-3)) );

    UTEST( eq(Slice_fromRange(atSlice(0), atRange(-10,-1,1), 0), atSlice(-10,10,1)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(-10,-2,2), 0), atSlice(-10,5,2)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(-10,-1,3), 0), atSlice(-10,4,3)) );
    UTEST( eq(Slice_fromRange(atSlice(0), atRange(-9,-3,3) , 0), atSlice(-9,3,3)) );

  UTEST_END
}
コード例 #5
0
ファイル: nffactor.c プロジェクト: BENGMN/soen490
/* Naive recombination of modular factors: combine up to maxK modular
 * factors, degree <= klim and divisible by hint
 *
 * target = polynomial we want to factor
 * famod = array of modular factors.  Product should be congruent to
 * target/lc(target) modulo p^a
 * For true factors: S1,S2 <= p^b, with b <= a and p^(b-a) < 2^31 */
static GEN
nfcmbf(nfcmbf_t *T, GEN p, long a, long maxK, long klim)
{
  GEN pol = T->pol, nf = T->nf, famod = T->fact, dn = T->dn;
  GEN bound = T->bound;
  GEN nfpol = gel(nf,1);
  long K = 1, cnt = 1, i,j,k, curdeg, lfamod = lg(famod)-1, dnf = degpol(nfpol);
  GEN res = cgetg(3, t_VEC);
  pari_sp av0 = avma;
  GEN pk = gpowgs(p,a), pks2 = shifti(pk,-1);

  GEN ind      = cgetg(lfamod+1, t_VECSMALL);
  GEN degpol   = cgetg(lfamod+1, t_VECSMALL);
  GEN degsofar = cgetg(lfamod+1, t_VECSMALL);
  GEN listmod  = cgetg(lfamod+1, t_COL);
  GEN fa       = cgetg(lfamod+1, t_COL);
  GEN lc = absi(leading_term(pol)), lt = is_pm1(lc)? NULL: lc;
  GEN C2ltpol, C = T->L->topowden, Tpk = T->L->Tpk;
  GEN Clt  = mul_content(C, lt);
  GEN C2lt = mul_content(C,Clt);
  const double Bhigh = get_Bhigh(lfamod, dnf);
  trace_data _T1, _T2, *T1, *T2;
  pari_timer ti;

  TIMERstart(&ti);

  if (maxK < 0) maxK = lfamod-1;

  C2ltpol = C2lt? gmul(C2lt,pol): pol;
  {
    GEN q = ceil_safe(sqrtr(T->BS_2));
    GEN t1,t2, ltdn, lt2dn;
    GEN trace1   = cgetg(lfamod+1, t_MAT);
    GEN trace2   = cgetg(lfamod+1, t_MAT);

    ltdn = mul_content(lt, dn);
    lt2dn= mul_content(ltdn, lt);

    for (i=1; i <= lfamod; i++)
    {
      pari_sp av = avma;
      GEN P = gel(famod,i);
      long d = degpol(P);

      degpol[i] = d; P += 2;
      t1 = gel(P,d-1);/* = - S_1 */
      t2 = gsqr(t1);
      if (d > 1) t2 = gsub(t2, gmul2n(gel(P,d-2), 1));
      /* t2 = S_2 Newton sum */
      t2 = typ(t2)!=t_INT? FpX_rem(t2, Tpk, pk): modii(t2, pk);
      if (lt)
      {
        if (typ(t2)!=t_INT) {
          t1 = FpX_red(gmul(ltdn, t1), pk);
          t2 = FpX_red(gmul(lt2dn,t2), pk);
        } else {
          t1 = remii(mulii(ltdn, t1), pk);
          t2 = remii(mulii(lt2dn,t2), pk);
        }
      }
      gel(trace1,i) = gclone( nf_bestlift(t1, NULL, T->L) );
      gel(trace2,i) = gclone( nf_bestlift(t2, NULL, T->L) ); avma = av;
    }
    T1 = init_trace(&_T1, trace1, T->L, q);
    T2 = init_trace(&_T2, trace2, T->L, q);
    for (i=1; i <= lfamod; i++) { 
      gunclone(gel(trace1,i));
      gunclone(gel(trace2,i));
    }
  }
  degsofar[0] = 0; /* sentinel */

  /* ind runs through strictly increasing sequences of length K,
   * 1 <= ind[i] <= lfamod */
nextK:
  if (K > maxK || 2*K > lfamod) goto END;
  if (DEBUGLEVEL > 3)
    fprintferr("\n### K = %d, %Z combinations\n", K,binomial(utoipos(lfamod), K));
  setlg(ind, K+1); ind[1] = 1;
  i = 1; curdeg = degpol[ind[1]];
  for(;;)
  { /* try all combinations of K factors */
    for (j = i; j < K; j++)
    {
      degsofar[j] = curdeg;
      ind[j+1] = ind[j]+1; curdeg += degpol[ind[j+1]];
    }
    if (curdeg <= klim && curdeg % T->hint == 0) /* trial divide */
    {
      GEN t, y, q, list;
      pari_sp av;

      av = avma;
      /* d - 1 test */
      if (T1)
      {
        t = get_trace(ind, T1);
        if (rtodbl(QuickNormL2(t,DEFAULTPREC)) > Bhigh)
        {
          if (DEBUGLEVEL>6) fprintferr(".");
          avma = av; goto NEXT;
        }
      }
      /* d - 2 test */
      if (T2)
      {
        t = get_trace(ind, T2);
        if (rtodbl(QuickNormL2(t,DEFAULTPREC)) > Bhigh)
        {
          if (DEBUGLEVEL>3) fprintferr("|");
          avma = av; goto NEXT;
        }
      }
      avma = av;
      y = lt; /* full computation */
      for (i=1; i<=K; i++)
      {
        GEN q = gel(famod, ind[i]);
        if (y) q = gmul(y, q);
        y = FqX_centermod(q, Tpk, pk, pks2);
      }
      y = nf_pol_lift(y, bound, T);
      if (!y)
      {
        if (DEBUGLEVEL>3) fprintferr("@");
        avma = av; goto NEXT;
      }
      /* try out the new combination: y is the candidate factor */
      q = RgXQX_divrem(C2ltpol, y, nfpol, ONLY_DIVIDES);
      if (!q)
      {
        if (DEBUGLEVEL>3) fprintferr("*");
        avma = av; goto NEXT;
      }

      /* found a factor */
      list = cgetg(K+1, t_VEC);
      gel(listmod,cnt) = list;
      for (i=1; i<=K; i++) list[i] = famod[ind[i]];

      y = Q_primpart(y);
      gel(fa,cnt++) = QXQX_normalize(y, nfpol);
      /* fix up pol */
      pol = q;
      for (i=j=k=1; i <= lfamod; i++)
      { /* remove used factors */
        if (j <= K && i == ind[j]) j++;
        else
        {
          famod[k] = famod[i];
          update_trace(T1, k, i);
          update_trace(T2, k, i);
          degpol[k] = degpol[i]; k++;
        }
      }
      lfamod -= K;
      if (lfamod < 2*K) goto END;
      i = 1; curdeg = degpol[ind[1]];

      if (C2lt) pol = Q_primpart(pol);
      if (lt) lt = absi(leading_term(pol));
      Clt  = mul_content(C, lt);
      C2lt = mul_content(C,Clt);
      C2ltpol = C2lt? gmul(C2lt,pol): pol;
      if (DEBUGLEVEL > 2)
      {
        fprintferr("\n"); msgTIMER(&ti, "to find factor %Z",y);
        fprintferr("remaining modular factor(s): %ld\n", lfamod);
      }
      continue;
    }

NEXT:
    for (i = K+1;;)
    {
      if (--i == 0) { K++; goto nextK; }
      if (++ind[i] <= lfamod - K + i)
      {
        curdeg = degsofar[i-1] + degpol[ind[i]];
        if (curdeg <= klim) break;
      }
    }
  }
END:
  if (degpol(pol) > 0)
  { /* leftover factor */
    if (signe(leading_term(pol)) < 0) pol = gneg_i(pol);

    if (C2lt && lfamod < 2*K) pol = QXQX_normalize(Q_primpart(pol), nfpol);
    setlg(famod, lfamod+1);
    gel(listmod,cnt) = shallowcopy(famod);
    gel(fa,cnt++) = pol;
  }
  if (DEBUGLEVEL>6) fprintferr("\n");
  if (cnt == 2) { 
    avma = av0; 
    gel(res,1) = mkvec(T->pol);
    gel(res,2) = mkvec(T->fact);
  }
  else
  {
    setlg(listmod, cnt); setlg(fa, cnt);
    gel(res,1) = fa;
    gel(res,2) = listmod;
    res = gerepilecopy(av0, res);
  }
  return res;
}
コード例 #6
0
ファイル: subfield.c プロジェクト: BENGMN/soen490
/* 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;
}