pimath 0.2.13 → 0.2.15

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 (59) hide show
  1. package/dist/pimath.js +856 -1882
  2. package/dist/pimath.js.map +1 -1
  3. package/package.json +2 -2
  4. package/src/algebra/equation.ts +562 -558
  5. package/src/algebra/equationSolver.ts +489 -489
  6. package/src/algebra/factor.ts +396 -392
  7. package/src/algebra/linearSystem.ts +446 -442
  8. package/src/algebra/matrix.ts +515 -511
  9. package/src/algebra/monom.ts +932 -928
  10. package/src/algebra/polyFactor.ts +724 -720
  11. package/src/algebra/polynom.ts +1233 -1229
  12. package/src/coefficients/fraction.ts +907 -748
  13. package/src/coefficients/root.ts +500 -359
  14. package/src/geometry/TupleN.ts +129 -129
  15. package/src/geometry/circle.ts +455 -455
  16. package/src/geometry/line.ts +658 -654
  17. package/src/geometry/point.ts +105 -105
  18. package/src/geometry/sphere3.ts +2 -2
  19. package/src/geometry/triangle.ts +488 -488
  20. package/src/geometry/vector.ts +230 -226
  21. package/src/numeric.ts +136 -51
  22. package/src/pimath.interface.ts +2 -0
  23. package/types/algebra/equation.d.ts +1 -0
  24. package/types/algebra/equation.d.ts.map +1 -1
  25. package/types/algebra/equationSolver.d.ts.map +1 -1
  26. package/types/algebra/factor.d.ts +1 -0
  27. package/types/algebra/factor.d.ts.map +1 -1
  28. package/types/algebra/linearSystem.d.ts +1 -0
  29. package/types/algebra/linearSystem.d.ts.map +1 -1
  30. package/types/algebra/matrix.d.ts +6 -5
  31. package/types/algebra/matrix.d.ts.map +1 -1
  32. package/types/algebra/monom.d.ts +1 -0
  33. package/types/algebra/monom.d.ts.map +1 -1
  34. package/types/algebra/polyFactor.d.ts +1 -0
  35. package/types/algebra/polyFactor.d.ts.map +1 -1
  36. package/types/algebra/polynom.d.ts +1 -0
  37. package/types/algebra/polynom.d.ts.map +1 -1
  38. package/types/coefficients/fraction.d.ts +62 -53
  39. package/types/coefficients/fraction.d.ts.map +1 -1
  40. package/types/coefficients/root.d.ts +3 -0
  41. package/types/coefficients/root.d.ts.map +1 -1
  42. package/types/geometry/TupleN.d.ts +1 -1
  43. package/types/geometry/TupleN.d.ts.map +1 -1
  44. package/types/geometry/circle.d.ts.map +1 -1
  45. package/types/geometry/line.d.ts +1 -0
  46. package/types/geometry/line.d.ts.map +1 -1
  47. package/types/geometry/point.d.ts.map +1 -1
  48. package/types/geometry/sphere3.d.ts +2 -2
  49. package/types/geometry/sphere3.d.ts.map +1 -1
  50. package/types/geometry/triangle.d.ts.map +1 -1
  51. package/types/geometry/vector.d.ts +1 -0
  52. package/types/geometry/vector.d.ts.map +1 -1
  53. package/types/index.d.ts +3 -3
  54. package/types/numeric.d.ts +4 -4
  55. package/types/numeric.d.ts.map +1 -1
  56. package/types/pimath.interface.d.ts +1 -0
  57. package/types/pimath.interface.d.ts.map +1 -1
  58. package/types/primes.data.d.ts +2 -0
  59. package/types/primes.data.d.ts.map +1 -0
