@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.
Files changed (58) hide show
  1. package/README.md +9 -9
  2. package/example/src/App.css +89 -84
  3. package/example/src/App.jsx +375 -151
  4. package/package.json +7 -6
  5. package/src/core.browser.js +10 -2
  6. package/src/core.js +32 -4
  7. package/src/generators/logistic.js +30 -25
  8. package/src/generators/mixer.js +7 -7
  9. package/src/generators/mt19937.js +10 -7
  10. package/src/generators/pcg64.js +23 -12
  11. package/src/generators/splitmix64.js +12 -6
  12. package/src/generators/tent.js +12 -7
  13. package/src/generators/xorshift64.js +6 -3
  14. package/src/index.d.ts +68 -4
  15. package/src/index.js +154 -2
  16. package/src/rng.browser.js +21 -10
  17. package/src/rng.js +95 -82
  18. package/src/utils/arrays.js +149 -0
  19. package/src/utils/bits.js +146 -21
  20. package/src/utils/categorical.js +68 -31
  21. package/src/utils/combinatorics.js +113 -69
  22. package/src/utils/confidence.js +145 -0
  23. package/src/utils/decomposition.js +204 -0
  24. package/src/utils/distributions-advanced.js +122 -0
  25. package/src/utils/distributions-extra.js +102 -11
  26. package/src/utils/distributions-special.js +77 -20
  27. package/src/utils/distributions.js +99 -35
  28. package/src/utils/effects.js +172 -0
  29. package/src/utils/entropy.browser.js +29 -26
  30. package/src/utils/entropy.js +18 -8
  31. package/src/utils/helpers.js +64 -0
  32. package/src/utils/hypothesis.js +167 -0
  33. package/src/utils/integration.js +137 -0
  34. package/src/utils/interpolation.js +221 -0
  35. package/src/utils/matrix.js +242 -0
  36. package/src/utils/noise.js +36 -22
  37. package/src/utils/odesolvers.js +176 -0
  38. package/src/utils/optimization.js +215 -0
  39. package/src/utils/precomputed.js +166 -0
  40. package/src/utils/probability.js +199 -0
  41. package/src/utils/regression.js +170 -0
  42. package/src/utils/resampling.js +112 -0
  43. package/src/utils/rootfinding.js +158 -0
  44. package/src/utils/sampling.js +86 -77
  45. package/src/utils/seed.js +10 -4
  46. package/src/utils/seeding.js +24 -12
  47. package/src/utils/sequence.js +116 -32
  48. package/src/utils/state.js +48 -36
  49. package/src/utils/statistics.js +64 -2
  50. package/src/utils/stochastic.js +91 -31
  51. package/src/utils/stratified.js +108 -0
  52. package/src/utils/timeseries.js +166 -0
  53. package/src/utils/transforms.js +146 -0
  54. package/test/comprehensive-new.js +126 -0
  55. package/test/comprehensive.js +4 -3
  56. package/test/error-handling.js +49 -0
  57. package/test/new-features.js +52 -0
  58. 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');
@@ -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
- const origSeq = orig.floats(3);
64
+ orig.floats(3);
65
65
  const cloned = cloneGenerator(orig);
66
- const clonedSeq = cloned.floats(3);
67
- console.log(` Clone has same sequence: ${JSON.stringify(origSeq) === JSON.stringify(clonedSeq)}`);
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