Esempio n. 1
0
int
mpfi_div_d (mpfi_ptr a, mpfi_srcptr b, const double c)
{
  mpfr_t tmp;
  int inexact_left, inexact_right;
  int inexact = 0;

  if (MPFI_NAN_P (b))
    {
      mpfr_set_nan (&(a->left));
      mpfr_set_nan (&(a->right));
      MPFR_RET_NAN;
    }

  if (c == 0.0)
    {
      if (mpfr_zero_p (&(b->left)))
        mpfr_set_nan (&(a->left));
      else
        mpfr_set_inf (&(a->left), -1);
      inexact_left = 0;

      if (mpfr_zero_p (&(b->right)))
        mpfr_set_nan (&(a->right));
      else
        mpfr_set_inf (&(a->right), +1);
      inexact_right = 0;
    }
  else if (c < 0.0)
    {
      mpfr_init2 (tmp, mpfr_get_prec (&(a->left)));
      inexact_left = mpfr_div_d (tmp, &(b->right), c, MPFI_RNDD);
      inexact_right = mpfr_div_d (&(a->right), &(b->left), c, MPFI_RNDU);
      mpfr_set (&(a->left), tmp, MPFI_RNDD);    /* exact */
      mpfr_clear (tmp);
    }
  else                          /* c > 0.0 */
    {
      inexact_left = mpfr_div_d (&(a->left), &(b->left), c, MPFI_RNDD);
      inexact_right = mpfr_div_d (&(a->right), &(b->right), c, MPFI_RNDU);
    }

  if (MPFI_NAN_P (a))
    MPFR_RET_NAN;

  /* no need to check to sign of the bounds in case they are 0 */
  if (inexact_left)
    inexact += 1;
  if (inexact_right)
    inexact += 2;

  return inexact;
}
Esempio n. 2
0
        BOOST_FORCEINLINE
        mpfr & operator()(mpfr &res, mpfr const & rhs, double lhs) const
        {
            mpfr_div_d(res.data, rhs.data, lhs, MPFR_RNDN);

            return res;
        }
