pimath 0.0.108 → 0.0.110

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 CHANGED
@@ -132,17 +132,18 @@ class Equation {
132
132
  // and all zero degree monoms to the right.
133
133
  this._left.subtract(this._right);
134
134
  this._right.zero();
135
- if (allLeft) {
136
- return this.moveLeft();
137
- }
138
- let mMove;
139
- for (let m of this._left.monoms) {
140
- if (m.degree().isZero()) {
141
- mMove = m.clone();
142
- this._left.subtract(mMove);
143
- this._right.subtract(mMove);
144
- }
145
- }
135
+ this._left.reorder();
136
+ // we eant all left (so equal zero) : it's done !
137
+ if (allLeft)
138
+ return this;
139
+ // Fetch all zero degree monoms.
140
+ this._left.monoms
141
+ .filter(m => m.degree().isZero())
142
+ .forEach(m => {
143
+ const move = m.clone();
144
+ this._left.subtract(move);
145
+ this._right.subtract(move);
146
+ });
146
147
  // Reorder the left and right polynoms
147
148
  this._left.reorder();
148
149
  this._right.reorder();
@@ -854,141 +855,120 @@ exports.Equation = Equation;
854
855
  Object.defineProperty(exports, "__esModule", ({ value: true }));
855
856
  exports.LinearSystem = void 0;
856
857
  const equation_1 = __webpack_require__(760);
857
- const polynom_1 = __webpack_require__(38);
858
- const random_1 = __webpack_require__(330);
859
858
  const fraction_1 = __webpack_require__(506);
859
+ const polynom_1 = __webpack_require__(38);
860
860
  // TODO: Must check and rework
861
861
  class LinearSystem {
862
862
  constructor(...equationStrings) {
863
+ this.buildTex = (equations, operators) => {
864
+ let equStr, equArray = [], m, letters = [];
865
+ // Get the letters from the linear system
866
+ for (let equ of equations) {
867
+ letters = letters.concat(equ.letters());
868
+ }
869
+ letters = [...new Set(letters)];
870
+ letters.sort();
871
+ for (let i = 0; i < equations.length; i++) {
872
+ let equ = equations[i];
873
+ equStr = [];
874
+ for (let L of letters) {
875
+ m = equ.left.monomByLetter(L);
876
+ if (equStr.length === 0) {
877
+ equStr.push(m.isZero() ? '' : m.tex);
878
+ }
879
+ else {
880
+ equStr.push(m.isZero() ? '' : ((m.coefficient.sign() === 1) ? '+' : '') + m.tex);
881
+ }
882
+ }
883
+ // Add the equal sign
884
+ equStr.push('=');
885
+ // Add the right hand part of the equation (should be only a number, because it has been reordered)
886
+ equStr.push(equ.right.tex);
887
+ // Add the operations if existing
888
+ if (operators !== undefined && operators[i] !== undefined) {
889
+ // add extra space at the end of the equation
890
+ equStr[equStr.length - 1] = equStr[equStr.length - 1] + ' \\phantom{\\quad}';
891
+ for (let o of operators[i]) {
892
+ equStr.push(`\\ \\cdot\\ ${o.startsWith('-') ? "\\left(" + o + "\\right)" : o}`);
893
+ }
894
+ }
895
+ // Add to the list.
896
+ equArray.push(equStr.join('&'));
897
+ }
898
+ let operatorsColumns = 0;
899
+ if (operators !== undefined && operators.length > 0) {
900
+ operatorsColumns = operators[0].length;
901
+ }
902
+ return `\\left\\{\\begin{array}{${"r".repeat(letters.length)}cl ${"|l".repeat(operatorsColumns)}}${equArray.join('\\\\\ ')}\\end{array}\\right.`;
903
+ };
904
+ this.stepTex = (letter) => {
905
+ const steps = this._resolutionSteps[letter];
906
+ if (steps === undefined) {
907
+ return '';
908
+ }
909
+ // steps = { equations[], operations: [[],[]]
910
+ let tex = [];
911
+ for (let i = 0; i < steps.length; i++) {
912
+ tex.push(this.buildTex(steps[i].equations, steps[i].operations));
913
+ }
914
+ return `\\begin{aligned}&${tex.join('\\\\&')}\\end{aligned}`;
915
+ };
863
916
  // ------------------------------------------
864
917
  // Creation / parsing functions
865
918
  // ------------------------------------------
866
919
  this.parse = (...equations) => {
920
+ // make the original equations
867
921
  this._equations = equations.map(value => new equation_1.Equation(value));
922
+ // get the letters.
868
923
  this._findLetters();
869
924
  return this;
870
925
  };
871
- this.setCoefficient = (...coefficients) => {
872
- // Reset the equations list
873
- this._equations = [];
874
- let i = 0;
875
- while (i < coefficients.length - this._letters.length) {
876
- let left = new polynom_1.Polynom().parse(this._letters.join(''), ...coefficients.slice(i, i + this._letters.length)), right = new polynom_1.Polynom(coefficients[i + this._letters.length].toString()), equ = new equation_1.Equation().create(left, right);
877
- this._equations.push(equ.clone());
878
- i = i + this._letters.length + 1;
879
- }
880
- return this;
881
- };
882
926
  this.clone = () => {
883
927
  return new LinearSystem().parse(...this._equations.map(equ => equ.clone()));
884
928
  };
885
- this.setLetters = (...letters) => {
886
- this._letters = letters;
887
- return this;
888
- };
889
- this._findLetters = () => {
890
- // Find all letters used.
891
- let variables = new Set();
892
- for (let equ of this._equations) {
893
- variables = new Set([...variables, ...equ.variables]);
929
+ // ------------------------------------------
930
+ this.reorder = () => {
931
+ for (let E of this._equations) {
932
+ E.reorder();
894
933
  }
895
- // TODO: How to transform (Set of string) to string[]
896
- // @ts-ignore
897
- this._letters = [...variables];
898
934
  return this;
899
935
  };
900
936
  // -----------------------------------------------
901
- // Equations generators and randomizers
902
- // -----------------------------------------------
903
- this.generate = (...solutions) => {
904
- let solutionsF = [];
905
- // Convert the numbers to fractions if necessary
906
- for (let s of solutions) {
907
- if (typeof s === "number") {
908
- solutionsF.push(new fraction_1.Fraction(s.toString()));
909
- }
910
- else {
911
- solutionsF.push(s.clone());
912
- }
937
+ // Equations solving algorithms
938
+ this.solve = (withResolution) => {
939
+ // Solve it by linear
940
+ this._solutions = {};
941
+ this._resolutionSteps = {};
942
+ // Reorder all equations.
943
+ this.reorder();
944
+ if (withResolution === undefined) {
945
+ withResolution = false;
913
946
  }
914
- // Create the equations and make sure they are not linear combined.
915
- this._equations = [];
916
- for (let i = 0; i < solutions.length; i++) {
917
- this._equations.push(this._generateOneEquation(...solutionsF));
947
+ for (let letter of this.variables) {
948
+ this._solutions[letter] = this._solveOneLetter(letter, withResolution);
918
949
  }
950
+ // TODO: LinearSystem - solve: optimization and handle undetermined and undefined systems.
919
951
  return this;
920
952
  };
921
- this._generateOneEquation = (...solutions) => {
922
- let coeff = [], leftValue = new fraction_1.Fraction().zero(), letters = ['x', 'y', 'z', 't', 'u', 'v', 'w', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'], equString = '', equ;
923
- for (let i = 0; i < solutions.length; i++) {
924
- coeff.push(random_1.Random.numberSym(5));
925
- leftValue.add(solutions[i].clone().multiply(coeff[i]));
926
- equString += `${(coeff[i] < 0) ? coeff[i] : '+' + coeff[i]}${letters[i]}`;
927
- }
928
- // LeftValue contains the left part oof the equation - and is then the isSame as the right part.
929
- // It might be a Fraction.
930
- // Must check if it's not a linear combination
931
- equ = new equation_1.Equation(`${equString}=${leftValue.display}`);
932
- if (equ.right.monoms[0].coefficient.denominator != 1) {
933
- equ.multiply(new fraction_1.Fraction(equ.right.monoms[0].coefficient.denominator, 1));
934
- }
935
- if (this._checkIfLinerCombination(equ)) {
936
- return equ;
937
- }
938
- else {
939
- return this._generateOneEquation(...solutions);
940
- }
941
- };
942
953
  this.mergeEquations = (eq1, eq2, factor1, factor2) => {
943
954
  // Set and clone the equations.
944
955
  let eq1multiplied = eq1.clone().multiply(new fraction_1.Fraction(factor1)), eq2multiplied = eq2.clone().multiply(new fraction_1.Fraction(factor2));
945
- // @ts-ignore
946
- console.log(eq1.tex, eq1multiplied.tex, factor1.tex);
947
- // @ts-ignore
948
- console.log(eq2.tex, eq2multiplied.tex, factor2.tex);
949
956
  // Add both equations together.
950
957
  eq1multiplied.left.add(eq2multiplied.left);
951
958
  eq1multiplied.right.add(eq2multiplied.right);
952
- console.log('resulting reduction', eq1multiplied.tex);
953
959
  return eq1multiplied;
954
960
  };
955
- // ------------------------------------------
956
- // Solvers algorithm
957
- // ------------------------------------------
958
- this.reorder = () => {
959
- for (let E of this._equations) {
960
- E.reorder();
961
- }
962
- return this;
963
- };
964
- this.solve = () => {
965
- // Solve it by linear
966
- this._solutions = {};
967
- this._resolutionSteps = [];
968
- // Reorder all equations.
969
- this.reorder();
970
- // Get all variables in the linear system
971
- let V = this.variables.sort();
972
- for (let letter of V) {
973
- console.log('SOLVING FOR', letter);
974
- this._solutions[letter] = this._solveOneLetter(letter, V);
961
+ this._findLetters = () => {
962
+ // Find all letters used.
963
+ let variables = new Set();
964
+ for (let equ of this._equations) {
965
+ variables = new Set([...variables, ...equ.variables]);
975
966
  }
976
- // TODO: LinearSystem - solve: optimization and handle undetermined and undefined systems.
967
+ this._letters = [...variables];
968
+ this._letters.sort();
977
969
  return this;
978
970
  };
979
- this._checkIfLinerCombination = (equ) => {
980
- return true;
981
- };
982
- // ------------------------------------------
983
- // Helpers
984
- // ------------------------------------------
985
- this.log = () => {
986
- let str = '';
987
- for (let E of this._equations) {
988
- str += `${E.tex}\\n}`;
989
- }
990
- return str;
991
- };
971
+ // TODO: allow construction to accept an array of values (like a matrix) to build the equations
992
972
  this._equations = [];
993
973
  this._letters = 'xyz'.split('');
994
974
  if (equationStrings !== undefined && equationStrings.length > 0) {
@@ -1021,38 +1001,15 @@ class LinearSystem {
1021
1001
  return true;
1022
1002
  }
1023
1003
  get variables() {
1024
- let V = [];
1025
- for (let E of this._equations) {
1026
- V = V.concat(E.variables);
1027
- }
1028
- return [...new Set(V)].sort();
1004
+ return this._letters;
1029
1005
  }
1030
1006
  get tex() {
1031
1007
  // Build the array of values.
1032
1008
  // Reorder
1033
1009
  // This clone the system :!!!
1034
1010
  //TODO: Avoid cloning this linear system
1035
- let LS = this.clone().reorder(), letters = LS.variables, equStr, equArray = [], m;
1036
- // TODO: Manage tex output of linear equations
1037
- for (let equ of LS.equations) {
1038
- equStr = [];
1039
- for (let L of letters) {
1040
- m = equ.left.monomByLetter(L);
1041
- if (equStr.length === 0) {
1042
- equStr.push(m.isZero() ? '' : m.tex);
1043
- }
1044
- else {
1045
- equStr.push(m.isZero() ? '' : ((m.coefficient.sign() === 1) ? '+' : '') + m.tex);
1046
- }
1047
- }
1048
- // Add the equal sign
1049
- equStr.push('=');
1050
- // Add the right hand part of the equation (should be only a number, because it has been reordered)
1051
- equStr.push(equ.right.tex);
1052
- // Add to the list.
1053
- equArray.push(equStr.join('&'));
1054
- }
1055
- return `\\left\\{\\begin{array}{${"r".repeat(letters.length)}cl}${equArray.join('\\\\\ ')}\\end{array}\\right.`;
1011
+ let LS = this.clone().reorder(), letters = LS.variables;
1012
+ return this.buildTex(LS.equations);
1056
1013
  }
1057
1014
  get solution() {
1058
1015
  let tex = [];
@@ -1060,67 +1017,91 @@ class LinearSystem {
1060
1017
  this.solve();
1061
1018
  }
1062
1019
  for (let letter in this._solutions) {
1063
- if (this._solutions[letter].isReal) {
1064
- console.log(`Undetermined (letter ${letter})`);
1065
- return;
1020
+ if (this._solutions[letter].display === "RR") {
1021
+ return `\\left\\{ \\left(${this._letters.join(';')}\\right) \\big\\vert ${this.equations[0].tex} \\right\\}`;
1066
1022
  }
1067
- if (this._solutions[letter].isVarnothing) {
1068
- console.log(`Undefined (letter ${letter})`);
1069
- return;
1023
+ if (this._solutions[letter].display === "O/") {
1024
+ return `\\varnothing`;
1070
1025
  }
1071
- tex.push(this._solutions[letter].value.tex);
1026
+ tex.push(this._solutions[letter].tex);
1072
1027
  }
1073
1028
  return `\\left(${tex.join(';')}\\right)`;
1074
1029
  }
1075
- // ------------------------------------------
1076
- // Mathematical operations
1077
- // ------------------------------------------
1078
1030
  _linearReduction(eq1, eq2, letter) {
1079
- // TODO: handle other signs for equations ?
1080
1031
  // Get the monom for the particular letter.
1081
1032
  let c1 = eq1.left.monomByDegree(1, letter).coefficient.clone(), c2 = eq2.left.monomByDegree(1, letter).coefficient.clone().opposed();
1082
- console.log('reduction: ', letter, eq1.tex, eq2.tex, c2.tex, c1.tex);
1083
- return this.mergeEquations(eq1, eq2, c2, c1);
1033
+ // if one value is -1, use 1 and make the other one opposed
1034
+ if (c2.isNegativeOne()) {
1035
+ c1.opposed();
1036
+ c2.opposed();
1037
+ }
1038
+ else if (c1.isNegativeOne()) {
1039
+ c1.opposed();
1040
+ c2.opposed();
1041
+ }
1042
+ return {
1043
+ merged: this.mergeEquations(eq1, eq2, c2, c1),
1044
+ factors: [c2, c1]
1045
+ };
1084
1046
  }
1085
1047
  /**
1086
1048
  * Linear reduction of the equations to have only one letter
1087
1049
  * @param letter letter to isolate
1088
- * @param V list of variables in the linear system.
1089
1050
  * @private
1090
1051
  */
1091
- _solveOneLetter(letter, V) {
1052
+ _solveOneLetter(letter, withResolution) {
1092
1053
  // list of equations.
1093
- let LE = this.clone().equations, reducedEquations = [];
1054
+ let LE = this.clone().equations, reducedEquations = [], lastIndex;
1055
+ this._resolutionSteps[letter] = [];
1094
1056
  // Reduce the equations.
1095
1057
  // Do it as long as there is more than one step, but no more than the number of equations.
1096
- for (let L of V) {
1058
+ for (let L of this.variables) {
1059
+ // Reset the stack
1060
+ reducedEquations = [];
1097
1061
  // remove the setLetter from all equations using linear combinations
1098
- if (L === letter) {
1062
+ if (L === letter)
1099
1063
  continue;
1064
+ if (withResolution) {
1065
+ this._resolutionSteps[letter].push({
1066
+ equations: LE.map(x => x.clone()),
1067
+ operations: [...new Array(LE.length)].map(x => [...new Array(LE.length - 1)].map(x => ""))
1068
+ });
1069
+ lastIndex = this._resolutionSteps[letter].length - 1;
1100
1070
  }
1101
- console.log('Removing the variable: ', L);
1102
1071
  // Linear reduction.
1103
- // TODO: Search for better association
1104
1072
  for (let i = 0; i < LE.length - 1; i++) {
1105
- reducedEquations.push(this._linearReduction(LE[i], LE[i + 1], L));
1073
+ const result = this._linearReduction(LE[i], LE[i + 1], L);
1074
+ reducedEquations.push(result.merged);
1075
+ if (withResolution) {
1076
+ this._resolutionSteps[letter][lastIndex].operations[i][i] = result.factors[0].tex;
1077
+ this._resolutionSteps[letter][lastIndex].operations[i + 1][i] = result.factors[1].tex;
1078
+ }
1106
1079
  }
1107
- console.log(reducedEquations.map(x => x.tex));
1108
- // Keep track of each steps.
1109
- this._resolutionSteps.push(new LinearSystem().parse(...reducedEquations));
1110
- // Set the list of equations to the new version.
1111
- LE = this._resolutionSteps[this._resolutionSteps.length - 1].clone().equations;
1112
- // Reset the stack
1113
- reducedEquations = [];
1080
+ LE = [...reducedEquations];
1114
1081
  }
1115
1082
  // Solve the equations
1116
- let E = this._resolutionSteps[this._resolutionSteps.length - 1].equations[0];
1083
+ // let E = this._resolutionSteps[this._resolutionSteps.length - 1].equations[0];
1084
+ let E = LE[0];
1117
1085
  E.solve();
1118
- console.log('Solutions for ', letter, ': ', E.solutions[0].tex);
1119
- return {
1120
- value: new fraction_1.Fraction(E.solutions[0].value),
1121
- isReal: E.isReal,
1122
- isVarnothing: E.isVarnothing
1123
- };
1086
+ const solution = E.solutions[0];
1087
+ if (withResolution) {
1088
+ this._resolutionSteps[letter].push({
1089
+ equations: [LE[0]],
1090
+ operations: [[LE[0].left.monoms[0].coefficient.tex]]
1091
+ });
1092
+ let P;
1093
+ if (solution.exact instanceof fraction_1.Fraction || typeof solution.exact === "string") {
1094
+ P = new polynom_1.Polynom(solution.exact);
1095
+ }
1096
+ else {
1097
+ P = new polynom_1.Polynom(solution.value);
1098
+ }
1099
+ this._resolutionSteps[letter].push({
1100
+ equations: [new equation_1.Equation(new polynom_1.Polynom(letter), P)],
1101
+ operations: []
1102
+ });
1103
+ }
1104
+ return E.solutions[0];
1124
1105
  }
1125
1106
  }
1126
1107
  exports.LinearSystem = LinearSystem;