@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/CHANGELOG.md +1 -1
- package/README.md +1 -1
- package/abs.js +6 -2
- package/angle.js +54 -122
- package/api.js +42 -20
- package/crossing.js +8 -58
- package/eqdelta.js +6 -22
- package/extrema.js +27 -69
- package/fit.js +14 -57
- package/int.js +128 -64
- package/interval.js +73 -205
- package/libc.js +38 -107
- package/min-error.js +27 -39
- package/mix.js +109 -391
- package/package.json +8 -5
- package/permutations.js +18 -47
- package/prec.js +18 -31
- package/prime.js +31 -48
- package/ratio.js +18 -16
- package/safe-div.js +4 -7
- package/solve.js +37 -92
- package/step.js +14 -63
package/permutations.js
CHANGED
|
@@ -1,48 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
25
|
+
}
|
|
26
|
+
return prime;
|
|
45
27
|
};
|
|
46
|
-
/**
|
|
47
|
-
* @internal
|
|
48
|
-
*/
|
|
49
28
|
const __updateSieve = (sieve, i, x, max) => {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
*
|
|
8
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
*
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
4
|
-
*
|
|
5
|
-
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
+
};
|