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 +154 -173
- 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 +12 -11
- package/esm/maths/algebra/equation.js.map +1 -1
- package/esm/maths/algebra/linearSystem.d.ts +9 -14
- package/esm/maths/algebra/linearSystem.js +142 -162
- package/esm/maths/algebra/linearSystem.js.map +1 -1
- package/package.json +1 -1
- package/src/maths/algebra/equation.ts +13 -11
- package/src/maths/algebra/linearSystem.ts +180 -190
- package/tests/algebra/linear.test.ts +4 -2
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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
-
|
|
886
|
-
|
|
887
|
-
|
|
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
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
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
|
-
|
|
915
|
-
|
|
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
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
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
|
-
|
|
967
|
+
this._letters = [...variables];
|
|
968
|
+
this._letters.sort();
|
|
977
969
|
return this;
|
|
978
970
|
};
|
|
979
|
-
|
|
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
|
-
|
|
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
|
|
1036
|
-
|
|
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].
|
|
1064
|
-
|
|
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].
|
|
1068
|
-
|
|
1069
|
-
return;
|
|
1023
|
+
if (this._solutions[letter].display === "O/") {
|
|
1024
|
+
return `\\varnothing`;
|
|
1070
1025
|
}
|
|
1071
|
-
tex.push(this._solutions[letter].
|
|
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
|
-
|
|
1083
|
-
|
|
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,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
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;
|