@cloudglides/nox 1.1.6 → 3.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 (66) hide show
  1. package/README.md +9 -9
  2. package/example/package.json +1 -1
  3. package/example/src/App.css +38 -7
  4. package/example/src/App.jsx +328 -25
  5. package/package.json +7 -6
  6. package/pnpm-workspace.yaml +3 -0
  7. package/src/core.browser.js +37 -4
  8. package/src/core.js +37 -4
  9. package/src/generators/logistic.js +30 -25
  10. package/src/generators/mixer.js +7 -7
  11. package/src/generators/mt19937.js +10 -7
  12. package/src/generators/pcg64.js +23 -12
  13. package/src/generators/splitmix64.js +12 -6
  14. package/src/generators/tent.js +12 -7
  15. package/src/generators/xorshift64.js +6 -3
  16. package/src/index.browser.js +168 -1
  17. package/src/index.d.ts +68 -4
  18. package/src/index.js +169 -1
  19. package/src/rng.browser.js +5 -6
  20. package/src/rng.js +95 -94
  21. package/src/utils/arrays.js +149 -0
  22. package/src/utils/bits.js +146 -21
  23. package/src/utils/categorical.js +68 -31
  24. package/src/utils/clustering.js +143 -0
  25. package/src/utils/combinatorics.js +113 -69
  26. package/src/utils/confidence.js +145 -0
  27. package/src/utils/decomposition.js +204 -0
  28. package/src/utils/diagnostics.js +309 -0
  29. package/src/utils/distributions-advanced.js +122 -0
  30. package/src/utils/distributions-extra.js +102 -11
  31. package/src/utils/distributions-special.js +77 -20
  32. package/src/utils/distributions.js +99 -35
  33. package/src/utils/effects.js +172 -0
  34. package/src/utils/entropy.browser.js +29 -26
  35. package/src/utils/entropy.js +18 -8
  36. package/src/utils/helpers.js +64 -0
  37. package/src/utils/hypothesis.js +167 -0
  38. package/src/utils/integration.js +137 -0
  39. package/src/utils/interpolation.js +221 -0
  40. package/src/utils/logistic.js +91 -0
  41. package/src/utils/matrix.js +242 -0
  42. package/src/utils/noise.js +36 -22
  43. package/src/utils/odesolvers.js +176 -0
  44. package/src/utils/optimization.js +215 -0
  45. package/src/utils/polynomial.js +136 -0
  46. package/src/utils/precomputed.js +166 -0
  47. package/src/utils/probability.js +199 -0
  48. package/src/utils/pvalues.js +142 -0
  49. package/src/utils/regression.js +170 -0
  50. package/src/utils/resampling.js +112 -0
  51. package/src/utils/rootfinding.js +158 -0
  52. package/src/utils/sampling.js +86 -77
  53. package/src/utils/seed.js +10 -4
  54. package/src/utils/seeding.js +24 -12
  55. package/src/utils/sequence.js +116 -32
  56. package/src/utils/state.js +48 -36
  57. package/src/utils/statistics.js +64 -2
  58. package/src/utils/stochastic.js +91 -31
  59. package/src/utils/stratified.js +108 -0
  60. package/src/utils/timeseries.js +166 -0
  61. package/src/utils/transforms.js +146 -0
  62. package/test/comprehensive.js +4 -3
  63. package/test/new-features.js +52 -0
  64. package/IMPROVEMENTS.md +0 -58
  65. package/PERFORMANCE.md +0 -69
  66. package/example/pnpm-lock.yaml +0 -1006
package/README.md CHANGED
@@ -5,13 +5,13 @@ Simple, unpredictable random number generator.
5
5
  ## Install
6
6
 
7
7
  ```bash
8
- npm install nox
8
+ npm install @cloudglides/nox
9
9
  ```
10
10
 
11
11
  ## Quick Start
12
12
 
13
13
  ```javascript
14
- import { rng, deterministic } from 'nox';
14
+ import { rng, deterministic } from '@cloudglides/nox';
15
15
 
16
16
  const r = rng();
17
17
 
@@ -31,7 +31,7 @@ r.bools(5); // [true, false, true, ...]
31
31
  ## Reproducible
32
32
 
33
33
  ```javascript
34
- import { deterministic } from 'nox';
34
+ import { deterministic } from '@cloudglides/nox';
35
35
 
