static inline real isotropicRandomR(dsfmt_t* dsfmtState, real scaleRad1, real scaleRad2,
				    real Mass1, real Mass2)
{
  // Rejection sampling radius generation
  real RHO_MAX = 3/(4*M_PI) * (Mass1/(mw_pow(scaleRad1,3)) + Mass2/(mw_pow(scaleRad2,3)));
  mwbool GOOD_RADIUS = 0;
  // Arbitrarily define sample range to be [0, 5(a1 + a2)

  real r;

  while (GOOD_RADIUS != 1)
    {
      r = mwXrandom(dsfmtState,0.0, 3*(scaleRad1 + scaleRad2));
      real u = (real)mwXrandom(dsfmtState,0.0,1.0);

      real val = 3/(4*M_PI)*(Mass1/(mw_pow(scaleRad1,3)) *mw_pow(1 + mw_pow(r,2)/mw_pow(scaleRad1,2),-5/2) + 
			     Mass2/(mw_pow(scaleRad2,3))*mw_pow(1 + mw_pow(r,2)/mw_pow(scaleRad2,2),-5/2));
      
      if (val/RHO_MAX > u)
      {
       	GOOD_RADIUS = 1;
      }
    }
  return r;
}
/* The estimate formula has the unfortunate property of being negative
   for small n.  This will be the most negative. Add this as an extra
   boost to prevent negative flops estimates.
 */
static real worstFlops(real cQ, real d, real f)
{
    real a = mw_pow(2.0, 3.0 - 3.0 * d / cQ);
    real b = (cQ - d) * mw_log(8.0);
    real c = cQ * mw_log(mw_pow(8.0, 1.0 - d / cQ));

    return -a * sqr(f) * (cQ + b - c) / (M_E * mw_log(8.0));
}
Exemplo n.º 3
0
real propability_match(int n, int k, real pobs){
    real result;
    result = choose(n, k);
    result *= mw_pow(pobs, (real)k);
    result *= mw_pow((1-pobs), (real)(n-k));
    result = mw_log(result);
    return result;
}
static inline real isotropicRandomV(real r, real scaleRad1, real scaleRad2,                                                                                                             				    real Mass1, real Mass2)  
{


  real val;
  val = mw_sqrt(Mass1/mw_sqrt(mw_pow(r,2) + mw_pow(scaleRad1,2)) 
		+ Mass2/mw_sqrt(mw_pow(r,2) + mw_pow(scaleRad2,2)));

  return val;
}
/* generatePlummer: generate Plummer model initial conditions for test
 * runs, scaled to units such that M = -4E = G = 1 (Henon, Heggie,
 * etc).  See Aarseth, SJ, Henon, M, & Wielen, R (1974) Astr & Ap, 37,
 * 183.
 */
static int nbGenerateIsotropicCore(lua_State* luaSt,

				   dsfmt_t* prng,
				   unsigned int nbody,
				   real mass1,
				   real mass2,

				   mwbool ignore,
				   
				   mwvector rShift,
				   mwvector vShift,
				   real radiusScale1,
				   real radiusScale2)
{
    unsigned int i;
    int table;
    Body b;
    real r, velScale;

    real mass = mass1 + mass2;
    real radiusScale = mw_sqrt(mw_pow(radiusScale1,2) + mw_pow(radiusScale2,2));
    memset(&b, 0, sizeof(b));

    velScale =  mw_sqrt(mass / radiusScale);     /* and recip. speed scale */

    b.bodynode.type = BODY(ignore);    /* Same for all in the model */
    b.bodynode.mass = mass / nbody;    /* Mass per particle */

    lua_createtable(luaSt, nbody, 0);
    table = lua_gettop(luaSt);
    
    for (i = 0; i < nbody; ++i)
    {
        do
        {
	  r = isotropicRandomR(prng, radiusScale1, radiusScale2, mass1, mass2);
	    /* FIXME: We should avoid the divide by 0.0 by multiplying
             * the original random number by 0.9999.. but I'm too lazy
             * to change the tests. Same with other models */
        }
        while (isinf(r));

        b.bodynode.pos = isotropicBodyPosition(prng, rShift, r);

        b.vel = isotropicBodyVelocity(prng, r, vShift, velScale, radiusScale1, radiusScale2, mass1, mass2);
	
        assert(nbPositionValid(b.bodynode.pos));

        pushBody(luaSt, &b);
	//	printf("Body %d is pushed. \n",i);
        lua_rawseti(luaSt, table, i + 1);
    }

    return 1;
}
/* For using a combination of light and dark models to generate timestep */
static real plummerTimestepIntegral(real smalla, real biga, real Md, real step)
{
    /* Calculate the enclosed mass of the big sphere within the little sphere's scale length */
    real encMass, val, r;

    encMass = 0.0;
    for (r = 0.0; r <= smalla; r += step)
    {
        val = sqr(r) / mw_pow(sqr(r) + sqr(biga), 2.5);
        encMass += val * step;
    }
    encMass *= 3.0 * Md * sqr(biga);

    return encMass;
}