generator.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. function Ziggurat(seeder = 123456789){
  2. var jsr = seeder;
  3. var wn = Array(128);
  4. var fn = Array(128);
  5. var kn = Array(128);
  6. function RNOR(){
  7. var hz = SHR3();
  8. var iz = hz & 127;
  9. return (Math.abs(hz) < kn[iz]) ? hz * wn[iz] : nfix(hz, iz);
  10. }
  11. this.nextGaussian = function(){
  12. return RNOR();
  13. };
  14. function nfix(hz, iz){
  15. var r = 3.442619855899;
  16. var r1 = 1.0 / r;
  17. var x;
  18. var y;
  19. while(true){
  20. x = hz * wn[iz];
  21. if( iz === 0 ){
  22. x = (-Math.log(UNI()) * r1);
  23. y = -Math.log(UNI());
  24. while( y + y < x * x){
  25. x = (-Math.log(UNI()) * r1);
  26. y = -Math.log(UNI());
  27. }
  28. return ( hz > 0 ) ? r+x : -r-x;
  29. }
  30. if( fn[iz] + UNI() * (fn[iz-1] - fn[iz]) < Math.exp(-0.5 * x * x) ){
  31. return x;
  32. }
  33. hz = SHR3();
  34. iz = hz & 127;
  35. if( Math.abs(hz) < kn[iz]){
  36. return (hz * wn[iz]);
  37. }
  38. }
  39. }
  40. function SHR3(){
  41. var jz = jsr;
  42. var jzr = jsr;
  43. jzr ^= (jzr << 13);
  44. jzr ^= (jzr >>> 17);
  45. jzr ^= (jzr << 5);
  46. jsr = jzr;
  47. return (jz+jzr) | 0;
  48. }
  49. function UNI(){
  50. return 0.5 * (1 + SHR3() / -Math.pow(2,31));
  51. }
  52. function zigset(){
  53. // seed generator based on current time
  54. //jsr ^= new Date().getTime();
  55. var m1 = 2147483648.0;
  56. var dn = 3.442619855899;
  57. var tn = dn;
  58. var vn = 9.91256303526217e-3;
  59. var q = vn / Math.exp(-0.5 * dn * dn);
  60. kn[0] = Math.floor((dn/q)*m1);
  61. kn[1] = 0;
  62. wn[0] = q / m1;
  63. wn[127] = dn / m1;
  64. fn[0] = 1.0;
  65. fn[127] = Math.exp(-0.5 * dn * dn);
  66. for(var i = 126; i >= 1; i--){
  67. dn = Math.sqrt(-2.0 * Math.log( vn / dn + Math.exp( -0.5 * dn * dn)));
  68. kn[i+1] = Math.floor((dn/tn)*m1);
  69. tn = dn;
  70. fn[i] = Math.exp(-0.5 * dn * dn);
  71. wn[i] = dn / m1;
  72. }
  73. }
  74. zigset();
  75. }
  76. module.exports = Ziggurat;