Example #1
0
GmpInt& GmpInt::operator/=(long value)
{
    copyIfShared();
    if(value >= 0)
        mpz_tdiv_q_ui(mData->mInteger, mData->mInteger, value);
    else
    {
        mpz_neg(mData->mInteger, mData->mInteger);
        mpz_tdiv_q_ui(mData->mInteger, mData->mInteger, -value);
    }
    return *this;
}
Example #2
0
void mpz_arctan(mpz_t r, unsigned long base, mpz_t pow, mpz_t t1, mpz_t t2)
{
    unsigned long i = 1;
    mpz_tdiv_q_ui(r, pow, base);
    mpz_set(t1, r);
    do {
        mpz_ui_pow_ui(t2, base, 2);
        mpz_tdiv_q(t1, t1, t2);
        mpz_tdiv_q_ui(t2, t1, 2*i+1);
        if (i++ & 1) mpz_sub(r, r, t2);
        else mpz_add(r, r, t2);
    } while (mpz_sgn(t2));
}
Example #3
0
void main() {
   char* hex = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d";
   mpz_t decimal;
   mpz_init(decimal);
   int exponent = 0;
   for (int i = strlen(hex)-1; i >= 0; i--) {
      int number = hex2decimal(hex[i]);
      // decimal += number * (int)Math.pow(16, exponent);
      mpz_t power;
      // mpz_t must be initialized before mpz_ui_pow_ui()
      mpz_init(power);
      mpz_ui_pow_ui(power, 16, exponent);
      mpz_addmul_ui(decimal, power, number);
      // printf("hex: %c, number: %d, exponent: %d, decimal: ", hex[i], number, exponent);
      // mpz_out_str(stdout, 10, decimal);
      // printf("\n");
      exponent += 1;
   }

   char* builder = malloc(sizeof(strlen(hex)));
   int divider = 64;
   mpz_t number;
   mpz_init_set(number, decimal);
   int index = 0;
   while (mpz_cmp_ui(number, divider) > 0) {
      mpz_t quotient;
      int remainder = mpz_tdiv_q_ui(quotient, number, divider);
      char letter = decimal2base64(remainder);
      builder[index] = letter;
      index++;
      mpz_set(number, quotient);
   }
   mpz_t quotient;
   int remainder = mpz_tdiv_q_ui(quotient, number, divider);
   char letter = decimal2base64(remainder);
   builder[index] = letter;
   index++;
   builder[index] = '\0';
   char* result = malloc(sizeof(strlen(builder)+1));
   strcpy(result, builder);
   reverse(result);
   puts(result);
   char* base64 = "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t";
   printf("hex:     %s\n", hex);
   printf("decimal: ");
   mpz_out_str(stdout, 10, decimal);
   printf("\n");
   printf("base64:  %s\n", base64);
   printf(strcmp(result, base64) == 0 ? "passed\n" : "failed\n");
}
Example #4
0
void actan(mpz_t res, unsigned long base, mpz_t pows)
{
	int i, neg = 1;
	mpz_tdiv_q_ui(res, pows, base);
	mpz_set(tmp1, res);
	for (i = 3; ; i += 2) {
		mpz_tdiv_q_ui(tmp1, tmp1, base * base);
		mpz_tdiv_q_ui(tmp2, tmp1, i);
		if (mpz_cmp_ui(tmp2, 0) == 0) break;
		if (neg) mpz_sub(res, res, tmp2);
		else	  mpz_add(res, res, tmp2);
		neg = !neg;
	}
}
Example #5
0
char *
mpc_get_str (mpc_t op)
{
  char *return_value;
  mpz_t temp_op;
  mpz_t temp1;
  mpz_t temp2;

  if (op.precision == 0)
    return_value = mpz_get_str (NULL, 10, op.object);
  else
    {
      mpz_init (temp_op);
      mpz_abs (temp_op, op.object);
      
      mpz_init_set (temp1, temp_op);
      mpz_init_set_ui (temp2, 1);

      power_of_ten (temp2, op.precision);
      mpz_tdiv_q (temp1, temp1, temp2);

      return_value = concatinate_free (mpz_get_str (NULL, 10, temp1), ".", true, false);

      mpz_mul (temp1, temp1, temp2);
      mpz_sub (temp1, temp_op, temp1);

      mpz_abs (temp1, temp1);

      mpz_tdiv_q_ui (temp2, temp2, 10);

      while (mpz_cmp (temp2, temp1) > 0)
	{
	  return_value = concatinate_free (return_value, "0", true, false);
	  mpz_tdiv_q_ui (temp2, temp2, 10);
	}

      return_value = concatinate_free (return_value, mpz_get_str (NULL, 10, temp1), true, true);

      if (mpz_sgn (op.object) < 0)
	return_value = concatinate_free ("-", return_value, false, true);

      mpz_clear (temp1);
      mpz_clear (temp2);
      mpz_clear (temp_op);
    }

  return return_value;
}
Example #6
0
void
mpc_get_mpz (mpz_t rop, mpc_t op)
{
  mpz_set (rop, op.object);
  while (op.precision-- != 0)
    mpz_tdiv_q_ui (rop, rop, 10);
}
Example #7
0
void
fmpz_tdiv_q_ui(fmpz_t f, const fmpz_t g, ulong h)
{
    fmpz c1 = *g;
    ulong c2 = h;

    if (h == 0)
    {
        printf("Exception: division by zero in fmpz_tdiv_q_ui\n");
        abort();
    }

    if (!COEFF_IS_MPZ(c1))      /* g is small */
    {
        if (c1 > 0)
        {
            fmpz_set_ui(f, c1 / c2);
        }
        else
        {
            ulong q = ((ulong) -c1) / c2;

            fmpz_set_si(f, - (long) q);
        }
    }
    else                        /* g is large */
    {
        __mpz_struct *mpz_ptr = _fmpz_promote(f);

        mpz_tdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2);
        _fmpz_demote_val(f);    /* division by h may result in small value */
    }
}
Example #8
0
File: prime.c Project: pbos/optimus
void factor(mpz_t num)
{
	if(mpz_probab_prime_p(num, 10) > 0)
	{
		mpz_set(factors[num_factors++], num);
		return;
	}

	// Trial division, "fairly cheap" compared to rest of QS
	for(size_t i = 0; i < num_primes; ++i)
	{
		while(mpz_tdiv_q_ui(q, num, primes[i]) == 0)
		{
			mpz_set_ui(factors[num_factors++], primes[i]);
			mpz_set(num, q);
		}
	}

	if(!mpz_cmp_ui(num, 1)) // If num==1 we're done
		return;

	if(mpz_probab_prime_p(num, 10) > 0)
	{
		mpz_set(factors[num_factors++], num);
		return;
	}

	sieve_factor(num);
}
Example #9
0
/*
First version -- uses Taylor series for exp(x) directly,
broken into two pieces

Note: this version is currently not used in the benchmark below
*/
void fix_exp(mpz_t z, mpz_t x, int prec)
{
    int k;
    int r = 8;
    //prec += 20;
    //mpz_set(_exp_x, x);
    //mpz_tdiv_q_2exp(_exp_x, _exp_x, r);
    mpz_tdiv_q_2exp(_exp_x, x, r);
    mpz_set_ui(_exp_s0, 1);
    mpz_mul_2exp(_exp_s0, _exp_s0, prec);
    mpz_set(_exp_s1, _exp_s0);
    mpz_mul(_exp_x2, _exp_x, _exp_x);
    mpz_tdiv_q_2exp(_exp_x2,_exp_x2,prec);
    mpz_set(_exp_a, _exp_x2);
    k = 2;
    while(1)
    {
        mpz_tdiv_q_ui(_exp_a, _exp_a, k);
        if (mpz_sgn(_exp_a) == 0)
            break;
        mpz_add(_exp_s0, _exp_s0, _exp_a);
        k += 1;
        mpz_tdiv_q_ui(_exp_a, _exp_a, k);
        if (mpz_sgn(_exp_a) == 0)
            break;
        mpz_add(_exp_s1, _exp_s1, _exp_a);
        k += 1;
        mpz_mul(_exp_a, _exp_a, _exp_x2);
        mpz_tdiv_q_2exp(_exp_a,_exp_a,prec);
        if (mpz_sgn(_exp_a) == 0)
            break;
    }
    mpz_mul(_exp_s1, _exp_s1, _exp_x);
    mpz_tdiv_q_2exp(_exp_s1,_exp_s1,prec);
    mpz_add(_exp_s0, _exp_s0, _exp_s1);
    for(k=0; k<r; k++)
    {
        mpz_mul(_exp_s0, _exp_s0, _exp_s0);
        mpz_tdiv_q_2exp(_exp_s0,_exp_s0,prec);
    }
    //mpz_tdiv_q_ui(z, _exp_s0, 20);
    mpz_set(z, _exp_s0);
}
Example #10
0
/**
 *  @brief Check if an node is a white move
 *  @param[in] id The identifier used
 *  @return 1 If the node is a white move
 *  @return 0 Otherwise
 *
 *  This function check if a given node is a white move
 *  or not, given its Identifier
 *
 */
