mapFolding 0.16.2__py3-none-any.whl → 0.16.4__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 (66) hide show
  1. easyRun/NOTcountingFolds.py +6 -5
  2. easyRun/countFolds.py +1 -1
  3. easyRun/generateAllModules.py +14 -0
  4. easyRun/meanders.py +1 -1
  5. mapFolding/__init__.py +1 -0
  6. mapFolding/_theSSOT.py +3 -2
  7. mapFolding/_theTypes.py +3 -0
  8. mapFolding/algorithms/A086345.py +75 -0
  9. mapFolding/algorithms/oeisIDbyFormula.py +2 -2
  10. mapFolding/algorithms/symmetricFolds.py +36 -0
  11. mapFolding/basecamp.py +80 -149
  12. mapFolding/dataBaskets.py +123 -5
  13. mapFolding/filesystemToolkit.py +4 -32
  14. mapFolding/oeis.py +5 -12
  15. mapFolding/reference/A086345Wu.py +25 -0
  16. mapFolding/reference/matrixMeandersAnalysis/signatures.py +3 -0
  17. mapFolding/someAssemblyRequired/A007822/A007822rawMaterials.py +10 -45
  18. mapFolding/someAssemblyRequired/A007822/_asynchronousAnnex.py +51 -0
  19. mapFolding/someAssemblyRequired/A007822/makeA007822AsynchronousModules.py +36 -195
  20. mapFolding/someAssemblyRequired/A007822/makeA007822Modules.py +42 -44
  21. mapFolding/someAssemblyRequired/RecipeJob.py +78 -18
  22. mapFolding/someAssemblyRequired/__init__.py +3 -8
  23. mapFolding/someAssemblyRequired/_toolkitContainers.py +32 -3
  24. mapFolding/someAssemblyRequired/infoBooth.py +40 -23
  25. mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +74 -153
  26. mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +56 -88
  27. mapFolding/someAssemblyRequired/makingModules_count.py +10 -12
  28. mapFolding/someAssemblyRequired/makingModules_doTheNeedful.py +6 -68
  29. mapFolding/someAssemblyRequired/{mapFolding → mapFoldingModules}/makeMapFoldingModules.py +24 -30
  30. mapFolding/someAssemblyRequired/meanders/makeMeandersModules.py +8 -6
  31. mapFolding/someAssemblyRequired/toolkitMakeModules.py +2 -2
  32. mapFolding/someAssemblyRequired/toolkitNumba.py +1 -1
  33. mapFolding/someAssemblyRequired/transformationTools.py +10 -12
  34. mapFolding/syntheticModules/A007822/algorithm.py +45 -50
  35. mapFolding/syntheticModules/A007822/asynchronous.py +91 -34
  36. mapFolding/syntheticModules/A007822/initializeState.py +15 -21
  37. mapFolding/syntheticModules/A007822/theorem2.py +16 -22
  38. mapFolding/syntheticModules/A007822/theorem2Numba.py +20 -26
  39. mapFolding/syntheticModules/A007822/theorem2Trimmed.py +17 -23
  40. mapFolding/syntheticModules/countParallelNumba.py +3 -7
  41. mapFolding/syntheticModules/daoOfMapFoldingNumba.py +1 -2
  42. mapFolding/syntheticModules/meanders/bigInt.py +9 -9
  43. mapFolding/syntheticModules/theorem2Numba.py +28 -9
  44. mapFolding/syntheticModules/theorem2Trimmed.py +1 -1
  45. mapFolding/tests/test_computations.py +1 -1
  46. {mapfolding-0.16.2.dist-info → mapfolding-0.16.4.dist-info}/METADATA +4 -1
  47. {mapfolding-0.16.2.dist-info → mapfolding-0.16.4.dist-info}/RECORD +52 -61
  48. mapFolding/_dataPacking.py +0 -68
  49. mapFolding/reference/meandersDumpingGround/A005316intOptimized.py +0 -122
  50. mapFolding/reference/meandersDumpingGround/A005316optimized128bit.py +0 -79
  51. mapFolding/reference/meandersDumpingGround/matrixMeandersBaseline.py +0 -65
  52. mapFolding/reference/meandersDumpingGround/matrixMeandersBaselineAnnex.py +0 -84
  53. mapFolding/reference/meandersDumpingGround/matrixMeandersSimpleQueue.py +0 -90
  54. mapFolding/syntheticModules/A007822/algorithmNumba.py +0 -94
  55. mapFolding/syntheticModules/A007822/asynchronousAnnex.py +0 -66
  56. mapFolding/syntheticModules/A007822/asynchronousAnnexNumba.py +0 -70
  57. mapFolding/syntheticModules/A007822/asynchronousNumba.py +0 -79
  58. mapFolding/syntheticModules/A007822/asynchronousTheorem2.py +0 -65
  59. mapFolding/syntheticModules/A007822/asynchronousTrimmed.py +0 -56
  60. mapFolding/syntheticModules/dataPacking.py +0 -26
  61. mapFolding/syntheticModules/dataPackingA007822.py +0 -92
  62. /mapFolding/someAssemblyRequired/{mapFolding → mapFoldingModules}/__init__.py +0 -0
  63. {mapfolding-0.16.2.dist-info → mapfolding-0.16.4.dist-info}/WHEEL +0 -0
  64. {mapfolding-0.16.2.dist-info → mapfolding-0.16.4.dist-info}/entry_points.txt +0 -0
  65. {mapfolding-0.16.2.dist-info → mapfolding-0.16.4.dist-info}/licenses/LICENSE +0 -0
  66. {mapfolding-0.16.2.dist-info → mapfolding-0.16.4.dist-info}/top_level.txt +0 -0
