示例#1
0
void F_mpz_mod_poly_make_monic(F_mpz_mod_poly_t output, F_mpz_mod_poly_t pol)
{
	if (!pol->length) 
	{
		output->length = 0;
		return;
	}
	
	F_mpz_t *lead_coeff = (F_mpz_t *)&pol->coeffs[pol->length-1];
	
	if (F_mpz_is_one(*lead_coeff))
	{
		F_mpz_mod_poly_set(output, pol);
		return;
	}
	F_mpz_t lead_inv;
	F_mpz_init(lead_inv);
	
	F_mpz_invert(lead_inv, *lead_coeff, pol->P);
	F_mpz_mod_poly_scalar_mul(output, pol, lead_inv);
}
示例#2
0
void F_mpz_mod_poly_divrem_basecase(F_mpz_mod_poly_t Q, F_mpz_mod_poly_t R, const F_mpz_mod_poly_t A, const F_mpz_mod_poly_t B)
{
   if (B->length == 0)
   {
      printf("Error: Divide by zero\n");
      abort();      
   }
   
   if (A->length < B->length)
   {
      F_mpz_mod_poly_set(R, A);
      F_mpz_mod_poly_zero(Q);
      
      return;
   }

   F_mpz_t lead_inv;
   F_mpz_init(lead_inv);
   F_mpz_invert(lead_inv, B->coeffs + B->length - 1, B->P);
   
   F_mpz * coeff_Q;
   
   F_mpz_mod_poly_t qB;
   F_mpz_mod_poly_init2(qB, B->P, B->length);
   
   F_mpz_mod_poly_t Bm1;
   _F_mpz_mod_poly_attach_truncate(Bm1, B, B->length - 1);
   
   long coeff = A->length - 1;
   
   F_mpz_mod_poly_set(R, A);
   
   if (A->length >= B->length)
   {
      F_mpz_mod_poly_fit_length(Q, A->length - B->length + 1);
      _F_mpz_mod_poly_set_length(Q, A->length - B->length + 1);
   } else F_mpz_mod_poly_zero(Q); 

   coeff_Q = Q->coeffs - B->length + 1;
   
   while (coeff >= (long) B->length - 1)
   {
      while ((coeff >= (long) B->length - 1) && (F_mpz_is_zero(R->coeffs + coeff)))
      {
         F_mpz_zero(coeff_Q + coeff);
         coeff--;
      }
      
      if (coeff >= (long) B->length - 1)
      {
         F_mpz_mulmod2(coeff_Q + coeff, R->coeffs + coeff, lead_inv, B->P);
         
         F_mpz_mod_poly_scalar_mul(qB, Bm1, coeff_Q + coeff);
         
         F_mpz_mod_poly_t R_sub;
         F_mpz_init(R_sub->P);
         F_mpz_set(R_sub->P, B->P);
         R_sub->coeffs = R->coeffs + coeff - B->length + 1;
         R_sub->length = B->length - 1;
         _F_mpz_mod_poly_sub(R_sub, R_sub, qB);
         F_mpz_clear(R_sub->P);
         
         coeff--;
      }
   }
   
   _F_mpz_mod_poly_set_length(R, B->length - 1);
   _F_mpz_mod_poly_normalise(R);
   F_mpz_mod_poly_clear(qB);
   F_mpz_clear(lead_inv);
}