Example #1
0
static GEN
fix_var(GEN x, long v)
{
  long i, l = lg(x);
  if (!v) return x;
  for (i=1; i<l; i++) { GEN t = gel(x,i); setvarn(t[1],v); setvarn(t[2],v); }
  return x;
}
Example #2
0
static void
init_primedata(primedata *S)
{
  long i, j, l, lff = lg(S->ff), v = fetch_var(), N = degpol(S->pol);
  GEN T, p = S->p;

  if (S->lcm == degpol(S->ff[lff-1]))
  {
    T = shallowcopy((GEN)S->ff[lff-1]);
    setvarn(T, v);
  }
  else
    T = init_Fq(p, S->lcm, v);
  name_var(v,"y");
  S->T = T;
  S->firstroot = cgetg(lff, t_VECSMALL);
  S->interp = cgetg(lff, t_VEC);
  S->fk = cgetg(N+1, t_VEC);
  for (l=1,j=1; j<lff; j++)
  { /* compute roots and fix ordering (Frobenius cycles) */
    GEN F = FpX_factorff_irred(gel(S->ff,j), T, p);
    gel(S->interp,j) = interpol(F,T,p);
    S->firstroot[j] = l;
    for (i=1; i<lg(F); i++,l++) S->fk[l] = F[i];
  }
  S->Trk     = init_traces(S->ff, T,p);
  S->bezoutC = get_bezout(S->pol, S->ff, p);
}
Example #3
0
static void
subfields_poldata(GEN T, poldata *PD)
{
  GEN  nf,L,dis;

  T = shallowcopy(get_nfpol(T, &nf));
  PD->pol = T; setvarn(T, 0);
  if (nf)
  {
    PD->den = Q_denom(gel(nf,7));
    PD->roo = gel(nf,6);
    PD->dis = mulii(absi(gel(nf,3)), sqri(gel(nf,4)));
  }
  else
  {
    PD->den = initgaloisborne(T,NULL,ZX_get_prec(T), &L,NULL,&dis);
    PD->roo = L;
    PD->dis = absi(dis);
  }
}
engine_RawRingElementArrayOrNull rawRoots(const RingElement *p, long prec,
                                          int unique) {
  const Ring *R = p->get_ring();
  const PolynomialRing *P = R->cast_to_PolynomialRing();
  if (P == 0) {
    ERROR("expected a polynomial ring");
    return NULL;
  }
  const int n = P->n_vars();
  if (n != 1) {
    ERROR("expected a univariate polynomial ring");
    return NULL;
  }
  const Ring *K = P->getCoefficients();
  int degree = 0;
  for (Nterm *t = p->get_value(); t != NULL; t = t->next) {
    degree = max(degree, abs(*(t->monom)));
  }
  if (prec == -1) {
    prec = (K->get_precision() == 0 ? 53 : K->get_precision());
  }

  engine_RawRingElementArrayOrNull result = nullptr;

  /* Start PARI computations. */
  pari_CATCH(e_STACK) {
#ifdef NDEBUG
    /*
     * Every time the stack is changed PARI writes a message to the file pari_errfile
     * which by default is /dev/stderr. To avoid showing this message to the user we
     * redirect to /dev/null before the PARI's stack is modified.
     */
    FILE *tmp, *dev_null = fopen("/dev/null", "w");
    if (dev_null != NULL) {
      tmp = pari_errfile;
      pari_errfile = dev_null;
    }
#endif
  allocatemem(0); // passing 0 will double the current stack size.
#ifdef NDEBUG
    /*
     * We set pari_errfile back to the default value just in case PARI crashes.
     */
    if (dev_null != NULL) {
      pari_errfile = tmp;
      fclose(dev_null);
    }
#endif
  } pari_RETRY {
    const pari_sp av = avma;

    GEN q = cgetg(2 + degree + 1, t_POL);
    setsigne(q, 1);
    setvarn(q, 0);
    for (int i = 0; i < degree + 1; ++i) {
      gel(q, 2 + i) = gen_0;
    }

    switch (K->ringID()) {
    case M2::ring_ZZ:
    ZZ_GMP:
      for (Nterm *t = p->get_value(); t != NULL; t = t->next) {
        gel(q, 2 + abs(*(t->monom))) =
            mpz_get_GEN(reinterpret_cast<const mpz_ptr>(t->coeff.poly_val));
      }
      break;
    case M2::ring_QQ:
      for (Nterm *t = p->get_value(); t != NULL; t = t->next) {
        gel(q, 2 + abs(*(t->monom))) =
            mpq_get_GEN(reinterpret_cast<const mpq_ptr>(t->coeff.poly_val));
      }
      break;
    case M2::ring_RR:
      pari_CATCH(e_OVERFLOW) {
        ERROR("coefficient is NaN or Infinity");
        avma = av;
        return NULL;
      }
      pari_TRY {
        for (Nterm *t = p->get_value(); t != NULL; t = t->next) {
          gel(q, 2 + abs(*(t->monom))) =
              dbltor(*reinterpret_cast<double *>(t->coeff.poly_val));
        }
      }
      pari_ENDCATCH
      break;
    case M2::ring_CC:
      pari_CATCH(e_OVERFLOW) {
        ERROR("coefficient is NaN or Infinity");
        avma = av;
        return NULL;
      }
      pari_TRY {
        for (Nterm *t = p->get_value(); t != NULL; t = t->next) {
          GEN z = cgetg(3, t_COMPLEX);
          gel(z, 1) = dbltor(reinterpret_cast<complex *>(t->coeff.poly_val)->re);
          gel(z, 2) = dbltor(reinterpret_cast<complex *>(t->coeff.poly_val)->im);
          gel(q, 2 + abs(*(t->monom))) = z;
        }
      }
      pari_ENDCATCH
      break;
    case M2::ring_RRR:
      for (Nterm *t = p->get_value(); t != NULL; t = t->next) {
        gel(q, 2 + abs(*(t->monom))) =
            mpfr_get_GEN(reinterpret_cast<const mpfr_ptr>(t->coeff.poly_val));
      }
      break;
    case M2::ring_CCC:
      for (Nterm *t = p->get_value(); t != NULL; t = t->next) {
        gel(q, 2 + abs(*(t->monom))) =
            mpc_get_GEN(reinterpret_cast<const mpc_ptr>(t->coeff.poly_val));
      }
      break;
    case M2::ring_old:
      if (K->is_ZZ()) {
        goto ZZ_GMP;
      }
    default:
      ERROR("expected coefficient ring of the form ZZ, QQ, RR or CC");
      return NULL;
    }

    if (unique) {
      q = RgX_div(q, RgX_gcd_simple(q, RgX_deriv(q)));
    }

    GEN roots = cleanroots(q, nbits2prec(prec));

    const size_t num_roots = lg(roots) - 1;
    result = getmemarraytype(engine_RawRingElementArray, num_roots);
    result->len = static_cast<int>(num_roots);

    ring_elem m2_root;
    if (prec <= 53) {
      const RingCC *CC = dynamic_cast<const RingCC *>(IM2_Ring_CCC(prec));

      for (int i = 0; i < num_roots; ++i) {
        const pari_sp av2 = avma;

        GEN pari_root = gel(roots, 1 + i);
        const complex root = {rtodbl(greal(pari_root)),
                              rtodbl(gimag(pari_root))};
        CC->ring().to_ring_elem(m2_root, root);
        result->array[i] = RingElement::make_raw(CC, m2_root);

        avma = av2;
      }
    } else {
      const RingCCC *CCC = dynamic_cast<const RingCCC *>(IM2_Ring_CCC(prec));

      for (int i = 0; i < num_roots; ++i) {
        const pari_sp av2 = avma;

        mpc_t root;
        auto root1 = reinterpret_cast<mpfc_t*>(&root);
        pari_mpc_init_set_GEN(root, gel(roots, 1 + i), GMP_RNDN);
        //        CCC->ring().to_ring_elem(m2_root, **reinterpret_cast<mpfc_t*>(&root));
        CCC->ring().to_ring_elem(m2_root, **root1);
        result->array[i] = RingElement::make_raw(CCC, m2_root);

        avma = av2;
      }
    }

    /* End PARI computations. */
    avma = av;
  }
  pari_ENDCATCH

  return result;
}