@cloudglides/nox 1.1.5 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -9
- package/example/src/App.css +89 -84
- package/example/src/App.jsx +375 -151
- package/package.json +7 -6
- package/src/core.browser.js +10 -2
- package/src/core.js +32 -4
- package/src/generators/logistic.js +30 -25
- package/src/generators/mixer.js +7 -7
- package/src/generators/mt19937.js +10 -7
- package/src/generators/pcg64.js +23 -12
- package/src/generators/splitmix64.js +12 -6
- package/src/generators/tent.js +12 -7
- package/src/generators/xorshift64.js +6 -3
- package/src/index.d.ts +68 -4
- package/src/index.js +154 -2
- package/src/rng.browser.js +21 -10
- package/src/rng.js +95 -82
- package/src/utils/arrays.js +149 -0
- package/src/utils/bits.js +146 -21
- package/src/utils/categorical.js +68 -31
- package/src/utils/combinatorics.js +113 -69
- package/src/utils/confidence.js +145 -0
- package/src/utils/decomposition.js +204 -0
- package/src/utils/distributions-advanced.js +122 -0
- package/src/utils/distributions-extra.js +102 -11
- package/src/utils/distributions-special.js +77 -20
- package/src/utils/distributions.js +99 -35
- package/src/utils/effects.js +172 -0
- package/src/utils/entropy.browser.js +29 -26
- package/src/utils/entropy.js +18 -8
- package/src/utils/helpers.js +64 -0
- package/src/utils/hypothesis.js +167 -0
- package/src/utils/integration.js +137 -0
- package/src/utils/interpolation.js +221 -0
- package/src/utils/matrix.js +242 -0
- package/src/utils/noise.js +36 -22
- package/src/utils/odesolvers.js +176 -0
- package/src/utils/optimization.js +215 -0
- package/src/utils/precomputed.js +166 -0
- package/src/utils/probability.js +199 -0
- package/src/utils/regression.js +170 -0
- package/src/utils/resampling.js +112 -0
- package/src/utils/rootfinding.js +158 -0
- package/src/utils/sampling.js +86 -77
- package/src/utils/seed.js +10 -4
- package/src/utils/seeding.js +24 -12
- package/src/utils/sequence.js +116 -32
- package/src/utils/state.js +48 -36
- package/src/utils/statistics.js +64 -2
- package/src/utils/stochastic.js +91 -31
- package/src/utils/stratified.js +108 -0
- package/src/utils/timeseries.js +166 -0
- package/src/utils/transforms.js +146 -0
- package/test/comprehensive-new.js +126 -0
- package/test/comprehensive.js +4 -3
- package/test/error-handling.js +49 -0
- package/test/new-features.js +52 -0
- package/IMPROVEMENTS.md +0 -58
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { rng, deterministic, normal, exponential, poisson, uniform } from '../src/index.js';
|
|
2
|
+
import { shuffle, pick, sample } from '../src/index.js';
|
|
3
|
+
import { PCG64, Xorshift64, Splitmix64, MT19937 } from '../src/index.js';
|
|
4
|
+
|
|
5
|
+
const assert = (condition, msg) => {
|
|
6
|
+
if (!condition) {
|
|
7
|
+
throw new Error(`✗ ${msg}`);
|
|
8
|
+
}
|
|
9
|
+
console.log(`✓ ${msg}`);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
console.log('\n=== BASIC OPERATIONS ===');
|
|
13
|
+
const r = rng();
|
|
14
|
+
assert(typeof r.nextFloat() === 'number', 'nextFloat returns number');
|
|
15
|
+
assert(r.nextFloat() >= 0 && r.nextFloat() <= 1, 'nextFloat in [0,1]');
|
|
16
|
+
assert(typeof r.nextInt(100) === 'number', 'nextInt returns number');
|
|
17
|
+
assert(r.int(1, 10) >= 1 && r.int(1, 10) <= 10, 'int in range');
|
|
18
|
+
assert(typeof r.bool() === 'boolean', 'bool returns boolean');
|
|
19
|
+
|
|
20
|
+
console.log('\n=== DETERMINISTIC ===');
|
|
21
|
+
const d1 = deterministic(12345);
|
|
22
|
+
const d2 = deterministic(12345);
|
|
23
|
+
const seq1 = d1.floats(100);
|
|
24
|
+
const seq2 = d2.floats(100);
|
|
25
|
+
assert(seq1.length === 100, 'deterministic generates correct count');
|
|
26
|
+
assert(JSON.stringify(seq1) === JSON.stringify(seq2), 'same seed produces same sequence');
|
|
27
|
+
|
|
28
|
+
console.log('\n=== GENERATORS ===');
|
|
29
|
+
const gens = [
|
|
30
|
+
{ name: 'PCG64', Gen: PCG64 },
|
|
31
|
+
{ name: 'Xorshift64', Gen: Xorshift64 },
|
|
32
|
+
{ name: 'Splitmix64', Gen: Splitmix64 },
|
|
33
|
+
{ name: 'MT19937', Gen: MT19937 }
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
for (const {name, Gen} of gens) {
|
|
37
|
+
const g = new Gen(42);
|
|
38
|
+
const vals = Array.from({length: 1000}, () => g.nextFloat());
|
|
39
|
+
const mean = vals.reduce((a, b) => a + b) / 1000;
|
|
40
|
+
assert(mean > 0.3 && mean < 0.7, `${name} mean ${mean.toFixed(3)} reasonable`);
|
|
41
|
+
assert(vals.every(v => v >= 0 && v <= 1), `${name} values in [0,1]`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
console.log('\n=== DISTRIBUTIONS ===');
|
|
45
|
+
const r2 = rng();
|
|
46
|
+
const normal5 = Array.from({length: 1000}, () => normal(r2));
|
|
47
|
+
assert(normal5.length === 1000, 'normal generates correct count');
|
|
48
|
+
const hasNegative = normal5.some(v => v < 0);
|
|
49
|
+
const hasPositive = normal5.some(v => v > 0);
|
|
50
|
+
assert(hasNegative && hasPositive, 'normal has both positive and negative values');
|
|
51
|
+
|
|
52
|
+
const exp5 = Array.from({length: 100}, () => exponential(r2));
|
|
53
|
+
assert(exp5.every(v => v >= 0), 'exponential all positive');
|
|
54
|
+
|
|
55
|
+
const poi = Array.from({length: 100}, () => poisson(r2, 5));
|
|
56
|
+
assert(poi.every(v => Number.isInteger(v) && v >= 0), 'poisson returns non-negative integers');
|
|
57
|
+
|
|
58
|
+
const uni = uniform(r2, 10, 20);
|
|
59
|
+
assert(uni >= 10 && uni <= 20, 'uniform in range');
|
|
60
|
+
|
|
61
|
+
console.log('\n=== ARRAY OPERATIONS ===');
|
|
62
|
+
const r3 = rng();
|
|
63
|
+
const arr = [1,2,3,4,5];
|
|
64
|
+
const shuffled = shuffle(arr, r3);
|
|
65
|
+
assert(shuffled.length === 5, 'shuffle preserves length');
|
|
66
|
+
assert(shuffled.some((v, i) => v !== arr[i]), 'shuffle actually shuffles');
|
|
67
|
+
|
|
68
|
+
const picked = pick(arr, r3);
|
|
69
|
+
assert(arr.includes(picked), 'pick returns array element');
|
|
70
|
+
|
|
71
|
+
const sampled = sample(arr, 3, r3);
|
|
72
|
+
assert(sampled.length === 3, 'sample returns correct count');
|
|
73
|
+
assert(sampled.every(v => arr.includes(v)), 'sample contains array elements');
|
|
74
|
+
|
|
75
|
+
console.log('\n=== BATCH OPERATIONS ===');
|
|
76
|
+
const r4 = rng();
|
|
77
|
+
const floats = r4.floats(100);
|
|
78
|
+
assert(floats.length === 100, 'floats correct length');
|
|
79
|
+
assert(floats.every(v => typeof v === 'number'), 'floats all numbers');
|
|
80
|
+
|
|
81
|
+
const ints = r4.ints(50, 100);
|
|
82
|
+
assert(ints.length === 50, 'ints correct length');
|
|
83
|
+
assert(ints.every(v => v >= 0 && v < 100), 'ints in range');
|
|
84
|
+
|
|
85
|
+
const bools = r4.bools(50);
|
|
86
|
+
assert(bools.length === 50, 'bools correct length');
|
|
87
|
+
assert(bools.every(v => typeof v === 'boolean'), 'bools all booleans');
|
|
88
|
+
|
|
89
|
+
console.log('\n=== EDGE CASES ===');
|
|
90
|
+
const r5 = rng();
|
|
91
|
+
try {
|
|
92
|
+
r5.int(1, 1);
|
|
93
|
+
assert(r5.int(1, 1) === 1, 'int(1,1) returns 1');
|
|
94
|
+
} catch (e) {
|
|
95
|
+
assert(false, 'int(1,1) should not throw');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
shuffle([], r5);
|
|
100
|
+
assert(true, 'shuffle([]) doesnt crash');
|
|
101
|
+
} catch (e) {
|
|
102
|
+
assert(false, 'shuffle([]) shouldnt throw');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const r6 = rng();
|
|
106
|
+
const batch = r6.batch(5, (rng, i) => i * rng.nextInt(10));
|
|
107
|
+
assert(batch.length === 5, 'batch with custom function');
|
|
108
|
+
|
|
109
|
+
console.log('\n=== PERFORMANCE CHECK ===');
|
|
110
|
+
const r7 = rng();
|
|
111
|
+
const start = performance.now();
|
|
112
|
+
for (let i = 0; i < 1000000; i++) {
|
|
113
|
+
r7.nextFloat();
|
|
114
|
+
}
|
|
115
|
+
const elapsed = performance.now() - start;
|
|
116
|
+
console.log(`✓ 1M nextFloat in ${elapsed.toFixed(0)}ms (${(1000000/elapsed|0).toLocaleString()}/sec)`);
|
|
117
|
+
|
|
118
|
+
const r8 = rng();
|
|
119
|
+
const start2 = performance.now();
|
|
120
|
+
for (let i = 0; i < 100000; i++) {
|
|
121
|
+
normal(r8);
|
|
122
|
+
}
|
|
123
|
+
const elapsed2 = performance.now() - start2;
|
|
124
|
+
console.log(`✓ 100k normal in ${elapsed2.toFixed(0)}ms (${(100000/elapsed2|0).toLocaleString()}/sec)`);
|
|
125
|
+
|
|
126
|
+
console.log('\n✅ All tests passed\n');
|
package/test/comprehensive.js
CHANGED
|
@@ -61,10 +61,11 @@ console.log(` State restored correctly: ${val2 === val2_restored}`);
|
|
|
61
61
|
|
|
62
62
|
console.log('\n7. Generator Cloning');
|
|
63
63
|
const orig = deterministic(12345);
|
|
64
|
-
|
|
64
|
+
orig.floats(3);
|
|
65
65
|
const cloned = cloneGenerator(orig);
|
|
66
|
-
const
|
|
67
|
-
|
|
66
|
+
const origNext = orig.floats(3);
|
|
67
|
+
const clonedNext = cloned.floats(3);
|
|
68
|
+
console.log(` Clone has same sequence: ${JSON.stringify(origNext) === JSON.stringify(clonedNext)}`);
|
|
68
69
|
|
|
69
70
|
console.log('\n8. Weighted Sampling');
|
|
70
71
|
const items = ['A', 'B', 'C'];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { rng, deterministic, normal, exponential, uniform, shuffle, pick, sample } from '../src/index.js';
|
|
2
|
+
|
|
3
|
+
const test = (name, fn) => {
|
|
4
|
+
try {
|
|
5
|
+
fn();
|
|
6
|
+
console.log(`✗ ${name} - should have thrown`);
|
|
7
|
+
} catch (e) {
|
|
8
|
+
console.log(`✓ ${name}`);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
console.log('=== ERROR HANDLING ===\n');
|
|
13
|
+
|
|
14
|
+
const r = rng();
|
|
15
|
+
|
|
16
|
+
// RNG methods
|
|
17
|
+
test('int() with non-number min', () => r.int('a', 100));
|
|
18
|
+
test('int() with non-number max', () => r.int(1, 'b'));
|
|
19
|
+
test('int() with non-integer min', () => r.int(1.5, 100));
|
|
20
|
+
test('bool() with invalid probability', () => r.bool(1.5));
|
|
21
|
+
test('bool() with negative probability', () => r.bool(-0.5));
|
|
22
|
+
test('range() with non-number min', () => r.range('a', 10, 1));
|
|
23
|
+
test('range() with negative step', () => r.range(1, 10, -1));
|
|
24
|
+
test('choice() with empty array', () => r.choice([]));
|
|
25
|
+
test('choice() with non-array', () => r.choice('notarray'));
|
|
26
|
+
|
|
27
|
+
// Batch operations
|
|
28
|
+
test('floats() with negative count', () => r.floats(-5));
|
|
29
|
+
test('ints() with non-integer count', () => r.ints(5.5, 100));
|
|
30
|
+
test('bools() with string count', () => r.bools('5'));
|
|
31
|
+
test('batch() with non-function', () => r.batch(5, 'notfn'));
|
|
32
|
+
|
|
33
|
+
// Distributions
|
|
34
|
+
test('normal() with invalid rng', () => normal({}, 0, 1));
|
|
35
|
+
test('exponential() with zero lambda', () => exponential(r, 0));
|
|
36
|
+
test('uniform() with min > max', () => uniform(r, 100, 10));
|
|
37
|
+
|
|
38
|
+
// Array operations
|
|
39
|
+
test('shuffle() with non-array', () => shuffle({}, r));
|
|
40
|
+
test('shuffle() with invalid rng', () => shuffle([1,2,3], {}));
|
|
41
|
+
test('pick() with empty array', () => pick([], r));
|
|
42
|
+
test('sample() with count > length', () => sample([1,2], 5, r));
|
|
43
|
+
test('sample() with zero count', () => sample([1,2], 0, r));
|
|
44
|
+
|
|
45
|
+
// Deterministic
|
|
46
|
+
test('deterministic() with no seed', () => deterministic());
|
|
47
|
+
test('deterministic() with null seed', () => deterministic(null));
|
|
48
|
+
|
|
49
|
+
console.log('\n✅ All error cases handled correctly\n');
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { rng, binomial, geometric, normals, exponentials, sampleWithReplacement, permute, range, cycle, clz, ctz, popcountNum, reverseBits, setBit, clearBit, toggleBit } from '../src/index.js';
|
|
2
|
+
|
|
3
|
+
console.log('=== NEW FEATURES TEST ===\n');
|
|
4
|
+
|
|
5
|
+
const r = rng();
|
|
6
|
+
|
|
7
|
+
console.log('1. Binomial Distribution');
|
|
8
|
+
const binom = binomial(r, 20, 0.5);
|
|
9
|
+
console.log(` binomial(20, 0.5): ${binom} (between 0-20)`);
|
|
10
|
+
|
|
11
|
+
console.log('\n2. Geometric Distribution');
|
|
12
|
+
const geom = geometric(r, 0.3);
|
|
13
|
+
console.log(` geometric(0.3): ${geom} (number of trials)`);
|
|
14
|
+
|
|
15
|
+
console.log('\n3. Batch Normal Distribution (with caching)');
|
|
16
|
+
const normals_arr = normals(r, 5);
|
|
17
|
+
console.log(` normals(5): [${normals_arr.map(n => n.toFixed(2)).join(', ')}]`);
|
|
18
|
+
|
|
19
|
+
console.log('\n4. Batch Exponential Distribution');
|
|
20
|
+
const exps = exponentials(r, 4, 1);
|
|
21
|
+
console.log(` exponentials(4): [${exps.map(e => e.toFixed(2)).join(', ')}]`);
|
|
22
|
+
|
|
23
|
+
console.log('\n5. Sampling with Replacement');
|
|
24
|
+
const sampled = sampleWithReplacement(['A', 'B', 'C'], 8, r);
|
|
25
|
+
console.log(` sampleWithReplacement([A,B,C], 8): [${sampled.join(', ')}]`);
|
|
26
|
+
|
|
27
|
+
console.log('\n6. Permutation (alias for shuffle)');
|
|
28
|
+
const perm = permute([1, 2, 3, 4], r);
|
|
29
|
+
console.log(` permute([1,2,3,4]): [${perm.join(', ')}]`);
|
|
30
|
+
|
|
31
|
+
console.log('\n7. Range Generation');
|
|
32
|
+
const r1 = range(0, 5);
|
|
33
|
+
const r2 = range(10, 5, -1);
|
|
34
|
+
console.log(` range(0, 5): [${r1.join(', ')}]`);
|
|
35
|
+
console.log(` range(10, 5, -1): [${r2.join(', ')}]`);
|
|
36
|
+
|
|
37
|
+
console.log('\n8. Cycle (repeat array)');
|
|
38
|
+
const cyc = cycle(['X', 'Y'], 6);
|
|
39
|
+
console.log(` cycle([X, Y], 6): [${cyc.join(', ')}]`);
|
|
40
|
+
|
|
41
|
+
console.log('\n9. Bit Operations');
|
|
42
|
+
const val = 0b11010110n;
|
|
43
|
+
console.log(` Value: 0b11010110`);
|
|
44
|
+
console.log(` clz(): ${clz(val)}`);
|
|
45
|
+
console.log(` ctz(): ${ctz(val)}`);
|
|
46
|
+
console.log(` popcountNum(214): ${popcountNum(214)}`);
|
|
47
|
+
console.log(` reverseBits() [8-bit]: 0b${reverseBits(val, 8).toString(2).padStart(8, '0')}`);
|
|
48
|
+
console.log(` setBit(0b11010110, 0): 0b${setBit(val, 0).toString(2).padStart(8, '0')}`);
|
|
49
|
+
console.log(` clearBit(0b11010110, 1): 0b${clearBit(val, 1).toString(2).padStart(8, '0')}`);
|
|
50
|
+
console.log(` toggleBit(0b11010110, 4): 0b${toggleBit(val, 4).toString(2).padStart(8, '0')}`);
|
|
51
|
+
|
|
52
|
+
console.log('\n✓ All new features working correctly');
|
package/IMPROVEMENTS.md
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# Improvements Made (Hour 2)
|
|
2
|
-
|
|
3
|
-
## Batch Operations
|
|
4
|
-
- Added `batch(count, fn)` - Execute custom function n times
|
|
5
|
-
- Added `floats(count)` - Generate array of floats
|
|
6
|
-
- Added `ints(count, max)` - Generate array of integers
|
|
7
|
-
- Added `bools(count, probability)` - Generate array of booleans
|
|
8
|
-
|
|
9
|
-
## RNG API Enhancements
|
|
10
|
-
- Added `range(min, max, step)` - Pick random value from stepped range
|
|
11
|
-
- Added `choice(arr)` - Pick random element from array
|
|
12
|
-
- Better error messages with TypeError vs RangeError distinctions
|
|
13
|
-
|
|
14
|
-
## Statistical Improvements
|
|
15
|
-
- Added `kolmogorovSmirnovTest(data)` - KS goodness-of-fit test
|
|
16
|
-
- Added `meanTest(data, expected)` - Test mean of distribution
|
|
17
|
-
- Added `varianceTest(data, expected)` - Test variance of distribution
|
|
18
|
-
- All tests return detailed result objects with pass/fail indicators
|
|
19
|
-
|
|
20
|
-
## Sampling Enhancements
|
|
21
|
-
- Improved `weightedPick()` with comprehensive validation
|
|
22
|
-
- Improved `weightedSample()` with type checking
|
|
23
|
-
- Improved `reservoirSample()` with better error handling
|
|
24
|
-
|
|
25
|
-
## Generator Optimizations
|
|
26
|
-
- Removed modulo bias in `nextInt()` - uses rejection sampling instead
|
|
27
|
-
- Applied to: PCG64, Xorshift64, Splitmix64, MT19937
|
|
28
|
-
- Ensures uniform distribution across all ranges
|
|
29
|
-
|
|
30
|
-
## Performance & Caching
|
|
31
|
-
- Added crypto cache in entropy source for performance
|
|
32
|
-
- Added `clearCryptoCache()` export for testing
|
|
33
|
-
- Better entropy mixing with proper BigInt operations
|
|
34
|
-
|
|
35
|
-
## Type Safety
|
|
36
|
-
- Added `IGenerator` interface for type consistency
|
|
37
|
-
- Added `GeneratorConstructor` type definition
|
|
38
|
-
- Added generic types to shuffle, pick, sample functions
|
|
39
|
-
- Added test result interfaces: `TestResult`, `KSTestResult`
|
|
40
|
-
- Complete TypeScript definitions for all new APIs
|
|
41
|
-
|
|
42
|
-
## Documentation
|
|
43
|
-
- Updated README with batch operations examples
|
|
44
|
-
- Added weighted sampling section
|
|
45
|
-
- Added statistical tests section
|
|
46
|
-
- Enhanced generator selection documentation
|
|
47
|
-
|
|
48
|
-
## Testing
|
|
49
|
-
- Added comprehensive test suite (test/comprehensive.js)
|
|
50
|
-
- Added advanced features test (test/advanced.js)
|
|
51
|
-
- All tests pass successfully
|
|
52
|
-
|
|
53
|
-
## Code Quality
|
|
54
|
-
- Total lines: 1107 → 1318 (+211)
|
|
55
|
-
- Files modified: 10
|
|
56
|
-
- Lines added/changed: 286
|
|
57
|
-
- Consistent error handling patterns
|
|
58
|
-
- Full backward compatibility maintained
|