pimath 0.0.131 → 0.0.133

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 (33) hide show
  1. package/dist/main.d.ts +39 -1
  2. package/package.json +2 -3
  3. package/dist/maths/pimath.d.ts +0 -39
  4. package/lib/main.ts +0 -1
  5. package/lib/maths/algebra/equation.ts +0 -891
  6. package/lib/maths/algebra/linearSystem.ts +0 -369
  7. package/lib/maths/algebra/logicalset.ts +0 -183
  8. package/lib/maths/algebra/monom.ts +0 -1027
  9. package/lib/maths/algebra/polynom.ts +0 -1537
  10. package/lib/maths/algebra/rational.ts +0 -244
  11. package/lib/maths/algebra/study/rationalStudy.ts +0 -287
  12. package/lib/maths/algebra/study.ts +0 -506
  13. package/lib/maths/coefficients/fraction.ts +0 -593
  14. package/lib/maths/coefficients/nthRoot.ts +0 -148
  15. package/lib/maths/geometry/circle.ts +0 -379
  16. package/lib/maths/geometry/line.ts +0 -604
  17. package/lib/maths/geometry/point.ts +0 -215
  18. package/lib/maths/geometry/triangle.ts +0 -368
  19. package/lib/maths/geometry/vector.ts +0 -243
  20. package/lib/maths/numeric.ts +0 -162
  21. package/lib/maths/numexp.ts +0 -198
  22. package/lib/maths/pimath.ts +0 -40
  23. package/lib/maths/randomization/random.ts +0 -80
  24. package/lib/maths/randomization/randomCore.ts +0 -19
  25. package/lib/maths/randomization/rndFraction.ts +0 -47
  26. package/lib/maths/randomization/rndGeometryCircle.ts +0 -50
  27. package/lib/maths/randomization/rndGeometryLine.ts +0 -53
  28. package/lib/maths/randomization/rndGeometryPoint.ts +0 -69
  29. package/lib/maths/randomization/rndHelpers.ts +0 -107
  30. package/lib/maths/randomization/rndMonom.ts +0 -57
  31. package/lib/maths/randomization/rndPolynom.ts +0 -90
  32. package/lib/maths/randomization/rndTypes.ts +0 -43
  33. package/lib/maths/shutingyard.ts +0 -496
