pimath 0.2.11 → 0.2.13
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 +882 -907
- package/dist/pimath.js.map +1 -1
- package/package.json +3 -2
- package/src/algebra/equation.ts +3 -2
- package/src/algebra/equationSolver.ts +2 -1
- package/src/algebra/factor.ts +10 -9
- package/src/algebra/linearSystem.ts +10 -9
- package/src/algebra/logicalset.ts +8 -3
- package/src/algebra/matrix.ts +10 -9
- package/src/algebra/monom.ts +10 -4
- package/src/algebra/operations.ts +3 -2
- package/src/algebra/polyFactor.ts +5 -4
- package/src/algebra/polynom.ts +30 -30
- package/src/coefficients/fraction.ts +6 -5
- package/src/coefficients/root.ts +5 -4
- package/src/errors.ts +45 -0
- package/src/geometry/TupleN.ts +4 -3
- package/src/geometry/geomMath.ts +3 -2
- package/src/geometry/line.ts +4 -2
- package/src/geometry/line3.ts +7 -6
- package/src/geometry/plane3.ts +3 -2
- package/src/geometry/point.ts +5 -4
- package/src/geometry/sphere3.ts +6 -5
- package/src/geometry/triangle.ts +3 -2
- package/src/geometry/vector.ts +6 -5
- package/src/helpers.ts +3 -1
- package/src/index.ts +23 -0
- package/src/numeric.ts +2 -1
- package/src/randomization/rndHelpers.ts +2 -1
- package/types/algebra/equation.d.ts.map +1 -1
- package/types/algebra/equationSolver.d.ts.map +1 -1
- package/types/algebra/factor.d.ts.map +1 -1
- package/types/algebra/linearSystem.d.ts.map +1 -1
- package/types/algebra/logicalset.d.ts.map +1 -1
- package/types/algebra/matrix.d.ts.map +1 -1
- package/types/algebra/monom.d.ts.map +1 -1
- package/types/algebra/operations.d.ts.map +1 -1
- package/types/algebra/polyFactor.d.ts.map +1 -1
- package/types/algebra/polynom.d.ts.map +1 -1
- package/types/coefficients/fraction.d.ts.map +1 -1
- package/types/coefficients/root.d.ts.map +1 -1
- package/types/errors.d.ts +20 -0
- package/types/errors.d.ts.map +1 -0
- package/types/geometry/TupleN.d.ts.map +1 -1
- package/types/geometry/geomMath.d.ts.map +1 -1
- package/types/geometry/line.d.ts.map +1 -1
- package/types/geometry/line3.d.ts.map +1 -1
- package/types/geometry/plane3.d.ts.map +1 -1
- package/types/geometry/point.d.ts.map +1 -1
- package/types/geometry/sphere3.d.ts.map +1 -1
- package/types/geometry/triangle.d.ts.map +1 -1
- package/types/geometry/vector.d.ts.map +1 -1
- package/types/helpers.d.ts.map +1 -1
- package/types/index.d.ts +12 -0
- package/types/index.d.ts.map +1 -1
- package/types/numeric.d.ts.map +1 -1
- package/types/randomization/rndHelpers.d.ts.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pimath",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.13",
|
|
4
4
|
"description": "A math library for teacher :)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/pimath.js",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@tailwindcss/vite": "^4.3.3",
|
|
42
|
+
"@eslint/js": "^10.0.1",
|
|
42
43
|
"@types/eslint": "^9.6.1",
|
|
43
44
|
"@vitejs/plugin-vue": "^6.0.8",
|
|
44
45
|
"autoprefixer": "^10.5.4",
|
|
@@ -56,6 +57,6 @@
|
|
|
56
57
|
"vue-router": "^5.2.0"
|
|
57
58
|
},
|
|
58
59
|
"dependencies": {
|
|
59
|
-
"piexpression": "^0.1.
|
|
60
|
+
"piexpression": "^0.1.5"
|
|
60
61
|
}
|
|
61
62
|
}
|
package/src/algebra/equation.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
} from "../pimath.interface"
|
|
10
10
|
import {Fraction} from "../coefficients"
|
|
11
11
|
import {Numeric} from "../numeric"
|
|
12
|
+
import {ParseError} from "../errors"
|
|
12
13
|
import {EquationSolver} from "./equationSolver"
|
|
13
14
|
import {Monom} from "./monom"
|
|
14
15
|
import {Polynom} from "./polynom"
|
|
@@ -62,7 +63,7 @@ export class Equation implements IPiMathObject<Equation>,
|
|
|
62
63
|
const strSign: string | false = this.#findSign(equationString)
|
|
63
64
|
|
|
64
65
|
if (strSign === false) {
|
|
65
|
-
throw new
|
|
66
|
+
throw new ParseError('The equation is not valid (no sign found)')
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
// The StrSign is found
|
|
@@ -507,7 +508,7 @@ export class Equation implements IPiMathObject<Equation>,
|
|
|
507
508
|
return '='
|
|
508
509
|
}
|
|
509
510
|
|
|
510
|
-
throw new
|
|
511
|
+
throw new ParseError('The equation is not valid (no sign found)')
|
|
511
512
|
}
|
|
512
513
|
|
|
513
514
|
// -----------------------------------------------
|
|
@@ -4,6 +4,7 @@ import {Fraction} from "../coefficients"
|
|
|
4
4
|
import {Numeric} from "../numeric"
|
|
5
5
|
import type {Equation} from "./equation"
|
|
6
6
|
import {Solution} from "../analyze"
|
|
7
|
+
import {MathError} from "../errors"
|
|
7
8
|
|
|
8
9
|
export class EquationSolver {
|
|
9
10
|
_: number
|
|
@@ -78,7 +79,7 @@ export class EquationSolver {
|
|
|
78
79
|
|
|
79
80
|
public solveAsCardan(): Solution[] {
|
|
80
81
|
if (this.#leftPolynom.degree().value !== 3) {
|
|
81
|
-
throw new
|
|
82
|
+
throw new MathError("The equation is not cubic.")
|
|
82
83
|
}
|
|
83
84
|
return this.#solveCubic_CardanFormula()
|
|
84
85
|
}
|
package/src/algebra/factor.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
import {Fraction} from "../coefficients/fraction"
|
|
11
11
|
import {Polynom} from "./polynom"
|
|
12
12
|
import {replace_in_array, splitIfOutsideParentheses, wrapParenthesis} from "../helpers"
|
|
13
|
+
import {MathError, NotImplementedError} from "../errors"
|
|
13
14
|
|
|
14
15
|
export class Factor implements IPiMathObject<Factor>,
|
|
15
16
|
IExpression<Factor>,
|
|
@@ -42,7 +43,7 @@ export class Factor implements IPiMathObject<Factor>,
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
public parse(/*value: InputValue<Factor>*/): Factor {
|
|
45
|
-
throw new
|
|
46
|
+
throw new NotImplementedError("Method not implemented.")
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
public clone(): Factor {
|
|
@@ -104,7 +105,7 @@ export class Factor implements IPiMathObject<Factor>,
|
|
|
104
105
|
}
|
|
105
106
|
|
|
106
107
|
public add(): Factor {
|
|
107
|
-
throw new
|
|
108
|
+
throw new MathError("Adding two factors is not possible")
|
|
108
109
|
}
|
|
109
110
|
|
|
110
111
|
public get asSingle(): this {
|
|
@@ -141,7 +142,7 @@ export class Factor implements IPiMathObject<Factor>,
|
|
|
141
142
|
return this.polynom.clone().pow(this.power.value)
|
|
142
143
|
}
|
|
143
144
|
|
|
144
|
-
throw new
|
|
145
|
+
throw new MathError("The power must be a natural number")
|
|
145
146
|
}
|
|
146
147
|
|
|
147
148
|
public divide(value: InputAlgebra<Factor | Polynom>): this {
|
|
@@ -159,7 +160,7 @@ export class Factor implements IPiMathObject<Factor>,
|
|
|
159
160
|
return this
|
|
160
161
|
}
|
|
161
162
|
|
|
162
|
-
throw new
|
|
163
|
+
throw new MathError("The two factors must be the same")
|
|
163
164
|
}
|
|
164
165
|
|
|
165
166
|
public evaluate(values: InputValue<Fraction> | literalType<number | Fraction>, asNumeric?: boolean): number | Fraction {
|
|
@@ -241,7 +242,7 @@ export class Factor implements IPiMathObject<Factor>,
|
|
|
241
242
|
return this
|
|
242
243
|
}
|
|
243
244
|
|
|
244
|
-
throw new
|
|
245
|
+
throw new MathError("The two factors must be the same")
|
|
245
246
|
}
|
|
246
247
|
|
|
247
248
|
public one(): this {
|
|
@@ -251,7 +252,7 @@ export class Factor implements IPiMathObject<Factor>,
|
|
|
251
252
|
}
|
|
252
253
|
|
|
253
254
|
public opposite(): Factor {
|
|
254
|
-
throw new
|
|
255
|
+
throw new NotImplementedError("Method not implemented.")
|
|
255
256
|
}
|
|
256
257
|
|
|
257
258
|
public get polynom(): Polynom {
|
|
@@ -276,11 +277,11 @@ export class Factor implements IPiMathObject<Factor>,
|
|
|
276
277
|
}
|
|
277
278
|
|
|
278
279
|
public primitive(): Factor {
|
|
279
|
-
throw new
|
|
280
|
+
throw new NotImplementedError("Method not implemented.")
|
|
280
281
|
}
|
|
281
282
|
|
|
282
283
|
public reduce(): Factor {
|
|
283
|
-
throw new
|
|
284
|
+
throw new NotImplementedError("Method not implemented.")
|
|
284
285
|
}
|
|
285
286
|
|
|
286
287
|
public root(value: number): this {
|
|
@@ -293,7 +294,7 @@ export class Factor implements IPiMathObject<Factor>,
|
|
|
293
294
|
}
|
|
294
295
|
|
|
295
296
|
public subtract(): Factor {
|
|
296
|
-
throw new
|
|
297
|
+
throw new MathError("Subtracting two factors is not possible")
|
|
297
298
|
}
|
|
298
299
|
|
|
299
300
|
public tableOfSigns(): TABLE_OF_SIGNS {
|
|
@@ -5,6 +5,7 @@ import {Monom} from "./monom"
|
|
|
5
5
|
import {Polynom} from "./polynom"
|
|
6
6
|
import {Numeric} from "../numeric"
|
|
7
7
|
import {Solution} from "../analyze"
|
|
8
|
+
import {DimensionError, IndexError, MathError, NotImplementedError} from "../errors"
|
|
8
9
|
|
|
9
10
|
export class LinearSystem implements IPiMathObject<LinearSystem>,
|
|
10
11
|
IEquation<LinearSystem>,
|
|
@@ -61,7 +62,7 @@ export class LinearSystem implements IPiMathObject<LinearSystem>,
|
|
|
61
62
|
// Check that each row has the same number of columns
|
|
62
63
|
const cols = matrix[0].length
|
|
63
64
|
if (matrix.some(row => row.length !== cols)) {
|
|
64
|
-
throw new
|
|
65
|
+
throw new DimensionError("All rows must have the same number of columns")
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
// Determine the default letters. The number of letters are cols-1
|
|
@@ -88,7 +89,7 @@ export class LinearSystem implements IPiMathObject<LinearSystem>,
|
|
|
88
89
|
if (value instanceof LinearSystem) {
|
|
89
90
|
const length = value.equations.length
|
|
90
91
|
if (length !== this.#equations.length) {
|
|
91
|
-
throw new
|
|
92
|
+
throw new DimensionError("The number of equations must be the same")
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
for (let i = 0; i < length; i++) {
|
|
@@ -96,7 +97,7 @@ export class LinearSystem implements IPiMathObject<LinearSystem>,
|
|
|
96
97
|
}
|
|
97
98
|
} else {
|
|
98
99
|
if (index === undefined || index < 0 || index >= this.#equations.length) {
|
|
99
|
-
throw new
|
|
100
|
+
throw new IndexError("Index out of range")
|
|
100
101
|
}
|
|
101
102
|
const equ = new Equation(value)
|
|
102
103
|
this.#equations[index].add(equ)
|
|
@@ -177,7 +178,7 @@ export class LinearSystem implements IPiMathObject<LinearSystem>,
|
|
|
177
178
|
}
|
|
178
179
|
|
|
179
180
|
public evaluate(values: InputValue<Fraction> | literalType<number | Fraction>, asNumeric?: boolean): number | Fraction {
|
|
180
|
-
throw new
|
|
181
|
+
throw new NotImplementedError("Method not implemented.")
|
|
181
182
|
}
|
|
182
183
|
|
|
183
184
|
public hasVariable(letter: string): boolean {
|
|
@@ -224,7 +225,7 @@ export class LinearSystem implements IPiMathObject<LinearSystem>,
|
|
|
224
225
|
// the value can be a number and the index of the equation to multiply
|
|
225
226
|
if (Array.isArray(value)) {
|
|
226
227
|
if (value.length !== this.#equations.length) {
|
|
227
|
-
throw new
|
|
228
|
+
throw new DimensionError("The number of values must be the same as the number of equations")
|
|
228
229
|
}
|
|
229
230
|
|
|
230
231
|
for (let i = 0; i < value.length; i++) {
|
|
@@ -234,7 +235,7 @@ export class LinearSystem implements IPiMathObject<LinearSystem>,
|
|
|
234
235
|
}
|
|
235
236
|
|
|
236
237
|
if (index === undefined || index < 0 || index >= this.#equations.length) {
|
|
237
|
-
throw new
|
|
238
|
+
throw new IndexError("Index out of range")
|
|
238
239
|
}
|
|
239
240
|
|
|
240
241
|
this.#equations[index].multiply(value)
|
|
@@ -280,7 +281,7 @@ export class LinearSystem implements IPiMathObject<LinearSystem>,
|
|
|
280
281
|
augmentedMatrix[i].forEach((value, index) => value.add(row_to_add[index]))
|
|
281
282
|
pivot = augmentedMatrix[i][i].clone()
|
|
282
283
|
} else {
|
|
283
|
-
throw new
|
|
284
|
+
throw new MathError('Unsolvable...')
|
|
284
285
|
}
|
|
285
286
|
|
|
286
287
|
|
|
@@ -353,7 +354,7 @@ export class LinearSystem implements IPiMathObject<LinearSystem>,
|
|
|
353
354
|
if (value instanceof LinearSystem) {
|
|
354
355
|
const length = value.equations.length
|
|
355
356
|
if (length !== this.#equations.length) {
|
|
356
|
-
throw new
|
|
357
|
+
throw new DimensionError("The number of equations must be the same")
|
|
357
358
|
}
|
|
358
359
|
|
|
359
360
|
for (let i = 0; i < length; i++) {
|
|
@@ -361,7 +362,7 @@ export class LinearSystem implements IPiMathObject<LinearSystem>,
|
|
|
361
362
|
}
|
|
362
363
|
} else {
|
|
363
364
|
if (index === undefined || index < 0 || index >= this.#equations.length) {
|
|
364
|
-
throw new
|
|
365
|
+
throw new IndexError("Index out of range")
|
|
365
366
|
}
|
|
366
367
|
const equ = new Equation(value)
|
|
367
368
|
this.#equations[index].subtract(equ)
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* @module Logicalset
|
|
4
4
|
*/
|
|
5
5
|
import {ShutingYard, ShutingyardMode} from "piexpression"
|
|
6
|
+
import {ParseError} from "../errors"
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Polynom class can handle polynoms, reorder, resolve, ...
|
|
@@ -26,9 +27,13 @@ export class LogicalSet {
|
|
|
26
27
|
|
|
27
28
|
parse = (value: string): this => {
|
|
28
29
|
// Parse the updated value to the shutingyard algorithm
|
|
29
|
-
|
|
30
|
-
.
|
|
31
|
-
|
|
30
|
+
try {
|
|
31
|
+
this.#rpn = new ShutingYard(ShutingyardMode.SET)
|
|
32
|
+
.parse(value)
|
|
33
|
+
.rpn
|
|
34
|
+
} catch (e) {
|
|
35
|
+
throw new ParseError(`Cannot parse "${value}" as a LogicalSet`, {cause: e})
|
|
36
|
+
}
|
|
32
37
|
|
|
33
38
|
return this
|
|
34
39
|
}
|
package/src/algebra/matrix.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type {IExpressionMultiply, InputAlgebra, InputValue, IPiMathObject} from
|
|
|
2
2
|
import {Polynom} from "./polynom"
|
|
3
3
|
import type {Vector} from "../geometry"
|
|
4
4
|
import {operation_pow} from "./operations"
|
|
5
|
+
import {DimensionError, IndexError, MathError, NotImplementedError} from "../errors"
|
|
5
6
|
|
|
6
7
|
export type IMatrixValues = InputAlgebra<Polynom>[][]
|
|
7
8
|
|
|
@@ -107,7 +108,7 @@ export class Matrix implements IPiMathObject<Matrix>,
|
|
|
107
108
|
|
|
108
109
|
public add(value: Matrix): this {
|
|
109
110
|
if (!this.canBeAdded(value)) {
|
|
110
|
-
throw new
|
|
111
|
+
throw new DimensionError("Cannot add a matrix with different dimensions.")
|
|
111
112
|
}
|
|
112
113
|
this.forEach((aij, i, j) => {
|
|
113
114
|
aij.add(value.values[i][j])
|
|
@@ -195,7 +196,7 @@ export class Matrix implements IPiMathObject<Matrix>,
|
|
|
195
196
|
|
|
196
197
|
public determinant(): Polynom {
|
|
197
198
|
if (!this.isSquare()) {
|
|
198
|
-
throw new
|
|
199
|
+
throw new DimensionError('Matrix is not square')
|
|
199
200
|
}
|
|
200
201
|
|
|
201
202
|
// Use the first line.
|
|
@@ -276,7 +277,7 @@ export class Matrix implements IPiMathObject<Matrix>,
|
|
|
276
277
|
// Check dimensions of each rows.
|
|
277
278
|
const L = values[0].length
|
|
278
279
|
if (values.some(row => row.length !== L)) {
|
|
279
|
-
throw new
|
|
280
|
+
throw new DimensionError("Each line must be the same length")
|
|
280
281
|
}
|
|
281
282
|
|
|
282
283
|
values.forEach(row => {
|
|
@@ -298,7 +299,7 @@ export class Matrix implements IPiMathObject<Matrix>,
|
|
|
298
299
|
// Each vectors must be the same dimension
|
|
299
300
|
const L = vectors[0].dimension
|
|
300
301
|
if (vectors.some(v => v.dimension !== L)) {
|
|
301
|
-
throw new
|
|
302
|
+
throw new DimensionError("Each vectors must be the same dimension")
|
|
302
303
|
}
|
|
303
304
|
|
|
304
305
|
this.fromDimensions(vectors[0].dimension, vectors.length)
|
|
@@ -314,7 +315,7 @@ export class Matrix implements IPiMathObject<Matrix>,
|
|
|
314
315
|
|
|
315
316
|
public inverse(): this {
|
|
316
317
|
if (!this.canBeInverted()) {
|
|
317
|
-
throw new
|
|
318
|
+
throw new MathError('The matrix cannot be inverted.')
|
|
318
319
|
}
|
|
319
320
|
|
|
320
321
|
const cofactors_matrix = new Matrix().fromDimensions(this.dimension.rows, this.dimension.cols)
|
|
@@ -387,7 +388,7 @@ export class Matrix implements IPiMathObject<Matrix>,
|
|
|
387
388
|
public multiply(value: InputValue<Polynom> | Matrix): this {
|
|
388
389
|
if (value instanceof Matrix) {
|
|
389
390
|
if (!this.canBeMultiplied(value)) {
|
|
390
|
-
throw new
|
|
391
|
+
throw new DimensionError(`Cannot multiply a matrix with incompatibles dimensions`)
|
|
391
392
|
}
|
|
392
393
|
|
|
393
394
|
// Multiply two matrix
|
|
@@ -455,7 +456,7 @@ export class Matrix implements IPiMathObject<Matrix>,
|
|
|
455
456
|
}
|
|
456
457
|
|
|
457
458
|
public reduce(): Matrix {
|
|
458
|
-
throw new
|
|
459
|
+
throw new NotImplementedError('Not yet implemented')
|
|
459
460
|
}
|
|
460
461
|
|
|
461
462
|
get rows(): Polynom[][] {
|
|
@@ -466,7 +467,7 @@ export class Matrix implements IPiMathObject<Matrix>,
|
|
|
466
467
|
const {rows, cols} = this.dimension
|
|
467
468
|
if ((row < 0 || row >= rows) ||
|
|
468
469
|
column < 0 || column >= cols) {
|
|
469
|
-
throw new
|
|
470
|
+
throw new IndexError(`${row}x${column} is out of range (${rows}x${cols})`)
|
|
470
471
|
}
|
|
471
472
|
|
|
472
473
|
this.#values[row][column] = new Polynom(value)
|
|
@@ -475,7 +476,7 @@ export class Matrix implements IPiMathObject<Matrix>,
|
|
|
475
476
|
|
|
476
477
|
public subtract(value: Matrix): this {
|
|
477
478
|
if (!this.canBeAdded(value)) {
|
|
478
|
-
throw new
|
|
479
|
+
throw new DimensionError("Cannot subtract a matrix with different dimensions.")
|
|
479
480
|
}
|
|
480
481
|
|
|
481
482
|
this.forEach((aij, i, j) => {
|
package/src/algebra/monom.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {Fraction} from "../coefficients"
|
|
|
14
14
|
import {Numeric} from "../numeric"
|
|
15
15
|
|
|
16
16
|
import {ShutingYard, ShutingyardType, type Token} from "piexpression"
|
|
17
|
+
import {MathError, NotImplementedError, ParseError} from "../errors"
|
|
17
18
|
|
|
18
19
|
export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse<Monom>, IAlgebra<Monom> {
|
|
19
20
|
#coefficient: Fraction
|
|
@@ -165,7 +166,7 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
|
|
|
165
166
|
|
|
166
167
|
this.#coefficient.add(mAsMonom.coefficient)
|
|
167
168
|
} else {
|
|
168
|
-
throw new
|
|
169
|
+
throw new MathError('Add monom: ' + this.display + ' is not similar with ' + mAsMonom.display)
|
|
169
170
|
}
|
|
170
171
|
}
|
|
171
172
|
return this
|
|
@@ -650,7 +651,7 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
|
|
|
650
651
|
*/
|
|
651
652
|
public root = (): this => {
|
|
652
653
|
// TODO: implement nth-root for monoms
|
|
653
|
-
throw new
|
|
654
|
+
throw new NotImplementedError('Method not implemented.')
|
|
654
655
|
}
|
|
655
656
|
|
|
656
657
|
/**
|
|
@@ -706,7 +707,7 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
|
|
|
706
707
|
|
|
707
708
|
this.#coefficient.add(mAsMonom.clone().coefficient.opposite())
|
|
708
709
|
} else {
|
|
709
|
-
throw new
|
|
710
|
+
throw new MathError('Subtract: Is not similar: ' + mAsMonom.display)
|
|
710
711
|
}
|
|
711
712
|
}
|
|
712
713
|
return this
|
|
@@ -890,7 +891,12 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
|
|
|
890
891
|
|
|
891
892
|
#shutingYardToReducedMonom = (inputStr: string): this => {
|
|
892
893
|
// Get the RPN array of the current expression
|
|
893
|
-
|
|
894
|
+
let SY: ShutingYard
|
|
895
|
+
try {
|
|
896
|
+
SY = new ShutingYard().parse(inputStr)
|
|
897
|
+
} catch (e) {
|
|
898
|
+
throw new ParseError(`Cannot parse "${inputStr}" as a Monom`, {cause: e})
|
|
899
|
+
}
|
|
894
900
|
const rpn: { token: string, tokenType: ShutingyardType }[] = SY.rpn
|
|
895
901
|
|
|
896
902
|
const stack: Monom[] = []
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import type {IExpressionMultiply, IPiMathObject} from "../pimath.interface"
|
|
2
|
+
import {InvalidArgumentError} from "../errors"
|
|
2
3
|
|
|
3
4
|
// TODO: create other operation_** to make things more generic !
|
|
4
5
|
export function operation_pow<T extends IPiMathObject<T> & IExpressionMultiply<T>>(item: T, value: number): T {
|
|
5
6
|
if (!Number.isSafeInteger(value)) {
|
|
6
|
-
throw new
|
|
7
|
+
throw new InvalidArgumentError('Can only raise item by an integer')
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
if (value < 0) {
|
|
10
|
-
throw new
|
|
11
|
+
throw new InvalidArgumentError('Can only raise item by a positive integer')
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
if (value === 0) {
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
TABLE_OF_SIGNS_VALUES
|
|
11
11
|
} from "../pimath.interface"
|
|
12
12
|
import {Fraction} from "../coefficients"
|
|
13
|
+
import {MathError, NotImplementedError, ParseError} from "../errors"
|
|
13
14
|
import {Factor, FACTOR_DISPLAY} from "./factor"
|
|
14
15
|
import {Polynom} from "./polynom"
|
|
15
16
|
import type {Solution} from "../analyze"
|
|
@@ -342,7 +343,7 @@ export class PolyFactor implements IPiMathObject<PolyFactor>,
|
|
|
342
343
|
|
|
343
344
|
if (polynom.isOne()) return this
|
|
344
345
|
|
|
345
|
-
if (polynom.isZero()) throw new
|
|
346
|
+
if (polynom.isZero()) throw new MathError("Cannot divide by zero")
|
|
346
347
|
|
|
347
348
|
this.#factors.push(new Factor(polynom, -1))
|
|
348
349
|
}
|
|
@@ -357,8 +358,8 @@ export class PolyFactor implements IPiMathObject<PolyFactor>,
|
|
|
357
358
|
// - or the string has something that prevents this => use fromPolynom
|
|
358
359
|
|
|
359
360
|
const [num, ...den] = splitIfOutsideParentheses(value, '/')
|
|
360
|
-
if(num==='') throw new
|
|
361
|
-
if(den.length>1) throw new
|
|
361
|
+
if(num==='') throw new ParseError('Parsing a PolyFactor from a string requires a numerator')
|
|
362
|
+
if(den.length>1) throw new ParseError('Parsing a PolyFactor from a string only allows max one signe "/"')
|
|
362
363
|
|
|
363
364
|
if(den.length===0) {
|
|
364
365
|
this.#factors = Factor.factorsFromString(stripParenthesis(num), true)
|
|
@@ -459,7 +460,7 @@ export class PolyFactor implements IPiMathObject<PolyFactor>,
|
|
|
459
460
|
}
|
|
460
461
|
|
|
461
462
|
public primitive(): PolyFactor {
|
|
462
|
-
throw new
|
|
463
|
+
throw new NotImplementedError("Method not implemented.")
|
|
463
464
|
}
|
|
464
465
|
|
|
465
466
|
public reduce(): this {
|
package/src/algebra/polynom.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Polynom module contains everything necessary to handle polynoms.*
|
|
3
3
|
*/
|
|
4
4
|
import {ShutingYard, ShutingyardType, type Token} from "piexpression"
|
|
5
|
+
import {InvalidArgumentError, MathError, ParseError} from "../errors"
|
|
5
6
|
import type {
|
|
6
7
|
IAlgebra,
|
|
7
8
|
IAnalyse,
|
|
@@ -212,7 +213,7 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
212
213
|
return this.divide(new Polynom(value))
|
|
213
214
|
}
|
|
214
215
|
|
|
215
|
-
throw new
|
|
216
|
+
throw new MathError(`Cannot divide by ${value as unknown as string}`)
|
|
216
217
|
}
|
|
217
218
|
|
|
218
219
|
public empty(): this {
|
|
@@ -242,7 +243,7 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
242
243
|
}
|
|
243
244
|
|
|
244
245
|
if (!this.degree(letter).isNatural() || !P.degree(letter).isNatural()) {
|
|
245
|
-
throw new
|
|
246
|
+
throw new MathError('Euclidean division requires integer degrees')
|
|
246
247
|
}
|
|
247
248
|
|
|
248
249
|
// Get at least a letter
|
|
@@ -396,7 +397,7 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
396
397
|
|
|
397
398
|
public getCoefficients(): Fraction[] {
|
|
398
399
|
if (!this.degree().isNatural()) {
|
|
399
|
-
throw new
|
|
400
|
+
throw new MathError('getCoefficients() requires a polynomial with integer degrees')
|
|
400
401
|
}
|
|
401
402
|
|
|
402
403
|
// Assume there is only one letter.
|
|
@@ -462,8 +463,6 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
462
463
|
}
|
|
463
464
|
|
|
464
465
|
public isDeveloped(polynomString: string): boolean {
|
|
465
|
-
let P: Polynom
|
|
466
|
-
|
|
467
466
|
// Start by removing the parenthesis after a "power"
|
|
468
467
|
const pString = polynomString.replaceAll(/\^\(([-0-9/]+)\)/g, '$1')
|
|
469
468
|
|
|
@@ -473,13 +472,9 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
473
472
|
}
|
|
474
473
|
|
|
475
474
|
|
|
476
|
-
//
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
P = new Polynom(polynomString)
|
|
480
|
-
} catch {
|
|
481
|
-
return false
|
|
482
|
-
}
|
|
475
|
+
// Build the polynom. A malformed string throws (ParseError) instead of
|
|
476
|
+
// being silently treated as "not developed".
|
|
477
|
+
const P = new Polynom(polynomString)
|
|
483
478
|
|
|
484
479
|
// Both polynom aren't the same (once developed and reduced => they cannot be equivalent)
|
|
485
480
|
if (!this.isEqual(P)) {
|
|
@@ -663,13 +658,13 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
663
658
|
try {
|
|
664
659
|
const k = new Fraction(value)
|
|
665
660
|
return this.#multiplyByFraction(k)
|
|
666
|
-
} catch {
|
|
667
|
-
throw new
|
|
661
|
+
} catch (e) {
|
|
662
|
+
throw new MathError('Cannot multiply by this value.', {cause: e})
|
|
668
663
|
}
|
|
669
664
|
}
|
|
670
665
|
|
|
671
666
|
// Something went wrong...
|
|
672
|
-
throw new
|
|
667
|
+
throw new MathError(`Cannot multiply by this value: ${value as unknown as string}`)
|
|
673
668
|
}
|
|
674
669
|
|
|
675
670
|
public get numberOfVars(): number {
|
|
@@ -801,7 +796,7 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
801
796
|
|
|
802
797
|
// Add the new monom to the result polynom
|
|
803
798
|
if (pow.isStrictlyNegative()) {
|
|
804
|
-
throw new
|
|
799
|
+
throw new MathError(`Cannot replace variable "${letter}" with negative power in a Polynom`)
|
|
805
800
|
}
|
|
806
801
|
resultPolynom.add(P.clone().pow(pow.numerator).multiply(m))
|
|
807
802
|
}
|
|
@@ -817,7 +812,7 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
817
812
|
// ------------------------------------------
|
|
818
813
|
|
|
819
814
|
public root(): Polynom {
|
|
820
|
-
throw new
|
|
815
|
+
throw new MathError('Cannot take the root from a polynom')
|
|
821
816
|
}
|
|
822
817
|
|
|
823
818
|
get roots(): Solution[] {
|
|
@@ -836,7 +831,7 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
836
831
|
}
|
|
837
832
|
|
|
838
833
|
public sqrt(): Polynom {
|
|
839
|
-
throw new
|
|
834
|
+
throw new MathError('Cannot take the square root from a polynom')
|
|
840
835
|
}
|
|
841
836
|
|
|
842
837
|
public subtract(...values: InputAlgebra<Polynom>[]): this {
|
|
@@ -1085,7 +1080,7 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
1085
1080
|
const letters = inputStr.split('')
|
|
1086
1081
|
|
|
1087
1082
|
if (fractions.length > letters.length + 1) {
|
|
1088
|
-
throw new
|
|
1083
|
+
throw new InvalidArgumentError(`Too many values: ${letters.length} letters but ${fractions.length} values provided`)
|
|
1089
1084
|
}
|
|
1090
1085
|
|
|
1091
1086
|
let i = 0
|
|
@@ -1127,7 +1122,7 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
1127
1122
|
break
|
|
1128
1123
|
|
|
1129
1124
|
case ShutingyardType.CONSTANT:
|
|
1130
|
-
throw new
|
|
1125
|
+
throw new ParseError('Unsupported CONSTANT token in Polynom parser')
|
|
1131
1126
|
|
|
1132
1127
|
case ShutingyardType.OPERATION:
|
|
1133
1128
|
if (stack.length >= 2) {
|
|
@@ -1136,7 +1131,7 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
1136
1131
|
|
|
1137
1132
|
// Check if the polynoms are not undefined.
|
|
1138
1133
|
if (a === undefined || b === undefined) {
|
|
1139
|
-
throw new
|
|
1134
|
+
throw new ParseError('Unexpected undefined operand in Polynom parser stack')
|
|
1140
1135
|
}
|
|
1141
1136
|
|
|
1142
1137
|
if (element.token === '+') {
|
|
@@ -1147,16 +1142,16 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
1147
1142
|
stack.push(a.multiply(b))
|
|
1148
1143
|
} else if (element.token === '/') {
|
|
1149
1144
|
if (b.degree().isStrictlyPositive()) {
|
|
1150
|
-
throw new
|
|
1145
|
+
throw new MathError('Cannot divide a Polynom by another Polynom of degree > 0')
|
|
1151
1146
|
} else {
|
|
1152
1147
|
// a.divide(b.monoms[0].coefficient)
|
|
1153
1148
|
stack.push(a.divide(b.monoms[0].coefficient))
|
|
1154
1149
|
}
|
|
1155
1150
|
} else if (element.token === '^') {
|
|
1156
1151
|
if (b.degree().isStrictlyPositive()) {
|
|
1157
|
-
throw new
|
|
1158
|
-
} else if (b.monoms[0].coefficient.
|
|
1159
|
-
//
|
|
1152
|
+
throw new MathError('Cannot elevate a polynom with another polynom !')
|
|
1153
|
+
} else if (b.monoms[0].coefficient.isNatural())
|
|
1154
|
+
// Natural (positive) power
|
|
1160
1155
|
{
|
|
1161
1156
|
stack.push(a.pow(b.monoms[0].coefficient.value))
|
|
1162
1157
|
} else {
|
|
@@ -1168,7 +1163,7 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
1168
1163
|
|
|
1169
1164
|
stack.push(a)
|
|
1170
1165
|
} else {
|
|
1171
|
-
throw new
|
|
1166
|
+
throw new MathError('Cannot raise a multi-monom Polynom to a fractional power')
|
|
1172
1167
|
}
|
|
1173
1168
|
}
|
|
1174
1169
|
}
|
|
@@ -1179,7 +1174,7 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
1179
1174
|
stack.push(a.opposite())
|
|
1180
1175
|
}
|
|
1181
1176
|
} else {
|
|
1182
|
-
throw new
|
|
1177
|
+
throw new ParseError("Error parsing the polynom")
|
|
1183
1178
|
}
|
|
1184
1179
|
|
|
1185
1180
|
|
|
@@ -1187,11 +1182,11 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
1187
1182
|
|
|
1188
1183
|
case ShutingyardType.MONOM:
|
|
1189
1184
|
// Should never appear.
|
|
1190
|
-
throw new
|
|
1185
|
+
throw new ParseError('Unexpected MONOM token in polynom parser')
|
|
1191
1186
|
|
|
1192
1187
|
case ShutingyardType.FUNCTION:
|
|
1193
1188
|
// Should never appear.
|
|
1194
|
-
throw new
|
|
1189
|
+
throw new ParseError(`Unsupported function token "${element.token}" in polynom parser`)
|
|
1195
1190
|
}
|
|
1196
1191
|
|
|
1197
1192
|
|
|
@@ -1203,7 +1198,12 @@ export class Polynom implements IPiMathObject<Polynom>,
|
|
|
1203
1198
|
*/
|
|
1204
1199
|
#shutingYardToReducedPolynom(inputStr: string): this {
|
|
1205
1200
|
// Get the RPN array of the current expression
|
|
1206
|
-
|
|
1201
|
+
let SY: ShutingYard
|
|
1202
|
+
try {
|
|
1203
|
+
SY = new ShutingYard().parse(inputStr)
|
|
1204
|
+
} catch (e) {
|
|
1205
|
+
throw new ParseError(`Cannot parse "${inputStr}" as a Polynom`, {cause: e})
|
|
1206
|
+
}
|
|
1207
1207
|
const rpn: { token: string, tokenType: ShutingyardType }[] = SY.rpn
|
|
1208
1208
|
|
|
1209
1209
|
// New version for reducing shuting yard.
|