UNPKG

ltcode

Version:

Luby Transform Code implementation.

70 lines (69 loc) 2.57 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PRNG = void 0; class PRNG { constructor(numBlocks, seed) { this.DEFAULT_DELTA = 0.5; this.PRNG_M = 2147483647; this.seed = seed; this.numBlocks = numBlocks; this.cumulativeDistributionFunction = this.generateRsdCdf(); } sample_source_blocks(seed) { const initialSamplingSeed = seed !== null ? seed : this.seed; if (seed !== null) { this.seed = seed; } const degree = this.sampleDegree(); const selectedBlocks = new Set(); while (selectedBlocks.size < degree) { const nextRandom = this.nextRandom(); const blockNumber = nextRandom % this.numBlocks; selectedBlocks.add(blockNumber); } return [initialSamplingSeed, selectedBlocks]; } nextRandom() { this.seed = 16807 * this.seed % this.PRNG_M; return this.seed; } sampleDegree() { const probability = this.nextRandom() / (this.PRNG_M - 1); for (let index = 0; index < this.cumulativeDistributionFunction.length; index++) { if (this.cumulativeDistributionFunction[index] > probability) { return index + 1; } } return this.cumulativeDistributionFunction.length; } generateTau(S) { const pivot = Math.floor(this.numBlocks / S); const tau = Array.from({ length: pivot - 1 }, (_, d) => S / this.numBlocks / (d + 1)); tau.push(S / this.numBlocks * Math.log(S / this.DEFAULT_DELTA)); tau.push(...Array.from({ length: this.numBlocks - pivot }, () => 0)); return tau; } generateRho() { return [1 / this.numBlocks, ...Array.from({ length: this.numBlocks - 1 }, (_, d) => 1 / ((d + 2) * (d + 1)))]; } generateMu() { const S = Math.log(this.numBlocks / this.DEFAULT_DELTA) * Math.sqrt(this.numBlocks) * 0.1; const tau = this.generateTau(S); const rho = this.generateRho(); const normalizer = this.sum(rho) + this.sum(tau); return Array.from({ length: this.numBlocks }, (_, d) => (rho[d] + tau[d]) / normalizer); } sum(arr) { return arr.reduce((a, b) => a + b, 0); } generateRsdCdf() { const mu = this.generateMu(); const arr = []; for (let d = 0; d < this.numBlocks; d++) { const slice_mu = mu.slice(0, d + 1); arr.push(this.sum(slice_mu)); } return arr; } } exports.PRNG = PRNG;