pimath 0.0.38 → 0.0.39
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/pi.js +72 -19
- package/dist/pi.js.map +1 -1
- package/dist/pi.min.js +1 -1
- package/dist/pi.min.js.map +1 -1
- package/esm/maths/algebra/polynom.d.ts +2 -0
- package/esm/maths/algebra/polynom.js +22 -0
- package/esm/maths/algebra/polynom.js.map +1 -1
- package/esm/maths/algebra/rational.d.ts +6 -6
- package/esm/maths/algebra/rational.js +39 -19
- package/esm/maths/algebra/rational.js.map +1 -1
- package/esm/maths/coefficients/fraction.js +3 -0
- package/esm/maths/coefficients/fraction.js.map +1 -1
- package/esm/maths/geometry/line.js +8 -0
- package/esm/maths/geometry/line.js.map +1 -1
- package/package.json +1 -1
- package/src/maths/algebra/polynom.ts +28 -0
- package/src/maths/algebra/rational.ts +129 -101
- package/src/maths/coefficients/fraction.ts +4 -0
- package/src/maths/geometry/line.ts +6 -0
- package/src/maths/geometry/point.ts +2 -2
- package/tests/algebra/rationnal.test.ts +44 -0
|
@@ -5,143 +5,171 @@
|
|
|
5
5
|
|
|
6
6
|
import {Polynom} from "./polynom";
|
|
7
7
|
import {Fraction} from "../coefficients/fraction";
|
|
8
|
+
import {literalType} from "./monom";
|
|
9
|
+
import {log} from "util";
|
|
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
|
-
this._denominator = denominator ? denominator.clone() : new Polynom();
|
|
25
|
-
}
|
|
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
26
|
|
|
27
|
-
|
|
28
|
-
this._numerator = this._numerator.clone()
|
|
29
|
-
this._denominator = this._denominator.clone()
|
|
27
|
+
private _numerator: Polynom;
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
get numerator(): Polynom {
|
|
30
|
+
return this._numerator
|
|
31
|
+
}
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
return `\\dfrac{ ${this._numerator.tex} }{ ${this._denominator.tex} }`;
|
|
36
|
-
}
|
|
33
|
+
private _denominator: Polynom;
|
|
37
34
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
get denominator(): Polynom {
|
|
36
|
+
return this._denominator
|
|
37
|
+
}
|
|
41
38
|
|
|
42
|
-
|
|
43
|
-
}
|
|
39
|
+
get tex(): string {
|
|
40
|
+
return `\\dfrac{ ${this._numerator.tex} }{ ${this._denominator.tex} }`;
|
|
41
|
+
}
|
|
44
42
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
get texFactors(): string {
|
|
44
|
+
this._numerator.factorize()
|
|
45
|
+
this._denominator.factorize()
|
|
48
46
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
47
|
+
return `\\dfrac{ ${this._numerator.texFactors} }{ ${this._denominator.texFactors} }`
|
|
48
|
+
}
|
|
52
49
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return '\\mathbb{R}'
|
|
57
|
-
} else if (zeroes[0] === true) {
|
|
58
|
-
return '\\varnothing'
|
|
59
|
-
} else {
|
|
60
|
-
return '\\mathbb{R}\\setminus\\left{' +
|
|
61
|
-
zeroes.map(x => {
|
|
62
|
-
return (typeof x === 'boolean') ? '' : x.frac
|
|
63
|
-
})
|
|
64
|
-
.join(';') + '\\right}'
|
|
65
|
-
}
|
|
66
|
-
}
|
|
50
|
+
clone = (): Rational => {
|
|
51
|
+
this._numerator = this._numerator.clone()
|
|
52
|
+
this._denominator = this._denominator.clone()
|
|
67
53
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
this._denominator.multiply(P);
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
71
56
|
|
|
72
|
-
|
|
57
|
+
domain = (): string => {
|
|
58
|
+
let zeroes = this._denominator.getZeroes();
|
|
59
|
+
if (zeroes.length === 0 || zeroes[0] === false) {
|
|
60
|
+
return '\\mathbb{R}'
|
|
61
|
+
} else if (zeroes[0] === true) {
|
|
62
|
+
return '\\varnothing'
|
|
63
|
+
} else {
|
|
64
|
+
return '\\mathbb{R}\\setminus\\left{' +
|
|
65
|
+
zeroes.map(x => {
|
|
66
|
+
return (typeof x === 'boolean') ? '' : x.frac
|
|
67
|
+
})
|
|
68
|
+
.join(';') + '\\right}'
|
|
73
69
|
}
|
|
70
|
+
}
|
|
74
71
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return this;
|
|
79
|
-
}
|
|
72
|
+
amplify = (P: Polynom): Rational => {
|
|
73
|
+
this._numerator.multiply(P);
|
|
74
|
+
this._denominator.multiply(P);
|
|
80
75
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return this;
|
|
84
|
-
}
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
85
78
|
|
|
86
|
-
|
|
87
|
-
|
|
79
|
+
simplify = (P: Polynom): Rational => {
|
|
80
|
+
let NumeratorEuclidien = this._numerator.euclidian(P);
|
|
81
|
+
if (!NumeratorEuclidien.reminder.isZero()) {
|
|
88
82
|
return this;
|
|
89
83
|
}
|
|
90
84
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
this._numerator.factorize();
|
|
94
|
-
console.log(this._numerator.factors.map(x => x.tex))
|
|
95
|
-
for (let f of this._numerator.factors) {
|
|
96
|
-
this.simplify(f);
|
|
97
|
-
}
|
|
98
|
-
|
|
85
|
+
let DenominatorEuclidien = this._denominator.euclidian(P);
|
|
86
|
+
if (!DenominatorEuclidien.reminder.isZero()) {
|
|
99
87
|
return this;
|
|
100
88
|
}
|
|
101
89
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
90
|
+
this._numerator = NumeratorEuclidien.quotient;
|
|
91
|
+
this._denominator = DenominatorEuclidien.quotient;
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
reduce = (): Rational => {
|
|
96
|
+
this._numerator.factorize();
|
|
97
|
+
for (let f of this._numerator.factors) {
|
|
98
|
+
this.simplify(f);
|
|
105
99
|
}
|
|
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
100
|
|
|
111
|
-
|
|
112
|
-
|
|
101
|
+
return this;
|
|
102
|
+
}
|
|
113
103
|
|
|
114
|
-
|
|
115
|
-
|
|
104
|
+
opposed = (): Rational => {
|
|
105
|
+
this._numerator.opposed();
|
|
106
|
+
return this;
|
|
107
|
+
}
|
|
108
|
+
add = (R: Rational): Rational => {
|
|
109
|
+
// 1. Make sure both rational are at the same denominator
|
|
110
|
+
// 2. Add the numerators.
|
|
111
|
+
// 3. Simplify
|
|
116
112
|
|
|
117
|
-
|
|
118
|
-
|
|
113
|
+
// Store the adding denominator
|
|
114
|
+
let denominator = this._denominator.clone()
|
|
119
115
|
|
|
120
|
-
|
|
121
|
-
|
|
116
|
+
// Amplif the main rational polynom by the adding denominator
|
|
117
|
+
this.amplify(R._denominator)
|
|
122
118
|
|
|
123
|
-
|
|
124
|
-
|
|
119
|
+
// Add to the numerator the adding value...
|
|
120
|
+
this._numerator.add(R._numerator.clone().multiply(denominator));
|
|
121
|
+
|
|
122
|
+
return this;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
subtract = (R: Rational): Rational => {
|
|
126
|
+
return this.add(R.clone().opposed())
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
limits = (value: Fraction | number, offset?: string, letter?: string): Fraction => {
|
|
130
|
+
if (value === Infinity || value === -Infinity) {
|
|
131
|
+
let {quotient, reminder} = this._numerator.clone().euclidian(this._denominator)
|
|
132
|
+
|
|
133
|
+
// quotient is positive => it will be infinite.
|
|
134
|
+
if(quotient.degree(letter).isStrictlyPositive()){
|
|
135
|
+
return value===Infinity ? quotient.limitToInfinity(letter):quotient.limitToNegativeInfinity(letter)
|
|
136
|
+
// return quotient.monomByDegree(undefined, letter).coefficient.sign()===1?(new Fraction()).infinite():(new Fraction()).infinite().opposed()
|
|
137
|
+
}else{
|
|
138
|
+
return quotient.monomByDegree(undefined, letter).coefficient
|
|
139
|
+
}
|
|
125
140
|
}
|
|
141
|
+
else {
|
|
142
|
+
let evalValues: literalType = {},
|
|
143
|
+
evalValuesOffset: literalType = {},
|
|
144
|
+
theLimit: Fraction | number,
|
|
145
|
+
theSign: number,
|
|
146
|
+
FR = this.clone().reduce()
|
|
126
147
|
|
|
127
|
-
|
|
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)
|
|
148
|
+
evalValues[letter === undefined ? 'x' : letter] = new Fraction(value)
|
|
131
149
|
|
|
132
|
-
|
|
150
|
+
if (offset !== 'above' && offset !== 'below') {
|
|
151
|
+
theLimit = FR._numerator.evaluate(evalValues)
|
|
152
|
+
.divide(FR._denominator.evaluate(evalValues))
|
|
133
153
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
154
|
+
return theLimit.isInfinity()?theLimit.abs():theLimit
|
|
155
|
+
} else {
|
|
156
|
+
if (offset === 'above') {
|
|
157
|
+
evalValuesOffset[letter === undefined ? 'x' : letter] = (new Fraction(value)).add(0.000001)
|
|
158
|
+
} else if (offset === 'below') {
|
|
159
|
+
evalValuesOffset[letter === undefined ? 'x' : letter] = (new Fraction(value)).subtract(0.000001)
|
|
139
160
|
}
|
|
140
|
-
|
|
141
|
-
|
|
161
|
+
|
|
162
|
+
theLimit = FR._numerator.evaluate(evalValues)
|
|
163
|
+
.divide(FR._denominator.evaluate(evalValues))
|
|
164
|
+
theSign = FR._numerator.evaluate(evalValuesOffset)
|
|
165
|
+
.divide(FR._denominator.evaluate(evalValuesOffset)).sign()
|
|
166
|
+
|
|
167
|
+
if (theLimit.isInfinity()) {
|
|
168
|
+
return theSign===1?theLimit.abs():theLimit.abs().opposed()
|
|
169
|
+
}else{
|
|
170
|
+
return theLimit
|
|
142
171
|
}
|
|
143
|
-
} else {
|
|
144
|
-
return this._numerator.evaluate({letter: new Fraction(value)}).divide(this._denominator.evaluate({letter: new Fraction(value)}))
|
|
145
172
|
}
|
|
146
173
|
}
|
|
147
174
|
}
|
|
175
|
+
}
|
|
@@ -195,6 +195,12 @@ export class Line {
|
|
|
195
195
|
}else if (values[2] === LinePropriety.Parallel){
|
|
196
196
|
return this.parseByPointAndVector(values[0], values[1])
|
|
197
197
|
}
|
|
198
|
+
}else if (values[0] instanceof Point && values[1] instanceof Line ) {
|
|
199
|
+
if(values[2]===LinePropriety.Parallel || values[2]===null) {
|
|
200
|
+
return this.parseByPointAndLine(values[0], values[1], LinePropriety.Parallel)
|
|
201
|
+
}else{
|
|
202
|
+
return this.parseByPointAndLine(values[0], values[1], LinePropriety.Perpendicular)
|
|
203
|
+
}
|
|
198
204
|
}
|
|
199
205
|
}
|
|
200
206
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import {describe} from "mocha";
|
|
2
|
+
import {Rational} from "../../src/maths/algebra/rational";
|
|
3
|
+
import {Polynom} from "../../src/maths/algebra/polynom";
|
|
4
|
+
import {Fraction} from "../../src/maths/coefficients/fraction";
|
|
5
|
+
import {expect} from "chai";
|
|
6
|
+
|
|
7
|
+
describe('Rational tests', () => {
|
|
8
|
+
it('should calculate correctly the limits to a value', () => {
|
|
9
|
+
|
|
10
|
+
const FR = new Rational(
|
|
11
|
+
new Polynom('(x+2)'),
|
|
12
|
+
new Polynom('(x-4)(x+2)')
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
expect(FR.limits(4).tex).to.be.equal("Infinity")
|
|
16
|
+
expect(FR.limits(4, 'below').tex).to.be.equal("-Infinity")
|
|
17
|
+
expect(FR.limits(4, 'above').tex).to.be.equal("Infinity")
|
|
18
|
+
expect(FR.limits(-2).tex).to.be.equal("-\\frac{ 1 }{ 6 }")
|
|
19
|
+
})
|
|
20
|
+
it('should calculate the limits to Infinity', ()=>{
|
|
21
|
+
const FR0 = new Rational(
|
|
22
|
+
new Polynom('3'),
|
|
23
|
+
new Polynom('x-5')
|
|
24
|
+
)
|
|
25
|
+
const FR2 = new Rational(
|
|
26
|
+
new Polynom('2x+5'),
|
|
27
|
+
new Polynom('x-5')
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
const FR3 = new Rational(
|
|
31
|
+
new Polynom('2x^2+5'),
|
|
32
|
+
new Polynom('x-5')
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
expect(FR0.limits(Infinity).value).to.be.equal(0)
|
|
36
|
+
expect(FR0.limits(-Infinity).value).to.be.equal(0)
|
|
37
|
+
|
|
38
|
+
expect(FR2.limits(Infinity).value).to.be.equal(2)
|
|
39
|
+
expect(FR2.limits(-Infinity).value).to.be.equal(2)
|
|
40
|
+
|
|
41
|
+
expect(FR3.limits(Infinity).value).to.be.equal(Infinity)
|
|
42
|
+
expect(FR3.limits(-Infinity).value).to.be.equal(-Infinity)
|
|
43
|
+
})
|
|
44
|
+
})
|