smath 1.15.1 → 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/dist/index.js CHANGED
@@ -1,570 +1,4 @@
1
- "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.approx = approx;
15
- exports.clamp = clamp;
16
- exports.normalize = normalize;
17
- exports.expand = expand;
18
- exports.translate = translate;
19
- exports.linspace = linspace;
20
- exports.logspace = logspace;
21
- exports.factorial = factorial;
22
- exports.factors = factors;
23
- exports.round2 = round2;
24
- exports.error = error;
25
- exports.sum = sum;
26
- exports.prod = prod;
27
- exports.avg = avg;
28
- exports.median = median;
29
- exports.varp = varp;
30
- exports.vars = vars;
31
- exports.stdevp = stdevp;
32
- exports.stdevs = stdevs;
33
- exports.runif = runif;
34
- exports.rint = rint;
35
- exports.rnorm = rnorm;
36
- exports.rdist = rdist;
37
- exports.shuffle = shuffle;
38
- exports.selectRandom = selectRandom;
39
- exports.selectRandomWeighted = selectRandomWeighted;
40
- exports.lim = lim;
41
- exports.differentiate = differentiate;
42
- exports.integrate = integrate;
43
- exports.rat = rat;
44
- exports.mixed = mixed;
45
- /**
46
- * @packageDocumentation
47
- * Small math function library
48
- *
49
- * ![NPM Downloads](https://img.shields.io/npm/d18m/smath)
50
- * ![NPM Last Update](https://img.shields.io/npm/last-update/smath)
51
- */
52
- /**
53
- * Check if two numbers are approximately equal with a maximum abolute error.
54
- * @param a Any number
55
- * @param b Any number
56
- * @param epsilon Maximum absolute error
57
- * @returns True if `a` is approximately `b`
58
- * @example
59
- * const b1 = SMath.approx(1 / 3, 0.33, 1e-6), // false
60
- * b2 = SMath.approx(1 / 3, 0.33, 1e-2); // true
61
- */
62
- function approx(a, b, epsilon) {
63
- if (epsilon === void 0) { epsilon = 1e-6; }
64
- return a - b < epsilon && b - a < epsilon;
65
- }
66
- /**
67
- * Clamp a number within a range.
68
- * @param n The number to clamp
69
- * @param min The minimum value of the range
70
- * @param max The maximum value of the range
71
- * @returns A clamped number
72
- * @example
73
- * const n1 = SMath.clamp(5, 0, 10), // 5
74
- * n2 = SMath.clamp(-2, 0, 10); // 0
75
- */
76
- function clamp(n, min, max) {
77
- if (n < min) {
78
- return min;
79
- }
80
- if (n > max) {
81
- return max;
82
- }
83
- return n;
84
- }
85
- /**
86
- * Normalize the number `n` from the range `min, max` to the range `0, 1`
87
- * @param n The number to normalize
88
- * @param min The minimum value in the range
89
- * @param max The maximum value in the range
90
- * @returns A normalized value
91
- * @example
92
- * const y = SMath.normalize(18, 9, 99); // 0.1
93
- */
94
- function normalize(n, min, max) {
95
- if (min === max) {
96
- return 0;
97
- }
98
- return (n - min) / (max - min);
99
- }
100
- /**
101
- * Expand a normalized number `n` to the range `min, max`
102
- * @param n A normalized number
103
- * @param min The minimum value in the range
104
- * @param max The maximum value in the range
105
- * @returns A value within the number range
106
- * @example
107
- * const y = SMath.expand(0.25, 4, 6); // 4.5
108
- */
109
- function expand(n, min, max) {
110
- return (max - min) * n + min;
111
- }
112
- /**
113
- * Translate a number `n` from the range `min1, max1` to the range `min2, max2`
114
- * @param n The number to translate
115
- * @param min1 The minimum value from the initial range
116
- * @param max1 The maximum value from the initial range
117
- * @param min2 The minimum value for the final range
118
- * @param max2 The maximum value for the final range
119
- * @returns A translated number in the final range
120
- * @example
121
- * const C = 20,
122
- * F = SMath.translate(C, 0, 100, 32, 212); // 68
123
- */
124
- function translate(n, min1, max1, min2, max2) {
125
- return expand(normalize(n, min1, max1), min2, max2);
126
- }
127
- /**
128
- * Generate an array of linearly spaced numbers.
129
- * @param min The initial value of the linear space
130
- * @param max The final value of the linear space
131
- * @param count The number of values in the space
132
- * @returns The linear space as an array of numbers
133
- * @example
134
- * const space = SMath.linspace(1, 5, 6);
135
- * // [ 1, 1.8, 2.6, 3.4, 4.2, 5 ]
136
- */
137
- function linspace(min, max, count) {
138
- var space = [];
139
- for (var i = 0; i < count; i++) {
140
- space[i] = translate(i, 0, count - 1, min, max);
141
- }
142
- return space;
143
- }
144
- /**
145
- * Generate an array of logarithmically spaced numbers.
146
- * @param min The initial magnitude of the space
147
- * @param max The final magnitude of the space
148
- * @param count The number of values in the space
149
- * @returns The logarithmic space as an array of numbers
150
- * @example
151
- * const space = SMath.logspace(0, 2, 5);
152
- * // [ 1, 3.2, 10, 31.6, 100 ]
153
- */
154
- function logspace(min, max, count) {
155
- return linspace(min, max, count).map(function (n) { return Math.pow(10, n); });
156
- }
157
- /**
158
- * Compute the factorial of `n`.
159
- * @param n Any positive integer
160
- * @returns `n!`
161
- * @example
162
- * const y = SMath.factorial(5); // 120
163
- */
164
- function factorial(n) {
165
- if (n < 0 || (n | 0) !== n) {
166
- throw new Error('Input must be a positive integer.');
167
- }
168
- else if (n === 0) {
169
- return 1;
170
- }
171
- else if (n <= 2) {
172
- return n;
173
- }
174
- else {
175
- return n * factorial(n - 1);
176
- }
177
- }
178
- /**
179
- * Factorize `n` into its prime factors.
180
- * @param n Any positive integer
181
- * @returns The array of prime factors
182
- * @example
183
- * const y = SMath.factors(12); // [ 2, 2, 3 ]
184
- */
185
- function factors(n) {
186
- if (n < 0 || (n | 0) !== n) {
187
- throw new Error('Input must be a positive integer!');
188
- }
189
- if (n <= 3) {
190
- return [n];
191
- }
192
- var f = [];
193
- var i = 2;
194
- while (n > 1 && i <= n) {
195
- if ((n / i) === ((n / i) | 0)) {
196
- n /= i;
197
- f.push(i);
198
- }
199
- else {
200
- i++;
201
- }
202
- }
203
- return f;
204
- }
205
- /**
206
- * Round a number to the nearest multiple of an arbitrary
207
- * base. Does not round when the base is set to zero.
208
- * @param n Any number to round
209
- * @param base Any base to round to
210
- * @returns `n` rounded to the nearest multiple of `base`
211
- * @example
212
- * const y = SMath.round2(Math.PI, 0.2); // 3.2
213
- */
214
- function round2(n, base) {
215
- var rounded = base ? base * Math.round(n / base) : n;
216
- var precision = 10; // Removes precision errors
217
- return parseFloat(rounded.toFixed(precision));
218
- }
219
- /**
220
- * Calculate the relative normalized error or deviation from any
221
- * value to an accepted value. An error of 0 indicates that the
222
- * two values are identical. An error of -0.1 indicates that the
223
- * experimental value is 10% smaller than (90% of) the accepted
224
- * value. An error of 1.0 indicates that the experimental value
225
- * is 100% greater (or twice the size) of the accepted value.
226
- * @param experimental The value observed or produced by a test
227
- * @param actual The accepted or theoretical value
228
- * @returns The relative (normalized) error
229
- * @example
230
- * const e = SMath.error(22.5, 25); // -0.1
231
- */
232
- function error(experimental, actual) {
233
- if (experimental === 0 && actual === 0) {
234
- return 0;
235
- }
236
- else {
237
- return (experimental - actual) / actual;
238
- }
239
- }
240
- /**
241
- * Add up all the inputs.
242
- * If none are present, returns 0.
243
- * @param data An array of numeric inputs
244
- * @returns The sum total
245
- * @example
246
- * const y = SMath.sum([1, 2, 3]); // 6
247
- */
248
- function sum(data) {
249
- return data.reduce(function (a, b) { return a + b; }, 0);
250
- }
251
- /**
252
- * Multiply all the inputs.
253
- * If none are present, returns 1.
254
- * @param data An array of numeric inputs
255
- * @returns The product
256
- * @example
257
- * const y = SMath.prod([2, 2, 3, 5]); // 60
258
- */
259
- function prod(data) {
260
- return data.reduce(function (a, b) { return a * b; }, 1);
261
- }
262
- /**
263
- * Compute the average, or mean, of a set of numbers.
264
- * @param data An array of numeric inputs
265
- * @returns The average, or mean
266
- * @example
267
- * const y = SMath.avg([1, 2, 4, 4]); // 2.75
268
- */
269
- function avg(data) {
270
- return sum(data) / data.length;
271
- }
272
- /**
273
- * Compute the median of a set of numbers.
274
- * @param data An array of numeric inputs
275
- * @returns The median of the dataset
276
- * @example
277
- * const y = SMath.median([2, 5, 3, 1]); // 2.5
278
- */
279
- function median(data) {
280
- data.sort(function (a, b) { return a - b; });
281
- if (data.length % 2) {
282
- return data[(data.length - 1) / 2];
283
- }
284
- return avg([data[data.length / 2 - 1], data[data.length / 2]]);
285
- }
286
- /**
287
- * Compute the variance of a **complete population**.
288
- * @param data An array of numeric inputs
289
- * @returns The population variance
290
- * @example
291
- * const y = SMath.varp([1, 2, 4, 4]); // 1.6875
292
- */
293
- function varp(data) {
294
- var mean = avg(data), squares = data.map(function (x) { return Math.pow((x - mean), 2); });
295
- return sum(squares) / data.length;
296
- }
297
- /**
298
- * Compute the variance of a **sample**.
299
- * @param data An array of numeric inputs
300
- * @returns The sample variance
301
- * @example
302
- * const y = SMath.vars([1, 2, 4, 4]); // 2.25
303
- */
304
- function vars(data) {
305
- var mean = avg(data), squares = data.map(function (x) { return Math.pow((x - mean), 2); });
306
- return sum(squares) / (data.length - 1);
307
- }
308
- /**
309
- * Compute the standard deviation of a **complete population**.
310
- * @param data An array of numeric inputs
311
- * @returns The population standard deviation
312
- * @example
313
- * const y = SMath.stdevp([1, 2, 3, 4]); // 1.118...
314
- */
315
- function stdevp(data) {
316
- return Math.sqrt(varp(data));
317
- }
318
- /**
319
- * Compute the standard deviation of a **sample**.
320
- * @param data An array of numeric inputs
321
- * @returns The sample standard deviation
322
- * @example
323
- * const y = SMath.stdevs([1, 2, 3, 4]); // 1.29...
324
- */
325
- function stdevs(data) {
326
- return Math.sqrt(vars(data));
327
- }
328
- /**
329
- * Generate a uniformly-distributed floating-point number within the range.
330
- * @param min The minimum bound
331
- * @param max The maximum bound
332
- * @returns A random float within the range
333
- * @example
334
- * const y = SMath.runif(-2, 2); // 0.376...
335
- */
336
- function runif(min, max) {
337
- return expand(Math.random(), min, max);
338
- }
339
- /**
340
- * Generate a uniformly-distributed integer within the range.
341
- * @param min The minimum bound (inclusive)
342
- * @param max The maximum bound (inclusive)
343
- * @returns A random integer within the range
344
- * @example
345
- * const y = SMath.rint(-4, 3); // -4
346
- */
347
- function rint(min, max) {
348
- min |= 0;
349
- max |= 0;
350
- if (min < 0) {
351
- min--;
352
- }
353
- if (max > 0) {
354
- max++;
355
- }
356
- return clamp(runif(min, max), min, max) | 0; // `| 0` pulls toward 0
357
- }
358
- /**
359
- * Generate a normally-distributed floating-point number.
360
- * @param mean The mean of the population distribution
361
- * @param stdev The standard deviation of the population
362
- * @returns A random float
363
- * @example
364
- * const y = SMath.rnorm(2, 3); // 1.627...
365
- */
366
- function rnorm(mean, stdev) {
367
- if (mean === void 0) { mean = 0; }
368
- if (stdev === void 0) { stdev = 1; }
369
- return mean + stdev * Math.sqrt(-2 * Math.log(Math.random())) * Math.cos(2 * Math.PI * Math.random());
370
- }
371
- /**
372
- * Generate a population of normally-distributed floating-point numbers.
373
- * @param count The number of values to generate
374
- * @param mean The mean of the population distribution
375
- * @param stdev The standard deviation of the population
376
- * @returns A population of random floats
377
- * @example
378
- * const dataset = SMath.rdist(3); // [ 1.051..., -0.779..., -2.254... ]
379
- */
380
- function rdist(count, mean, stdev) {
381
- if (mean === void 0) { mean = 0; }
382
- if (stdev === void 0) { stdev = 1; }
383
- var distribution = [];
384
- for (var i = 0; i < count; i++) {
385
- distribution[i] = rnorm(mean, stdev);
386
- }
387
- return distribution;
388
- }
389
- /**
390
- * Randomize an array of arbitrary elements.
391
- * @param stack An array of arbitrary elements
392
- * @returns The `stack` array in a random order
393
- * @example
394
- * const shuffled = SMath.shuffle(['a', 'b', 'c']); // [ 'c', 'a', 'b' ]
395
- */
396
- function shuffle(stack) {
397
- var rawData = [];
398
- for (var _i = 0, stack_1 = stack; _i < stack_1.length; _i++) {
399
- var item = stack_1[_i];
400
- rawData.push({ index: Math.random(), value: item });
401
- }
402
- return rawData.sort(function (a, b) { return a.index - b.index; }).map(function (a) { return a.value; });
403
- }
404
- /**
405
- * Select a single item from an array at random with uniform weights.
406
- * @param stack An array of arbirary item
407
- * @returns A single randomly selected item
408
- * @example
409
- * const selected = SMath.selectRandom([10, 20, 30, 40]); // 30
410
- */
411
- function selectRandom(stack) {
412
- return stack[rint(0, stack.length - 1)];
413
- }
414
- /**
415
- * Select a single index in an array at random with different weights.
416
- * @param weights The weights for each item
417
- * @returns The 0-based index of the randomly selected item
418
- * @example
419
- * const index = SMath.selectRandomWeighted([3.5, 4, 1]); // 1
420
- */
421
- function selectRandomWeighted(weights) {
422
- var startWeights = [];
423
- var accumulation = 0;
424
- for (var _i = 0, weights_1 = weights; _i < weights_1.length; _i++) {
425
- var weight = weights_1[_i];
426
- accumulation += clamp(0, weight, Infinity);
427
- startWeights.push(accumulation);
428
- }
429
- var random = runif(0, accumulation);
430
- return startWeights.findIndex(function (weight) { return random < weight; });
431
- }
432
- /**
433
- * Take the limit of a function. A return value of `NaN` indicates
434
- * that no limit exists either due to a discontinuity or imaginary value.
435
- * @param f Function `f(x)`
436
- * @param x The x-value where to take the limit
437
- * @param h The approach distance
438
- * @param discontinuity_cutoff The discontinuity cutoff
439
- * @returns `lim(f(x->x))`
440
- * @example
441
- * const y = SMath.lim(Math.log, 0); // -Infinity
442
- */
443
- function lim(f, x, h, discontinuity_cutoff) {
444
- if (h === void 0) { h = 1e-6; }
445
- if (discontinuity_cutoff === void 0) { discontinuity_cutoff = 1e-3; }
446
- var center = f(x), left1 = f(x - h), left2 = f(x - h / 2), right1 = f(x + h), right2 = f(x + h / 2);
447
- var left, right;
448
- if (Number.isFinite(center)) {
449
- return center;
450
- }
451
- // Check the limit approaching from the left
452
- if (Number.isFinite(left1) && Number.isFinite(left2)) {
453
- if (approx(left1, left2, discontinuity_cutoff)) {
454
- left = left2; // Converges
455
- }
456
- else if (left1 > 0 && left2 > left1) {
457
- left = Infinity; // Diverges to +inf
458
- }
459
- else if (left1 < 0 && left2 < left1) {
460
- left = -Infinity; // Diverges to -inf
461
- }
462
- else {
463
- left = NaN; // Diverges
464
- }
465
- }
466
- else {
467
- left = NaN; // Discontinuous
468
- }
469
- // Check the limit approaching from the right
470
- if (Number.isFinite(right1) && Number.isFinite(right2)) {
471
- if (approx(right1, right2, discontinuity_cutoff)) {
472
- right = right2; // Converges
473
- }
474
- else if (right1 > 0 && right2 > right1) {
475
- right = Infinity; // Diverges to +inf
476
- }
477
- else if (right1 < 0 && right2 < right1) {
478
- right = -Infinity; // Diverges to -inf
479
- }
480
- else {
481
- right = NaN; // Diverges
482
- }
483
- }
484
- else {
485
- right = NaN; // Discontinuous
486
- }
487
- // Check if limits match or are close
488
- if (left === right) { // Handles +/-Infinity case
489
- return left;
490
- }
491
- else if (Number.isNaN(left) && Number.isNaN(right)) {
492
- return center;
493
- }
494
- else if (!Number.isNaN(left) && Number.isNaN(right)) {
495
- return left;
496
- }
497
- else if (Number.isNaN(left) && !Number.isNaN(right)) {
498
- return right;
499
- }
500
- else if (approx(left, right, discontinuity_cutoff)) {
501
- return avg([left, right]);
502
- }
503
- else {
504
- return NaN;
505
- }
506
- }
507
- /**
508
- * Take the derivative of a function.
509
- * @param f Function `f(x)`
510
- * @param x The x-value where to evaluate the derivative
511
- * @param epsilon Small step value
512
- * @returns `f'(x)`
513
- * @example
514
- * const y = SMath.differentiate(x => 3 * x ** 2, 2); // 12
515
- */
516
- function differentiate(f, x, epsilon) {
517
- if (epsilon === void 0) { epsilon = 1e-6; }
518
- return lim(function (h) { return (f(x + h) - f(x - h)) / (2 * h); }, 0, epsilon);
519
- }
520
- /**
521
- * Compute the definite integral of a function.
522
- * @param f Function `f(x)`
523
- * @param a The miminum integral bound
524
- * @param b The maximum integral bound
525
- * @param Ndx The number of rectangles to compute
526
- * @returns `F(b)-F(a)`
527
- * @example
528
- * const y = SMath.integrate(x => 3 * x ** 2, 1, 2); // 7
529
- */
530
- function integrate(f, a, b, Ndx) {
531
- if (Ndx === void 0) { Ndx = 1e6; }
532
- return ((b - a) / Ndx) * sum(linspace(a, b, Ndx).map(function (x) { return f(x); }));
533
- }
534
- /**
535
- * Convert an arbitrary decimal number into a simplified fraction (or ratio).
536
- * See `mixed()` for instructions on how to break out the whole number part.
537
- * @param n The decimal number to convert
538
- * @param epsilon Maximum absolute error
539
- * @returns An object containing the fraction's numerator and denominator
540
- * @example
541
- * const frac = SMath.rat(0.625); // { num: 5, den: 8 }
542
- */
543
- function rat(n, epsilon) {
544
- if (epsilon === void 0) { epsilon = 1e-6; }
545
- var num = 0, den = 1;
546
- var sign = n < 0 ? -1 : 1;
547
- while (!approx(sign * n, num / den, epsilon)) {
548
- if (sign * n > num / den) {
549
- num++;
550
- }
551
- else {
552
- den++;
553
- }
554
- }
555
- return { num: sign * num, den: den };
556
- }
557
- /**
558
- * Convert an arbitrary decimal number into a simplified fraction, after
559
- * breaking out the whole number part first. See `rat()` for keeping the
560
- * number as a ratio without separating the whole number part.
561
- * @param n A decimal number to convert
562
- * @param epsilon Maximum absolute error
563
- * @returns An object containing the whole part and fraction numerator and denominator
564
- * @example
565
- * const frac = SMath.mixed(-8 / 6); // { whole: -1, num: 1, den: 3 }
566
- */
567
- function mixed(n, epsilon) {
568
- if (epsilon === void 0) { epsilon = 1e-6; }
569
- return __assign({ whole: n | 0 }, rat(n < -1 ? (n | 0) - n : n - (n | 0), epsilon));
570
- }
1
+ import * as SMath_1 from './smath.js';
2
+ export { SMath_1 as SMath };
3
+ import * as DataFit_1 from './datafit/index.js';
4
+ export { DataFit_1 as DataFit };