@@ -1,392 +1,396 @@
1
- import type {
2
- IAlgebra,
3
- IExpression,
4
- InputAlgebra,
5
- InputValue,
6
- IPiMathObject,
7
- literalType,
8
- TABLE_OF_SIGNS
9
- } from "../pimath.interface"
10
- import {Fraction} from "../coefficients/fraction"
11
- import {Polynom} from "./polynom"
12
- import {replace_in_array, splitIfOutsideParentheses, wrapParenthesis} from "../helpers"
13
- import {MathError, NotImplementedError} from "../errors"
14
-
15
- export class Factor implements IPiMathObject<Factor>,
16
- IExpression<Factor>,
17
- IAlgebra<Factor> {
18
- #displayMode: FACTOR_DISPLAY
19
- #polynom: Polynom
20
- #power: Fraction
21
- #singleMode = false
22
-
23
- constructor(value?: InputAlgebra<Polynom> | Factor, power?: InputValue<Fraction>) {
24
-
25
- if (value instanceof Factor) {
26
- this.#polynom = value.polynom.clone()
27
- this.#power = value.power.clone()
28
-
29
- if (power !== undefined) {
30
- this.#power.multiply(new Fraction(power))
31
- }
32
- } else if (value !== undefined) {
33
- this.#polynom = new Polynom(value)
34
- this.#power = new Fraction(power ?? 1)
35
- } else {
36
- this.#polynom = new Polynom()
37
- this.#power = new Fraction(1)
38
- }
39
-
40
- this.#displayMode = FACTOR_DISPLAY.POWER
41
-
42
- return this
43
- }
44
-
45
- public parse(/*value: InputValue<Factor>*/): Factor {
46
- throw new NotImplementedError("Method not implemented.")
47
- }
48
-
49
- public clone(): Factor {
50
- return new Factor(this)
51
- }
52
-
53
- public get tex(): string {
54
- const num = this.power.numerator
55
- const den = this.power.denominator
56
-
57
- let base: string
58
- let power: string
59
-
60
- if (this.#displayMode === FACTOR_DISPLAY.ROOT && den > 1) {
61
- base = `\\sqrt${den === 2 ? '' : `[ ${den} ]`}{ ${this.polynom.tex} }`
62
- power = num === 1 ? '' : `^{ ${num} }`
63
- } else {
64
- base = this.#singleMode && this.power.isOne() ? this.polynom.tex : wrapParenthesis(this.polynom.tex)
65
- power = (den === 1 && num === 1) ? '' : `^{ ${this.power.tex} }`
66
- }
67
-
68
- // Add the power if it's not 1 or -1
69
- base = `${base}${power}`
70
-
71
- // If the power is negative, make it as a fraction.
72
- if (this.#displayMode === FACTOR_DISPLAY.ROOT && num < 0) {
73
- base = `\\frac{ 1 }{ ${base} }`
74
- }
75
-
76
-
77
- return base
78
- }
79
-
80
- public get display(): string {
81
- const num = this.power.numerator
82
- const den = this.power.denominator
83
-
84
- let base: string
85
- let power: string
86
-
87
- if (this.#displayMode === FACTOR_DISPLAY.ROOT && den > 1) {
88
- base = `${den === 2 ? 'sqrt' : `root(${den})`}(${this.polynom.display})`
89
- power = num === 1 ? '' : `^(${num})`
90
- } else {
91
- base = this.#singleMode && this.power.isOne() ? this.polynom.display : wrapParenthesis(this.polynom.display, false)
92
- power = (den === 1 && num === 1) ? '' : `^(${this.power.display})`
93
- }
94
-
95
- // Add the power if it's not 1 or -1
96
- base = `${base}${power}`
97
-
98
- // If the power is negative, make it as a fraction.
99
- if (this.#displayMode === FACTOR_DISPLAY.ROOT && num < 0) {
100
- base = `1/(${base})`
101
- }
102
-
103
-
104
- return base
105
- }
106
-
107
- public add(): Factor {
108
- throw new MathError("Adding two factors is not possible")
109
- }
110
-
111
- public get asSingle(): this {
112
- this.#singleMode = true
113
- return this
114
- }
115
-
116
- public degree(letter?: string): Fraction {
117
- return this.polynom.degree(letter).multiply(this.power)
118
- }
119
-
120
- public derivative(): Factor[] {
121
- // The power is zero, the derivative is zero
122
- if (this.power.isZero()) {
123
- return [new Factor('0')]
124
- }
125
-
126
- // The power is one, the derivative is the derivative of the polynom
127
- if (this.power.isOne()) {
128
- return [new Factor(this.polynom.clone().derivative())]
129
- }
130
-
131
- // In any other case, the derivative consist of three Factors:
132
- // the derivative of the polynom, the power and the polynom
133
- return [
134
- new Factor(this.power.clone()),
135
- new Factor(this.polynom.clone().derivative()),
136
- new Factor(this.polynom.clone(), this.power.clone().subtract(1))
137
- ]
138
- }
139
-
140
- public develop(): Polynom {
141
- if (this.power.isNatural()) {
142
- return this.polynom.clone().pow(this.power.value)
143
- }
144
-
145
- throw new MathError("The power must be a natural number")
146
- }
147
-
148
- public divide(value: InputAlgebra<Factor | Polynom>): this {
149
- if (value instanceof Factor) {
150
- if (this.isSameAs(value)) {
151
- this.power.subtract(value.power)
152
- return this
153
- }
154
- }
155
-
156
-
157
- const P = new Polynom(value as Polynom)
158
- if (this.isSameAs(P)) {
159
- this.power.subtract(1)
160
- return this
161
- }
162
-
163
- throw new MathError("The two factors must be the same")
164
- }
165
-
166
- public evaluate(values: InputValue<Fraction> | literalType<number | Fraction>, asNumeric?: boolean): number | Fraction {
167
- if (asNumeric) {
168
- return (this.polynom.evaluate(values, true) as number) ** this.power.value
169
- }
170
-
171
-
172
- return (this.polynom.evaluate(values) as Fraction).pow(this.power)
173
- }
174
-
175
- public fromPolynom(polynom: InputValue<Polynom>): this {
176
- this.#polynom = new Polynom(polynom)
177
- this.#power = new Fraction(1)
178
- return this
179
- }
180
-
181
- public hasVariable(letter: string): boolean {
182
- return this.polynom.hasVariable(letter)
183
- }
184
-
185
- public inverse(): this {
186
- this.power.opposite()
187
- return this
188
- }
189
-
190
- public isEqual(value: Factor): boolean {
191
- // Must have the same polynom and the same reduce power
192
-
193
- return this.isSameAs(value) &&
194
- this.power.isEqual(value.power)
195
- }
196
-
197
- public isOne(): boolean {
198
- return this.polynom.isOne() || this.power.isZero()
199
- }
200
-
201
- public isSameAs(value: InputAlgebra<Factor | Polynom>) {
202
- let P: Polynom
203
- if (value instanceof Factor) {
204
- P = value.polynom
205
- } else if (value instanceof Polynom) {
206
- P = value
207
- } else {
208
- P = new Polynom(value)
209
- }
210
-
211
-
212
- return this.polynom.isEqual(P)
213
- }
214
-
215
- public isZero(): boolean {
216
- return this.polynom.isZero()
217
- }
218
-
219
- public multiply(value: InputAlgebra<Factor | Polynom>): this {
220
- const F = new Factor(value)
221
-
222
- // Case if this and value are monoms of degree one.
223
- if(this.polynom.monoms.length===1 && this.power.isOne()
224
- &&
225
- F.polynom.monoms.length===1 && this.power.isOne()
226
- ){
227
- this.polynom.multiply(F.polynom)
228
- return this
229
- }
230
-
231
- if (value instanceof Factor) {
232
- if (this.isSameAs(value)) {
233
- this.power.add(value.power)
234
- return this
235
- }
236
- }
237
-
238
-
239
- const P = new Polynom(value as Polynom)
240
- if (this.isSameAs(P)) {
241
- this.power.add(1)
242
- return this
243
- }
244
-
245
- throw new MathError("The two factors must be the same")
246
- }
247
-
248
- public one(): this {
249
- this.#polynom.one()
250
- this.#power.one()
251
- return this
252
- }
253
-
254
- public opposite(): Factor {
255
- throw new NotImplementedError("Method not implemented.")
256
- }
257
-
258
- public get polynom(): Polynom {
259
- return this.#polynom
260
- }
261
-
262
- public set polynom(value: Polynom) {
263
- this.#polynom = value
264
- }
265
-
266
- public pow(value: number | Fraction): this {
267
- this.power.multiply(value)
268
- return this
269
- }
270
-
271
- public get power(): Fraction {
272
- return this.#power
273
- }
274
-
275
- public set power(value: InputValue<Fraction>) {
276
- this.#power = new Fraction(value)
277
- }
278
-
279
- public primitive(): Factor {
280
- throw new NotImplementedError("Method not implemented.")
281
- }
282
-
283
- public reduce(): Factor {
284
- throw new NotImplementedError("Method not implemented.")
285
- }
286
-
287
- public root(value: number): this {
288
- this.power.divide(value)
289
- return this
290
- }
291
-
292
- public sqrt(): this {
293
- return this.root(2)
294
- }
295
-
296
- public subtract(): Factor {
297
- throw new MathError("Subtracting two factors is not possible")
298
- }
299
-
300
- public tableOfSigns(): TABLE_OF_SIGNS {
301
- const pow = this.power.clone().reduce()
302
- const tos = this.polynom.tableOfSigns()
303
-
304
- // The zero roots becomes defence (d) if the power is negative
305
- if (pow.isStrictlyNegative()) {
306
- tos.signs = replace_in_array(tos.signs, 'z', 'd')
307
- }
308
-
309
- // The - sign becomes
310
- // + (plus) if the power num is even and the power den is odd
311
- // i (invalid) if the power denominator is even
312
- if (pow.denominator % 2 === 0) {
313
- // it's an even roots : no negative values!
314
- tos.signs = replace_in_array(tos.signs, '-', 'h')
315
- } else if (pow.numerator % 2 === 0) {
316
- // it's an even power : negative values becomes positive !
317
- tos.signs = replace_in_array(tos.signs, '-', '+')
318
- }
319
-
320
-
321
- return {roots: tos.roots, signs: tos.signs}
322
- }
323
-
324
- public get variables(): string[] {
325
- return this.polynom.variables
326
- }
327
-
328
- public get withPower(): this {
329
- this.#displayMode = FACTOR_DISPLAY.POWER
330
- return this
331
- }
332
-
333
- public get withRoot(): this {
334
- this.#displayMode = FACTOR_DISPLAY.ROOT
335
- return this
336
- }
337
-
338
- public zero(): this {
339
- this.#polynom.zero()
340
- this.#power.one()
341
- return this
342
- }
343
-
344
- static checkParseAsFactors(str: string): boolean {
345
- const splitPlus = splitIfOutsideParentheses(str, "+")
346
- if(splitPlus[0]==='') splitPlus.shift()
347
- if(splitPlus.length>1) return false
348
-
349
- const splitMinus = splitIfOutsideParentheses(str, "-")
350
- if(splitMinus[0]==='') splitMinus.shift()
351
- if(splitMinus.length>1) return false
352
-
353
- return true
354
- }
355
-
356
- static factorsFromString(value: string, isNumerator = true): Factor[] {
357
- if (!Factor.checkParseAsFactors(value)) {
358
- return [new Factor(value, isNumerator ? 1 : -1)]
359
- }
360
-
361
- const sign = isNumerator ? 1 : -1
362
- const factors: Factor[] = []
363
-
364
- // Alternance : facteur parenthésé avec puissance optionnelle | séquence non-parenthésée
365
- const regex =
366
- /\(([^)]+)\)(?:\^(-?[0-9]+(?:\/[0-9]+)?|\(-?[0-9]+(?:\/[0-9]+)?\)))?|([^(]+)/g
367
-
368
- for (const match of value.matchAll(regex)) {
369
- if (match[1] !== undefined) {
370
- // Cas : (expr)^puissance
371
- const powStr = (match[2] ?? '1')
372
- .replace(/[()]/g, '')
373
-
374
- factors.push(new Factor(
375
- new Polynom(match[1]),
376
- new Fraction(powStr).multiply(sign))
377
- )
378
- } else if (match[3]?.trim()) {
379
- // Cas : monôme ou constante hors parenthèses (ex: 3x^2, 3)
380
- factors.push(new Factor(new Polynom(match[3].trim()), new Fraction(sign)))
381
- }
382
- }
383
-
384
- return factors
385
- }
386
- }
387
-
388
- export enum FACTOR_DISPLAY {
389
- ROOT,
390
- POWER
391
- }
392
-
1
+ import type {
2
+ IAlgebra,
3
+ IExpression,
4
+ InputAlgebra,
5
+ InputValue,
6
+ IPiMathObject,
7
+ literalType,
8
+ TABLE_OF_SIGNS
9
+ } from "../pimath.interface"
10
+ import {Fraction} from "../coefficients/fraction"
11
+ import {Polynom} from "./polynom"
12
+ import {replace_in_array, splitIfOutsideParentheses, wrapParenthesis} from "../helpers"
13
+ import {MathError, NotImplementedError} from "../errors"
14
+
15
+ export class Factor implements IPiMathObject<Factor>,
16
+ IExpression<Factor>,
17
+ IAlgebra<Factor> {
18
+ #displayMode: FACTOR_DISPLAY
19
+ #polynom: Polynom
20
+ #power: Fraction
21
+ #singleMode = false
22
+
23
+ constructor(value?: InputAlgebra<Polynom> | Factor, power?: InputValue<Fraction>) {
24
+
25
+ if (value instanceof Factor) {
26
+ this.#polynom = value.polynom.clone()
27
+ this.#power = value.power.clone()
28
+
29
+ if (power !== undefined) {
30
+ this.#power.multiply(new Fraction(power))
31
+ }
32
+ } else if (value !== undefined) {
33
+ this.#polynom = new Polynom(value)
34
+ this.#power = new Fraction(power ?? 1)
35
+ } else {
36
+ this.#polynom = new Polynom()
37
+ this.#power = new Fraction(1)
38
+ }
39
+
40
+ this.#displayMode = FACTOR_DISPLAY.POWER
41
+
42
+ return this
43
+ }
44
+
45
+ parse(/*value: InputValue<Factor>*/): Factor {
46
+ throw new NotImplementedError("Method not implemented.")
47
+ }
48
+
49
+ copy(): this {
50
+ throw new NotImplementedError("copy() is not yet implemented for Factor")
51
+ }
52
+
53
+ clone(): Factor {
54
+ return new Factor(this)
55
+ }
56
+
57
+ get tex(): string {
58
+ const num = this.power.numerator
59
+ const den = this.power.denominator
60
+
61
+ let base: string
62
+ let power: string
63
+
64
+ if (this.#displayMode === FACTOR_DISPLAY.ROOT && den > 1) {
65
+ base = `\\sqrt${den === 2 ? '' : `[ ${den} ]`}{ ${this.polynom.tex} }`
66
+ power = num === 1 ? '' : `^{ ${num} }`
67
+ } else {
68
+ base = this.#singleMode && this.power.isOne() ? this.polynom.tex : wrapParenthesis(this.polynom.tex)
69
+ power = (den === 1 && num === 1) ? '' : `^{ ${this.power.tex} }`
70
+ }
71
+
72
+ // Add the power if it's not 1 or -1
73
+ base = `${base}${power}`
74
+
75
+ // If the power is negative, make it as a fraction.
76
+ if (this.#displayMode === FACTOR_DISPLAY.ROOT && num < 0) {
77
+ base = `\\frac{ 1 }{ ${base} }`
78
+ }
79
+
80
+
81
+ return base
82
+ }
83
+
84
+ get display(): string {
85
+ const num = this.power.numerator
86
+ const den = this.power.denominator
87
+
88
+ let base: string
89
+ let power: string
90
+
91
+ if (this.#displayMode === FACTOR_DISPLAY.ROOT && den > 1) {
92
+ base = `${den === 2 ? 'sqrt' : `root(${den})`}(${this.polynom.display})`
93
+ power = num === 1 ? '' : `^(${num})`
94
+ } else {
95
+ base = this.#singleMode && this.power.isOne() ? this.polynom.display : wrapParenthesis(this.polynom.display, false)
96
+ power = (den === 1 && num === 1) ? '' : `^(${this.power.display})`
97
+ }
98
+
99
+ // Add the power if it's not 1 or -1
100
+ base = `${base}${power}`
101
+
102
+ // If the power is negative, make it as a fraction.
103
+ if (this.#displayMode === FACTOR_DISPLAY.ROOT && num < 0) {
104
+ base = `1/(${base})`
105
+ }
106
+
107
+
108
+ return base
109
+ }
110
+
111
+ add(): Factor {
112
+ throw new MathError("Adding two factors is not possible")
113
+ }
114
+
115
+ get asSingle(): this {
116
+ this.#singleMode = true
117
+ return this
118
+ }
119
+
120
+ degree(letter?: string): Fraction {
121
+ return this.polynom.degree(letter).multiply(this.power)
122
+ }
123
+
124
+ derivative(): Factor[] {
125
+ // The power is zero, the derivative is zero
126
+ if (this.power.isZero()) {
127
+ return [new Factor('0')]
128
+ }
129
+
130
+ // The power is one, the derivative is the derivative of the polynom
131
+ if (this.power.isOne()) {
132
+ return [new Factor(this.polynom.clone().derivative())]
133
+ }
134
+
135
+ // In any other case, the derivative consist of three Factors:
136
+ // the derivative of the polynom, the power and the polynom
137
+ return [
138
+ new Factor(this.power.clone()),
139
+ new Factor(this.polynom.clone().derivative()),
140
+ new Factor(this.polynom.clone(), this.power.clone().subtract(1))
141
+ ]
142
+ }
143
+
144
+ develop(): Polynom {
145
+ if (this.power.isNatural()) {
146
+ return this.polynom.clone().pow(this.power.value)
147
+ }
148
+
149
+ throw new MathError("The power must be a natural number")
150
+ }
151
+
152
+ divide(value: InputAlgebra<Factor | Polynom>): this {
153
+ if (value instanceof Factor) {
154
+ if (this.isSameAs(value)) {
155
+ this.power.subtract(value.power)
156
+ return this
157
+ }
158
+ }
159
+
160
+
161
+ const P = new Polynom(value as Polynom)
162
+ if (this.isSameAs(P)) {
163
+ this.power.subtract(1)
164
+ return this
165
+ }
166
+
167
+ throw new MathError("The two factors must be the same")
168
+ }
169
+
170
+ evaluate(values: InputValue<Fraction> | literalType<number | Fraction>, asNumeric?: boolean): number | Fraction {
171
+ if (asNumeric) {
172
+ return (this.polynom.evaluate(values, true) as number) ** this.power.value
173
+ }
174
+
175
+
176
+ return (this.polynom.evaluate(values) as Fraction).pow(this.power)
177
+ }
178
+
179
+ fromPolynom(polynom: InputValue<Polynom>): this {
180
+ this.#polynom = new Polynom(polynom)
181
+ this.#power = new Fraction(1)
182
+ return this
183
+ }
184
+
185
+ hasVariable(letter: string): boolean {
186
+ return this.polynom.hasVariable(letter)
187
+ }
188
+
189
+ inverse(): this {
190
+ this.power.opposite()
191
+ return this
192
+ }
193
+
194
+ isEqual(value: Factor): boolean {
195
+ // Must have the same polynom and the same reduce power
196
+
197
+ return this.isSameAs(value) &&
198
+ this.power.isEqual(value.power)
199
+ }
200
+
201
+ isOne(): boolean {
202
+ return this.polynom.isOne() || this.power.isZero()
203
+ }
204
+
205
+ isSameAs(value: InputAlgebra<Factor | Polynom>) {
206
+ let P: Polynom
207
+ if (value instanceof Factor) {
208
+ P = value.polynom
209
+ } else if (value instanceof Polynom) {
210
+ P = value
211
+ } else {
212
+ P = new Polynom(value)
213
+ }
214
+
215
+
216
+ return this.polynom.isEqual(P)
217
+ }
218
+
219
+ isZero(): boolean {
220
+ return this.polynom.isZero()
221
+ }
222
+
223
+ multiply(value: InputAlgebra<Factor | Polynom>): this {
224
+ const F = new Factor(value)
225
+
226
+ // Case if this and value are monoms of degree one.
227
+ if(this.polynom.monoms.length===1 && this.power.isOne()
228
+ &&
229
+ F.polynom.monoms.length===1 && this.power.isOne()
230
+ ){
231
+ this.polynom.multiply(F.polynom)
232
+ return this
233
+ }
234
+
235
+ if (value instanceof Factor) {
236
+ if (this.isSameAs(value)) {
237
+ this.power.add(value.power)
238
+ return this
239
+ }
240
+ }
241
+
242
+
243
+ const P = new Polynom(value as Polynom)
244
+ if (this.isSameAs(P)) {
245
+ this.power.add(1)
246
+ return this
247
+ }
248
+
249
+ throw new MathError("The two factors must be the same")
250
+ }
251
+
252
+ one(): this {
253
+ this.#polynom.one()
254
+ this.#power.one()
255
+ return this
256
+ }
257
+
258
+ opposite(): Factor {
259
+ throw new NotImplementedError("Method not implemented.")
260
+ }
261
+
262
+ get polynom(): Polynom {
263
+ return this.#polynom
264
+ }
265
+
266
+ set polynom(value: Polynom) {
267
+ this.#polynom = value
268
+ }
269
+
270
+ pow(value: number | Fraction): this {
271
+ this.power.multiply(value)
272
+ return this
273
+ }
274
+
275
+ get power(): Fraction {
276
+ return this.#power
277
+ }
278
+
279
+ set power(value: InputValue<Fraction>) {
280
+ this.#power = new Fraction(value)
281
+ }
282
+
283
+ primitive(): Factor {
284
+ throw new NotImplementedError("Method not implemented.")
285
+ }
286
+
287
+ reduce(): Factor {
288
+ throw new NotImplementedError("Method not implemented.")
289
+ }
290
+
291
+ root(value: number): this {
292
+ this.power.divide(value)
293
+ return this
294
+ }
295
+
296
+ sqrt(): this {
297
+ return this.root(2)
298
+ }
299
+
300
+ subtract(): Factor {
301
+ throw new MathError("Subtracting two factors is not possible")
302
+ }
303
+
304
+ tableOfSigns(): TABLE_OF_SIGNS {
305
+ const pow = this.power.clone().reduce()
306
+ const tos = this.polynom.tableOfSigns()
307
+
308
+ // The zero roots becomes defence (d) if the power is negative
309
+ if (pow.isStrictlyNegative()) {
310
+ tos.signs = replace_in_array(tos.signs, 'z', 'd')
311
+ }
312
+
313
+ // The - sign becomes
314
+ // + (plus) if the power num is even and the power den is odd
315
+ // i (invalid) if the power denominator is even
316
+ if (pow.denominator % 2 === 0) {
317
+ // it's an even roots : no negative values!
318
+ tos.signs = replace_in_array(tos.signs, '-', 'h')
319
+ } else if (pow.numerator % 2 === 0) {
320
+ // it's an even power : negative values becomes positive !
321
+ tos.signs = replace_in_array(tos.signs, '-', '+')
322
+ }
323
+
324
+
325
+ return {roots: tos.roots, signs: tos.signs}
326
+ }
327
+
328
+ get variables(): string[] {
329
+ return this.polynom.variables
330
+ }
331
+
332
+ get withPower(): this {
333
+ this.#displayMode = FACTOR_DISPLAY.POWER
334
+ return this
335
+ }
336
+
337
+ get withRoot(): this {
338
+ this.#displayMode = FACTOR_DISPLAY.ROOT
339
+ return this
340
+ }
341
+
342
+ zero(): this {
343
+ this.#polynom.zero()
344
+ this.#power.one()
345
+ return this
346
+ }
347
+
348
+ static checkParseAsFactors(str: string): boolean {
349
+ const splitPlus = splitIfOutsideParentheses(str, "+")
350
+ if(splitPlus[0]==='') splitPlus.shift()
351
+ if(splitPlus.length>1) return false
352
+
353
+ const splitMinus = splitIfOutsideParentheses(str, "-")
354
+ if(splitMinus[0]==='') splitMinus.shift()
355
+ if(splitMinus.length>1) return false
356
+
357
+ return true
358
+ }
359
+
360
+ static factorsFromString(value: string, isNumerator = true): Factor[] {
361
+ if (!Factor.checkParseAsFactors(value)) {
362
+ return [new Factor(value, isNumerator ? 1 : -1)]
363
+ }
364
+
365
+ const sign = isNumerator ? 1 : -1
366
+ const factors: Factor[] = []
367
+
368
+ // Alternance : facteur parenthésé avec puissance optionnelle | séquence non-parenthésée
369
+ const regex =
370
+ /\(([^)]+)\)(?:\^(-?[0-9]+(?:\/[0-9]+)?|\(-?[0-9]+(?:\/[0-9]+)?\)))?|([^(]+)/g
371
+
372
+ for (const match of value.matchAll(regex)) {
373
+ if (match[1] !== undefined) {
374
+ // Cas : (expr)^puissance
375
+ const powStr = (match[2] ?? '1')
376
+ .replace(/[()]/g, '')
377
+
378
+ factors.push(new Factor(
379
+ new Polynom(match[1]),
380
+ new Fraction(powStr).multiply(sign))
381
+ )
382
+ } else if (match[3]?.trim()) {
383
+ // Cas : monôme ou constante hors parenthèses (ex: 3x^2, 3)
384
+ factors.push(new Factor(new Polynom(match[3].trim()), new Fraction(sign)))
385
+ }
386
+ }
387
+
388
+ return factors
389
+ }
390
+ }
391
+
392
+ export enum FACTOR_DISPLAY {
393
+ ROOT,
394
+ POWER
395
+ }
396
+