@@ -1,369 +0,0 @@
1
- import {Equation, ISolution} from "./equation";
2
- import {Monom} from "./monom";
3
- import {Fraction} from "../coefficients/fraction";
4
- import {Polynom} from "./polynom";
5
- import {Numeric} from "../numeric.ts";
6
-
7
- // TODO: Must check and rework
8
- export class LinearSystem {
9
- // Stores the original equations
10
- private _equations: Equation[];
11
- // Determine the letters in the linear system, usually ['x', 'y']
12
- private _letters: string[];
13
- // Resolution steps contains each steps
14
- // letter : target letter
15
- // steps: {system: current LinearSystem, operations: [*3,/5] or [[*3,*2], [,*5], [*2,]]}
16
- private _resolutionSteps: {
17
- [key: string]: {
18
- equations: Equation[],
19
- operations: (string[])[]
20
- }[]
21
- };
22
- // Get the solution of the equation
23
- private _solutions: { [letter: string]: ISolution };
24
-
25
- constructor(...equationStrings: (string | Equation)[]) {
26
- // TODO: allow construction to accept an array of values (like a matrix) to build the equations
27
- this._equations = [];
28
- this._letters = 'xyz'.split('');
29
-
30
- if (equationStrings !== undefined && equationStrings.length > 0) {
31
- this.parse(...equationStrings);
32
- }
33
-
34
- return this;
35
- }
36
-
37
- // ------------------------------------------
38
- // Getter and setter
39
- // ------------------------------------------
40
- get equations(): Equation[] {
41
- return this._equations;
42
- }
43
-
44
- set equations(value) {
45
- this._equations = value;
46
- }
47
-
48
- get letters(): string {
49
- return this._letters.join('')
50
- }
51
-
52
- set letters(value: string) {
53
- this._letters = value.split('');
54
- }
55
-
56
- get isSolvable(): boolean {
57
- let V = this.variables;
58
-
59
- // TODO: in some case, it is possible to resolve systems if there isn't the isSame number of vars and equations
60
- if (V.length !== this._equations.length) {
61
- return false;
62
- }
63
-
64
- //TODO: Must check if two equations isn't a linear combination of the others ?
65
-
66
- return true;
67
- }
68
-
69
- get variables(): string[] {
70
- return this._letters
71
- }
72
-
73
- get tex(): string {
74
- // Build the array of values.
75
- // Reorder
76
- // This clone the system :!!!
77
- //TODO: Avoid cloning this linear system
78
- let LS = this.clone().reorder(),
79
- letters = LS.variables
80
-
81
- return this.buildTex(LS.equations)
82
- }
83
-
84
- get solution(): string {
85
- let tex: string[] = [];
86
-
87
- if (this._solutions === undefined) {
88
- this.solve();
89
- }
90
-
91
- for (let letter in this._solutions) {
92
- if (this._solutions[letter].display === "RR") {
93
- return `\\left\\{ \\left(${this._letters.join(';')}\\right) \\big\\vert ${this.equations[0].tex} \\right\\}`;
94
- }
95
- if (this._solutions[letter].display === "O/") {
96
- return `\\varnothing`
97
- }
98
-
99
- tex.push(this._solutions[letter].tex);
100
- }
101
- return `\\left(${tex.join(';')}\\right)`;
102
- }
103
-
104
- get solutionAsDisplay(): string {
105
- let display: string[] = [];
106
-
107
- if (this._solutions === undefined) {
108
- this.solve();
109
- }
110
-
111
- for (let letter in this._solutions) {
112
- if (this._solutions[letter].display === "RR") {
113
- return `{(${this._letters.join(';')}) | ${this.equations[0].display} }`;
114
- }
115
- if (this._solutions[letter].display === "O/") {
116
- return "O/"
117
- }
118
-
119
- display.push(this._solutions[letter].display);
120
- }
121
- return `(${display.join(';')})`;
122
- }
123
-
124
- get resolutionSteps(): { [p: string]: { equations: Equation[]; operations: string[][] }[] } {
125
- return this._resolutionSteps;
126
- }
127
-
128
- buildTex = (equations: Equation[], operators?: (string[])[]): string => {
129
- let equStr: string[],
130
- equArray: string[] = [],
131
- m: Monom,
132
- letters: string[] = []
133
-
134
- // Get the letters from the linear system
135
- for (let equ of equations) {
136
- letters = letters.concat(equ.letters())
137
- }
138
- letters = [...new Set(letters)]
139
- letters.sort()
140
-
141
- for (let i = 0; i < equations.length; i++) {
142
- let equ = equations[i]
143
-
144
- equStr = [];
145
- for (let L of letters) {
146
- m = equ.left.monomByLetter(L);
147
-
148
- if (equStr.length === 0) {
149
- equStr.push(m.isZero() ? '' : m.tex);
150
- } else {
151
- equStr.push(m.isZero() ? '' : ((m.coefficient.sign() === 1) ? '+' : '') + m.tex);
152
- }
153
- }
154
-
155
- // Add the equal sign
156
- equStr.push('=');
157
-
158
- // Add the right hand part of the equation (should be only a number, because it has been reordered)
159
- equStr.push(equ.right.tex);
160
-
161
- // Add the operations if existing
162
- if (operators !== undefined && operators[i] !== undefined) {
163
- // add extra space at the end of the equation
164
- equStr[equStr.length - 1] = equStr[equStr.length - 1] + ' \\phantom{\\quad}'
165
- for (let o of operators[i]) {
166
- equStr.push(`\\ \\cdot\\ ${o.startsWith('-') ? "\\left(" + o + "\\right)" : o}`)
167
- }
168
- }
169
-
170
- // Add to the list.
171
- equArray.push(equStr.join('&'));
172
- }
173
-
174
- let operatorsColumns = 0
175
- if (operators !== undefined && operators.length > 0) {
176
- operatorsColumns = operators[0].length
177
- }
178
- return `\\left\\{\\begin{array}{${"r".repeat(letters.length)}cl ${"|l".repeat(operatorsColumns)}}${equArray.join('\\\\\ ')}\\end{array}\\right.`;
179
- }
180
-
181
- stepTex = (letter: string): string => {
182
- const steps = this._resolutionSteps[letter]
183
-
184
- if (steps === undefined) {
185
- return ''
186
- }
187
-
188
- // steps = { equations[], operations: [[],[]]
189
- let tex: string[] = []
190
- for (let i = 0; i < steps.length; i++) {
191
- tex.push(this.buildTex(steps[i].equations, steps[i].operations))
192
- }
193
-
194
- return `\\begin{aligned}&${tex.join('\\\\&')}\\end{aligned}`
195
-
196
- }
197
-
198
- // ------------------------------------------
199
- // Creation / parsing functions
200
-
201
- // ------------------------------------------
202
- parse = (...equations: (string | Equation)[]): LinearSystem => {
203
- // make the original equations
204
- this._equations = equations.map(value => new Equation(value));
205
- // get the letters.
206
- this._findLetters();
207
- return this;
208
- };
209
-
210
- clone = (): LinearSystem => {
211
- return new LinearSystem().parse(...this._equations.map(equ => equ.clone()));
212
- };
213
-
214
- // ------------------------------------------
215
- reorder = (): LinearSystem => {
216
- for (let E of this._equations) {
217
- E.reorder();
218
- }
219
- return this;
220
- };
221
-
222
-
223
- // -----------------------------------------------
224
- // Equations solving algorithms
225
-
226
- solve = (withResolution?: boolean): LinearSystem => {
227
- // Solve it by linear
228
- this._solutions = {};
229
- this._resolutionSteps = {};
230
-
231
- // Reorder all equations.
232
- this.reorder();
233
-
234
- if (withResolution === undefined) {
235
- withResolution = false
236
- }
237
-
238
- for (let letter of this.variables) {
239
- this._solutions[letter] = this._solveOneLetter(letter, withResolution)
240
- }
241
-
242
- // TODO: LinearSystem - solve: optimization and handle undetermined and undefined systems.
243
- return this;
244
- };
245
-
246
- mergeEquations = (eq1: Equation, eq2: Equation, factor1: Fraction, factor2: Fraction): Equation => {
247
- // Set and clone the equations.
248
-
249
- let eq1multiplied = eq1.clone().multiply(new Fraction(factor1)),
250
- eq2multiplied = eq2.clone().multiply(new Fraction(factor2));
251
-
252
- // Add both equations together.
253
- eq1multiplied.left.add(eq2multiplied.left);
254
- eq1multiplied.right.add(eq2multiplied.right);
255
-
256
- return eq1multiplied;
257
- }
258
-
259
- private _findLetters = (): LinearSystem => {
260
- // Find all letters used.
261
- let variables: Set<string> = new Set();
262
-
263
- for (let equ of this._equations) {
264
- variables = new Set([...variables, ...equ.variables]);
265
- }
266
-
267
- this._letters = [...variables];
268
- this._letters.sort()
269
- return this;
270
- }
271
-
272
- private _linearReduction(eq1: Equation, eq2: Equation, letter: string): { merged: Equation, factors: Fraction[] } {
273
- // Get the monom for the particular letter.
274
- let c1 = eq1.left.monomByDegree(1, letter).coefficient.clone(),
275
- c2 = eq2.left.monomByDegree(1, letter).coefficient.clone().opposed();
276
-
277
- // Reduce c1 and c2 by the gcd
278
- const gcdN = Numeric.gcd(c1.numerator, c2.numerator),
279
- gcdD = Numeric.gcd(c1.denominator, c2.denominator)
280
- c1.divide(gcdN).multiply(gcdD)
281
- c2.divide(gcdN).multiply(gcdD)
282
-
283
- // if one value is -1, use 1 and make the other one opposed
284
- if (c2.isNegativeOne()) {
285
- c1.opposed()
286
- c2.opposed()
287
- } else if (c1.isNegativeOne()) {
288
- c1.opposed()
289
- c2.opposed()
290
- }
291
-
292
- return {
293
- merged: this.mergeEquations(eq1, eq2, c2, c1),
294
- factors: [c2, c1]
295
- }
296
- }
297
-
298
- /**
299
- * Linear reduction of the equations to have only one letter
300
- * @param letter letter to isolate
301
- * @private
302
- */
303
- private _solveOneLetter(letter: string, withResolution: boolean): ISolution {
304
- // list of equations.
305
- let LE: Equation[] = this.clone().equations,
306
- reducedEquations: Equation[] = [],
307
- lastIndex
308
-
309
- this._resolutionSteps[letter] = []
310
-
311
- // Reduce the equations.
312
- // Do it as long as there is more than one step, but no more than the number of equations.
313
- for (let L of this.variables) {
314
- // Reset the stack
315
- reducedEquations = [];
316
-
317
- // remove the setLetter from all equations using linear combinations
318
- if (L === letter) continue;
319
-
320
- if (withResolution) {
321
- this._resolutionSteps[letter].push({
322
- equations: LE.map(x => x.clone()),
323
- operations: [...new Array(LE.length)].map(x => [...new Array(LE.length - 1)].map(x => ""))
324
- })
325
- lastIndex = this._resolutionSteps[letter].length - 1
326
- }
327
-
328
- // Linear reduction.
329
- for (let i = 0; i < LE.length - 1; i++) {
330
- const result = this._linearReduction(LE[i], LE[i + 1], L)
331
- reducedEquations.push(result.merged)
332
-
333
- if (withResolution) {
334
- this._resolutionSteps[letter][lastIndex].operations[i][i] = result.factors[0].tex
335
- this._resolutionSteps[letter][lastIndex].operations[i + 1][i] = result.factors[1].tex
336
- }
337
- }
338
-
339
- LE = [...reducedEquations]
340
- }
341
-
342
- // Solve the equations
343
- // let E = this._resolutionSteps[this._resolutionSteps.length - 1].equations[0];
344
- let E = LE[0];
345
- E.solve()
346
- const solution = E.solutions[0]
347
-
348
- if (withResolution) {
349
- this._resolutionSteps[letter].push({
350
- equations: [LE[0]],
351
- operations: [[LE[0].left.monoms[0].coefficient.tex]]
352
- })
353
-
354
- let P: Polynom
355
- if (solution.exact instanceof Fraction || typeof solution.exact === "string") {
356
- P = new Polynom(solution.exact)
357
- } else {
358
- P = new Polynom(solution.value)
359
- }
360
- this._resolutionSteps[letter].push({
361
- equations: [new Equation(new Polynom(letter), P)],
362
- operations: []
363
- })
364
-
365
- }
366
- return E.solutions[0]
367
- }
368
-
369
- }
@@ -1,183 +0,0 @@
1
- /**
2
- * Polynom module contains everything necessary to handle polynoms.
3
- * @module Logicalset
4
- */
5
-
6
- import {Shutingyard, ShutingyardMode} from '../shutingyard.ts';
7
-
8
- /**
9
- * Polynom class can handle polynoms, reorder, resolve, ...
10
- */
11
- export class Logicalset {
12
- private _rawString: string;
13
- private _rpn: { token: string, tokenType: string }[]
14
-
15
- /**
16
- *
17
- * @param {string} value (optional) Default polynom to parse on class creation
18
- */
19
- constructor(value: string) {
20
- this._rawString = value
21
- this.parse(value)
22
- return this;
23
- }
24
-
25
- get isLogicalset() {
26
- return true;
27
- };
28
-
29
- get rpn(): { token: string, tokenType: string }[] {
30
- return this._rpn
31
- }
32
-
33
- get tex(): string {
34
- let varStack: { token: string, tokenType: string } [] = []
35
-
36
- for (let token of this._rpn) {
37
- if (token.tokenType === 'variable') {
38
- varStack.push(token);
39
- } else {
40
- switch (token.token) {
41
- case '&':
42
- if (varStack.length >= 2) {
43
- let second = varStack.pop(),
44
- first = varStack.pop()
45
-
46
- if (first.tokenType === 'mix') {
47
- first.token = `( ${first.token} )`
48
- }
49
- if (second.tokenType === 'mix') {
50
- second.token = `( ${second.token} )`
51
- }
52
- varStack.push({token: `${first.token} \\cap ${second.token}`, tokenType: 'mix'})
53
- }
54
- break
55
- case '|':
56
- if (varStack.length >= 2) {
57
- let second = varStack.pop(),
58
- first = varStack.pop()
59
-
60
- if (first.tokenType === 'mix') {
61
- first.token = `( ${first.token} )`
62
- }
63
- if (second.tokenType === 'mix') {
64
- second.token = `( ${second.token} )`
65
- }
66
- varStack.push({token: `${first.token} \\cup ${second.token}`, tokenType: 'mix'})
67
- }
68
- break
69
- case '-':
70
- if (varStack.length >= 2) {
71
- let second = varStack.pop(),
72
- first = varStack.pop()
73
-
74
- if (first.tokenType === 'mix') {
75
- first.token = `( ${first.token} )`
76
- }
77
- if (second.tokenType === 'mix') {
78
- second.token = `( ${second.token} )`
79
- }
80
- varStack.push({token: `${first.token} \\setminus ${second.token}`, tokenType: 'mix'})
81
- }
82
- break
83
- case '!':
84
- if (varStack.length >= 1) {
85
- let first = varStack.pop()
86
- varStack.push({token: `\\overline{ ${first.token} }`, tokenType: 'variable'})
87
- }
88
- break
89
- }
90
- }
91
- }
92
-
93
- return varStack[0].token
94
- }
95
-
96
- evaluate(tokenSets: { [key: string]: unknown[] }, reference?: unknown[]): unknown[] {
97
- let varStack: (Set<unknown>)[] = []
98
-
99
- let referenceSet: Set<unknown>
100
- if (reference === undefined) {
101
- referenceSet = new Set()
102
- for (let key in tokenSets) {
103
- referenceSet = new Set([...referenceSet, ...tokenSets[key]])
104
- }
105
- } else {
106
- referenceSet = new Set(reference)
107
- }
108
-
109
- for (let token of this._rpn) {
110
- if (token.tokenType === 'variable') {
111
- // The variable has no token - assume it's empty.
112
- if (tokenSets[token.token] === undefined) {
113
- varStack.push(new Set())
114
- } else {
115
- varStack.push(new Set(tokenSets[token.token]));
116
- }
117
-
118
- } else {
119
- switch (token.token) {
120
- case '&':
121
- if (varStack.length >= 2) {
122
- let second = varStack.pop(),
123
- first = varStack.pop()
124
-
125
- varStack.push(new Set([...first].filter(x => second.has(x))))
126
- }
127
- break
128
- case '|':
129
- if (varStack.length >= 2) {
130
- let second = varStack.pop(),
131
- first = varStack.pop()
132
- varStack.push(new Set([...first, ...second]))
133
- }
134
- break
135
- case '-':
136
- if (varStack.length >= 2) {
137
- let second = varStack.pop(),
138
- first = varStack.pop()
139
- varStack.push(new Set([...first].filter(x => !second.has(x))))
140
- }
141
- break
142
- case '!':
143
- if (varStack.length >= 1) {
144
- let first = varStack.pop()
145
-
146
- varStack.push(new Set([...referenceSet].filter(x => !first.has(x))))
147
- }
148
- break
149
- }
150
- }
151
- }
152
-
153
- return [...varStack[0]].sort();
154
- }
155
-
156
- vennAB(): any[] {
157
- return this.evaluate({
158
- A: ['A', 'AB'],
159
- B: ['B', 'AB']
160
- },
161
- ['A', 'B', 'AB', 'E']
162
- )
163
- }
164
-
165
- vennABC(): any[] {
166
- return this.evaluate({
167
- A: ['A', 'AB', 'AC', 'ABC'],
168
- B: ['B', 'AB', 'BC', 'ABC'],
169
- C: ['C', 'AC', 'BC', 'ABC']
170
- },
171
- ['A', 'B', 'C', 'AB', 'AC', 'BC', 'E']
172
- )
173
- }
174
-
175
- private parse = (value: string): Logicalset => {
176
- // TODO: Must format the value string to convert some items...
177
-
178
- // Parse the updated value to the shutingyard algorithm
179
- this._rpn = new Shutingyard(ShutingyardMode.SET).parse(value).rpn;
180
-
181
- return this;
182
- }
183
- }