math-exercises 3.0.215 → 3.0.217
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/lib/exercises/math/arithmetic/whichDayInXDays.d.ts.map +1 -1
- package/lib/exercises/math/arithmetic/whichDayInXDays.js +2 -1
- package/lib/exercises/math/calculLitteral/equation/exp/expOfFEqualsExpOfGEquation.d.ts.map +1 -1
- package/lib/exercises/math/calculLitteral/equation/exp/expOfFEqualsExpOfGEquation.js +19 -32
- package/lib/exercises/math/complex/unitRoots/giveOneSolutionToComplexPowNEqualsOne.js +1 -1
- package/lib/exercises/math/conversion/clock/index.d.ts +0 -1
- package/lib/exercises/math/conversion/clock/index.d.ts.map +1 -1
- package/lib/exercises/math/conversion/clock/index.js +1 -1
- package/lib/exercises/math/derivation/derivative/trigo/sinCosDerivativeRewriteUsingCos2PlusSin2Equals1.js +2 -2
- package/lib/exercises/math/graphs/adjacentMatrixPath.d.ts +10 -0
- package/lib/exercises/math/graphs/adjacentMatrixPath.d.ts.map +1 -0
- package/lib/exercises/math/graphs/adjacentMatrixPath.js +89 -0
- package/lib/exercises/math/graphs/edgesNumberFromSummitsDegrees.d.ts +7 -0
- package/lib/exercises/math/graphs/edgesNumberFromSummitsDegrees.d.ts.map +1 -0
- package/lib/exercises/math/graphs/edgesNumberFromSummitsDegrees.js +98 -0
- package/lib/exercises/math/graphs/eulerianChainFromAdjacentMatrix.d.ts +8 -0
- package/lib/exercises/math/graphs/eulerianChainFromAdjacentMatrix.d.ts.map +1 -0
- package/lib/exercises/math/graphs/eulerianChainFromAdjacentMatrix.js +96 -0
- package/lib/exercises/math/graphs/graphsChainOrPathOfLengthN.d.ts +15 -0
- package/lib/exercises/math/graphs/graphsChainOrPathOfLengthN.d.ts.map +1 -0
- package/lib/exercises/math/graphs/graphsChainOrPathOfLengthN.js +262 -0
- package/lib/exercises/math/graphs/graphsCheckIsConnectedGraph.d.ts +11 -0
- package/lib/exercises/math/graphs/graphsCheckIsConnectedGraph.d.ts.map +1 -0
- package/lib/exercises/math/graphs/graphsCheckIsConnectedGraph.js +178 -0
- package/lib/exercises/math/graphs/graphsCheckIsConnectedUndirectedGraph.d.ts +11 -0
- package/lib/exercises/math/graphs/graphsCheckIsConnectedUndirectedGraph.d.ts.map +1 -0
- package/lib/exercises/math/graphs/graphsCheckIsConnectedUndirectedGraph.js +178 -0
- package/lib/exercises/math/graphs/graphsCheckIsSameGraph.d.ts +19 -0
- package/lib/exercises/math/graphs/graphsCheckIsSameGraph.d.ts.map +1 -0
- package/lib/exercises/math/graphs/graphsCheckIsSameGraph.js +301 -0
- package/lib/exercises/math/graphs/graphsCheckIsVerticesAdjacent.d.ts +16 -0
- package/lib/exercises/math/graphs/graphsCheckIsVerticesAdjacent.d.ts.map +1 -0
- package/lib/exercises/math/graphs/graphsCheckIsVerticesAdjacent.js +207 -0
- package/lib/exercises/math/graphs/graphsDegreeOfVertex.d.ts +15 -0
- package/lib/exercises/math/graphs/graphsDegreeOfVertex.d.ts.map +1 -0
- package/lib/exercises/math/graphs/graphsDegreeOfVertex.js +232 -0
- package/lib/exercises/math/graphs/graphsOrderOfGraph.d.ts +14 -0
- package/lib/exercises/math/graphs/graphsOrderOfGraph.d.ts.map +1 -0
- package/lib/exercises/math/graphs/graphsOrderOfGraph.js +222 -0
- package/lib/exercises/math/graphs/index.d.ts +10 -0
- package/lib/exercises/math/graphs/index.d.ts.map +1 -0
- package/lib/exercises/math/graphs/index.js +9 -0
- package/lib/exercises/math/index.d.ts +1 -0
- package/lib/exercises/math/index.d.ts.map +1 -1
- package/lib/exercises/math/index.js +1 -0
- package/lib/exercises/math/integration/fromExpr/integralFromExpr.d.ts.map +1 -1
- package/lib/exercises/math/integration/fromExpr/integralFromExpr.js +2 -0
- package/lib/exercises/math/matrices/areMatricesInverse.d.ts +9 -0
- package/lib/exercises/math/matrices/areMatricesInverse.d.ts.map +1 -0
- package/lib/exercises/math/matrices/areMatricesInverse.js +106 -0
- package/lib/exercises/math/matrices/computeFixedMatrixInRecurrenceSequence.d.ts +9 -0
- package/lib/exercises/math/matrices/computeFixedMatrixInRecurrenceSequence.d.ts.map +1 -0
- package/lib/exercises/math/matrices/computeFixedMatrixInRecurrenceSequence.js +144 -0
- package/lib/exercises/math/matrices/findInversedMatrixFromSystem.d.ts +8 -0
- package/lib/exercises/math/matrices/findInversedMatrixFromSystem.d.ts.map +1 -0
- package/lib/exercises/math/matrices/findInversedMatrixFromSystem.js +148 -0
- package/lib/exercises/math/matrices/index.d.ts +12 -0
- package/lib/exercises/math/matrices/index.d.ts.map +1 -1
- package/lib/exercises/math/matrices/index.js +12 -0
- package/lib/exercises/math/matrices/isMatrixTransitionMatrix.d.ts +8 -0
- package/lib/exercises/math/matrices/isMatrixTransitionMatrix.d.ts.map +1 -0
- package/lib/exercises/math/matrices/isMatrixTransitionMatrix.js +132 -0
- package/lib/exercises/math/matrices/matrixBuildMatrixFromCoefficients.d.ts +8 -0
- package/lib/exercises/math/matrices/matrixBuildMatrixFromCoefficients.d.ts.map +1 -0
- package/lib/exercises/math/matrices/matrixBuildMatrixFromCoefficients.js +152 -0
- package/lib/exercises/math/matrices/matrixCheckIsSymmetrical.d.ts +8 -0
- package/lib/exercises/math/matrices/matrixCheckIsSymmetrical.d.ts.map +1 -0
- package/lib/exercises/math/matrices/matrixCheckIsSymmetrical.js +155 -0
- package/lib/exercises/math/matrices/matrixComputeDetOfMat2.d.ts +8 -0
- package/lib/exercises/math/matrices/matrixComputeDetOfMat2.d.ts.map +1 -0
- package/lib/exercises/math/matrices/matrixComputeDetOfMat2.js +142 -0
- package/lib/exercises/math/matrices/matrixComputeInverseOfMat2.d.ts +8 -0
- package/lib/exercises/math/matrices/matrixComputeInverseOfMat2.d.ts.map +1 -0
- package/lib/exercises/math/matrices/matrixComputeInverseOfMat2.js +237 -0
- package/lib/exercises/math/matrices/matrixComputeLinearCombination.d.ts +15 -0
- package/lib/exercises/math/matrices/matrixComputeLinearCombination.d.ts.map +1 -0
- package/lib/exercises/math/matrices/matrixComputeLinearCombination.js +232 -0
- package/lib/exercises/math/matrices/matrixComputePower.d.ts +12 -0
- package/lib/exercises/math/matrices/matrixComputePower.d.ts.map +1 -0
- package/lib/exercises/math/matrices/matrixComputePower.js +230 -0
- package/lib/exercises/math/matrices/matrixComputeProduct.d.ts +9 -0
- package/lib/exercises/math/matrices/matrixComputeProduct.d.ts.map +1 -0
- package/lib/exercises/math/matrices/matrixComputeProduct.js +178 -0
- package/lib/exercises/math/matrices/writeMatrixAssociatedToSystem.d.ts +8 -0
- package/lib/exercises/math/matrices/writeMatrixAssociatedToSystem.d.ts.map +1 -0
- package/lib/exercises/math/matrices/writeMatrixAssociatedToSystem.js +105 -0
- package/lib/exercises/math/spaceGeometry/parametricLine/lineLineRelativePositionsFromParametricLines.d.ts.map +1 -1
- package/lib/exercises/math/spaceGeometry/parametricLine/lineLineRelativePositionsFromParametricLines.js +56 -3
- package/lib/exercises/math/spaceGeometry/planes/findNormalVectorFromPlaneEquation.d.ts.map +1 -1
- package/lib/exercises/math/spaceGeometry/planes/findNormalVectorFromPlaneEquation.js +6 -0
- package/lib/exercises/vea/matrixVEA.d.ts +2 -0
- package/lib/exercises/vea/matrixVEA.d.ts.map +1 -0
- package/lib/exercises/vea/matrixVEA.js +1 -0
- package/lib/exercises/vea/treeTableVEA.d.ts.map +1 -1
- package/lib/exercises/vea/treeTableVEA.js +2 -0
- package/lib/index.d.ts +86 -13
- package/lib/index.d.ts.map +1 -1
- package/lib/math/geometry/point.d.ts.map +1 -1
- package/lib/math/geometry/point.js +3 -1
- package/lib/math/graphs/graph.d.ts +43 -0
- package/lib/math/graphs/graph.d.ts.map +1 -0
- package/lib/math/graphs/graph.js +447 -0
- package/lib/math/matrices/matrix.d.ts +42 -3
- package/lib/math/matrices/matrix.d.ts.map +1 -1
- package/lib/math/matrices/matrix.js +173 -7
- package/lib/math/matrices/parseMatrix.d.ts +3 -0
- package/lib/math/matrices/parseMatrix.d.ts.map +1 -0
- package/lib/math/matrices/parseMatrix.js +22 -0
- package/lib/math/systems/generalSystem.d.ts +2 -0
- package/lib/math/systems/generalSystem.d.ts.map +1 -1
- package/lib/math/systems/generalSystem.js +5 -0
- package/lib/math/utils/graphs/graphRenderer.d.ts +25 -0
- package/lib/math/utils/graphs/graphRenderer.d.ts.map +1 -0
- package/lib/math/utils/graphs/graphRenderer.js +123 -0
- package/lib/playground.d.ts +6 -1
- package/lib/playground.d.ts.map +1 -1
- package/lib/playground.js +6 -5
- package/lib/tree/parsers/latexParser.d.ts +1 -1
- package/lib/tree/utilities/nodeSimplifier.d.ts +1 -1
- package/lib/types/keyIds.d.ts +2 -0
- package/lib/types/keyIds.d.ts.map +1 -1
- package/lib/utils/arrays/arrayChunks.d.ts +9 -0
- package/lib/utils/arrays/arrayChunks.d.ts.map +1 -0
- package/lib/utils/arrays/arrayChunks.js +34 -0
- package/lib/utils/strings/ordinalSuffixed.d.ts +2 -0
- package/lib/utils/strings/ordinalSuffixed.d.ts.map +1 -0
- package/lib/utils/strings/ordinalSuffixed.js +5 -0
- package/package.json +7 -1
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
import { NodeComparator } from "../../tree/utilities/nodeComparator.js";
|
|
2
|
+
import { random } from "../../utils/alea/random.js";
|
|
3
|
+
import { shuffle } from "../../utils/alea/shuffle.js";
|
|
4
|
+
import { splitIntoRandomChunks } from "../../utils/arrays/arrayChunks.js";
|
|
5
|
+
import { zip } from "../../utils/arrays/arrayZip.js";
|
|
6
|
+
import { Matrix, MatrixConstructor, } from "../matrices/matrix.js";
|
|
7
|
+
export class GraphConstructor {
|
|
8
|
+
static randomConnected(nbVertices, isSimple = true, //simple === no loop A--A
|
|
9
|
+
isDirected = false, minDensity = 0.12,
|
|
10
|
+
// maxDensity: number = 0.4,
|
|
11
|
+
poolVertexName = "ABCDEFGHIJKLM".split("")) {
|
|
12
|
+
const vertexNames = poolVertexName.slice(0, nbVertices);
|
|
13
|
+
const arrIndex = shuffle([...new Array(nbVertices).keys()]);
|
|
14
|
+
// console.log("arrArrIndex", arrArrIndex);
|
|
15
|
+
const coreChain = (() => {
|
|
16
|
+
if (arrIndex.length > 1) {
|
|
17
|
+
return zip(arrIndex.slice(0, -1), arrIndex.slice(1));
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
if (isSimple) {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
const [indexSolo] = arrIndex;
|
|
25
|
+
return [[indexSolo, indexSolo]];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
})();
|
|
29
|
+
// console.log("arrCoreChain", arrCoreChain);
|
|
30
|
+
const coreNet = (() => {
|
|
31
|
+
const coreNetDirected = coreChain.reduce((acc, [startI, endI], i, coreChain) => {
|
|
32
|
+
if (i === 0) {
|
|
33
|
+
acc.push([startI, endI]);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const [start0, _] = coreChain[0];
|
|
37
|
+
const arrEndPrevious = coreChain.slice(0, i).map(([_, end]) => end);
|
|
38
|
+
const arrEndAvailable = [start0, ...arrEndPrevious];
|
|
39
|
+
const startIRandom = random(arrEndAvailable);
|
|
40
|
+
acc.push([startIRandom, endI]);
|
|
41
|
+
}
|
|
42
|
+
return acc;
|
|
43
|
+
}, []);
|
|
44
|
+
if (isDirected) {
|
|
45
|
+
return coreNetDirected;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
const coreNetDirectedReversed = coreNetDirected.map(([startI, endI]) => [endI, startI]);
|
|
49
|
+
const coreNetSimple = [...coreNetDirected, ...coreNetDirectedReversed];
|
|
50
|
+
return coreNetSimple;
|
|
51
|
+
}
|
|
52
|
+
})();
|
|
53
|
+
// console.log("arrCoreNet", arrCoreNet);
|
|
54
|
+
const dictConnectionsCore = coreNet.reduce((acc, [startI, endI]) => {
|
|
55
|
+
if (!acc[startI]) {
|
|
56
|
+
acc[startI] = {};
|
|
57
|
+
}
|
|
58
|
+
acc[startI][endI] = true;
|
|
59
|
+
return acc;
|
|
60
|
+
}, {});
|
|
61
|
+
// console.log("dictConnectionsCore", dictConnectionsCore);
|
|
62
|
+
const [rows, cols] = [nbVertices, nbVertices];
|
|
63
|
+
const elts = [...Array(rows).keys()].map((i) => [...Array(cols).keys()].map((j) => (dictConnectionsCore[i]?.[j] ? 1 : 0).toTree()));
|
|
64
|
+
// console.log(
|
|
65
|
+
// "elts",
|
|
66
|
+
// elts.map((row) => row.map((elt) => elt.toTex())),
|
|
67
|
+
// );
|
|
68
|
+
//fill randomly
|
|
69
|
+
const mat = new Matrix(elts);
|
|
70
|
+
const graphSrc = new Graph(vertexNames, mat, isDirected);
|
|
71
|
+
const graphDensified = graphSrc.densifyUpTo(minDensity);
|
|
72
|
+
return graphDensified;
|
|
73
|
+
}
|
|
74
|
+
static random(nbVertices, isSimple = true, //simple === no loop A--A
|
|
75
|
+
isDirected = false, minDensity = 0.12, poolVertexName = "ABCDEFGHIJKLM".split(""), isConnected = true) {
|
|
76
|
+
if (isConnected) {
|
|
77
|
+
return this.randomConnected(nbVertices, isSimple, isDirected, minDensity, poolVertexName);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
const vertexNames = shuffle(poolVertexName.slice(0, nbVertices));
|
|
81
|
+
const minLengthChunk = nbVertices < 4 ? 1 : 2;
|
|
82
|
+
const arrVertexNamesChunk = splitIntoRandomChunks(vertexNames, 2, vertexNames.length - minLengthChunk);
|
|
83
|
+
const arrSubGraph = arrVertexNamesChunk.map((vertexNamesChunk) => this.randomConnected(vertexNamesChunk.length, isSimple, isDirected, minDensity, vertexNamesChunk));
|
|
84
|
+
return this.graphByMergingSimpleGraphs(arrSubGraph);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
static randomChain(nbVertices, poolVertexName = "ABCDEFGHIJKLM".split(""), isDirected) {
|
|
88
|
+
if (nbVertices < 2) {
|
|
89
|
+
throw new Error("nbVertices < 2");
|
|
90
|
+
}
|
|
91
|
+
const vertexNames = poolVertexName.slice(0, nbVertices);
|
|
92
|
+
const arrIndex = shuffle([...new Array(nbVertices).keys()]);
|
|
93
|
+
// console.log("arrArrIndex", arrArrIndex);
|
|
94
|
+
const coreChain = zip(arrIndex.slice(0, -1), arrIndex.slice(1));
|
|
95
|
+
const dictConnectionsCore = coreChain.reduce((acc, [startI, endI]) => {
|
|
96
|
+
if (!acc[startI]) {
|
|
97
|
+
acc[startI] = {};
|
|
98
|
+
}
|
|
99
|
+
acc[startI][endI] = true;
|
|
100
|
+
return acc;
|
|
101
|
+
}, {});
|
|
102
|
+
// console.log("dictConnectionsCore", dictConnectionsCore);
|
|
103
|
+
const [rows, cols] = [nbVertices, nbVertices];
|
|
104
|
+
const elts = [...Array(rows).keys()].map((i) => [...Array(cols).keys()].map((j) => (dictConnectionsCore[i]?.[j] ? 1 : 0).toTree()));
|
|
105
|
+
const matDirected = new Matrix(elts);
|
|
106
|
+
const mat = isDirected ? matDirected : matDirected.symmetrized();
|
|
107
|
+
return new Graph(vertexNames, mat, isDirected);
|
|
108
|
+
}
|
|
109
|
+
// static randomWeighted(
|
|
110
|
+
// nbVertices: number,
|
|
111
|
+
// isDirected: boolean = false,
|
|
112
|
+
// isConnected: boolean = true,
|
|
113
|
+
// precision: number,
|
|
114
|
+
// ) {
|
|
115
|
+
// const graphSimple = GraphConstructor.random(
|
|
116
|
+
// nbVertices,
|
|
117
|
+
// isDirected,
|
|
118
|
+
// isConnected,
|
|
119
|
+
// );
|
|
120
|
+
// }
|
|
121
|
+
// static randomValued(
|
|
122
|
+
// nbVertices: number,
|
|
123
|
+
// isDirected: boolean = false,
|
|
124
|
+
// isConnected: boolean = true,
|
|
125
|
+
// funcRandomValue: () => number,
|
|
126
|
+
// ) {
|
|
127
|
+
// const graphSimple = GraphConstructor.random(
|
|
128
|
+
// nbVertices,
|
|
129
|
+
// isDirected,
|
|
130
|
+
// isConnected,
|
|
131
|
+
// );
|
|
132
|
+
// const elementsValued = graphSimple.mat.elements.map((row) =>
|
|
133
|
+
// row.map((elt) =>
|
|
134
|
+
// NodeComparator.compareViaSub(elt, (0).toTree())
|
|
135
|
+
// ? (0).toTree()
|
|
136
|
+
// : funcRandomValue().toTree(),
|
|
137
|
+
// ),
|
|
138
|
+
// );
|
|
139
|
+
// return new Graph(graphSimple.vertexNames, new Matrix(elementsValued));
|
|
140
|
+
// }
|
|
141
|
+
static graphByMergingSimpleGraphs(arrGraph) {
|
|
142
|
+
const isDirected = arrGraph.some((graph) => graph.isDirected);
|
|
143
|
+
const arrNameVertexSorted = arrGraph
|
|
144
|
+
.map((graph) => graph.vertexNames)
|
|
145
|
+
.reduce((acc, vertexNames) => {
|
|
146
|
+
acc = [...new Set([...acc, ...vertexNames])].toSorted((str1, str2) => str1.localeCompare(str2));
|
|
147
|
+
return acc;
|
|
148
|
+
}, []);
|
|
149
|
+
const arrDictConnections = arrGraph.map((graph) => graph.dictConnections());
|
|
150
|
+
const elementsMerged = arrNameVertexSorted.map(([nameVertexRow]) => arrNameVertexSorted.map(([nameVertexCol]) => arrDictConnections.reduce((acc, dict) => {
|
|
151
|
+
if (NodeComparator.isEqualViaSub(acc, (0).toTree())) {
|
|
152
|
+
if (dict[nameVertexRow]?.[nameVertexCol]) {
|
|
153
|
+
acc = (1).toTree();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
//ignore
|
|
158
|
+
}
|
|
159
|
+
return acc;
|
|
160
|
+
}, (0).toTree())));
|
|
161
|
+
const matMerged = new Matrix(elementsMerged);
|
|
162
|
+
return new Graph(arrNameVertexSorted, matMerged, isDirected);
|
|
163
|
+
}
|
|
164
|
+
static graphByAddingRandomEdge(graph) {
|
|
165
|
+
const arrIJWithoutDiag = [...Array(graph.vertexNames.length).keys()]
|
|
166
|
+
.flatMap((i) => [...Array(graph.vertexNames.length).keys()].map((j) => [i, j]))
|
|
167
|
+
.filter(([i, j]) => i !== j);
|
|
168
|
+
const edgeIJNotExisting = shuffle(arrIJWithoutDiag).find(([i, j]) => NodeComparator.isEqualViaSub(graph.mat.elements[i][j], (0).toTree()));
|
|
169
|
+
if (edgeIJNotExisting) {
|
|
170
|
+
const [vertexNameStart, vertexNameEnd] = edgeIJNotExisting.map((index) => graph.vertexNames[index]);
|
|
171
|
+
const miniGraph = GraphConstructor.randomConnected(2, true, graph.isDirected, 0, [vertexNameStart, vertexNameEnd]);
|
|
172
|
+
return GraphConstructor.graphByMergingSimpleGraphs([graph, miniGraph]);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
return graph;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
static fromIdentifiers(identifiers) {
|
|
179
|
+
const { vertexNames, matIds, isDirected } = identifiers;
|
|
180
|
+
const mat = MatrixConstructor.fromIdentifiers(matIds);
|
|
181
|
+
return new Graph(vertexNames, mat, isDirected);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
export class Graph {
|
|
185
|
+
vertexNames;
|
|
186
|
+
mat;
|
|
187
|
+
isDirected;
|
|
188
|
+
constructor(vertexNames, mat, isDirected) {
|
|
189
|
+
this.vertexNames = vertexNames;
|
|
190
|
+
this.mat = mat;
|
|
191
|
+
this.isDirected = isDirected ?? !mat.isSymmetrical();
|
|
192
|
+
}
|
|
193
|
+
toIdentifiers() {
|
|
194
|
+
const graphIds = {
|
|
195
|
+
vertexNames: this.vertexNames,
|
|
196
|
+
matIds: this.mat.toIdentifiers(),
|
|
197
|
+
isDirected: this.isDirected,
|
|
198
|
+
};
|
|
199
|
+
return graphIds;
|
|
200
|
+
}
|
|
201
|
+
dictConnections() {
|
|
202
|
+
return Object.fromEntries(this.mat.elements.map((row, i) => {
|
|
203
|
+
const nameFrom = this.vertexNames[i];
|
|
204
|
+
const dictTo = Object.fromEntries(row.map((elt, j) => {
|
|
205
|
+
const nameTo = this.vertexNames[j];
|
|
206
|
+
const isConnection = !NodeComparator.isEqualViaSub(elt, (0).toTree());
|
|
207
|
+
return [nameTo, isConnection];
|
|
208
|
+
}));
|
|
209
|
+
return [nameFrom, dictTo];
|
|
210
|
+
}));
|
|
211
|
+
}
|
|
212
|
+
arrConnection() {
|
|
213
|
+
return Object.entries(this.dictConnections()).flatMap(([nameVertexStart, dict]) => Object.entries(dict).map(([nameVertexEnd, isConnection]) => [nameVertexStart, nameVertexEnd, isConnection]));
|
|
214
|
+
}
|
|
215
|
+
density() {
|
|
216
|
+
return this.mat.density();
|
|
217
|
+
}
|
|
218
|
+
densifyUpTo(minDensity) {
|
|
219
|
+
const { vertexNames, isDirected } = this;
|
|
220
|
+
let mat = this.mat;
|
|
221
|
+
let counter = -1;
|
|
222
|
+
while (mat.density() < minDensity && counter < 1000) {
|
|
223
|
+
counter++;
|
|
224
|
+
const graphPrev = new Graph(vertexNames, mat, isDirected);
|
|
225
|
+
const graph = GraphConstructor.graphByAddingRandomEdge(graphPrev);
|
|
226
|
+
mat = graph.mat;
|
|
227
|
+
}
|
|
228
|
+
return new Graph(vertexNames, mat, isDirected);
|
|
229
|
+
}
|
|
230
|
+
undirectedGraph() {
|
|
231
|
+
const graphReversed = new Graph(this.vertexNames, this.mat.transposed());
|
|
232
|
+
const graphUndirected = GraphConstructor.graphByMergingSimpleGraphs([
|
|
233
|
+
this,
|
|
234
|
+
graphReversed,
|
|
235
|
+
]);
|
|
236
|
+
return graphUndirected;
|
|
237
|
+
}
|
|
238
|
+
isWeaklyConnected() {
|
|
239
|
+
const adjMatrix = (this.isDirected ? this.undirectedGraph() : this)
|
|
240
|
+
.adjacencyMatrix()
|
|
241
|
+
.elements.map((row) => row.map((elt) => elt.evaluate()));
|
|
242
|
+
//AI CODE (Edge) {
|
|
243
|
+
const n = adjMatrix.length;
|
|
244
|
+
// Validate adjacency matrix
|
|
245
|
+
if (n === 0)
|
|
246
|
+
return false;
|
|
247
|
+
for (const row of adjMatrix) {
|
|
248
|
+
if (row.length !== n) {
|
|
249
|
+
throw new Error("Invalid adjacency matrix: must be square.");
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
const visited = new Array(n).fill(false);
|
|
253
|
+
// DFS traversal
|
|
254
|
+
function dfs(node) {
|
|
255
|
+
visited[node] = true;
|
|
256
|
+
for (let neighbor = 0; neighbor < n; neighbor++) {
|
|
257
|
+
if (adjMatrix[node][neighbor] !== 0 && !visited[neighbor]) {
|
|
258
|
+
dfs(neighbor);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
// Start DFS from node 0
|
|
263
|
+
dfs(0);
|
|
264
|
+
// Check if all nodes were visited
|
|
265
|
+
return visited.every((v) => v);
|
|
266
|
+
//AI CODE (Edge) }
|
|
267
|
+
}
|
|
268
|
+
getWeaklyConnectedSubgraphCoveringChainsAsArrIndex() {
|
|
269
|
+
const adjMatrix = (this.isDirected ? this.undirectedGraph() : this)
|
|
270
|
+
.adjacencyMatrix()
|
|
271
|
+
.elements.map((row) => row.map((elt) => elt.evaluate()));
|
|
272
|
+
const n = adjMatrix.length;
|
|
273
|
+
const linked = (i, j) => i !== j &&
|
|
274
|
+
((adjMatrix[i]?.[j] ?? 0) !== 0 || (adjMatrix[j]?.[i] ?? 0) !== 0);
|
|
275
|
+
// Voisinage non orienté
|
|
276
|
+
const neighbors = Array.from({ length: n }, (_, i) => {
|
|
277
|
+
const list = [];
|
|
278
|
+
for (let j = 0; j < n; j++)
|
|
279
|
+
if (linked(i, j))
|
|
280
|
+
list.push(j);
|
|
281
|
+
return list;
|
|
282
|
+
});
|
|
283
|
+
// 1. Composantes connexes
|
|
284
|
+
const seen = new Array(n).fill(false);
|
|
285
|
+
const components = [];
|
|
286
|
+
for (let start = 0; start < n; start++) {
|
|
287
|
+
if (seen[start])
|
|
288
|
+
continue;
|
|
289
|
+
const component = [];
|
|
290
|
+
const stack = [start];
|
|
291
|
+
seen[start] = true;
|
|
292
|
+
while (stack.length > 0) {
|
|
293
|
+
const node = stack.pop();
|
|
294
|
+
component.push(node);
|
|
295
|
+
for (const nb of neighbors[node]) {
|
|
296
|
+
if (!seen[nb]) {
|
|
297
|
+
seen[nb] = true;
|
|
298
|
+
stack.push(nb);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
components.push(component.sort((a, b) => a - b));
|
|
303
|
+
}
|
|
304
|
+
// 2. Chaîne couvrant une composante
|
|
305
|
+
const coveringChain = (component) => {
|
|
306
|
+
if (component.length === 1)
|
|
307
|
+
return [...component];
|
|
308
|
+
// Arbre couvrant en profondeur (donne des branches longues)
|
|
309
|
+
const tree = new Map(component.map((v) => [v, []]));
|
|
310
|
+
const inTree = new Set([component[0]]);
|
|
311
|
+
const grow = (u) => {
|
|
312
|
+
for (const v of neighbors[u]) {
|
|
313
|
+
if (!inTree.has(v)) {
|
|
314
|
+
inTree.add(v);
|
|
315
|
+
tree.get(u).push(v);
|
|
316
|
+
tree.get(v).push(u);
|
|
317
|
+
grow(v);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
grow(component[0]);
|
|
322
|
+
// Sommet le plus éloigné (BFS dans l'arbre) + parents pour remonter la branche
|
|
323
|
+
const farthest = (src) => {
|
|
324
|
+
const parent = new Map([[src, -1]]);
|
|
325
|
+
const queue = [src];
|
|
326
|
+
for (let i = 0; i < queue.length; i++) {
|
|
327
|
+
for (const v of tree.get(queue[i])) {
|
|
328
|
+
if (!parent.has(v)) {
|
|
329
|
+
parent.set(v, queue[i]);
|
|
330
|
+
queue.push(v);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return { last: queue[queue.length - 1], parent };
|
|
335
|
+
};
|
|
336
|
+
// Diamètre de l'arbre : de a à b
|
|
337
|
+
const a = farthest(component[0]).last;
|
|
338
|
+
const { last: b, parent } = farthest(a);
|
|
339
|
+
const onDiameter = new Set();
|
|
340
|
+
for (let v = b; v !== -1; v = parent.get(v))
|
|
341
|
+
onDiameter.add(v);
|
|
342
|
+
// Parcours depuis a : les sous-arbres annexes d'abord (avec retour),
|
|
343
|
+
// la branche du diamètre en dernier (sans retour)
|
|
344
|
+
const chain = [];
|
|
345
|
+
const visit = (u, from) => {
|
|
346
|
+
chain.push(u);
|
|
347
|
+
const children = tree
|
|
348
|
+
.get(u)
|
|
349
|
+
.filter((v) => v !== from)
|
|
350
|
+
.sort((x, y) => Number(onDiameter.has(x)) - Number(onDiameter.has(y)));
|
|
351
|
+
for (const child of children) {
|
|
352
|
+
visit(child, u);
|
|
353
|
+
if (!onDiameter.has(child))
|
|
354
|
+
chain.push(u); // retour arrière
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
visit(a, -1);
|
|
358
|
+
// Normalisation : commencer par la plus petite extrémité
|
|
359
|
+
return chain[0] > chain[chain.length - 1] ? chain.reverse() : chain;
|
|
360
|
+
};
|
|
361
|
+
return components.map(coveringChain);
|
|
362
|
+
}
|
|
363
|
+
getSomePathsWithNbEdges(nbEdges, nbToFindIfPossible) {
|
|
364
|
+
const n = nbEdges;
|
|
365
|
+
const adjMatrix = this.adjacencyMatrix().elements.map((row) => row.map((elt) => elt.evaluate()));
|
|
366
|
+
const numVertices = adjMatrix.length;
|
|
367
|
+
const paths = [];
|
|
368
|
+
function dfs(currentPath) {
|
|
369
|
+
if (paths.length === nbToFindIfPossible)
|
|
370
|
+
return;
|
|
371
|
+
if (currentPath.length - 1 === n) {
|
|
372
|
+
paths.push([...currentPath]); // store a copy
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
const last = currentPath[currentPath.length - 1];
|
|
376
|
+
const arrNeighborShuffled = shuffle([...Array(numVertices).keys()]);
|
|
377
|
+
arrNeighborShuffled.forEach((neighbor) => {
|
|
378
|
+
if (adjMatrix[last][neighbor] !== 0) {
|
|
379
|
+
// edge exists
|
|
380
|
+
currentPath.push(neighbor);
|
|
381
|
+
dfs(currentPath);
|
|
382
|
+
currentPath.pop();
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
const arrStartShuffled = shuffle([...Array(numVertices).keys()]);
|
|
387
|
+
arrStartShuffled.forEach((start) => {
|
|
388
|
+
dfs([start]);
|
|
389
|
+
});
|
|
390
|
+
return paths;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
*
|
|
394
|
+
* @param nameVertexTarget
|
|
395
|
+
* @returns [d, d-, d+]
|
|
396
|
+
*/
|
|
397
|
+
getArrDegreeOfVertex(nameVertexTarget) {
|
|
398
|
+
if (this.isDirected) {
|
|
399
|
+
const dMinus = this.getArrVertexNameAdjacentXComing(nameVertexTarget, true).length;
|
|
400
|
+
const dPlus = this.getArrVertexNameAdjacentXComing(nameVertexTarget, false).length;
|
|
401
|
+
const d = dMinus + dPlus;
|
|
402
|
+
return [d, dMinus, dPlus];
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
const dPlus = this.getArrVertexNameAdjacentXComing(nameVertexTarget, false).length;
|
|
406
|
+
return [dPlus, dPlus, dPlus];
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
getArrVertexNameAdjacent(nameVertexTarget) {
|
|
410
|
+
const arrNameVertexAdjacent = [
|
|
411
|
+
...new Set([
|
|
412
|
+
...this.getArrVertexNameAdjacentXComing(nameVertexTarget, true),
|
|
413
|
+
...this.getArrVertexNameAdjacentXComing(nameVertexTarget, false),
|
|
414
|
+
]),
|
|
415
|
+
];
|
|
416
|
+
return arrNameVertexAdjacent;
|
|
417
|
+
}
|
|
418
|
+
getArrVertexNameAdjacentXComing(nameVertexTarget, isIncomingVertices) {
|
|
419
|
+
if (isIncomingVertices) {
|
|
420
|
+
const arrNameVertexAdjacentIncoming = Object.entries(this.dictConnections())
|
|
421
|
+
.filter(([_, dict]) => dict[nameVertexTarget])
|
|
422
|
+
.map(([nameVertex, _]) => nameVertex);
|
|
423
|
+
return arrNameVertexAdjacentIncoming;
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
const arrNameVertexAdjacentOutgoing = Object.entries(this.dictConnections()[nameVertexTarget])
|
|
427
|
+
.filter(([_, isConnection]) => isConnection)
|
|
428
|
+
.map(([vertexName, _]) => vertexName);
|
|
429
|
+
return arrNameVertexAdjacentOutgoing;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
isValidPath(arrNameVertex) {
|
|
433
|
+
const dictConnections = this.dictConnections();
|
|
434
|
+
return zip(arrNameVertex.slice(0, -1), arrNameVertex.slice(1)).every(([nameVertexStart, nameVertexEnd]) => dictConnections[nameVertexStart]?.[nameVertexEnd]);
|
|
435
|
+
}
|
|
436
|
+
adjacencyMatrix() {
|
|
437
|
+
const elementsQuantized = this.mat.elements.map((row) => row.map((elt) => NodeComparator.isEqualViaSub(elt, (0).toTree())
|
|
438
|
+
? (0).toTree()
|
|
439
|
+
: (1).toTree()));
|
|
440
|
+
return new Matrix(elementsQuantized);
|
|
441
|
+
}
|
|
442
|
+
equals(graph2) {
|
|
443
|
+
const isSameVertex = () => zip(this.vertexNames, graph2.vertexNames).every(([nameVertex1, nameVertex2]) => nameVertex1 === nameVertex2);
|
|
444
|
+
const isSameMat = () => this.mat.equals(graph2.mat);
|
|
445
|
+
return isSameVertex() && isSameMat();
|
|
446
|
+
}
|
|
447
|
+
}
|
|
@@ -1,13 +1,52 @@
|
|
|
1
|
-
import { AlgebraicNode } from "../../tree/nodes/algebraicNode.js";
|
|
1
|
+
import { AlgebraicNode, SimplifyOptions } from "../../tree/nodes/algebraicNode.js";
|
|
2
|
+
import { NodeIdentifiers } from "../../tree/nodes/nodeConstructor.js";
|
|
3
|
+
import { SubstractNode } from "../../tree/nodes/operators/substractNode.js";
|
|
4
|
+
import { RandintProps } from "../utils/random/randint.js";
|
|
5
|
+
type MatrixConstructorOpts = {
|
|
6
|
+
allowIdentity?: boolean;
|
|
7
|
+
elementsOpts?: RandintProps;
|
|
8
|
+
adjacentAllowLoop?: boolean;
|
|
9
|
+
niceInversible?: boolean;
|
|
10
|
+
};
|
|
2
11
|
export declare abstract class MatrixConstructor {
|
|
3
|
-
static random(rows: number, cols: number): Matrix;
|
|
12
|
+
static random(rows: number, cols: number, opts?: MatrixConstructorOpts): Matrix;
|
|
13
|
+
static identity(order: number): Matrix;
|
|
14
|
+
static randomInversible(rows: number, cols: number, opts?: MatrixConstructorOpts): Matrix;
|
|
15
|
+
static fromIdentifiers(identifiers: MatrixIdentifiers): Matrix;
|
|
16
|
+
static emptyVarMatrix(nbRows: number, nbCols: number): Matrix;
|
|
17
|
+
static randomAdjacent(length: number, opts?: MatrixConstructorOpts): Matrix;
|
|
4
18
|
}
|
|
19
|
+
export type MatrixIdentifiers = {
|
|
20
|
+
id: "matrix";
|
|
21
|
+
elementsIds: NodeIdentifiers[][];
|
|
22
|
+
};
|
|
5
23
|
export declare class Matrix {
|
|
6
24
|
elements: AlgebraicNode[][];
|
|
7
25
|
rows: number;
|
|
8
26
|
columns: number;
|
|
9
27
|
constructor(elements: AlgebraicNode[][]);
|
|
10
|
-
|
|
28
|
+
transposed(): Matrix;
|
|
29
|
+
isSymmetrical(): boolean;
|
|
30
|
+
symmetrized(): Matrix;
|
|
31
|
+
toIdentifiers(): MatrixIdentifiers;
|
|
32
|
+
determinant(): SubstractNode;
|
|
33
|
+
toInversed(): Matrix;
|
|
34
|
+
isIdentity(): boolean;
|
|
35
|
+
isTransition(): boolean;
|
|
36
|
+
inverse(): Matrix | undefined;
|
|
37
|
+
density(): number;
|
|
38
|
+
matForMapFunc(func: (elt: AlgebraicNode, i: number, j: number) => AlgebraicNode): Matrix;
|
|
39
|
+
times(k: AlgebraicNode): Matrix;
|
|
40
|
+
opposite(): Matrix;
|
|
41
|
+
isMatAdditionPossible(matPrime: Matrix): boolean;
|
|
42
|
+
add(matPrime: Matrix): Matrix;
|
|
43
|
+
substract(matPrime: Matrix): Matrix;
|
|
44
|
+
isMatProductPossible(matPrime: Matrix): boolean;
|
|
45
|
+
matrixProduct(matPrime: Matrix): Matrix;
|
|
46
|
+
power(exponent: number): Matrix;
|
|
47
|
+
equals(matPrime: Matrix): boolean;
|
|
11
48
|
toTex(): string;
|
|
49
|
+
simplify(simplifyOpts?: SimplifyOptions): Matrix;
|
|
12
50
|
}
|
|
51
|
+
export {};
|
|
13
52
|
//# sourceMappingURL=matrix.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matrix.d.ts","sourceRoot":"","sources":["../../../src/math/matrices/matrix.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"matrix.d.ts","sourceRoot":"","sources":["../../../src/math/matrices/matrix.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,eAAe,EAChB,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EACL,eAAe,EAEhB,MAAM,qCAAqC,CAAC;AAO7C,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAK5E,OAAO,EAAW,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAEnE,KAAK,qBAAqB,GAAG;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AACF,8BAAsB,iBAAiB;IACrC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB;IActE,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM;IAS7B,MAAM,CAAC,gBAAgB,CACrB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,qBAAqB;IAW9B,MAAM,CAAC,eAAe,CAAC,WAAW,EAAE,iBAAiB;IAQrD,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAQpD,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB;CAWnE;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,QAAQ,CAAC;IACb,WAAW,EAAE,eAAe,EAAE,EAAE,CAAC;CAClC,CAAC;AAEF,qBAAa,MAAM;IACjB,QAAQ,EAAE,aAAa,EAAE,EAAE,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;gBACJ,QAAQ,EAAE,aAAa,EAAE,EAAE;IAMvC,UAAU;IAIV,aAAa;IAQb,WAAW;IAIX,aAAa,IAAI,iBAAiB;IAQlC,WAAW;IASX,UAAU;IAaV,UAAU;IAcV,YAAY;IAgBZ,OAAO;IAgBP,OAAO;IAOP,aAAa,CACX,IAAI,EAAE,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,aAAa;IAQnE,KAAK,CAAC,CAAC,EAAE,aAAa;IAMtB,QAAQ;IAIR,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIhD,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAM7B,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAInC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAI/C,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAmBvC,KAAK,CAAC,QAAQ,EAAE,MAAM;IAUtB,MAAM,CAAC,QAAQ,EAAE,MAAM;IAYvB,KAAK;IAML,QAAQ,CAAC,YAAY,CAAC,EAAE,eAAe;CAMxC"}
|