Exemple #1
0
char
binetasymptotic(floatnum x,
                int digits)
{
  floatstruct recsqr;
  floatstruct sum;
  floatstruct smd;
  floatstruct pwr;
  int i, workprec;

  if (float_getexponent(x) >= digits)
  {
    /* if x is very big, ln(gamma(x)) is
    dominated by x*ln x and the Binet function
    does not contribute anything substantial to
    the final result */
    float_setzero(x);
    return 1;
  }
  float_create(&recsqr);
  float_create(&sum);
  float_create(&smd);
  float_create(&pwr);

  float_copy(&pwr, &c1, EXACT);
  float_setzero(&sum);
  float_div(&smd, &c1, &c12, digits+1);
  workprec = digits - 2*float_getexponent(x)+3;
  i = 1;
  if (workprec > 0)
  {
    float_mul(&recsqr, x, x, workprec);
    float_reciprocal(&recsqr, workprec);
    while (float_getexponent(&smd) > -digits-1
           && ++i <= MAXBERNOULLIIDX)
    {
      workprec = digits + float_getexponent(&smd) + 3;
      float_add(&sum, &sum, &smd, digits+1);
      float_mul(&pwr, &recsqr, &pwr, workprec);
      float_muli(&smd, &cBernoulliDen[i-1], 2*i*(2*i-1), workprec);
      float_div(&smd, &pwr, &smd, workprec);
      float_mul(&smd, &smd, &cBernoulliNum[i-1], workprec);
    }
  }
  else
    /* sum reduces to the first summand*/
    float_move(&sum, &smd);
  if (i > MAXBERNOULLIIDX)
      /* x was not big enough for the asymptotic
    series to converge sufficiently */
    float_setnan(x);
  else
    float_div(x, &sum, x, digits);
  float_free(&pwr);
  float_free(&smd);
  float_free(&sum);
  float_free(&recsqr);
  return i <= MAXBERNOULLIIDX;
}
Error
pack2floatnum(
  floatnum x,
  p_number_desc n)
{
  floatstruct tmp;
  int digits;
  int saveerr;
  int saverange;
  Error result;
  signed char base;

  if ((result = _pack2int(x, &n->intpart)) != Success)
    return result;
  if (float_isnan(x))
    return Success;
  saveerr = float_geterror();
  saverange = float_setrange(MAXEXP);
  float_create(&tmp);
  float_move(&tmp, x);
  float_setzero(x);
  digits = DECPRECISION - float_getexponent(&tmp);
  if (digits <= 0
      || (result = _pack2frac(x, &n->fracpart, digits)) == Success)
    float_add(x, x, &tmp, DECPRECISION);
  if (result != Success)
    return result;
  if ((!float_getlength(x)) == 0) /* no zero, no NaN? */
  {
    base = n->prefix.base;
    float_setinteger(&tmp, base);
    if (n->exp >= 0)
    {
      _raiseposi_(&tmp, n->exp, DECPRECISION + 2);
      float_mul(x, x, &tmp, DECPRECISION + 2);
    }
    else
    {
      _raiseposi_(&tmp, -n->exp, DECPRECISION + 2);
      float_div(x, x, &tmp, DECPRECISION + 2);
    }
  }
  float_free(&tmp);
  float_setsign(x, n->prefix.sign == IO_SIGN_COMPLEMENT? -1 : n->prefix.sign);
  float_geterror();
  float_seterror(saveerr);
  float_setrange(saverange);
  if (!float_isvalidexp(float_getexponent(x)))
    float_setnan(x);
  return float_isnan(x)? IOExpOverflow : Success;
}
Exemple #3
0
void
ponder_move( int side_to_move, int book, int mid, int exact, int wld ) {
  EvaluationType eval_info;
  HashEntry entry;
  double move_start_time, move_stop_time;
  int i, j;
  int this_move, hash_move;
  int expect_count;
  int stored_echo;
  int best_pv_depth;
  int expect_list[64];
  int best_pv[61];

  /* Disable all time control mechanisms as it's the opponent's
     time we're using */

  toggle_abort_check( FALSE );
  toggle_midgame_abort_check( FALSE );
  start_move( 0, 0, disc_count( BLACKSQ ) + disc_count( WHITESQ ) );
  clear_ponder_times();
  determine_hash_values( side_to_move, board );

  reset_counter( &nodes );

  /* Find the scores for the moves available to the opponent. */

  hash_move = 0;
  find_hash( &entry, ENDGAME_MODE );
  if ( entry.draft != NO_HASH_MOVE )
    hash_move = entry.move[0];
  else {
    find_hash( &entry, MIDGAME_MODE );
    if ( entry.draft != NO_HASH_MOVE )
      hash_move = entry.move[0];
  }

  stored_echo = echo;
  echo = FALSE;
  (void) compute_move( side_to_move, FALSE, 0, 0, FALSE, FALSE,
		       MIN( PONDER_DEPTH, mid ), 0, 0, FALSE, &eval_info );
  echo = stored_echo;

  /* Sort the opponents on the score and push the table move (if any)
     to the front of the list */

  if ( force_return )
    expect_count = 0;
  else {
    sort_moves( move_count[disks_played] );
    (void) float_move( hash_move, move_count[disks_played] );

    expect_count = move_count[disks_played];
    for ( i = 0; i < expect_count; i++ )
      expect_list[i] = move_list[disks_played][i];

#if TEXT_BASED
    printf( "%s=%d\n", HASH_MOVE_TEXT, hash_move );
    for ( i = 0; i < expect_count; i++ ) {
      printf( "%c%c %-6.2f  ", TO_SQUARE( move_list[disks_played][i] ),
	      evals[disks_played][move_list[disks_played][i]] / 128.0 );
      if ( (i % 7 == 6) || (i == expect_count - 1) )
	puts( "" );
    }
#endif
  }

  /* Go through the expected moves in order and prepare responses. */

  best_pv_depth = 0;
  for ( i = 0; !force_return && (i < expect_count); i++ ) {
    move_start_time = get_real_timer();
    set_ponder_move( expect_list[i] );
    this_move = expect_list[i];
    prefix_move = this_move;
    (void) make_move( side_to_move, this_move, TRUE );
    (void) compute_move( OPP( side_to_move ), FALSE, 0, 0, TRUE, FALSE,
			 mid, exact, wld, FALSE, &eval_info );
    unmake_move( side_to_move, this_move );
    clear_ponder_move();
    move_stop_time =  get_real_timer();
    add_ponder_time( expect_list[i], move_stop_time - move_start_time );
    ponder_depth[expect_list[i]] =
      MAX( ponder_depth[expect_list[i]], max_depth_reached - 1 );
    if ( (i == 0) && !force_return ) {  /* Store the PV for the first move */
      best_pv_depth = pv_depth[0];
      for ( j = 0; j < pv_depth[0]; j++ )
	best_pv[j] = pv[0][j];
    }
  }

  /* Make sure the PV looks reasonable when leaving - either by
     clearing it altogether or, preferrably, using the stored PV for
     the first move if it is available. */

  max_depth_reached++;
  prefix_move = 0;
  if ( best_pv_depth == 0 )
    pv_depth[0] = 0;
  else {
    pv_depth[0] = best_pv_depth + 1;
    pv[0][0] = expect_list[0];
    for ( i = 0; i < best_pv_depth; i++ )
      pv[0][i + 1] = best_pv[i];
  }

  /* Don't forget to enable the time control mechanisms when leaving */

  toggle_abort_check( TRUE );
  toggle_midgame_abort_check( TRUE );
}
Exemple #4
0
char
erfcsum(
  floatnum x, /* should be the square of the parameter to erfc */
  int digits)
{
  int i, workprec;
  floatstruct sum, smd;
  floatnum Ei;

  if (digits > erfcdigits)
  {
    /* cannot re-use last evaluation's intermediate results */
    for (i = MAXERFCIDX; --i >= 0;)
      /* clear all exp(-k*k*alpha*alpha) to indicate their absence */
      float_free(&erfccoeff[i]);
    /* current precision */
    erfcdigits = digits;
    /* create new alpha appropriate for the desired precision
       This alpha need not be high precision, any alpha near the
       one evaluated here would do */
    float_muli(&erfcalpha, &cLn10, digits + 4, 3);
    float_sqrt(&erfcalpha, 3);
    float_div(&erfcalpha, &cPi, &erfcalpha, 3);
    float_mul(&erfcalphasqr, &erfcalpha, &erfcalpha, EXACT);
    /* the exp(-k*k*alpha*alpha) are later evaluated iteratively.
       Initiate the iteration here */
    float_copy(&erfct2, &erfcalphasqr, EXACT);
    float_neg(&erfct2);
    _exp(&erfct2, digits + 3); /* exp(-alpha*alpha) */
    float_copy(erfccoeff, &erfct2, EXACT); /* start value */
    float_mul(&erfct3, &erfct2, &erfct2, digits + 3); /* exp(-2*alpha*alpha) */
  }
  float_create(&sum);
  float_create(&smd);
  float_setzero(&sum);
  for (i = 0; ++i < MAXERFCIDX;)
  {
    Ei = &erfccoeff[i-1];
    if (float_isnan(Ei))
    {
      /* if exp(-i*i*alpha*alpha) is not available, evaluate it from
         the coefficient of the last summand */
      float_mul(&erfct2, &erfct2, &erfct3, workprec + 3);
      float_mul(Ei, &erfct2, &erfccoeff[i-2], workprec + 3);
    }
    /* Ei finally decays rapidly. save some time by adjusting the
       working precision */
    workprec = digits + float_getexponent(Ei) + 1;
    if (workprec <= 0)
      break;
    /* evaluate the summand exp(-i*i*alpha*alpha)/(i*i*alpha*alpha+x) */
    float_muli(&smd, &erfcalphasqr, i*i, workprec);
    float_add(&smd, x, &smd, workprec + 2);
    float_div(&smd, Ei, &smd, workprec + 1);
    /* add summand to the series */
    float_add(&sum, &sum, &smd, digits + 3);
  }
  float_move(x, &sum);
  float_free(&smd);
  return 1;
}