pimath 0.1.39 → 0.1.40
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/pimath.js +188 -159
- package/dist/pimath.js.map +1 -1
- package/package.json +4 -2
- package/src/algebra/equation.ts +556 -0
- package/src/algebra/equationSolver.ts +539 -0
- package/src/algebra/factor.ts +339 -0
- package/src/algebra/index.ts +11 -0
- package/src/algebra/linearSystem.ts +388 -0
- package/src/algebra/logicalset.ts +256 -0
- package/src/algebra/matrix.ts +474 -0
- package/src/algebra/monom.ts +1015 -0
- package/src/algebra/operations.ts +24 -0
- package/src/algebra/polyFactor.ts +668 -0
- package/src/algebra/polynom.ts +1394 -0
- package/src/analyze/solution.ts +115 -0
- package/src/analyze/tableOfSigns.ts +30 -0
- package/src/coefficients/fraction.ts +678 -0
- package/src/coefficients/index.ts +4 -0
- package/src/coefficients/nthRoot.ts +149 -0
- package/src/coefficients/root.ts +299 -0
- package/src/geometry/circle.ts +386 -0
- package/src/geometry/geomMath.ts +70 -0
- package/src/geometry/index.ts +10 -0
- package/src/geometry/line.ts +677 -0
- package/src/geometry/line3.ts +206 -0
- package/src/geometry/plane3.ts +170 -0
- package/src/geometry/point.ts +66 -0
- package/src/geometry/sphere3.ts +214 -0
- package/src/geometry/triangle.ts +354 -0
- package/src/geometry/vector.ts +341 -0
- package/src/helpers.ts +35 -0
- package/src/index.ts +60 -0
- package/src/numeric.ts +199 -0
- package/src/pimath.interface.ts +160 -0
- package/src/randomization/algebra/rndEquation.ts +41 -0
- package/src/randomization/algebra/rndMonom.ts +39 -0
- package/src/randomization/algebra/rndPolynom.ts +86 -0
- package/src/randomization/coefficient/rndFraction.ts +38 -0
- package/src/randomization/geometry/rndCircle.ts +27 -0
- package/src/randomization/geometry/rndLine.ts +37 -0
- package/src/randomization/geometry/rndLine3.ts +27 -0
- package/src/randomization/geometry/rndVector.ts +63 -0
- package/src/randomization/random.ts +91 -0
- package/src/randomization/rndHelpers.ts +102 -0
- package/src/randomization/rndTypes.ts +63 -0
- package/types/algebra/equationSolver.d.ts +3 -0
- package/types/algebra/equationSolver.d.ts.map +1 -1
- package/types/algebra/polyFactor.d.ts +5 -0
- package/types/algebra/polyFactor.d.ts.map +1 -1
- package/types/analyze/solution.d.ts +21 -0
- package/types/analyze/solution.d.ts.map +1 -0
- package/types/analyze/tableOfSigns.d.ts +9 -0
- package/types/analyze/tableOfSigns.d.ts.map +1 -0
- package/types/coefficients/root.d.ts +38 -0
- package/types/coefficients/root.d.ts.map +1 -0
- package/types/geometry/point.d.ts +1 -1
- package/types/geometry/point.d.ts.map +1 -1
- package/types/helpers.d.ts +1 -0
- package/types/helpers.d.ts.map +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/numeric.d.ts +2 -0
- package/types/numeric.d.ts.map +1 -1
- package/types/pimath.interface.d.ts +26 -26
- package/types/pimath.interface.d.ts.map +1 -1
package/src/helpers.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export function wrapParenthesis(str: string, tex = true): string {
|
|
2
|
+
return tex ? `\\left( ${str} \\right)` : `(${str})`
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function stripParenthesis(str: string): string {
|
|
6
|
+
if(str.startsWith('(')){
|
|
7
|
+
str = str.substring(1)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if(str.endsWith(')')){
|
|
11
|
+
str = str.substring(0, str.length-1)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return str
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function wrapVert(str: string, tex = true): string {
|
|
18
|
+
return tex ? `\\left\\vert ${str} \\right\\vert` : `|${str}|`
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function wrapNorm(str: string, tex = true): string {
|
|
22
|
+
return tex ? `\\left\\Vect ${str} \\right\\Vect` : `||${str}||`
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function replace_in_array<T>(haystack: string[], search: string, target: string, start?: number, end?: number): T {
|
|
26
|
+
return haystack.map((x, index) => {
|
|
27
|
+
if (start !== undefined && index < start) {
|
|
28
|
+
return x
|
|
29
|
+
}
|
|
30
|
+
if (end !== undefined && index > end) {
|
|
31
|
+
return x
|
|
32
|
+
}
|
|
33
|
+
return x === search ? target : x
|
|
34
|
+
}) as T
|
|
35
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Expose as global
|
|
2
|
+
export * from "./coefficients"
|
|
3
|
+
export * from "./algebra"
|
|
4
|
+
export * from "./geometry"
|
|
5
|
+
|
|
6
|
+
// Import items individually to make a global object
|
|
7
|
+
|
|
8
|
+
// Coefficients
|
|
9
|
+
import {Fraction, NthRoot} from "./coefficients"
|
|
10
|
+
|
|
11
|
+
// Algebra
|
|
12
|
+
import {Equation, Factor, LinearSystem, LogicalSet, Monom, PolyFactor, Polynom, Matrix} from "./algebra"
|
|
13
|
+
|
|
14
|
+
// Geometry
|
|
15
|
+
import {Circle, Line, Line3, Plane3, Point, Triangle, Vector, Sphere3} from "./geometry"
|
|
16
|
+
|
|
17
|
+
// Numeric
|
|
18
|
+
import {Numeric} from "./numeric"
|
|
19
|
+
export {Numeric}
|
|
20
|
+
|
|
21
|
+
// NumExp
|
|
22
|
+
import {NumExp} from "piexpression"
|
|
23
|
+
export {NumExp}
|
|
24
|
+
|
|
25
|
+
// randomization
|
|
26
|
+
import {Random} from "./randomization/random"
|
|
27
|
+
export {Random}
|
|
28
|
+
|
|
29
|
+
// Typesetting
|
|
30
|
+
export type * from "./pimath.interface"
|
|
31
|
+
|
|
32
|
+
// Make a global object
|
|
33
|
+
const PiMath = {
|
|
34
|
+
Numeric,
|
|
35
|
+
Fraction,
|
|
36
|
+
Root: NthRoot,
|
|
37
|
+
Monom,
|
|
38
|
+
Polynom,
|
|
39
|
+
Equation,
|
|
40
|
+
Matrix,
|
|
41
|
+
LinearSystem,
|
|
42
|
+
Factor,
|
|
43
|
+
PolyFactor,
|
|
44
|
+
LogicalSet,
|
|
45
|
+
Random,
|
|
46
|
+
Geometry: {
|
|
47
|
+
Vector,
|
|
48
|
+
Point,
|
|
49
|
+
Line,
|
|
50
|
+
Triangle,
|
|
51
|
+
Circle,
|
|
52
|
+
Line3,
|
|
53
|
+
Plane3,
|
|
54
|
+
Sphere3
|
|
55
|
+
},
|
|
56
|
+
NumExp
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Export as default value
|
|
60
|
+
export default PiMath
|
package/src/numeric.ts
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
|
|
2
|
+
function decompose(value: number): number[][] {
|
|
3
|
+
const divs: number[] = dividers(value)
|
|
4
|
+
const arr: number[][] = []
|
|
5
|
+
let u, v
|
|
6
|
+
|
|
7
|
+
while (divs.length > 0) {
|
|
8
|
+
u = divs.shift() ?? 1
|
|
9
|
+
v = (divs.length > 0 ? divs.pop() : +u) ?? 1
|
|
10
|
+
|
|
11
|
+
arr.push([u, v])
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return arr
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function divideNumbersByGCD(...values: number[]): number[] {
|
|
18
|
+
const g = greatestCommonDivisor(...values)
|
|
19
|
+
|
|
20
|
+
return values.map(x => x / g)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Get the list of all dividers of a number.
|
|
25
|
+
* @param value
|
|
26
|
+
*/
|
|
27
|
+
function dividers(value: number): number[] {
|
|
28
|
+
const absV = Math.abs(value)
|
|
29
|
+
const maxV = Math.sqrt(absV)
|
|
30
|
+
|
|
31
|
+
// Initialize the list of dividers.
|
|
32
|
+
const D: number[] = []
|
|
33
|
+
|
|
34
|
+
for (let i = 1; i <= maxV; i++) {
|
|
35
|
+
if (value % i === 0) {
|
|
36
|
+
D.push(i)
|
|
37
|
+
D.push(absV / i)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Order numbers.
|
|
42
|
+
D.sort(function (a, b) {
|
|
43
|
+
return a - b
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
// Make sure the array of value is unique.
|
|
47
|
+
return [...new Set(D)]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Great Common Divisor
|
|
52
|
+
* @param values : number values
|
|
53
|
+
*/
|
|
54
|
+
function greatestCommonDivisor(...values: number[]): number {
|
|
55
|
+
// Define the gcd for two number
|
|
56
|
+
const gcd2 = function (a: number, b: number): number {
|
|
57
|
+
if (b === 0) {
|
|
58
|
+
return a
|
|
59
|
+
}
|
|
60
|
+
return gcd2(b, a % b)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
let g = 1,
|
|
64
|
+
i = 2
|
|
65
|
+
|
|
66
|
+
// Nothing is given
|
|
67
|
+
if (values.length === 0) {
|
|
68
|
+
return 1
|
|
69
|
+
}
|
|
70
|
+
// Only one number is given
|
|
71
|
+
if (values.length === 1) {
|
|
72
|
+
// The first number is zero
|
|
73
|
+
if (values[0] === 0) {
|
|
74
|
+
return 1
|
|
75
|
+
}
|
|
76
|
+
// Return the number
|
|
77
|
+
return values[0]
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// We have at least 2 numbers.
|
|
81
|
+
g = gcd2(values[0], values[1])
|
|
82
|
+
|
|
83
|
+
// The gcd of the two first value is one ? It's already finished.
|
|
84
|
+
if (g === 1) {
|
|
85
|
+
return 1
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// The current gcd isn't one. Continue with all next values.
|
|
89
|
+
for (i = 2; i < values.length; i++) {
|
|
90
|
+
g = gcd2(g, values[i])
|
|
91
|
+
// Escape if gcd is already one.
|
|
92
|
+
if (g === 1) {
|
|
93
|
+
break
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return Math.abs(g)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Least Common Multiple
|
|
102
|
+
* @param values: list of numbers
|
|
103
|
+
*/
|
|
104
|
+
function leastCommonMultiple(...values: number[]): number {
|
|
105
|
+
return values.reduce(function (a, b) {
|
|
106
|
+
return Math.abs(a * b / greatestCommonDivisor(a, b))
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function numberCorrection(value: number, number_of_digits = 3) {
|
|
111
|
+
return +value.toFixed(number_of_digits)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function periodic(value: number): number {
|
|
115
|
+
if (Number.isSafeInteger(value)) {
|
|
116
|
+
return 0
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Assume it's with decimal.
|
|
120
|
+
const decimal = (value.toString()).split('.')[0]
|
|
121
|
+
|
|
122
|
+
// The decimal part is limited
|
|
123
|
+
if (decimal.length < 10) {
|
|
124
|
+
return 0
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Find the periodic if it exists.
|
|
128
|
+
throw new Error('Periodic value: Not implemented yet')
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Get the list of the nth first prime numbers.
|
|
133
|
+
* @param nb : number of primes to choose from
|
|
134
|
+
*/
|
|
135
|
+
function primes(nb?: number): number[] {
|
|
136
|
+
const primesValues: number[] = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973]
|
|
137
|
+
if (nb === undefined) {
|
|
138
|
+
return primesValues
|
|
139
|
+
} else {
|
|
140
|
+
return primesValues.slice(0, Math.min(primesValues.length, nb))
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function pythagoreanTripletsWithTarget(target: number, targetIsSquare?: boolean): number[][] {
|
|
145
|
+
// méthode inverse, à partir du triplet.
|
|
146
|
+
const triplets = [],
|
|
147
|
+
targetValue = targetIsSquare === true ? +target : target ** 2
|
|
148
|
+
for (let u = 0; u <= target; u++) {
|
|
149
|
+
for (let v = 0; v <= target; v++) {
|
|
150
|
+
if (u ** 2 + v ** 2 === targetValue) {
|
|
151
|
+
triplets.push([u, v, target])
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return triplets
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function round(value: number, decimals = 2): number {
|
|
160
|
+
const exp: number = Math.round(Number(`${value}e${decimals}`))
|
|
161
|
+
|
|
162
|
+
return Number(`${exp}e-${decimals}`)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function greatestPower(value: number, index: number): number {
|
|
166
|
+
let search_value = Math.floor(Math.pow(value, 1 / index))
|
|
167
|
+
|
|
168
|
+
let radical = value
|
|
169
|
+
let factor = 1
|
|
170
|
+
|
|
171
|
+
while (search_value > 1) {
|
|
172
|
+
const pow = Math.pow(search_value, index)
|
|
173
|
+
if (radical % pow) {
|
|
174
|
+
factor *= search_value
|
|
175
|
+
radical = radical / pow
|
|
176
|
+
|
|
177
|
+
search_value = Math.floor(Math.pow(radical, 1 / index))
|
|
178
|
+
}else{
|
|
179
|
+
search_value--
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return factor
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
export const Numeric = {
|
|
188
|
+
decompose,
|
|
189
|
+
dividers,
|
|
190
|
+
divideNumbersByGCD,
|
|
191
|
+
gcd: greatestCommonDivisor,
|
|
192
|
+
lcm: leastCommonMultiple,
|
|
193
|
+
numberCorrection,
|
|
194
|
+
periodic,
|
|
195
|
+
primes,
|
|
196
|
+
pythagoreanTripletsWithTarget,
|
|
197
|
+
round,
|
|
198
|
+
greatestPower
|
|
199
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import type {Fraction, NthRoot} from "./coefficients"
|
|
2
|
+
import type {Equation, Factor, Monom} from "./algebra"
|
|
3
|
+
import type {Line, Point, Vector} from "./geometry"
|
|
4
|
+
|
|
5
|
+
export type InputValue<T> = T | string | number | Fraction | NthRoot;
|
|
6
|
+
export type InputAlgebra<T> = InputValue<T> | Monom
|
|
7
|
+
export type literalType<T> = Record<string, T>;
|
|
8
|
+
|
|
9
|
+
export type compareSign =
|
|
10
|
+
'>' | ">=" | "=>" | "geq" |
|
|
11
|
+
'<' | "<=" | "=<" | "leq" |
|
|
12
|
+
'=' | "<>" | "neq" | "same";
|
|
13
|
+
|
|
14
|
+
export type EQUATION_SIGN = "=" | "<=" | ">=" | "<" | ">"
|
|
15
|
+
|
|
16
|
+
export enum PARTICULAR_SOLUTION {
|
|
17
|
+
real = "\\mathbb{R}",
|
|
18
|
+
varnothing = "\\varnothing"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface IPiMathObject<T> {
|
|
22
|
+
readonly display: string
|
|
23
|
+
readonly tex: string
|
|
24
|
+
|
|
25
|
+
parse(...value: unknown[]): T;
|
|
26
|
+
|
|
27
|
+
clone(): T;
|
|
28
|
+
}
|
|
29
|
+
export interface IExpressionBase<T>{
|
|
30
|
+
add(value: InputValue<T>): T;
|
|
31
|
+
|
|
32
|
+
isEqual(value: InputValue<T>): boolean;
|
|
33
|
+
|
|
34
|
+
isOne(): boolean;
|
|
35
|
+
|
|
36
|
+
isZero(): boolean;
|
|
37
|
+
|
|
38
|
+
one(): T;
|
|
39
|
+
|
|
40
|
+
opposite(): T;
|
|
41
|
+
|
|
42
|
+
reduce(): T;
|
|
43
|
+
|
|
44
|
+
subtract(value: InputValue<T>): T;
|
|
45
|
+
|
|
46
|
+
zero(): T;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface IExpressionMultiply<T> extends IExpressionBase<T>{
|
|
50
|
+
multiply(value: InputValue<T>): T;
|
|
51
|
+
|
|
52
|
+
pow(value: number): T;
|
|
53
|
+
}
|
|
54
|
+
export interface IExpression<T> extends IExpressionMultiply<T>{
|
|
55
|
+
divide(value: InputValue<T>): T | null;
|
|
56
|
+
|
|
57
|
+
inverse(): T | undefined;
|
|
58
|
+
|
|
59
|
+
root(value: number): T | undefined;
|
|
60
|
+
|
|
61
|
+
sqrt(): T | undefined;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface IEquation<T> {
|
|
65
|
+
|
|
66
|
+
reduce(): T;
|
|
67
|
+
|
|
68
|
+
solve(): ISolution[]
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface IAlgebra<T> {
|
|
72
|
+
readonly variables: string[];
|
|
73
|
+
|
|
74
|
+
degree(letter?: string): Fraction;
|
|
75
|
+
|
|
76
|
+
evaluate(values: literalType<Fraction | number> | InputValue<Fraction>, asNumeric?: boolean): Fraction | number | boolean;
|
|
77
|
+
|
|
78
|
+
hasVariable(letter: string): boolean;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface IAnalyse<T> {
|
|
82
|
+
derivative(): T | T[];
|
|
83
|
+
|
|
84
|
+
integrate(a: InputValue<Fraction>, b: InputValue<T>, letter?: string): Fraction;
|
|
85
|
+
|
|
86
|
+
primitive(): T;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface ISolution {
|
|
90
|
+
display: string,
|
|
91
|
+
exact: Fraction | boolean
|
|
92
|
+
tex: string,
|
|
93
|
+
value: number,
|
|
94
|
+
variable: string,
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export type TABLE_OF_SIGNS_VALUES = '-'|'+'|'h'|'z'|'t'|'d'|'u'|'n'|''
|
|
98
|
+
|
|
99
|
+
export interface TABLE_OF_SIGNS {roots: ISolution[], signs: TABLE_OF_SIGNS_VALUES[]}
|
|
100
|
+
export interface FACTOR_TABLE_OF_SIGNS extends TABLE_OF_SIGNS {factor: Factor}
|
|
101
|
+
export interface POLYFACTOR_TABLE_OF_SIGNS extends TABLE_OF_SIGNS {
|
|
102
|
+
factors: FACTOR_TABLE_OF_SIGNS[]
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export enum LinePropriety {
|
|
106
|
+
None = 'none',
|
|
107
|
+
Parallel = 'parallel',
|
|
108
|
+
Perpendicular = 'perpendicular',
|
|
109
|
+
Tangent = 'tangent'
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export enum Line3Propriety {
|
|
113
|
+
None = 'none',
|
|
114
|
+
Parallel = 'parallel',
|
|
115
|
+
Perpendicular = 'perpendicular',
|
|
116
|
+
Tangent = 'tangent'
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface Plane3Config {
|
|
120
|
+
coefficients?: number[]
|
|
121
|
+
directions?: Vector[],
|
|
122
|
+
equation?: Equation,
|
|
123
|
+
normal?: Vector,
|
|
124
|
+
point?: Point,
|
|
125
|
+
points?: Point[],
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
export interface remarquableLines {
|
|
130
|
+
'bisectors': {
|
|
131
|
+
'A': Line,
|
|
132
|
+
'B': Line,
|
|
133
|
+
'C': Line,
|
|
134
|
+
'intersection': Vector | null
|
|
135
|
+
},
|
|
136
|
+
externalBisectors: {
|
|
137
|
+
'A': Line,
|
|
138
|
+
'B': Line,
|
|
139
|
+
'C': Line,
|
|
140
|
+
'intersection': Vector | null
|
|
141
|
+
}
|
|
142
|
+
'heights': {
|
|
143
|
+
'A': Line,
|
|
144
|
+
'B': Line,
|
|
145
|
+
'C': Line,
|
|
146
|
+
'intersection': Vector | null
|
|
147
|
+
},
|
|
148
|
+
'medians': {
|
|
149
|
+
'A': Line,
|
|
150
|
+
'B': Line,
|
|
151
|
+
'C': Line,
|
|
152
|
+
'intersection': Vector | null
|
|
153
|
+
},
|
|
154
|
+
'mediators': {
|
|
155
|
+
'AB': Line,
|
|
156
|
+
'AC': Line,
|
|
157
|
+
'BC': Line,
|
|
158
|
+
'intersection': Vector | null
|
|
159
|
+
},
|
|
160
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { randomEquationConfig } from "../rndTypes"
|
|
2
|
+
import { Polynom } from "../../algebra/polynom"
|
|
3
|
+
import { Equation } from "../../algebra/equation"
|
|
4
|
+
import { rndPolynom } from "./rndPolynom"
|
|
5
|
+
|
|
6
|
+
export function rndEquation(userConfig?: randomEquationConfig): Equation {
|
|
7
|
+
const config = Object.assign(
|
|
8
|
+
{
|
|
9
|
+
letters: 'x',
|
|
10
|
+
degree: 1,
|
|
11
|
+
fraction: false,
|
|
12
|
+
zero: false,
|
|
13
|
+
unit: false,
|
|
14
|
+
factorable: false,
|
|
15
|
+
allowNullMonom: true,
|
|
16
|
+
numberOfMonoms: 0,
|
|
17
|
+
positive: true,
|
|
18
|
+
solution: {
|
|
19
|
+
allowZero: true,
|
|
20
|
+
fraction: false,
|
|
21
|
+
nothing: false,
|
|
22
|
+
everything: false
|
|
23
|
+
}
|
|
24
|
+
}, userConfig)
|
|
25
|
+
|
|
26
|
+
// Create a polynom
|
|
27
|
+
const P = new Polynom().one()
|
|
28
|
+
|
|
29
|
+
for (let i = 0; i < config.degree; i++) {
|
|
30
|
+
const factor = rndPolynom({
|
|
31
|
+
degree: 1,
|
|
32
|
+
unit: config.unit,
|
|
33
|
+
fraction: config.fraction,
|
|
34
|
+
letters: config.letters,
|
|
35
|
+
zero: config.zero
|
|
36
|
+
})
|
|
37
|
+
P.multiply(factor)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return new Equation(P, 0)
|
|
41
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { randomMonomConfig } from "../rndTypes"
|
|
2
|
+
import { Monom } from "../../algebra/monom"
|
|
3
|
+
import { rndFraction } from "../coefficient/rndFraction"
|
|
4
|
+
import { randomItem } from "../rndHelpers"
|
|
5
|
+
|
|
6
|
+
export function rndMonom(userConfig?: randomMonomConfig): Monom {
|
|
7
|
+
const config = Object.assign(
|
|
8
|
+
{
|
|
9
|
+
letters: 'x',
|
|
10
|
+
degree: 2,
|
|
11
|
+
fraction: true,
|
|
12
|
+
zero: false
|
|
13
|
+
}, userConfig)
|
|
14
|
+
|
|
15
|
+
// Create a monom instance
|
|
16
|
+
const M = new Monom()
|
|
17
|
+
|
|
18
|
+
// Generate the coefficient
|
|
19
|
+
M.coefficient = rndFraction({
|
|
20
|
+
zero: config.zero,
|
|
21
|
+
reduced: true,
|
|
22
|
+
natural: !config.fraction
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
if (config.letters.length > 1) {
|
|
26
|
+
// Initialise each items...
|
|
27
|
+
for (const L of config.letters.split('')) {
|
|
28
|
+
M.setLetter(L, 0)
|
|
29
|
+
}
|
|
30
|
+
for (let i = 0; i < config.degree; i++) {
|
|
31
|
+
const L = randomItem(config.letters.split(""))
|
|
32
|
+
M.setLetter(L, M.degree(L).clone().add(1))
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
M.setLetter(config.letters, config.degree)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return M
|
|
39
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { randomPolynomConfig } from "../rndTypes"
|
|
2
|
+
import { rndMonom } from "./rndMonom"
|
|
3
|
+
import { Polynom, Monom } from "../../algebra"
|
|
4
|
+
import { randomInt } from "../rndHelpers"
|
|
5
|
+
|
|
6
|
+
const factorableConfig = {
|
|
7
|
+
letters: 'x',
|
|
8
|
+
degree: 2,
|
|
9
|
+
fraction: false,
|
|
10
|
+
zero: false,
|
|
11
|
+
unit: false,
|
|
12
|
+
factorable: false,
|
|
13
|
+
allowNullMonom: true,
|
|
14
|
+
numberOfMonoms: 0,
|
|
15
|
+
positive: true
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function rndPolynom(userConfig?: randomPolynomConfig): Polynom {
|
|
19
|
+
const config = Object.assign(
|
|
20
|
+
factorableConfig,
|
|
21
|
+
userConfig
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
// TODO: Create a factorable polynom does not work !!!!!
|
|
25
|
+
|
|
26
|
+
// Create the polynom
|
|
27
|
+
const P = new Polynom().empty()
|
|
28
|
+
|
|
29
|
+
let M: Monom
|
|
30
|
+
|
|
31
|
+
for (let i = config.degree; i >= 0; i--) {
|
|
32
|
+
// Create monom of corresponding degree.
|
|
33
|
+
M = rndMonom({
|
|
34
|
+
letters: config.letters,
|
|
35
|
+
degree: i,
|
|
36
|
+
fraction: config.fraction,
|
|
37
|
+
zero: (i === config.degree) ? false : config.allowNullMonom
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
// If degree is the greatest and unit is true, set the monom value to one.
|
|
41
|
+
if (config.unit && config.degree === i) {
|
|
42
|
+
M.coefficient.one()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Add to the polynom
|
|
46
|
+
P.add(M)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Make sure the first monom is positive.
|
|
50
|
+
if (config.positive && P.monomByDegree().coefficient.isNegative()) {
|
|
51
|
+
P.monomByDegree().coefficient.opposite()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// If the number of monoms is greater than the allowed value, remove some of them... except the first one !
|
|
55
|
+
if (config.numberOfMonoms
|
|
56
|
+
&& config.numberOfMonoms > 0
|
|
57
|
+
&& config.numberOfMonoms < P.length) {
|
|
58
|
+
while (P.length > config.numberOfMonoms) {
|
|
59
|
+
// Remove a random monom, except the first one
|
|
60
|
+
const index = randomInt(1, P.length - 1)
|
|
61
|
+
|
|
62
|
+
P.monoms.splice(index, 1)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return P.reduce()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function rndFactorablePolynom(userConfig?: randomPolynomConfig): Polynom {
|
|
70
|
+
const config = Object.assign(
|
|
71
|
+
factorableConfig,
|
|
72
|
+
userConfig
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
const P = new Polynom().one()
|
|
76
|
+
|
|
77
|
+
const _factorableConfig = { ...config }
|
|
78
|
+
_factorableConfig.degree = 1
|
|
79
|
+
_factorableConfig.factorable = false
|
|
80
|
+
|
|
81
|
+
for (let i = 0; i < config.degree; i++) {
|
|
82
|
+
P.multiply(rndPolynom(_factorableConfig))
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return P.reduce()
|
|
86
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { randomCoefficientConfig } from "../rndTypes"
|
|
2
|
+
import { Fraction } from "../../coefficients/fraction"
|
|
3
|
+
import { randomInt, randomIntSym } from "../rndHelpers"
|
|
4
|
+
|
|
5
|
+
export function rndFraction(userConfig?: randomCoefficientConfig): Fraction {
|
|
6
|
+
const config = Object.assign(
|
|
7
|
+
{
|
|
8
|
+
negative: true,
|
|
9
|
+
max: 10,
|
|
10
|
+
reduced: true,
|
|
11
|
+
zero: true,
|
|
12
|
+
natural: false
|
|
13
|
+
}, userConfig)
|
|
14
|
+
|
|
15
|
+
// Create a null fraction
|
|
16
|
+
const Q = new Fraction()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
if (config.negative) {
|
|
20
|
+
// Allow negative numbers
|
|
21
|
+
Q.numerator = randomIntSym(config.max, config.zero)
|
|
22
|
+
} else {
|
|
23
|
+
// Only positive numbers
|
|
24
|
+
Q.numerator = randomInt(config.zero ? 0 : 1, config.max)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (config.natural) {
|
|
28
|
+
Q.denominator = 1
|
|
29
|
+
} else {
|
|
30
|
+
let securityCount = 0
|
|
31
|
+
while (Q.isRelative() && securityCount < 10) {
|
|
32
|
+
Q.denominator = randomInt(1, config.max)
|
|
33
|
+
securityCount++
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return config.reduced ? Q.reduce() : Q
|
|
38
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Circle } from "../../geometry/circle"
|
|
2
|
+
import { randomInt } from "../rndHelpers"
|
|
3
|
+
import type { randomGeometryCircleConfig } from "../rndTypes"
|
|
4
|
+
import { rndVector } from "./rndVector"
|
|
5
|
+
|
|
6
|
+
export function rndCircle(userConfig?: randomGeometryCircleConfig): Circle {
|
|
7
|
+
const config = Object.assign(
|
|
8
|
+
{
|
|
9
|
+
center: {
|
|
10
|
+
x: { min: -10, max: 10 },
|
|
11
|
+
y: { min: -10, max: 10 }
|
|
12
|
+
},
|
|
13
|
+
pointsOnCircle: 8
|
|
14
|
+
}, userConfig)
|
|
15
|
+
|
|
16
|
+
const center = rndVector(config.center)
|
|
17
|
+
|
|
18
|
+
let rv, r
|
|
19
|
+
if (config.pointsOnCircle === 8) {
|
|
20
|
+
rv = randomInt(1, 3),
|
|
21
|
+
r = rv ** 2 + (rv + 1) ** 2
|
|
22
|
+
} else {
|
|
23
|
+
r = randomInt(1, 20)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return new Circle(center, r, true)
|
|
27
|
+
}
|