@cloudglides/nox 1.1.6 → 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 (57) hide show
  1. package/README.md +9 -9
  2. package/example/src/App.css +38 -7
  3. package/example/src/App.jsx +328 -25
  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 -1
  16. package/src/rng.browser.js +5 -6
  17. package/src/rng.js +95 -94
  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.js +4 -3
  55. package/test/new-features.js +52 -0
  56. package/IMPROVEMENTS.md +0 -58
  57. package/PERFORMANCE.md +0 -69
@@ -1,29 +1,34 @@
1
1
  export class Logistic {
2
- constructor(seed = 0.5, r = 3.99) {
3
- if (typeof seed !== 'number' || seed < 0 || seed > 1) {
4
- throw new Error('seed must be between 0 and 1');
5
- }
6
- if (typeof r !== 'number' || r <= 0 || r > 4) {
7
- throw new Error('r must be between 0 and 4');
8
- }
9
- this.x = seed;
10
- this.r = r;
11
- }
12
-
13
- next() {
14
- this.x = this.r * this.x * (1 - this.x);
15
- return this.x;
16
- }
17
-
18
- nextInt(max = 2147483647) {
19
- if (max <= 0) {
20
- throw new Error('max must be positive');
21
- }
22
- if (!Number.isInteger(max)) {
23
- throw new TypeError('max must be an integer');
24
- }
25
- return Math.floor(this.next() * max);
26
- }
2
+ constructor(seed = 0.5, r = 3.99) {
3
+ if (typeof seed !== 'number' || seed < 0 || seed > 1) {
4
+ throw new Error('seed must be between 0 and 1');
5
+ }
6
+ if (typeof r !== 'number' || r <= 0 || r > 4) {
7
+ throw new Error('r must be between 0 and 4');
8
+ }
9
+ this.x = seed;
10
+ this.r = r;
11
+ }
12
+
13
+ next() {
14
+ this.x = this.r * this.x * (1 - this.x);
15
+ return this.x;
16
+ }
17
+
18
+ nextInt(max = 2147483647) {
19
+ if (typeof max !== 'number' || !Number.isInteger(max)) {
20
+ throw new TypeError('max must be an integer');
21
+ }
22
+ if (max <= 0) {
23
+ throw new RangeError('max must be positive');
24
+ }
25
+ const limit = Math.floor(1 / max) * max;
26
+ let val;
27
+ do {
28
+ val = Math.floor(this.next() * Number.MAX_SAFE_INTEGER);
29
+ } while (val >= limit);
30
+ return val % max;
31
+ }
27
32
 
28
33
  nextFloat() {
29
34
  return this.next();
@@ -24,12 +24,12 @@ export class Mixer {
24
24
  }
25
25
 
26
26
  nextInt(max = 2147483647) {
27
- if (max <= 0) {
28
- throw new Error('max must be positive');
29
- }
30
- if (!Number.isInteger(max)) {
31
- throw new TypeError('max must be an integer');
32
- }
27
+ if (typeof max !== 'number' || !Number.isInteger(max)) {
28
+ throw new TypeError('max must be an integer');
29
+ }
30
+ if (max <= 0) {
31
+ throw new RangeError('max must be positive');
32
+ }
33
33
 
34
34
  const v1 = this.rng1.nextInt(max);
35
35
  const v2 = this.rng2.nextInt(max);
@@ -39,6 +39,6 @@ export class Mixer {
39
39
  nextFloat() {
40
40
  const f1 = this.rng1.nextFloat();
41
41
  const f2 = this.rng2.nextFloat();
42
- return Math.abs(f1 - f2);
42
+ return Math.abs(f1 - f2) % 1.0;
43
43
  }
44
44
  }
@@ -1,5 +1,8 @@
1
1
  export class MT19937 {
2
2
  constructor(seed = 5489) {
3
+ if (typeof seed !== 'number' && typeof seed !== 'bigint') {
4
+ throw new TypeError('Seed must be a number or bigint');
5
+ }
3
6
  this.N = 624;
4
7
  this.M = 397;
5
8
  this.MATRIX_A = 0x9908b0df;
@@ -52,13 +55,13 @@ export class MT19937 {
52
55
  }
53
56
 
54
57
  nextInt(max = 2147483647) {
55
- if (max <= 0) {
56
- throw new Error('max must be positive');
57
- }
58
-
59
- if (max < 65536) {
60
- return this.next() & 0xFFFF % max;
61
- }
58
+ if (max <= 0) {
59
+ throw new Error('max must be positive');
60
+ }
61
+
62
+ if (max < 65536) {
63
+ return (this.next() & 0xFFFF) % max;
64
+ }
62
65
 
63
66
  const limit = Math.floor((0x100000000 / max)) * max;
64
67
  let val;
@@ -1,11 +1,17 @@
1
1
  export class PCG64 {
2
- constructor(seed = 1n, inc = 1n) {
3
- this.state = 0n;
4
- this.inc = ((typeof inc === 'number' ? BigInt(inc) : inc) << 1n) | 1n;
5
- this.step();
6
- this.state += (typeof seed === 'number' ? BigInt(seed) : seed);
7
- this.step();
8
- }
2
+ constructor(seed = 1n, inc = 1n) {
3
+ if (typeof seed !== 'number' && typeof seed !== 'bigint') {
4
+ throw new TypeError('Seed must be a number or bigint');
5
+ }
6
+ if (typeof inc !== 'number' && typeof inc !== 'bigint') {
7
+ throw new TypeError('inc must be a number or bigint');
8
+ }
9
+ this.state = 0n;
10
+ this.inc = ((typeof inc === 'number' ? BigInt(inc) : inc) << 1n) | 1n;
11
+ this.step();
12
+ this.state += (typeof seed === 'number' ? BigInt(seed) : seed);
13
+ this.step();
14
+ }
9
15
 
10
16
  step() {
11
17
  this.state = (this.state * 6364136223846793005n + this.inc) & ((1n << 64n) - 1n);
@@ -15,17 +21,22 @@ export class PCG64 {
15
21
  const oldState = this.state;
16
22
  this.step();
17
23
 
18
- const xorShifted = ((oldState >> 18n) ^ oldState) >> 27n;
24
+ const M = 0x2545F4914F6CDD1Dn;
25
+ const x = (oldState >> 18n) ^ oldState;
19
26
  const rot = oldState >> 59n;
20
- const result = (xorShifted >> rot) | ((xorShifted << (64n - rot)) & ((1n << 64n) - 1n));
27
+ const rotated = (x >> rot) | ((x << (64n - rot)) & ((1n << 64n) - 1n));
28
+ const result = ((rotated * M) & ((1n << 64n) - 1n)) ^ (rotated >> 29n);
21
29
 
22
30
  return result;
23
31
  }
24
32
 
25
33
  nextInt(max = 2147483647) {
26
- if (max <= 0) {
27
- throw new Error('max must be positive');
28
- }
34
+ if (typeof max !== 'number' || !Number.isInteger(max)) {
35
+ throw new TypeError('max must be an integer');
36
+ }
37
+ if (max <= 0) {
38
+ throw new RangeError('max must be positive');
39
+ }
29
40
 
30
41
  if (max < 65536) {
31
42
  return Number(this.next() & 0xFFFFn) % max;
@@ -1,7 +1,10 @@
1
1
  export class Splitmix64 {
2
- constructor(seed = 1) {
3
- this.state = BigInt(seed);
4
- }
2
+ constructor(seed = 1) {
3
+ if (typeof seed !== 'number' && typeof seed !== 'bigint') {
4
+ throw new TypeError('Seed must be a number or bigint');
5
+ }
6
+ this.state = BigInt(seed);
7
+ }
5
8
 
6
9
  next() {
7
10
  let z = (this.state += 0x9e3779b97f4a7c15n);
@@ -11,9 +14,12 @@ export class Splitmix64 {
11
14
  }
12
15
 
13
16
  nextInt(max = 2147483647) {
14
- if (max <= 0) {
15
- throw new Error('max must be positive');
16
- }
17
+ if (typeof max !== 'number' || !Number.isInteger(max)) {
18
+ throw new TypeError('max must be an integer');
19
+ }
20
+ if (max <= 0) {
21
+ throw new RangeError('max must be positive');
22
+ }
17
23
 
18
24
  if (max < 65536) {
19
25
  return Number(this.next() & 0xFFFFn) % max;
@@ -21,13 +21,18 @@ export class Tent {
21
21
  }
22
22
 
23
23
  nextInt(max = 2147483647) {
24
- if (max <= 0) {
25
- throw new Error('max must be positive');
26
- }
27
- if (!Number.isInteger(max)) {
28
- throw new TypeError('max must be an integer');
29
- }
30
- return Math.floor(this.next() * max);
24
+ if (typeof max !== 'number' || !Number.isInteger(max)) {
25
+ throw new TypeError('max must be an integer');
26
+ }
27
+ if (max <= 0) {
28
+ throw new RangeError('max must be positive');
29
+ }
30
+ const limit = Math.floor(1 / max) * max;
31
+ let val;
32
+ do {
33
+ val = Math.floor(this.next() * Number.MAX_SAFE_INTEGER);
34
+ } while (val >= limit);
35
+ return val % max;
31
36
  }
32
37
 
33
38
  nextFloat() {
@@ -17,9 +17,12 @@ export class Xorshift64 {
17
17
  }
18
18
 
19
19
  nextInt(max = 2147483647) {
20
- if (max <= 0) {
21
- throw new Error('max must be positive');
22
- }
20
+ if (typeof max !== 'number' || !Number.isInteger(max)) {
21
+ throw new TypeError('max must be an integer');
22
+ }
23
+ if (max <= 0) {
24
+ throw new RangeError('max must be positive');
25
+ }
23
26
 
24
27
  if (max < 65536) {
25
28
  return Number(this.next() & 0xFFFFn) % max;
package/src/index.d.ts CHANGED
@@ -29,10 +29,16 @@ export function normal(rng: RNG | IGenerator, mean?: number, stddev?: number): n
29
29
  export function exponential(rng: RNG | IGenerator, lambda?: number): number;
30
30
  export function uniform(rng: RNG | IGenerator, min: number, max: number): number;
31
31
  export function poisson(rng: RNG | IGenerator, lambda: number): number;
32
+ export function normals(rng: RNG | IGenerator, count: number, mean?: number, stddev?: number): number[];
33
+ export function exponentials(rng: RNG | IGenerator, count: number, lambda?: number): number[];
32
34
 
33
35
  export function shuffle<T>(arr: T[], rng: RNG | IGenerator, inPlace?: boolean): T[];
34
36
  export function pick<T>(arr: T[], rng: RNG | IGenerator): T;
35
37
  export function sample<T>(arr: T[], count: number, rng: RNG | IGenerator): T[];
38
+ export function sampleWithReplacement<T>(arr: T[], count: number, rng: RNG | IGenerator): T[];
39
+ export function permute<T>(arr: T[], rng: RNG | IGenerator): T[];
40
+ export function range(start: number, end: number, step?: number): number[];
41
+ export function cycle<T>(arr: T[], count: number): T[];
36
42
 
37
43
  export function saveState(rng: RNG): any;
38
44
  export function restoreState(rng: RNG, snapshot: any): void;
@@ -63,6 +69,10 @@ export interface KSTestResult {
63
69
  export function meanTest(data: number[], expectedMean?: number): TestResult;
64
70
  export function varianceTest(data: number[], expectedVariance?: number): TestResult;
65
71
  export function kolmogorovSmirnovTest(data: number[]): KSTestResult;
72
+ export function skewness(data: number[]): number;
73
+ export function kurtosis(data: number[]): number;
74
+ export function median(data: number[]): number;
75
+ export function quantile(data: number[], q: number): number;
66
76
 
67
77
  export class Xorshift64 {
68
78
  constructor(seed?: number | bigint);
@@ -107,8 +117,62 @@ export class Tent {
107
117
  }
108
118
 
109
119
  export class Mixer {
110
- constructor(rng1: any, rng2: any);
111
- next(): bigint;
112
- nextInt(max?: number): number;
113
- nextFloat(): number;
120
+ constructor(rng1: IGenerator, rng2: IGenerator);
121
+ next(): bigint;
122
+ nextInt(max?: number): number;
123
+ nextFloat(): number;
114
124
  }
125
+
126
+ export function beta(rng: RNG | IGenerator, alpha: number, beta: number): number;
127
+ export function gamma(rng: RNG | IGenerator, shape: number, scale?: number): number;
128
+ export function chi2(rng: RNG | IGenerator, k: number): number;
129
+ export function binomial(rng: RNG | IGenerator, n: number, p: number): number;
130
+ export function geometric(rng: RNG | IGenerator, p: number): number;
131
+ export function weibull(rng: RNG | IGenerator, shape: number, scale?: number): number;
132
+ export function lognormal(rng: RNG | IGenerator, mu: number, sigma: number): number;
133
+ export function rayleigh(rng: RNG | IGenerator, sigma?: number): number;
134
+ export function cauchy(rng: RNG | IGenerator, median?: number, scale?: number): number;
135
+
136
+ export function brownianMotion(rng: RNG | IGenerator, steps: number, dt?: number): number[];
137
+ export function ornsteinUhlenbeck(rng: RNG | IGenerator, steps: number, theta?: number, mu?: number, sigma?: number): number[];
138
+ export function geometricBrownian(rng: RNG | IGenerator, steps: number, mu?: number, sigma?: number, dt?: number): number[];
139
+
140
+ export function perlin2D(rng: RNG | IGenerator, x: number, y: number, octaves?: number): number;
141
+ export function valueNoise(rng: RNG | IGenerator, x: number, y: number, scale?: number): number;
142
+
143
+ export function categorical<T>(rng: RNG | IGenerator, categories: T[], probabilities: number[]): T;
144
+ export function multinomial(rng: RNG | IGenerator, n: number, categories: any[], probabilities: number[]): Record<string, number>;
145
+ export function categorical2D(rng: RNG | IGenerator, matrix: number[][]): [number, number];
146
+
147
+ export function combinations<T>(arr: T[], k: number): T[][];
148
+ export function permutations<T>(arr: T[]): T[][];
149
+ export function kPermutations<T>(arr: T[], k: number): T[][];
150
+ export function randomCombination<T>(arr: T[], k: number, rng: RNG | IGenerator): T[];
151
+ export function randomPermutation<T>(arr: T[], rng: RNG | IGenerator): T[];
152
+
153
+ export function rotateBits(val: bigint, shift: number | bigint): bigint;
154
+ export function extractBits(val: bigint, start: number, length: number): bigint;
155
+ export function hammingWeight(val: bigint): number;
156
+ export function bitRange(val: bigint, min: number, max: number): bigint;
157
+ export function popcountNum(val: number): number;
158
+ export function clz(val: bigint): number;
159
+ export function ctz(val: bigint): number;
160
+ export function reverseBits(val: bigint, width?: number): bigint;
161
+ export function setBit(val: bigint, pos: number): bigint;
162
+ export function clearBit(val: bigint, pos: number): bigint;
163
+ export function toggleBit(val: bigint, pos: number): bigint;
164
+
165
+ export class SeedSequence {
166
+ constructor(entropy?: null | string | number | bigint);
167
+ next(): bigint;
168
+ spawn(n?: number): bigint[];
169
+ }
170
+
171
+ export function seedMultiple(rngClasses: (new (seed?: number | bigint) => IGenerator)[], entropy?: null | string | number | bigint): IGenerator[];
172
+ export function seedFromTime(): bigint;
173
+ export function seedFromEntropy(entropy: string): bigint;
174
+
175
+ export function chiSquareTest(data: number[], bins?: number): { chi2: number; expected: number; histogram: number[] };
176
+ export function entropy(data: number[], bins?: number): number;
177
+ export function autocorrelation(data: number[], lag: number): number;
178
+ export function runTest(data: number[], threshold?: number): number;
package/src/index.js CHANGED
@@ -6,9 +6,15 @@ export {
6
6
  exponential,
7
7
  uniform,
8
8
  poisson,
9
+ normals,
10
+ exponentials,
9
11
  shuffle,
10
12
  pick,
11
13
  sample,
14
+ sampleWithReplacement,
15
+ permute,
16
+ range,
17
+ cycle,
12
18
  saveState,
13
19
  restoreState,
14
20
  cloneGenerator,
@@ -17,7 +23,154 @@ export {
17
23
  reservoirSample,
18
24
  meanTest,
19
25
  varianceTest,
20
- kolmogorovSmirnovTest
26
+ kolmogorovSmirnovTest,
27
+ skewness,
28
+ kurtosis,
29
+ median,
30
+ quantile,
31
+ beta,
32
+ gamma,
33
+ chi2,
34
+ binomial,
35
+ geometric,
36
+ weibull,
37
+ lognormal,
38
+ rayleigh,
39
+ cauchy,
40
+ dirichlet,
41
+ dirichlets,
42
+ mixture,
43
+ mixtures,
44
+ studentT,
45
+ studentTs,
46
+ betaBinomial,
47
+ brownianMotion,
48
+ ornsteinUhlenbeck,
49
+ geometricBrownian,
50
+ categorical,
51
+ multinomial,
52
+ categorical2D,
53
+ perlin2D,
54
+ valueNoise,
55
+ combinations,
56
+ permutations,
57
+ kPermutations,
58
+ randomCombination,
59
+ randomPermutation,
60
+ rotateBits,
61
+ extractBits,
62
+ hammingWeight,
63
+ bitRange,
64
+ popcountNum,
65
+ clz,
66
+ ctz,
67
+ reverseBits,
68
+ setBit,
69
+ clearBit,
70
+ toggleBit,
71
+ SeedSequence,
72
+ seedMultiple,
73
+ seedFromTime,
74
+ seedFromEntropy,
75
+ repeat,
76
+ until,
77
+ times,
78
+ chiSquareTest,
79
+ entropy,
80
+ autocorrelation,
81
+ runTest,
82
+ clearCryptoCache,
83
+ combined,
84
+ bootstrap,
85
+ jackknife,
86
+ crossValidation,
87
+ permutationTest,
88
+ stratifiedSample,
89
+ stratifiedSampleProportional,
90
+ stratify,
91
+ cdf,
92
+ ppf,
93
+ sf,
94
+ WeightedDistribution,
95
+ CategoricalDistribution,
96
+ NormalDistribution,
97
+ bootstrapCI,
98
+ meanCI,
99
+ proportionCI,
100
+ cohensD,
101
+ hedgesG,
102
+ correlation,
103
+ cramersV,
104
+ etaSquared,
105
+ glasssDelta,
106
+ sum,
107
+ mean,
108
+ min,
109
+ max,
110
+ unique,
111
+ chunk,
112
+ flatten,
113
+ zip,
114
+ transpose,
115
+ partition,
116
+ tTest,
117
+ welchTTest,
118
+ mannWhitneyU,
119
+ oneWayAnova,
120
+ zscore,
121
+ standardize,
122
+ minMaxScale,
123
+ logTransform,
124
+ sqrtTransform,
125
+ rank,
126
+ robustScale,
127
+ LinearRegression,
128
+ MultipleRegression,
129
+ diff,
130
+ lag,
131
+ shift,
132
+ sma,
133
+ ema,
134
+ acf,
135
+ pacf,
136
+ matrixAdd,
137
+ matrixSub,
138
+ matrixMul,
139
+ elementwiseMul,
140
+ scalarMul,
141
+ determinant,
142
+ trace,
143
+ norm,
144
+ inverse as matrixInverse,
145
+ trapezoidal,
146
+ simpsons,
147
+ adaptiveSimpson,
148
+ gaussQuadrature,
149
+ numericalDerivative,
150
+ numericalSecondDerivative,
151
+ LinearInterpolator,
152
+ CubicSplineInterpolator,
153
+ lagrangeInterpolation,
154
+ polynomialFit,
155
+ bisection,
156
+ newtonRaphson,
157
+ secant,
158
+ falsePosition,
159
+ fixedPoint,
160
+ eulerMethod,
161
+ rk4,
162
+ systemEuler,
163
+ systemRK4,
164
+ rk45Adaptive,
165
+ svd,
166
+ qr,
167
+ cholesky,
168
+ lu,
169
+ gradientDescent,
170
+ momentumDescent,
171
+ adam,
172
+ simplex,
173
+ brent
21
174
  } from './core.js';
22
175
 
23
176
  export {
@@ -36,8 +36,7 @@ export class RNG {
36
36
  }
37
37
  if (min > max) [min, max] = [max, min];
38
38
  const range = max - min + 1;
39
- let val = Math.floor(this.nextFloat() * range);
40
- return val + min;
39
+ return min + this.nextInt(range);
41
40
  }
42
41
 
43
42
  bool(probability = 0.5) {
@@ -55,13 +54,13 @@ export class RNG {
55
54
  throw new TypeError('min, max, and step must be numbers');
56
55
  }
57
56
  if (!Number.isInteger(min) || !Number.isInteger(max) || !Number.isInteger(step)) {
58
- throw new Error('min, max, and step must be integers');
57
+ throw new TypeError('min, max, and step must be integers');
59
58
  }
60
59
  if (step <= 0) {
61
- throw new Error('step must be positive');
60
+ throw new RangeError('step must be positive');
62
61
  }
63
62
  if (min > max) {
64
- throw new Error('min must be less than or equal to max');
63
+ throw new RangeError('min must be less than or equal to max');
65
64
  }
66
65
 
67
66
  const count = Math.floor((max - min) / step) + 1;
@@ -75,7 +74,7 @@ export class RNG {
75
74
  }
76
75
  const len = arr.length;
77
76
  if (len === 0) {
78
- throw new TypeError('choice() requires non-empty array');
77
+ throw new RangeError('choice() requires non-empty array');
79
78
  }
80
79
  return arr[this.nextInt(len)];
81
80
  }