예제 #1
0
void DUPFFformal_deriv2(DUPFF fprime, const DUPFF f)
/* fprime and f may be identical */
{
  int df, dans, j, p;

  p = CurrentFF.prime;
  df = DUPFFdeg(f);
  /* find degree of the answer */
  for (dans=df; dans >= 1; dans--)
    if (f->coeffs[dans] != 0 && (dans%p != 0)) break;
  dans--;
  if (dans < 0)
  {
    fprime->deg = -1;
    return;
  }
  if (fprime->maxdeg < dans)
  {
    JERROR(JERROR_DEG_TOO_LOW);
    return;
  }
  fprime->deg = dans;
  for (j = 1; j <= dans+1; j++)
    fprime->coeffs[j-1] = FFmul(j%p, f->coeffs[j]);
  return;
}
DUPFF DUPFFexgcd(DUPFF *fcofac, DUPFF *gcofac, const DUPFF f, const DUPFF g)
{
  DUPFF u, v, uf, ug, vf, vg;
  FFelem q, lcu, lcvrecip, p;
  int df, dg, du, dv;

  if (DUPFFdeg(f) < DUPFFdeg(g)) return DUPFFexgcd(gcofac, fcofac, g, f);
  if (DUPFFdeg(f) != 2 || DUPFFdeg(g) != 1) abort();
  if (f->coeffs[0] == 0) return f;
  p = 2;

  df = DUPFFdeg(f);  if (df < 0) df = 0; /* both inputs are zero */
  dg = DUPFFdeg(g);  if (dg < 0) dg = 0; /* one input is zero */
  u = DUPFFcopy(f);
  v = DUPFFcopy(g);

  uf = DUPFFnew(dg); uf->coeffs[0] = 1; uf->deg = 0;
  ug = DUPFFnew(df);
  vf = DUPFFnew(dg);
  vg = DUPFFnew(df); vg->coeffs[0] = 1; vg->deg = 0;

  while (DUPFFdeg(v) > 0)
  {
    dv = DUPFFdeg(v);
    lcvrecip = FFmul(1, v->coeffs[dv]);
    while (DUPFFdeg(u) >= dv)
    {
      du = DUPFFdeg(u);
      lcu = u->coeffs[du];
      q = FFmul(lcu, lcvrecip);
      DUPFFshift_add(u, v, du-dv, p-q);
      DUPFFshift_add(uf, vf, du-dv, p-q);
      DUPFFshift_add(ug, vg, du-dv, p-q);
    }
    DUPFFswap(u, v);
    DUPFFswap(uf, vf);
    DUPFFswap(ug, vg);
  }
  if (DUPFFdeg(v) == 0)
  {
    DUPFFswap(u, v);
    DUPFFswap(uf, vf);
    DUPFFswap(ug, vg);
  }
  DUPFFfree(vf);
  DUPFFfree(vg);
  DUPFFfree(v);
  *fcofac = uf;
  *gcofac = ug;
  return u;
}
예제 #3
0
DMPFF DMPFFgcd_aux(DMPFF f, DMPFF g)
{
  int var, i, p, nvars;
  int *df, *dg, *dans, *substitution;
  FF Fp;
  DUPFF fx, gx;
  
  DMPFFdegs(df, f);
  nvars = 0;
  for (var = 0; var < NVARS; var++) if (df[var]) nvars++;
  if (nvars == 0) return one;
  if (nvars == 1) return DMPFFunivariate_gcd(f, g, var);

  /* We have at least two variables . */
  DMPFFdegs(dg, g);

  /* Predict degrees of the result in each variable.  We may guess too high. */
  /* For each var map to univariate by random substitution and compute gcd */
  p = CurrentFF.prime;
  for (var = 0; var < NVARS; var++)
  {
    if (df[var] == 0) continue;
    do
    {
      for (i=0; i < NVARS; i++)
        substitution[i] = rand()%p; /* only need values for SOME variables  */
      fx = DMPFF_to_DUPFF(f, var, substitution);
      gx = DMPFF_to_DUPFF(g, var, substitution);
    } while (DUPFFdeg(fx) < df[var] || DUPFFdeg(gx) < dg[var]);
    DUPFFgcd2(fx, gx);
    dans[var] = DUPFFdeg(fx);
    DUPFFdtor(fx);
    DUPFFdtor(gx);
    if (dans[var] > 0) continue;
    /* if var does not appear in the answer, remove it from f and g */
    nvars--;
    if (nvars == 0) return one;
    f = DMPFFcontent(f, var);
    g = DMPFFcontent(g, var);
    if (nvars == 1) return DMPFFunivariate_gcd(f, g, var);
  }
  /* At this point the predicted degrees are probably correct. */

printf("Predicted degrees are: ");for(i=0;i<NVARS;i++)printf("%3d ",dans[vars]);printf("\n");

  /* Pick the 'main' variable. */
  for (var=0; dans[var] == 0; var++);
  fc = DMPFFcontent(f, var);
  gc = DMPFFcontent(g, var);
  f = DMPFFdivexact(f, fc);
  g = DMPFFdivexact(g, gc);
  hc = DMPFFgcd(fc, gc);

  fx = DMPFF_to_DUPFF(f, var, substitution);
  gx = DMPFF_to_DUPFF(g, var, substitution);
  hx = DUPFFgcd2(fx, gx);
  fcofac = DUPFFdiv(fx, hx);
  gcofac = DUPFFdiv(gx, hx);
  tmp = DUPFFgcd2(fcofac, hx);
  if (DUPFFdeg(tmp) == 0)
  {
    DMPFFlift(f, hx, fcofac, substitution, dans);
  }
  tmp = DUPFFgcd2(gcofac, hx);
  if (DUPFFdeg(tmp) == 0)
  {
    DMPFFlift(g, hx, gcofac, substitution, dans);
  }
  for (i=1; i < p; i++)
  {
    DUPFFadd3(fcofac, fcofac, gcofac);
    DUPFFadd3(fx, fx, gx);
    DMPFFadd3(f, f, g);
    tmp = DUPFFgcd(fcofac, hx);
    if (DUPFFdeg(tmp) == 0) break
  }
  DMPFFlift(f, hx, fcofac, substitution, dans);
}