36
36
  const r = deterministic(42);
37
37
  // Always same sequence
@@ -40,7 +40,7 @@ const r = deterministic(42);
40
40
  ## Distributions
41
41
 
42
42
  ```javascript
43
- import { rng, normal, exponential, uniform, poisson } from 'nox';
43
+ import { rng, normal, exponential, uniform, poisson } from '@cloudglides/nox';
44
44
 
45
45
  const r = rng();
46
46
 
@@ -53,7 +53,7 @@ poisson(r, lambda=5);
53
53
  ## Sampling
54
54
 
55
55
  ```javascript
56
- import { rng, shuffle, pick, sample } from 'nox';
56
+ import { rng, shuffle, pick, sample } from '@cloudglides/nox';
57
57
 
58
58
  const r = rng();
59
59
 
@@ -65,7 +65,7 @@ sample([1, 2, 3, 4, 5], 3, r);
65
65
  ## State
66
66
 
67
67
  ```javascript
68
- import { rng, saveState, restoreState } from 'nox';
68
+ import { rng, saveState, restoreState } from '@cloudglides/nox';
69
69
 
70
70
  const r = rng();
71
71
  const snapshot = saveState(r);
@@ -78,7 +78,7 @@ r.nextFloat(); // Same value
78
78
  ## Weighted Sampling
79
79
 
80
80
  ```javascript
81
- import { rng, weightedPick, reservoirSample } from 'nox';
81
+ import { rng, weightedPick, reservoirSample } from '@cloudglides/nox';
82
82
 
83
83
  const r = rng();
84
84
  const items = ['A', 'B', 'C'];
@@ -91,7 +91,7 @@ reservoirSample(stream, k, r); // Sample k from large stream
91
91
  ## Statistical Tests
92
92
 
93
93
  ```javascript
94
- import { rng, meanTest, varianceTest, kolmogorovSmirnovTest } from 'nox';
94
+ import { rng, meanTest, varianceTest, kolmogorovSmirnovTest } from '@cloudglides/nox';
95
95
 
96
96
  const r = rng();
97
97
  const data = r.floats(1000);
@@ -106,7 +106,7 @@ const ks = kolmogorovSmirnovTest(data); // Test uniform distribution
106
106
  For reproducible results or specific generator properties:
107
107
 
108
108
  ```javascript
109
- import { RNG, PCG64, MT19937, Xorshift64, Splitmix64 } from 'nox';
109
+ import { RNG, PCG64, MT19937, Xorshift64, Splitmix64 } from '@cloudglides/nox';
110
110
 
111
111
  const r = new RNG(PCG64, seed); // PCG64 (default, fast, high quality)
112
112
  const r = new RNG(MT19937, seed); // MT19937 (Mersenne Twister)
@@ -9,7 +9,7 @@
9
9
  "preview": "vite preview"
10
10
  },
11
11
  "dependencies": {
12
- "@cloudglides/nox": "^1.1.3",
12
+ "@cloudglides/nox": "workspace:*",
13
13
  "react": "^18.2.0",
14
14
  "react-dom": "^18.2.0"
15
15
  },
@@ -26,11 +26,34 @@ header p {
26
26
  font-size: 0.95rem;
27
27
  }
28
28
 
29
+ .tabs-container {
30
+ padding: 1.5rem 2rem;
31
+ border-bottom: 1px solid #eee;
32
+ max-width: 1200px;
33
+ margin: 0 auto;
34
+ width: 100%;
35
+ }
36
+
37
+ .category {
38
+ margin-bottom: 1.5rem;
39
+ }
40
+
41
+ .category:last-child {
42
+ margin-bottom: 0;
43
+ }
44
+
45
+ .category h3 {
46
+ font-size: 0.9rem;
47
+ font-weight: 600;
48
+ color: #666;
49
+ margin: 0 0 0.6rem 0;
50
+ text-transform: uppercase;
51
+ letter-spacing: 0.5px;
52
+ }
53
+
29
54
  .tabs {
30
55
  display: flex;
31
56
  gap: 0.5rem;
32
- padding: 1.5rem 2rem;
33
- border-bottom: 1px solid #eee;
34
57
  flex-wrap: wrap;
35
58
  }
36
59
 