int identifier_is_white(Identifier id) {
  Identifier tmp;
  int ret;
  mpz_init(tmp);

  mpz_tdiv_q_ui(tmp, id, 100000);
  ret = (mpz_tdiv_ui(tmp, 10) % 2);
  mpz_clear(tmp);
  return ret;
}
Example #11
0
/**
 *  @brief Check if an node contains a enpassant move
 *  @param[in] id The identifier used
 *  @return 1 If the node contains enpassant
 *  @return 0 Otherwise
 *
 *  This function check if a given node contains a enpassant move
 *  or not, given its Identifier
 *
 */
int identifier_is_passant(Identifier id) {
  Identifier tmp;
  int ret;
  mpz_init(tmp);

  mpz_tdiv_q_ui(tmp, id, 10000);
  ret = mpz_tdiv_ui(tmp, 10);
  mpz_clear(tmp);
  return ret;
}
Example #12
0
/**
 *  @brief Get the castling state
 *  @param[in] id The identifier used
 *  @return [|0;15|] Meaning a state of castling
 *
 *  This function check the castling state of an node, given its
 *  Identifier
 *
 */
int identifier_get_cast(Identifier id) {
  Identifier tmp;
  int ret;
  mpz_init(tmp);

  mpz_tdiv_q_ui(tmp, id, 100);
  ret = mpz_tdiv_ui(tmp, 100);
  mpz_clear(tmp);
  return ret;
}
Example #13
0
void bg_decrypt_block(bg_prikey key, FILE *in, FILE *out, mp_size_t len) {
	mpz_t y, xqmp, xpmq, pp, qq, negone;
	unsigned long int l;
	bbs_state *bbs;

	mpz_init(y);
	mpz_init(xqmp);
	mpz_init(xpmq);
	mpz_init(pp);
	mpz_init(qq);
	mpz_init_set_si(negone, -1);
	bbs = init_bbs(negone, key.n);
	bbs_gen(bbs, NULL, 8*len, 0);
	bbs_iter(bbs);
	bbs_close(bbs);
	l = bbs->len;
	mpz_inp_raw(y, in);

	mpz_add_ui(pp, key.p, 1);
	mpz_tdiv_q_ui(pp, pp, 4);
	mpz_pow_ui(pp, pp, l);
	mpz_powm_sec(pp, y, pp, key.p);

	mpz_add_ui(qq, key.q, 1);
	mpz_tdiv_q_ui(qq, qq, 4);
	mpz_pow_ui(qq, qq, l);
	mpz_powm_sec(qq, y, qq, key.q);

	mpz_mul(xqmp, key.q, pp);
	mpz_powm(pp, key.q, negone, key.p);
	mpz_mul(xqmp, xqmp, pp);

	mpz_mul(xpmq, key.p, qq);
	mpz_powm(qq, key.p, negone, key.q);
	mpz_mul(xpmq, xpmq, qq);

	mpz_add(y, xqmp, xpmq);
	mpz_mod(y, y, key.n);

	bbs = init_bbs(y, key.n);
	while(len && !feof(in)) len -= bg_xor(bbs, in, out, len);
	bbs_close(bbs);
}
Example #14
0
mpz_class digitalSum( mpz_class x ) {
	mpz_class result = 0;
	unsigned long digit;

	while( x != 0 ) {
		digit = mpz_tdiv_q_ui( x.get_mpz_t(), x.get_mpz_t(), 10 );
		result += digit;
	}

	return result;
}
Example #15
0
void S1(mpz_t n, uint64_t crn, int8_t* mu, mpz_t result)
{
  mpz_t tmp;
  mpz_inits(result, tmp, NULL);
  uint64_t i;
  for(i=1; i<=crn; i++)
    {
      mpz_tdiv_q_ui(tmp, n, i);
      mpz_mul_si(tmp, tmp, mu[i]);
      mpz_add(result, result, tmp);
    }
}
Example #16
0
/**
 *  @brief Extract an item from the stack
 *  @return -1 If the stack is empty
 *  @return int the first element of the stack
 *
 *  This function extract an item from the stack
 *  and returns it
 *  @note If the stack contains 0 it means it is empty since
 *  the moveGenerator will never add the a1a1 move.
 *
 */
