Exemplo n.º 1
0
int test_bernoulli_mod_p(unsigned long p)
{
   unsigned long *res = (unsigned long*) flint_stack_alloc((p-1)/2);
   if(!bernoulli_mod_p_mpz(res, p))
   {
      printf("Could not factor p = %d\n", p);
      flint_stack_release();
      return FALSE;
   }
   int result = verify_bernoulli_mod_p(res, p);
   flint_stack_release();
   return result;
}
Exemplo n.º 2
0
Arquivo: fmpz.c Projeto: hperl/flint
void fmpz_tdiv(fmpz_t res, const fmpz_t a, const fmpz_t b) 
{
   long a0 = a[0];
   long b0 = b[0];
   unsigned long sizea = FLINT_ABS(a0);
   unsigned long sizeb = FLINT_ABS(b0);
   while ((!a[sizea]) && (sizea)) sizea--;
   while ((!b[sizeb]) && (sizeb)) sizeb--;
      

   mp_limb_t mslimb;
   fmpz_t temp;
      
   if (sizeb == 0)
   {
      printf("Error: division by zero!\n");
      abort();          
   } else if (sizea < sizeb) // Todo: make this deal with sizea == sizeb but a < b
   {
      res[0] = 0;
   } else 
   {
      temp = (fmpz_t) flint_stack_alloc(sizeb);
      mpn_tdiv_qr(res+1, temp, 0, a+1, sizea, b+1, sizeb);
      res[0] = sizea - sizeb + 1;
      if ((long) (a0 ^ b0) < 0) res[0] = -res[0];
      flint_stack_release();  
   }
   NORM(res);
}     
Exemplo n.º 3
0
Arquivo: fmpz.c Projeto: hperl/flint
// truncated multiplication for fmpz
void fmpz_mul_trunc(fmpz_t res, fmpz_t a, fmpz_t b, unsigned long trunc)
{
    unsigned long sizea = FLINT_MIN(fmpz_size(a), trunc);
    unsigned long sizeb = FLINT_MIN(fmpz_size(b), trunc);
    while ((!a[sizea]) && (sizea)) sizea--;
    while ((!b[sizeb]) && (sizeb)) sizeb--;

    if ((sizea == 0) || (sizeb == 0)) {
        res[0] = 0;
        return;
    }

    if (trunc >= sizea + sizeb) {
        mp_limb_t mslimb;
        if (sizea >= sizeb) mslimb = F_mpn_mul(res+1, a+1, sizea, b+1, sizeb);
        else mslimb = F_mpn_mul(res+1, b+1, sizeb, a+1, sizea);
        res[0] = sizea + sizeb - (mslimb == 0);
    } else {
        mp_limb_t mslimb;
        fmpz_t temp = flint_stack_alloc(sizea + sizeb + 1);
        if (sizea >= sizeb) mslimb = F_mpn_mul_trunc(temp+1, a+1, sizea, b+1, sizeb, trunc);
        else mslimb = F_mpn_mul_trunc(temp+1, b+1, sizeb, a+1, sizea, trunc);
        temp[0] = trunc;
        if (UNLIKELY(!mslimb))
            __fmpz_normalise(temp); // normalise if most significant limb == 0
        fmpz_set(res, temp);
        flint_stack_release();
    }
    if ((long) (a[0] ^ b[0]) < 0L) res[0] = -res[0];
}
Exemplo n.º 4
0
Arquivo: fmpz.c Projeto: hperl/flint
void fmpz_addmul(fmpz_t res, const fmpz_t a, const fmpz_t b) 
{
      long a0 = a[0];
      long b0 = b[0];
      unsigned long sizea = FLINT_ABS(a0);
      unsigned long sizeb = FLINT_ABS(b0);
      while ((!a[sizea]) && (sizea)) sizea--;
      while ((!b[sizeb]) && (sizeb)) sizeb--;
      
      fmpz_t temp;
      mp_limb_t mslimb;
      
      if (sizea && sizeb)
      {
         if (sizea + sizeb < 100)
         {
            temp = (fmpz_t) flint_stack_alloc_small(sizea + sizeb + 1);
            if (sizea >= sizeb) mslimb = mpn_mul(temp+1, a+1, sizea, b+1, sizeb);
            else mslimb = mpn_mul(temp+1, b+1, sizeb, a+1, sizea);
            temp[0] = sizea + sizeb - (mslimb == 0);
            if ((long) (a[0] ^ b[0]) < 0) temp[0] = -temp[0];
            fmpz_add(res, res, temp);
            flint_stack_release_small();
         } else
         {
            temp = (fmpz_t) flint_stack_alloc(sizea + sizeb + 1);
            if (sizea >= sizeb) mslimb = F_mpn_mul(temp+1, a+1, sizea, b+1, sizeb);
            else mslimb = F_mpn_mul(temp+1, b+1, sizeb, a+1, sizea);
            temp[0] = sizea + sizeb - (mslimb == 0);
            if ((long) (a[0] ^ b[0]) < 0) temp[0] = -temp[0];
            fmpz_add(res, res, temp);
            flint_stack_release();
         }        
      }     
} 
Exemplo n.º 5
0
void tiny_poly_clear(poly_t * poly_inf)
{
   mpz_clear(poly_inf->C);
   flint_stack_release(); // release all A_inv2B[i]
   flint_stack_release(); // release soln1
   flint_stack_release(); // release soln2
   flint_stack_release(); // release A_inv
   flint_stack_release(); // release inv_p2
   flint_stack_release(); // release A_inv2B
   flint_stack_release(); // release A_modp
   flint_stack_release(); // release A_ind
   flint_stack_release(); // release B_terms
   
}
Exemplo n.º 6
0
Arquivo: fmpz.c Projeto: hperl/flint
void fmpz_mul(fmpz_t res, const fmpz_t a, const fmpz_t b) 
{
      long a0 = a[0];
      long b0 = b[0];
      unsigned long sizea = FLINT_ABS(a0);
      unsigned long sizeb = FLINT_ABS(b0);
      while ((!a[sizea]) && (sizea)) sizea--;
      while ((!b[sizeb]) && (sizeb)) sizeb--;
      
      mp_limb_t mslimb;
      fmpz_t temp;
      
      if ((sizea == 0) || (sizeb == 0))
      {
        res[0] = 0;
      } else if (sizea + sizeb < 100)
      {
         temp = (fmpz_t) flint_stack_alloc_small(sizea + sizeb + 1);
         if (sizea > sizeb) mslimb = mpn_mul(temp+1, a+1, sizea, b+1, sizeb);
         else if (sizea == sizeb) 
			{
				mpn_mul_n(temp+1, a+1, b+1, sizeb);
				mslimb = temp[2*sizeb];
			}
			else mslimb = mpn_mul(temp+1, b+1, sizeb, a+1, sizea);
         temp[0] = sizea + sizeb - (mslimb == 0);
         F_mpn_copy(res, temp, temp[0]+1);
         if ((long) (a0 ^ b0) < 0) res[0] = -res[0];
         flint_stack_release_small();     
      } else if (sizea + sizeb < 2*FLINT_FFT_LIMBS_CROSSOVER)
      {
         temp = (fmpz_t) flint_stack_alloc(sizea + sizeb + 1);
         if (sizea > sizeb) mslimb = mpn_mul(temp+1, a+1, sizea, b+1, sizeb);
			else if (sizea == sizeb) 
			{
				mpn_mul_n(temp+1, a+1, b+1, sizeb);
				mslimb = temp[2*sizeb];
			}
			else mslimb = mpn_mul(temp+1, b+1, sizeb, a+1, sizea);
         temp[0] = sizea + sizeb - (mslimb == 0);
         F_mpn_copy(res, temp, temp[0]+1);
         if ((long) (a0 ^ b0) < 0) res[0] = -res[0];
         flint_stack_release();   
      } else
      {
         if (sizea >= sizeb) mslimb = F_mpn_mul(res+1, a+1, sizea, b+1, sizeb);
         else mslimb = F_mpn_mul(res+1, b+1, sizeb, a+1, sizea);
         res[0] = sizea+sizeb - (mslimb == 0);
         if ((long) (a0 ^ b0) < 0) res[0] = -res[0];
      }
}      
Exemplo n.º 7
0
Arquivo: fmpz.c Projeto: hperl/flint
void fmpz_fdiv(fmpz_t res, const fmpz_t a, const fmpz_t b) 
{
   long a0 = a[0];
   long b0 = b[0];
   unsigned long sizea = FLINT_ABS(a0);
   unsigned long sizeb = FLINT_ABS(b0);
   while ((!a[sizea]) && (sizea)) sizea--;
   while ((!b[sizeb]) && (sizeb)) sizeb--;
      

   mp_limb_t mslimb;
   fmpz_t temp;
      
   if (sizeb == 0)
   {
      printf("Error: division by zero!\n");
      abort();          
   } else if (sizea < sizeb) // Todo: make this deal with sizea == sizeb but a < b
   {
      if (((long) (a0 ^ b0) < 0L) && (a0)) 
      {
         res[0] = -1L;
         res[1] = 1;  
      } else res[0] = 0;
      return;
   } else 
   {
      temp = (fmpz_t) flint_stack_alloc(sizeb);
      mpn_tdiv_qr(res+1, temp, 0, a+1, sizea, b+1, sizeb);
      res[0] = sizea - sizeb + 1;
      if ((long) (a0 ^ b0) < 0L) res[0] = -res[0];
      NORM(res);
      if ((long) (a0 ^ b0) < 0L)
      {
         unsigned long i = 0; 
         for (; i < sizeb; i++)
         {
            if (temp[i]) break;
         }
         if (i < sizeb)
         {
            fmpz_sub_ui_inplace(res, 1UL);
         }
      }
      flint_stack_release();  
   }
}     
Exemplo n.º 8
0
Arquivo: fmpz.c Projeto: hperl/flint
void fmpz_gcd(fmpz_t output, fmpz_t x1, fmpz_t x2)
{
	ulong size1 = FLINT_ABS(x1[0]);
	ulong size2 = FLINT_ABS(x2[0]);
   mpz_t m1, m2, m0, m_out;
	m1->_mp_d = x1 + 1;
   m2->_mp_d = x2 + 1;
	m1->_mp_alloc = size1;
	m1->_mp_size = size1;
	m2->_mp_alloc = size2;
	m2->_mp_size = size2;
	ulong size_out = FLINT_MAX(size1, size2)+1;
	m0->_mp_d = flint_stack_alloc(size_out);
   m0->_mp_alloc = size_out;
   m0->_mp_size = 0;
	mpz_gcd(m0, m1, m2);
	size_out = m0->_mp_size;
	F_mpn_copy(output + 1, m0->_mp_d, size_out);
	output[0] = size_out;
	flint_stack_release();
}
Exemplo n.º 9
0
void compute_B_terms(QS_t * qs_inf, poly_t * poly_inf)
{
   unsigned long s = poly_inf->s;
   unsigned long * A_ind = poly_inf->A_ind;
   unsigned long * A_modp = poly_inf->A_modp;
   unsigned long * B_terms = poly_inf->B_terms;
   prime_t * factor_base = qs_inf->factor_base;
   unsigned long limbs = qs_inf->prec+1;
   unsigned long limbs2;
   unsigned long * A = poly_inf->A;
   unsigned long * B = poly_inf->B;
   unsigned long p, i; 
   unsigned long * temp1 = (unsigned long *) flint_stack_alloc(limbs);
   unsigned long temp;
   mp_limb_t msl;
   double pinv;
   
   for (i = 0; i < s; i++)
   {
      p = factor_base[A_ind[i]].p;
      pinv = z_precompute_inverse(p);
      mpn_divmod_1(temp1 + 1, A + 1, A[0], p);
      temp1[0] = A[0] - (temp1[A[0]] == 0); 
      A_modp[i] = (temp = mpn_mod_1(temp1 + 1, temp1[0], p));
      temp = z_invert(temp, p);
      temp = z_mulmod_precomp(temp, qs_inf->sqrts[A_ind[i]], p, pinv);
      if (temp > p/2) temp = p - temp;
      msl = mpn_mul_1(B_terms + i*limbs + 1, temp1 + 1, temp1[0], temp);
      if (msl) 
      {
         B_terms[i*limbs + temp1[0] + 1] = msl;
         B_terms[i*limbs] = temp1[0] + 1;
      }
      else B_terms[i*limbs] = temp1[0];
#if B_TERMS
      mpz_t temp;
      mpz_init(temp);
      fmpz_to_mpz(temp, B_terms + i*limbs);
      gmp_printf("B_%ld = %Zd\n", i, temp);
      mpz_clear(temp);
#endif
   }
   
   F_mpn_copy(B, B_terms, B_terms[0]+1);  // Set B to the sum of the B terms
   if (limbs > B_terms[0] + 1) F_mpn_clear(B + B_terms[0] + 1, limbs - B_terms[0] - 1);
   for (i = 1; i < s; i++)
   {
      limbs2 = B_terms[i*limbs];
      msl = mpn_add_n(B+1, B+1, B_terms + i*limbs + 1, limbs2);
      if (msl) mpn_add_1(B + limbs2 + 1, B + limbs2 + 1, limbs - limbs2 - 1, msl);
   }
   B[0] = limbs - 1;
   while (!B[B[0]] && B[0]) B[0]--;
#if B_TERMS
   mpz_t temp2;
   mpz_init(temp2);
   fmpz_to_mpz(temp2, B);
   gmp_printf("B = %Zd\n", temp2);
   mpz_clear(temp2);
#endif
   
   flint_stack_release(); // release temp1
}
Exemplo n.º 10
0
void compute_A(QS_t * qs_inf, poly_t * poly_inf)
{
   unsigned long min = poly_inf->min;
   unsigned long span = poly_inf->span;
   unsigned long s = poly_inf->s;
   unsigned long * A_ind = poly_inf->A_ind;
   unsigned long * A = poly_inf->A;
   unsigned long * target_A = poly_inf->target_A;
   unsigned long * current_A = (unsigned long *) flint_stack_alloc(qs_inf->prec+1);  
   unsigned long * diff = (unsigned long *) flint_stack_alloc(qs_inf->prec+1);  
   unsigned long * best_diff = (unsigned long *) flint_stack_alloc(qs_inf->prec+1);  
   prime_t * factor_base = qs_inf->factor_base;
   unsigned long factor, p;
   unsigned long best1, best2, best3;
   unsigned long odds = s - 3;
   mp_limb_t msl;
   int taken;
   long i, j, k;
   
   A[0] = 1;
   A[1] = 1;
   for (i = 0; i < odds; i++) // Randomly choose the first s-3 prime factors of A with odd indices
   {
      do
      {
         taken = 0;
         A_ind[i] = ((z_randint(span) + min) | 1);
         if (A_ind[i] == min + span) A_ind[i] -= 2;
         for (j = 0; j < i; j++)
         {
            if (A_ind[i] == A_ind[j]) taken = 1;
         }  
      } while (taken);
      msl = mpn_mul_1(A+1, A+1, A[0], factor_base[A_ind[i]].p);
      if (msl) // Compute the product of these s-3 primes
      {
         A[A[0]+1] = msl;
         A[0]++;
      }
   }
 
   for (k = 0; k < 30; k++) // Now try 8 different sets of even index primes as the remaining factors
   {
      F_mpn_copy(current_A, A, A[0] + 1);
      for (i = 0; i < 3; i++) // Randomly choose the last 3 prime factors of A with even indices
      {
         do
         {
            taken = 0;
            A_ind[s-3+i] = ((z_randint(span) + min) & -2L);
            if (A_ind[s-3+i] < min) A_ind[s-3+i] += 2;
            for (j = 0; j < i; j++)
            {
               if (A_ind[s-3+i] == A_ind[s-3+j]) taken = 1;
            }  
         } while (taken);

         msl = mpn_mul_1(current_A+1, current_A+1, current_A[0], factor_base[A_ind[s-3+i]].p);
         if (msl) // Compute the product of these s-3 primes and the odd indexed primes
         {
            current_A[current_A[0]+1] = msl;
            current_A[0]++;
         }
      }
      
      if (k == 0)  // Just store the first difference as the best one
      {
         if (target_A[0] >= current_A[0]) // Compute the difference with the target A
         {
            msl = mpn_sub(best_diff+1, target_A+1, target_A[0], current_A+1, current_A[0]);
            best_diff[0] = target_A[0];
         }
         else 
         {
            msl = mpn_sub(best_diff+1, current_A+1, current_A[0], target_A+1, target_A[0]);
            best_diff[0] = current_A[0];
         }
         if (msl) F_mpn_negate(best_diff+1, best_diff+1, best_diff[0]);
         while ((!best_diff[best_diff[0]]) && (best_diff[0])) best_diff[0]--; // Normalise best_diff
         
         best1 = A_ind[s-3];
         best2 = A_ind[s-2];
         best3 = A_ind[s-1];
   
         continue;
      }

      if (target_A[0] >= current_A[0]) // Compute the difference with the target A
      {
         msl = mpn_sub(diff+1, target_A+1, target_A[0], current_A+1, current_A[0]);
         diff[0] = target_A[0];
      }
      else 
      {
         msl = mpn_sub(diff+1, current_A+1, current_A[0], target_A+1, target_A[0]);
         diff[0] = current_A[0];
      }
      if (msl) F_mpn_negate(diff+1, diff+1, diff[0]);
      while ((!diff[diff[0]]) && (diff[0])) diff[0]--; // Normalise diff

      if ((diff[0] < best_diff[0]) || ((diff[0] == best_diff[0]) && (mpn_cmp(diff+1, best_diff+1, diff[0]) < 0)))  // The new diff is better
      {
         F_mpn_copy(best_diff, diff, diff[0]+1);
         best1 = A_ind[s-3];
         best2 = A_ind[s-2];
         best3 = A_ind[s-1];         
      }
   }    

   A_ind[s-3] = best1; // Multiply A by the product of these 3 primes and store their indices
   A_ind[s-2] = best2;
   A_ind[s-1] = best3;   
   for (i = 0; i < 3; i++) 
   {
      msl = mpn_mul_1(A+1, A+1, A[0], factor_base[A_ind[s+i-3]].p);
      if (msl) 
      {
         A[A[0]+1] = msl;
         A[0]++;
      }
   }
              
#if POLY_A
   mpz_t A_disp, targ_A;
   mpz_init(A_disp);
   mpz_init(targ_A);
   fmpz_to_mpz(A_disp, A);
   fmpz_to_mpz(targ_A, target_A);
   gmp_printf("A = %Zd, target A = %Zd\n", A_disp, targ_A);
   mpz_clear(A_disp);
   mpz_clear(targ_A);
#endif    
 
   /*for (i = 0; i < s; i++)
   {
      p = factor_base[A_ind[i]].p;
      poly_inf->inv_p2[i] = z_precompute_inverse(p*p);
   } */

   fmpz_to_mpz(poly_inf->A_mpz, A);
   
   flint_stack_release(); // release current_A
   flint_stack_release(); // release diff
   flint_stack_release(); // release best_diff     
}
Exemplo n.º 11
0
void poly_clear(poly_t * poly_inf)
{
   mpz_clear(poly_inf->A_mpz);
   mpz_clear(poly_inf->B_mpz);
   mpz_clear(poly_inf->C);
   flint_stack_release(); // release all A_inv2B[i]
   flint_stack_release(); // release posn1
   flint_stack_release(); // release posn2
   flint_stack_release(); // release soln1
   flint_stack_release(); // release soln2
   flint_stack_release(); // release A_inv
   flint_stack_release(); // release inv_p2
   flint_stack_release(); // release A_inv2B
   flint_stack_release(); // release A_modp
   flint_stack_release(); // release A_ind
   flint_stack_release(); // release target_A
   flint_stack_release(); // release A
   flint_stack_release(); // release B_terms
   flint_stack_release(); // release B
}
Exemplo n.º 12
0
void sqrts_clear(void)
{
   flint_stack_release();
}
Exemplo n.º 13
0
Arquivo: fmpz.c Projeto: hperl/flint
int fmpz_divides(fmpz_t q, const fmpz_t a, const fmpz_t b) 
{
   long a0 = a[0];
   long b0 = b[0];
   unsigned long sizea = FLINT_ABS(a0);
   unsigned long sizeb = FLINT_ABS(b0);   

   mp_limb_t mslimb;
   fmpz_t temp;
      
   if (sizeb == 0)
   {
      printf("Error: division by zero!\n");
      abort();          
   } else if (sizea == 0)
	{
		q[0] = 0;
		return 1;
	} else if (sizea < sizeb) 
   {
      return 0;
   } else if (sizea == sizeb) 
	{
		int cmp = fmpz_cmpabs(a, b);
		if (cmp < 0) return 0;
      if (cmp == 0)
		{
			if ((long) (a0 ^ b0) < 0L) q[0] = -1L;
			else q[0] = 1L;
			q[1] = 1;
		   return 1;
		}
   } 

   if (fmpz_is_one(b)) 
	{
	   fmpz_set(q, a); 
		return 1;
	}

	if (fmpz_is_m1(b))
	{
		fmpz_neg(q, a);
		return 1;
	}
	  
	temp = (fmpz_t) flint_stack_alloc(sizeb + 2);
   mpn_tdiv_qr(q+1, temp+1, 0, a+1, sizea, b+1, sizeb);
      
	temp[0] = sizeb;
   NORM(temp);
      
	if (temp[0] != 0) 
	{
		flint_stack_release();
		return 0;
	}

	q[0] = sizea - sizeb + 1;
	NORM(q);

	if ((long) (a0 ^ b0) < 0L) q[0] = -q[0];
   
	flint_stack_release();
	return 1;
}     
Exemplo n.º 14
0
Arquivo: fmpz.c Projeto: hperl/flint
void fmpz_mod(fmpz_t res, const fmpz_t a, const fmpz_t b) 
{
   long a0 = a[0];
   long b0 = b[0];
   unsigned long sizea = FLINT_ABS(a0);
   unsigned long sizeb = b0;
   while ((!a[sizea]) && (sizea)) sizea--;
   while ((!b[sizeb]) && (sizeb)) sizeb--;
      

   mp_limb_t mslimb;
   fmpz_t temp, temp2;
      
   if (sizeb == 0)
   {
      printf("Error: division by zero!\n");
      abort();          
   } else if (sizea < sizeb) 
   {
      if ((long) a0 < 0L) 
      {
         temp = (fmpz_t) flint_stack_alloc(sizeb + 2);
         fmpz_add(temp, a, b);
         fmpz_set(res, temp);
         flint_stack_release();  
      } else fmpz_set(res, a);
      return;
   } else if ((sizea == sizeb) && (fmpz_cmpabs(a, b) < 0L))
   {
      if (fmpz_sgn(a) < 0) fmpz_add(res, a, b);
      else fmpz_set(res, a);
	  return;
   } else
   {
      if (fmpz_is_one(b)) 
	  {
	     fmpz_set_ui(res, 0L); 
		 return;
	  }
	  temp = (fmpz_t) flint_stack_alloc(sizea - sizeb + 1);
      temp2 = (fmpz_t) flint_stack_alloc(sizeb + 2);
      mpn_tdiv_qr(temp, temp2+1, 0, a+1, sizea, b+1, sizeb);
      temp2[0] = sizeb;
      NORM(temp2);
      if (a0 < 0L)
      {
         unsigned long i = 0; 
         for (; i < sizeb; i++)
         {
            if (temp2[i+1]) break;
         }
         if (i < sizeb)
         {
            fmpz_sub(temp2, b, temp2);
         } 
         fmpz_set(res, temp2);
      } else fmpz_set(res, temp2);
      flint_stack_release();  
      flint_stack_release();  
   }
}     
Exemplo n.º 15
0
void primes_clear(void)
{
   flint_stack_release();
}
Exemplo n.º 16
0
void sizes_clear(void)
{
   flint_stack_release();
}
Exemplo n.º 17
0
Arquivo: fmpz.c Projeto: hperl/flint
void fmpz_comb_init(fmpz_comb_t comb, ulong * primes, ulong num_primes)
{
   ulong i, j, k;
	
	comb->primes = primes;
   comb->num_primes = num_primes;

   ulong n = 0L;
   while (num_primes > (1L<<n)) n++;
   comb->n = n;
	ulong num;

	
   // create zn_poly modulus information
	comb->mod = (zn_mod_t *) flint_heap_alloc_bytes(sizeof(zn_mod_t)*num_primes);
   for (ulong i = 0; i < num_primes; i++) 
      zn_mod_init(comb->mod[i], primes[i]);

	if (n == 0) return; // nothing to do

	// allocate space for comb
   comb->comb = (fmpz_t **) flint_heap_alloc(n);

   j = (1L<<(n - 1));
   ulong size = 2;
   mp_limb_t * ptr;
   for (i = 0; i < n; i++)
   {
      comb->comb[i] = (fmpz_t *) flint_heap_alloc(j);

      ptr = (mp_limb_t *) flint_heap_alloc((1L<<n) + j);
      for (k = 0; k < j; k++, ptr += (size + 1))
      {
         comb->comb[i][k] = ptr;
      }

      j/=2;
      size*=2;
   }

	// allocate space for res
	comb->res = (fmpz_t **) flint_heap_alloc(n);
   j = (1L<<(n - 1));
   size = 2;
   for (i = 0; i < n; i++)
   {
      comb->res[i] = (fmpz_t *) flint_heap_alloc(j);
		
      ptr = (mp_limb_t *) flint_heap_alloc((1L<<n) + j);
      for (k = 0; k < j; k++, ptr += (size + 1))
      {
         comb->res[i][k] = ptr;
      }
      
		j/=2;
      size*=2;
   }

	// compute products of pairs of primes and place in comb
	for (i = 0, j = 0; i + 2 <= num_primes; i += 2, j++)
   {
      fmpz_set_ui(comb->comb[0][j], primes[i]);
      fmpz_mul_ui(comb->comb[0][j], comb->comb[0][j], primes[i+1]);
   }
   if (i < num_primes) // in case number of primes is odd
   {
      fmpz_set_ui(comb->comb[0][j], primes[i]);
	   i+=2;
	   j++;
	}
   num = (1L<<n); // set the rest of the entries on that row of the comb to 1
	for (; i < num; i += 2, j++)
   {
      fmpz_set_ui(comb->comb[0][j], 1L);
	}

	// compute rest of comb by multiplying in pairs
	ulong log_comb = 1;
	num /= 2;
   while (num >= 2)
   {
      for (i = 0, j = 0; i < num; i += 2, j++)
      {
         fmpz_mul(comb->comb[log_comb][j], comb->comb[log_comb-1][i], comb->comb[log_comb-1][i+1]);
      }
      log_comb++;
      num /= 2;
   }

	// compute inverses from pairs of primes
	fmpz_t temp = (fmpz_t) flint_stack_alloc(2);
   fmpz_t temp2 = (fmpz_t) flint_stack_alloc(2);
   for (i = 0, j = 0; i + 2 <= num_primes; i += 2, j++)
   {
       fmpz_set_ui(temp, primes[i]);
       fmpz_set_ui(temp2, primes[i+1]);
       fmpz_invert(comb->res[0][j], temp, temp2);
	}
   flint_stack_release(); //temp2
   flint_stack_release(); //temp
   
   ulong log_res = 1;
   num = (1L<<(n - 1));

   // compute remaining inverses, each level combining pairs from the level below
	while (log_res < n)
   {
      for (i = 0, j = 0; i < num; i += 2, j++)
      {
         fmpz_invert(comb->res[log_res][j], comb->comb[log_res-1][i], comb->comb[log_res-1][i+1]);
      }
      log_res++;
      num /= 2;
   }  
}
Exemplo n.º 18
0
void flint_stack_release_small(void)
{
   flint_stack_release();
}