#include #include #include #define INTMAX 2147483647.0 #define a 16807 /* multiplier */ #define m 2147483647L/* 2**31 - 1 */ #define q 127773L/* m div a */ #define r 2836 /* m mod a */ #ifndef RNUM #define RNUM static long randomnum = 2; inline long nextlongrand(long seed) { unsigned long lo, hi; lo = a * (long)(seed & 0xFFFF); hi = a * (long)((unsigned long)seed >> 16); lo += (hi & 0x7FFF) << 16; if (lo > m) { lo &= m; ++lo; } lo += hi >> 15; if (lo > m) { lo &= m; ++lo; } return (long)lo; } inline long longrand(void) /* return next random long */ { randomnum = nextlongrand(randomnum); return randomnum; } static void slongrand(unsigned long seed) /* to seed it */ { randomnum = seed ? (seed & m) : 1; /* nonzero seed */ } static inline double frandom() { return (longrand() / INTMAX); } /* PDF of uniform x */ static inline double rectangle() { return (double) (longrand() / INTMAX); } /* PDF of triangle x, CDF of triangle x**2 */ static inline double triangle() { return (double)sqrt(longrand() / INTMAX); } /* PDF of negative triangle 2 - 2x, CDF of negative triangle 2x - x**2 */ static inline double negtriangle() { return (1.0 - (double)sqrt(1.0 - longrand() / INTMAX)); } /* PDF of camel70-20: width 20 10 40 10 20, height 10 35 10 35 10 * CDF of camel70-20: 1/2 x for 0 - 0.2 * 7/2 x - 60 for 0.2 - 0.3 * 1/4 x + 37.5 for 0.3 - 0.7 * 7/2 x - 190 for 0.7 - 0.8 * 1/2 x + 50 for 0.8 - 1 */ static inline double camel70_20() { double frand; frand = longrand() / INTMAX; if (frand < 0.1) return 2.0 * frand; else if (frand < 0.45) return (frand + 0.6) * 2.0 / 7.0; else if (frand < 0.55) return (frand - 0.375) * 4.0; else if (frand < 0.9) return (frand + 1.9) * 2.0 / 7.0; else return (frand - 0.5) * 2.0; } /* PDF of camel98-1: width 20 0.5 59 0.5 20, height 0.5 49 1 49 0.5 * CDF of camel98-1: 1/40 x for 0 - 0.2 * 98 x - 1959.5 for 0.2 - 0.25 * 1/59 x + 49.153 for 0.25 - 0.795 * 98 x - 7740.5 for 0.795 - 0.8 * 1/40 x + 97.5 for 0.8 - 1 */ static inline double camel98_1() { double frand; frand = longrand() / INTMAX; if (frand < 0.005) return 40.0 * frand; else if (frand < 0.495) return (frand + 19.595) / 98.0; else if (frand < 0.505) return (frand - 0.49153) * 59.0; else if (frand < 0.995) return (frand + 77.405) / 98.0; else return (frand - 0.975) * 40.0; } #endif