@thi.ng/math 5.7.6 → 5.7.8

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/permutations.js CHANGED
@@ -1,48 +1,19 @@
1
- /**
2
- * Computes factorial for `n`. Throws an error if `n < 0`.
3
- *
4
- * @param n
5
- */
6
- export const factorial = (n) => {
7
- if (n < 0)
8
- throw new Error(`illegal argument: ${n}`);
9
- let res = 1;
10
- for (let i = 1; i <= n; i++)
11
- res *= i;
12
- return res;
1
+ const factorial = (n) => {
2
+ if (n < 0)
3
+ throw new Error(`illegal argument: ${n}`);
4
+ let res = 1;
5
+ for (let i = 1; i <= n; i++)
6
+ res *= i;
7
+ return res;
8
+ };
9
+ const permutationsWithRep = (n, k) => n ** k;
10
+ const permutationsWithoutRep = (n, k) => factorial(n) / factorial(n - k);
11
+ const combinationsWithRep = (n, k) => factorial(n + k - 1) / (factorial(k) * factorial(n - 1));
12
+ const combinationsWithoutRep = (n, k) => factorial(n) / (factorial(k) * factorial(n - k));
13
+ export {
14
+ combinationsWithRep,
15
+ combinationsWithoutRep,
16
+ factorial,
17
+ permutationsWithRep,
18
+ permutationsWithoutRep
13
19
  };
14
- /**
15
- * Computes `n ** k`
16
- *
17
- * @param n number of choices
18
- * @param k number of selected
19
- */
20
- export const permutationsWithRep = (n, k) => n ** k;
21
- /**
22
- * Computes `n! / (n - k)!`
23
- *
24
- * @remarks
25
- * Reference:
26
- * https://en.wikipedia.org/wiki/Permutation#k-permutations_of_n
27
- *
28
- * @param n number of choices
29
- * @param k number of selected
30
- */
31
- export const permutationsWithoutRep = (n, k) => factorial(n) / factorial(n - k);
32
- /**
33
- * Computes `(n + k - 1)! / (k! * (n - 1)!)`
34
- *
35
- * @param n number of choices
36
- * @param k number of selected
37
- */
38
- export const combinationsWithRep = (n, k) => factorial(n + k - 1) / (factorial(k) * factorial(n - 1));
39
- /**
40
- * Computes `n! / (k! * (n - k)!)`
41
- *
42
- * @remarks
43
- * https://en.wikipedia.org/wiki/Combination#Number_of_k-combinations
44
- *
45
- * @param n number of choices
46
- * @param k number of selected
47
- */
48
- export const combinationsWithoutRep = (n, k) => factorial(n) / (factorial(k) * factorial(n - k));
package/prec.js CHANGED
@@ -1,33 +1,20 @@
1
1
  import { EPS } from "./api.js";
2
- /**
3
- * Similar to {@link fmod}, {@link remainder}. Returns `a - b * floor(a / b)`
4
- * (same as GLSL `mod(a, b)`)
5
- *
6
- * @remarks
7
- * **Caution:** Due to the introduction of libc math functions in v4.0.0 and the
8
- * resulting name/behavior clashes between the modulo logic in JS, C & GLSL,
9
- * this function previously _was_ called `fmod`, but going forward has been
10
- * renamed to align w/ its GLSL version and exhibits a different behavior to the
11
- * current {@link fmod} function.
12
- *
13
- * https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/mod.xhtml
14
- *
15
- * @param a -
16
- * @param b -
17
- */
18
- export const mod = (a, b) => a - b * Math.floor(a / b);
19
- export const fract = (x) => x - Math.floor(x);
20
- export const trunc = (x) => (x < 0 ? Math.ceil(x) : Math.floor(x));
21
- export const roundTo = (x, prec = 1) => Math.round(x / prec) * prec;
22
- export const floorTo = (x, prec = 1) => Math.floor(x / prec) * prec;
23
- export const ceilTo = (x, prec = 1) => Math.ceil(x / prec) * prec;
24
- /**
25
- * Only rounds `x` to nearest int if `fract(x)` <= `eps` or >= `1-eps`.
26
- *
27
- * @param x -
28
- * @param eps -
29
- */
30
- export const roundEps = (x, eps = EPS) => {
31
- const f = fract(x);
32
- return f <= eps || f >= 1 - eps ? Math.round(x) : x;
2
+ const mod = (a, b) => a - b * Math.floor(a / b);
3
+ const fract = (x) => x - Math.floor(x);
4
+ const trunc = (x) => x < 0 ? Math.ceil(x) : Math.floor(x);
5
+ const roundTo = (x, prec = 1) => Math.round(x / prec) * prec;
6
+ const floorTo = (x, prec = 1) => Math.floor(x / prec) * prec;
7
+ const ceilTo = (x, prec = 1) => Math.ceil(x / prec) * prec;
8
+ const roundEps = (x, eps = EPS) => {
9
+ const f = fract(x);
10
+ return f <= eps || f >= 1 - eps ? Math.round(x) : x;
11
+ };
12
+ export {
13
+ ceilTo,
14
+ floorTo,
15
+ fract,
16
+ mod,
17
+ roundEps,
18
+ roundTo,
19
+ trunc
33
20
  };
package/prime.js CHANGED
@@ -1,54 +1,37 @@
1
- /**
2
- * Returns iterator of all prime numbers ≤ given `x` using Sieve of
3
- * Eratosthenes.
4
- *
5
- * @remarks
6
- * Reference: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
7
- *
8
- * @param x -
9
- */
10
- export function* primesUntil(x) {
11
- if (x < 1)
12
- return;
13
- yield 1;
14
- const sieve = [];
15
- const max = Math.sqrt(x) | 0;
16
- for (let i = 2; i <= x; i++) {
17
- if (!sieve[i]) {
18
- yield i;
19
- __updateSieve(sieve, i, x, max);
20
- }
1
+ function* primesUntil(x) {
2
+ if (x < 1)
3
+ return;
4
+ yield 1;
5
+ const sieve = [];
6
+ const max = Math.sqrt(x) | 0;
7
+ for (let i = 2; i <= x; i++) {
8
+ if (!sieve[i]) {
9
+ yield i;
10
+ __updateSieve(sieve, i, x, max);
21
11
  }
12
+ }
22
13
  }
23
- /**
24
- * Returns largest prime number ≤ given `x` using Sieve of Eratosthenes. Returns
25
- * -1 if x < 1.
26
- *
27
- * @remarks
28
- * Reference: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
29
- *
30
- * @param x -
31
- */
32
- export const nearestPrime = (x) => {
33
- if (x < 1)
34
- return -1;
35
- let prime = 1;
36
- const sieve = [];
37
- const max = Math.sqrt(x) | 0;
38
- for (let i = 2; i <= x; i++) {
39
- if (!sieve[i]) {
40
- prime = i;
41
- __updateSieve(sieve, i, x, max);
42
- }
14
+ const nearestPrime = (x) => {
15
+ if (x < 1)
16
+ return -1;
17
+ let prime = 1;
18
+ const sieve = [];
19
+ const max = Math.sqrt(x) | 0;
20
+ for (let i = 2; i <= x; i++) {
21
+ if (!sieve[i]) {
22
+ prime = i;
23
+ __updateSieve(sieve, i, x, max);
43
24
  }
44
- return prime;
25
+ }
26
+ return prime;
45
27
  };
46
- /**
47
- * @internal
48
- */
49
28
  const __updateSieve = (sieve, i, x, max) => {
50
- if (i <= max) {
51
- for (let j = i * i; j <= x; j += i)
52
- sieve[j] = true;
53
- }
29
+ if (i <= max) {
30
+ for (let j = i * i; j <= x; j += i)
31
+ sieve[j] = true;
32
+ }
33
+ };
34
+ export {
35
+ nearestPrime,
36
+ primesUntil
54
37
  };
package/ratio.js CHANGED
@@ -1,18 +1,20 @@
1
- export const simplifyRatio = (num, denom) => {
2
- let e1 = Math.abs(num);
3
- let e2 = Math.abs(denom);
4
- while (true) {
5
- if (e1 < e2) {
6
- const t = e1;
7
- e1 = e2;
8
- e2 = t;
9
- }
10
- const r = e1 % e2;
11
- if (r) {
12
- e1 = r;
13
- }
14
- else {
15
- return [num / e2, denom / e2];
16
- }
1
+ const simplifyRatio = (num, denom) => {
2
+ let e1 = Math.abs(num);
3
+ let e2 = Math.abs(denom);
4
+ while (true) {
5
+ if (e1 < e2) {
6
+ const t = e1;
7
+ e1 = e2;
8
+ e2 = t;
17
9
  }
10
+ const r = e1 % e2;
11
+ if (r) {
12
+ e1 = r;
13
+ } else {
14
+ return [num / e2, denom / e2];
15
+ }
16
+ }
17
+ };
18
+ export {
19
+ simplifyRatio
18
20
  };
package/safe-div.js CHANGED
@@ -1,7 +1,4 @@
1
- /**
2
- * Returns `a` divided by `b` or zero if `b = 0`.
3
- *
4
- * @param a -
5
- * @param b -
6
- */
7
- export const safeDiv = (a, b) => (b !== 0 ? a / b : 0);
1
+ const safeDiv = (a, b) => b !== 0 ? a / b : 0;
2
+ export {
3
+ safeDiv
4
+ };
package/solve.js CHANGED
@@ -1,97 +1,42 @@
1
1
  import { EPS } from "./api.js";
2
2
  import { safeDiv } from "./safe-div.js";
3
- /**
4
- * Produces a new function which computes derivative of the given single-arg
5
- * function. The extra optional arg `eps` is used to define the step width for
6
- * computing derived values:
7
- *
8
- * `f'(x) = (f(x + eps) - f(x)) / eps`
9
- *
10
- * The original function is assumed to be fully differentiable in the interval
11
- * the returned function is going to be used. No validity checks of any form are
12
- * done.
13
- *
14
- * https://en.wikipedia.org/wiki/Derivative#Continuity_and_differentiability
15
- *
16
- * @param fn -
17
- * @param eps -
18
- */
19
- export const derivative = (f, eps = EPS) => (x) => (f(x + eps) - f(x)) / eps;
20
- /**
21
- * Computes solution for linear equation: `ax + b = 0`.
22
- *
23
- * Note: Returns 0 iff `a == 0`
24
- *
25
- * @param a - slope
26
- * @param b - constant offset
27
- */
28
- export const solveLinear = (a, b) => safeDiv(-b, a);
29
- /**
30
- * Computes solutions for quadratic equation: `ax^2 + bx + c = 0`. Returns array
31
- * of real solutions. Note: `a` MUST NOT be zero. If the quadratic term is
32
- * missing, use {@link solveLinear} instead.
33
- *
34
- * - https://en.wikipedia.org/wiki/Quadratic_function
35
- * - https://en.wikipedia.org/wiki/Quadratic_equation
36
- *
37
- * @param a - quadratic coefficient
38
- * @param b - linear coefficient
39
- * @param c - constant offset
40
- * @param eps - tolerance to determine multiple roots
41
- */
42
- export const solveQuadratic = (a, b, c, eps = 1e-9) => {
43
- const d = 2 * a;
44
- let r = b * b - 4 * a * c;
45
- return r < 0
46
- ? []
47
- : r < eps
48
- ? [-b / d]
49
- : ((r = Math.sqrt(r)), [(-b - r) / d, (-b + r) / d]);
3
+ const derivative = (f, eps = EPS) => (x) => (f(x + eps) - f(x)) / eps;
4
+ const solveLinear = (a, b) => safeDiv(-b, a);
5
+ const solveQuadratic = (a, b, c, eps = 1e-9) => {
6
+ const d = 2 * a;
7
+ let r = b * b - 4 * a * c;
8
+ return r < 0 ? [] : r < eps ? [-b / d] : (r = Math.sqrt(r), [(-b - r) / d, (-b + r) / d]);
50
9
  };
51
- /**
52
- * Computes solutions for quadratic equation: `ax^3 + bx^2 + c*x + d = 0`.
53
- * Returns array of solutions, both real & imaginary. Note: `a` MUST NOT be
54
- * zero. If the cubic term is missing (i.e. zero), use {@link solveQuadratic} or
55
- * {@link solveLinear} instead.
56
- *
57
- * https://en.wikipedia.org/wiki/Cubic_function
58
- *
59
- * @param a - cubic coefficient
60
- * @param b - quadratic coefficient
61
- * @param c - linear coefficient
62
- * @param d - constant offset
63
- * @param eps - tolerance to determine multiple roots
64
- */
65
- export const solveCubic = (a, b, c, d, eps = 1e-9) => {
66
- const aa = a * a;
67
- const bb = b * b;
68
- const ba3 = b / (3 * a);
69
- const p = (3 * a * c - bb) / (3 * aa);
70
- const q = (2 * bb * b - 9 * a * b * c + 27 * aa * d) / (27 * aa * a);
71
- if (Math.abs(p) < eps) {
72
- return [Math.cbrt(-q) - ba3];
73
- }
74
- else if (Math.abs(q) < eps) {
75
- return p < 0
76
- ? [-Math.sqrt(-p) - ba3, -ba3, Math.sqrt(-p) - ba3]
77
- : [-ba3];
78
- }
79
- else {
80
- const denom = (q * q) / 4 + (p * p * p) / 27;
81
- if (Math.abs(denom) < eps) {
82
- return [(-1.5 * q) / p - ba3, (3 * q) / p - ba3];
83
- }
84
- else if (denom > 0) {
85
- const u = Math.cbrt(-q / 2 - Math.sqrt(denom));
86
- return [u - p / (3 * u) - ba3];
87
- }
88
- else {
89
- const u = 2 * Math.sqrt(-p / 3), t = Math.acos((3 * q) / p / u) / 3, k = (2 * Math.PI) / 3;
90
- return [
91
- u * Math.cos(t) - ba3,
92
- u * Math.cos(t - k) - ba3,
93
- u * Math.cos(t - 2 * k) - ba3,
94
- ];
95
- }
10
+ const solveCubic = (a, b, c, d, eps = 1e-9) => {
11
+ const aa = a * a;
12
+ const bb = b * b;
13
+ const ba3 = b / (3 * a);
14
+ const p = (3 * a * c - bb) / (3 * aa);
15
+ const q = (2 * bb * b - 9 * a * b * c + 27 * aa * d) / (27 * aa * a);
16
+ if (Math.abs(p) < eps) {
17
+ return [Math.cbrt(-q) - ba3];
18
+ } else if (Math.abs(q) < eps) {
19
+ return p < 0 ? [-Math.sqrt(-p) - ba3, -ba3, Math.sqrt(-p) - ba3] : [-ba3];
20
+ } else {
21
+ const denom = q * q / 4 + p * p * p / 27;
22
+ if (Math.abs(denom) < eps) {
23
+ return [-1.5 * q / p - ba3, 3 * q / p - ba3];
24
+ } else if (denom > 0) {
25
+ const u = Math.cbrt(-q / 2 - Math.sqrt(denom));
26
+ return [u - p / (3 * u) - ba3];
27
+ } else {
28
+ const u = 2 * Math.sqrt(-p / 3), t = Math.acos(3 * q / p / u) / 3, k = 2 * Math.PI / 3;
29
+ return [
30
+ u * Math.cos(t) - ba3,
31
+ u * Math.cos(t - k) - ba3,
32
+ u * Math.cos(t - 2 * k) - ba3
33
+ ];
96
34
  }
35
+ }
36
+ };
37
+ export {
38
+ derivative,
39
+ solveCubic,
40
+ solveLinear,
41
+ solveQuadratic
97
42
  };
package/step.js CHANGED
@@ -1,64 +1,15 @@
1
1
  import { clamp01 } from "./interval.js";
2
- /**
3
- * Step/threshold function.
4
- *
5
- * @param edge - threshold
6
- * @param x - test value
7
- * @returns 0, if `x < e`, else 1
8
- */
9
- export const step = (edge, x) => (x < edge ? 0 : 1);
10
- /**
11
- * GLSL-style smoothStep threshold function.
12
- *
13
- * @remarks
14
- * Also see {@link smoothStep01}, {@link smootherStep}.
15
- *
16
- * @param edge - lower threshold
17
- * @param edge2 - upper threshold
18
- * @param x - test value
19
- * @returns 0, if `x < edge1`, 1 if `x > edge2`, else S-curve polynomial interpolation
20
- */
21
- export const smoothStep = (edge, edge2, x) => smoothStep01(clamp01((x - edge) / (edge2 - edge)));
22
- /**
23
- * Specialized version of {@link smoothStep}, assuming edges are 0/1
24
- * respectively and `x` is in [0..1]. No clamping performed.
25
- *
26
- * @param x
27
- */
28
- export const smoothStep01 = (x) => x * x * (3 - 2 * x);
29
- /**
30
- * Similar to {@link smoothStep} but using different, higher degree polynomial.
31
- *
32
- * @remarks
33
- * Also see {@link smootherStep01}.
34
- *
35
- * @param edge -
36
- * @param edge2 -
37
- * @param x -
38
- */
39
- export const smootherStep = (edge, edge2, x) => smootherStep01(clamp01((x - edge) / (edge2 - edge)));
40
- /**
41
- * Specialized version of {@link smootherStep}, assuming edges are 0/1
42
- * respectively and `x` is in [0..1]. No clamping performed.
43
- *
44
- * @param x
45
- */
46
- export const smootherStep01 = (x) => x * x * x * (x * (x * 6 - 15) + 10);
47
- /**
48
- * Exponential ramp with variable shape
49
- *
50
- * @remarks
51
- * Example configurations:
52
- *
53
- * - S-curve: k=8, n=4
54
- * - Step near 1.0: k=8, n=20
55
- * - Pulse: k=0.005, n=-10
56
- * - Ease-in: k=0.5, n=0.25
57
- *
58
- * Interactive graph: https://www.desmos.com/calculator/gcnuyppycz
59
- *
60
- * @param k -
61
- * @param n -
62
- * @param x -
63
- */
64
- export const expStep = (k, n, x) => 1 - Math.exp(-k * Math.pow(x, n));
2
+ const step = (edge, x) => x < edge ? 0 : 1;
3
+ const smoothStep = (edge, edge2, x) => smoothStep01(clamp01((x - edge) / (edge2 - edge)));
4
+ const smoothStep01 = (x) => x * x * (3 - 2 * x);
5
+ const smootherStep = (edge, edge2, x) => smootherStep01(clamp01((x - edge) / (edge2 - edge)));
6
+ const smootherStep01 = (x) => x * x * x * (x * (x * 6 - 15) + 10);
7
+ const expStep = (k, n, x) => 1 - Math.exp(-k * Math.pow(x, n));
8
+ export {
9
+ expStep,
10
+ smoothStep,
11
+ smoothStep01,
12
+ smootherStep,
13
+ smootherStep01,
14
+ step
15
+ };