int stack_pop(Stack *s) {
  mpz_t tmp;
  int ret;
  if (!mpz_cmp_ui(*s, 0)) {
    ret = -1;
  } else {
    mpz_init_set(tmp, *s);

    ret = (mpz_tdiv_q_ui(*s, tmp, MAX_PAIRS));
    mpz_clear(tmp);
  }
  return ret;
}
Example #17
0
unsigned int isTruncatableRight(mpz_t n)
{
    mpz_t value;
    mpz_init(value);
    mpz_set(value, n);
    while (mpz_cmp_ui(value, 0) > 0)
    {
        //printNumber("right ", value, "\n");
        if (!isPrime(value))
            return 0;
        mpz_tdiv_q_ui(value, value, 10);
    }
    return 1;
}
Example #18
0
static void select_curve_params(mpz_t a, mpz_t b, mpz_t g,
                                long D, mpz_t *roots, long i, mpz_t N, mpz_t t)
{
  int N_is_not_1_congruent_3;

  mpz_set_ui(a, 0);
  mpz_set_ui(b, 0);
  if      (D == -3) { mpz_set_si(b, -1); }
  else if (D == -4) { mpz_set_si(a, -1); }
  else {
    mpz_sub_ui(t, roots[i], 1728);
    mpz_mod(t, t, N);
    /* c = (j * inverse(j-1728)) mod n */
    if (mpz_divmod(b, roots[i], t, N, b)) {
      mpz_mul_si(a, b, -3);   /* r = -3c */
      mpz_mul_si(b, b, 2);    /* s =  2c */
    }
  }
  mpz_mod(a, a, N);
  mpz_mod(b, b, N);

  /* g:  1 < g < Ni && (g/Ni) != -1 && (g%3!=1 || cubic non-residue) */
  N_is_not_1_congruent_3 = ! mpz_congruent_ui_p(N, 1, 3);
  for ( mpz_set_ui(g, 2);  mpz_cmp(g, N) < 0;  mpz_add_ui(g, g, 1) ) {
    if (mpz_jacobi(g, N) != -1)
      continue;
    if (N_is_not_1_congruent_3)
      break;
    mpz_sub_ui(t, N, 1);
    mpz_tdiv_q_ui(t, t, 3);
    mpz_powm(t, g, t, N);   /* t = g^((Ni-1)/3) mod Ni */
    if (mpz_cmp_ui(t, 1) == 0)
      continue;
    if (D == -3) {
      mpz_powm_ui(t, t, 3, N);
      if (mpz_cmp_ui(t, 1) != 0)   /* Additional check when D == -3 */
        continue;
    }
    break;
  }
  if (mpz_cmp(g, N) >= 0)    /* No g can be found: N is composite */
    mpz_set_ui(g, 0);
}
Example #19
0
char factored(long lptr,mpz_t T)
{
    char facted = FALSE;// 可以分解 
    int i,j,r,st;
    partial = FALSE;// 被分成了两个部分 
    for(j=1;j<=mm;j++) // 尝试完全分解它 
    {
        r=(int)(lptr%epr[j]);
        if(r<0) r+=epr[j];
        if(r!=r1[j] && r!=r2[j]) continue;
        while(mpz_tdiv_q_ui(X, T, epr[j])==0) // X = T/epr[j],尝试对 T 用 epr[j] 做质因数分解
        {
            e[j]++;// 指数+1
            if(X!=T) mpz_set(T, X); //T = X,继续做
        }
        st=qsieve_getsize(T); // 如果T fits in int那么 st 存的就是 T
        if(st==1) // 被当前的epr[j]分解成1了,直接返回true
        {
           facted=TRUE;
           break;
        }
        if(qsieve_getsize(X)<=epr[j]) // X保存的是最后一次 T/epr[j] 的结果,尽管epr[j]可能不整除 T
        {
            if(st>=0x7FFFFFFF || (st/epr[mm])>(1+mlf/50)) break;
            if(st<=epr[mm]) // 当前剩下的数比epr中最大的那个要小,那么就找找看后面的素数
                for(i=j;i<=mm;i++)
                if(st==epr[i])
                {
                    e[i]++;
                    facted=TRUE;
                    break;
                }
            if(facted) break; //没有被部分分解,partial=false
            lp=st;
            partial=TRUE; //被部分分解了
            facted=TRUE; 
            break;
        }
    }
    return facted;
}
Example #20
0
unsigned int isTruncatableLeft(mpz_t n)
{
    unsigned int len = numberLength(n);
    mpz_t value, power;
    mpz_init(value);
    mpz_init(power);
    mpz_set(value, n);
    mpz_set_ui(power, 1);
    for (unsigned int i = 1; i < len; i++)
        mpz_mul_ui(power, power, 10);
    while (mpz_cmp_ui(power, 0) > 0)
    {
        //printNumber("left ", value, ", power ");
        //printNumber("", power, "\n");
        if (!isPrime(value))
            return 0;
        mpz_mod(value, value, power);
        mpz_tdiv_q_ui(power, power, 10);
    }
    return 1;
}
Example #21
0
/**
 *  @brief Puts the "history" part of id in a stack
 *  @param[in] id The identifier holding the data
 *  @param[out] stack The stack in which to store extracted data
 *
 *  Extract the "history" part of the identifier (the moves since root board)
 *  and store it in a stack
 *
 */