@@ -39,7 +62,7 @@ header p {
39
62
  border: 1px solid #000;
40
63
  background: #fff;
41
64
  cursor: pointer;
42
- font-size: 0.9rem;
65
+ font-size: 0.85rem;
43
66
  font-weight: 500;
44
67
  transition: 0.15s;
45
68
  }
@@ -56,7 +79,7 @@ header p {
56
79
  .content {
57
80
  flex: 1;
58
81
  padding: 2rem;
59
- max-width: 600px;
82
+ max-width: 800px;
60
83
  margin: 0 auto;
61
84
  width: 100%;
62
85
  }
@@ -84,7 +107,7 @@ header p {
84
107
 
85
108
  .result-row .label {
86
109
  font-weight: 600;
87
- min-width: 110px;
110
+ min-width: 140px;
88
111
  color: #333;
89
112
  }
90
113
 
@@ -118,14 +141,22 @@ footer a:hover {
118
141
  font-size: 1.8rem;
119
142
  }
120
143
 
121
- .tabs {
144
+ .tabs-container {
122
145
  padding: 1rem;
146
+ }
147
+
148
+ .category h3 {
149
+ font-size: 0.8rem;
150
+ margin-bottom: 0.4rem;
151
+ }
152
+
153
+ .tabs {
123
154
  gap: 0.3rem;
124
155
  }
125
156
 
126
157
  .tabs button {
127
158
  padding: 0.4rem 0.8rem;
128
- font-size: 0.85rem;
159
+ font-size: 0.75rem;
129
160
  }
130
161
 
131
162
  .content {
@@ -1,5 +1,24 @@
1
1
  import { useState } from 'react'
2
- import { rng, deterministic, normal, exponential } from '@cloudglides/nox'
2
+ import {
3
+ rng, deterministic, normal, exponential, poisson, uniform,
4
+ shuffle, sample, pick, weightedPick,
5
+ meanTest, varianceTest, kolmogorovSmirnovTest,
6
+ cohensD, correlation, cramersV,
7
+ bootstrapCI, meanCI,
8
+ tTest, welchTTest, oneWayAnova,
9
+ LinearRegression, MultipleRegression,
10
+ diff, lag, sma, ema, acf,
11
+ matrixAdd, matrixMul, determinant, matrixInverse,
12
+ trapezoidal, simpsons, numericalDerivative,
13
+ LinearInterpolator, CubicSplineInterpolator,
14
+ bisection, newtonRaphson, brent,
15
+ rk4,
16
+ svd, qr, cholesky,
17
+ zscore, standardize, minMaxScale,
18
+ sum, mean, min, max, unique,
19
+ dirichlet, mixture,
20
+ gradientDescent, adam
21
+ } from '@cloudglides/nox'
3
22
  import './App.css'
4
23
 
5
24
  const FORMAT = (n) => typeof n === 'number' ? n.toFixed(4) : n
@@ -8,7 +27,7 @@ export default function App() {
8
27
  const [results, setResults] = useState(null)
9
28
 
10
29
  const handlers = {
11
- basic: () => {
30
+ basics: () => {
12
31
  const r = rng()
13
32
  setResults({
14
33
  title: 'Basic Operations',
@@ -16,60 +35,344 @@ export default function App() {
16
35
  ['nextFloat', FORMAT(r.nextFloat())],
17
36
  ['int(1-100)', r.int(1, 100)],
18
37
  ['bool(0.5)', r.bool(0.5) ? 'true' : 'false'],
19
- ['choice', r.choice(['', '🎲', '', '🔮'])]
38
+ ['choice', r.choice(['A', 'B', 'C', 'D'])],
39
+ ['range(1-10, step 2)', r.range(1, 10, 2).join(', ')]
20
40
  ]
21
41
  })
22
42
  },
23
43
 
24
- batch: () => {
44
+ distributions: () => {
25
45
  const r = rng()
46
+ const normals = Array.from({length: 5}, () => FORMAT(normal(r)))
47
+ const exponentials = Array.from({length: 5}, () => FORMAT(exponential(r)))
48
+ const dir = dirichlet(r, [1, 2, 3]).map(FORMAT)
26
49
  setResults({
27
- title: 'Batch Operations',
50
+ title: 'Distributions',
28
51
  data: [
29
- ['floats(10)', r.floats(10).map(FORMAT).join(', ')],
30
- ['ints(10, 100)', r.ints(10, 100).join(', ')],
31
- ['bools(10)', r.bools(10).join(', ')]
52
+ ['normal(5)', normals.join(', ')],
53
+ ['exponential(5)', exponentials.join(', ')],
54
+ ['poisson(λ=3)', [poisson(r, 3), poisson(r, 3), poisson(r, 3)].join(', ')],
55
+ ['dirichlet[1,2,3]', dir.join(', ')]
32
56
  ]
33
57
  })
34
58
  },
35
59
 
36
- distributions: () => {
60
+ sampling: () => {
37
61
  const r = rng()
62
+ const arr = [1, 2, 3, 4, 5]
63
+ const weights = [0.1, 0.2, 0.3, 0.2, 0.2]
38
64
  setResults({
39
- title: 'Distributions',
65
+ title: 'Sampling Methods',
40
66
  data: [
41
- ['normal(5)', Array.from({length: 5}, () => FORMAT(normal(r))).join(', ')],
42
- ['exponential(5)', Array.from({length: 5}, () => FORMAT(exponential(r))).join(', ')]
67
+ ['shuffle', shuffle(arr, r).join(', ')],
68
+ ['sample(3)', sample(arr, 3, r).join(', ')],
69
+ ['pick', pick(arr, r)],
70
+ ['weightedPick', weightedPick(arr, weights, r)],
71
+ ['unique', unique([1, 2, 2, 3, 3, 3]).join(', ')]
43
72
  ]
44
73
  })
45
74
  },
46
75
 
47
- deterministic: () => {
48
- const r1 = deterministic(42)
49
- const r2 = deterministic(42)
76
+ statistics: () => {
77
+ const r = rng()
78
+ const data = r.floats(100).map(x => x * 10)
79
+ const mean_val = mean(data)
80
+ const std = Math.sqrt(data.reduce((s, x) => s + (x - mean_val) ** 2, 0) / data.length)
81
+
82
+ const data2 = r.floats(50).map(x => x * 8)
83
+ const d = cohensD(data, data2)
84
+ const corr = correlation(data.slice(0, 50), data2.slice(0, 50))
85
+
50
86
  setResults({
51
- title: 'Deterministic (seed=42)',
87
+ title: 'Statistics & Effect Sizes',
52
88
  data: [
53
- ['sequence 1', r1.floats(5).map(FORMAT).join(', ')],
54
- ['sequence 2', r2.floats(5).map(FORMAT).join(', ')],
55
- ['identical', 'YES ✓']
89
+ ['mean', FORMAT(mean_val)],
90
+ ['min', FORMAT(min(data))],
91
+ ['max', FORMAT(max(data))],
92
+ ["Cohen's d", FORMAT(d)],
93
+ ['correlation', FORMAT(corr)],
94
+ ['KS-test', FORMAT(kolmogorovSmirnovTest(data.map(x => x / 10)))]
95
+ ]
96
+ })
97
+ },
98
+
99
+ hypothesis: () => {
100
+ const r = rng()
101
+ const group1 = r.floats(30).map(x => 5 + x * 2)
102
+ const group2 = r.floats(30).map(x => 5.5 + x * 2)
103
+
104
+ const t_result = tTest(group1, group2)
105
+ const w_result = welchTTest(group1, group2)
106
+
107
+ const groups = [group1, group2]
108
+ const anova = oneWayAnova(groups)
109
+
110
+ setResults({
111
+ title: 'Hypothesis Testing',
112
+ data: [
113
+ ['t-test (t, df)', `${FORMAT(t_result.t)}, ${t_result.df}`],
114
+ ["Welch's t-test", FORMAT(w_result.t)],
115
+ ['ANOVA (F, df)', `${FORMAT(anova.f)}, ${anova.dfB}/${anova.dfW}`],
116
+ ['meanCI(group1)', `[${FORMAT(meanCI(group1, 1).lower)}, ${FORMAT(meanCI(group1, 1).upper)}]`]
117
+ ]
118
+ })
119
+ },
120
+
121
+ regression: () => {
122
+ const x = [1, 2, 3, 4, 5]
123
+ const y = [2.1, 3.9, 6.2, 7.8, 10.1]
124
+
125
+ const model = new LinearRegression(x, y)
126
+
127
+ const xMulti = [[1, 2], [2, 3], [3, 4], [4, 5]]
128
+ const yMulti = [2, 5, 9, 13]
129
+ const modelMulti = new MultipleRegression(xMulti, yMulti)
130
+
131
+ setResults({
132
+ title: 'Regression Models',
133
+ data: [
134
+ ['Linear: slope', FORMAT(model.slope)],
135
+ ['Linear: intercept', FORMAT(model.intercept)],
136
+ ['Linear: R²', FORMAT(model.rSquared)],
137
+ ['Linear: RMSE', FORMAT(model.rmse)],
138
+ ['Multiple R²', FORMAT(modelMulti.rSquared)],
139
+ ['Multiple adj-R²', FORMAT(modelMulti.adjRSquared)]
140
+ ]
141
+ })
142
+ },
143
+
144
+ timeseries: () => {
145
+ const r = rng()
146
+ const ts = Array.from({length: 20}, (_, i) => 10 + i * 0.5 + (r.nextFloat() - 0.5) * 2)
147
+
148
+ const diffed = diff(ts, 1)
149
+ const lagged = lag(ts, 2).slice(2)
150
+ const sma_vals = sma(ts, 3).filter(x => x !== null)
151
+ const ema_vals = ema(ts, 3)
152
+ const acf_vals = acf(ts, 5)
153
+
154
+ setResults({
155
+ title: 'Time Series Analysis',
156
+ data: [
157
+ ['original (first 5)', ts.slice(0, 5).map(FORMAT).join(', ')],
158
+ ['diff(order=1)', diffed.slice(0, 5).map(FORMAT).join(', ')],
159
+ ['SMA(window=3)', sma_vals.slice(0, 5).map(FORMAT).join(', ')],
160
+ ['EMA(window=3)', ema_vals.slice(0, 5).map(FORMAT).join(', ')],
161
+ ['ACF (lag 0-2)', acf_vals.slice(0, 3).map(FORMAT).join(', ')]
162
+ ]
163
+ })
164
+ },
165
+
166
+ matrix: () => {
167
+ const A = [[1, 2], [3, 4]]
168
+ const B = [[5, 6], [7, 8]]
169
+
170
+ const sum = matrixAdd(A, B)
171
+ const prod = matrixMul(A, B)
172
+ const det = determinant(A)
173
+ const inv = matrixInverse(A)
174
+
175
+ setResults({
176
+ title: 'Matrix Operations',
177
+ data: [
178
+ ['A+B[0][0]', FORMAT(sum[0][0])],
179
+ ['A*B[0][0]', FORMAT(prod[0][0])],
180
+ ['det(A)', FORMAT(det)],
181
+ ['inv(A)[0][1]', FORMAT(inv[0][1])],
182
+ ['trace(A)', FORMAT(1 + 4)]
183
+ ]
184
+ })
185
+ },
186
+
187
+ decomposition: () => {
188
+ const A = [[1, 2], [3, 4]]
189
+
190
+ const {U, S, VT} = svd(A, 10)
191
+ const {Q, R} = qr(A)
192
+
193
+ try {
194
+ const L = cholesky([[4, 2], [2, 3]])
195
+ setResults({
196
+ title: 'Matrix Decompositions',
197
+ data: [
198
+ ['SVD S[0]', FORMAT(S[0])],
199
+ ['SVD S[1]', FORMAT(S[1])],
200
+ ['QR R[0][0]', FORMAT(R[0][0])],
201
+ ['QR R[0][1]', FORMAT(R[0][1])],
202
+ ['Cholesky L[0][0]', FORMAT(L[0][0])],
203
+ ['Cholesky L[1][0]', FORMAT(L[1][0])]
204
+ ]
205
+ })
206
+ } catch {
207
+ setResults({
208
+ title: 'Matrix Decompositions',
209
+ data: [
210
+ ['SVD S[0]', FORMAT(S[0])],
211
+ ['QR R[0][0]', FORMAT(R[0][0])],
212
+ ['Cholesky', 'Not positive definite']
213
+ ]
214
+ })
215
+ }
216
+ },
217
+
218
+ integration: () => {
219
+ const f = (x) => Math.sin(x)
220
+ const a = 0, b = Math.PI
221
+
222
+ const trap = trapezoidal(f, a, b, 100)
223
+ const simp = simpsons(f, a, b, 100)
224
+ const deriv1 = numericalDerivative(f, 1)
225
+ const deriv2 = numericalDerivative(Math.cos, 0)
226
+
227
+ setResults({
228
+ title: 'Numerical Integration & Derivatives',
229
+ data: [
230
+ ['∫sin(x) [0,π] exact', '2.0000'],
231
+ ['∫sin(x) trapezoidal', FORMAT(trap)],
232
+ ['∫sin(x) Simpson', FORMAT(simp)],
233
+ ['d/dx sin(x) at x=1', FORMAT(deriv1)],
234
+ ['d/dx cos(x) at x=0', FORMAT(deriv2)]
235
+ ]
236
+ })
237
+ },
238
+
239
+ interpolation: () => {
240
+ const x = [0, 1, 2, 3, 4]
241
+ const y = [0, 1, 4, 9, 16]
242
+
243
+ const linear = new LinearInterpolator(x, y)
244
+ const cubic = new CubicSplineInterpolator(x, y)
245
+
246
+ const x_interp = 1.5
247
+ const y_linear = linear.evaluate(x_interp)
248
+ const y_cubic = cubic.evaluate(x_interp)
249
+
250
+ setResults({
251
+ title: 'Interpolation',
252
+ data: [
253
+ ['x points', x.join(', ')],
254
+ ['y points', y.join(', ')],
255
+ [`Linear at x=${x_interp}`, FORMAT(y_linear)],
256
+ [`Cubic spline at x=${x_interp}`, FORMAT(y_cubic)],
257
+ ['Expected (x²) at 1.5', FORMAT(1.5 * 1.5)]
258
+ ]
259
+ })
260
+ },
261
+
262
+ rootfinding: () => {
263
+ const f = (x) => x ** 2 - 4
264
+ const df = (x) => 2 * x
265
+
266
+ const bisect = bisection(f, 1, 3, 1e-6)
267
+ const newton = newtonRaphson(f, df, 3, 1e-6)
268
+ const brentResult = brent(f, 1, 3, 1e-6)
269
+
270
+ setResults({
271
+ title: 'Root Finding Methods',
272
+ data: [
273
+ ['f(x) = x² - 4, root is x=2'],
274
+ ['bisection: root', FORMAT(bisect.root)],
275
+ ['bisection: iterations', bisect.iterations],
276
+ ['Newton-Raphson: root', FORMAT(newton.root)],
277
+ ['Newton-Raphson: iterations', newton.iterations],
278
+ ['Brent: root', FORMAT(brentResult.root)],
279
+ ['Brent: iterations', brentResult.iterations]
280
+ ]
281
+ })
282
+ },
283
+
284
+ ode: () => {
285
+ const dydt = (t, y) => -y
286
+ const y0 = 1
287
+ const result = rk4(dydt, y0, 0, 2, 0.1)
288
+
289
+ const analytical = Math.exp(-2)
290
+
291
+ setResults({
292
+ title: 'ODE Solver (dy/dt = -y, y(0)=1)',
293
+ data: [
294
+ ['Solver method', 'RK4 (4th order)'],
295
+ ['Time steps', result.t.length],
296
+ ['t values', result.t.slice(0, 5).map(FORMAT).join(', ')],
297
+ ['y values', result.y.slice(0, 5).map(FORMAT).join(', ')],
298
+ ['y(2) numerical', FORMAT(result.y[result.y.length - 1])],
299
+ ['y(2) analytical', FORMAT(analytical)]
300
+ ]
301
+ })
302
+ },
303
+
304
+ transforms: () => {
305
+ const r = rng()
306
+ const data = r.floats(20).map(x => x * 10 + 5)
307
+
308
+ const z = zscore(data)
309
+ const std = standardize(data)
310
+ const scaled = minMaxScale(data)
311
+
312
+ setResults({
313
+ title: 'Data Transformations',
314
+ data: [
315
+ ['original: mean', FORMAT(mean(data))],
316
+ ['original: min', FORMAT(min(data))],
317
+ ['original: max', FORMAT(max(data))],
318
+ ['z-score: mean', FORMAT(mean(z).toFixed(10))],
319
+ ['z-score: std', FORMAT(Math.sqrt(z.reduce((s, x) => s + x * x, 0) / z.length))],
320
+ ['minmax: min', FORMAT(min(scaled))],
321
+ ['minmax: max', FORMAT(max(scaled))]
322
+ ]
323
+ })
324
+ },
325
+
326
+ optimization: () => {
327
+ const f = (x) => (x - 3) ** 2 + 2
328
+ const df = (x) => 2 * (x - 3)
329
+
330
+ const gd = gradientDescent(f, df, 0, 0.1, 100, 1e-6)
331
+ const adamResult = adam(f, df, 0, 0.1, 100, 0.9, 0.999, 1e-8, 1e-6)
332
+
333
+ setResults({
334
+ title: 'Optimization Methods',
335
+ data: [
336
+ ['Minimize: f(x) = (x-3)² + 2, min at x=3'],
337
+ ['Gradient Descent x', FORMAT(gd.x)],
338
+ ['Gradient Descent iterations', gd.iterations],
339
+ ['Gradient Descent value', FORMAT(gd.value)],
340
+ ['Adam x', FORMAT(adamResult.x)],
341
+ ['Adam iterations', adamResult.iterations],
342
+ ['Adam value', FORMAT(adamResult.value)]
56
343
  ]
57
344
  })
58
345
  }
59
346
  }
60
347
 
348
+ const categoryGroups = {
349
+ 'Core': ['basics', 'distributions', 'sampling'],
350
+ 'Statistics': ['statistics', 'hypothesis'],
351
+ 'Modeling': ['regression', 'timeseries'],
352
+ 'Numerics': ['integration', 'interpolation', 'rootfinding', 'ode'],
353
+ 'Linear Algebra': ['matrix', 'decomposition'],
354
+ 'Advanced': ['optimization', 'transforms']
355
+ }
356
+
61
357
  return (
62
358
  <div className="app">
63
359
  <header>
64
360
  <h1>nox</h1>
65
- <p>Fast RNG with multiple algorithms</p>
361
+ <p>Comprehensive RNG and Numerical Computing Library</p>
66
362
  </header>
67
363
 
68
- <div className="tabs">
69
- {Object.keys(handlers).map(key => (
70
- <button key={key} onClick={handlers[key]}>
71
- {key.charAt(0).toUpperCase() + key.slice(1)}
72
- </button>
364
+ <div className="tabs-container">
365
+ {Object.entries(categoryGroups).map(([category, items]) => (
366
+ <div key={category} className="category">
367
+ <h3>{category}</h3>
368
+ <div className="tabs">
369
+ {items.map(key => (
370
+ <button key={key} onClick={handlers[key]}>
371
+ {key.charAt(0).toUpperCase() + key.slice(1).replace(/([A-Z])/g, ' $1')}
372
+ </button>
373
+ ))}
374
+ </div>
375
+ </div>
73
376
  ))}
74
377
  </div>
75
378
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudglides/nox",
3
- "version": "1.1.6",
3
+ "version": "3.0.0",
4
4
  "description": "Unpredictable random number generator with multiple algorithms and distributions",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -12,6 +12,10 @@
12
12
  "default": "./src/index.js"
13
13
  }
14
14
  },
15
+ "scripts": {
16
+ "test": "node test/basic.js",
17
+ "bench": "node test/benchmark.js"
18
+ },
15
19
  "keywords": [
16
20
  "random",
17
21
  "rng",
@@ -21,11 +25,8 @@
21
25
  ],
22
26
  "author": "",
23
27
  "license": "ISC",
28
+ "packageManager": "pnpm@10.24.0",
24
29
  "publishConfig": {
25
30
  "access": "public"
26
- },
27
- "scripts": {
28
- "test": "node test/basic.js",
29
- "bench": "node test/benchmark.js"
30
31
  }
31
- }
32
+ }
@@ -0,0 +1,3 @@
1
+ packages:
2
+ - '.'
3
+ - 'example'
@@ -1,10 +1,43 @@
1
1
  export { rng, RNG } from './rng.browser.js';
2
2
  export { deterministic } from './presets.browser.js';
3
3
 
4
- export { normal, exponential, uniform, poisson } from './utils/distributions.js';
5
- export { shuffle, pick, sample } from './utils/sequence.js';
4
+ export { normal, exponential, uniform, poisson, normals, exponentials } from './utils/distributions.js';
5
+ export { beta, gamma, chi2, binomial, geometric } from './utils/distributions-extra.js';
6
+ export { weibull, lognormal, rayleigh, cauchy } from './utils/distributions-special.js';
7
+ export { dirichlet, dirichlets, mixture, mixtures, studentT, studentTs, betaBinomial } from './utils/distributions-advanced.js';
8
+ export { shuffle, pick, sample, sampleWithReplacement, permute, range, cycle } from './utils/sequence.js';
6
9
  export { saveState, restoreState, cloneGenerator } from './utils/state.js';
7
10
  export { weightedPick, weightedSample, reservoirSample } from './utils/sampling.js';
8
- export { meanTest, varianceTest, kolmogorovSmirnovTest } from './utils/statistics.js';
9
-
11
+ export { meanTest, varianceTest, kolmogorovSmirnovTest, chiSquareTest, entropy, autocorrelation, runTest, skewness, kurtosis, median, quantile } from './utils/statistics.js';
10
12
  export { combined, clearCryptoCache } from './utils/entropy.browser.js';
13
+ export { brownianMotion, ornsteinUhlenbeck, geometricBrownian } from './utils/stochastic.js';
14
+ export { categorical, multinomial, categorical2D } from './utils/categorical.js';
15
+ export { perlin2D, valueNoise } from './utils/noise.js';
16
+ export { combinations, permutations, kPermutations, randomCombination, randomPermutation } from './utils/combinatorics.js';
17
+ export { rotateBits, extractBits, hammingWeight, bitRange, popcountNum, clz, ctz, reverseBits, setBit, clearBit, toggleBit } from './utils/bits.js';
18
+ export { SeedSequence, seedMultiple } from './utils/seeding.js';
19
+ export { seedFromTime, seedFromEntropy } from './utils/seed.js';
20
+ export { repeat, until, times } from './utils/helpers.js';
21
+ export { bootstrap, jackknife, crossValidation, permutationTest } from './utils/resampling.js';
22
+ export { stratifiedSample, stratifiedSampleProportional, stratify } from './utils/stratified.js';
23
+ export { cdf, ppf, sf } from './utils/probability.js';
24
+ export { WeightedDistribution, CategoricalDistribution, NormalDistribution } from './utils/precomputed.js';
25
+ export { bootstrapCI, meanCI, proportionCI } from './utils/confidence.js';
26
+ export { cohensD, hedgesG, correlation, cramersV, etaSquared, glasssDelta } from './utils/effects.js';
27
+ export { sum, mean, min, max, unique, chunk, flatten, zip, transpose, partition } from './utils/arrays.js';
28
+ export { tTest, welchTTest, mannWhitneyU, oneWayAnova } from './utils/hypothesis.js';
29
+ export { zscore, standardize, minMaxScale, logTransform, sqrtTransform, rank, robustScale } from './utils/transforms.js';
30
+ export { LinearRegression, MultipleRegression } from './utils/regression.js';
31
+ export { diff, lag, shift, sma, ema, acf, pacf } from './utils/timeseries.js';
32
+ export { matrixAdd, matrixSub, matrixMul, elementwiseMul, scalarMul, determinant, trace, norm, inverse as matrixInverse } from './utils/matrix.js';
33
+ export { trapezoidal, simpsons, adaptiveSimpson, gaussQuadrature, numericalDerivative, numericalSecondDerivative } from './utils/integration.js';
34
+ export { LinearInterpolator, CubicSplineInterpolator, lagrangeInterpolation, polynomialFit } from './utils/interpolation.js';
35
+ export { bisection, newtonRaphson, secant, falsePosition, fixedPoint } from './utils/rootfinding.js';
36
+ export { eulerMethod, rk4, systemEuler, systemRK4, rk45Adaptive } from './utils/odesolvers.js';
37
+ export { svd, qr, cholesky, lu } from './utils/decomposition.js';
38
+ export { gradientDescent, momentumDescent, adam, simplex, brent } from './utils/optimization.js';
39
+ export { tTestPValue, zTestPValue, fTestPValue, chi2PValue, uTestPValue, pearsonPValue } from './utils/pvalues.js';
40
+ export { residualDiagnostics, leverageValues, cookDistance, durwinWatson, vif } from './utils/diagnostics.js';
41
+ export { LogisticRegression } from './utils/logistic.js';
42
+ export { PolynomialRegression } from './utils/polynomial.js';
43
+ export { KMeans } from './utils/clustering.js';