コード例 #1
0
ファイル: log.c プロジェクト: gioAlea/Crab_Cavity_Simulations
void scs_log(scs_ptr res, db_number y, int E) {
    scs_t R, sc_ln2_times_E, res1, addi;
    scs_ptr ti, inv_wi;
    db_number z, wi;
    int i;


#if EVAL_PERF
    crlibm_second_step_taken++;
#endif


    /* to normalize y.d and round to nearest      */
    /* + (1-trunc(sqrt(2.)/2 * 2^(4))*2^(-4) )+2.^(-(4+1))*/
    z.d = y.d + norm_number.d;
    i = (z.i[HI_ENDIAN] & 0x000fffff);
    i = i >> 16; /* 0<= i <=11 */


    wi.d = ((double)(11+i))*0.0625;

    /* (1+f-w_i) */
    y.d -= wi.d;

    /* Table reduction */
    ti     = table_ti_ptr[i];
    inv_wi = table_inv_wi_ptr[i];

    /* R = (1+f-w_i)/w_i */
    scs_set_d(R, y.d);
    scs_mul(R, R, inv_wi);


    /*
     * Polynomial evaluation of log(1 + R) with an error less than 2^(-130)
     */

    scs_mul(res1, constant_poly_ptr[0], R);
    for(i=1; i<20; i++) {
        scs_add(addi, constant_poly_ptr[i], res1);
        scs_mul(res1, addi, R);
    }

    if(E==0) {
        scs_add(res, res1, ti);
    } else {
        /* sc_ln2_times_E = E*log(2)  */
        scs_set(sc_ln2_times_E, sc_ln2_ptr);

        if (E >= 0) {
            scs_mul_ui(sc_ln2_times_E, (unsigned int) E);
        } else {
            scs_mul_ui(sc_ln2_times_E, (unsigned int) -E);
            sc_ln2_times_E->sign = -1;
        }
        scs_add(addi, res1, ti);
        scs_add(res, addi, sc_ln2_times_E);
    }
}
コード例 #2
0
int rem_pio2_scs(scs_ptr result, const scs_ptr x){
  uint64_t r[SCS_NB_WORDS+3], tmp;
  unsigned int N;
  /* result r[0],...,r[10] could store till 300 bits of precision */
  /* that is really enough for computing the reduced argument */
  int sign, i, j, ind;
  int *two_over_pi_pt;

  if ((X_EXP != 1)||(X_IND < -1)){
    scs_set(result, x);
    return 0;
  }
  


  /* Compute the product |x| * 2/Pi */
  if ((X_IND == -1)){
    /* In this case we consider number between ]-1,+1[    */
    /* we may use simpler algorithm such as Cody And Waite */
    r[0] =  0;    r[1] =  0;
    r[2] =  (uint64_t)(two_over_pi[0]) * X_HW[0];
    r[3] = ((uint64_t)(two_over_pi[0]) * X_HW[1]
	   +(uint64_t)(two_over_pi[1]) * X_HW[0]);
    if(X_HW[2] == 0){
      for(i=4; i<(SCS_NB_WORDS+3); i++){   
	r[i] = ((uint64_t)(two_over_pi[i-3]) * X_HW[1]
	       +(uint64_t)(two_over_pi[i-2]) * X_HW[0]);
      }}else {
	for(i=4; i<(SCS_NB_WORDS+3); i++){   
	  r[i] = ((uint64_t)(two_over_pi[i-4]) * X_HW[2]
		 +(uint64_t)(two_over_pi[i-3]) * X_HW[1]
		 +(uint64_t)(two_over_pi[i-2]) * X_HW[0]);
	}
      }
  }else {
    if (X_IND == 0){
      r[0] =  0;
      r[1] =  (uint64_t)(two_over_pi[0]) * X_HW[0];
      r[2] = ((uint64_t)(two_over_pi[0]) * X_HW[1]
	     +(uint64_t)(two_over_pi[1]) * X_HW[0]);
      if(X_HW[2] == 0){
	for(i=3; i<(SCS_NB_WORDS+3); i++){   
	  r[i] = ((uint64_t)(two_over_pi[i-2]) * X_HW[1]
		 +(uint64_t)(two_over_pi[i-1]) * X_HW[0]);
	}}else {
	  for(i=3; i<(SCS_NB_WORDS+3); i++){   
	    r[i] = ((uint64_t)(two_over_pi[i-3]) * X_HW[2]
		   +(uint64_t)(two_over_pi[i-2]) * X_HW[1]
		   +(uint64_t)(two_over_pi[i-1]) * X_HW[0]);
	  }}
    }else {
      if (X_IND == 1){
	r[0] =  (uint64_t)(two_over_pi[0]) * X_HW[0];
	r[1] = ((uint64_t)(two_over_pi[0]) * X_HW[1]
	       +(uint64_t)(two_over_pi[1]) * X_HW[0]);
	if(X_HW[2] == 0){
	  for(i=2; i<(SCS_NB_WORDS+3); i++){   
	    r[i] = ((uint64_t)(two_over_pi[i-1]) * X_HW[1]
		   +(uint64_t)(two_over_pi[ i ]) * X_HW[0]);
	  }}else {
	    for(i=2; i<(SCS_NB_WORDS+3); i++){   
	      r[i] = ((uint64_t)(two_over_pi[i-2]) * X_HW[2]
		     +(uint64_t)(two_over_pi[i-1]) * X_HW[1]
		     +(uint64_t)(two_over_pi[ i ]) * X_HW[0]);
	    }}
      }else {
	if (X_IND == 2){
  	  r[0] = ((uint64_t)(two_over_pi[0]) * X_HW[1]
		 +(uint64_t)(two_over_pi[1]) * X_HW[0]);
	  if(X_HW[2] == 0){
	    for(i=1; i<(SCS_NB_WORDS+3); i++){   
	      r[i] = ((uint64_t)(two_over_pi[ i ]) * X_HW[1]
		     +(uint64_t)(two_over_pi[i+1]) * X_HW[0]);
	    }}else {
	      for(i=1; i<(SCS_NB_WORDS+3); i++){   
		r[i] = ((uint64_t)(two_over_pi[i-1]) * X_HW[2]
		       +(uint64_t)(two_over_pi[ i ]) * X_HW[1]
		       +(uint64_t)(two_over_pi[i+1]) * X_HW[0]);
	      }}
	}else {
	  ind = (X_IND - 3);
	  two_over_pi_pt = (int*)&(two_over_pi[ind]);
	  if(X_HW[2] == 0){
	    for(i=0; i<(SCS_NB_WORDS+3); i++){   
	      r[i] = ((uint64_t)(two_over_pi_pt[i+1]) * X_HW[1]
		     +(uint64_t)(two_over_pi_pt[i+2]) * X_HW[0]);
	    }}else {
	      for(i=0; i<(SCS_NB_WORDS+3); i++){   
		r[i] = ((uint64_t)(two_over_pi_pt[ i ]) * X_HW[2]
		       +(uint64_t)(two_over_pi_pt[i+1]) * X_HW[1]
		       +(uint64_t)(two_over_pi_pt[i+2]) * X_HW[0]);
	      }
	    }
	}
      }
    }
  }
      
  /* Carry propagate */
  r[SCS_NB_WORDS+1] += r[SCS_NB_WORDS+2]>>30;
  for(i=(SCS_NB_WORDS+1); i>0; i--) {tmp=r[i]>>30;   r[i-1] += tmp;  r[i] -= (tmp<<30);}  
      
  /* The integer part is in r[0] */
  N = (unsigned int)(r[0]);
#if 0
  printf("r[0] = %d\n", N);
#endif


  /* test if the reduced part is bigger than Pi/4 */
  if (r[1] > (uint64_t)(SCS_RADIX)/2){
    N += 1;
    sign = -1;
    for(i=1; i<(SCS_NB_WORDS+3); i++) { r[i]=((~(unsigned int)(r[i])) & 0x3fffffff);}
  } 
  else
    sign = 1; 


  /* Now we get the reduce argument and check for possible
   * cancellation By Kahan algorithm we will have at most 2 digits
   * of cancellations r[1] and r[2] in the worst case.
   */    
  if (r[1] == 0)
    if (r[2] == 0) i = 3;
    else           i = 2;
  else             i = 1;

  for(j=0; j<SCS_NB_WORDS; j++) { R_HW[j] = (unsigned int)(r[i+j]);}


  R_EXP   = 1;
  R_IND   = -i;
  R_SGN   = sign*X_SGN; 
  
  /* Last step :
   *   Multiplication by pi/2
   */
  scs_mul(result, Pio2_ptr, result);
  return X_SGN*N;
}
コード例 #3
0
ファイル: log10.c プロジェクト: JamesMolson/SixTrack
/*************************************************************
 *************************************************************
 *               ROUNDED  TO NEAREST
 *************************************************************
 *************************************************************/
