UNPKG

sobol

Version:

Sobol quasi random sample generator

65 lines (60 loc) 2.15 kB
// Thanks to https://github.com/croquelois/sobol import fs from "fs"; var BITS = 52; var SCALE = 2 << 51; var MAX_DIMENSION = 21201; var file161 = __dirname + "/dims161.txt"; var file21201 = __dirname + "/dims21201.txt"; export class SobolSequenceGenerator { constructor(dim) { if (dim < 1 || dim > MAX_DIMENSION) throw new Error("Out of range dimension"); this.dimension = dim; this.count = 0; var direction = (this.direction = []); /*of []*/ this.x = []; this.zero = []; var tmp = []; for (var i = 0; i <= BITS; i++) tmp.push(0); for (var i = 0; i < dim; i++) { direction[i] = tmp.slice(); this.x[i] = 0; this.zero[i] = 0; } var data = fs.readFileSync(dim <= 161 ? file161 : file21201); var lines = ("" + data).split("\n"); for (var i = 1; i <= BITS; i++) direction[0][i] = 1 << (BITS - i); for (var d = 1; d < dim; d++) { var cells = lines[d].split(/\s+/).map(function(str) { return parseInt(str, 10); }); var s = cells[1]; var a = cells[2]; var m = [0]; for (var i = 0; i < s; i++) m.push(cells[3 + i]); for (var i = 1; i <= s; i++) direction[d][i] = m[i] << (BITS - i); for (var i = s + 1; i <= BITS; i++) { direction[d][i] = direction[d][i - s] ^ (direction[d][i - s] >> s); for (var k = 1; k <= s - 1; k++) direction[d][i] ^= ((a >> (s - 1 - k)) & 1) * direction[d][i - k]; } } } nextVector() { var v = []; if (this.count == 0) { this.count++; return this.zero.slice(); } var c = 1; var value = this.count - 1; while ((value & 1) == 1) { value >>= 1; c++; } for (var i = 0; i < this.dimension; i++) { this.x[i] ^= this.direction[i][c]; v[i] = this.x[i] / SCALE; } this.count++; return v; } }