mapFolding 0.6.0__py3-none-any.whl → 0.7.1__py3-none-any.whl

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.
Files changed (54) hide show
  1. mapFolding/__init__.py +6 -104
  2. mapFolding/basecamp.py +12 -8
  3. mapFolding/beDRY.py +103 -286
  4. mapFolding/filesystem.py +95 -0
  5. mapFolding/noHomeYet.py +20 -0
  6. mapFolding/oeis.py +46 -39
  7. mapFolding/reference/flattened.py +377 -0
  8. mapFolding/reference/hunterNumba.py +132 -0
  9. mapFolding/reference/irvineJavaPort.py +120 -0
  10. mapFolding/reference/jax.py +208 -0
  11. mapFolding/reference/lunnan.py +153 -0
  12. mapFolding/reference/lunnanNumpy.py +123 -0
  13. mapFolding/reference/lunnanWhile.py +121 -0
  14. mapFolding/reference/rotatedEntryPoint.py +240 -0
  15. mapFolding/reference/total_countPlus1vsPlusN.py +211 -0
  16. mapFolding/someAssemblyRequired/Z0Z_workbench.py +33 -0
  17. mapFolding/someAssemblyRequired/__init__.py +16 -0
  18. mapFolding/someAssemblyRequired/getLLVMforNoReason.py +21 -0
  19. mapFolding/someAssemblyRequired/ingredientsNumba.py +100 -0
  20. mapFolding/someAssemblyRequired/synthesizeCountingFunctions.py +7 -0
  21. mapFolding/someAssemblyRequired/synthesizeDataConverters.py +135 -0
  22. mapFolding/someAssemblyRequired/synthesizeNumba.py +91 -0
  23. mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +417 -0
  24. mapFolding/someAssemblyRequired/synthesizeNumbaModules.py +91 -0
  25. mapFolding/someAssemblyRequired/transformationTools.py +425 -0
  26. mapFolding/someAssemblyRequired/whatWillBe.py +357 -0
  27. mapFolding/syntheticModules/__init__.py +0 -0
  28. mapFolding/syntheticModules/dataNamespaceFlattened.py +30 -0
  29. mapFolding/syntheticModules/multiprocessingCount_doTheNeedful.py +216 -0
  30. mapFolding/syntheticModules/numbaCount.py +90 -0
  31. mapFolding/syntheticModules/numbaCountExample.py +158 -0
  32. mapFolding/syntheticModules/numbaCountSequential.py +111 -0
  33. mapFolding/syntheticModules/numbaCount_doTheNeedful.py +13 -0
  34. mapFolding/syntheticModules/numba_doTheNeedful.py +12 -0
  35. mapFolding/syntheticModules/numba_doTheNeedfulExample.py +13 -0
  36. mapFolding/theDao.py +216 -229
  37. mapFolding/theSSOT.py +269 -101
  38. {mapfolding-0.6.0.dist-info → mapfolding-0.7.1.dist-info}/METADATA +7 -6
  39. mapfolding-0.7.1.dist-info/RECORD +51 -0
  40. {mapfolding-0.6.0.dist-info → mapfolding-0.7.1.dist-info}/WHEEL +1 -1
  41. {mapfolding-0.6.0.dist-info → mapfolding-0.7.1.dist-info}/top_level.txt +1 -0
  42. tests/__init__.py +0 -0
  43. tests/conftest.py +278 -0
  44. tests/test_computations.py +53 -0
  45. tests/test_filesystem.py +52 -0
  46. tests/test_oeis.py +128 -0
  47. tests/test_other.py +84 -0
  48. tests/test_tasks.py +56 -0
  49. mapFolding/theConfiguration.py +0 -58
  50. mapFolding/theSSOTdatatypes.py +0 -155
  51. mapFolding/theWrongWay.py +0 -7
  52. mapfolding-0.6.0.dist-info/RECORD +0 -16
  53. {mapfolding-0.6.0.dist-info → mapfolding-0.7.1.dist-info}/LICENSE +0 -0
  54. {mapfolding-0.6.0.dist-info → mapfolding-0.7.1.dist-info}/entry_points.txt +0 -0