double log10_rn(double x)
{
  scs_t R, res1;
  scs_t sc_ln2_r10_times_E;
  scs_ptr inv_wi, ti;
 
  db_number nb, nb2, wi, resd;
  int i, E=0;

  nb.d = x;
  /* Filter cases */
  if (nb.i[HI_ENDIAN] < 0x00100000){        /* x < 2^(-1022)    */
    if (((nb.i[HI_ENDIAN] & 0x7fffffff)|nb.i[LO_ENDIAN])==0)
      /* return 1.0/0.0; */                       /* log(+/-0) = -Inf */
	 return NInf.d;
    if (nb.i[HI_ENDIAN] < 0) 
      /* return (x-x)/0; */                       /* log(-x) = Nan    */
	 return NaN.d;

    /* Subnormal number */
    E    -= (SCS_NB_BITS*2); /* keep in mind that x is a subnormal number */ 
    nb.d *=SCS_RADIX_TWO_DOUBLE;  /* make x as normal number     */         
    /* We may just want add 2 to the scs number.index */
    /* may be .... we will see */
  }
  if (nb.i[HI_ENDIAN] >= 0x7ff00000)
    return x+x;                             /* Inf or Nan       */

  /* find n, nb.d such that sqrt(2)/2 < nb.d < sqrt(2) */
  E += (nb.i[HI_ENDIAN]>>20)-1023;
  nb.i[HI_ENDIAN] =  (nb.i[HI_ENDIAN] & 0x000fffff) | 0x3ff00000;
  if (nb.d > SQRT_2){
    nb.d *= 0.5;
    E++;
  }


  /* to normalize nb.d and round to nearest      */
  /* +((2^4 - trunc(sqrt(2)/2) *2^4 )*2 + 1)/2^5 */ 
  nb2.d = nb.d + norm_number.d; 
  i = (nb2.i[HI_ENDIAN] & 0x000fffff);
  i = i >> 16; /* 0<= i <=11 */
  
  wi.d = (11+i)*(double)0.6250e-1;

  /* (1+f-w_i) */
  nb.d -= wi.d; 
  
  /* Table reduction */
  ti     = table_ti_ptr[i]; 
  inv_wi = table_inv_wi_ptr[i];

 
  /* R = (1+f-w_i)/w_i */
  scs_set_d(R, nb.d);
  scs_mul(R, R, inv_wi);
 

  /* sc_ln2_r10_times_E = E*log10(2)  */
  scs_set(sc_ln2_r10_times_E, sc_ln2_r10_ptr);
  
  if (E >= 0){
    scs_mul_ui(sc_ln2_r10_times_E, (unsigned int) E);
  }else{
    scs_mul_ui(sc_ln2_r10_times_E, (unsigned int) -E);
    sc_ln2_r10_times_E->sign = -1;
  }


  /*
   * Polynomial evaluation of log10(1 + R) with an error less than 2^(-130)
   */
  scs_mul(res1, constant_poly_ptr[0], R);
  for(i=1; i<20; i++){
    scs_add(res1, constant_poly_ptr[i], res1);
    scs_mul(res1, res1, R);
  }
  scs_add(res1, res1, ti);
  scs_add(res1, res1, sc_ln2_r10_times_E);  


  scs_get_d(&resd.d, res1);  
  
  return resd.d;
}
コード例 #4
0
static void scs_atan(scs_ptr res_scs, scs_ptr x){
  scs_t X_scs, denom1_scs, denom2_scs, poly_scs, X2;
  scs_t atanbhihi,atanbhilo, atanblo, atanbhi, atanb;
  scs_t bsc_ptr;
  db_number db;
  double test;
  int k, i=31;


  scs_get_d(&db.d, x);

#if EVAL_PERF
  crlibm_second_step_taken++;
#endif

  /* test if x as to be reduced */
  if (db.d > MIN_REDUCTION_NEEDED) {
    /* Compute i so that  x E [a[i],a[i+1]] */
    if (db.d < arctan_table[i][A].d) i-= 16;
    else i+=16;
    if (db.d < arctan_table[i][A].d) i-= 8;
    else i+= 8;
    if (db.d < arctan_table[i][A].d) i-= 4;
    else i+= 4;
    if (db.d < arctan_table[i][A].d) i-= 2;
    else i+= 2;
    if (db.d < arctan_table[i][A].d) i-= 1;
    else if (i<61) i+= 1;
    if (db.d < arctan_table[i][A].d) i-= 1;

    /* evaluate X = (x - b(i)) / (1 + x*b(i)) */
    scs_set_d(bsc_ptr, arctan_table[i][B].d);

    scs_mul(denom1_scs,bsc_ptr,x);
    scs_add(denom2_scs,denom1_scs,SCS_ONE);
    scs_sub(X_scs,x,bsc_ptr);
    scs_div(X_scs,X_scs,denom2_scs);

    scs_get_d(&test,X_scs);

    /* Polynomial evaluation of atan(X) , X = (x-b(i)) / (1+ x*b(i)) */
    scs_square(X2, X_scs);
    scs_set(res_scs, constant_poly_ptr[0]);
    for(k=1; k < 10; k++) {
      /* we use Horner expression */
      scs_mul(res_scs, res_scs, X2);
      scs_add(res_scs, constant_poly_ptr[k], res_scs);
    }
    scs_mul(poly_scs, res_scs, X_scs);

    /* reconstruction : */

    /* 1st we load atan ( b[i] ) in a scs*/
    scs_set_d( atanbhihi , arctan_table[i][ATAN_BHI].d);
    scs_set_d( atanbhilo , arctan_table[i][ATAN_BLO].d);
    scs_set_d( atanblo , atan_blolo[i].d);
    scs_add(atanbhi,atanbhihi,atanbhilo);
    scs_add(atanb,atanbhi,atanblo);
    scs_add(res_scs,atanb, poly_scs);
    return;
  }

  else
    { /* no reduction needed */
      /* Polynomial evaluation of atan(x) */
      scs_square(X2, x);
      scs_set(res_scs, constant_poly_ptr[0]);
      for(k=1; k < 10; k++) {
        /* we use Horner expression */
        scs_mul(res_scs, res_scs, X2);
        scs_add(res_scs, constant_poly_ptr[k], res_scs);
      }
      scs_mul(res_scs, res_scs, x);
      return;
    }
}