pimath 0.2.3 → 0.2.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pimath",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "A math library for teacher :)",
5
5
  "type": "module",
6
6
  "main": "dist/pimath.js",
@@ -303,7 +303,7 @@ export class Equation implements
303
303
 
304
304
  // -----------------------------------------------
305
305
  public letters = (): string[] => {
306
- return [...new Set([...this.#left.letters(), ...this.#right.letters()])]
306
+ return [...new Set([...this.#left.variables, ...this.#right.variables])]
307
307
  }
308
308
 
309
309
  // -----------------------------------------------
@@ -89,36 +89,7 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
89
89
  * Get the tex output of the monom
90
90
  */
91
91
  public get tex(): string {
92
- let L = ''
93
- const letters = Object.keys(this.#literal).sort()
94
-
95
- for (const letter of letters) {
96
- if (this.#literal[letter].isNotZero()) {
97
- L += letter
98
- if (this.#literal[letter].isNotEqual(1)) {
99
- L += `^{ ${this.#literal[letter].tfrac.tex} }`
100
- }
101
- }
102
- }
103
-
104
- if (L === '') {
105
- // No setLetter - means it's only a number !
106
- if (this.#coefficient.value != 0) {
107
- return this.#coefficient.frac.tex
108
- } else {
109
- return '0'
110
- }
111
- } else {
112
- if (this.#coefficient.value === 1) {
113
- return L
114
- } else if (this.#coefficient.value === -1) {
115
- return `-${L}`
116
- } else if (this.#coefficient.value === 0) {
117
- return '0'
118
- } else {
119
- return `${this.#coefficient.frac.tex}${L}`
120
- }
121
- }
92
+ return this.#format('tex')
122
93
  }
123
94
 
124
95
  // Display getter
@@ -126,35 +97,7 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
126
97
  * This display getter is to be used in the polynom display getter
127
98
  */
128
99
  public get display(): string {
129
- let L = ''
130
- const letters = Object.keys(this.#literal).sort()
131
- for (const letter of letters) {
132
- if (this.#literal[letter].isNotZero()) {
133
- L += letter
134
- if (this.#literal[letter].isNotEqual(1)) {
135
- L += `^(${this.#literal[letter].display})`
136
- }
137
- }
138
- }
139
-
140
- if (L === '') {
141
- // No setLetter - means it's only a number !
142
- if (this.#coefficient.value != 0) {
143
- return this.#coefficient.display
144
- } else {
145
- return ''
146
- }
147
- } else {
148
- if (this.#coefficient.value === 1) {
149
- return L
150
- } else if (this.#coefficient.value === -1) {
151
- return `-${L}`
152
- } else if (this.#coefficient.value === 0) {
153
- return '0'
154
- } else {
155
- return `${this.#coefficient.display}${L}`
156
- }
157
- }
100
+ return this.#format('display')
158
101
  }
159
102
 
160
103
  public static gcd = (...monoms: Monom[]): Monom => {
@@ -177,7 +120,7 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
177
120
  // Remove the inexistant letters from the resulting monom
178
121
  for (const letter in M.literal) {
179
122
  if (!(letter in m.literal)) {
180
- M.literal[letter].zero()
123
+ M.removeVariable(letter)
181
124
  }
182
125
  }
183
126
  for (const letter in m.literal) {
@@ -222,7 +165,7 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
222
165
 
223
166
  this.#coefficient.add(mAsMonom.coefficient)
224
167
  } else {
225
- console.log('Add monom: ' + this.display + ' is not similar with ', mAsMonom.display)
168
+ throw new Error('Add monom: ' + this.display + ' is not similar with ' + mAsMonom.display)
226
169
  }
227
170
  }
228
171
  return this
@@ -338,7 +281,7 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
338
281
  let literals: literalType<Fraction>[] = []
339
282
  for (const L in this.literal) {
340
283
  // L is the letter.
341
- literals = this._getLiteralDividers(literals, L)
284
+ literals = this.#getLiteralDividers(literals, L)
342
285
  }
343
286
 
344
287
  const monomDividers: Monom[] = []
@@ -437,12 +380,12 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
437
380
  public integrate(a: InputValue<Fraction>, b: InputValue<Fraction>, letter?: string): Fraction {
438
381
  const primitive = this.primitive(letter)
439
382
 
440
- return (primitive.evaluate(b) as Fraction)
441
- .subtract(primitive.evaluate(a) as Fraction)
383
+ return (primitive.evaluate(b, false) as Fraction)
384
+ .subtract(primitive.evaluate(a, false) as Fraction)
442
385
  }
443
386
 
444
387
  public inverse = (): this => {
445
- this.#coefficient.opposite()
388
+ this.#coefficient.inverse()
446
389
  for (const letter in this.#literal) {
447
390
  this.#literal[letter].opposite()
448
391
  }
@@ -482,8 +425,8 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
482
425
  return false
483
426
  }
484
427
 
485
- // The natural power must be be even
486
- if (this.literal[letter].isEven()) {
428
+ // The natural power must be even - if it's odd, the monom is not a square.
429
+ if (this.literal[letter].isOdd()) {
487
430
  return false
488
431
  }
489
432
  }
@@ -645,37 +588,7 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
645
588
  }
646
589
 
647
590
  public get plotFunction(): string {
648
- let L = ''
649
- const letters = Object.keys(this.#literal).sort()
650
-
651
- for (const letter of letters) {
652
- if (this.#literal[letter].isNotZero()) {
653
- L += (L === '' ? "" : "*") + letter
654
- if (this.#literal[letter].isNotEqual(1)) {
655
- L += `^(${this.#literal[letter].display})`
656
- }
657
- }
658
- }
659
-
660
- // No literal part
661
- if (L === '') {
662
- // No setLetter - means it's only a number !
663
- if (this.#coefficient.value != 0) {
664
- return this.#coefficient.display
665
- } else {
666
- return ''
667
- }
668
- } else {
669
- if (this.#coefficient.value === 1) {
670
- return L
671
- } else if (this.#coefficient.value === -1) {
672
- return `-${L}`
673
- } else if (this.#coefficient.value === 0) {
674
- return '0'
675
- } else {
676
- return `${this.#coefficient.display}*${L}`
677
- }
678
- }
591
+ return this.#format('plot')
679
592
  }
680
593
 
681
594
  /**
@@ -733,8 +646,10 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
733
646
 
734
647
  /**
735
648
  * Get the nth-root of the monom
649
+ * @todo Not yet implemented
736
650
  */
737
651
  public root = (): this => {
652
+ // TODO: implement nth-root for monoms
738
653
  throw new Error('Method not implemented.')
739
654
  }
740
655
 
@@ -751,6 +666,7 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
751
666
  // Set the power of the letter to zero => remove it
752
667
  if (this.hasVariable(letter) && pow.isZero()) {
753
668
  this.removeVariable(letter)
669
+ return this
754
670
  }
755
671
 
756
672
 
@@ -766,10 +682,11 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
766
682
  if (this.isSquare()) {
767
683
  this.#coefficient.sqrt()
768
684
  for (const letter in this.#literal) {
769
- this.#literal[letter].clone().divide(2)
685
+ this.#literal[letter].divide(2)
770
686
  }
771
687
  }
772
688
 
689
+ // TODO: throw an error if the monom is not a square ? Or allow the result to be a monom with rational powers ?
773
690
  return this
774
691
  }
775
692
 
@@ -789,7 +706,7 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
789
706
 
790
707
  this.#coefficient.add(mAsMonom.clone().coefficient.opposite())
791
708
  } else {
792
- console.log('Subtract: Is not similar: ', mAsMonom.display)
709
+ throw new Error('Subtract: Is not similar: ' + mAsMonom.display)
793
710
  }
794
711
  }
795
712
  return this
@@ -865,39 +782,58 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
865
782
  return r
866
783
  }
867
784
 
868
- #shutingYardToReducedMonom = (inputStr: string): this => {
869
- // Get the RPN array of the current expression
870
- const SY: ShutingYard = new ShutingYard().parse(inputStr)
871
- const rpn: { token: string, tokenType: ShutingyardType }[] = SY.rpn
785
+ #format = (type: 'tex' | 'display' | 'plot'): string => {
786
+ let L = ''
787
+ const letters = Object.keys(this.#literal).sort()
872
788
 
873
- const stack: Monom[] = []
789
+ for (const letter of letters) {
790
+ if (this.#literal[letter].isNotZero()) {
791
+ if (type === 'plot' && L !== '') { L += '*' }
792
+ L += letter
793
+ if (this.#literal[letter].isNotEqual(1)) {
794
+ L += type === 'tex'
795
+ ? `^{ ${this.#literal[letter].tfrac.tex} }`
796
+ : `^(${this.#literal[letter].display})`
797
+ }
798
+ }
799
+ }
874
800
 
875
- if (rpn.length === 0) {
876
- this.zero()
877
- return this
878
- } else if (rpn.length === 1) {
879
- const element = rpn[0]
801
+ const coeffStr = type === 'tex' ? this.#coefficient.frac.tex : this.#coefficient.display
880
802
 
881
- this.one()
882
- if (element.tokenType === ShutingyardType.COEFFICIENT) {
883
- this.coefficient = new Fraction(element.token)
884
- } else if (element.tokenType === ShutingyardType.VARIABLE) {
885
- this.setLetter(element.token, 1)
886
- }
887
- return this
888
- } else {
889
- // Reset the monom
890
- for (const element of rpn) {
891
- this.#shutingYard_AddToken(stack, element)
892
- }
803
+ if (L === '') {
804
+ return this.#coefficient.value !== 0 ? coeffStr : '0'
893
805
  }
894
806
 
895
- this.one()
896
- this.multiply(stack[0])
897
- return this
807
+ if (this.#coefficient.value === 1) { return L }
808
+ if (this.#coefficient.value === -1) { return `-${L}` }
809
+ if (this.#coefficient.value === 0) { return '0' }
810
+ return type === 'plot' ? `${coeffStr}*${L}` : `${coeffStr}${L}`
811
+ }
812
+
813
+ #getLiteralDividers(arr: literalType<Fraction>[], letter: string): literalType<Fraction>[] {
814
+ const tmpList: Record<string, Fraction>[] = []
815
+
816
+ // Be default, this.literal[letter] should be a rational number.
817
+ for (let d = 0; d <= this.literal[letter].value; d++) {
818
+ if (arr.length === 0) {
819
+ const litt: literalType<Fraction> = {}
820
+ litt[letter] = new Fraction(d)
821
+ tmpList.push(litt)
822
+ } else {
823
+ for (const item of arr) {
824
+ const litt: literalType<Fraction> = {}
825
+ for (const currentLetter in item) {
826
+ litt[currentLetter] = item[currentLetter]
827
+ }
828
+ litt[letter] = new Fraction(d)
829
+ tmpList.push(litt)
830
+ }
831
+ }
832
+ }
833
+ return tmpList
898
834
  }
899
835
 
900
- #shutingYard_AddToken = (stack: Monom[], element: Token): void => {
836
+ #shutingYardAddToken = (stack: Monom[], element: Token): void => {
901
837
  let q1: Monom, q2: Monom, m: Monom, letter: string, pow: Fraction
902
838
 
903
839
  if (element.tokenType === ShutingyardType.COEFFICIENT) {
@@ -952,26 +888,35 @@ export class Monom implements IPiMathObject<Monom>, IExpression<Monom>, IAnalyse
952
888
  }
953
889
  }
954
890
 
955
- private _getLiteralDividers(arr: literalType<Fraction>[], letter: string): literalType<Fraction>[] {
956
- const tmpList: Record<string, Fraction>[] = []
891
+ #shutingYardToReducedMonom = (inputStr: string): this => {
892
+ // Get the RPN array of the current expression
893
+ const SY: ShutingYard = new ShutingYard().parse(inputStr)
894
+ const rpn: { token: string, tokenType: ShutingyardType }[] = SY.rpn
957
895
 
958
- // Be default, this.literal[letter] should be a rational number.
959
- for (let d = 0; d <= this.literal[letter].value; d++) {
960
- if (arr.length === 0) {
961
- const litt: literalType<Fraction> = {}
962
- litt[letter] = new Fraction(d)
963
- tmpList.push(litt)
964
- } else {
965
- for (const item of arr) {
966
- const litt: literalType<Fraction> = {}
967
- for (const currentLetter in item) {
968
- litt[currentLetter] = item[currentLetter]
969
- }
970
- litt[letter] = new Fraction(d)
971
- tmpList.push(litt)
972
- }
896
+ const stack: Monom[] = []
897
+
898
+ if (rpn.length === 0) {
899
+ this.zero()
900
+ return this
901
+ } else if (rpn.length === 1) {
902
+ const element = rpn[0]
903
+
904
+ this.one()
905
+ if (element.tokenType === ShutingyardType.COEFFICIENT) {
906
+ this.coefficient = new Fraction(element.token)
907
+ } else if (element.tokenType === ShutingyardType.VARIABLE) {
908
+ this.setLetter(element.token, 1)
909
+ }
910
+ return this
911
+ } else {
912
+ // Reset the monom
913
+ for (const element of rpn) {
914
+ this.#shutingYardAddToken(stack, element)
973
915
  }
974
916
  }
975
- return tmpList
917
+
918
+ this.one()
919
+ this.multiply(stack[0])
920
+ return this
976
921
  }
977
922
  }