CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-pure-rand

Pure pseudorandom number generators with immutable state management and uniform distribution functions

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

utilities.mddocs/

Utility Functions

Pure Rand provides utility functions for common operations like generating multiple values at once and skipping ahead in the generator sequence. These functions follow the same pure/unsafe pattern as the rest of the library.

Capabilities

Multiple Value Generation

Generate arrays of random values efficiently, useful for initialization or batch processing.

generateN

Pure function that generates multiple values without modifying the original generator.

/**
 * Generate array of random numbers from a generator
 * @param rng - RandomGenerator instance
 * @param num - Number of values to generate
 * @returns Tuple of [array of generated values, new generator]
 */
function generateN(rng: RandomGenerator, num: number): [number[], RandomGenerator];

Usage Examples:

import { generateN, xoroshiro128plus } from 'pure-rand';

const rng = xoroshiro128plus(42);

// Generate 5 random values
const [values, nextRng] = generateN(rng, 5);
console.log(values); // [-1478741536, 1458377984, -254826496, 1967597568, -985538560]

// Original generator unchanged, can be reused
const [moreValues, anotherRng] = generateN(rng, 3);
console.log(moreValues); // Same first 3 values as above

// Continue with the new generator
const [finalValues, finalRng] = generateN(nextRng, 2);

unsafeGenerateN

Unsafe function that generates multiple values by mutating the generator for maximum performance.

/**
 * Generate array of random numbers, mutating the generator for performance
 * @param rng - RandomGenerator instance (will be mutated)
 * @param num - Number of values to generate
 * @returns Array of generated values
 */
function unsafeGenerateN(rng: RandomGenerator, num: number): number[];

Usage Examples:

import { unsafeGenerateN, xoroshiro128plus } from 'pure-rand';

const rng = xoroshiro128plus(42);

// Generate values (mutates rng)
const values1 = unsafeGenerateN(rng, 5);
const values2 = unsafeGenerateN(rng, 3); // Continues from where values1 left off

// High-performance batch generation
const largeArray = unsafeGenerateN(rng, 10000);

Sequence Skipping

Skip ahead in the generator sequence without generating intermediate values, useful for parallel processing or jumping to specific positions.

skipN

Pure function that skips N generations and returns a new generator.

/**
 * Skip N generations in the sequence without generating values
 * @param rng - RandomGenerator instance
 * @param num - Number of generations to skip
 * @returns New generator at the target position
 */
function skipN(rng: RandomGenerator, num: number): RandomGenerator;

Usage Examples:

import { skipN, uniformIntDistribution, xoroshiro128plus } from 'pure-rand';

const rng = xoroshiro128plus(42);

// Get value at current position
const [value1, rng2] = uniformIntDistribution(1, 100, rng);

// Skip ahead 1000 generations
const skippedRng = skipN(rng, 1000);
const [value1000, rng1001] = uniformIntDistribution(1, 100, skippedRng);

// This is equivalent to calling next() 1000 times but much faster

unsafeSkipN

Unsafe function that skips N generations by mutating the generator.

/**
 * Skip N generations in place, mutating the generator for performance
 * @param rng - RandomGenerator instance (will be mutated)
 * @param num - Number of generations to skip
 */
function unsafeSkipN(rng: RandomGenerator, num: number): void;

Usage Examples:

import { unsafeSkipN, unsafeUniformIntDistribution, xoroshiro128plus } from 'pure-rand';

const rng = xoroshiro128plus(42);

// Get first value
const value1 = unsafeUniformIntDistribution(1, 100, rng);

// Skip ahead 500 generations (mutates rng)
unsafeSkipN(rng, 500);

// Now rng is at position 501
const value501 = unsafeUniformIntDistribution(1, 100, rng);

Common Usage Patterns

Batch Initialization

Generate arrays of values for initialization:

import { generateN, uniformIntDistribution, xoroshiro128plus } from 'pure-rand';

const rng = xoroshiro128plus(Date.now());

// Initialize array with random values
const [rawValues, nextRng] = generateN(rng, 100);

// Or generate distributed values
const diceRolls: number[] = [];
let currentRng = nextRng;
for (let i = 0; i < 50; i++) {
  const [roll, newRng] = uniformIntDistribution(1, 6, currentRng);
  diceRolls.push(roll);
  currentRng = newRng;
}

// More efficient unsafe version
const unsafeRng = xoroshiro128plus(Date.now());
const fastDiceRolls: number[] = [];
for (let i = 0; i < 50; i++) {
  fastDiceRolls.push(unsafeUniformIntDistribution(1, 6, unsafeRng));
}

Parallel Processing Setup

Use skipN to create generators for different workers:

import { skipN, xoroshiro128plus } from 'pure-rand';

const baseSeed = 42;
const itemsPerWorker = 1000;

// Create generators for 4 workers
const workers = [];
let baseRng = xoroshiro128plus(baseSeed);

for (let i = 0; i < 4; i++) {
  workers.push({
    id: i,
    rng: baseRng,
    startIndex: i * itemsPerWorker,
    endIndex: (i + 1) * itemsPerWorker
  });
  
  // Skip ahead for next worker
  baseRng = skipN(baseRng, itemsPerWorker);
}

// Each worker now has independent, non-overlapping sequences

Reproducible Sampling

Skip to specific positions for reproducible sampling:

import { skipN, uniformIntDistribution, xoroshiro128plus } from 'pure-rand';

const masterRng = xoroshiro128plus(12345);

// Sample at specific positions
const positions = [0, 100, 500, 750, 1200];
const samples: number[] = [];

for (const position of positions) {
  const positionRng = skipN(masterRng, position);
  const [sample] = uniformIntDistribution(1, 1000, positionRng);
  samples.push(sample);
}

console.log(samples); // Always the same values for seed 12345

Performance Comparison

import { generateN, unsafeGenerateN, skipN, unsafeSkipN, xoroshiro128plus } from 'pure-rand';

const count = 10000;

// Pure operations (safe, creates new instances)
console.time('Pure generateN');
const rng1 = xoroshiro128plus(42);
const [values, newRng] = generateN(rng1, count);
console.timeEnd('Pure generateN');

console.time('Pure skipN');
const rng2 = xoroshiro128plus(42);
const skippedRng = skipN(rng2, count);
console.timeEnd('Pure skipN');

// Unsafe operations (faster, mutates in place)
console.time('Unsafe generateN');
const rng3 = xoroshiro128plus(42);
const unsafeValues = unsafeGenerateN(rng3, count);
console.timeEnd('Unsafe generateN');

console.time('Unsafe skipN');
const rng4 = xoroshiro128plus(42);
unsafeSkipN(rng4, count);
console.timeEnd('Unsafe skipN');

Function Selection Guide

  • generateN: Use when you need multiple raw values and want to preserve the original generator
  • unsafeGenerateN: Use for maximum performance when you don't need the original generator
  • skipN: Use to jump ahead in sequences for parallel processing or specific sampling
  • unsafeSkipN: Use for high-performance sequence advancement when mutating the generator is acceptable

All utility functions work with any generator type and complement the distribution functions for comprehensive random number generation workflows.

Install with Tessl CLI

npx tessl i tessl/npm-pure-rand

docs

distributions.md

generators.md

index.md

utilities.md

tile.json