int identifier_to_stack(Identifier id, Stack *stack) {
  return mpz_tdiv_q_ui(*stack, id, 1000000);
}
Example #22
0
int main()
{
    unsigned int i,j,a,*SV;
    unsigned char logpi;
    int k,S,r,s1,s2,s,NS,logm,ptr,threshold,epri;
    long M,la,lptr;

    qsieve=gmpinit(-36,0);

    if(initv()<0) return 0;

    hmod=2*mlf+1;
    mpz_set_si(TA, hmod);
    while(!mpz_probab_prime_p(TA, qsieve->NTRY)) mpz_sub_ui(TA, TA, 2); //TT=不大于TT的素数
    hmod=qsieve_getsize(TA);
    hmod2=hmod-2;
    for(k=0;k<hmod;k++) hash[k]=(-1);

    M=50*(long)mm;
    NS=(int)(M/SSIZE);
    if(M%SSIZE!=0) NS++;
    M=SSIZE*(long)NS; // M为不小于50*mm的SSIZE的倍数中最小的 from 以上四行
    logm=0;
    la=M;
    while((la/=2)>0) logm++; // 以2为底
    rp[0]=logp[0]=0;
    for(k=1;k<=mm;k++) //求k*N在每个素数下的二次剩余解,与每个素数的ln(pi)
    {
        r=mpz_tdiv_q_ui(TA, D, epr[k]);
        rp[k]=qsieve_sqrmp(r,epr[k]);
        logp[k]=0;
        r=epr[k];
        while((r/=2)>0) logp[k]++;
    }

    r=mpz_tdiv_q_ui(TA, D, 8);
    if(r==5) logp[1]++;
    if(r==1) logp[1]+=2;

    threshold=logm+mpz_sizeinbase(R, 2)-2*logp[mm];

    jj=0;
    nlp=0;
    mpz_mul_si(DG, D, 2);
    mpz_root(DG, DG, 2);

    mpz_set_si(TA, M);
    qsieve_divide(DG,TA,DG);
    mpz_root(DG, DG, 2);
    if(mpz_tdiv_q_ui(TA, DG, 2)==0) mpz_add_ui(DG, DG, 1);
    if(mpz_tdiv_q_ui(TA, DG, 4)==1) mpz_add_ui(DG, DG, 2); // 令DG等于大于等于DG的数中模4余3的最小的数
    printf("  0%");

    while(1) //不断尝试新的多项式,可以并行计算
    {
        r=qsieve->NTRY;
        qsieve->NTRY=1;
        do
        {
            do {
               mpz_add_ui(DG, DG, 4);
            } while(!(mpz_probab_prime_p(DG, qsieve->NTRY) ? TRUE : FALSE));
            mpz_sub_ui(TA, DG, 1);
            mpz_tdiv_q_ui(TA, TA, 2);
            mpz_powm_sec(TA, D, TA, DG);
        } while(qsieve_getsize(TA)!=1); //直到DD是二次剩余
        qsieve->NTRY=r;
        mpz_add_ui(TA, DG, 1);
        mpz_tdiv_q_ui(TA, TA, 4);
        mpz_powm_sec(B, D, TA, DG);
        mpz_neg(TA, D);
        qsieve_muladddiv(B,B,TA,DG,TA,TA);
        mpz_neg(TA, TA);

        mpz_mul_si(A, B, 2);
        qsieve_extgcd(A,DG,A,A,A);
        qsieve_muladddiv(A,TA,TA,DG,DG,A);
        mpz_mul(TA, A, DG);
        mpz_add(B, B, TA);
        mpz_mul(A, DG, DG);
        qsieve_extgcd(DG,D,IG,IG,IG);
        
        r1[0]=r2[0]=0;
        for(k=1;k<=mm;k++) //s1和s2是两个解
        {
            s=mpz_tdiv_q_ui(TA, B, epr[k]);
            r=mpz_tdiv_q_ui(TA, A, epr[k]);
            r=qsieve_getinvers(r,epr[k]);

            s1=(epr[k]-s+rp[k]);
            s2=(epr[k]-s+epr[k]-rp[k]);
            if(s1 > s2)
            {
                int t = s1;
                s1 = s2;
                s2 = t;
            }
            r1[k]=(int)((((long long)s1)*((long long)r)) % ((long long)epr[k]));
            r2[k]=(int)((((long long)s2)*((long long)r)) % ((long long)epr[k]));
        }
        
        for(ptr=(-NS);ptr<NS;ptr++)
        {
            la=(long)ptr*SSIZE;
            SV=(unsigned int *)sieve;
            for(i=0; i<SSIZE/sizeof(int); i++) *SV++=0;
            for(k=1; k<=mm; k++)
            {
                epri=epr[k];
                logpi=logp[k];
                r=(int)(la%epri);
                s1=(r1[k]-r)%epri;
                if(s1<0) s1+=epri;
                s2=(r2[k]-r)%epri;
                if(s2<0) s2+=epri;

			/* 这部分是筛法的主要部分,数组下标表示多项式P(x)的参数x 
				s1与s2是两个P(x)=0(mod p)的解 */
                for(j=s1;j<SSIZE;j+=epri) sieve[j]+=logpi;
                if(s1==s2) continue;
                for(j=s2;j<SSIZE;j+=epri) sieve[j]+=logpi;
            }

            for(a=0;a<SSIZE;a++) //找那些没有被筛掉的数
            {
                if(sieve[a]<threshold) continue;
                lptr=la+a;
                mpz_set_si(TA, lptr);
                S=0;
                mpz_mul(TA, A, TA);
                mpz_add(TA, TA, B);
                qsieve_muladddiv(TA,IG,TA,D,D,P);
                if(qsieve_getsize(P)<0) mpz_add(P, P, D);
                qsieve_muladddiv(P,P,P,D,D,V);
                mpz_abs(TA, TA);
                if(qsieve_compare(TA,R)<0) S=1;
                if(S==1) mpz_sub(V, D, V);
                if(V!=TA) mpz_set(TA, V);
                e[0]=S;
                for(k=1;k<=mm;k++) e[k]=0;
                if(!factored(lptr,TA)) continue;
                if(gotcha())
                {
                    mpz_gcd(P, TA, N);
                    qsieve_getsize(P);
                    printf("\b\b\b\b100%\nFactors are\n");
                    qsieve_outnum(P,stdout);
                    qsieve_divide(N,P,N);
                    qsieve_outnum(N,stdout);
                    return 0;
                }
            }
        }
    }
    return 0;
}
Example #23
0
/*
Computes the exponential / trigonometric series

  alt = 0  -- c = cosh(x), s = sinh(x)
  alt = 1  -- c = cos(x), s = sin(x)
  alt = 2  -- c = exp(x), s = n/a

using the cosh/sinh series. Parameters:

  prec -- 
  r    -- number of argument reductions
  J    -- number of partitions of the series

*/
void exp_series(mpz_t c, mpz_t s, mpz_t x, int prec, int r, int J, int alt)
{
    int i, k, wp;

    wp = prec + 2*r + 10;

    mpz_fixed_one(_exp_one, wp);

    /*   x / 2^r, adjusted to wp   */
    mpz_mul_2exp(_exp_x, x, wp-prec);
    mpz_tdiv_q_2exp(_exp_x, _exp_x, r);

    if (J < 1)
        J = 1;
    
    for (i=0; i<J; i++)
    {
        if (i == 0)
        {
            mpz_set(_exp_pows[i], _exp_one);
        }
        else if (i == 1)
        {
            mpz_mul(_exp_pows[i], _exp_x, _exp_x);
            mpz_tdiv_q_2exp(_exp_pows[i], _exp_pows[i], wp);
        }
        else
        {
            mpz_mul(_exp_pows[i], _exp_pows[i-1], _exp_pows[1]);
            mpz_tdiv_q_2exp(_exp_pows[i], _exp_pows[i], wp);
        }
        mpz_set_ui(_exp_sums[i], 0);
    }

    if (J == 1)
    {
        mpz_mul(_exp_x, _exp_x, _exp_x);
        mpz_tdiv_q_2exp(_exp_x, _exp_x, wp);
        mpz_set(_exp_a, _exp_x);
    }
    else
    {
        mpz_mul(_exp_x, _exp_pows[J-1], _exp_pows[1]);
        mpz_tdiv_q_2exp(_exp_x, _exp_x, wp);
        mpz_set(_exp_a, _exp_pows[1]);
    }

    k = 2;
    while (mpz_sgn(_exp_a) != 0)
    {
        for (i=0; i<J; i++)
        {
            mpz_tdiv_q_ui(_exp_a, _exp_a, (k-1)*k);
            if ((alt == 1) && (k & 2))
            {
                mpz_sub(_exp_sums[i], _exp_sums[i], _exp_a);
            }
            else
            {
                mpz_add(_exp_sums[i], _exp_sums[i], _exp_a);
            }
            k += 2;
        }
        mpz_mul(_exp_a, _exp_a, _exp_x);
        mpz_tdiv_q_2exp(_exp_a, _exp_a, wp);
    }

    for (i=1; i<J; i++)
    {
        mpz_mul(_exp_sums[i], _exp_sums[i], _exp_pows[i]);
        mpz_tdiv_q_2exp(_exp_sums[i], _exp_sums[i], wp);
    }

    mpz_set(c, _exp_one);
    for (i=0; i<J; i++)
    {
        mpz_add(c, c, _exp_sums[i]);
    }

    /*
    Repeatedly apply the duplication formula

      cosh(2*x) = 2*cosh(x)^2 - 1
      cos(2*x) = 2*cos(x)^2 - 1
      exp(2*x) = exp(x)^2
    */

    if (alt == 2)
    {
        /* s = sqrt(|1-c^2|) */
        mpz_mul_2exp(_exp_one, _exp_one, wp);
        mpz_mul(s, c, c);
        mpz_sub(s, _exp_one, s);
        mpz_abs(s, s);
        mpz_sqrt(s, s);
        mpz_add(c, c, s);
        for (i=0; i<r; i++)
        {
            mpz_mul(c, c, c);
            mpz_tdiv_q_2exp(c, c, wp);
        }
    }
    else
    {
        for (i=0; i<r; i++)
        {
            mpz_mul(c, c, c);
            mpz_tdiv_q_2exp(c, c, wp-1);
            mpz_sub(c, c, _exp_one);
        }
        /* s = sqrt(|1-c^2|) */
        mpz_mul_2exp(_exp_one, _exp_one, wp);
        mpz_mul(s, c, c);
        mpz_sub(s, _exp_one, s);
        mpz_abs(s, s);
        mpz_sqrt(s, s);
    }

    mpz_tdiv_q_2exp(c, c, wp-prec);
    mpz_tdiv_q_2exp(s, s, wp-prec);

}
Example #24
0
int perform_xSigmax(struct classify_data* data)
{
    //printf("Going to start x'Sigmax calculation\n");
    void* socket = data->socket;
    paillier_pubkey_t* pkey = data->pub;
    paillier_prvkey_t* skey = data->prv;
    mpz_t mid;
    mpz_init_set(mid,pkey->n);
    mpz_tdiv_q_ui(mid,mid,2);
    paillier_plaintext_t** texts = data->texts;
    int len = data->maxcol;
    int i,j;
    int nlen;

    paillier_ciphertext_t** z = perform_sip(socket,pkey,texts,len,&nlen,data->rand);
    paillier_plaintext_t** ai = (paillier_plaintext_t**)malloc(nlen*sizeof(paillier_plaintext_t*));
    
    //TODO: find out why I can't use free_cipherarray here?
    for(j=0;j<nlen;j++){
        ai[j] = paillier_dec(NULL,pkey,skey,z[j]);
        if(mpz_cmp(ai[j]->m,mid)>0){
            mpz_sub(ai[j]->m,ai[j]->m,pkey->n);
        }
        paillier_freeciphertext(z[j]);
    }
    free(z);
    //printf("Recieved the result of x'Sigma for all sigmas\n");

    z = perform_sip(socket,pkey,texts,len,&nlen,data->rand);
    paillier_plaintext_t** qi = (paillier_plaintext_t**)malloc(nlen*sizeof(paillier_plaintext_t*));
    for(j=0;j<nlen;j++){
        qi[j] = paillier_dec(NULL,pkey,skey,z[j]);
        if(mpz_cmp(qi[j]->m,mid)>0){
            mpz_sub(qi[j]->m,qi[j]->m,pkey->n);
        }
    }
    free_cipherarray(z,nlen);

    //printf("Recieved the result of bx\n");
    
    mpz_t* aix = (mpz_t*)malloc(len*sizeof(mpz_t));
    mpz_t tmp;
    for(i=0;i<nlen;i++){
        mpz_init(aix[i]);
        mpz_add(aix[i],aix[i],qi[i]->m);
    }
    mpz_init(tmp);
    for(i=0;i<data->maxcol;i++){
        for(j=0;j<nlen;j++){
            mpz_mul(tmp,ai[j*data->maxcol+i]->m,texts[i]->m);
            mpz_add(aix[j],aix[j],tmp);
        }
    }

    //printf("Computed new answers\n");
    int index=0;
    mpz_t maxval;
    mpz_init(maxval);
    mpz_set(maxval,aix[0]);
    for(i=0;i<nlen;i++){
//        mpz_tdiv_q_ui(aix[i],aix[i],1000*1000*1000);
//        gmp_printf("ANSWER: %Zd\n",aix[i]);
        if(mpz_cmp(aix[i],maxval) > 0){
            index = i;
            mpz_set(maxval,aix[i]);
        }
        mpz_clear(aix[i]);
        paillier_freeplaintext(ai[i]);
        paillier_freeplaintext(qi[i]);
    }
   // gmp_printf("Max index was: %i with value %Zd\n",index,maxval);
    mpz_clear(maxval);
    free(aix);
    mpz_clear(tmp);
    //TODO: ask keith why this doesn't work
    //free(ai);
    return index;
    


}
Example #25
0
void zTrial(fact_obj_t *fobj)
{
	//trial divide n using primes below limit. optionally, print factors found.
	//input expected in the gmp_n field of div_obj.
	uint32 r,k=0;
	uint32 limit = fobj->div_obj.limit;
	int print = fobj->div_obj.print;
	FILE *flog;
	fp_digit q;
	mpz_t tmp;
	mpz_init(tmp);

	flog = fopen(fobj->flogname,"a");
	if (flog == NULL)
	{
		printf("fopen error: %s\n", strerror(errno));
		printf("could not open %s for writing\n",fobj->flogname);
		return;
	}

	if (P_MAX < limit)
	{
		free(PRIMES);
		PRIMES = soe_wrapper(spSOEprimes, szSOEp, 0, limit, 0, &NUM_P);
		P_MIN = PRIMES[0];
		P_MAX = PRIMES[NUM_P-1];
	}

	while ((mpz_cmp_ui(fobj->div_obj.gmp_n, 1) > 0) && 
		(PRIMES[k] < limit) && 
		(k < (uint32)NUM_P))
	{
		q = (fp_digit)PRIMES[k];
		r = mpz_tdiv_ui(fobj->div_obj.gmp_n, q);
		
		if (r != 0)
			k++;
		else
		{			
			mpz_tdiv_q_ui(fobj->div_obj.gmp_n, fobj->div_obj.gmp_n, q);
			mpz_set_64(tmp, q);

			add_to_factor_list(fobj, tmp);

#if BITS_PER_DIGIT == 64
			logprint(flog,"div: found prime factor = %" PRIu64 "\n",q);
#else
			logprint(flog,"div: found prime factor = %u\n",q);
#endif

			if (print && (VFLAG > 0))
#if BITS_PER_DIGIT == 64
				printf("div: found prime factor = %" PRIu64 "\n",q);
#else
				printf("div: found prime factor = %u\n",q);
#endif
		}
	}

	fclose(flog);
	mpz_clear(tmp);
}
Example #26
0
int
mpz_perfect_power_p (mpz_srcptr u)
{
  unsigned long int prime;
  unsigned long int n, n2;
  int i;
  unsigned long int rem;
  mpz_t u2, q;
  int exact;
  mp_size_t uns;
  mp_size_t usize = SIZ (u);
  TMP_DECL;

  if (mpz_cmpabs_ui (u, 1) <= 0)
    return 1;			/* -1, 0, and +1 are perfect powers */

  n2 = mpz_scan1 (u, 0);
  if (n2 == 1)
    return 0;			/* 2 divides exactly once.  */

  TMP_MARK;

  uns = ABS (usize) - n2 / BITS_PER_MP_LIMB;
  MPZ_TMP_INIT (q, uns);
  MPZ_TMP_INIT (u2, uns);

  mpz_tdiv_q_2exp (u2, u, n2);
  mpz_abs (u2, u2);

  if (mpz_cmp_ui (u2, 1) == 0)
    {
      TMP_FREE;
      /* factoring completed; consistent power */
      return ! (usize < 0 && POW2P(n2));
    }

  if (isprime (n2))
    goto n2prime;

  for (i = 1; primes[i] != 0; i++)
    {
      prime = primes[i];

      if (mpz_cmp_ui (u2, prime) < 0)
	break;

      if (mpz_divisible_ui_p (u2, prime))	/* divisible by this prime? */
	{
	  rem = mpz_tdiv_q_ui (q, u2, prime * prime);
	  if (rem != 0)
	    {
	      TMP_FREE;
	      return 0;		/* prime divides exactly once, reject */
	    }
	  mpz_swap (q, u2);
	  for (n = 2;;)
	    {
	      rem = mpz_tdiv_q_ui (q, u2, prime);
	      if (rem != 0)
		break;
	      mpz_swap (q, u2);
	      n++;
	    }

	  n2 = gcd (n2, n);
	  if (n2 == 1)
	    {
	      TMP_FREE;
	      return 0;		/* we have multiplicity 1 of some factor */
	    }

	  if (mpz_cmp_ui (u2, 1) == 0)
	    {
	      TMP_FREE;
	      /* factoring completed; consistent power */
	      return ! (usize < 0 && POW2P(n2));
	    }

	  /* As soon as n2 becomes a prime number, stop factoring.
	     Either we have u=x^n2 or u is not a perfect power.  */
	  if (isprime (n2))
	    goto n2prime;
	}
    }

  if (n2 == 0)
    {
      /* We found no factors above; have to check all values of n.  */
      unsigned long int nth;
      for (nth = usize < 0 ? 3 : 2;; nth++)
	{
	  if (! isprime (nth))
	    continue;
#if 0
	  exact = mpz_padic_root (q, u2, nth, PTH);
	  if (exact)
#endif
	    exact = mpz_root (q, u2, nth);
	  if (exact)
	    {
	      TMP_FREE;
	      return 1;
	    }
	  if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0)
	    {
	      TMP_FREE;
	      return 0;
	    }
	}
    }
  else
    {
      unsigned long int nth;

      if (usize < 0 && POW2P(n2))
	{
	  TMP_FREE;
	  return 0;
	}

      /* We found some factors above.  We just need to consider values of n
	 that divides n2.  */
      for (nth = 2; nth <= n2; nth++)
	{
	  if (! isprime (nth))
	    continue;
	  if (n2 % nth != 0)
	    continue;
#if 0
	  exact = mpz_padic_root (q, u2, nth, PTH);
	  if (exact)
#endif
	    exact = mpz_root (q, u2, nth);
	  if (exact)
	    {
	      if (! (usize < 0 && POW2P(nth)))
		{
		  TMP_FREE;
		  return 1;
		}
	    }
	  if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0)
	    {
	      TMP_FREE;
	      return 0;
	    }
	}

      TMP_FREE;
      return 0;
    }