@@ -281,7 +281,7 @@ def decorateCallableWithNumba(ingredientsFunction: IngredientsFunction, paramete
281
281
  return ingredientsFunction
282
282
 
283
283
  @dataclasses.dataclass
284
- class SpicesJobNumba:
284
+ class SpicesJobNumba: # slots?
285
285
  """Configuration container for Numba-specific job processing options.
286
286
 
287
287
  (AI generated docstring)
@@ -79,10 +79,10 @@ def shatter_dataclassesDOTdataclass(logicalPathDataclass: identifierDotAttribute
79
79
 
80
80
  dataclassClassDef: ast.ClassDef | None = extractClassDef(parseLogicalPath2astModule(logicalPathDataclass), identifierDataclass)
81
81
  if not dataclassClassDef:
82
- message = f"I could not find `{identifierDataclass = }` in `{logicalPathDataclass = }`."
82
+ message: str = f"I could not find `{identifierDataclass = }` in `{logicalPathDataclass = }`."
83
83
  raise ValueError(message)
84
84
 
85
- countingVariable = None
85
+ countingVariable: str | None = None
86
86
  for aField in dataclasses.fields(importLogicalPath2Identifier(logicalPathDataclass, identifierDataclass)): # pyright: ignore [reportArgumentType]
87
87
  Official_fieldOrder.append(aField.name)
88
88
  dictionaryDeReConstruction[aField.name] = DeReConstructField2ast(logicalPathDataclass, dataclassClassDef, identifierDataclassInstance, aField)
@@ -99,6 +99,7 @@ def shatter_dataclassesDOTdataclass(logicalPathDataclass: identifierDotAttribute
99
99
  Z0Z_field2AnnAssign={dictionaryDeReConstruction[field].name: dictionaryDeReConstruction[field].Z0Z_hack for field in Official_fieldOrder},
100
100
  list_argAnnotated4ArgumentsSpecification=[dictionaryDeReConstruction[field].ast_argAnnotated for field in Official_fieldOrder],
101
101
  list_keyword_field__field4init=[dictionaryDeReConstruction[field].ast_keyword_field__field for field in Official_fieldOrder if dictionaryDeReConstruction[field].init],
102
+ listIdentifiersStaticScalars=[dictionaryDeReConstruction[field].name for field in Official_fieldOrder if (dictionaryDeReConstruction[field].Z0Z_hack[1] == 'scalar' and not dictionaryDeReConstruction[field].init)],
102
103
  listAnnotations=[dictionaryDeReConstruction[field].astAnnotation for field in Official_fieldOrder],
103
104
  listName4Parameters=[dictionaryDeReConstruction[field].astName for field in Official_fieldOrder],
104
105
  listUnpack=[Make.AnnAssign(dictionaryDeReConstruction[field].astName, dictionaryDeReConstruction[field].astAnnotation, dictionaryDeReConstruction[field].ast_nameDOTname) for field in Official_fieldOrder],
@@ -145,12 +146,11 @@ def removeDataclassFromFunction(ingredientsTarget: IngredientsFunction, shattere
145
146
  """
146
147
  ingredientsTarget.astFunctionDef.args = Make.arguments(list_arg=shatteredDataclass.list_argAnnotated4ArgumentsSpecification)
147
148
  ingredientsTarget.astFunctionDef.returns = shatteredDataclass.signatureReturnAnnotation
148
- changeReturnCallable = NodeChanger(Be.Return, Then.replaceWith(Make.Return(shatteredDataclass.fragments4AssignmentOrParameters)))
149
- changeReturnCallable.visit(ingredientsTarget.astFunctionDef)
149
+ NodeChanger(Be.Return, Then.replaceWith(Make.Return(shatteredDataclass.fragments4AssignmentOrParameters))).visit(ingredientsTarget.astFunctionDef)
150
150
  ingredientsTarget.astFunctionDef = unparseFindReplace(ingredientsTarget.astFunctionDef, shatteredDataclass.map_stateDOTfield2Name)
151
151
  return ingredientsTarget
152
152
 
153
- def unpackDataclassCallFunctionRepackDataclass(ingredientsCaller: IngredientsFunction, targetCallableIdentifier: str, shatteredDataclass: ShatteredDataclass) -> IngredientsFunction:
153
+ def unpackDataclassCallFunctionRepackDataclass(ingredientsCaller: IngredientsFunction, identifierCallee: str, shatteredDataclass: ShatteredDataclass) -> IngredientsFunction:
154
154
  """Transform a caller function to interface with a dataclass-free target function.
155
155
 
156
156
  (AI generated docstring)
@@ -184,12 +184,10 @@ def unpackDataclassCallFunctionRepackDataclass(ingredientsCaller: IngredientsFun
184
184
  The modified caller function with appropriate unpacking and repacking around the target call.
185
185
 
186
186
  """
187
- astCallTargetCallable = Make.Call(Make.Name(targetCallableIdentifier), shatteredDataclass.listName4Parameters)
188
- replaceAssignTargetCallable = NodeChanger(Be.Assign.valueIs(IfThis.isCallIdentifier(targetCallableIdentifier)), Then.replaceWith(Make.Assign([shatteredDataclass.fragments4AssignmentOrParameters], value=astCallTargetCallable)))
189
- unpack4targetCallable = NodeChanger(Be.Assign.valueIs(IfThis.isCallIdentifier(targetCallableIdentifier)), Then.insertThisAbove(shatteredDataclass.listUnpack))
190
- repack4targetCallable = NodeChanger(Be.Assign.valueIs(IfThis.isCallIdentifier(targetCallableIdentifier)), Then.insertThisBelow([shatteredDataclass.repack]))
191
- replaceAssignTargetCallable.visit(ingredientsCaller.astFunctionDef)
192
- unpack4targetCallable.visit(ingredientsCaller.astFunctionDef)
193
- repack4targetCallable.visit(ingredientsCaller.astFunctionDef)
187
+ AssignAndCall: ast.Assign = Make.Assign([shatteredDataclass.fragments4AssignmentOrParameters], value=Make.Call(Make.Name(identifierCallee), shatteredDataclass.listName4Parameters))
188
+ NodeChanger(Be.Assign.valueIs(IfThis.isCallIdentifier(identifierCallee)), Then.replaceWith(AssignAndCall)).visit(ingredientsCaller.astFunctionDef)
189
+ NodeChanger(Be.Assign.valueIs(IfThis.isCallIdentifier(identifierCallee)), Then.insertThisAbove(shatteredDataclass.listUnpack)).visit(ingredientsCaller.astFunctionDef)
190
+ NodeChanger(Be.Assign.valueIs(IfThis.isCallIdentifier(identifierCallee)), Then.insertThisBelow([shatteredDataclass.repack])).visit(ingredientsCaller.astFunctionDef)
194
191
  return ingredientsCaller
195
192
 
193
+
@@ -1,77 +1,72 @@
1
- from mapFolding.dataBaskets import MapFoldingState
1
+ import numpy
2
2
 
3
+ from mapFolding.dataBaskets import SymmetricFoldsState
3
4
 
4
- def filterAsymmetricFolds(state: MapFoldingState) -> MapFoldingState:
5
- state.indexLeaf = 0
6
- leafConnectee = 0
7
- while leafConnectee < state.leavesTotal + 1:
8
- leafNumber = int(state.leafBelow[state.indexLeaf])
9
- state.leafComparison[leafConnectee] = (leafNumber - state.indexLeaf + state.leavesTotal) % state.leavesTotal
10
- state.indexLeaf = leafNumber
11
- leafConnectee += 1
12
- indexInMiddle = state.leavesTotal // 2
13
- state.indexMiniGap = 0
14
- while state.indexMiniGap < state.leavesTotal + 1:
15
- ImaSymmetricFold = True
16
- leafConnectee = 0
17
- while leafConnectee < indexInMiddle:
18
- if state.leafComparison[(state.indexMiniGap + leafConnectee) % (state.leavesTotal + 1)] != state.leafComparison[(state.indexMiniGap + state.leavesTotal - 1 - leafConnectee) % (state.leavesTotal + 1)]:
19
- ImaSymmetricFold = False
20
- break
21
- leafConnectee += 1
22
- state.groupsOfFolds += ImaSymmetricFold
23
- state.indexMiniGap += 1
24
- return state
25
-
26
- def activeLeafGreaterThan0(state: MapFoldingState) -> bool:
5
+
6
+ def filterAsymmetricFolds(state: SymmetricFoldsState) -> SymmetricFoldsState:
7
+ state.indexLeaf = 1
8
+ state.leafComparison[0] = 1
9
+ state.leafConnectee = 1
10
+ while state.leafConnectee < state.leavesTotal + 1:
11
+ state.indexMiniGap = state.leafBelow[state.indexLeaf]
12
+ state.leafComparison[state.leafConnectee] = (state.indexMiniGap - state.indexLeaf + state.leavesTotal) % state.leavesTotal
13
+ state.indexLeaf = state.indexMiniGap
14
+ state.leafConnectee += 1
15
+ state.arrayGroupOfFolds = numpy.take(state.leafComparison, state.indicesArrayGroupOfFolds)
16
+ compared = state.arrayGroupOfFolds[..., 0:state.leavesTotal // 2] == state.arrayGroupOfFolds[..., state.leavesTotal // 2:None]
17
+ for indexRow in range(len(compared)):
18
+ state.groupsOfFolds += compared[indexRow].all()
19
+ return state
20
+
21
+ def activeLeafGreaterThan0(state: SymmetricFoldsState) -> bool:
27
22
  return state.leaf1ndex > 0
28
23
 
29
- def activeLeafGreaterThanLeavesTotal(state: MapFoldingState) -> bool:
24
+ def activeLeafGreaterThanLeavesTotal(state: SymmetricFoldsState) -> bool:
30
25
  return state.leaf1ndex > state.leavesTotal
31
26
 
32
- def activeLeafIsTheFirstLeaf(state: MapFoldingState) -> bool:
27
+ def activeLeafIsTheFirstLeaf(state: SymmetricFoldsState) -> bool:
33
28
  return state.leaf1ndex <= 1
34
29
 
35
- def activeLeafIsUnconstrainedInAllDimensions(state: MapFoldingState) -> bool:
30
+ def activeLeafIsUnconstrainedInAllDimensions(state: SymmetricFoldsState) -> bool:
36
31
  return not state.dimensionsUnconstrained
37
32
 
38
- def activeLeafUnconstrainedInThisDimension(state: MapFoldingState) -> MapFoldingState:
33
+ def activeLeafUnconstrainedInThisDimension(state: SymmetricFoldsState) -> SymmetricFoldsState:
39
34
  state.dimensionsUnconstrained -= 1
40
35
  return state
41
36
 
42
- def filterCommonGaps(state: MapFoldingState) -> MapFoldingState:
37
+ def filterCommonGaps(state: SymmetricFoldsState) -> SymmetricFoldsState:
43
38
  state.gapsWhere[state.gap1ndex] = state.gapsWhere[state.indexMiniGap]
44
39
  if state.countDimensionsGapped[state.gapsWhere[state.indexMiniGap]] == state.dimensionsUnconstrained:
45
40
  state = incrementActiveGap(state)
46
41
  state.countDimensionsGapped[state.gapsWhere[state.indexMiniGap]] = 0
47
42
  return state
48
43
 
49
- def gapAvailable(state: MapFoldingState) -> bool:
44
+ def gapAvailable(state: SymmetricFoldsState) -> bool:
50
45
  return state.leaf1ndex > 0
51
46
 
52
- def incrementActiveGap(state: MapFoldingState) -> MapFoldingState:
47
+ def incrementActiveGap(state: SymmetricFoldsState) -> SymmetricFoldsState:
53
48
  state.gap1ndex += 1
54
49
  return state
55
50
 
56
- def incrementGap1ndexCeiling(state: MapFoldingState) -> MapFoldingState:
51
+ def incrementGap1ndexCeiling(state: SymmetricFoldsState) -> SymmetricFoldsState:
57
52
  state.gap1ndexCeiling += 1
58
53
  return state
59
54
 
60
- def incrementIndexMiniGap(state: MapFoldingState) -> MapFoldingState:
55
+ def incrementIndexMiniGap(state: SymmetricFoldsState) -> SymmetricFoldsState:
61
56
  state.indexMiniGap += 1
62
57
  return state
63
58
 
64
- def initializeIndexMiniGap(state: MapFoldingState) -> MapFoldingState:
59
+ def initializeIndexMiniGap(state: SymmetricFoldsState) -> SymmetricFoldsState:
65
60
  state.indexMiniGap = state.gap1ndex
66
61
  return state
67
62
 
68
- def initializeVariablesToFindGaps(state: MapFoldingState) -> MapFoldingState:
63
+ def initializeVariablesToFindGaps(state: SymmetricFoldsState) -> SymmetricFoldsState:
69
64
  state.dimensionsUnconstrained = state.dimensionsTotal
70
65
  state.gap1ndexCeiling = state.gapRangeStart[state.leaf1ndex - 1]
71
66
  state.indexDimension = 0
72
67
  return state
73
68
 
74
- def insertActiveLeaf(state: MapFoldingState) -> MapFoldingState:
69
+ def insertActiveLeaf(state: SymmetricFoldsState) -> SymmetricFoldsState:
75
70
  state.indexLeaf = 0
76
71
  while state.indexLeaf < state.leaf1ndex:
77
72
  state.gapsWhere[state.gap1ndexCeiling] = state.indexLeaf
@@ -79,7 +74,7 @@ def insertActiveLeaf(state: MapFoldingState) -> MapFoldingState:
79
74
  state.indexLeaf += 1
80
75
  return state
81
76
 
82
- def insertActiveLeafAtGap(state: MapFoldingState) -> MapFoldingState:
77
+ def insertActiveLeafAtGap(state: SymmetricFoldsState) -> SymmetricFoldsState:
83
78
  state.gap1ndex -= 1
84
79
  state.leafAbove[state.leaf1ndex] = state.gapsWhere[state.gap1ndex]
85
80
  state.leafBelow[state.leaf1ndex] = state.leafBelow[state.leafAbove[state.leaf1ndex]]
@@ -89,50 +84,50 @@ def insertActiveLeafAtGap(state: MapFoldingState) -> MapFoldingState:
89
84
  state.leaf1ndex += 1
90
85
  return state
91
86
 
92
- def leafBelowSentinelIs1(state: MapFoldingState) -> bool:
87
+ def leafBelowSentinelIs1(state: SymmetricFoldsState) -> bool:
93
88
  return state.leafBelow[0] == 1
94
89
 
95
- def leafConnecteeIsActiveLeaf(state: MapFoldingState) -> bool:
90
+ def leafConnecteeIsActiveLeaf(state: SymmetricFoldsState) -> bool:
96
91
  return state.leafConnectee == state.leaf1ndex
97
92
 
98
- def lookForGaps(state: MapFoldingState) -> MapFoldingState:
93
+ def lookForGaps(state: SymmetricFoldsState) -> SymmetricFoldsState:
99
94
  state.gapsWhere[state.gap1ndexCeiling] = state.leafConnectee
100
95
  if state.countDimensionsGapped[state.leafConnectee] == 0:
101
96
  state = incrementGap1ndexCeiling(state)
102
97
  state.countDimensionsGapped[state.leafConnectee] += 1
103
98
  return state
104
99
 
105
- def lookupLeafConnecteeInConnectionGraph(state: MapFoldingState) -> MapFoldingState:
100
+ def lookupLeafConnecteeInConnectionGraph(state: SymmetricFoldsState) -> SymmetricFoldsState:
106
101
  state.leafConnectee = state.connectionGraph[state.indexDimension, state.leaf1ndex, state.leaf1ndex]
107
102
  return state
108
103
 
109
- def loopingLeavesConnectedToActiveLeaf(state: MapFoldingState) -> bool:
104
+ def loopingLeavesConnectedToActiveLeaf(state: SymmetricFoldsState) -> bool:
110
105
  return state.leafConnectee != state.leaf1ndex
111
106
 
112
- def loopingThroughTheDimensions(state: MapFoldingState) -> bool:
107
+ def loopingThroughTheDimensions(state: SymmetricFoldsState) -> bool:
113
108
  return state.indexDimension < state.dimensionsTotal
114
109
 
115
- def loopingToActiveGapCeiling(state: MapFoldingState) -> bool:
110
+ def loopingToActiveGapCeiling(state: SymmetricFoldsState) -> bool:
116
111
  return state.indexMiniGap < state.gap1ndexCeiling
117
112
 
118
- def noGapsHere(state: MapFoldingState) -> bool:
113
+ def noGapsHere(state: SymmetricFoldsState) -> bool:
119
114
  return state.leaf1ndex > 0 and state.gap1ndex == state.gapRangeStart[state.leaf1ndex - 1]
120
115
 
121
- def tryAnotherLeafConnectee(state: MapFoldingState) -> MapFoldingState:
116
+ def tryAnotherLeafConnectee(state: SymmetricFoldsState) -> SymmetricFoldsState:
122
117
  state.leafConnectee = state.connectionGraph[state.indexDimension, state.leaf1ndex, state.leafBelow[state.leafConnectee]]
123
118
  return state
124
119
 
125
- def tryNextDimension(state: MapFoldingState) -> MapFoldingState:
120
+ def tryNextDimension(state: SymmetricFoldsState) -> SymmetricFoldsState:
126
121
  state.indexDimension += 1
127
122
  return state
128
123
 
129
- def undoLastLeafPlacement(state: MapFoldingState) -> MapFoldingState:
124
+ def undoLastLeafPlacement(state: SymmetricFoldsState) -> SymmetricFoldsState:
130
125
  state.leaf1ndex -= 1
131
126
  state.leafBelow[state.leafAbove[state.leaf1ndex]] = state.leafBelow[state.leaf1ndex]
132
127
  state.leafAbove[state.leafBelow[state.leaf1ndex]] = state.leafAbove[state.leaf1ndex]
133
128
  return state
134
129
 
135
- def count(state: MapFoldingState) -> MapFoldingState:
130
+ def count(state: SymmetricFoldsState) -> SymmetricFoldsState:
136
131
  while activeLeafGreaterThan0(state):
137
132
  if activeLeafIsTheFirstLeaf(state) or leafBelowSentinelIs1(state):
138
133
  if activeLeafGreaterThanLeavesTotal(state):
@@ -161,6 +156,6 @@ def count(state: MapFoldingState) -> MapFoldingState:
161
156
  state.groupsOfFolds = (state.groupsOfFolds + 1) // 2
162
157
  return state
163
158
 
164
- def doTheNeedful(state: MapFoldingState) -> MapFoldingState:
159
+ def doTheNeedful(state: SymmetricFoldsState) -> SymmetricFoldsState:
165
160
  state = count(state)
166
161
  return state
@@ -1,58 +1,115 @@
1
- from mapFolding.dataBaskets import MapFoldingState
2
- from mapFolding.syntheticModules.A007822.asynchronousAnnex import (
3
- filterAsymmetricFolds, getSymmetricFoldsTotal,
4
- initializeConcurrencyManager)
5
-
6
-
7
- def activeLeafGreaterThan0(state: MapFoldingState) -> bool:
1
+ from copy import deepcopy
2
+ from queue import Queue
3
+ from threading import Lock, Thread
4
+
5
+ import numpy
6
+
7
+ from mapFolding import DatatypeFoldsTotal
8
+ from mapFolding.dataBaskets import SymmetricFoldsState
9
+
10
+ listThreads: list[Thread] = []
11
+ queueFutures: Queue[SymmetricFoldsState] = Queue()
12
+ symmetricFoldsTotal: int = 0
13
+ LOCKsymmetricFoldsTotal = Lock()
14
+ STOPsignal = object()
15
+
16
+ def initializeConcurrencyManager(maxWorkers: int, symmetricFolds: int=0) -> None:
17
+ global listThreads, symmetricFoldsTotal, queueFutures
18
+ listThreads = []
19
+ queueFutures = Queue()
20
+ symmetricFoldsTotal = symmetricFolds
21
+ indexThread = 0
22
+ while indexThread < maxWorkers:
23
+ thread = Thread(target=_threadDoesSomething, name=f'thread{indexThread}', daemon=True)
24
+ thread.start()
25
+ listThreads.append(thread)
26
+ indexThread += 1
27
+
28
+ def _threadDoesSomething() -> None:
29
+ global symmetricFoldsTotal
30
+ while True:
31
+ state = queueFutures.get()
32
+ if state is STOPsignal:
33
+ break
34
+ state = _filterAsymmetricFolds(state)
35
+ with LOCKsymmetricFoldsTotal:
36
+ symmetricFoldsTotal += state.groupsOfFolds
37
+
38
+ def filterAsymmetricFolds(state: SymmetricFoldsState) -> None:
39
+ queueFutures.put_nowait(deepcopy(state))
40
+
41
+ def getSymmetricFoldsTotal() -> DatatypeFoldsTotal:
42
+ for _thread in listThreads:
43
+ queueFutures.put(STOPsignal)
44
+ for thread in listThreads:
45
+ thread.join()
46
+ return symmetricFoldsTotal
47
+
48
+ def _filterAsymmetricFolds(state: SymmetricFoldsState) -> SymmetricFoldsState:
49
+ state.indexLeaf = 1
50
+ state.leafComparison[0] = 1
51
+ state.leafConnectee = 1
52
+ while state.leafConnectee < state.leavesTotal + 1:
53
+ state.indexMiniGap = state.leafBelow[state.indexLeaf]
54
+ state.leafComparison[state.leafConnectee] = (state.indexMiniGap - state.indexLeaf + state.leavesTotal) % state.leavesTotal
55
+ state.indexLeaf = state.indexMiniGap
56
+ state.leafConnectee += 1
57
+ state.arrayGroupOfFolds = numpy.take(state.leafComparison, state.indicesArrayGroupOfFolds)
58
+ state.indexMiniGap = 0
59
+ while state.indexMiniGap < len(state.arrayGroupOfFolds):
60
+ state.groupsOfFolds += int(numpy.all(numpy.equal(state.arrayGroupOfFolds[state.indexMiniGap, slice(0, state.leavesTotal // 2)], state.arrayGroupOfFolds[state.indexMiniGap, slice(state.leavesTotal // 2, None)])))
61
+ state.indexMiniGap += 1
62
+ return state
63
+
64
+ def activeLeafGreaterThan0(state: SymmetricFoldsState) -> bool:
8
65
  return state.leaf1ndex > 0
9
66
 
10
- def activeLeafGreaterThanLeavesTotal(state: MapFoldingState) -> bool:
67
+ def activeLeafGreaterThanLeavesTotal(state: SymmetricFoldsState) -> bool:
11
68
  return state.leaf1ndex > state.leavesTotal
12
69
 
13
- def activeLeafIsTheFirstLeaf(state: MapFoldingState) -> bool:
70
+ def activeLeafIsTheFirstLeaf(state: SymmetricFoldsState) -> bool:
14
71
  return state.leaf1ndex <= 1
15
72
 
16
- def activeLeafIsUnconstrainedInAllDimensions(state: MapFoldingState) -> bool:
73
+ def activeLeafIsUnconstrainedInAllDimensions(state: SymmetricFoldsState) -> bool:
17
74
  return not state.dimensionsUnconstrained
18
75
 
19
- def activeLeafUnconstrainedInThisDimension(state: MapFoldingState) -> MapFoldingState:
76
+ def activeLeafUnconstrainedInThisDimension(state: SymmetricFoldsState) -> SymmetricFoldsState:
20
77
  state.dimensionsUnconstrained -= 1
21
78
  return state
22
79
 
23
- def filterCommonGaps(state: MapFoldingState) -> MapFoldingState:
80
+ def filterCommonGaps(state: SymmetricFoldsState) -> SymmetricFoldsState:
24
81
  state.gapsWhere[state.gap1ndex] = state.gapsWhere[state.indexMiniGap]
25
82
  if state.countDimensionsGapped[state.gapsWhere[state.indexMiniGap]] == state.dimensionsUnconstrained:
26
83
  state = incrementActiveGap(state)
27
84
  state.countDimensionsGapped[state.gapsWhere[state.indexMiniGap]] = 0
28
85
  return state
29
86
 
30
- def gapAvailable(state: MapFoldingState) -> bool:
87
+ def gapAvailable(state: SymmetricFoldsState) -> bool:
31
88
  return state.leaf1ndex > 0
32
89
 
33
- def incrementActiveGap(state: MapFoldingState) -> MapFoldingState:
90
+ def incrementActiveGap(state: SymmetricFoldsState) -> SymmetricFoldsState:
34
91
  state.gap1ndex += 1
35
92
  return state
36
93
 
37
- def incrementGap1ndexCeiling(state: MapFoldingState) -> MapFoldingState:
94
+ def incrementGap1ndexCeiling(state: SymmetricFoldsState) -> SymmetricFoldsState:
38
95
  state.gap1ndexCeiling += 1
39
96
  return state
40
97
 
41
- def incrementIndexMiniGap(state: MapFoldingState) -> MapFoldingState:
98
+ def incrementIndexMiniGap(state: SymmetricFoldsState) -> SymmetricFoldsState:
42
99
  state.indexMiniGap += 1
43
100
  return state
44
101
 
45
- def initializeIndexMiniGap(state: MapFoldingState) -> MapFoldingState:
102
+ def initializeIndexMiniGap(state: SymmetricFoldsState) -> SymmetricFoldsState:
46
103
  state.indexMiniGap = state.gap1ndex
47
104
  return state
48
105
 
49
- def initializeVariablesToFindGaps(state: MapFoldingState) -> MapFoldingState:
106
+ def initializeVariablesToFindGaps(state: SymmetricFoldsState) -> SymmetricFoldsState:
50
107
  state.dimensionsUnconstrained = state.dimensionsTotal
51
108
  state.gap1ndexCeiling = state.gapRangeStart[state.leaf1ndex - 1]
52
109
  state.indexDimension = 0
53
110
  return state
54
111
 
55
- def insertActiveLeaf(state: MapFoldingState) -> MapFoldingState:
112
+ def insertActiveLeaf(state: SymmetricFoldsState) -> SymmetricFoldsState:
56
113
  state.indexLeaf = 0
57
114
  while state.indexLeaf < state.leaf1ndex:
58
115
  state.gapsWhere[state.gap1ndexCeiling] = state.indexLeaf
@@ -60,7 +117,7 @@ def insertActiveLeaf(state: MapFoldingState) -> MapFoldingState:
60
117
  state.indexLeaf += 1
61
118
  return state
62
119
 
63
- def insertActiveLeafAtGap(state: MapFoldingState) -> MapFoldingState:
120
+ def insertActiveLeafAtGap(state: SymmetricFoldsState) -> SymmetricFoldsState:
64
121
  state.gap1ndex -= 1
65
122
  state.leafAbove[state.leaf1ndex] = state.gapsWhere[state.gap1ndex]
66
123
  state.leafBelow[state.leaf1ndex] = state.leafBelow[state.leafAbove[state.leaf1ndex]]
@@ -70,54 +127,54 @@ def insertActiveLeafAtGap(state: MapFoldingState) -> MapFoldingState:
70
127
  state.leaf1ndex += 1
71
128
  return state
72
129
 
73
- def leafBelowSentinelIs1(state: MapFoldingState) -> bool:
130
+ def leafBelowSentinelIs1(state: SymmetricFoldsState) -> bool:
74
131
  return state.leafBelow[0] == 1
75
132
 
76
- def leafConnecteeIsActiveLeaf(state: MapFoldingState) -> bool:
133
+ def leafConnecteeIsActiveLeaf(state: SymmetricFoldsState) -> bool:
77
134
  return state.leafConnectee == state.leaf1ndex
78
135
 
79
- def lookForGaps(state: MapFoldingState) -> MapFoldingState:
136
+ def lookForGaps(state: SymmetricFoldsState) -> SymmetricFoldsState:
80
137
  state.gapsWhere[state.gap1ndexCeiling] = state.leafConnectee
81
138
  if state.countDimensionsGapped[state.leafConnectee] == 0:
82
139
  state = incrementGap1ndexCeiling(state)
83
140
  state.countDimensionsGapped[state.leafConnectee] += 1
84
141
  return state
85
142
 
86
- def lookupLeafConnecteeInConnectionGraph(state: MapFoldingState) -> MapFoldingState:
143
+ def lookupLeafConnecteeInConnectionGraph(state: SymmetricFoldsState) -> SymmetricFoldsState:
87
144
  state.leafConnectee = state.connectionGraph[state.indexDimension, state.leaf1ndex, state.leaf1ndex]
88
145
  return state
89
146
 
90
- def loopingLeavesConnectedToActiveLeaf(state: MapFoldingState) -> bool:
147
+ def loopingLeavesConnectedToActiveLeaf(state: SymmetricFoldsState) -> bool:
91
148
  return state.leafConnectee != state.leaf1ndex
92
149
 
93
- def loopingThroughTheDimensions(state: MapFoldingState) -> bool:
150
+ def loopingThroughTheDimensions(state: SymmetricFoldsState) -> bool:
94
151
  return state.indexDimension < state.dimensionsTotal
95
152
 
96
- def loopingToActiveGapCeiling(state: MapFoldingState) -> bool:
153
+ def loopingToActiveGapCeiling(state: SymmetricFoldsState) -> bool:
97
154
  return state.indexMiniGap < state.gap1ndexCeiling
98
155
 
99
- def noGapsHere(state: MapFoldingState) -> bool:
156
+ def noGapsHere(state: SymmetricFoldsState) -> bool:
100
157
  return state.leaf1ndex > 0 and state.gap1ndex == state.gapRangeStart[state.leaf1ndex - 1]
101
158
 
102
- def tryAnotherLeafConnectee(state: MapFoldingState) -> MapFoldingState:
159
+ def tryAnotherLeafConnectee(state: SymmetricFoldsState) -> SymmetricFoldsState:
103
160
  state.leafConnectee = state.connectionGraph[state.indexDimension, state.leaf1ndex, state.leafBelow[state.leafConnectee]]
104
161
  return state
105
162
 
106
- def tryNextDimension(state: MapFoldingState) -> MapFoldingState:
163
+ def tryNextDimension(state: SymmetricFoldsState) -> SymmetricFoldsState:
107
164
  state.indexDimension += 1
108
165
  return state
109
166
 
110
- def undoLastLeafPlacement(state: MapFoldingState) -> MapFoldingState:
167
+ def undoLastLeafPlacement(state: SymmetricFoldsState) -> SymmetricFoldsState:
111
168
  state.leaf1ndex -= 1
112
169
  state.leafBelow[state.leafAbove[state.leaf1ndex]] = state.leafBelow[state.leaf1ndex]
113
170
  state.leafAbove[state.leafBelow[state.leaf1ndex]] = state.leafAbove[state.leaf1ndex]
114
171
  return state
115
172
 
116
- def count(state: MapFoldingState) -> MapFoldingState:
173
+ def count(state: SymmetricFoldsState) -> SymmetricFoldsState:
117
174
  while activeLeafGreaterThan0(state):
118
175
  if activeLeafIsTheFirstLeaf(state) or leafBelowSentinelIs1(state):
119
176
  if activeLeafGreaterThanLeavesTotal(state):
120
- filterAsymmetricFolds(state.leafBelow)
177
+ filterAsymmetricFolds(state)
121
178
  else:
122
179
  state = initializeVariablesToFindGaps(state)
123
180
  while loopingThroughTheDimensions(state):
@@ -144,7 +201,7 @@ def count(state: MapFoldingState) -> MapFoldingState:
144
201
  state.groupsOfFolds = (state.groupsOfFolds + 1) // 2
145
202
  return state
146
203
 
147
- def doTheNeedful(state: MapFoldingState, maxWorkers: int | None=None) -> MapFoldingState:
204
+ def doTheNeedful(state: SymmetricFoldsState, maxWorkers: int) -> SymmetricFoldsState:
148
205
  initializeConcurrencyManager(maxWorkers)
149
206
  state = count(state)
150
207
  return state
@@ -1,28 +1,22 @@
1
- from mapFolding.dataBaskets import MapFoldingState
1
+ from mapFolding.dataBaskets import SymmetricFoldsState
2
+ import numpy
2
3
 
3
- def transitionOnGroupsOfFolds(state: MapFoldingState) -> MapFoldingState:
4
+ def transitionOnGroupsOfFolds(state: SymmetricFoldsState) -> SymmetricFoldsState:
4
5
  while state.groupsOfFolds == 0:
5
6
  if state.leaf1ndex <= 1 or state.leafBelow[0] == 1:
6
7
  if state.leaf1ndex > state.leavesTotal:
7
- state.indexLeaf = 0
8
- leafConnectee = 0
9
- while leafConnectee < state.leavesTotal + 1:
10
- leafNumber = int(state.leafBelow[state.indexLeaf])
11
- state.leafComparison[leafConnectee] = (leafNumber - state.indexLeaf + state.leavesTotal) % state.leavesTotal
12
- state.indexLeaf = leafNumber
13
- leafConnectee += 1
14
- indexInMiddle = state.leavesTotal // 2
15
- state.indexMiniGap = 0
16
- while state.indexMiniGap < state.leavesTotal + 1:
17
- ImaSymmetricFold = True
18
- leafConnectee = 0
19
- while leafConnectee < indexInMiddle:
20
- if state.leafComparison[(state.indexMiniGap + leafConnectee) % (state.leavesTotal + 1)] != state.leafComparison[(state.indexMiniGap + state.leavesTotal - 1 - leafConnectee) % (state.leavesTotal + 1)]:
21
- ImaSymmetricFold = False
22
- break
23
- leafConnectee += 1
24
- state.groupsOfFolds += ImaSymmetricFold
25
- state.indexMiniGap += 1
8
+ state.indexLeaf = 1
9
+ state.leafComparison[0] = 1
10
+ state.leafConnectee = 1
11
+ while state.leafConnectee < state.leavesTotal + 1:
12
+ state.indexMiniGap = state.leafBelow[state.indexLeaf]
13
+ state.leafComparison[state.leafConnectee] = (state.indexMiniGap - state.indexLeaf + state.leavesTotal) % state.leavesTotal
14
+ state.indexLeaf = state.indexMiniGap
15
+ state.leafConnectee += 1
16
+ state.arrayGroupOfFolds = numpy.take(state.leafComparison, state.indicesArrayGroupOfFolds)
17
+ compared = state.arrayGroupOfFolds[..., 0:state.leavesTotal // 2] == state.arrayGroupOfFolds[..., state.leavesTotal // 2:None]
18
+ for indexRow in range(len(compared)):
19
+ state.groupsOfFolds += compared[indexRow].all()
26
20
  else:
27
21
  state.dimensionsUnconstrained = state.dimensionsTotal
28
22
  state.gap1ndexCeiling = state.gapRangeStart[state.leaf1ndex - 1]
@@ -1,29 +1,23 @@
1
- from mapFolding.dataBaskets import MapFoldingState
1
+ from mapFolding.dataBaskets import SymmetricFoldsState
2
2
  from mapFolding.syntheticModules.A007822.initializeState import transitionOnGroupsOfFolds
3
+ import numpy
3
4
 
4
- def count(state: MapFoldingState) -> MapFoldingState:
5
+ def count(state: SymmetricFoldsState) -> SymmetricFoldsState:
5
6
  while state.leaf1ndex > 4:
6
7
  if state.leafBelow[0] == 1:
7
8
  if state.leaf1ndex > state.leavesTotal:
8
- state.indexLeaf = 0
9
- leafConnectee = 0
10
- while leafConnectee < state.leavesTotal + 1:
11
- leafNumber = int(state.leafBelow[state.indexLeaf])
12
- state.leafComparison[leafConnectee] = (leafNumber - state.indexLeaf + state.leavesTotal) % state.leavesTotal
13
- state.indexLeaf = leafNumber
14
- leafConnectee += 1
15
- indexInMiddle = state.leavesTotal // 2
16
- state.indexMiniGap = 0
17
- while state.indexMiniGap < state.leavesTotal + 1:
18
- ImaSymmetricFold = True
19
- leafConnectee = 0
20
- while leafConnectee < indexInMiddle:
21
- if state.leafComparison[(state.indexMiniGap + leafConnectee) % (state.leavesTotal + 1)] != state.leafComparison[(state.indexMiniGap + state.leavesTotal - 1 - leafConnectee) % (state.leavesTotal + 1)]:
22
- ImaSymmetricFold = False
23
- break
24
- leafConnectee += 1
25
- state.groupsOfFolds += ImaSymmetricFold
26
- state.indexMiniGap += 1
9
+ state.indexLeaf = 1
10
+ state.leafComparison[0] = 1
11
+ state.leafConnectee = 1
12
+ while state.leafConnectee < state.leavesTotal + 1:
13
+ state.indexMiniGap = state.leafBelow[state.indexLeaf]
14
+ state.leafComparison[state.leafConnectee] = (state.indexMiniGap - state.indexLeaf + state.leavesTotal) % state.leavesTotal
15
+ state.indexLeaf = state.indexMiniGap
16
+ state.leafConnectee += 1
17
+ state.arrayGroupOfFolds = numpy.take(state.leafComparison, state.indicesArrayGroupOfFolds)
18
+ compared = state.arrayGroupOfFolds[..., 0:state.leavesTotal // 2] == state.arrayGroupOfFolds[..., state.leavesTotal // 2:None]
19
+ for indexRow in range(len(compared)):
20
+ state.groupsOfFolds += compared[indexRow].all()
27
21
  else:
28
22
  state.dimensionsUnconstrained = state.dimensionsTotal
29
23
  state.gap1ndexCeiling = state.gapRangeStart[state.leaf1ndex - 1]
@@ -69,7 +63,7 @@ def count(state: MapFoldingState) -> MapFoldingState:
69
63
  state.groupsOfFolds = (state.groupsOfFolds + 1) // 2
70
64
  return state
71
65
 
72
- def doTheNeedful(state: MapFoldingState) -> MapFoldingState:
66
+ def doTheNeedful(state: SymmetricFoldsState) -> SymmetricFoldsState:
73
67
  state = transitionOnGroupsOfFolds(state)
74
68
  state = count(state)
75
69
  return state