Esempio n. 3
0
SeedValue seed_mpfr_div (SeedContext ctx,
                         SeedObject function,
                         SeedObject this_object,
                         gsize argument_count,
                         const SeedValue args[],
                         SeedException * exception)
{
    mpfr_rnd_t rnd;
    mpfr_ptr rop, op1, op2;
    gdouble dop1, dop2;
    gint ret;
    seed_mpfr_t argt1, argt2;
    /* only want 1 double argument. alternatively, could accept 2,
       add those, and set from the result*/

    CHECK_ARG_COUNT("mpfr.div", 3);

    rop = seed_object_get_private(this_object);
    rnd = seed_value_to_mpfr_rnd_t(ctx, args[2], exception);

    argt1 = seed_mpfr_arg_type(ctx, args[0], exception);
    argt2 = seed_mpfr_arg_type(ctx, args[1], exception);

    if ( (argt1 & argt2) == SEED_MPFR_MPFR )
    {
        /* both mpfr_t */
        op1 = seed_object_get_private(args[0]);
        op2 = seed_object_get_private(args[1]);
        ret = mpfr_div(rop, op1, op2, rnd);
    }
    else if ( (argt1 | argt2) == (SEED_MPFR_MPFR | SEED_MPFR_DOUBLE) )
    {
        /* a double and an mpfr_t. Figure out the order */
        if ( argt1 == SEED_MPFR_MPFR )
        {
            op1 = seed_object_get_private(args[0]);
            dop2 = seed_value_to_double(ctx, args[1], exception);
            mpfr_div_d(rop, op1, dop2, rnd);
        }
        else
        {
            dop1 = seed_value_to_double(ctx, args[0], exception);
            op2 = seed_object_get_private(args[1]);
            mpfr_d_div(rop, dop1, op2, rnd);
        }
    }
    else if ( (argt1 & argt2) == SEED_MPFR_DOUBLE )
    {
        /* 2 doubles. hopefully doesn't happen */
        dop1 = seed_value_to_double(ctx, args[0], exception);
        dop2 = seed_value_to_double(ctx, args[1], exception);
        ret = mpfr_set_d(rop, dop1 / dop2, rnd);
    }
    else
    {
        TYPE_EXCEPTION("mpfr.div", "double or mpfr_t");
    }

    return seed_value_from_int(ctx, ret, exception);
}
Esempio n. 4
0
static void
check_nans (void)
{
  mpfr_t  x, y;
  int inexact;

  mpfr_init2 (x, 123);
  mpfr_init2 (y, 123);

  /* nan / 1.0 is nan */
  mpfr_set_nan (x);
  mpfr_clear_flags ();
  inexact = mpfr_div_d (y, x, 1.0, GMP_RNDN);
  MPFR_ASSERTN (inexact == 0);
  MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
  MPFR_ASSERTN (mpfr_nan_p (y));

  /* +inf / 1.0 == +inf */
  mpfr_set_inf (x, 1);
  mpfr_clear_flags ();
  inexact = mpfr_div_d (y, x, 1.0, GMP_RNDN);
  MPFR_ASSERTN (inexact == 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);
  MPFR_ASSERTN (mpfr_inf_p (y));
  MPFR_ASSERTN (MPFR_IS_POS (y));

  /* -inf / 1.0 == -inf */
  mpfr_set_inf (x, -1);
  mpfr_clear_flags ();
  inexact = mpfr_div_d (y, x, 1.0, GMP_RNDN);
  MPFR_ASSERTN (inexact == 0);
  MPFR_ASSERTN (__gmpfr_flags == 0);
  MPFR_ASSERTN (mpfr_inf_p (y));
  MPFR_ASSERTN (MPFR_IS_NEG (y));

  /* 0.0 / 0.0 is nan */
  mpfr_set_d (x, 0.0, GMP_RNDN);
  mpfr_clear_flags ();
  inexact = mpfr_div_d (y, x, 0.0, GMP_RNDN);
  MPFR_ASSERTN (inexact == 0);
  MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
  MPFR_ASSERTN (mpfr_nan_p (y));

  mpfr_clear (x);
  mpfr_clear (y);
}
Esempio n. 5
0
void coords_zoom(coords* c, double multiplier)
{
    mpfr_mul_d( c->_size,   c->_size,   multiplier, GMP_RNDN);
    mpfr_set(   *c->size,   c->_size,               GMP_RNDN);

    if (c->aspect > 1.0)
        mpfr_div_d(c->height,   c->width,   c->aspect,  GMP_RNDN);
    else
        mpfr_mul_d(c->width,   c->height,   c->aspect,  GMP_RNDN);

    coords_calculate_precision(c);
    coords_center_to_rect(c);
}
Esempio n. 6
0
void coords_center_to_rect(coords* c)
{
    mpfr_t tmp;
    mpfr_init2(tmp, c->precision);

    DMSG("updating from center to rect\n");

    if (c->aspect > 1.0)
    {
        DMSG("wide image");

        mpfr_div_d( c->height,  c->width,   c->aspect,  GMP_RNDN);

        mpfr_div_ui(tmp,        c->width,   2,          GMP_RNDN);
        mpfr_sub(   c->xmin,    c->cx,      tmp,        GMP_RNDN);
        mpfr_add(   c->xmax,    c->xmin,    c->width,   GMP_RNDN);

        mpfr_div_d( tmp,        tmp,        c->aspect,  GMP_RNDN);
        mpfr_sub(   c->ymin,    c->cy,      tmp,        GMP_RNDN);
        mpfr_add(   c->ymax,    c->ymin,    c->height,  GMP_RNDN);
    }
    else
    {
        DMSG("tall image");

        mpfr_mul_d( c->width,   c->height,  c->aspect,  GMP_RNDN);

        mpfr_div_ui(tmp,        c->height,  2,          GMP_RNDN);
        mpfr_sub(   c->ymin,    c->cy,      tmp,        GMP_RNDN);
        mpfr_add(   c->ymax,    c->ymin,    c->height,  GMP_RNDN);

        mpfr_mul_d( tmp,        tmp,        c->aspect,  GMP_RNDN);
        mpfr_sub(   c->xmin,    c->cx,      tmp,        GMP_RNDN);
        mpfr_add(   c->xmax,    c->xmin,    c->width,   GMP_RNDN);
    }

    mpfr_clear(tmp);
}
Esempio n. 7
0
int
main (void)
{
  mpfr_t x, y, z;
  double d;
  int inexact;

  tests_start_mpfr ();

  /* check with enough precision */
  mpfr_init2 (x, IEEE_DBL_MANT_DIG);
  mpfr_init2 (y, IEEE_DBL_MANT_DIG);
  mpfr_init2 (z, IEEE_DBL_MANT_DIG);

  mpfr_set_str (y, "4096", 10, MPFR_RNDN);
  d = 0.125;
  mpfr_clear_flags ();
  inexact = mpfr_div_d (x, y, d, MPFR_RNDN);
  if (inexact != 0)
    {
      printf ("Inexact flag error in mpfr_div_d\n");
      exit (1);
    }
  mpfr_set_str (z, "32768", 10, MPFR_RNDN);
  if (mpfr_cmp (z, x))
    {
      printf ("Error in mpfr_div_d (");
      mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN);
      printf (" + %.20g)\nexpected ", d);
      mpfr_out_str (stdout, 10, 0, z, MPFR_RNDN);
      printf ("\ngot     ");
      mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
      printf ("\n");
      exit (1);
    }
  mpfr_clears (x, y, z, (mpfr_ptr) 0);

  check_nans ();

  test_generic (2, 1000, 100);

  tests_end_mpfr ();
  return 0;
}
Esempio n. 8
0
void coords_rect_to_center(coords* c)
{
    DMSG("updating from rect to center\n");

    /* calc width, height */
    mpfr_sub(   c->width,   c->xmax,    c->xmin,        GMP_RNDN);
    mpfr_div_d( c->height,  c->width,   c->aspect,      GMP_RNDN);

    /* calc ymin */
    mpfr_sub(   c->ymin,    c->ymax,    c->height,      GMP_RNDN);

    /* calc center x */
    mpfr_add(   c->cx,      c->xmin,    c->xmax,        GMP_RNDN);
    mpfr_div_ui(c->cx,      c->cx,      2,              GMP_RNDN);

    /* calc center y */
    mpfr_add(   c->cy,      c->ymin,    c->ymax,        GMP_RNDN);
    mpfr_div_ui(c->cy,      c->cy,      2,              GMP_RNDN);
}
Esempio n. 9
0
static PyObject *
GMPy_Real_FloorDiv(PyObject *x, PyObject *y, CTXT_Object *context)
{
    MPFR_Object *result;

    CHECK_CONTEXT(context);

    if (!(result = GMPy_MPFR_New(0, context))) {
        /* LCOV_EXCL_START */
        return NULL;
        /* LCOV_EXCL_STOP */
    }

    if (MPFR_Check(x)) {
        if (MPFR_Check(y)) {
            mpfr_clear_flags();

            result->rc = mpfr_div(result->f, MPFR(x), MPFR(y), GET_MPFR_ROUND(context));
            result->rc = mpfr_floor(result->f, result->f);
            goto done;
        }

        if (PyIntOrLong_Check(y)) {
            int error;
            long tempi = GMPy_Integer_AsLongAndError(y, &error);

            if (!error) {
                mpfr_clear_flags();

                result->rc = mpfr_div_si(result->f, MPFR(x), tempi, GET_MPFR_ROUND(context));
                result->rc = mpfr_floor(result->f, result->f);
                goto done;
            }
            else {
                mpz_set_PyIntOrLong(global.tempz, y);
                mpfr_clear_flags();

                result->rc = mpfr_div_z(result->f, MPFR(x), global.tempz, GET_MPFR_ROUND(context));
                result->rc = mpfr_floor(result->f, result->f);
                goto done;
            }
        }

        if (CHECK_MPZANY(y)) {
            mpfr_clear_flags();

            result->rc = mpfr_div_z(result->f, MPFR(x), MPZ(y), GET_MPFR_ROUND(context));
            result->rc = mpfr_floor(result->f, result->f);
            goto done;
        }

        if (IS_RATIONAL(y)) {
            MPQ_Object *tempy;

            if (!(tempy = GMPy_MPQ_From_Number(y, context))) {
                Py_DECREF((PyObject*)result);
                return NULL;
            }
            mpfr_clear_flags();

            result->rc = mpfr_div_q(result->f, MPFR(x), tempy->q, GET_MPFR_ROUND(context));
            result->rc = mpfr_floor(result->f, result->f);
            Py_DECREF((PyObject*)tempy);
            goto done;
        }

        if (PyFloat_Check(y)) {
            mpfr_clear_flags();

            result->rc = mpfr_div_d(result->f, MPFR(x), PyFloat_AS_DOUBLE(y), GET_MPFR_ROUND(context));
            result->rc = mpfr_floor(result->f, result->f);
            goto done;
        }
    }

    if (MPFR_Check(y)) {
        if (PyIntOrLong_Check(x)) {
            int error;
            long tempi = GMPy_Integer_AsLongAndError(x, &error);
            if (!error) {
                mpfr_clear_flags();

                result->rc = mpfr_si_div(result->f, tempi, MPFR(y), GET_MPFR_ROUND(context));
                result->rc = mpfr_floor(result->f, result->f);
                goto done;
            }
        }

        /* Since mpfr_z_div does not exist, this combination is handled at the
         * end by converting x to an mpfr. Ditto for rational.*/

        if (PyFloat_Check(x)) {
            mpfr_clear_flags();

            result->rc = mpfr_d_div(result->f, PyFloat_AS_DOUBLE(x), MPFR(y), GET_MPFR_ROUND(context));
            result->rc = mpfr_floor(result->f, result->f);
            goto done;
        }
    }

    /* Handle the remaining cases.
     * Note: verify that MPZ if converted at full precision! */

    if (IS_REAL(x) && IS_REAL(y)) {
        MPFR_Object *tempx, *tempy;

        tempx = GMPy_MPFR_From_Real(x, 1, context);
        tempy = GMPy_MPFR_From_Real(y, 1, context);
        if (!tempx || !tempy) {
            Py_XDECREF((PyObject*)tempx);
            Py_XDECREF((PyObject*)tempy);
            Py_DECREF((PyObject*)result);
            return NULL;
        }
        mpfr_clear_flags();

        result->rc = mpfr_div(result->f, MPFR(tempx), MPFR(tempy), GET_MPFR_ROUND(context));
        result->rc = mpfr_floor(result->f, result->f);
        Py_DECREF((PyObject*)tempx);
        Py_DECREF((PyObject*)tempy);
        goto done;
    }

    Py_DECREF((PyObject*)result);
    Py_RETURN_NOTIMPLEMENTED;

  done:
    _GMPy_MPFR_Cleanup(&result, context);
    return (PyObject*)result;
}
Esempio n. 10
0
/* Function to calculate the entropy	                */
void eff_point(mpfr_t *ent, mpfr_t *ipdf, mpfr_t *jdist, mpfr_t *pp, mpfr_t *gamma_bcs, mpfr_t *p0, int conns, int phi, int mu, int gamma, double pin, double xi, double yi, double delta, mpfr_prec_t prec)
{
 unsigned int z,sx,sy,i;
 int ppdex=0,p0dex=0,thr;
 double po,cost;
 double *bpdf;
 bpdf=(double *) malloc((conns+1)*sizeof(double));
 binomialpdf(bpdf,conns,pin); //CONSIDER USING GSL version here?

 mpfr_t rp;
 mpfr_init2(rp,prec);
 mpfr_set_d(rp,0,MPFR_RNDN);
 mpfr_t nunity;
 mpfr_init2(nunity,prec);
 mpfr_set_d(nunity,-1,MPFR_RNDN);
 mpfr_t tbin;
 mpfr_init2(tbin,prec);
 mpfr_t t1;
 mpfr_init2(t1,prec);
 mpfr_t gate;
 mpfr_init2(gate,prec);
 mpfr_t qa;
 mpfr_init2(qa,prec);
 mpfr_t s0;
 mpfr_init2(s0,prec);
 mpfr_t jdist_tot;
 mpfr_init2(jdist_tot,prec);
 
 for(thr=phi;thr<=conns;thr++)
   po=po+*(bpdf+thr);
 cost=mu*(pin*xi+(1-pin))+delta*gamma*(po*yi+(1-po));

 for(sx=0;sx<=mu;sx++)
 {
   ppdex=sx;
   p0dex=sx;
        for(sy=1;sy<=gamma;sy++)
        {
           mpfr_set_d(qa,0,MPFR_RNDN);
           for(z=0;z<=gamma-sy;z++)
           {      
              mpfr_pow_ui(rp,nunity,(unsigned long int)z,MPFR_RNDN);
              mpfr_mul(rp,rp,*(gamma_bcs+(gamma-sy)*(gamma+1)+z),MPFR_RNDN);
       
                  if(mpfr_cmp_d(*(pp+ppdex),0)>0)
                  {
        
                   if(mpfr_cmp(*(p0+p0dex),*(pp+ppdex))>0)
                    mpfr_set_d(gate,1,MPFR_RNDN);
                   else
                   {
                     mpfr_sub(gate,*(pp+ppdex),*(p0+p0dex),MPFR_RNDN);
                     mpfr_div(gate,gate,*(pp+ppdex),MPFR_RNDN);
                   }
                   mpfr_pow_ui(t1,*(pp+ppdex),(unsigned long int)z+sy,MPFR_RNDN);
                   mpfr_mul(rp,rp,gate,MPFR_RNDN); 
                  }  
                  else
                    mpfr_set_d(t1,0,MPFR_RNDN);
        
                  mpfr_mul(rp,rp,t1,MPFR_RNDN);
                  mpfr_add(qa,qa,rp,MPFR_RNDN);
           }
          
           mpfr_add(qa,qa,*(p0+p0dex),MPFR_RNDN);
           mpfr_set_d(jdist_tot,0,MPFR_RNDN);
           for(i=0;i<=mu;i++)
           { 
             if(i!=sx)
               mpfr_add(jdist_tot, jdist_tot,*(jdist+i*(gamma+1)+sy),MPFR_RNDN);
           }
      
           mpfr_div(jdist_tot,jdist_tot,*(gamma_bcs+gamma*(gamma+1)+sy),MPFR_RNDN);
           mpfr_mul(qa,qa,*(ipdf+sx),MPFR_RNDN);
           mpfr_add(qa,qa,jdist_tot,MPFR_RNDN);
      
           if(mpfr_cmp_d(qa,0)>0)
           {
             mpfr_log2(qa,qa,MPFR_RNDN);
             mpfr_mul(qa,qa,*(jdist+sx*(gamma+1)+sy),MPFR_RNDN);
           }
           else
             mpfr_set_d(qa,0,MPFR_RNDN);
           mpfr_sub(*ent,*ent,qa,MPFR_RNDN);

         }
 }
 mpfr_set_d(jdist_tot,0,MPFR_RNDN);  
 for(i=0;i<=mu;i++) 
   mpfr_add(jdist_tot, jdist_tot,*(jdist+i*(gamma+1)),MPFR_RNDN);
 if(mpfr_cmp_d(jdist_tot,0)>0)  
 {
    mpfr_log2(s0,jdist_tot,MPFR_RNDN);  
    mpfr_mul(s0,jdist_tot,s0,MPFR_RNDN);  
    mpfr_sub(*ent,*ent,s0,MPFR_RNDN);  
    mpfr_div_d(*ent,*ent,cost,MPFR_RNDN);
 }  

 mpfr_clear(s0);
 mpfr_clear(rp);
 mpfr_clear(nunity);
 mpfr_clear(tbin);
 mpfr_clear(t1);
 free(bpdf);
 
}
Esempio n. 11
0
MpfrFloat MpfrFloat::operator/(double value) const
{
    MpfrFloat retval(kNoInitialization);
    mpfr_div_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN);
    return retval;
}
Esempio n. 12
0
MpfrFloat& MpfrFloat::operator/=(double value)
{
    copyIfShared();
    mpfr_div_d(mData->mFloat, mData->mFloat, value, GMP_RNDN);
    return *this;
}
Esempio n. 13
0
int
nth_new_moon( mpfr_t *result, int n_int ) {
    mpfr_t n, k, C, approx, E, solar_anomaly, lunar_anomaly, moon_argument, omega, extra, correction, additional;

#if(0)
PerlIO_printf(PerlIO_stderr(), "nth_new_moon = %d\n", n_int );
#endif
    if ( dt_astro_global_cache.cache_size > n_int ) {
        mpfr_t *cached = dt_astro_global_cache.cache[n_int];
        if (cached != NULL) {
#if(0)
            PerlIO_printf(PerlIO_stderr(), "Cache HIT for %d\n", n_int);
#endif
            mpfr_set( *result, *cached, GMP_RNDN );
            return 1;
        }
    }

    mpfr_init_set_ui( n, n_int, GMP_RNDN );

    /* k = n - 24724 */
    mpfr_init_set(k, n, GMP_RNDN);
    mpfr_sub_ui(k, k, 24724, GMP_RNDN );

    /* c = k / 1236.85 */
    mpfr_init_set(C, k, GMP_RNDN );
    mpfr_div_d(C, C, 1236.85, GMP_RNDN);

    {
        mpfr_t a, b, c, d, e;
        mpfr_init(approx);
        mpfr_init_set_d(a, 730125.59765, GMP_RNDN );
        mpfr_init_set_d(b, MEAN_SYNODIC_MONTH * 1236.85, GMP_RNDN );
        mpfr_init_set_d(c, 0.0001337, GMP_RNDN );
        mpfr_init_set_d(d, -0.000000150, GMP_RNDN );
        mpfr_init_set_d(e, 0.00000000073, GMP_RNDN );
        polynomial( &approx, &C, 5, &a, &b, &c, &d, &e );
        mpfr_clear(a);
        mpfr_clear(b);
        mpfr_clear(c);
        mpfr_clear(d);
        mpfr_clear(e);
#ifdef ANNOYING_DEBUG
#if (ANNOYING_DEBUG)
mpfr_fprintf(stderr,
    "approx = %.10RNf\n", approx);
#endif
#endif
    }

    {
        mpfr_t a, b, c;
        mpfr_init(E);
        mpfr_init_set_ui(a, 1, GMP_RNDN);
        mpfr_init_set_d(b, -0.002516, GMP_RNDN );
        mpfr_init_set_d(c, -0.0000074, GMP_RNDN );
        polynomial( &E, &C, 3, &a, &b, &c );
        mpfr_clear(a);
        mpfr_clear(b);
        mpfr_clear(c);
    }

    {
        mpfr_t a, b, c, d;
        mpfr_init(solar_anomaly);
        mpfr_init_set_d(a, 2.5534, GMP_RNDN);
        mpfr_init_set_d(b, 1236.85, GMP_RNDN);
        mpfr_mul_d(b, b, 29.10535669, GMP_RNDN);
        mpfr_init_set_d(c, -0.0000218, GMP_RNDN );
        mpfr_init_set_d(d, -0.00000011, GMP_RNDN );
        polynomial( &solar_anomaly, &C, 4, &a, &b, &c, &d);
        mpfr_clear(a);
        mpfr_clear(b);
        mpfr_clear(c);
        mpfr_clear(d);
    }

    {
        mpfr_t a, b, c, d, e;
        mpfr_init(lunar_anomaly);
        mpfr_init_set_d(a, 201.5643, GMP_RNDN);
        mpfr_init_set_d(b, 385.81693528 * 1236.85, GMP_RNDN);
        mpfr_init_set_d(c, 0.0107438, GMP_RNDN);
        mpfr_init_set_d(d, 0.00001239, GMP_RNDN);
        mpfr_init_set_d(e, -0.000000058, GMP_RNDN);
        polynomial( &lunar_anomaly, &C, 5, &a, &b, &c, &d, &e);
        mpfr_clear(a);
        mpfr_clear(b);
        mpfr_clear(c);
        mpfr_clear(d);
        mpfr_clear(e);
    }

    {
        mpfr_t a, b, c, d, e;
        mpfr_init(moon_argument);
        mpfr_init_set_d(a, 160.7108, GMP_RNDN);
        mpfr_init_set_d(b, 390.67050274 * 1236.85, GMP_RNDN);
        mpfr_init_set_d(c, -0.0016431, GMP_RNDN);
        mpfr_init_set_d(d, -0.00000227, GMP_RNDN);
        mpfr_init_set_d(e, 0.000000011, GMP_RNDN);
        polynomial( &moon_argument, &C, 5, &a, &b, &c, &d, &e);
        mpfr_clear(a);
        mpfr_clear(b);
        mpfr_clear(c);
        mpfr_clear(d);
        mpfr_clear(e);
    }

    {
        mpfr_t a, b, c, d;
        mpfr_init(omega);
        mpfr_init_set_d(a, 124.7746, GMP_RNDN);
        mpfr_init_set_d(b, -1.56375580 * 1236.85, GMP_RNDN);
        mpfr_init_set_d(c, 0.0020691, GMP_RNDN);
        mpfr_init_set_d(d, 0.00000215, GMP_RNDN);
        polynomial( &omega, &C, 4, &a, &b, &c, &d);
        mpfr_clear(a);
        mpfr_clear(b);
        mpfr_clear(c);
        mpfr_clear(d);
    }

    {
        mpfr_t a, b, c;
        mpfr_init(extra);
        mpfr_init_set_d(a, 299.77, GMP_RNDN);
        mpfr_init_set_d(b, 132.8475848, GMP_RNDN);
        mpfr_init_set_d(c, -0.009173, GMP_RNDN);
        polynomial(&extra, &c, 3, &a, &b, &c);
        dt_astro_sin(&extra, &extra);
        mpfr_mul_d(extra, extra, 0.000325, GMP_RNDN);
        mpfr_clear(a);
        mpfr_clear(b);
        mpfr_clear(c);
    }

    mpfr_init(correction);
    dt_astro_sin(&correction, &omega);
    mpfr_mul_d(correction, correction, -0.00017, GMP_RNDN);

    {
        int i;
        for( i = 0; i < NTH_NEW_MOON_CORRECTION_ARGS_SIZE; i++ ) {
            mpfr_t a, v, w, x, y, z;
            mpfr_init_set_d(v, NTH_NEW_MOON_CORRECTION_ARGS[i][0], GMP_RNDN);
            mpfr_init_set_d(w, NTH_NEW_MOON_CORRECTION_ARGS[i][1], GMP_RNDN);
            mpfr_init_set_d(x, NTH_NEW_MOON_CORRECTION_ARGS[i][2], GMP_RNDN);
            mpfr_init_set_d(y, NTH_NEW_MOON_CORRECTION_ARGS[i][3], GMP_RNDN);
            mpfr_init_set_d(z, NTH_NEW_MOON_CORRECTION_ARGS[i][4], GMP_RNDN);

            mpfr_mul(x, x, solar_anomaly, GMP_RNDN);
            mpfr_mul(y, y, lunar_anomaly, GMP_RNDN);
            mpfr_mul(z, z, moon_argument, GMP_RNDN);

            mpfr_add(x, x, y, GMP_RNDN);
            mpfr_add(x, x, z, GMP_RNDN);
            dt_astro_sin(&x, &x);

            mpfr_init(a);
            mpfr_pow(a, E, w, GMP_RNDN);

            mpfr_mul(a, a, v, GMP_RNDN);
            mpfr_mul(a, a, x, GMP_RNDN);
            mpfr_add( correction, correction, a, GMP_RNDN );

            mpfr_clear(a);
            mpfr_clear(v);
            mpfr_clear(w);
            mpfr_clear(x);
            mpfr_clear(y);
            mpfr_clear(z);
        }
    }

    {
        int z;
        mpfr_init_set_ui(additional, 0, GMP_RNDN);
        for (z = 0; z < NTH_NEW_MOON_ADDITIONAL_ARGS_SIZE; z++) {
            mpfr_t i, j, l;
            mpfr_init_set_d(i, NTH_NEW_MOON_ADDITIONAL_ARGS[z][0], GMP_RNDN);
            mpfr_init_set_d(j, NTH_NEW_MOON_ADDITIONAL_ARGS[z][1], GMP_RNDN);
            mpfr_init_set_d(l, NTH_NEW_MOON_ADDITIONAL_ARGS[z][2], GMP_RNDN);

            mpfr_mul(j, j, k, GMP_RNDN);
            mpfr_add(j, j, i, GMP_RNDN);
            dt_astro_sin(&j, &j);
            mpfr_mul(l, l, j, GMP_RNDN);

            mpfr_add(additional, additional, l, GMP_RNDN);

            mpfr_clear(i);
            mpfr_clear(j);
            mpfr_clear(l);
        }
    }

#ifdef ANNOYING_DEBUG
#if (ANNOYING_DEBUG)
mpfr_fprintf(stderr,
    "correction = %.10RNf\nextra = %.10RNf\nadditional = %.10RNf\n", correction, extra, additional );
#endif
#endif
    mpfr_set(*result, approx, GMP_RNDN);
    mpfr_add(*result, *result, correction, GMP_RNDN);
    mpfr_add(*result, *result, extra, GMP_RNDN);
    mpfr_add(*result, *result, additional, GMP_RNDN);

    adjust_lunar_phase_to_zero( result );

    mpfr_clear(n);
    mpfr_clear(k);
    mpfr_clear(C);
    mpfr_clear(approx);
    mpfr_clear(E);
    mpfr_clear(solar_anomaly);
    mpfr_clear(lunar_anomaly);
    mpfr_clear(moon_argument);
    mpfr_clear(omega);
    mpfr_clear(extra);
    mpfr_clear(correction);
    mpfr_clear(additional);


    if (dt_astro_global_cache.cache_size == 0) {
        dt_astro_global_cache.cache_size = 200000;
        Newxz( dt_astro_global_cache.cache, dt_astro_global_cache.cache_size, mpfr_t * );
    }
Esempio n. 14
0
static inline void
adjust_lunar_phase_to_zero(mpfr_t *result) {
    mpfr_t ll, delta;
    int mode = -1;
    int loop = 1;
    int count = 0;
    /* Adjust values so that it's as close as possible to 0 degrees.
     * if we have a delta of 1 degree, then we're about
     *  1 / ( 360 / MEAN_SYNODIC_MONTH )
     * days apart
     */

    mpfr_init(ll);
    mpfr_init_set_d(delta, 0.0001, GMP_RNDN);

    while (loop) {
        int flipped = mode;
        mpfr_t new_moment;
        count++;
        mpfr_init(new_moment);
        lunar_phase(&ll, result);
#if (TRACE)
mpfr_fprintf(stderr,
    "Adjusting ll from (%.30RNf) moment is %.5RNf delta is %.30RNf\n", ll, *result, delta);
#endif
        /* longitude was greater than 180, so we're looking to add a few
         * degrees to make it close to 360 ( 0 )
         */
        if (mpfr_cmp_ui( ll, 180 ) > 0) {
            mode = 1;
            mpfr_sub_ui(delta, ll, 360, GMP_RNDN);
            mpfr_div_d(delta, delta, 360 / MEAN_SYNODIC_MONTH, GMP_RNDN);
            mpfr_add( new_moment, *result, delta, GMP_RNDN );
#if (TRACE)
mpfr_fprintf(stderr, "add %.30RNf -> %.30RNf\n", *result, new_moment);
#endif
            mpfr_set(*result, new_moment, GMP_RNDN);
            if (mpfr_cmp(new_moment, *result) == 0) {
                loop = 0;
            }
        } else if (mpfr_cmp_ui( ll, 180 ) < 0 ) {
            if ( mpfr_cmp_d( ll, 0.000000000000000000001 ) < 0) {
                loop = 0;
            } else {
                mode = 0;
                mpfr_sub_ui(delta, ll, 0, GMP_RNDN);
                mpfr_div_d(delta, delta, 360 / MEAN_SYNODIC_MONTH, GMP_RNDN);
                mpfr_sub( new_moment, *result, delta, GMP_RNDN );
#if (TRACE)
mpfr_fprintf(stderr, "sub %.120RNf -> %.120RNf\n", *result, new_moment);
#endif
                if (mpfr_cmp(new_moment, *result) == 0) {
                    loop = 0;
                }
                mpfr_set(*result, new_moment, GMP_RNDN);
            }
        } else {
            loop = 0;
        }
        if (flipped != -1 && flipped != mode) {
            mpfr_div_d(delta, delta, 1.1, GMP_RNDN);
        }
        mpfr_clear(new_moment);
    }
    mpfr_clear(delta);
    mpfr_clear(ll);
}