mapFolding/theDao.py CHANGED
@@ -1,232 +1,219 @@
1
- from mapFolding import indexMy, indexTrack
2
- from numba import prange
3
- from numpy import dtype, integer, ndarray
4
- from typing import Any
5
-
6
- # `.value` is not necessary for this module or most modules. But, this module is transformed into Numba "jitted" functions, and Numba won't use `Enum` for an ndarray index without `.value`.
7
- def activeLeafConnectedToItself(my: ndarray[tuple[int], dtype[integer[Any]]]) -> Any:
8
- return my[indexMy.leafConnectee.value] == my[indexMy.leaf1ndex.value]
9
-
10
- def activeLeafGreaterThan0(my: ndarray[tuple[int], dtype[integer[Any]]]) -> Any:
11
- return my[indexMy.leaf1ndex.value] > 0
12
-
13
- def activeLeafGreaterThanLeavesTotal(foldGroups: ndarray[tuple[int], dtype[integer[Any]]], my: ndarray[tuple[int], dtype[integer[Any]]]) -> Any:
14
- return my[indexMy.leaf1ndex.value] > foldGroups[-1]
15
-
16
- def activeLeafIsTheFirstLeaf(my: ndarray[tuple[int], dtype[integer[Any]]]) -> Any:
17
- return my[indexMy.leaf1ndex.value] <= 1
18
-
19
- def allDimensionsAreUnconstrained(my: ndarray[tuple[int], dtype[integer[Any]]]) -> Any:
20
- return not my[indexMy.dimensionsUnconstrained.value]
21
-
22
- def backtrack(my: ndarray[tuple[int], dtype[integer[Any]]], track: ndarray[tuple[int, int], dtype[integer[Any]]]) -> None:
23
- my[indexMy.leaf1ndex.value] -= 1
24
- track[indexTrack.leafBelow.value, track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]]] = track[indexTrack.leafBelow.value, my[indexMy.leaf1ndex.value]]
25
- track[indexTrack.leafAbove.value, track[indexTrack.leafBelow.value, my[indexMy.leaf1ndex.value]]] = track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]]
26
-
27
- def countGaps(gapsWhere: ndarray[tuple[int], dtype[integer[Any]]], my: ndarray[tuple[int], dtype[integer[Any]]], track: ndarray[tuple[int, int], dtype[integer[Any]]]) -> None:
28
- gapsWhere[my[indexMy.gap1ndexCeiling.value]] = my[indexMy.leafConnectee.value]
29
- if track[indexTrack.countDimensionsGapped.value, my[indexMy.leafConnectee.value]] == 0:
30
- incrementGap1ndexCeiling(my=my)
31
- track[indexTrack.countDimensionsGapped.value, my[indexMy.leafConnectee.value]] += 1
32
-
33
- def decrementDimensionsUnconstrained(my: ndarray[tuple[int], dtype[integer[Any]]]) -> None:
34
- my[indexMy.dimensionsUnconstrained.value] -= 1
35
-
36
- def dimensionsUnconstrainedCondition(connectionGraph: ndarray[tuple[int, int, int], dtype[integer[Any]]], my: ndarray[tuple[int], dtype[integer[Any]]]) -> Any:
37
- return connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], my[indexMy.leaf1ndex.value]] == my[indexMy.leaf1ndex.value]
38
-
39
- def filterCommonGaps(gapsWhere: ndarray[tuple[int], dtype[integer[Any]]], my: ndarray[tuple[int], dtype[integer[Any]]], track: ndarray[tuple[int, int], dtype[integer[Any]]]) -> None:
40
- gapsWhere[my[indexMy.gap1ndex.value]] = gapsWhere[my[indexMy.indexMiniGap.value]]
41
- if track[indexTrack.countDimensionsGapped.value, gapsWhere[my[indexMy.indexMiniGap.value]]] == my[indexMy.dimensionsUnconstrained.value]:
42
- incrementActiveGap(my=my)
43
- track[indexTrack.countDimensionsGapped.value, gapsWhere[my[indexMy.indexMiniGap.value]]] = 0
44
-
45
- def incrementActiveGap(my: ndarray[tuple[int], dtype[integer[Any]]]) -> None:
46
- my[indexMy.gap1ndex.value] += 1
47
-
48
- def incrementGap1ndexCeiling(my: ndarray[tuple[int], dtype[integer[Any]]]) -> None:
49
- my[indexMy.gap1ndexCeiling.value] += 1
50
-
51
- def incrementIndexDimension(my: ndarray[tuple[int], dtype[integer[Any]]]) -> None:
52
- my[indexMy.indexDimension.value] += 1
53
-
54
- def incrementIndexMiniGap(my: ndarray[tuple[int], dtype[integer[Any]]]) -> None:
55
- my[indexMy.indexMiniGap.value] += 1
56
-
57
- def initializeIndexMiniGap(my: ndarray[tuple[int], dtype[integer[Any]]]) -> None:
58
- my[indexMy.indexMiniGap.value] = my[indexMy.gap1ndex.value]
59
-
60
- def initializeLeafConnectee(connectionGraph: ndarray[tuple[int, int, int], dtype[integer[Any]]], my: ndarray[tuple[int], dtype[integer[Any]]]) -> None:
61
- my[indexMy.leafConnectee.value] = connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], my[indexMy.leaf1ndex.value]]
62
-
63
- def initializeVariablesToFindGaps(my: ndarray[tuple[int], dtype[integer[Any]]], track: ndarray[tuple[int, int], dtype[integer[Any]]]) -> None:
64
- my[indexMy.dimensionsUnconstrained.value] = my[indexMy.dimensionsTotal.value]
65
- my[indexMy.gap1ndexCeiling.value] = track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value] - 1]
66
- my[indexMy.indexDimension.value] = 0
67
-
68
- def insertUnconstrainedLeaf(gapsWhere: ndarray[tuple[int], dtype[integer[Any]]], my: ndarray[tuple[int], dtype[integer[Any]]]) -> None:
69
- my[indexMy.indexLeaf.value] = 0
70
- while my[indexMy.indexLeaf.value] < my[indexMy.leaf1ndex.value]:
71
- gapsWhere[my[indexMy.gap1ndexCeiling.value]] = my[indexMy.indexLeaf.value]
72
- my[indexMy.gap1ndexCeiling.value] += 1
73
- my[indexMy.indexLeaf.value] += 1
74
-
75
- def leafBelowSentinelIs1(track: ndarray[tuple[int, int], dtype[integer[Any]]]) -> Any:
76
- return track[indexTrack.leafBelow.value, 0] == 1
77
-
78
- def loopingLeavesConnectedToActiveLeaf(my: ndarray[tuple[int], dtype[integer[Any]]]) -> Any:
79
- return my[indexMy.leafConnectee.value] != my[indexMy.leaf1ndex.value]
80
-
81
- def loopingToActiveGapCeiling(my: ndarray[tuple[int], dtype[integer[Any]]]) -> Any:
82
- return my[indexMy.indexMiniGap.value] < my[indexMy.gap1ndexCeiling.value]
83
-
84
- def loopUpToDimensionsTotal(my: ndarray[tuple[int], dtype[integer[Any]]]) -> Any:
85
- return my[indexMy.indexDimension.value] < my[indexMy.dimensionsTotal.value]
86
-
87
- def noGapsHere(my: ndarray[tuple[int], dtype[integer[Any]]], track: ndarray[tuple[int, int], dtype[integer[Any]]]) -> Any:
88
- return my[indexMy.leaf1ndex.value] > 0 and my[indexMy.gap1ndex.value] == track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value] - 1]
89
-
90
- def placeLeaf(gapsWhere: ndarray[tuple[int], dtype[integer[Any]]], my: ndarray[tuple[int], dtype[integer[Any]]], track: ndarray[tuple[int, int], dtype[integer[Any]]]) -> None:
91
- my[indexMy.gap1ndex.value] -= 1
92
- track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]] = gapsWhere[my[indexMy.gap1ndex.value]]
93
- track[indexTrack.leafBelow.value, my[indexMy.leaf1ndex.value]] = track[indexTrack.leafBelow.value, track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]]]
94
- track[indexTrack.leafBelow.value, track[indexTrack.leafAbove.value, my[indexMy.leaf1ndex.value]]] = my[indexMy.leaf1ndex.value]
95
- track[indexTrack.leafAbove.value, track[indexTrack.leafBelow.value, my[indexMy.leaf1ndex.value]]] = my[indexMy.leaf1ndex.value]
96
- track[indexTrack.gapRangeStart.value, my[indexMy.leaf1ndex.value]] = my[indexMy.gap1ndex.value]
97
- my[indexMy.leaf1ndex.value] += 1
98
-
99
- def thereIsAnActiveLeaf(my: ndarray[tuple[int], dtype[integer[Any]]]) -> Any:
100
- return my[indexMy.leaf1ndex.value] > 0
101
-
102
- def thisIsMyTaskIndex(my: ndarray[tuple[int], dtype[integer[Any]]]) -> Any:
103
- return my[indexMy.leaf1ndex.value] != my[indexMy.taskDivisions.value] or my[indexMy.leafConnectee.value] % my[indexMy.taskDivisions.value] == my[indexMy.taskIndex.value]
104
-
105
- def updateLeafConnectee(connectionGraph: ndarray[tuple[int, int, int], dtype[integer[Any]]], my: ndarray[tuple[int], dtype[integer[Any]]], track: ndarray[tuple[int, int], dtype[integer[Any]]]) -> None:
106
- my[indexMy.leafConnectee.value] = connectionGraph[my[indexMy.indexDimension.value], my[indexMy.leaf1ndex.value], track[indexTrack.leafBelow.value, my[indexMy.leafConnectee.value]]]
107
-
108
- def countInitialize(connectionGraph: ndarray[tuple[int, int, int], dtype[integer[Any]]]
109
- , gapsWhere: ndarray[tuple[int] , dtype[integer[Any]]]
110
- , my: ndarray[tuple[int] , dtype[integer[Any]]]
111
- , track: ndarray[tuple[int, int] , dtype[integer[Any]]]
112
- ) -> None:
113
-
114
- while activeLeafGreaterThan0(my=my):
115
- if activeLeafIsTheFirstLeaf(my=my) or leafBelowSentinelIs1(track=track):
116
- initializeVariablesToFindGaps(my=my, track=track)
117
- while loopUpToDimensionsTotal(my=my):
118
- if dimensionsUnconstrainedCondition(connectionGraph=connectionGraph, my=my):
119
- decrementDimensionsUnconstrained(my=my)
120
- else:
121
- initializeLeafConnectee(connectionGraph=connectionGraph, my=my)
122
- while loopingLeavesConnectedToActiveLeaf(my=my):
123
- countGaps(gapsWhere=gapsWhere, my=my, track=track)
124
- updateLeafConnectee(connectionGraph=connectionGraph, my=my, track=track)
125
- incrementIndexDimension(my=my)
126
- if allDimensionsAreUnconstrained(my=my):
127
- insertUnconstrainedLeaf(gapsWhere=gapsWhere, my=my)
128
- initializeIndexMiniGap(my=my)
129
- while loopingToActiveGapCeiling(my=my):
130
- filterCommonGaps(gapsWhere=gapsWhere, my=my, track=track)
131
- incrementIndexMiniGap(my=my)
132
- if thereIsAnActiveLeaf(my=my):
133
- placeLeaf(gapsWhere=gapsWhere, my=my, track=track)
134
- if my[indexMy.gap1ndex.value] > 0:
135
- return
136
-
137
- def countParallel(connectionGraph: ndarray[tuple[int, int, int], dtype[integer[Any]]]
138
- , foldGroups: ndarray[tuple[int] , dtype[integer[Any]]]
139
- , gapsWhere: ndarray[tuple[int] , dtype[integer[Any]]]
140
- , my: ndarray[tuple[int] , dtype[integer[Any]]]
141
- , track: ndarray[tuple[int, int] , dtype[integer[Any]]]
142
- ) -> None:
143
-
144
- gapsWherePARALLEL = gapsWhere.copy()
145
- myPARALLEL = my.copy()
146
- trackPARALLEL = track.copy()
147
-
148
- taskDivisionsPrange = myPARALLEL[indexMy.taskDivisions.value]
149
-
150
- for indexSherpa in prange(taskDivisionsPrange): # type: ignore
151
- groupsOfFolds: int = 0
152
-
153
- gapsWhere = gapsWherePARALLEL.copy()
154
- my = myPARALLEL.copy()
155
- track = trackPARALLEL.copy()
156
-
157
- my[indexMy.taskIndex.value] = indexSherpa
158
-
159
- while activeLeafGreaterThan0(my=my):
160
- if activeLeafIsTheFirstLeaf(my=my) or leafBelowSentinelIs1(track=track):
161
- if activeLeafGreaterThanLeavesTotal(foldGroups=foldGroups, my=my):
162
- groupsOfFolds += 1
163
- else:
164
- initializeVariablesToFindGaps(my=my, track=track)
165
- while loopUpToDimensionsTotal(my=my):
166
- if dimensionsUnconstrainedCondition(connectionGraph=connectionGraph, my=my):
167
- decrementDimensionsUnconstrained(my=my)
168
- else:
169
- initializeLeafConnectee(connectionGraph=connectionGraph, my=my)
170
- while loopingLeavesConnectedToActiveLeaf(my=my):
171
- if thisIsMyTaskIndex(my=my):
172
- countGaps(gapsWhere=gapsWhere, my=my, track=track)
173
- updateLeafConnectee(connectionGraph=connectionGraph, my=my, track=track)
174
- incrementIndexDimension(my=my)
175
- initializeIndexMiniGap(my=my)
176
- while loopingToActiveGapCeiling(my=my):
177
- filterCommonGaps(gapsWhere=gapsWhere, my=my, track=track)
178
- incrementIndexMiniGap(my=my)
179
- while noGapsHere(my=my, track=track):
180
- backtrack(my=my, track=track)
181
- if thereIsAnActiveLeaf(my=my):
182
- placeLeaf(gapsWhere=gapsWhere, my=my, track=track)
183
- foldGroups[my[indexMy.taskIndex.value]] = groupsOfFolds
184
-
185
- def countSequential( connectionGraph: ndarray[tuple[int, int, int], dtype[integer[Any]]]
186
- , foldGroups: ndarray[tuple[int] , dtype[integer[Any]]]
187
- , gapsWhere: ndarray[tuple[int] , dtype[integer[Any]]]
188
- , my: ndarray[tuple[int] , dtype[integer[Any]]]
189
- , track: ndarray[tuple[int, int] , dtype[integer[Any]]]
190
- ) -> None:
191
-
192
- groupsOfFolds: int = 0
193
-
194
- while activeLeafGreaterThan0(my=my):
195
- if activeLeafIsTheFirstLeaf(my=my) or leafBelowSentinelIs1(track=track):
196
- if activeLeafGreaterThanLeavesTotal(foldGroups=foldGroups, my=my):
197
- groupsOfFolds += 1
1
+ from concurrent.futures import ProcessPoolExecutor
2
+ from mapFolding.theSSOT import ComputationState
3
+ import concurrent.futures
4
+ import copy
5
+ import multiprocessing
6
+
7
+ # When to use multiprocessing.set_start_method https://github.com/hunterhogan/mapFolding/issues/6
8
+ if __name__ == '__main__':
9
+ multiprocessing.set_start_method('spawn')
10
+
11
+ def activeLeafConnectedToItself(state: ComputationState) -> bool:
12
+ return state.leafConnectee == state.leaf1ndex
13
+
14
+ def activeLeafGreaterThan0(state: ComputationState) -> bool:
15
+ return state.leaf1ndex > 0
16
+
17
+ def activeLeafGreaterThanLeavesTotal(state: ComputationState) -> bool:
18
+ return state.leaf1ndex > state.leavesTotal
19
+
20
+ def activeLeafIsTheFirstLeaf(state: ComputationState) -> bool:
21
+ return state.leaf1ndex <= 1
22
+
23
+ def allDimensionsAreUnconstrained(state: ComputationState) -> bool:
24
+ return not state.dimensionsUnconstrained
25
+
26
+ def backtrack(state: ComputationState) -> ComputationState:
27
+ state.leaf1ndex -= 1
28
+ state.leafBelow[state.leafAbove[state.leaf1ndex]] = state.leafBelow[state.leaf1ndex]
29
+ state.leafAbove[state.leafBelow[state.leaf1ndex]] = state.leafAbove[state.leaf1ndex]
30
+ return state
31
+
32
+ def countGaps(state: ComputationState) -> ComputationState:
33
+ state.gapsWhere[state.gap1ndexCeiling] = state.leafConnectee
34
+ if state.countDimensionsGapped[state.leafConnectee] == 0:
35
+ state = incrementGap1ndexCeiling(state)
36
+ state.countDimensionsGapped[state.leafConnectee] += 1
37
+ return state
38
+
39
+ def decrementDimensionsUnconstrained(state: ComputationState) -> ComputationState:
40
+ state.dimensionsUnconstrained -= 1
41
+ return state
42
+
43
+ def dimensionsUnconstrainedCondition(state: ComputationState) -> bool:
44
+ return state.connectionGraph[state.indexDimension, state.leaf1ndex, state.leaf1ndex] == state.leaf1ndex
45
+
46
+ def filterCommonGaps(state: ComputationState) -> ComputationState:
47
+ state.gapsWhere[state.gap1ndex] = state.gapsWhere[state.indexMiniGap]
48
+ if state.countDimensionsGapped[state.gapsWhere[state.indexMiniGap]] == state.dimensionsUnconstrained:
49
+ state = incrementActiveGap(state)
50
+ state.countDimensionsGapped[state.gapsWhere[state.indexMiniGap]] = 0
51
+ return state
52
+
53
+ def incrementActiveGap(state: ComputationState) -> ComputationState:
54
+ state.gap1ndex += 1
55
+ return state
56
+
57
+ def incrementGap1ndexCeiling(state: ComputationState) -> ComputationState:
58
+ state.gap1ndexCeiling += 1
59
+ return state
60
+
61
+ def incrementIndexDimension(state: ComputationState) -> ComputationState:
62
+ state.indexDimension += 1
63
+ return state
64
+
65
+ def incrementIndexMiniGap(state: ComputationState) -> ComputationState:
66
+ state.indexMiniGap += 1
67
+ return state
68
+
69
+ def initializeIndexMiniGap(state: ComputationState) -> ComputationState:
70
+ state.indexMiniGap = state.gap1ndex
71
+ return state
72
+
73
+ def initializeLeafConnectee(state: ComputationState) -> ComputationState:
74
+ state.leafConnectee = state.connectionGraph[state.indexDimension, state.leaf1ndex, state.leaf1ndex]
75
+ return state
76
+
77
+ def initializeVariablesToFindGaps(state: ComputationState) -> ComputationState:
78
+ state.dimensionsUnconstrained = state.dimensionsTotal
79
+ state.gap1ndexCeiling = state.gapRangeStart[state.leaf1ndex - 1]
80
+ state.indexDimension = 0
81
+ return state
82
+
83
+ def insertUnconstrainedLeaf(state: ComputationState) -> ComputationState:
84
+ indexLeaf = 0
85
+ while indexLeaf < state.leaf1ndex:
86
+ state.gapsWhere[state.gap1ndexCeiling] = indexLeaf
87
+ state.gap1ndexCeiling += 1
88
+ indexLeaf += 1
89
+ return state
90
+
91
+ def leafBelowSentinelIs1(state: ComputationState) -> bool:
92
+ return state.leafBelow[0] == 1
93
+
94
+ def loopingLeavesConnectedToActiveLeaf(state: ComputationState) -> bool:
95
+ return state.leafConnectee != state.leaf1ndex
96
+
97
+ def loopingToActiveGapCeiling(state: ComputationState) -> bool:
98
+ return state.indexMiniGap < state.gap1ndexCeiling
99
+
100
+ def loopUpToDimensionsTotal(state: ComputationState) -> bool:
101
+ return state.indexDimension < state.dimensionsTotal
102
+
103
+ def noGapsHere(state: ComputationState) -> bool:
104
+ return (state.leaf1ndex > 0) and (state.gap1ndex == state.gapRangeStart[state.leaf1ndex - 1])
105
+
106
+ def placeLeaf(state: ComputationState) -> ComputationState:
107
+ state.gap1ndex -= 1
108
+ state.leafAbove[state.leaf1ndex] = state.gapsWhere[state.gap1ndex]
109
+ state.leafBelow[state.leaf1ndex] = state.leafBelow[state.leafAbove[state.leaf1ndex]]
110
+ state.leafBelow[state.leafAbove[state.leaf1ndex]] = state.leaf1ndex
111
+ state.leafAbove[state.leafBelow[state.leaf1ndex]] = state.leaf1ndex
112
+ state.gapRangeStart[state.leaf1ndex] = state.gap1ndex
113
+ state.leaf1ndex += 1
114
+ return state
115
+
116
+ def thereIsAnActiveLeaf(state: ComputationState) -> bool:
117
+ return state.leaf1ndex > 0
118
+
119
+ def thisIsMyTaskIndex(state: ComputationState) -> bool:
120
+ return (state.leaf1ndex != state.taskDivisions) or (state.leafConnectee % state.taskDivisions == state.taskIndex)
121
+
122
+ def updateLeafConnectee(state: ComputationState) -> ComputationState:
123
+ state.leafConnectee = state.connectionGraph[state.indexDimension, state.leaf1ndex, state.leafBelow[state.leafConnectee]]
124
+ return state
125
+
126
+ def countInitialize(state: ComputationState) -> ComputationState:
127
+ while activeLeafGreaterThan0(state):
128
+ if activeLeafIsTheFirstLeaf(state) or leafBelowSentinelIs1(state):
129
+ state = initializeVariablesToFindGaps(state)
130
+ while loopUpToDimensionsTotal(state):
131
+ state = initializeLeafConnectee(state)
132
+ if activeLeafConnectedToItself(state):
133
+ state = decrementDimensionsUnconstrained(state)
134
+ else:
135
+ while loopingLeavesConnectedToActiveLeaf(state):
136
+ state = countGaps(state)
137
+ state = updateLeafConnectee(state)
138
+ state = incrementIndexDimension(state)
139
+ if allDimensionsAreUnconstrained(state):
140
+ state = insertUnconstrainedLeaf(state)
141
+ state = initializeIndexMiniGap(state)
142
+ while loopingToActiveGapCeiling(state):
143
+ state = filterCommonGaps(state)
144
+ state = incrementIndexMiniGap(state)
145
+ if thereIsAnActiveLeaf(state):
146
+ state = placeLeaf(state)
147
+ if state.gap1ndex > 0:
148
+ break
149
+ return state
150
+
151
+ def countParallel(state: ComputationState) -> ComputationState:
152
+ while activeLeafGreaterThan0(state):
153
+ if activeLeafIsTheFirstLeaf(state) or leafBelowSentinelIs1(state):
154
+ if activeLeafGreaterThanLeavesTotal(state):
155
+ state.groupsOfFolds += 1
156
+ else:
157
+ state = initializeVariablesToFindGaps(state)
158
+ while loopUpToDimensionsTotal(state):
159
+ if dimensionsUnconstrainedCondition(state):
160
+ state = decrementDimensionsUnconstrained(state)
161
+ else:
162
+ state = initializeLeafConnectee(state)
163
+ while loopingLeavesConnectedToActiveLeaf(state):
164
+ if thisIsMyTaskIndex(state):
165
+ state = countGaps(state)
166
+ state = updateLeafConnectee(state)
167
+ state = incrementIndexDimension(state)
168
+ state = initializeIndexMiniGap(state)
169
+ while loopingToActiveGapCeiling(state):
170
+ state = filterCommonGaps(state)
171
+ state = incrementIndexMiniGap(state)
172
+ while noGapsHere(state):
173
+ state = backtrack(state)
174
+ if thereIsAnActiveLeaf(state):
175
+ state = placeLeaf(state)
176
+ state.foldGroups[state.taskIndex] = state.groupsOfFolds
177
+ return state
178
+
179
+ def countSequential(state: ComputationState) -> ComputationState:
180
+ while activeLeafGreaterThan0(state):
181
+ if activeLeafIsTheFirstLeaf(state) or leafBelowSentinelIs1(state):
182
+ if activeLeafGreaterThanLeavesTotal(state):
183
+ state.groupsOfFolds += 1
198
184
  else:
199
- initializeVariablesToFindGaps(my=my, track=track)
200
- while loopUpToDimensionsTotal(my=my):
201
- initializeLeafConnectee(connectionGraph=connectionGraph, my=my)
202
- if activeLeafConnectedToItself(my=my):
203
- decrementDimensionsUnconstrained(my=my)
185
+ state = initializeVariablesToFindGaps(state)
186
+ while loopUpToDimensionsTotal(state):
187
+ state = initializeLeafConnectee(state)
188
+ if activeLeafConnectedToItself(state):
189
+ state = decrementDimensionsUnconstrained(state)
204
190
  else:
205
- while loopingLeavesConnectedToActiveLeaf(my=my):
206
- countGaps(gapsWhere=gapsWhere, my=my, track=track)
207
- updateLeafConnectee(connectionGraph=connectionGraph, my=my, track=track)
208
- incrementIndexDimension(my=my)
209
- initializeIndexMiniGap(my=my)
210
- while loopingToActiveGapCeiling(my=my):
211
- filterCommonGaps(gapsWhere=gapsWhere, my=my, track=track)
212
- incrementIndexMiniGap(my=my)
213
- while noGapsHere(my=my, track=track):
214
- backtrack(my=my, track=track)
215
- if thereIsAnActiveLeaf(my=my):
216
- placeLeaf(gapsWhere=gapsWhere, my=my, track=track)
217
- foldGroups[my[indexMy.taskIndex.value]] = groupsOfFolds
218
-
219
- def doTheNeedful(connectionGraph: ndarray[tuple[int, int, int], dtype[integer[Any]]]
220
- , foldGroups: ndarray[tuple[int] , dtype[integer[Any]]]
221
- , gapsWhere: ndarray[tuple[int] , dtype[integer[Any]]]
222
- , mapShape: ndarray[tuple[int] , dtype[integer[Any]]]
223
- , my: ndarray[tuple[int] , dtype[integer[Any]]]
224
- , track: ndarray[tuple[int, int] , dtype[integer[Any]]]
225
- ) -> None:
226
-
227
- countInitialize(connectionGraph, gapsWhere, my, track)
228
-
229
- if my[indexMy.taskDivisions.value] > 0:
230
- countParallel(connectionGraph, foldGroups, gapsWhere, my, track)
191
+ while loopingLeavesConnectedToActiveLeaf(state):
192
+ state = countGaps(state)
193
+ state = updateLeafConnectee(state)
194
+ state = incrementIndexDimension(state)
195
+ state = initializeIndexMiniGap(state)
196
+ while loopingToActiveGapCeiling(state):
197
+ state = filterCommonGaps(state)
198
+ state = incrementIndexMiniGap(state)
199
+ while noGapsHere(state):
200
+ state = backtrack(state)
201
+ if thereIsAnActiveLeaf(state):
202
+ state = placeLeaf(state)
203
+ state.foldGroups[state.taskIndex] = state.groupsOfFolds
204
+ return state
205
+
206
+ def doTheNeedful(state: ComputationState) -> ComputationState:
207
+ state = countInitialize(state)
208
+ if state.taskDivisions > 0:
209
+ dictionaryConcurrency: dict[int, concurrent.futures.Future[ComputationState]] = {}
210
+ with ProcessPoolExecutor(state.concurrencyLimit) as concurrencyManager:
211
+ for indexSherpa in range(state.taskDivisions):
212
+ stateParallel = copy.deepcopy(state)
213
+ stateParallel.taskIndex = indexSherpa
214
+ dictionaryConcurrency[indexSherpa] = concurrencyManager.submit(countParallel, stateParallel)
215
+ for indexSherpa in range(state.taskDivisions):
216
+ state.foldGroups[indexSherpa] = dictionaryConcurrency[indexSherpa].result().foldGroups[indexSherpa]
217
+ return state
231
218
  else:
232
- countSequential(connectionGraph, foldGroups, gapsWhere, my, track)
219
+ return countSequential(state)