pimath 0.0.68 → 0.0.71
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 +8 -2
- 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/equation.js +1 -1
- package/esm/maths/algebra/equation.js.map +1 -1
- package/esm/maths/algebra/polynom.js +1 -1
- package/esm/maths/algebra/polynom.js.map +1 -1
- package/esm/maths/coefficients/fraction.d.ts +1 -0
- package/esm/maths/coefficients/fraction.js +3 -0
- package/esm/maths/coefficients/fraction.js.map +1 -1
- package/esm/maths/expressions/expression.d.ts +6 -0
- package/esm/maths/expressions/expression.js +79 -1
- package/esm/maths/expressions/expression.js.map +1 -1
- package/esm/maths/expressions/expressionFactor.d.ts +8 -1
- package/esm/maths/expressions/expressionFactor.js +51 -4
- package/esm/maths/expressions/expressionFactor.js.map +1 -1
- package/esm/maths/expressions/expressionMember.d.ts +12 -1
- package/esm/maths/expressions/expressionMember.js +128 -19
- package/esm/maths/expressions/expressionMember.js.map +1 -1
- package/esm/maths/expressions/expressionParser.d.ts +2 -0
- package/esm/maths/expressions/expressionParser.js +74 -34
- package/esm/maths/expressions/expressionParser.js.map +1 -1
- package/esm/maths/expressions/factors/ExpFactor.d.ts +2 -2
- package/esm/maths/expressions/factors/ExpFactor.js +15 -3
- package/esm/maths/expressions/factors/ExpFactor.js.map +1 -1
- package/esm/maths/expressions/factors/ExpFactorConstant.d.ts +1 -0
- package/esm/maths/expressions/factors/ExpFactorConstant.js +3 -0
- package/esm/maths/expressions/factors/ExpFactorConstant.js.map +1 -1
- package/esm/maths/expressions/factors/ExpFactorExponential.d.ts +1 -0
- package/esm/maths/expressions/factors/ExpFactorExponential.js +4 -0
- package/esm/maths/expressions/factors/ExpFactorExponential.js.map +1 -1
- package/esm/maths/expressions/factors/ExpFactorNumber.d.ts +3 -2
- package/esm/maths/expressions/factors/ExpFactorNumber.js +23 -0
- package/esm/maths/expressions/factors/ExpFactorNumber.js.map +1 -1
- package/esm/maths/expressions/factors/ExpFactorPower.d.ts +5 -1
- package/esm/maths/expressions/factors/ExpFactorPower.js +15 -2
- package/esm/maths/expressions/factors/ExpFactorPower.js.map +1 -1
- package/esm/maths/expressions/factors/ExpFactorTrigo.d.ts +1 -0
- package/esm/maths/expressions/factors/ExpFactorTrigo.js +8 -0
- package/esm/maths/expressions/factors/ExpFactorTrigo.js.map +1 -1
- package/esm/maths/expressions/factors/ExpFactorVariable.d.ts +1 -0
- package/esm/maths/expressions/factors/ExpFactorVariable.js +3 -0
- package/esm/maths/expressions/factors/ExpFactorVariable.js.map +1 -1
- package/esm/maths/expressions/polynomexp.bkp.js +0 -1
- package/esm/maths/expressions/polynomexp.bkp.js.map +1 -1
- package/esm/maths/shutingyard.js +3 -0
- package/esm/maths/shutingyard.js.map +1 -1
- package/package.json +1 -1
- package/src/maths/algebra/equation.ts +1 -1
- package/src/maths/algebra/polynom.ts +1 -1
- package/src/maths/coefficients/fraction.ts +4 -0
- package/src/maths/expressions/expression.ts +115 -20
- package/src/maths/expressions/expressionFactor.ts +59 -7
- package/src/maths/expressions/expressionMember.ts +141 -22
- package/src/maths/expressions/expressionParser.ts +79 -33
- package/src/maths/expressions/factors/ExpFactor.ts +19 -6
- package/src/maths/expressions/factors/ExpFactorConstant.ts +4 -0
- package/src/maths/expressions/factors/ExpFactorExponential.ts +7 -0
- package/src/maths/expressions/factors/ExpFactorNumber.ts +32 -4
- package/src/maths/expressions/factors/ExpFactorPower.ts +21 -3
- package/src/maths/expressions/factors/ExpFactorTrigo.ts +10 -1
- package/src/maths/expressions/factors/ExpFactorVariable.ts +5 -0
- package/src/maths/expressions/polynomexp.bkp.ts +0 -1
- package/src/maths/shutingyard.ts +4 -1
- package/tests/expressions/expressions.test.ts +24 -3
- package/tests/geometry/circle.test.ts +6 -0
- package/esm/maths/expressions/factors/ExpFactorSin.d.ts +0 -7
- package/esm/maths/expressions/factors/ExpFactorSin.js +0 -22
- package/esm/maths/expressions/factors/ExpFactorSin.js.map +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {Expression} from "./internals";
|
|
2
|
+
import {Numeric} from "../numeric";
|
|
2
3
|
|
|
3
4
|
export abstract class ExpressionFactor {
|
|
4
5
|
constructor(
|
|
@@ -30,6 +31,10 @@ export abstract class ExpressionFactor {
|
|
|
30
31
|
return this.makeTeX()
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
get display(): string {
|
|
35
|
+
return this.makeDisplay()
|
|
36
|
+
}
|
|
37
|
+
|
|
33
38
|
get power(): number {
|
|
34
39
|
return this._power;
|
|
35
40
|
}
|
|
@@ -62,10 +67,18 @@ export abstract class ExpressionFactor {
|
|
|
62
67
|
|
|
63
68
|
abstract makeTeX(numberOfFactors?: number, position?: number): string
|
|
64
69
|
|
|
70
|
+
abstract makeDisplay(numberOfFactors?: number, position?: number): string
|
|
71
|
+
|
|
65
72
|
abstract derivative(variable: string): Expression
|
|
66
73
|
|
|
67
74
|
abstract integrate(variable: string): Expression
|
|
68
75
|
|
|
76
|
+
getArguments(): Expression[] {
|
|
77
|
+
if (this._argument !== null){
|
|
78
|
+
return [this.argument]
|
|
79
|
+
}
|
|
80
|
+
return []
|
|
81
|
+
}
|
|
69
82
|
hasVariable(variable?: string): boolean {
|
|
70
83
|
|
|
71
84
|
if (variable === undefined) {
|
|
@@ -78,15 +91,13 @@ export abstract class ExpressionFactor {
|
|
|
78
91
|
}
|
|
79
92
|
|
|
80
93
|
return false
|
|
81
|
-
|
|
82
94
|
}
|
|
83
95
|
|
|
84
96
|
isNumeric(): boolean {
|
|
85
|
-
|
|
86
|
-
|
|
97
|
+
for(let expressionArgument of this.getArguments()){
|
|
98
|
+
if(!expressionArgument.isNumeric()){return false}
|
|
87
99
|
}
|
|
88
|
-
|
|
89
|
-
|
|
100
|
+
return true
|
|
90
101
|
}
|
|
91
102
|
|
|
92
103
|
hasRoot(): boolean {
|
|
@@ -106,6 +117,28 @@ export abstract class ExpressionFactor {
|
|
|
106
117
|
return this.texPower(this.texRoot(tex))
|
|
107
118
|
}
|
|
108
119
|
|
|
120
|
+
displayPowerAndRoot(display: string): string {
|
|
121
|
+
return this.displayPower(this.displayRoot(display))
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
displayPower(display: string):string {
|
|
125
|
+
if (this.hasPower(this.inline)) {
|
|
126
|
+
return `${display}^(${Math.abs(this.power)})`
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return display
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
displayRoot(display: string): string {
|
|
133
|
+
if (this.root === 2) {
|
|
134
|
+
return `sqrt( ${display} )`
|
|
135
|
+
} else if (this.root > 2) {
|
|
136
|
+
return `nthrt(${display},${this.root})`
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return display
|
|
140
|
+
}
|
|
141
|
+
|
|
109
142
|
texPower(tex: string): string {
|
|
110
143
|
if (this.hasPower(this.inline)) {
|
|
111
144
|
return `${tex}^{ ${Math.abs(this.power)} }`
|
|
@@ -114,8 +147,12 @@ export abstract class ExpressionFactor {
|
|
|
114
147
|
return tex
|
|
115
148
|
}
|
|
116
149
|
|
|
117
|
-
wrapWithParentheses(tex: string): string {
|
|
118
|
-
|
|
150
|
+
wrapWithParentheses(tex: string, asTex?: boolean): string {
|
|
151
|
+
if(asTex===undefined || asTex===true) {
|
|
152
|
+
return `\\left( ${tex} \\right)`
|
|
153
|
+
}else{
|
|
154
|
+
return `( ${tex} )`
|
|
155
|
+
}
|
|
119
156
|
}
|
|
120
157
|
|
|
121
158
|
texRoot(tex: string): string {
|
|
@@ -135,4 +172,19 @@ export abstract class ExpressionFactor {
|
|
|
135
172
|
|
|
136
173
|
return this._argument === 0
|
|
137
174
|
}
|
|
175
|
+
|
|
176
|
+
reduce(): ExpressionFactor {
|
|
177
|
+
let gcd = Numeric.gcd(this.root, this.power)
|
|
178
|
+
|
|
179
|
+
if(gcd>1){
|
|
180
|
+
this.root = this.root/gcd
|
|
181
|
+
this.power = this.power/gcd
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
for(let expressionArgument of this.getArguments()){
|
|
185
|
+
expressionArgument.reduce()
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return this
|
|
189
|
+
}
|
|
138
190
|
}
|
|
@@ -24,39 +24,87 @@ export class ExpressionMember {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
get tex(): string {
|
|
27
|
-
|
|
28
|
-
den = this.denominator,
|
|
29
|
-
numTex = num.map((x, index) => x.makeTeX(num.length, index)),
|
|
30
|
-
denTex = den.map((x, index) => x.makeTeX(den.length, index))
|
|
31
|
-
|
|
32
|
-
if (den.length > 0) {
|
|
33
|
-
return `\\frac{ ${numTex.join("")} }{ ${denTex.join("")} }`
|
|
34
|
-
} else {
|
|
35
|
-
return numTex.join("")
|
|
36
|
-
}
|
|
27
|
+
return this.toString(true)
|
|
37
28
|
}
|
|
38
29
|
|
|
39
|
-
|
|
40
|
-
|
|
30
|
+
get display(): string {
|
|
31
|
+
return this.toString(false)
|
|
32
|
+
}
|
|
41
33
|
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
toString(asTex: boolean): string {
|
|
35
|
+
if (asTex === undefined) {
|
|
36
|
+
asTex = true
|
|
44
37
|
}
|
|
45
38
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
let outputArray = this.factors.map(x => {
|
|
40
|
+
return {
|
|
41
|
+
value: asTex ? x.tex : x.display,
|
|
42
|
+
valueWithoutParentheses: asTex ? x.makeTeX(1, 0):x.makeDisplay(1, 0),
|
|
43
|
+
denominator: x.power < 0,
|
|
44
|
+
number: (x instanceof ExpFactorNumber)
|
|
45
|
+
}
|
|
46
|
+
}), output: string = ''
|
|
47
|
+
|
|
48
|
+
while (outputArray.length > 0) {
|
|
49
|
+
let item = outputArray.shift()
|
|
50
|
+
|
|
51
|
+
if (item.denominator) {
|
|
52
|
+
if (asTex) {
|
|
53
|
+
output += `\\frac{1}{ ${item.valueWithoutParentheses} }`
|
|
54
|
+
} else {
|
|
55
|
+
output += `1/(${item.valueWithoutParentheses})`
|
|
56
|
+
}
|
|
49
57
|
} else {
|
|
50
|
-
|
|
58
|
+
if (outputArray.length > 0 && outputArray[0].denominator) {
|
|
59
|
+
let item2 = outputArray.shift()
|
|
60
|
+
if (asTex) {
|
|
61
|
+
output += `\\frac{ ${item.valueWithoutParentheses} }{ ${item2.valueWithoutParentheses} }`
|
|
62
|
+
} else {
|
|
63
|
+
output += `(${item.valueWithoutParentheses})/(${item2.valueWithoutParentheses})`
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
output += item.value
|
|
67
|
+
|
|
68
|
+
// Check if we need to add the multiplication sign.
|
|
69
|
+
if (outputArray.length > 0) {
|
|
70
|
+
if (item.number && outputArray[0].number) {
|
|
71
|
+
if(outputArray.length>1){
|
|
72
|
+
if(!outputArray[1].denominator){
|
|
73
|
+
output +=asTex ? " \\cdot " : "*"
|
|
74
|
+
}
|
|
75
|
+
}else{
|
|
76
|
+
output +=asTex ? " \\cdot " : "*"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
51
82
|
}
|
|
52
|
-
} else {
|
|
53
|
-
this.factors.unshift(new ExpFactorNumber(-1))
|
|
54
83
|
}
|
|
55
84
|
|
|
56
|
-
|
|
57
|
-
return this
|
|
85
|
+
return output
|
|
58
86
|
}
|
|
59
87
|
|
|
88
|
+
// opposed(): ExpressionMember {
|
|
89
|
+
// let firstMember = this.factors[0]
|
|
90
|
+
//
|
|
91
|
+
// if (firstMember === undefined) {
|
|
92
|
+
// return this
|
|
93
|
+
// }
|
|
94
|
+
//
|
|
95
|
+
// if (firstMember instanceof ExpFactorNumber) {
|
|
96
|
+
// if (firstMember.hasPower() || firstMember.hasRoot()) {
|
|
97
|
+
// this.factors.unshift(new ExpFactorNumber(-1))
|
|
98
|
+
// } else {
|
|
99
|
+
// firstMember.number = -firstMember.number
|
|
100
|
+
// }
|
|
101
|
+
// } else {
|
|
102
|
+
// this.factors.unshift(new ExpFactorNumber(-1))
|
|
103
|
+
// }
|
|
104
|
+
//
|
|
105
|
+
// return this
|
|
106
|
+
// }
|
|
107
|
+
|
|
60
108
|
add(value: ExpressionFactor): ExpressionMember {
|
|
61
109
|
this._factors.push(value)
|
|
62
110
|
return this
|
|
@@ -111,4 +159,75 @@ export class ExpressionMember {
|
|
|
111
159
|
|
|
112
160
|
return true
|
|
113
161
|
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Returns the "coefficient", ie a member with only numeric values factors.
|
|
165
|
+
*/
|
|
166
|
+
coefficient(): ExpressionMember {
|
|
167
|
+
let EM = new ExpressionMember()
|
|
168
|
+
|
|
169
|
+
for (let factor of this.factors) {
|
|
170
|
+
if (factor.isNumeric()) {
|
|
171
|
+
EM.add(factor)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return EM
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Returns a member with all factors containing a literal part.
|
|
179
|
+
*/
|
|
180
|
+
literal(): ExpressionMember {
|
|
181
|
+
let EM = new ExpressionMember()
|
|
182
|
+
|
|
183
|
+
for (let factor of this.factors) {
|
|
184
|
+
if (!factor.isNumeric()) {
|
|
185
|
+
EM.add(factor)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return EM
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
similarTo(member: ExpressionMember): boolean {
|
|
192
|
+
// TODO: identify two "similar" member, ie with the same literal parts.
|
|
193
|
+
return true
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
reduce(): ExpressionMember {
|
|
197
|
+
// Merge all ExpFactorNumbers that are number
|
|
198
|
+
let numerator = new ExpFactorNumber(1),
|
|
199
|
+
denominator = new ExpFactorNumber(1, -1),
|
|
200
|
+
literal: ExpressionFactor[] = []
|
|
201
|
+
|
|
202
|
+
for (let factor of this.factors) {
|
|
203
|
+
// Reduce the factor
|
|
204
|
+
factor.reduce()
|
|
205
|
+
|
|
206
|
+
if (factor instanceof ExpFactorNumber && factor.root === 1) {
|
|
207
|
+
if (factor.power > 0) {
|
|
208
|
+
numerator.number = numerator.number * (factor.number ** factor.power)
|
|
209
|
+
} else {
|
|
210
|
+
denominator.number = denominator.number * (factor.number ** (-factor.power))
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
literal.push(factor)
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
let EM = new ExpressionMember()
|
|
218
|
+
|
|
219
|
+
// There is a numerator
|
|
220
|
+
if(numerator.number!==1){
|
|
221
|
+
EM.addFactors(numerator)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// No denominator.
|
|
225
|
+
if(denominator.number!==1){
|
|
226
|
+
EM.addFactors(denominator)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Add the other factors
|
|
230
|
+
EM.addFactors(...literal)
|
|
231
|
+
return EM
|
|
232
|
+
}
|
|
114
233
|
}
|
|
@@ -25,6 +25,7 @@ export class ExpressionParser {
|
|
|
25
25
|
|
|
26
26
|
constructor(value: string) {
|
|
27
27
|
this._expression = this.parse(value)
|
|
28
|
+
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
get expression(): Expression {
|
|
@@ -92,26 +93,13 @@ export class ExpressionParser {
|
|
|
92
93
|
let a = stack.pop()
|
|
93
94
|
|
|
94
95
|
if (item.token === 'sqrt') {
|
|
95
|
-
|
|
96
|
-
// Transform the argument to expression
|
|
97
|
-
if(! (a instanceof Expression)){a = new Expression(a)}
|
|
98
|
-
stack.push(new ExpFactor(a, 1, 2))
|
|
96
|
+
stack.push(this.tokenOperationSqrt(a))
|
|
99
97
|
} else if (item.token === 'nthrt') {
|
|
100
|
-
|
|
101
|
-
let b = stack.pop()
|
|
102
|
-
// Transform the argument to expression
|
|
103
|
-
if(! (b instanceof Expression)){b = new Expression(b)}
|
|
104
|
-
// the "a" value is the nth root. It must be a number
|
|
105
|
-
let n = 2
|
|
106
|
-
if(a instanceof ExpFactorNumber){
|
|
107
|
-
n = a.number
|
|
108
|
-
}else{
|
|
109
|
-
throw "The nth root value must be a number, not " + a.tex
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
stack.push(new ExpFactor(b, 1, n))
|
|
98
|
+
stack.push(this.tokenOperationRoot(a, stack.pop()))
|
|
113
99
|
} else if (item.token in TRIGONOMETRIC) {
|
|
114
|
-
if(!
|
|
100
|
+
if (!(a instanceof Expression)) {
|
|
101
|
+
a = new Expression(a)
|
|
102
|
+
}
|
|
115
103
|
stack.push(new ExpFactorTrigo(item.token, a))
|
|
116
104
|
}
|
|
117
105
|
break
|
|
@@ -158,48 +146,56 @@ export class ExpressionParser {
|
|
|
158
146
|
}
|
|
159
147
|
|
|
160
148
|
private tokenOperationMultiply(a: Expression | ExpressionMember | ExpressionFactor, b: Expression | ExpressionMember | ExpressionFactor): ExpressionMember {
|
|
149
|
+
let EM = new ExpressionMember()
|
|
161
150
|
if (a instanceof Expression) {
|
|
162
|
-
|
|
151
|
+
EM.addFactors(new ExpFactor(a))
|
|
152
|
+
// a = new ExpFactor(a)
|
|
163
153
|
} else if (a instanceof ExpressionMember) {
|
|
164
|
-
a
|
|
154
|
+
// a.add()
|
|
155
|
+
EM.addFactors(...a.factors)
|
|
156
|
+
// a = new ExpFactor(new Expression(a))
|
|
165
157
|
} else if (a instanceof ExpressionFactor) {
|
|
166
158
|
// Do nothing
|
|
159
|
+
EM.addFactors(a)
|
|
167
160
|
}
|
|
168
161
|
|
|
169
162
|
if (b instanceof Expression) {
|
|
170
|
-
b = new ExpFactor(b)
|
|
163
|
+
// b = new ExpFactor(b)
|
|
164
|
+
EM.addFactors(new ExpFactor(b))
|
|
171
165
|
} else if (b instanceof ExpressionMember) {
|
|
172
|
-
b = new ExpFactor(new Expression(b))
|
|
166
|
+
// b = new ExpFactor(new Expression(b))
|
|
167
|
+
EM.addFactors(...b.factors)
|
|
173
168
|
} else if (b instanceof ExpressionFactor) {
|
|
174
169
|
// Do nothing
|
|
170
|
+
EM.addFactors(b)
|
|
175
171
|
}
|
|
176
172
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
return new ExpressionMember(a, b)
|
|
180
|
-
|
|
173
|
+
return EM
|
|
181
174
|
}
|
|
182
175
|
|
|
183
176
|
private tokenOperationDivide(a: Expression | ExpressionMember | ExpressionFactor, b: Expression | ExpressionMember | ExpressionFactor): ExpressionMember {
|
|
177
|
+
let EM = new ExpressionMember()
|
|
178
|
+
|
|
184
179
|
if (a instanceof Expression) {
|
|
185
|
-
|
|
180
|
+
EM.addFactors(new ExpFactor(a))
|
|
186
181
|
} else if (a instanceof ExpressionMember) {
|
|
187
|
-
|
|
182
|
+
EM.addFactors(...a.factors)
|
|
188
183
|
} else if (a instanceof ExpressionFactor) {
|
|
189
184
|
// Do nothing
|
|
185
|
+
EM.addFactors(a)
|
|
190
186
|
}
|
|
191
187
|
|
|
192
188
|
if (b instanceof Expression) {
|
|
193
|
-
|
|
189
|
+
EM.addFactors(new ExpFactor(b, -1))
|
|
194
190
|
} else if (b instanceof ExpressionMember) {
|
|
195
|
-
|
|
191
|
+
EM.addFactors(new ExpFactor(new Expression(b), -1))
|
|
196
192
|
} else if (b instanceof ExpressionFactor) {
|
|
197
193
|
// Do nothing
|
|
198
194
|
b.power = -b.power
|
|
195
|
+
EM.addFactors(b)
|
|
199
196
|
}
|
|
200
197
|
|
|
201
|
-
|
|
202
|
-
return new ExpressionMember(a, b)
|
|
198
|
+
return EM
|
|
203
199
|
}
|
|
204
200
|
|
|
205
201
|
private tokenOperationPower(a: Expression | ExpressionMember | ExpressionFactor, b: Expression | ExpressionMember | ExpressionFactor): ExpressionFactor {
|
|
@@ -209,7 +205,13 @@ export class ExpressionParser {
|
|
|
209
205
|
a = new Expression(a)
|
|
210
206
|
} else if (a instanceof ExpressionFactor) {
|
|
211
207
|
// Make a new factor of itself
|
|
212
|
-
|
|
208
|
+
console.log(a)
|
|
209
|
+
if (a.power === 1 && b instanceof ExpFactorNumber) {
|
|
210
|
+
a.power = b.value
|
|
211
|
+
return a
|
|
212
|
+
} else {
|
|
213
|
+
a = new Expression(new ExpressionMember(a))
|
|
214
|
+
}
|
|
213
215
|
}
|
|
214
216
|
|
|
215
217
|
// b can be :
|
|
@@ -246,4 +248,48 @@ export class ExpressionParser {
|
|
|
246
248
|
|
|
247
249
|
}
|
|
248
250
|
|
|
251
|
+
private tokenOperationSqrt(a: Expression | ExpressionMember | ExpressionFactor): Expression | ExpressionFactor {
|
|
252
|
+
|
|
253
|
+
// Transform the argument to expression
|
|
254
|
+
if (a instanceof Expression) {
|
|
255
|
+
return new ExpFactor(a, 1, 2)
|
|
256
|
+
} else if (a instanceof ExpressionMember) {
|
|
257
|
+
if (a.factors.length === 1 && !a.factors[0].hasPower()) {
|
|
258
|
+
a.factors[0].root = 2
|
|
259
|
+
return a.factors[0]
|
|
260
|
+
} else {
|
|
261
|
+
return new ExpFactor(new Expression(a), 1, 2)
|
|
262
|
+
}
|
|
263
|
+
} else if (a instanceof ExpressionFactor) {
|
|
264
|
+
if (!a.hasPower()) {
|
|
265
|
+
a.root = 2
|
|
266
|
+
return a
|
|
267
|
+
} else {
|
|
268
|
+
return new ExpFactor(new Expression(a), 1, 2)
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// Fallback
|
|
272
|
+
return a
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
private tokenOperationRoot(a:Expression | ExpressionMember | ExpressionFactor, b:Expression | ExpressionMember | ExpressionFactor): ExpFactor {
|
|
276
|
+
// a is the power
|
|
277
|
+
// b is the argument
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
// Transform the argument to expression
|
|
282
|
+
if (!(b instanceof Expression)) {
|
|
283
|
+
b = new Expression(b)
|
|
284
|
+
}
|
|
285
|
+
// the "a" value is the nth root. It must be a number
|
|
286
|
+
let n = 2
|
|
287
|
+
if (a instanceof ExpFactorNumber) {
|
|
288
|
+
n = a.number
|
|
289
|
+
} else {
|
|
290
|
+
throw "The nth root value must be a number, not " + a.tex
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return new ExpFactor(b, 1, n)
|
|
294
|
+
}
|
|
249
295
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {Expression} from "../internals";
|
|
2
|
-
import {ExpressionFactor} from "../internals";
|
|
1
|
+
import {Expression, ExpressionFactor} from "../internals";
|
|
3
2
|
|
|
4
3
|
|
|
5
4
|
export class ExpFactor extends ExpressionFactor {
|
|
@@ -13,14 +12,28 @@ export class ExpFactor extends ExpressionFactor {
|
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
makeTeX(numberOfFactors?: number, position?: number): string {
|
|
16
|
-
// If there is a root value, no need to make further checks
|
|
17
15
|
// TODO: no need to wrap if it's single ?
|
|
18
|
-
if(this.hasRoot() || this.hasPower()){
|
|
16
|
+
if (this.hasRoot() || this.hasPower()) {
|
|
19
17
|
return this.texPower(this.texRoot(
|
|
20
|
-
this.
|
|
18
|
+
this.argument.tex
|
|
19
|
+
// this.wrapWithParentheses(this.argument.tex)
|
|
21
20
|
))
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
if (numberOfFactors === 1) {
|
|
24
|
+
return this.argument.tex
|
|
25
|
+
} else {
|
|
26
|
+
return this.argument.isFactor() ? this.argument.tex : this.wrapWithParentheses(this.argument.tex)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
makeDisplay(numberOfFactors?: number, position?: number): string {
|
|
31
|
+
if (this.hasRoot() || this.hasPower()) {
|
|
32
|
+
return this.displayPower(this.texRoot(
|
|
33
|
+
this.wrapWithParentheses(this.argument.display, false)
|
|
34
|
+
))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return this.argument.isFactor() ? this.argument.display : this.wrapWithParentheses(this.argument.display)
|
|
25
38
|
}
|
|
26
39
|
}
|
|
@@ -16,4 +16,11 @@ export class ExpFactorExponential extends ExpressionFactor {
|
|
|
16
16
|
|
|
17
17
|
return this.texPowerAndRoot(tex)
|
|
18
18
|
}
|
|
19
|
+
|
|
20
|
+
makeDisplay(numberOfFactors?: number, position?: number): string {
|
|
21
|
+
let display: string = `e^( ${ this.argument.tex } )`
|
|
22
|
+
|
|
23
|
+
return this.displayPowerAndRoot(display)
|
|
24
|
+
}
|
|
25
|
+
|
|
19
26
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {Expression} from "../internals";
|
|
2
|
-
import {ExpressionFactor} from "../internals";
|
|
1
|
+
import {Expression, ExpressionFactor} from "../internals";
|
|
3
2
|
|
|
4
3
|
export class ExpFactorNumber extends ExpressionFactor {
|
|
5
4
|
private _number: number
|
|
5
|
+
|
|
6
6
|
constructor(value: number, power?: number, root?: number) {
|
|
7
7
|
super(null, power, root);
|
|
8
8
|
|
|
@@ -13,8 +13,8 @@ export class ExpFactorNumber extends ExpressionFactor {
|
|
|
13
13
|
this._number = value
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
get value():number {
|
|
17
|
-
return Math.pow(this._number, this.root/this.root)
|
|
16
|
+
get value(): number {
|
|
17
|
+
return Math.pow(this._number, this.root / this.root)
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
get number(): number {
|
|
@@ -30,6 +30,10 @@ export class ExpFactorNumber extends ExpressionFactor {
|
|
|
30
30
|
return this.texPower(this.texRoot(this._number.toString()))
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
makeDisplay(numberOfFactors?: number, position?: number): string {
|
|
34
|
+
return this.displayPower(this.displayRoot(this._number.toString()))
|
|
35
|
+
}
|
|
36
|
+
|
|
33
37
|
derivative(variable: string): Expression {
|
|
34
38
|
return undefined;
|
|
35
39
|
}
|
|
@@ -41,4 +45,28 @@ export class ExpFactorNumber extends ExpressionFactor {
|
|
|
41
45
|
hasVariable(variable?: string): boolean {
|
|
42
46
|
return false
|
|
43
47
|
}
|
|
48
|
+
|
|
49
|
+
reduce(): ExpressionFactor {
|
|
50
|
+
// Reduce the power / root value
|
|
51
|
+
super.reduce()
|
|
52
|
+
|
|
53
|
+
if (this.power > 1) {
|
|
54
|
+
this.number = this.number ** this.power
|
|
55
|
+
this.power = 1
|
|
56
|
+
}
|
|
57
|
+
if (this.power < -1) {
|
|
58
|
+
this.number = this.number ** (-this.power)
|
|
59
|
+
this.power = -1
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if(this.root>1){
|
|
63
|
+
// Maybe it's a perfect root ?
|
|
64
|
+
if(Number.isSafeInteger(Math.pow(this.number, 1/this.root))){
|
|
65
|
+
this.number = Math.pow(this.number, 1/this.root)
|
|
66
|
+
this.root = 1
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return this
|
|
71
|
+
}
|
|
44
72
|
}
|
|
@@ -2,11 +2,19 @@ import {Expression} from "../internals";
|
|
|
2
2
|
import {ExpressionFactor} from "../internals";
|
|
3
3
|
|
|
4
4
|
export class ExpFactorPower extends ExpressionFactor {
|
|
5
|
-
|
|
5
|
+
get powerArgument(): Expression {
|
|
6
|
+
return this._powerArgument;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
set powerArgument(value: Expression) {
|
|
10
|
+
this._powerArgument = value;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
private _powerArgument: Expression
|
|
6
14
|
constructor(radical: Expression, power: Expression, power2?: number, root?:number) {
|
|
7
15
|
super(radical, power2, root);
|
|
8
16
|
|
|
9
|
-
this.
|
|
17
|
+
this._powerArgument = power
|
|
10
18
|
}
|
|
11
19
|
derivative(variable: string): Expression {
|
|
12
20
|
return undefined
|
|
@@ -17,8 +25,18 @@ private powerArgument: Expression
|
|
|
17
25
|
}
|
|
18
26
|
|
|
19
27
|
makeTeX(): string {
|
|
20
|
-
let tex: string = `{ ${ this.argument.tex } }^{ ${this.
|
|
28
|
+
let tex: string = `{ ${ this.argument.tex } }^{ ${this._powerArgument.tex } }`
|
|
21
29
|
|
|
22
30
|
return this.texPowerAndRoot(this.wrapWithParentheses(tex))
|
|
23
31
|
}
|
|
32
|
+
|
|
33
|
+
getArguments(): Expression[] {
|
|
34
|
+
return [this.argument, this.powerArgument]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
makeDisplay(numberOfFactors?: number, position?: number): string {
|
|
38
|
+
let display: string = `( ${ this.argument.display } )^( ${this._powerArgument.display } )`
|
|
39
|
+
|
|
40
|
+
return this.displayPowerAndRoot(this.wrapWithParentheses(display, false))
|
|
41
|
+
}
|
|
24
42
|
}
|
|
@@ -12,7 +12,6 @@ export enum TRIGONOMETRIC {
|
|
|
12
12
|
acot='acot'
|
|
13
13
|
}
|
|
14
14
|
export class ExpFactorTrigo extends ExpressionFactor {
|
|
15
|
-
|
|
16
15
|
private _trigo: string
|
|
17
16
|
constructor(trigo: string, argument: Expression, power?: number, root?: number) {
|
|
18
17
|
|
|
@@ -41,4 +40,14 @@ export class ExpFactorTrigo extends ExpressionFactor {
|
|
|
41
40
|
tex+= `\\left( ${this.argument.tex} \\right)`
|
|
42
41
|
return this.texRoot(tex);
|
|
43
42
|
}
|
|
43
|
+
|
|
44
|
+
makeDisplay(numberOfFactors?: number, position?: number): string {
|
|
45
|
+
let display = `${this._trigo}`
|
|
46
|
+
if(this.root>1){
|
|
47
|
+
display += `^( ${this.root} )`
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
display+= `( ${this.argument.display} )`
|
|
51
|
+
return this.displayRoot(display);
|
|
52
|
+
}
|
|
44
53
|
}
|
|
@@ -26,6 +26,11 @@ export class ExpFactorVariable extends ExpressionFactor {
|
|
|
26
26
|
return this.texPower(this.texRoot(this._variable))
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
makeDisplay(numberOfFactors?: number, position?: number): string {
|
|
30
|
+
return this.displayPower(this.displayRoot(this._variable))
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
29
34
|
derivative(variable: string): Expression {
|
|
30
35
|
return undefined;
|
|
31
36
|
}
|