pimath 0.0.49 → 0.0.53
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/README.md +1 -1
- package/dist/pi.js +626 -358
- package/dist/pi.js.map +1 -1
- package/dist/pi.min.js +1 -1
- package/dist/pi.min.js.map +1 -1
- package/docs/assets/highlight.css +78 -78
- package/docs/assets/icons.css +1043 -1043
- package/docs/assets/main.js +52 -52
- package/docs/assets/search.js +1 -1
- package/docs/assets/style.css +1413 -1388
- package/docs/classes/Logicalset.Logicalset-1.html +5 -0
- package/docs/classes/Polynom.Rational.html +4 -0
- package/docs/classes/Vector.Point.html +1 -0
- package/docs/classes/Vector.Vector-1.html +1 -0
- package/docs/classes/algebra_equation.Equation.html +26 -0
- package/docs/classes/algebra_linearSystem.LinearSystem.html +1 -0
- package/docs/classes/algebra_monom.Monom.html +114 -0
- package/docs/classes/algebra_polynom.Polynom.html +30 -0
- package/docs/classes/coefficients_fraction.Fraction.html +19 -0
- package/docs/classes/coefficients_nthroot.NthRoot.html +3 -0
- package/docs/classes/expressions_numexp.NumExp.html +1 -0
- package/docs/classes/expressions_polynomexp.PolynomExpFactor.html +1 -0
- package/docs/classes/expressions_polynomexp.PolynomExpProduct.html +1 -0
- package/docs/classes/geometry_circle.Circle.html +3 -0
- package/docs/classes/geometry_line.Line.html +3 -0
- package/docs/classes/geometry_triangle.Triangle.html +17 -0
- package/docs/classes/numeric.Numeric.html +14 -14
- package/docs/classes/shutingyard.Shutingyard.html +18 -18
- package/docs/enums/algebra_equation.PARTICULAR_SOLUTION.html +1 -0
- package/docs/enums/geometry_line.LinePropriety.html +1 -0
- package/docs/enums/shutingyard.ShutingyardMode.html +1 -1
- package/docs/enums/shutingyard.ShutingyardType.html +1 -1
- package/docs/index.html +11 -11
- package/docs/interfaces/algebra_equation.ISolution.html +3 -0
- package/docs/interfaces/geometry_triangle.remarquableLines.html +1 -0
- package/docs/modules/Logicalset.html +3 -0
- package/docs/modules/Polynom.html +3 -0
- package/docs/modules/Vector.html +3 -0
- package/docs/modules/algebra_equation.html +1 -0
- package/docs/modules/algebra_linearSystem.html +1 -0
- package/docs/modules/algebra_monom.html +1 -0
- package/docs/modules/algebra_polynom.html +1 -0
- package/docs/modules/coefficients_fraction.html +1 -0
- package/docs/modules/coefficients_nthroot.html +1 -0
- package/docs/modules/expressions_numexp.html +1 -0
- package/docs/modules/expressions_polynomexp.html +1 -0
- package/docs/modules/geometry_circle.html +1 -0
- package/docs/modules/geometry_line.html +1 -0
- package/docs/modules/geometry_triangle.html +1 -0
- package/docs/modules/numeric.html +1 -1
- package/docs/modules/shutingyard.html +1 -1
- package/docs/modules.html +1 -1
- package/esm/index.d.ts +2 -2
- package/esm/index.js +2 -2
- package/esm/maths/algebra/equation.d.ts +7 -2
- package/esm/maths/algebra/equation.js +62 -19
- package/esm/maths/algebra/equation.js.map +10 -1
- package/esm/maths/algebra/linearSystem.js +1 -1
- package/esm/maths/algebra/linearSystem.js.map +10 -1
- package/esm/maths/algebra/monom.js +2 -2
- package/esm/maths/algebra/monom.js.map +10 -1
- package/esm/maths/algebra/polynom.d.ts +5 -1
- package/esm/maths/algebra/polynom.js +157 -81
- package/esm/maths/algebra/polynom.js.map +1 -1
- package/esm/maths/algebra/rational.d.ts +16 -6
- package/esm/maths/algebra/rational.js +139 -30
- package/esm/maths/algebra/rational.js.map +10 -1
- package/esm/maths/coefficients/fraction.d.ts +3 -1
- package/esm/maths/coefficients/fraction.js +37 -5
- package/esm/maths/coefficients/fraction.js.map +1 -1
- package/esm/maths/coefficients/{nthroot.d.ts → nthRoot.d.ts} +5 -5
- package/esm/maths/coefficients/{nthroot.js → nthRoot.js} +5 -5
- package/esm/maths/coefficients/{nthroot.js.map → nthRoot.js.map} +1 -1
- package/esm/maths/expressions/polynomexp.bkp.js +2 -3
- package/esm/maths/expressions/polynomexp.bkp.js.map +10 -1
- package/esm/maths/expressions/polynomexp.js +3 -3
- package/esm/maths/expressions/polynomexp.js.map +10 -1
- package/esm/maths/geometry/line.js +8 -0
- package/esm/maths/geometry/line.js.map +1 -1
- package/esm/maths/geometry/point.js +1 -1
- package/esm/maths/geometry/point.js.map +10 -1
- package/esm/maths/randomization/random.js +5 -1
- package/esm/maths/randomization/random.js.map +10 -1
- package/package.json +11 -11
- package/public/index.html +234 -235
- package/src/index.ts +2 -2
- package/src/maths/algebra/equation.ts +68 -19
- package/src/maths/algebra/linearSystem.ts +1 -1
- package/src/maths/algebra/monom.ts +3 -4
- package/src/maths/algebra/polynom.ts +170 -87
- package/src/maths/algebra/rational.ts +243 -98
- package/src/maths/coefficients/fraction.ts +44 -6
- package/src/maths/coefficients/{nthroot.ts → nthRoot.ts} +5 -5
- package/src/maths/expressions/polynomexp.bkp.ts +1 -2
- package/src/maths/expressions/polynomexp.ts +2 -1
- package/src/maths/geometry/line.ts +0 -1
- package/src/maths/geometry/point.ts +1 -1
- package/tests/algebra/equation.test.ts +36 -0
- package/tests/algebra/monom.test.ts +2 -5
- package/tests/algebra/polynom.test.ts +7 -3
- package/tests/algebra/rationnal.test.ts +96 -0
- package/tests/coefficients/fraction.test.ts +43 -1
- package/tests/geometry/circle.test.ts +4 -2
- package/tests/polynomexp.test.ts +0 -3
- package/tsconfig.json +16 -5
- package/docs/classes/Algebra.Equation.html +0 -26
- package/docs/classes/algebra.LinearSystem.html +0 -1
- package/docs/classes/algebra.Logicalset.html +0 -5
- package/docs/classes/algebra.Monom.html +0 -114
- package/docs/classes/algebra.Polynom.html +0 -30
- package/docs/classes/algebra.PolynomExpFactor.html +0 -1
- package/docs/classes/algebra.PolynomExpProduct.html +0 -1
- package/docs/classes/algebra.Rational.html +0 -4
- package/docs/classes/coefficients.Fraction.html +0 -19
- package/docs/classes/coefficients.Nthroot.html +0 -3
- package/docs/classes/geometry.Circle.html +0 -3
- package/docs/classes/geometry.Line.html +0 -3
- package/docs/classes/geometry.Point.html +0 -1
- package/docs/classes/geometry.Triangle.html +0 -17
- package/docs/classes/geometry.Vector.html +0 -1
- package/docs/enums/geometry.LinePropriety.html +0 -1
- package/docs/interfaces/geometry.remarquableLines.html +0 -1
- package/docs/modules/Algebra.html +0 -1
- package/docs/modules/Random.html +0 -1
- package/docs/modules/coefficients.html +0 -1
- package/docs/modules/geometry.html +0 -1
- package/docs/modules/random.Random.html +0 -1
|
@@ -5,143 +5,288 @@
|
|
|
5
5
|
|
|
6
6
|
import {Polynom} from "./polynom";
|
|
7
7
|
import {Fraction} from "../coefficients/fraction";
|
|
8
|
+
import {literalType} from "./monom";
|
|
9
|
+
import {Equation, ISolution, PARTICULAR_SOLUTION} from "./equation";
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* Rational class can handle rational polynoms
|
|
11
13
|
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
14
|
+
export class Rational {
|
|
15
|
+
private _rawString: string;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
*
|
|
19
|
+
* @param numerator
|
|
20
|
+
* @param denominator
|
|
21
|
+
*/
|
|
22
|
+
constructor(numerator?: Polynom, denominator?: Polynom) {
|
|
23
|
+
this._numerator = numerator ? numerator.clone() : new Polynom();
|
|
24
|
+
this._denominator = denominator ? denominator.clone() : new Polynom();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
private _numerator: Polynom;
|
|
28
|
+
|
|
29
|
+
get numerator(): Polynom {
|
|
30
|
+
return this._numerator
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private _denominator: Polynom;
|
|
34
|
+
|
|
35
|
+
get denominator(): Polynom {
|
|
36
|
+
return this._denominator
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
get tex(): string {
|
|
40
|
+
return `\\frac{ ${this._numerator.tex} }{ ${this._denominator.tex} }`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
get texFactors(): string {
|
|
44
|
+
return `\\frac{ ${this._numerator.texFactors} }{ ${this._denominator.texFactors} }`
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
clone = (): Rational => {
|
|
48
|
+
this._numerator = this._numerator.clone()
|
|
49
|
+
this._denominator = this._denominator.clone()
|
|
50
|
+
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
domain = (): string => {
|
|
55
|
+
let zeroes = this._denominator.getZeroes();
|
|
56
|
+
if (zeroes.length === 0 || zeroes[0].tex === PARTICULAR_SOLUTION.real) {
|
|
57
|
+
return PARTICULAR_SOLUTION.real
|
|
58
|
+
} else if (zeroes[0].tex === PARTICULAR_SOLUTION.varnothing) {
|
|
59
|
+
return PARTICULAR_SOLUTION.varnothing
|
|
60
|
+
} else {
|
|
61
|
+
return '\\mathbb{R}\\setminus\\left\\{' +
|
|
62
|
+
zeroes.map(x => x.tex).join(';') + '\\right\\}'
|
|
25
63
|
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
amplify = (P: Polynom): Rational => {
|
|
67
|
+
this._numerator.multiply(P);
|
|
68
|
+
this._denominator.multiply(P);
|
|
69
|
+
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
derivative = (letter?: string): Rational => {
|
|
74
|
+
let N = this._numerator.clone(),
|
|
75
|
+
D = this._denominator.clone(),
|
|
76
|
+
dN = N.clone().derivative(letter),
|
|
77
|
+
dD = D.clone().derivative(letter)
|
|
26
78
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
this._denominator = this._denominator.clone()
|
|
79
|
+
this._numerator = dN.clone().multiply(D).subtract(N.clone().multiply(dD))
|
|
80
|
+
this._denominator = D.clone().pow(2)
|
|
30
81
|
|
|
82
|
+
return this
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
simplify = (P: Polynom): Rational => {
|
|
86
|
+
let NumeratorEuclidien = this._numerator.euclidian(P);
|
|
87
|
+
if (!NumeratorEuclidien.reminder.isZero()) {
|
|
31
88
|
return this;
|
|
32
89
|
}
|
|
33
90
|
|
|
34
|
-
|
|
35
|
-
|
|
91
|
+
let DenominatorEuclidien = this._denominator.euclidian(P);
|
|
92
|
+
if (!DenominatorEuclidien.reminder.isZero()) {
|
|
93
|
+
return this;
|
|
36
94
|
}
|
|
37
95
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
96
|
+
this._numerator = NumeratorEuclidien.quotient;
|
|
97
|
+
this._denominator = DenominatorEuclidien.quotient;
|
|
98
|
+
return this;
|
|
99
|
+
}
|
|
41
100
|
|
|
42
|
-
|
|
101
|
+
reduce = (): Rational => {
|
|
102
|
+
this._numerator.factorize();
|
|
103
|
+
for (let f of this._numerator.factors) {
|
|
104
|
+
this.simplify(f);
|
|
43
105
|
}
|
|
44
106
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
107
|
+
return this;
|
|
108
|
+
}
|
|
48
109
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
110
|
+
opposed = (): Rational => {
|
|
111
|
+
this._numerator.opposed();
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
add = (R: Rational): Rational => {
|
|
115
|
+
// 1. Make sure both rational are at the same denominator
|
|
116
|
+
// 2. Add the numerators.
|
|
117
|
+
// 3. Simplify
|
|
52
118
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
119
|
+
// Store the adding denominator
|
|
120
|
+
let denominator = this._denominator.clone()
|
|
121
|
+
|
|
122
|
+
// Amplif the main rational polynom by the adding denominator
|
|
123
|
+
this.amplify(R._denominator)
|
|
124
|
+
|
|
125
|
+
// Add to the numerator the adding value...
|
|
126
|
+
this._numerator.add(R._numerator.clone().multiply(denominator));
|
|
127
|
+
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
subtract = (R: Rational): Rational => {
|
|
132
|
+
return this.add(R.clone().opposed())
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
limits = (value: Fraction | number, offset?: string, letter?: string): Fraction => {
|
|
136
|
+
if (value === Infinity || value === -Infinity) {
|
|
137
|
+
let {quotient, reminder} = this._numerator.clone().euclidian(this._denominator)
|
|
138
|
+
|
|
139
|
+
// quotient is positive => it will be infinite.
|
|
140
|
+
if (quotient.degree(letter).isStrictlyPositive()) {
|
|
141
|
+
return value === Infinity ? quotient.limitToInfinity(letter) : quotient.limitToNegativeInfinity(letter)
|
|
142
|
+
// return quotient.monomByDegree(undefined, letter).coefficient.sign()===1?(new Fraction()).infinite():(new Fraction()).infinite().opposed()
|
|
59
143
|
} else {
|
|
60
|
-
return
|
|
61
|
-
zeroes.map(x => {
|
|
62
|
-
return (typeof x === 'boolean') ? '' : x.frac
|
|
63
|
-
})
|
|
64
|
-
.join(';') + '\\right}'
|
|
144
|
+
return quotient.monomByDegree(undefined, letter).coefficient
|
|
65
145
|
}
|
|
66
|
-
}
|
|
146
|
+
} else {
|
|
147
|
+
let evalValues: literalType = {},
|
|
148
|
+
evalValuesOffset: literalType = {},
|
|
149
|
+
theLimit: Fraction | number,
|
|
150
|
+
theSign: number,
|
|
151
|
+
FR = this.clone().reduce()
|
|
67
152
|
|
|
68
|
-
|
|
69
|
-
this._numerator.multiply(P);
|
|
70
|
-
this._denominator.multiply(P);
|
|
153
|
+
evalValues[letter === undefined ? 'x' : letter] = new Fraction(value)
|
|
71
154
|
|
|
72
|
-
|
|
73
|
-
|
|
155
|
+
if (offset !== 'above' && offset !== 'below') {
|
|
156
|
+
theLimit = FR._numerator.evaluate(evalValues)
|
|
157
|
+
.divide(FR._denominator.evaluate(evalValues))
|
|
74
158
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
159
|
+
return theLimit.isInfinity() ? theLimit.abs() : theLimit
|
|
160
|
+
} else {
|
|
161
|
+
if (offset === 'above') {
|
|
162
|
+
evalValuesOffset[letter === undefined ? 'x' : letter] = (new Fraction(value)).add(0.000001)
|
|
163
|
+
} else if (offset === 'below') {
|
|
164
|
+
evalValuesOffset[letter === undefined ? 'x' : letter] = (new Fraction(value)).subtract(0.000001)
|
|
165
|
+
}
|
|
80
166
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
167
|
+
theLimit = FR._numerator.evaluate(evalValues)
|
|
168
|
+
.divide(FR._denominator.evaluate(evalValues))
|
|
169
|
+
theSign = FR._numerator.evaluate(evalValuesOffset)
|
|
170
|
+
.divide(FR._denominator.evaluate(evalValuesOffset)).sign()
|
|
85
171
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
172
|
+
if (theLimit.isInfinity()) {
|
|
173
|
+
return theSign === 1 ? theLimit.abs() : theLimit.abs().opposed()
|
|
174
|
+
} else {
|
|
175
|
+
return theLimit
|
|
176
|
+
}
|
|
177
|
+
}
|
|
89
178
|
}
|
|
179
|
+
}
|
|
90
180
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
181
|
+
makeTableOfSigns = (): { factors: Polynom[], zeroes: ISolution[], signs: (string[])[], tex: string } => {
|
|
182
|
+
// Factorize the numerator and the denominator
|
|
183
|
+
this._numerator.factorize()
|
|
184
|
+
this._denominator.factorize()
|
|
185
|
+
|
|
186
|
+
let zeroes = Equation.makeSolutionsUnique([...this._numerator.getZeroes(), ...this._denominator.getZeroes()], true),
|
|
187
|
+
NFactors = this._numerator.factors,
|
|
188
|
+
DFactors = this._denominator.factors
|
|
189
|
+
|
|
190
|
+
let tableOfSigns: (string[])[] = [],
|
|
191
|
+
result: string[] = []
|
|
192
|
+
|
|
193
|
+
NFactors.forEach(factor => {
|
|
194
|
+
tableOfSigns.push(this._makeOneLineOfTableOfSigns(factor, zeroes, 'z'))
|
|
195
|
+
})
|
|
196
|
+
DFactors.forEach(factor => {
|
|
197
|
+
tableOfSigns.push(this._makeOneLineOfTableOfSigns(factor, zeroes, 'd'))
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
// Empty line
|
|
201
|
+
tableOfSigns.push([])
|
|
202
|
+
|
|
203
|
+
// Add the final row as cumulative
|
|
204
|
+
let resultLine: string[] = tableOfSigns[0].map((x, index) => {
|
|
205
|
+
if (index === 0) {
|
|
206
|
+
return ''
|
|
97
207
|
}
|
|
208
|
+
if (index === tableOfSigns[0].length - 1) {
|
|
209
|
+
return ''
|
|
210
|
+
}
|
|
211
|
+
if (index % 2 === 0) {
|
|
212
|
+
return 't'
|
|
213
|
+
}
|
|
214
|
+
return '+'
|
|
215
|
+
})
|
|
98
216
|
|
|
99
|
-
|
|
217
|
+
for (let current of tableOfSigns) {
|
|
218
|
+
for (let i = 0; i < current.length; i++) {
|
|
219
|
+
if (i % 2 === 0) {
|
|
220
|
+
// t, z or d
|
|
221
|
+
if (resultLine[i] === 'd') {
|
|
222
|
+
continue
|
|
223
|
+
}
|
|
224
|
+
if (current[i] !== 't') {
|
|
225
|
+
resultLine[i] = current[i]
|
|
226
|
+
}
|
|
227
|
+
} else {
|
|
228
|
+
// + or -
|
|
229
|
+
if (current[i] === '-') {
|
|
230
|
+
resultLine[i] = resultLine[i] === '+' ? '-' : '+'
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
100
234
|
}
|
|
101
235
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
236
|
+
// Add the variation line.
|
|
237
|
+
// TODO: add the variation line.
|
|
238
|
+
|
|
239
|
+
tableOfSigns.push(resultLine)
|
|
240
|
+
|
|
241
|
+
let tos = {
|
|
242
|
+
factors: [...NFactors, ...DFactors],
|
|
243
|
+
zeroes: zeroes,
|
|
244
|
+
signs: tableOfSigns,
|
|
245
|
+
tex: ''
|
|
105
246
|
}
|
|
106
|
-
add = (R: Rational): Rational => {
|
|
107
|
-
// 1. Make sure both rational are at the same denominator
|
|
108
|
-
// 2. Add the numerators.
|
|
109
|
-
// 3. Simplify
|
|
110
247
|
|
|
111
|
-
|
|
112
|
-
let denominator = this._denominator.clone()
|
|
248
|
+
this._makeTexFromTableOfSigns(tos)
|
|
113
249
|
|
|
114
|
-
|
|
115
|
-
|
|
250
|
+
return tos
|
|
251
|
+
}
|
|
116
252
|
|
|
117
|
-
|
|
118
|
-
this._numerator.add(R._numerator.clone().multiply(denominator));
|
|
253
|
+
private _makeTexFromTableOfSigns = (tos: { factors: Polynom[], zeroes: ISolution[], signs: (string[])[], tex: string }): string => {
|
|
119
254
|
|
|
120
|
-
|
|
121
|
-
|
|
255
|
+
let tex = `\\begin{tikzpicture}
|
|
256
|
+
\\tkzTabInit[lgt=3,espcl=2,deltacl=0]{/1.2,\\(${tos.factors.map(x => x.tex).join('\\)/1,\\(')}\\)/1,/.1,\\(f(x)\\)/1.2}{{\\scriptsize \\hspace{1cm} \\(-\\infty\\)},\\(${tos.zeroes.map(x => x.tex).join('\\),\\(')}\\),{\\scriptsize \\hspace{-1cm} \\(+\\infty\\)}}`
|
|
257
|
+
tos.signs.forEach(list => {
|
|
258
|
+
tex += (`\n\\tkzTabLine{${list.join(',')}}`)
|
|
259
|
+
})
|
|
260
|
+
tex += `\n\\end{tikzpicture}`
|
|
122
261
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
262
|
+
tos.tex = tex
|
|
263
|
+
|
|
264
|
+
return tex
|
|
265
|
+
}
|
|
266
|
+
private _makeOneLineOfTableOfSigns = (factor: Polynom, zeroes: ISolution[], zeroSign: string): string[] => {
|
|
267
|
+
let oneLine: string[] = [],
|
|
268
|
+
currentZero = factor.getZeroes().map(x=>x.tex)
|
|
126
269
|
|
|
127
|
-
limits = (value: Fraction | number, letter?: string): Fraction | number => {
|
|
128
|
-
if (value === Infinity || value === -Infinity) {
|
|
129
|
-
let N = this._numerator.monomByDegree(this._numerator.degree(letter), letter),
|
|
130
|
-
D = this._denominator.monomByDegree(this._denominator.degree(letter), letter)
|
|
131
270
|
|
|
132
|
-
|
|
271
|
+
// First +/- sign, before the first zero
|
|
272
|
+
oneLine.push('')
|
|
273
|
+
oneLine.push(factor.evaluate(zeroes[0].value - 1).sign() === 1 ? '+' : '-')
|
|
133
274
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
} else {
|
|
144
|
-
return this._numerator.evaluate({letter: new Fraction(value)}).divide(this._denominator.evaluate({letter: new Fraction(value)}))
|
|
275
|
+
for (let i = 0; i < zeroes.length; i++) {
|
|
276
|
+
// Add the zero if it's the current one
|
|
277
|
+
oneLine.push(currentZero.includes(zeroes[i].tex) ? zeroSign : 't')
|
|
278
|
+
|
|
279
|
+
// + / - sign after the current zero
|
|
280
|
+
if (i < zeroes.length - 1) {
|
|
281
|
+
oneLine.push(factor.evaluate((zeroes[i].value + zeroes[i + 1].value) / 2).sign() === 1 ? '+' : '-')
|
|
282
|
+
} else if (i === zeroes.length - 1) {
|
|
283
|
+
oneLine.push(factor.evaluate(zeroes[i].value + 1).sign() === 1 ? '+' : '-')
|
|
145
284
|
}
|
|
285
|
+
|
|
146
286
|
}
|
|
287
|
+
|
|
288
|
+
oneLine.push('')
|
|
289
|
+
|
|
290
|
+
return oneLine
|
|
147
291
|
}
|
|
292
|
+
}
|
|
@@ -21,10 +21,6 @@ export class Fraction {
|
|
|
21
21
|
return this;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
get isFraction() {
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
24
|
// ------------------------------------------
|
|
29
25
|
// Getter and setter
|
|
30
26
|
// ------------------------------------------
|
|
@@ -51,6 +47,10 @@ export class Fraction {
|
|
|
51
47
|
|
|
52
48
|
// Display getter
|
|
53
49
|
get tex(): string {
|
|
50
|
+
if(this.isInfinity()){
|
|
51
|
+
return `${this.sign()===1?'+':'-'}\\infty`
|
|
52
|
+
}
|
|
53
|
+
|
|
54
54
|
if (this._denominator === 1) {
|
|
55
55
|
return `${this._numerator}`;
|
|
56
56
|
} else if (this._numerator < 0) {
|
|
@@ -346,6 +346,44 @@ export class Fraction {
|
|
|
346
346
|
return M
|
|
347
347
|
}
|
|
348
348
|
|
|
349
|
+
static average = (...fractions: (Fraction|number)[]): Fraction => {
|
|
350
|
+
let M = new Fraction().zero()
|
|
351
|
+
|
|
352
|
+
for(let f of fractions){
|
|
353
|
+
M.add(f)
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
M.divide(fractions.length)
|
|
357
|
+
|
|
358
|
+
return M
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
static unique = (fractions: Fraction[], sorted?: boolean): Fraction[] => {
|
|
362
|
+
// TODO: make sure it's wokring -> test !
|
|
363
|
+
let unique:{[Key:string]:boolean} = {},
|
|
364
|
+
distinct: Fraction[] = []
|
|
365
|
+
fractions.forEach(x => {
|
|
366
|
+
if(!unique[x.clone().reduce().tex]){
|
|
367
|
+
distinct.push(x.clone())
|
|
368
|
+
unique[x.tex]=true
|
|
369
|
+
}
|
|
370
|
+
})
|
|
371
|
+
|
|
372
|
+
if(sorted) {
|
|
373
|
+
return Fraction.sort(distinct)
|
|
374
|
+
}else{
|
|
375
|
+
return distinct
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
static sort = (fractions: Fraction[], reverse?:boolean): Fraction[] => {
|
|
379
|
+
// Todo make sure it's the correct order, not reverse -> make a test
|
|
380
|
+
let sorted = fractions.sort((a, b)=>a.value-b.value)
|
|
381
|
+
|
|
382
|
+
if(reverse){sorted.reverse()}
|
|
383
|
+
|
|
384
|
+
return sorted
|
|
385
|
+
}
|
|
386
|
+
|
|
349
387
|
// ------------------------------------------
|
|
350
388
|
// Mathematical operations specific to fractions
|
|
351
389
|
// ------------------------------------------
|
|
@@ -463,10 +501,10 @@ export class Fraction {
|
|
|
463
501
|
return isNaN(this._numerator);
|
|
464
502
|
}
|
|
465
503
|
isInfinity = (): boolean => {
|
|
466
|
-
return this._numerator === Infinity;
|
|
504
|
+
return Math.abs(this._numerator) === Infinity;
|
|
467
505
|
}
|
|
468
506
|
isFinite = (): boolean => {
|
|
469
|
-
return !this.isInfinity();
|
|
507
|
+
return !this.isInfinity() && !this.isNaN();
|
|
470
508
|
}
|
|
471
509
|
isSquare = (): boolean => {
|
|
472
510
|
return Math.sqrt(this._numerator) % 1 === 0 && Math.sqrt(this._denominator) % 1 === 0
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* NthRoot is something like "a+b\sqrt{3}
|
|
3
3
|
*/
|
|
4
|
-
export class
|
|
4
|
+
export class NthRoot {
|
|
5
5
|
private _radical: number;
|
|
6
6
|
private _nth: number;
|
|
7
7
|
private _coefficient: number;
|
|
@@ -80,7 +80,7 @@ export class Nthroot {
|
|
|
80
80
|
// ------------------------------------------
|
|
81
81
|
// Creation / parsing functions
|
|
82
82
|
// ------------------------------------------
|
|
83
|
-
parse = (radical: number, nthroot?: number, coefficient?: number):
|
|
83
|
+
parse = (radical: number, nthroot?: number, coefficient?: number): NthRoot => {
|
|
84
84
|
this._coefficient = (coefficient === undefined) ? 1 : coefficient;
|
|
85
85
|
this._nth = (nthroot === undefined) ? 2 : nthroot;
|
|
86
86
|
this._radical = (radical === undefined) ? 1 : radical;
|
|
@@ -94,7 +94,7 @@ export class Nthroot {
|
|
|
94
94
|
// ------------------------------------------
|
|
95
95
|
// Mathematical operations
|
|
96
96
|
// ------------------------------------------
|
|
97
|
-
reduce = ():
|
|
97
|
+
reduce = (): NthRoot => {
|
|
98
98
|
// Max value to test.
|
|
99
99
|
let V = Math.floor(Math.pow(this._radical, 1 / this._nth));
|
|
100
100
|
while (V > 1) {
|
|
@@ -112,7 +112,7 @@ export class Nthroot {
|
|
|
112
112
|
return this;
|
|
113
113
|
};
|
|
114
114
|
|
|
115
|
-
multiply = (N:
|
|
115
|
+
multiply = (N: NthRoot): NthRoot => {
|
|
116
116
|
this._radical *= N.radical;
|
|
117
117
|
return this.reduce();
|
|
118
118
|
};
|
|
@@ -57,9 +57,8 @@ export class PolynomExpFactor {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
console.log(numerators.length)
|
|
61
60
|
if (denominators.length > 0) {
|
|
62
|
-
return `\\
|
|
61
|
+
return `\\frac{ ${numerators.length > 0 ? numerators.join('') : 1} }{ ${denominators.join('')} }`
|
|
63
62
|
} else {
|
|
64
63
|
return numerators.join('')
|
|
65
64
|
}
|
|
@@ -10,6 +10,7 @@ export class PolynomExpFactor {
|
|
|
10
10
|
this._fn = mathFunction
|
|
11
11
|
this._powerAsInteger = true
|
|
12
12
|
this._forceParenthesis = true
|
|
13
|
+
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
private _forceParenthesis: boolean
|
|
@@ -206,7 +207,7 @@ export class PolynomExpProduct {
|
|
|
206
207
|
// restore all degrees to negative again.
|
|
207
208
|
denominators.map(x => x.degree.opposed())
|
|
208
209
|
|
|
209
|
-
tex = `\\
|
|
210
|
+
tex = `\\frac{ ${numeratorsAsTex.join(' \\cdot ')} }{ ${denominatorsAsTex.join(' \\cdot ')} }`
|
|
210
211
|
}
|
|
211
212
|
}
|
|
212
213
|
|
|
@@ -181,7 +181,7 @@ export class Point {
|
|
|
181
181
|
|
|
182
182
|
value = V.norm
|
|
183
183
|
fraction = V.normSquare.sqrt()
|
|
184
|
-
tex = V.normSquare.isSquare()?fraction.tex
|
|
184
|
+
tex = V.normSquare.isSquare() ? fraction.tex : `\\sqrt{\\frac{ ${V.normSquare.numerator} }{ ${V.normSquare.denominator} }}`
|
|
185
185
|
}
|
|
186
186
|
return { value, fraction, tex }
|
|
187
187
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {describe} from "mocha";
|
|
2
|
+
import {expect} from "chai";
|
|
3
|
+
import {Equation} from "../../src/maths/algebra/equation";
|
|
4
|
+
|
|
5
|
+
describe('Equations tests', () => {
|
|
6
|
+
it('should get the solutions', () => {
|
|
7
|
+
|
|
8
|
+
let E1 = new Equation('3x+8', '0')
|
|
9
|
+
E1.solve()
|
|
10
|
+
expect(E1.solutions[0].tex).to.be.equal('-\\frac{ 8 }{ 3 }')
|
|
11
|
+
|
|
12
|
+
let E2 = new Equation('x^2+5x+6', '0')
|
|
13
|
+
E2.solve()
|
|
14
|
+
expect(E2.solutions.map(x=>x.tex)).to.have.all.members(['-3', '-2'])
|
|
15
|
+
|
|
16
|
+
let E3 = new Equation('(x-3)(x+2)(3x-5)', '0')
|
|
17
|
+
E3.solve()
|
|
18
|
+
expect(E3.solutions.map(x=>x.tex)).to.have.all.members([ '-2', '3', '\\frac{ 5 }{ 3 }' ])
|
|
19
|
+
|
|
20
|
+
let E4 = new Equation('x^2+x+10', '0')
|
|
21
|
+
E4.solve()
|
|
22
|
+
expect(E4.solutions.map(x=>x.tex)).to.have.all.members([ '\\varnothing' ])
|
|
23
|
+
|
|
24
|
+
let E5 = new Equation('(x-3)(x+2)(x-5)(x-7)(x+2)', 0)
|
|
25
|
+
E5.solve()
|
|
26
|
+
expect(E5.solutions.map(x=>x.tex)).to.have.all.members([ '-2', '3', '5', '7' ] )
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
let E6 = new Equation('5x^2+7x-31', 0)
|
|
30
|
+
E6.solve()
|
|
31
|
+
expect(E6.solutions.map(x=>x.tex)).to.have.all.members([
|
|
32
|
+
'\\frac{-7 - \\sqrt{669} }{ 10 }',
|
|
33
|
+
'\\frac{-7 + \\sqrt{669} }{ 10 }'
|
|
34
|
+
] )
|
|
35
|
+
})
|
|
36
|
+
})
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
import {expect} from 'chai';
|
|
2
|
-
import {Monom} from "../../src/maths/algebra";
|
|
3
2
|
import {Random} from "../../src/maths/randomization/random";
|
|
4
3
|
import {describe} from "mocha";
|
|
5
|
-
import {
|
|
6
|
-
import {Shutingyard} from "../../src/maths/shutingyard";
|
|
7
|
-
import {log} from "util";
|
|
4
|
+
import {Monom} from "../../src/maths/algebra/monom";
|
|
8
5
|
|
|
9
6
|
describe('Monom with integer power', () => {
|
|
10
7
|
it('parsing', () => {
|
|
@@ -79,6 +76,6 @@ describe('Monom with fraction power', () => {
|
|
|
79
76
|
console.log(M.tex)
|
|
80
77
|
|
|
81
78
|
// TODO: Problem while displaying numerical expression
|
|
82
|
-
expect(M.tex).to.be.equal('-\\
|
|
79
|
+
expect(M.tex).to.be.equal('-\\frac{ 7 }{ 5 }x^{\\tfrac{ 22 }{ 15 }}')
|
|
83
80
|
})
|
|
84
81
|
})
|
|
@@ -15,7 +15,7 @@ describe('Polynom tests', () => {
|
|
|
15
15
|
const P = new Polynom('-3/5x-2')
|
|
16
16
|
|
|
17
17
|
console.log(P.tex)
|
|
18
|
-
expect(P.tex).to.be.equal('-\\
|
|
18
|
+
expect(P.tex).to.be.equal('-\\frac{ 3 }{ 5 }x-2')
|
|
19
19
|
})
|
|
20
20
|
|
|
21
21
|
it('Tex display', () => {
|
|
@@ -43,7 +43,7 @@ describe('Polynom tests', () => {
|
|
|
43
43
|
expect(F.integrate(0, 2).value).to.be.equal(-4)
|
|
44
44
|
expect(G.integrate(-3, 3).display).to.be.equal('174/5')
|
|
45
45
|
})
|
|
46
|
-
it('Random Polynom of degree
|
|
46
|
+
it('Random Polynom of degree 6', () => {
|
|
47
47
|
let P = Random.polynom({
|
|
48
48
|
degree: 6,
|
|
49
49
|
numberOfMonoms: 3,
|
|
@@ -72,6 +72,10 @@ describe('Polynom tests', () => {
|
|
|
72
72
|
|
|
73
73
|
P.factorize()
|
|
74
74
|
expect(P.factors.map(x => x.tex)).to.have.all.members(['x-2', 'x-3'])
|
|
75
|
+
|
|
76
|
+
let P2 = new Polynom('x^4-32x^2+256')
|
|
77
|
+
P2.factorize()
|
|
78
|
+
expect(P2.factors.map(x => x.tex)).to.have.all.members(['x-4', 'x-4', 'x+4', 'x+4'])
|
|
75
79
|
})
|
|
76
80
|
})
|
|
77
81
|
|
|
@@ -79,7 +83,7 @@ describe('Polynom parsing with rational power', () => {
|
|
|
79
83
|
it('should parse with rational powers', () => {
|
|
80
84
|
const P = new Polynom('3x^(2/3)-5x+5/3');
|
|
81
85
|
|
|
82
|
-
expect(P.tex).to.be.equal('3x^{\\tfrac{ 2 }{ 3 }}-5x+\\
|
|
86
|
+
expect(P.tex).to.be.equal('3x^{\\tfrac{ 2 }{ 3 }}-5x+\\frac{ 5 }{ 3 }')
|
|
83
87
|
})
|
|
84
88
|
})
|
|
85
89
|
|