n2prime:
  if (usize < 0 && POW2P(n2))
    {
      TMP_FREE;
      return 0;
    }

  exact = mpz_root (NULL, u2, n2);
  TMP_FREE;
  return exact;
}
Example #27
0
File: cal.c Project: hotaru2k3/cal
int main(int argc, char **argv) {
    mpz_t year, tmp1, tmp2, tmp3, tmp4;
    unsigned long day_of_week = 0;
    uintmax_t month_min = 1, month_max = 12;
    int_fast8_t month_days = 0;
    const int_fast8_t months_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,
                                          30, 31
                                        };
    time_t t = time(NULL);
    char weekday[13] = {0}, weekdays[92] = {0}, month_name[13] = {0};
    struct tm *time_struct = localtime(&t);
    setlocale(LC_ALL, "");
    mpz_init(year);
    switch(argc) {
    case 1:
        mpz_set_ui(year, time_struct->tm_year + 1900);
        month_min = month_max = time_struct->tm_mon + 1;
        break;
    case 2:
        mpz_set_str(year, argv[1], 10);
        break;
    default:
        month_min = month_max = strtoumax(argv[1], NULL, 10);
        mpz_set_str(year, argv[2], 10);
    }
    if(mpz_sgn(year) < 1 || !month_min || month_min > 12) {
        fputs("http://opengroup.org/onlinepubs/9699919799/utilities/cal.html\n",
              stderr);
        exit(1);
    }
    for(int_fast8_t i = 0; i < 7; ++i) {
        time_struct->tm_wday = i;
        strftime(weekday, 13, "%a", time_struct);
        strcat(weekdays, weekday);
        strcat(weekdays, " ");
    }
    strcat(weekdays, "\n");
    for(uintmax_t month = month_min; month <= month_max; ++month) {
        time_struct->tm_mon = month - 1;
        strftime(month_name, 13, "%b", time_struct);
        if(month > month_min) putchar('\n');
        for(int_fast8_t i = (23 - strlen(mpz_get_str(NULL, 10, year))) / 2; i > 0; --i)
            putchar(' ');
        fputs(month_name, stdout);
        putchar(' ');
        printf("%s\n", mpz_get_str(NULL, 10, year));
        fputs(weekdays, stdout);
        if(!mpz_cmp_ui(year, 1752) && month == 9) {
            fputs("         1   2  14  15  16", stdout);
            fputs("17  18  19  20  21  22  23", stdout);
            fputs("24  25  26  27  28  29  30", stdout);
        } else {
            month_days = months_days[month - 1];
            mpz_init(tmp1);
            mpz_init(tmp2);
            mpz_init(tmp3);
            mpz_init(tmp4);
            if(mpz_cmp_ui(year, 1752) > 0 || (!mpz_cmp_ui(year, 1752) && month > 9)) {
                /* Gregorian */
                if(month == 2 && mpz_divisible_ui_p(year, 4) && (!mpz_divisible_ui_p(year,
                        100) || mpz_divisible_ui_p(year, 400))) month_days = 29;
                mpz_add_ui(tmp4, year, 4800 - (14 - month) / 12);
                mpz_tdiv_q_ui(tmp1, tmp4, 4);
                mpz_tdiv_q_ui(tmp2, tmp4, 100);
                mpz_tdiv_q_ui(tmp3, tmp4, 400);
                mpz_mul_ui(tmp4, tmp4, 365);
                mpz_add(tmp4, tmp4, tmp1);
                mpz_sub(tmp4, tmp4, tmp2);
                mpz_add(tmp4, tmp4, tmp3);
                mpz_add_ui(tmp4, tmp4, (153 * (month + 12 * ((14 - month) / 12) - 3) + 2) /
                           5);
                mpz_sub_ui(tmp4, tmp4, 32043);
                day_of_week = mpz_tdiv_ui(tmp4, 7);
            } else {
                /* Julian */
                if(month == 2 && mpz_divisible_ui_p(year, 4))
                    month_days = 29;
                mpz_add_ui(tmp2, year, 4800 - (14 - month) / 12);
                mpz_tdiv_q_ui(tmp1, tmp2, 4);
                mpz_mul_ui(tmp2, tmp2, 365);
                mpz_add(tmp2, tmp2, tmp1);
                mpz_add_ui(tmp2, tmp2, (153 * (month + 12 * ((14 - month) / 12) - 3) + 2) /
                           5);
                mpz_sub_ui(tmp2, tmp2, 32081);
                day_of_week = mpz_tdiv_ui(tmp2, 7);
            }
            mpz_clear(tmp1);
            mpz_clear(tmp2);
            mpz_clear(tmp3);
            mpz_clear(tmp4);
            for(uint_fast8_t i = 0; i < day_of_week; ++i) fputs("    ", stdout);
            for(int_fast8_t i = 1; i <= month_days; ++i) {
                printf("%2u", i);
                ++day_of_week;
                if(i < month_days)
                    fputs((day_of_week %= 7) ? "  " : "\n", stdout);
            }
        }
        putchar('\n');
    }
    mpz_clear(year);
    return 0;
}
int
main (int argc, char **argv)
{
  mpz_t dividend;
  mpz_t quotient, remainder;
  mpz_t quotient2, remainder2;
  mpz_t temp;
  mp_size_t dividend_size;
  unsigned long divisor;
  int i;
  int reps = 10000;
  gmp_randstate_ptr rands;
  mpz_t bs;
  unsigned long bsi, size_range;
  unsigned long r_rq, r_q, r_r, r;

  tests_start ();
  rands = RANDS;

  mpz_init (bs);

  if (argc == 2)
     reps = atoi (argv[1]);

  mpz_init (dividend);
  mpz_init (quotient);
  mpz_init (remainder);
  mpz_init (quotient2);
  mpz_init (remainder2);
  mpz_init (temp);

  for (i = 0; i < reps; i++)
    {
      mpz_urandomb (bs, rands, 32);
      size_range = mpz_get_ui (bs) % 10 + 2; /* 0..2047 bit operands */

      do
	{
	  mpz_rrandomb (bs, rands, 64);
	  divisor = mpz_get_ui (bs);
	}
      while (divisor == 0);

      mpz_urandomb (bs, rands, size_range);
      dividend_size = mpz_get_ui (bs);
      mpz_rrandomb (dividend, rands, dividend_size);

      mpz_urandomb (bs, rands, 2);
      bsi = mpz_get_ui (bs);
      if ((bsi & 1) != 0)
	mpz_neg (dividend, dividend);

      /* printf ("%ld\n", SIZ (dividend)); */

      r_rq = mpz_tdiv_qr_ui (quotient, remainder, dividend, divisor);
      r_q = mpz_tdiv_q_ui (quotient2, dividend, divisor);
      r_r = mpz_tdiv_r_ui (remainder2, dividend, divisor);
      r = mpz_tdiv_ui (dividend, divisor);

      /* First determine that the quotients and remainders computed
	 with different functions are equal.  */
      if (mpz_cmp (quotient, quotient2) != 0)
	dump_abort ("quotients from mpz_tdiv_qr_ui and mpz_tdiv_q_ui differ",
		    dividend, divisor);
      if (mpz_cmp (remainder, remainder2) != 0)
	dump_abort ("remainders from mpz_tdiv_qr_ui and mpz_tdiv_r_ui differ",
		    dividend, divisor);

      /* Check if the sign of the quotient is correct.  */
      if (mpz_cmp_ui (quotient, 0) != 0)
	if ((mpz_cmp_ui (quotient, 0) < 0)
	    != (mpz_cmp_ui (dividend, 0) < 0))
	dump_abort ("quotient sign wrong", dividend, divisor);

      /* Check if the remainder has the same sign as the dividend
	 (quotient rounded towards 0).  */
      if (mpz_cmp_ui (remainder, 0) != 0)
	if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (dividend, 0) < 0))
	  dump_abort ("remainder sign wrong", dividend, divisor);

      mpz_mul_ui (temp, quotient, divisor);
      mpz_add (temp, temp, remainder);
      if (mpz_cmp (temp, dividend) != 0)
	dump_abort ("n mod d != n - [n/d]*d", dividend, divisor);

      mpz_abs (remainder, remainder);
      if (mpz_cmp_ui (remainder, divisor) >= 0)
	dump_abort ("remainder greater than divisor", dividend, divisor);

      if (mpz_cmp_ui (remainder, r_rq) != 0)
	dump_abort ("remainder returned from mpz_tdiv_qr_ui is wrong",
		    dividend, divisor);
      if (mpz_cmp_ui (remainder, r_q) != 0)
	dump_abort ("remainder returned from mpz_tdiv_q_ui is wrong",
		    dividend, divisor);
      if (mpz_cmp_ui (remainder, r_r) != 0)
	dump_abort ("remainder returned from mpz_tdiv_r_ui is wrong",
		    dividend, divisor);
      if (mpz_cmp_ui (remainder, r) != 0)
	dump_abort ("remainder returned from mpz_tdiv_ui is wrong",
		    dividend, divisor);
    }

  mpz_clear (bs);
  mpz_clear (dividend);
  mpz_clear (quotient);
  mpz_clear (remainder);
  mpz_clear (quotient2);
  mpz_clear (remainder2);
  mpz_clear (temp);

  tests_end ();
  exit (0);
}
Example #29
0
int main(int argc, char** argv)
{
	int 		my_rank,
				procs;

	MPI_Status	status;

	mpz_t 		q,
				p,
				pq,
				n,
				gap,
				sqn;

	mpz_t			*k;

	double 		*timearray;
	double		begin, end;
	double 		time_spent;
	
	int 		done = 0,
				found = 0;

	MPI_Init(&argc, &argv);
	MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
	MPI_Comm_size(MPI_COMM_WORLD, &procs);


	begin = MPI_Wtime();

	mpz_init(n);
	mpz_init(q);
	mpz_init(p);
	mpz_init(pq);
	mpz_init(sqn);
	mpz_init(gap);

	mpz_set_str(n,argv[1],10);
	mpz_sqrt(sqn,n);
	mpz_set(gap, sqn);

	mpz_set_ui(p,1);
	mpz_nextprime(q, p);


	size_t mag = mpz_sizeinbase (gap, 10);
	mag=mag*procs;

	k = (mpz_t*)malloc(sizeof(mpz_t)*(mag+1));
	
	mpz_t temp;
	mpz_init(temp);
	mpz_tdiv_q_ui(temp,gap,mag);	

	for (int i=0;i<=mag;i++)
	{
		mpz_init(k[i]);
		mpz_mul_ui(k[i],temp,i);
	}
	mpz_set(k[mag],sqn);





	int counter=0;


	for (int i=my_rank; i<mag; i=i+procs)
	{
		mpz_set(q,k[i]);

		mpz_sub_ui(q,q,1);
		mpz_nextprime(q,q);


		while (( mpz_cmp(q,k[i+1]) <= 0 )&&(!done)&&(!found)&&(mpz_cmp(q,sqn)<=0))
		{//finding the prime numbers
			counter++;
			if (counter%5000==0)MPI_Allreduce(&found, &done, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);

			if (mpz_divisible_p(n,q)==0) 
			{//if n is not divisible by q
				mpz_nextprime(q,q);
				continue;
			}

			//since it is divisible, try n/q and see if result is prime
			mpz_divexact(p,n,q);
			int reps;
			if (mpz_probab_prime_p(p,reps)!=0)
			{
				found = 1;
				done = 1;
			}
			else
			{
				mpz_nextprime(q,q);
			}
		}//done finding primes

		
		if (found || done) break;
		
	}
	
	end = MPI_Wtime();



	if (found)
	{
		MPI_Allreduce(&found, &done, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
		gmp_printf("*************************\nP%d: Finished\np*q=n\np=%Zd q=%Zd n=%Zd\n*************************\n", my_rank,p,q,n);
	}
	else if (!done)
	{
		while (!done&&!found)
			MPI_Allreduce(&found, &done, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
	}



	time_spent = (double)(end - begin);





	if (my_rank!=0)
	{
		MPI_Send(&time_spent, sizeof(double),MPI_CHAR,0,0,MPI_COMM_WORLD);
	}
	else
	{
		timearray = (double*)malloc(sizeof(double)*procs);
		
		
		timearray[0] = time_spent;

		int j; 
		for (j = 1; j<procs;j++)
		{
			double *ptr = timearray+j;
			MPI_Recv(ptr, sizeof(double),MPI_CHAR,j,0,MPI_COMM_WORLD,&status);
		}


		writeTime(argv[1],timearray,procs);
		free(timearray);

	}


	
	free(k);

	MPI_Finalize();
	return 0;
}
Example #30
0
uint64 init_sieve(soe_staticdata_t *sdata)
{
	int i,k;
	uint64 numclasses = sdata->numclasses;
	uint64 prodN = sdata->prodN;
	uint64 allocated_bytes = 0;
	uint64 lowlimit = sdata->orig_llimit; 
	uint64 highlimit = sdata->orig_hlimit;
	uint64 numflags, numbytes, numlinebytes;

	//create the selection masks
	for (i=0;i<BITSINBYTE;i++)
		nmasks[i] = ~masks[i];

	//allocate the residue classes.  
	sdata->rclass = (uint32 *)malloc(numclasses * sizeof(uint32));
	allocated_bytes += numclasses * sizeof(uint32);

	//find the residue classes
	k=0;
	for (i=1;i<prodN;i++)
	{
		if (spGCD(i,(uint64)prodN) == 1)
		{
			sdata->rclass[k] = (uint32)i;
			//printf("%u ",i);
			k++;
		}
	}

	sdata->min_sieved_val = 1ULL << 63;
	
	//temporarily set lowlimit to the first multiple of numclasses*prodN < lowlimit
	if (sdata->sieve_range == 0)
	{
		lowlimit = (lowlimit/(numclasses*prodN))*(numclasses*prodN);
		sdata->lowlimit = lowlimit;
	}
	else
	{
		mpz_t tmpz, tmpz2;
		mpz_init(tmpz);
		mpz_init(tmpz2);

		//the start of the range of interest is controlled by offset, not lowlimit
		//figure out how it needs to change to accomodate sieving
		mpz_tdiv_q_ui(tmpz, *sdata->offset, numclasses * prodN);
		mpz_mul_ui(tmpz, tmpz, numclasses * prodN);		
		mpz_sub(tmpz2, *sdata->offset, tmpz);

		//raise the high limit by the amount the offset was lowered, so that
		//we allocate enough flags to cover the range of interest
		highlimit += mpz_get_ui(tmpz2);
		sdata->orig_hlimit += mpz_get_ui(tmpz2);

		//also raise the original lowlimit so that we don't include sieve primes
		//that we shouldn't when finalizing the process.
		sdata->orig_llimit += mpz_get_ui(tmpz2);

		//copy the new value to the pointer, which will get passed back to sieve_to_depth
		mpz_set(*sdata->offset, tmpz);
		mpz_clear(tmpz);
		mpz_clear(tmpz2);

		//set the lowlimit to 0; the real start of the range is controlled by offset
		sdata->lowlimit = 0;
	}

	//reallocate flag structure for wheel and block sieving
	//starting at lowlimit, we need a flag for every 'numresidues' numbers out of 'prodN' up to 
	//limit.  round limit up to make this a whole number.
	numflags = (highlimit - lowlimit)/prodN;
	numflags += ((numflags % prodN) != 0);
	numflags *= numclasses;

	//since we can pack 8 flags in a byte, we need numflags/8 bytes allocated.
	numbytes = numflags / BITSINBYTE + ((numflags % BITSINBYTE) != 0);

	//since there are N lines to sieve over, each line will contain (numflags/8)/N bytes
	//so round numflags/8 up to the nearest multiple of N
	numlinebytes = numbytes/numclasses + ((numbytes % numclasses) != 0);

	//we want an integer number of blocks, so round up to the nearest multiple of blocksize bytes
	i = 0;
	while (1)
	{
		i += BLOCKSIZE;
		if (i > numlinebytes)
			break;
	}
	numlinebytes = i;

	//all this rounding has likely changed the desired high limit.  compute the new highlimit.
	//the orignial desired high limit is already recorded so the proper count will be returned.
	//todo... did we round too much?  look into this.
	highlimit = (uint64)((uint64)numlinebytes * (uint64)prodN * (uint64)BITSINBYTE + lowlimit);
	sdata->highlimit = highlimit;
	sdata->numlinebytes = numlinebytes;

	//a block consists of BLOCKSIZE bytes of flags
	//which holds FLAGSIZE flags.
	sdata->blocks = numlinebytes/BLOCKSIZE;

	//each flag in a block is spaced prodN integers apart.  record the resulting size of the 
	//number line encoded in each block.
	sdata->blk_r = FLAGSIZE*prodN;

	//allocate space for the root of each sieve prime
	sdata->root = (int *)malloc(sdata->pboundi * sizeof(int));
	allocated_bytes += sdata->pboundi * sizeof(uint32);
	if (sdata->root == NULL)
	{
		printf("error allocating roots\n");
		exit(-1);
	}
	else
	{
		if (VFLAG > 2)
			printf("allocated %u bytes for roots\n",(uint32)(sdata->pboundi * sizeof(uint32)));
	}

	//compute the breakpoints at which we switch to other sieving methods	
	if (sdata->pboundi > BUCKETSTARTI)
	{
		sdata->bucket_start_id = BUCKETSTARTI;
		sdata->num_bucket_primes = sdata->pboundi - sdata->bucket_start_id;		
	}
	else
	{
		sdata->num_bucket_primes = 0;
		sdata->bucket_start_id = sdata->pboundi;
	}

	//any prime larger than this will only hit the interval once (in residue space)
	sdata->large_bucket_start_prime = sdata->blocks * FLAGSIZE;

	//block ranges for the various line sieving scenarios:
	//2 classes: block range = 1572864, approx min prime index = 119275
	//8 classes: block range = 7864320, min prime index = 531290
	//48 classes: block range = 55050240, min prime index = 3285304
	//480 classes: block range = 605552640, min prime index = 31599827
	sdata->inplace_start_id = sdata->pboundi;
	sdata->num_inplace_primes = 0;
#if defined(INPLACE_BUCKET)

	switch (sdata->numclasses)
	{
	case 2:
		if (sdata->pboundi > 119275)
		{
			sdata->inplace_start_id = 119275;
			sdata->num_inplace_primes = sdata->pboundi - sdata->inplace_start_id;		
			sdata->num_bucket_primes = sdata->inplace_start_id - sdata->bucket_start_id;
		}

		break;
	case 8:
		if (sdata->pboundi > 531290)
		{
			sdata->inplace_start_id = 531290;
			sdata->num_inplace_primes = sdata->pboundi - sdata->inplace_start_id;	
			sdata->num_bucket_primes = sdata->inplace_start_id - sdata->bucket_start_id;
		}

		break;
	case 48:
		if (sdata->pboundi > 3285304)
		{
			sdata->inplace_start_id = 3285304;
			sdata->num_inplace_primes = sdata->pboundi - sdata->inplace_start_id;
			sdata->num_bucket_primes = sdata->inplace_start_id - sdata->bucket_start_id;
		}

		break;
	case 480:
		if (sdata->pboundi > 31599827)
		{
			sdata->inplace_start_id = 31599827;
			sdata->num_inplace_primes = sdata->pboundi - sdata->inplace_start_id;
			sdata->num_bucket_primes = sdata->inplace_start_id - sdata->bucket_start_id;
		}

		break;
	default:
		printf("unknown number of classes\n");
		exit(1);

		break;
	}

	// allocate data structures for inplace sieving
	if (sdata->num_inplace_primes > 0)
	{	
		// set up a two dimensional array of pointers to elements of the sieving prime array
		// first dimension is block number
		// second dimension is class number
		// element is a pointer to a uint32 (a sieving prime)
		sdata->inplace_ptrs = (int **)malloc(sdata->blocks * sizeof(int *));
		for (i=0; i<sdata->blocks; i++)
		{
			int j;
			sdata->inplace_ptrs[i] = (int *)malloc(sdata->numclasses * sizeof(int));
			for (j=0; j<sdata->numclasses; j++)
				sdata->inplace_ptrs[i][j] = -1;
		}

		// allocate space for the inplace data we'll need
		sdata->inplace_data = (soe_inplace_p *)malloc(
			sdata->num_inplace_primes * sizeof(soe_inplace_p));
	}

#endif

	//these are only used by the bucket sieve
	sdata->lower_mod_prime = (uint32 *)malloc(sdata->num_bucket_primes * sizeof(uint32));
	allocated_bytes += sdata->num_bucket_primes * sizeof(uint32);
	if (sdata->lower_mod_prime == NULL)
	{
		printf("error allocating lower mod prime\n");
		exit(-1);
	}
	else
	{
		if (VFLAG > 2)
			printf("allocated %u bytes for lower mod prime\n",
			(uint32)sdata->num_bucket_primes * (uint32)sizeof(uint32));
	}

	//allocate all of the lines if we are computing primes.  if we are
	//only counting them, just create the pointer array - lines will
	//be allocated as needed during sieving
	sdata->lines = (uint8 **)malloc(sdata->numclasses * sizeof(uint8 *));
	numbytes = 0;
	if (sdata->only_count)
	{
		//don't allocate anything now, but
		//provide an figure for the memory that will be allocated later
		numbytes = numlinebytes * sizeof(uint8) * THREADS;
	}
	else
	{
		//actually allocate all of the lines
		for (i=0; i<sdata->numclasses; i++)
		{
			sdata->lines[i] = (uint8 *)malloc(numlinebytes * sizeof(uint8));
			if (sdata->lines[i] == NULL)
			{
				printf("error allocated sieve lines\n");
				exit(-1);
			}
			numbytes += numlinebytes * sizeof(uint8);
		}
	}

	if (VFLAG > 2)
		printf("allocated %" PRIu64 " bytes for sieve lines\n",numbytes);
	allocated_bytes += numbytes;

	return allocated_bytes;
}