real pickdist(real eta, real sigma) { static real eta0 = -1.0, sigcorr; int niter; real x, y, q; if (eta != eta0) { sigcorr = rsqrt(8 * eta / (bessel_K(0.75, 1/(32*eta)) / bessel_K(0.25, 1/(32*eta)) - 1)); eprintf("[%s: sigma correction factor = %f]\n", getargv0(), sigcorr); eta0 = eta; } niter = 0; do { x = xrandom(-1.0, 1.0); y = xrandom(0.0, YMAX); q = rexp(- 0.5 * rsqr(fmap(x)) - eta * rsqr(rsqr(fmap(x)))) * (1 + x*x) / rsqr(1 - x*x); if (q > YMAX) /* should not ever happen */ error("%s: guess out of bounds\n x = %f q = %f > %f\n", getargv0(), x, q, YMAX); niter++; if (niter > 1000) error("%s: 1000 iterations without success\n", getargv0()); } while (y > q || x*x == 1); /* 2nd test prevents infty */ return (sigcorr * sigma * fmap(x)); }
real vnpick(real (*fun)(real), real xmin, real xmax, real fmax, string name) { int ncyc; bool warn; real fr, fx, x; ncyc = 0; warn = FALSE; fr = 1.0; fx = 0.0; while (fr > fx) { x = xrandom(xmin, xmax); fx = (*fun)(x); fr = xrandom(0.0, 1.1 * fmax); if (fx > 1.01 * fmax && ! warn) { eprintf("[%s.vnpick: %s(%g) = %g > %s_max = %g]\n", getprog(), name, x, fx, name, fmax); warn = TRUE; } if (fx > 1.1 * fmax) error("%s.vnpick: %s(x) out of bounds\n", getprog(), name); ncyc++; if (ncyc % NCYC == 0) eprintf("[%s.vnpick: %d cycles picking %s(x)]\n",getprog(), ncyc, name); } return (x); }
/* Read data. */ static int random_pread (void *handle, void *buf, uint32_t count, uint64_t offset, uint32_t flags) { uint32_t i; unsigned char *b = buf; uint64_t s; for (i = 0; i < count; ++i) { /* We use nbdkit common/include/random.h to make random numbers. * * However we're not quite using it in the ordinary way. In order * to be able to read any byte of data without needing to run the * PRNG from the start, the random data is computed from the index * and seed through three rounds of PRNG: * * index i PRNG(seed+i) -> PRNG -> PRNG -> mod 256 -> b[i] * index i+1 PRNG(seed+i+1) -> PRNG -> PRNG -> mod 256 -> b[i+1] * etc */ struct random_state state; xsrandom (seed + offset + i, &state); xrandom (&state); xrandom (&state); s = xrandom (&state); s &= 255; b[i] = s; } return 0; }
local void testdata(void) { real rsc, vsc, r, v, x, y; bodyptr p; float scale = 1.0f; float vscale = 1.0f; float mscale = 1.0f; if (nbody < 1) // check for silly values error("%s: absurd value for nbody\n", getargv0()); bodytab = (bodyptr) allocate(nbody * sizeof(body)); // alloc space for bodies rsc = (3 * PI) / 16; // set length scale factor vsc = rsqrt(1.0 / rsc); // find speed scale factor for (p = bodytab; p < bodytab+nbody; p++) { // loop over particles Type(p) = BODY; // tag as a body //Mass(p) = 1.0 / nbody; // set masses equal // Set mass randomly, like in brute Mass(p) = (rand() / (float) RAND_MAX) * mscale; x = xrandom(0.0, MFRAC); // pick enclosed mass r = 1.0 / rsqrt(rpow(x, -2.0/3.0) - 1); // find enclosing radius pickshell(Pos(p), NDIM, rsc * r); // pick position vector do { // select from fn g(x) x = xrandom(0.0, 1.0); // for x in range 0:1 y = xrandom(0.0, 0.1); // max of g(x) is 0.092 } while (y > x*x * rpow(1 - x*x, 3.5)); // using von Neumann tech v = x * rsqrt(2.0 / rsqrt(1 + r*r)); // find resulting speed pickshell(Vel(p), NDIM, vsc * v); // pick velocity vector } tnow = 0.0; // set elapsed model time }
nemo_main() { int n=getiparam("n"); int iter=getiparam("iter"); int m=getiparam("m"); int seed = init_xrandom(getparam("seed")); int i,j,k,l; real *x, sum; real t0,t1,t2; init_timers(100); stamp_timers(0); x = (real *) allocate(n*sizeof(real)); for (i=0; i<n; i++) /* init the whole array */ x[i] = xrandom(0.0,1.0); for (i=0; i<m; i++) /* cache it in again ? */ x[i] = xrandom(0.0,1.0); sum = 0.0; t0 = cputime(); stamp_timers(1); if (m==0) { /* do it in one sweep, the N^2 algorithm */ stamp_timers(2); for (l=0; l<iter; l++) for (j=0; j<n; j++) for (i=0; i<n; i++) sum += FUN(x[i],x[j]); stamp_timers(3); } else { /* N/M times a small M*M patch that may be in cache */ stamp_timers(2); for (l=0; l<iter; l++) for (k=0; k<n-m; k++) for (j=k; j<k+m; j++) for (i=k; i<k+m; i++) sum += FUN(x[i],x[j]); stamp_timers(3); } stamp_timers(4); t1 = cputime(); if (m) printf("%d %d %d sum=%lg Mops=%lg\n", n,iter,m,sum,iter*m*m*n/(t1-t0)/60.0/1e6); else printf("%d %d %d sum=%lg Mops=%lg\n", n,iter,m,sum,iter*n*n/(t1-t0)/60.0/1e6); stamp_timers(5); printf("%Ld %Ld %Ld %Ld %Ld\n", diff_timers(0,1), diff_timers(1,2), diff_timers(2,3), diff_timers(3,4), diff_timers(4,5)); }
/* The "+=" operator combines two samples. If you have two empty samples "a" and "b", then call push() several times on each, then say "a += b", then that is equivalent to having push()ed all the values into "a" originally. */ reservoir_sample_t &operator+=(const reservoir_sample_t &s) { /* If each element of the incoming sample literally represents one object, then we can just use push(). */ if (s.n < goal) { for (int i = 0; i < s.n; i++) push(s.samples[i]); /* If each element of us just represents one object, we reduce it to the above case by switching the operands. */ } else if (n < goal) { reservoir_sample_t temp(*this); *this = s; *this += temp; /* Both samples are full, so we "zipper" them, choosing randomly between the two samples at each point with the appropriate probability. */ } else { assert(n >= goal && s.n >= goal); for (int i = 0; i < goal; i++) { if (xrandom(0, n + s.n - 1) < s.n) { samples[i] = s.samples[i]; } } n += s.n; } }
void polymodel(void) { gsl_interp_accel *pmsplacc = gsl_interp_accel_alloc(); bodyptr p; real rad, phi, vel, psi, vr, vp, a, E, J; vector rhat, vtmp, vper; for (p = btab; p < NthBody(btab, nbody); p = NextBody(p)) { rad = rad_m(xrandom(0.0, mtot)); phi = gsl_spline_eval(pmspline, (double) rad, pmsplacc); vel = pick_v(phi); psi = pick_psi(); vr = vel * rcos(psi); vp = vel * rsin(psi); Mass(p) = mtot / nbody; pickshell(rhat, NDIM, 1.0); MULVS(Pos(p), rhat, rad); pickshell(vtmp, NDIM, 1.0); a = dotvp(vtmp, rhat); MULVS(vper, rhat, - a); ADDV(vper, vper, vtmp); a = absv(vper); MULVS(vper, vper, vp / a); MULVS(Vel(p), rhat, vr); ADDV(Vel(p), Vel(p), vper); Phi(p) = phi; E = phi + 0.5 * rsqr(vel); J = rad * ABS(vp); Aux(p) = Kprime * rpow(phi1 - E, npol - 1.5) * rpow(J, 2 * mpol); } gsl_interp_accel_free(pmsplacc); }
void gspsphere(void) { real gamma0, mcut, r, sig2, eint = 0.0; static real *sig2tab = NULL; bodyptr bp; nbody = getiparam("nbody"); assert(nbody > 0); gamma0 = getdparam("gamma"); mcut = getdparam("mcut"); assert(0.0 < mcut && mcut <= 1.0); if (sig2tab == NULL) sig2tab = calc_sig2_gsp(gsp, ggsp, 0.0); if (btab == NULL) btab = (bodyptr) allocate(nbody * SizeofBody); for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) { Mass(bp) = gsp->mtot / nbody; r = r_mass_gsp(gsp, xrandom(0.0, mcut * gsp->mtot)); pickshell(Pos(bp), NDIM, r); CLRV(Vel(bp)); Rho(bp) = rho_gsp(gsp, r); sig2 = sig2_gsp(gsp, ggsp, 0.0, sig2tab, r); EntFunc(bp) = sig2 / rpow(Rho(bp), gamma0 - 1); Uintern(bp) = sig2 / (gamma0 - 1); eint += Mass(bp) * Uintern(bp); } eprintf("[%s: thermal energy = %f]\n", getargv0(), eint); }
void makedisk(bool randspin) { int i; bodyptr bp; double m, r, v, phi; matrix xmat, zmat; vector tmpv; for (i = 0; i < ndisk; i++) { // loop initializing bodies bp = NthBody(disk, i); // set ptr to body number i m = mdtab[NTAB-1] * ((double) i + 0.5) / ndisk; r = gsl_interp_eval(rm_spline, mdtab, rdtab, m, NULL); v = gsl_interp_eval(vr_spline, rdtab, vctab, r, NULL); phi = xrandom(0.0, 2 * M_PI); Pos(bp)[0] = r * sin(phi); Pos(bp)[1] = r * cos(phi); Pos(bp)[2] = 0.0; Vel(bp)[0] = v * cos(phi); Vel(bp)[1] = - v * sin(phi); Vel(bp)[2] = 0.0; pickshell(AuxVec(bp), NDIM, 1.0); if (randspin) { xmatrix(xmat, acos(AuxVec(bp)[2])); zmatrix(zmat, atan2(AuxVec(bp)[0], AuxVec(bp)[1])); MULMV(tmpv, xmat, Pos(bp)); MULMV(Pos(bp), zmat, tmpv); MULMV(tmpv, xmat, Vel(bp)); MULMV(Vel(bp), zmat, tmpv); } } }
void polymodel1(void) { bodyptr p; real r, x, v; for (p = btab; p < NthBody(btab, nbody); p = NextBody(p)) { Mass(p) = 1.0 / nbody; r = xrandom(0.0, 2.0); pickshell(Pos(p), 3, r); x = SQRT2 * rcos(PI * (2.0 - xrandom(0.0, 1.0)) / 4.0); v = (xrandom(-1.0, 1.0) < 0.0 ? -1.0 : 1.0) * (1 - x*x) * rsqrt(rlog(2 / r)); MULVS(Vel(p), Pos(p), v/r); Phi(p) = 0.5 * rlog(r / 2.0) - 0.5; } bodyfields[4] = NULL; // don't output Aux data }
void makedisk(void) { real m, r, phi, vcir, omega, Adisk, kappa, sigma1, sigma2, mu_eff, sig_r, sig_p, sig_z, vrad, vorb2, vorb, vphi; double Trr = 0.0, Tpp = 0.0, Tzz = 0.0; int i; bodyptr dp; for (i = 0; i < ndisk; i++) { /* loop initializing bodies */ m = mdtab[NTAB-1] * ((real) i + 0.5) / ndisk; r = seval(m, &mdtab[0], &rdtab[0], &rdtab[NTAB], NTAB); vcir = seval(r, &rdtab[0], &vctab[0], &vctab[NTAB], NTAB); omega = vcir / r; Adisk = (omega - spldif(r, &rdtab[0], &vctab[0], &vctab[NTAB], NTAB)) / 2; if (omega - Adisk < 0.0) error("%s: kappa undefined (omega - Adisk < 0)\n" " r, omega, Adisk = %f %f %f\n", getargv0(), r, omega, Adisk); kappa = 2 * rsqrt(rsqr(omega) - Adisk * omega); sigma1 = rsqr(alpha1) * mdisk1 * rexp(- alpha1 * r) / TWO_PI; sigma2 = rsqr(alpha2) * mdisk2 * rexp(- alpha2 * r) / TWO_PI; mu_eff = (r_mu>0 ? 1 + (mu - 1) * (r / (r + r_mu)) : mu); sig_z = rsqrt(PI * (sigma1 + sigma2) * zdisk); sig_r = mu_eff * sig_z; sig_p = (0.5 * kappa / omega) * sig_r; vorb2 = rsqr(vcir) + rsqr(sig_r) * (1 - 2 * alpha1 * r) - rsqr(sig_p) + (r_mu>0 ? rsqr(sig_z) * r * mu_eff*(2*mu-2)*r_mu/rsqr(r+r_mu) : 0); vorb = rsqrt(MAX(vorb2, 0.0)); dp = NthBody(disk, i); /* set up ptr to disk body */ Mass(dp) = mdisk1 / ndisk; phi = xrandom(0.0, TWO_PI); Pos(dp)[0] = r * rsin(phi); Pos(dp)[1] = r * rcos(phi); Pos(dp)[2] = zdisk * ratanh(xrandom(-1.0, 1.0)); vrad = (eta > 0 ? pickdist(eta, sig_r) : grandom(0.0, sig_r)); vphi = (eta > 0 ? pickdist(eta, sig_p) : grandom(0.0, sig_p)) + vorb; Vel(dp)[0] = vrad * rsin(phi) + vphi * rcos(phi); Vel(dp)[1] = vrad * rcos(phi) - vphi * rsin(phi); Vel(dp)[2] = grandom(0.0, sig_z); Trr += Mass(dp) * rsqr(sig_r) / 2; Tpp += Mass(dp) * (rsqr(vorb) + rsqr(sig_p)) / 2; Tzz += Mass(dp) * rsqr(sig_z) / 2; } eprintf("[%s: Trr = %f Tpp = %f Tzz = %f]\n", getargv0(), Trr, Tpp, Tzz); }
void pickvec(vector x, bool cf) { dprintf(1,"pickvec: cf = %d\t", cf); if (cf) /* cent. concentrated? */ pickshell(x, NDIM, xrandom(0.0, 1.0)); /* pick from M(r) = r */ else pickball(x, NDIM, 1.0); /* use uniform distr. */ dprintf(1,"x = [%8.4f,%8.4f,%8.4f]\n", x[0], x[1], x[2]); }
int choose_seeds(seed_t *seeds, int nseeds) { nseeds = std::min(nseeds, parent->size); /* Choose consecutive seeds to avoid duplicates. */ int start = xrandom(rnd, 0, parent->size - 1); for (int i = 0; i < nseeds; i++) { seeds[i] = start++; if (start == parent->size) start = 0; } return nseeds; }
testdisk(int n) { Body *dp; real rmin2, rmax2, r_i, theta_i, mass_i, rring; real cost, sint; int i, ndim=NDIM; double pos_d[NDIM], vel_d[NDIM], pot_d, time_d = 0.0; double tani = tan(pitch*PI/180.0); if (disk == NULL) disk = (Body *) allocate(ndisk * sizeof(Body)); rmin2 = rmin * rmin; rmax2 = rmax * rmax; rring = 0.5*(rmin+rmax); mass_i = 1.0 / (real)ndisk; for (dp=disk, i = 0; i < ndisk; dp++, i++) { Mass(dp) = mass_i; if (Qkey) Key(dp) = key; r_i = sqrt(rmin2 + xrandom(0.0,1.0) * (rmax2 - rmin2)); if (Qtest) theta_i = 0.0; else if (Quniform) theta_i = xrandom(0.0,TWO_PI); else theta_i = frandom(0.0,360.0,density) * PI / 180.0; theta_i += offset; if (Qlinear) { theta_i -= SPk * (r_i-rref) * TWO_PI; /* linear spiral arm */ } else { theta_i -= log(r_i/rref)/tani; /* logaarithmic spiral arm */ } cost = cos(theta_i); sint = sin(theta_i); Phase(dp)[0][0] = pos_d[0] = r_i * cost; /* set positions */ Phase(dp)[0][1] = pos_d[1] = r_i * sint; Phase(dp)[0][2] = pos_d[2] = 0.0; (*potential)(&ndim,pos_d,vel_d,&pot_d,&time_d); /* get flow */ Phase(dp)[1][0] = vel_d[0] * jz_sign; Phase(dp)[1][1] = vel_d[1] * jz_sign; Phase(dp)[1][2] = 0.0; } }
real pick_psi(void) { static real hmax = -1.0; real x, psi; if (hmax < 0.0) hmax = (mpol > 0 ? rpow(2.0, mpol) : 1); x = vnpick(hfunc, 0.0, 1.0, hmax, "hfunc"); psi = racos(1 - rpow(x, 1 / (mpol + 1))); return (xrandom(-1.0, 1.0) < 0.0 ? PI - psi : psi); }
char *make_nonce() { char *nonce = malloc(NONCE_SIZE); int rnd; memset(nonce, 0, NONCE_SIZE); rnd = xrandom(); pthread_mutex_lock(&rng_lock); random_r(&rng_state, &rnd); pthread_mutex_unlock(&rng_lock); snprintf((char *) nonce, NONCE_SIZE - 1, "%d", rnd); return nonce; }
void gspmodel(void) { real beta_a, mcut, vcut, vfac; static real *sig2 = NULL; real r, vmax2, sigr, sig, x, y, vr, v1, v2; bodyptr bp; vector rhat, vec1, vec2, vtmp; beta_a = getdparam("beta_a"); assert(beta_a <= 1.0); nbody = getiparam("nbody"); assert(nbody > 0); mcut = getdparam("mcut"); assert(0.0 < mcut && mcut <= 1.0); vcut = getdparam("vcut"); assert(vcut > 0.0); if (sig2 == NULL) sig2 = calc_sig2_gsp(gsp, ggsp, beta_a); if (btab == NULL) btab = (bodyptr) allocate(nbody * SizeofBody); vfac = rsqrt(1 - beta_a); for (bp = btab; bp < NthBody(btab, nbody); bp = NextBody(bp)) { Mass(bp) = gsp->mtot / nbody; r = r_mass_gsp(gsp, xrandom(0.0, mcut * gsp->mtot)); vmax2 = -2 * rsqr(vcut) * phi_gsp(ggsp, r); if (vfac > 1.0) vmax2 = vmax2 / rsqr(vfac); sigr = rsqrt(sig2_gsp(gsp, ggsp, beta_a, sig2, r)); sig = fixsigma(sigr, rsqrt(vmax2)); do { vr = grandom(0.0, sig); v1 = grandom(0.0, sig); v2 = grandom(0.0, sig); } while (vr*vr + v1*v1 + v2*v2 > vmax2); picktriad(rhat, vec1, vec2); MULVS(Pos(bp), rhat, r); MULVS(Vel(bp), rhat, vr); MULVS(vtmp, vec1, v1 * vfac); ADDV(Vel(bp), Vel(bp), vtmp); MULVS(vtmp, vec2, v2 * vfac); ADDV(Vel(bp), Vel(bp), vtmp); Phi(bp) = phi_gsp(ggsp, r); Aux(bp) = Phi(bp) + 0.5 * dotvp(Vel(bp), Vel(bp)); } if (getbparam("besort")) qsort(btab, nbody, SizeofBody, berank); if (getbparam("zerocm")) snapcenter(btab, nbody, MassField.offset); if (! strnull(getparam("auxvar"))) setauxvar(btab, nbody); }
int main () { std::srand (static_cast<unsigned>(std::time (0) ^ getpid ())); Cache<int, int> int_cache (10000); for (size_t i = 0; i != int_cache.get_capacity (); ++i) { int_cache.insert (xrandom (1000000), xrandom (1000000)); } Cache<int, int> const & cache_ref = int_cache; for (size_t i = 0; i != cache_ref.get_capacity () * 100; ++i) { cache_ref.get (xrandom (1000000), &value); } std::cout << "last value: " << value << std::endl; std::pair<unsigned long, unsigned long> stats = cache_ref.get_stats (); std::cout << "hits: " << stats.first << " / misses: " << stats.second << std::endl; }
/* push() puts a new object into the sample. */ void push(sample_t s) { /* We have room to store the object directly */ if (n < goal) { samples[n] = s; /* We don't have room; we may have to kick something out */ } else { int slot = xrandom(0, n); if (slot < goal) samples[slot] = s; } n++; }
Z32 roll_dice2(DiceRep dice) { Z16u die = 0, i = 0; Z16 numdice = 0, offset = 0; Z32 rslt = 0; dice2(dice, numdice, die, offset); if (!numdice) return offset; rslt = offset; for (i = 0; i < numdice; ++i) rslt += (1 + xrandom(die)); return rslt; }
void plummodel(real mfrac) { real rsc, vsc, r, v, x, y; bodyptr p; if (mfrac < 0 || mfrac > 1) // check for silly values error("%s: absurd value for mfrac\n", getprog()); rsc = (3 * PI) / 16; // set length scale factor vsc = rsqrt(1.0 / rsc); // and speed scale factor for (p = btab; p < NthBody(btab,nbody); p = NextBody(p)) { // loop over particles Mass(p) = 1.0 / nbody; // set masses equal x = xrandom(0.0, mfrac); // pick enclosed mass r = 1.0 / rsqrt(rpow(x, -2.0/3.0) - 1); // find enclosing radius pickshell(Pos(p), NDIM, rsc * r); // pick position vector do { // use von Neumann rejection x = xrandom(0.0, 1.0); // for x in range 0:1 y = xrandom(0.0, 0.1); // max of g(x) is 0.092 } while (y > x*x * rpow(1 - x*x, 3.5)); // select from g(x) v = x * rsqrt(2.0 / rsqrt(1 + r*r)); // find resulting speed pickshell(Vel(p), NDIM, vsc * v); // pick velocity vector Phi(p) = -1.0 / (rsc * rsqrt(rsqr(r) + 1)); // compute model potential } }
int bestx(int b, int loops){ int bestx = 0, bestxt = 0; int x, xt, i, j; for(x=0; x<256; x++){ xt = 0; for(i=0; i<loops; i++){ for(j=0; j<16; j++){ in[j] = xrandom() >> 16; } in[b] = x; xt += aescycles(); xt += aescycles(); xt += aescycles(); xt += aescycles(); xt += aescycles(); } if(xt>bestxt){ bestx = x, bestxt = xt; } } return bestx; }
void bernstein(char *seed){ int loops, b, j, k; mrandom(strlen(seed), seed); for(loops=4; loops<=65536; loops*=16){ for(b=0; b<16; b++){ printf("%.2d, %.5d loops:", b, loops); for(k=0; k<10; k++){ for(j=0; j<16; j++){ key[j] = xrandom() >> 16; } ExpandKey(key, expkey); printf(" %.2x", bestx(b, loops) ^ key[b]); fflush(stdout); } printf("\n"); } } }
/* * mrandom: * * Initialize the random number generator based on the given seed. * */ void mrandom(int len, char *ptr){ unsigned short rand = *ptr; int idx, bit = len * 4; memset(RandTbl, 0, sizeof(RandTbl)); RandHead = 0; while(rand *= 20077, rand += 11, bit--){ if(ptr[bit>>2] & (1<<(bit & 3))){ for(idx = 0; idx<5; idx++){ rand *= 20077, rand += 11; RandTbl[rand % 96 << 2] ^= 1; } } } for(idx=0; idx<96*63; idx++){ xrandom (); } }
void testdisk(void) { int ndisk, i; real rmin2, rmax2, eps2, sigma, r_i, theta_i, m_i, v_i; bodyptr gp, sp; ndisk = getiparam("ndisk"); ngalaxy = ndisk + (getbparam("nosphr") ? 0 : nspheroid); galaxy = (bodyptr) allocate(ngalaxy * SizeofBody); rmin2 = rsqr(getdparam("rmin")); rmax2 = rsqr(getdparam("rmax")); eps2 = rsqr(getdparam("eps")); sigma = getdparam("sigma"); init_random(getiparam("seed")); for (i = 0; i < ndisk; i++) { /* build disk */ gp = NthBody(galaxy, i); Mass(gp) = 0.0; /* set mass to zero */ r_i = rsqrt(rmin2 + i * (rmax2 - rmin2) / (ndisk - 1.0)); theta_i = xrandom(0.0, TWO_PI); Pos(gp)[0] = r_i * rsin(theta_i); /* set positions */ Pos(gp)[1] = r_i * rcos(theta_i); Pos(gp)[2] = 0.0; if (r_i < rsph[NTAB-1]) m_i = seval(r_i, &rsph[0], &msph[0], &msph[NTAB], NTAB); else m_i = msph[NTAB-1]; v_i = rsqrt(MAX(m_i, 0.0) * r_i*r_i / rpow(r_i*r_i + eps2, 1.5)); /* set velocities */ Vel(gp)[0] = grandom( v_i * rcos(theta_i), sigma); Vel(gp)[1] = grandom(- v_i * rsin(theta_i), sigma); Vel(gp)[2] = grandom( 0.0, sigma); } if (! getbparam("nosphr")) for (i = 0; i < nspheroid; i++) { /* append spheroid */ sp = NthBody(spheroid, i); gp = NthBody(galaxy, ndisk + i); memcpy(gp, sp, SizeofBody); } if (getbparam("zerocm")) snapcenter(galaxy, ngalaxy, MassField.offset); }
local void makedisk() { Body *bp; int i, nzero=0; real mdsk_i, rad_i, theta_i, vcir_i, omega, Aoort, kappa; real mu, sig_r, sig_t, sig_z, vrad_i, veff_i, vorb_i; real z1; static bool first = TRUE; disktab = (Body *) allocate(ndisk * sizeof(Body)); for (bp = disktab, i = 0; i < ndisk; bp++, i++) { Mass(bp) = mdsk[NTAB-1] / ndisk; mdsk_i = mdsk[NTAB-1] * ((real) i + 1.0) / ndisk; rad_i = seval(mdsk_i, &mdsk[0], &rdsk[0], &rdsk[NTAB], NTAB); theta_i = xrandom(0.0, TWO_PI); Pos(bp)[0] = rad_i * sin(theta_i); /* assign positions */ Pos(bp)[1] = rad_i * cos(theta_i); if (zmode==0) Pos(bp)[2] = grandom(0.0, 0.5 * z0); /* gauss */ else if (zmode==1) { z1 = xrandom(-1.0,1.0); Pos(bp)[2] = log(1-ABS(z1)) * z0; /* exp */ if (z1<0) Pos(bp)[2] = -Pos(bp)[2]; } else if (zmode==2) { z1 = frandom(0.0,10.0,mysech2) * z0; /* sech^2 */ if (xrandom(-1.0,1.0) < 0) z1 = -z1; Pos(bp)[2] = z1; } else if (zmode==3) { z1 = frandom(0.0,10.0,myexp) * z0; /* exp */ if (xrandom(-1.0,1.0) < 0) z1 = -z1; Pos(bp)[2] = z1; } else error("zmode=%d not supported yet",zmode); vcir_i = seval(rad_i, &rcir[0], &vcir[0], &vcir[NTAB], NTAB); omega = vcir_i / rad_i; Aoort = - 0.5 * (spldif(rad_i, &rcir[0], &vcir[0], &vcir[NTAB], NTAB) - omega); if (omega - Aoort < 0.0) printf("rad_i, omega, Aoort = %f %f %f\n", rad_i, omega, Aoort); kappa = 2 * sqrt(omega*omega - Aoort * omega); mu = alpha*alpha * mdisk * exp(- alpha * rad_i) / TWO_PI; if (cmode==1) { /* Straight from Josh - mkbaredisk*/ sig_r = 3.358 * Qtoomre * mu / kappa; sig_t = 0.5 * sig_r * kappa / omega; sig_z = 0.5 * sig_r; } else if (cmode==2) { sig_z = sqrt(PI * mu * z0); /* isothermal sech sheet */ sig_r = 2.0 * sig_z; /* with constant scaleheight */ Qtoomre = sig_r * kappa / (3.358 * mu); /* See vdKruit/Searle */ sig_t = 0.5 * sig_r * kappa / omega; } else error("illegal mode=%d",cmode); vrad_i = grandom(0.0, sig_r); if (gammas > 0.0) /* Josh' method: averaged */ veff_i = (vcir_i*vcir_i + (gammas - 3*alpha*rad_i) * sig_r*sig_r); else /* a little more accurate ? */ veff_i = sqr(vcir_i) - sqr(sig_r) * (sqr(sig_t/sig_r) - 1.5 + 0.5*sqr(sig_z/sig_r) + 2*alpha*rad_i); if (veff_i < 0.0) { nzero++; veff_i = 0.0; } else veff_i = sqrt(veff_i); vorb_i = veff_i + grandom(0.0, sig_t); Vel(bp)[0] = /* assign velocities */ (vrad_i * Pos(bp)[0] + vorb_i * Pos(bp)[1]) / rad_i; Vel(bp)[1] = (vrad_i * Pos(bp)[1] - vorb_i * Pos(bp)[0]) / rad_i; Vel(bp)[2] = grandom(0.0, sig_z); if (Qtab) { if (first) { first = FALSE; printf ("# R M V_circ Ome Kap Aoort mu sig_r sig_t sig_z v_eff Qtoomre sig_t/sig_r sig_z/sig_r fac\n"); } printf ("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g\n", rad_i,mdsk_i,vcir_i,omega,kappa,Aoort,mu,sig_r,sig_t,sig_z,veff_i, Qtoomre, sig_t/sig_r,sig_z/sig_r, 1.5-(sqr(sig_t) + 0.5*sqr(sig_z))/sqr(sig_r) ); } } if (nzero) dprintf(0,"Warning: %d stars with too little orbital motion\n",nzero); if (getbparam("zerocm")) centersnap(disktab, ndisk); }
static int readgen (void) { char *data = NULL; struct stat buf; off_t start; if (NULL == (data = malloc ((sizeof *data) * read_length * bpb / 8))) { print_error ("Out of memory"); return 1; } if (0 != fstat (fileno (infp), &buf)) { print_error ("%s", strerror (errno)); exit (EXIT_FAILURE); } /* pick a random starting point (this assumes that every base is * byte-aligned) */ srandom (time (NULL)); start = xrandom () % (buf.st_size - read_length*bpb/8); if (start < 0) { print_error ("Input does not contain enough bases."); exit (EXIT_FAILURE); } /* seek to the random position in the file */ if (0 != fseek (infp, start, SEEK_SET)) { print_error ("Failed to seek to random position in input file"); exit (EXIT_FAILURE); } /* actually read from the input file */ if (read_length*bpb/8 != fread (data, 1, read_length*bpb/8, infp)) { print_error ("Error reading data"); return 1; } /* apply any mutations */ if (xrandom () % 100 < mrate1) data[xrandom () % (read_length*bpb/8)]++; if (xrandom () % 100 < mrate2) { data[xrandom () % (read_length*bpb/8)]++; data[xrandom () % (read_length*bpb/8)]++; } if (xrandom () % 100 < mrate3) { data[xrandom () % (read_length*bpb/8)]++; data[xrandom () % (read_length*bpb/8)]++; data[xrandom () % (read_length*bpb/8)]++; } fwrite (&start, sizeof start, 1, outfp); fwrite (data, 1, read_length*bpb/8, outfp); free (data); return 0; }
void nemo_main() { int i, seed, bits; real mg, mh, tsnap; double vx, vy, vz; double fmax, f0, f1, v2, vmax, vmax2; bool Qcenter = getbparam("zerocm"); bool Qphi = getbparam("addphi"); stream outstr = stropen(getparam("out"),"w"); mu = getdparam("m"); a = getdparam("a"); seed = init_xrandom(getparam("seed")); nobj = getiparam("nbody"); if (nobj%2) warning("Total number of particles reset to %d\n",2*((nobj+1)/2)); nobj = ((nobj+1)/2); if (hasvalue("headline")) set_headline(getparam("headline")); put_history(outstr); b = a - 1; btab = (Body *) allocate(2*nobj*sizeof(Body)); for(i=0, bp=btab; i<2*nobj; i++, bp++) { double eta, radius, cth, sth, phi; double psi0; eta = (double) xrandom(0.0,1.0); radius = rad(eta); if( i >= nobj ) { if( mu == 0.0 ) break; radius *= a; } if( i<nobj ) { galaxy = 1; } else { galaxy = 0; } phi = xrandom(0.0,2*M_PI); cth = xrandom(-1.0,1.0); sth = sqrt(1.0 - cth*cth); Pos(bp)[0] = (real) (radius*sth*cos(phi)); Pos(bp)[1] = (real) (radius*sth*sin(phi)); Pos(bp)[2] = (real) (radius*cth); psi0 = -pot(radius); if (Qphi) Phi(bp) = psi0; vmax2 = 2.0*psi0; vmax = sqrt(vmax2); fmax = f(psi0); f0 = fmax; f1 = 1.1*fmax; /* just some initial values */ while( f1 > f0 ) { /* pick a velocity */ v2 = 2.0*vmax2; while( v2 > vmax2 ) { /* rejection technique */ vx = vmax*xrandom(-1.0,1.0); vy = vmax*xrandom(-1.0,1.0); vz = vmax*xrandom(-1.0,1.0); v2 = vx*vx + vy*vy + vz*vz; } f0 = f((psi0 - 0.5*v2)); f1 = fmax*xrandom(0.0,1.0); } Vel(bp)[0] = vx; Vel(bp)[1] = vy; Vel(bp)[2] = vz; } mg = 1.0/nobj; mh = mu/nobj; for(i=0, bp=btab; i<2*nobj; i++, bp++) { if (i<nobj) Mass(bp) = mg; else Mass(bp) = mh; } if (Qcenter) cofm(); bits = MassBit | PhaseSpaceBit; if (Qphi) bits |= PotentialBit; nobj *= 2; tsnap = 0.0; put_snap(outstr, &btab, &nobj, &tsnap, &bits); strclose(outstr); }