Example #1
0
void _pq_nmod_insure_dual(const pq_nmod_elt_t x, const pq_nmod_t A) {
  if (nmod_poly_is_zero(x->dual) &&
      !nmod_poly_is_zero(x->mono)) {
    pq_nmod_elt_struct* tmp = (pq_nmod_elt_struct*)x;
    nmod_poly_fit_length(tmp->dual, nmod_poly_degree(A->M));
    nmod_poly_tmulmod(tmp->dual->coeffs, A->newton->coeffs, x->mono, A->M, A->S);
    tmp->dual->length = nmod_poly_degree(A->M);
  }
}
void embeddings_isomorphism_inverse(mp_ptr F, const nmod_poly_t G, 
				    const embeddings_t FP, const embeddings_t FQ, const embeddings_t FR){

  long m = nmod_poly_degree(FP->P);
  long n = nmod_poly_degree(FQ->P);

  mp_ptr ell = _nmod_vec_init(m*n);
  nmod_poly_tmulmod(ell, FR->TP->coeffs, G, FR->P, FR->SP);

  mp_ptr Ftrace = _nmod_vec_init(m*n);
  embeddings_tisomorphism(Ftrace, ell, FP, FQ, FR);

  nmod_poly_convert_from_trace_bi(F, Ftrace, FP->P, FP->iP, FQ->P, FQ->iP);

  _nmod_vec_clear(Ftrace);
  _nmod_vec_clear(ell);
}
void embeddings_isomorphism(nmod_poly_t G, mp_srcptr F, 
			    const embeddings_t FP, const embeddings_t FQ, const embeddings_t FR){

  long m = nmod_poly_degree(FP->P);
  long n = nmod_poly_degree(FQ->P);

  long i;
  nmod_poly_t tmpF, tmpG, S, X;

  nmod_t mod = FP->P->mod;
  nmod_poly_init(tmpF, mod.n);
  nmod_poly_init(tmpG, mod.n);
  nmod_poly_init(S, mod.n);
  nmod_poly_init(X, mod.n);

  nmod_poly_zero(G);
  nmod_poly_zero(X);
  nmod_poly_set_coeff_ui(X, 1, 1);
  embeddings_embed(S, X, FP, FQ, FR);
  
  for (i = m-1; i >= 0; i--){
    nmod_poly_fit_length(tmpF, n);
    long j;
    long offset = i*n;
    for (j = 0; j < n; j++)
      tmpF->coeffs[j] = F[offset+j];
    tmpF->length = n;
    _nmod_poly_normalise(tmpF);
    
    embeddings_embed(tmpG, tmpF, FQ, FP, FR);
    nmod_poly_mulmod(G, G, S, FR->P);
    nmod_poly_add(G, G, tmpG);
  }

  nmod_poly_clear(tmpF);
  nmod_poly_clear(tmpG);
  nmod_poly_clear(X);
  nmod_poly_clear(S);
}
Example #4
0
void
nmod_poly_factor_squarefree(nmod_poly_factor_t res, const nmod_poly_t f)
{
    nmod_poly_t f_d, g, g_1;
    mp_limb_t p;
    slong deg, i;

    if (f->length <= 1) 
    {
        res->num = 0;
        return;
    }

    if (f->length == 2)
    {
        nmod_poly_factor_insert(res, f, 1);
        return;
    }

    p = nmod_poly_modulus(f);
    deg = nmod_poly_degree(f);

    
    /* Step 1, look at f', if it is zero then we are done since f = h(x)^p
       for some particular h(x), clearly f(x) = sum a_k x^kp, k <= deg(f) */

    nmod_poly_init(g_1, p);
    nmod_poly_init(f_d, p);
    nmod_poly_init(g, p);
    nmod_poly_derivative(f_d, f);

    /* Case 1 */
    if (nmod_poly_is_zero(f_d))
    {
        nmod_poly_factor_t new_res;
        nmod_poly_t h;

        nmod_poly_init(h, p);

        for (i = 0; i <= deg / p; i++) /* this will be an integer since f'=0 */
        {
            nmod_poly_set_coeff_ui(h, i, nmod_poly_get_coeff_ui(f, i * p));
        }
        
        /* Now run square-free on h, and return it to the pth power */
        nmod_poly_factor_init(new_res);

        nmod_poly_factor_squarefree(new_res, h);
        nmod_poly_factor_pow(new_res, p);

        nmod_poly_factor_concat(res, new_res);
        nmod_poly_clear(h);
        nmod_poly_factor_clear(new_res);
   }
   else 
   { 
        nmod_poly_t h, z;

        nmod_poly_gcd(g, f, f_d);
        nmod_poly_div(g_1, f, g);

        i = 1;

        nmod_poly_init(h, p);
        nmod_poly_init(z, p);

        /* Case 2 */
        while (!nmod_poly_is_one(g_1)) 
        {
            nmod_poly_gcd(h, g_1, g);
            nmod_poly_div(z, g_1, h);

            /* out <- out.z */
            if (z->length > 1)
            {
                nmod_poly_factor_insert(res, z, 1);
                nmod_poly_make_monic(res->p + (res->num - 1),
                                     res->p + (res->num - 1));
                if (res->num)
                    res->exp[res->num - 1] *= i;
            }

            i++;
            nmod_poly_set(g_1, h);
            nmod_poly_div(g, g, h);
        }

        nmod_poly_clear(h);
        nmod_poly_clear(z);
        
        nmod_poly_make_monic(g, g);

        if (!nmod_poly_is_one(g))
        {
            /* so now we multiply res with square-free(g^1/p) ^ p  */
            nmod_poly_t g_p; /* g^(1/p) */
            nmod_poly_factor_t new_res_2;

            nmod_poly_init(g_p, p);

            for (i = 0; i <= nmod_poly_degree(g) / p; i++)
                nmod_poly_set_coeff_ui(g_p, i, nmod_poly_get_coeff_ui(g, i*p));

            nmod_poly_factor_init(new_res_2);

            /* square-free(g^(1/p)) */
            nmod_poly_factor_squarefree(new_res_2, g_p);
            nmod_poly_factor_pow(new_res_2, p);

            nmod_poly_factor_concat(res, new_res_2);
            nmod_poly_clear(g_p);
            nmod_poly_factor_clear(new_res_2);
        }
   }

    nmod_poly_clear(g_1);
    nmod_poly_clear(f_d);
    nmod_poly_clear(g);
}
void embeddings_isomorphism_2(nmod_poly_t G, mp_srcptr F, 
			      const embeddings_t FP, const embeddings_t FQ, const embeddings_t FR){

  nmod_t mod = G->mod;
  long m = nmod_poly_degree(FP->P);
  long n = nmod_poly_degree(FQ->P);

  long np = n + m - 1;
  long p = ceil(sqrt(np));
  long q = ceil((1.0*np)/p);
  long i, j, k;

  nmod_poly_t iT, iTm, T, X, tmp;
  nmod_poly_struct *TT;

  nmod_poly_init(iTm, mod.n);
  nmod_poly_init(iT, mod.n);
  nmod_poly_init(T, mod.n);
  nmod_poly_init(X, mod.n);
  nmod_poly_init(tmp, mod.n);

  nmod_poly_mat_t MT, MH, MV;
  nmod_poly_mat_init(MT, q, n, mod.n);
  nmod_poly_mat_init(MH, p, q, mod.n);
  nmod_poly_mat_init(MV, p, n, mod.n);

  TT = flint_malloc(sizeof(nmod_poly_struct) * (q+1));
  for (i = 0; i < q+1; i++)
    nmod_poly_init(TT+i, mod.n);

  nmod_poly_set_coeff_ui(X, 1, 1);
  embeddings_embed(T, X, FQ, FP, FR);
  nmod_poly_invmod(iT, T, FR->P);
  nmod_poly_powmod_ui_binexp(iTm, iT, m-1, FR->P);

  nmod_poly_zero(TT);
  nmod_poly_set_coeff_ui(TT, 0, 1);

  for (i = 1; i < q+1; i++)
    nmod_poly_mulmod(TT+i, TT+(i-1), T, FR->P);

  for (i = 0; i < q; i++)
    for (j = 0; j < n; j++){
      long jm = j*m;
      for (k = 0; k < m; k++)
  	nmod_poly_set_coeff_ui(nmod_poly_mat_entry(MT, i, j), k, nmod_poly_get_coeff_ui(TT+i, k+jm));
    }

  for (i = 0; i < p; i++)
    for (j = 0; j < q; j++){
      long idx = i*q+j;
      long lo = FLINT_MAX(0,m-1-idx);
      long hi = FLINT_MIN(m,n+m-1-idx);
      for (k = lo; k < hi; k++)
  	nmod_poly_set_coeff_ui(nmod_poly_mat_entry(MH, i, j), k, F[k*n+k+idx-m+1]);
    }

  nmod_poly_mat_mul(MV, MH, MT);

  nmod_poly_zero(G);

  for (i = p-1; i >= 0; i--){
    nmod_poly_zero(tmp);
    for (j = 0; j < n; j++){
      long len = nmod_poly_mat_entry(MV, i, j)->length;
      mp_ptr coefs = nmod_poly_mat_entry(MV, i, j)->coeffs;
      long jm = j*m;
      for (k = 0; k < len; k++)
  	nmod_poly_set_coeff_ui(tmp, k+jm, n_addmod(nmod_poly_get_coeff_ui(tmp, k+jm), coefs[k], mod.n));
    }
    nmod_poly_rem(tmp, tmp, FR->P);
    nmod_poly_mulmod(G, G, TT+q, FR->P);
    nmod_poly_add(G, G, tmp);
  }

  nmod_poly_mulmod(G, G, iTm, FR->P);
			     

  nmod_poly_clear(tmp);
  nmod_poly_mat_clear(MT);
  nmod_poly_mat_clear(MH);
  nmod_poly_mat_clear(MV);

  for (i = 0; i < q+1; i++)
    nmod_poly_clear(TT+i);
  flint_free(TT);

  nmod_poly_clear(iTm);
  nmod_poly_clear(iT);
  nmod_poly_clear(T);
  nmod_poly_clear(X);



}