mapFolding 0.9.3__tar.gz → 0.9.5__tar.gz

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 (65) hide show
  1. {mapfolding-0.9.3 → mapfolding-0.9.5}/PKG-INFO +2 -1
  2. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/__init__.py +41 -7
  3. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/basecamp.py +100 -9
  4. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/beDRY.py +7 -15
  5. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/dataBaskets.py +12 -0
  6. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/datatypes.py +4 -4
  7. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/oeis.py +2 -7
  8. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/someAssemblyRequired/RecipeJob.py +97 -3
  9. mapfolding-0.9.5/mapFolding/someAssemblyRequired/Z0Z_makeSomeModules.py +326 -0
  10. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/someAssemblyRequired/__init__.py +37 -29
  11. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/someAssemblyRequired/_theTypes.py +19 -19
  12. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/someAssemblyRequired/_tool_Make.py +12 -6
  13. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/someAssemblyRequired/_tool_Then.py +59 -21
  14. mapfolding-0.9.5/mapFolding/someAssemblyRequired/_toolboxAST.py +57 -0
  15. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/someAssemblyRequired/_toolboxAntecedents.py +123 -40
  16. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/someAssemblyRequired/_toolboxContainers.py +128 -37
  17. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/someAssemblyRequired/_toolboxPython.py +52 -50
  18. mapfolding-0.9.5/mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +274 -0
  19. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +6 -4
  20. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/someAssemblyRequired/toolboxNumba.py +3 -27
  21. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/someAssemblyRequired/transformationTools.py +47 -177
  22. mapfolding-0.9.5/mapFolding/syntheticModules/daoOfMapFolding.py +74 -0
  23. mapfolding-0.9.5/mapFolding/syntheticModules/dataPacking.py +25 -0
  24. mapfolding-0.9.5/mapFolding/syntheticModules/initializeCount.py +49 -0
  25. mapfolding-0.9.5/mapFolding/syntheticModules/theorem2.py +49 -0
  26. mapfolding-0.9.5/mapFolding/syntheticModules/theorem2Numba.py +45 -0
  27. mapfolding-0.9.5/mapFolding/syntheticModules/theorem2Trimmed.py +43 -0
  28. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding.egg-info/PKG-INFO +2 -1
  29. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding.egg-info/SOURCES.txt +10 -2
  30. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding.egg-info/requires.txt +1 -0
  31. {mapfolding-0.9.3 → mapfolding-0.9.5}/pyproject.toml +2 -1
  32. {mapfolding-0.9.3 → mapfolding-0.9.5}/tests/test_computations.py +4 -2
  33. mapfolding-0.9.3/mapFolding/Z0Z_flowControl.py +0 -99
  34. {mapfolding-0.9.3 → mapfolding-0.9.5}/LICENSE +0 -0
  35. {mapfolding-0.9.3 → mapfolding-0.9.5}/README.md +0 -0
  36. /mapfolding-0.9.3/mapFolding/theDaoOfMapFolding.py → /mapfolding-0.9.5/mapFolding/daoOfMapFolding.py +0 -0
  37. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/py.typed +0 -0
  38. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/reference/__init__.py +0 -0
  39. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/reference/flattened.py +0 -0
  40. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/reference/hunterNumba.py +0 -0
  41. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/reference/irvineJavaPort.py +0 -0
  42. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/reference/jaxCount.py +0 -0
  43. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/reference/jobsCompleted/[2x19]/p2x19.py +0 -0
  44. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/reference/jobsCompleted/__init__.py +0 -0
  45. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/reference/jobsCompleted/p2x19/p2x19.py +0 -0
  46. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/reference/lunnonNumpy.py +0 -0
  47. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/reference/lunnonWhile.py +0 -0
  48. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/reference/rotatedEntryPoint.py +0 -0
  49. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/reference/total_countPlus1vsPlusN.py +0 -0
  50. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/someAssemblyRequired/getLLVMforNoReason.py +0 -0
  51. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/syntheticModules/__init__.py +0 -0
  52. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/syntheticModules/numbaCount.py +0 -0
  53. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/theDao.py +0 -0
  54. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/theSSOT.py +0 -0
  55. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding/toolboxFilesystem.py +0 -0
  56. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding.egg-info/dependency_links.txt +0 -0
  57. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding.egg-info/entry_points.txt +0 -0
  58. {mapfolding-0.9.3 → mapfolding-0.9.5}/mapFolding.egg-info/top_level.txt +0 -0
  59. {mapfolding-0.9.3 → mapfolding-0.9.5}/setup.cfg +0 -0
  60. {mapfolding-0.9.3 → mapfolding-0.9.5}/tests/__init__.py +0 -0
  61. {mapfolding-0.9.3 → mapfolding-0.9.5}/tests/conftest.py +0 -0
  62. {mapfolding-0.9.3 → mapfolding-0.9.5}/tests/test_filesystem.py +0 -0
  63. {mapfolding-0.9.3 → mapfolding-0.9.5}/tests/test_oeis.py +0 -0
  64. {mapfolding-0.9.3 → mapfolding-0.9.5}/tests/test_other.py +0 -0
  65. {mapfolding-0.9.3 → mapfolding-0.9.5}/tests/test_tasks.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mapFolding
3
- Version: 0.9.3
3
+ Version: 0.9.5
4
4
  Summary: Map folding algorithm with code transformation framework for optimizing numerical computations
5
5
  Author-email: Hunter Hogan <HunterHogan@pm.me>
6
6
  License: CC-BY-NC-4.0
@@ -32,6 +32,7 @@ Requires-Python: >=3.10
32
32
  Description-Content-Type: text/markdown
33
33
  License-File: LICENSE
34
34
  Requires-Dist: autoflake
35
+ Requires-Dist: cytoolz
35
36
  Requires-Dist: more_itertools
36
37
  Requires-Dist: numba_progress
37
38
  Requires-Dist: numba
@@ -44,7 +44,41 @@ allowing users to compute map folding totals for larger dimensions than previous
44
44
  foundation for exploring advanced code transformation techniques.
45
45
  """
46
46
 
47
- from mapFolding.datatypes import (
47
+ from typing import Any, TypeAlias
48
+ import sys
49
+
50
+ stuPyd: TypeAlias = Any
51
+
52
+ if sys.version_info >= (3, 12):
53
+ from ast import (
54
+ ParamSpec as astDOTParamSpec,
55
+ type_param as astDOTtype_param,
56
+ TypeAlias as astDOTTypeAlias,
57
+ TypeVar as astDOTTypeVar,
58
+ TypeVarTuple as astDOTTypeVarTuple,
59
+ )
60
+ else:
61
+ astDOTParamSpec: TypeAlias = stuPyd
62
+ astDOTtype_param: TypeAlias = stuPyd
63
+ astDOTTypeAlias: TypeAlias = stuPyd
64
+ astDOTTypeVar: TypeAlias = stuPyd
65
+ astDOTTypeVarTuple: TypeAlias = stuPyd
66
+
67
+ if sys.version_info >= (3, 11):
68
+ from ast import TryStar as astDOTTryStar
69
+ from typing import TypedDict as TypedDict
70
+ from typing import NotRequired as NotRequired
71
+ else:
72
+ astDOTTryStar: TypeAlias = stuPyd
73
+ try:
74
+ from typing_extensions import TypedDict as TypedDict
75
+ from typing_extensions import NotRequired as NotRequired
76
+ except Exception:
77
+ TypedDict = dict[stuPyd, stuPyd]
78
+ from collections.abc import Iterable
79
+ NotRequired: TypeAlias = Iterable
80
+
81
+ from mapFolding.datatypes import ( # noqa: E402
48
82
  Array1DElephino as Array1DElephino,
49
83
  Array1DFoldsTotal as Array1DFoldsTotal,
50
84
  Array1DLeavesTotal as Array1DLeavesTotal,
@@ -58,18 +92,18 @@ from mapFolding.datatypes import (
58
92
  NumPyLeavesTotal as NumPyLeavesTotal,
59
93
  )
60
94
 
61
- from mapFolding.theSSOT import (
95
+ from mapFolding.theSSOT import ( # noqa: E402
62
96
  ComputationState as ComputationState,
63
97
  raiseIfNoneGitHubIssueNumber3 as raiseIfNoneGitHubIssueNumber3,
64
98
  The as The,
65
99
  )
66
100
 
67
- from mapFolding.theDao import (
101
+ from mapFolding.theDao import ( # noqa: E402
68
102
  countInitialize as countInitialize,
69
103
  doTheNeedful as doTheNeedful,
70
104
  )
71
105
 
72
- from mapFolding.beDRY import (
106
+ from mapFolding.beDRY import ( # noqa: E402
73
107
  getLeavesTotal as getLeavesTotal,
74
108
  getTaskDivisions as getTaskDivisions,
75
109
  outfitCountFolds as outfitCountFolds,
@@ -77,7 +111,7 @@ from mapFolding.beDRY import (
77
111
  validateListDimensions as validateListDimensions,
78
112
  )
79
113
 
80
- from mapFolding.toolboxFilesystem import (
114
+ from mapFolding.toolboxFilesystem import ( # noqa: E402
81
115
  getPathFilenameFoldsTotal as getPathFilenameFoldsTotal,
82
116
  getPathRootJobDEFAULT as getPathRootJobDEFAULT,
83
117
  saveFoldsTotal as saveFoldsTotal,
@@ -85,9 +119,9 @@ from mapFolding.toolboxFilesystem import (
85
119
  writeStringToHere as writeStringToHere,
86
120
  )
87
121
 
88
- from mapFolding.Z0Z_flowControl import countFolds
122
+ from mapFolding.basecamp import countFolds as countFolds # noqa: E402
89
123
 
90
- from mapFolding.oeis import (
124
+ from mapFolding.oeis import ( # noqa: E402
91
125
  clearOEIScache as clearOEIScache,
92
126
  getFoldsTotalKnown as getFoldsTotalKnown,
93
127
  getOEISids as getOEISids,
@@ -23,10 +23,15 @@ from mapFolding import (
23
23
  from os import PathLike
24
24
  from pathlib import PurePath
25
25
 
26
- def countFolds(listDimensions: Sequence[int]
26
+ def countFolds(listDimensions: Sequence[int] | None = None
27
27
  , pathLikeWriteFoldsTotal: PathLike[str] | PurePath | None = None
28
28
  , computationDivisions: int | str | None = None
29
29
  , CPUlimit: int | float | bool | None = None
30
+ # , * I need to improve `standardizedEqualToCallableReturn` so it will work with keyword arguments
31
+ , mapShape: tuple[int, ...] | None = None
32
+ , oeisID: str | None = None
33
+ , oeis_n: int | None = None
34
+ , flow: str | None = None
30
35
  ) -> int:
31
36
  """
32
37
  Count the total number of possible foldings for a given map dimensions.
@@ -75,21 +80,107 @@ def countFolds(listDimensions: Sequence[int]
75
80
  computation time. If logicalCores >= `leavesTotal`, it will probably be faster. If logicalCores <= 2 * `leavesTotal`, it
76
81
  will almost certainly be slower for all map dimensions.
77
82
  """
78
- mapShape: tuple[int, ...] = validateListDimensions(listDimensions)
79
- concurrencyLimit: int = setProcessorLimit(CPUlimit, The.concurrencyPackage)
80
- computationStateInitialized: ComputationState = outfitCountFolds(mapShape, computationDivisions, concurrencyLimit)
83
+ # mapShape =====================================================================
84
+
85
+ if mapShape:
86
+ pass
87
+ else:
88
+ if oeisID and oeis_n:
89
+ from mapFolding.oeis import settingsOEIS
90
+ try:
91
+ mapShape = settingsOEIS[oeisID]['getMapShape'](oeis_n)
92
+ except KeyError:
93
+ pass
94
+ if not mapShape and listDimensions:
95
+ mapShape = validateListDimensions(listDimensions)
96
+
97
+ if mapShape is None:
98
+ raise ValueError(f"""I received these values:
99
+ `{listDimensions = }`,
100
+ `{mapShape = }`,
101
+ `{oeisID = }` and `{oeis_n = }`,
102
+ but I was unable to select a map for which to count the folds.""")
103
+
104
+ # task division instructions ===============================================
105
+
106
+ if computationDivisions:
107
+ # NOTE `The.concurrencyPackage`
108
+ concurrencyLimit: int = setProcessorLimit(CPUlimit, The.concurrencyPackage)
109
+ from mapFolding.beDRY import getLeavesTotal, getTaskDivisions
110
+ leavesTotal: int = getLeavesTotal(mapShape)
111
+ taskDivisions = getTaskDivisions(computationDivisions, concurrencyLimit, leavesTotal)
112
+ del leavesTotal
113
+ else:
114
+ concurrencyLimit = 1
115
+ taskDivisions = 0
116
+
117
+ # memorialization instructions ===========================================
81
118
 
82
119
  if pathLikeWriteFoldsTotal is not None:
83
- pathFilenameFoldsTotal = getPathFilenameFoldsTotal(computationStateInitialized.mapShape, pathLikeWriteFoldsTotal)
120
+ pathFilenameFoldsTotal = getPathFilenameFoldsTotal(mapShape, pathLikeWriteFoldsTotal)
84
121
  saveFoldsTotalFAILearly(pathFilenameFoldsTotal)
85
122
  else:
86
123
  pathFilenameFoldsTotal = None
87
124
 
88
- computationStateComplete: ComputationState = The.dispatcher(computationStateInitialized)
125
+ # Flow control until I can figure out a good way ===============================
126
+
127
+ if flow == 'daoOfMapFolding':
128
+ from mapFolding.dataBaskets import MapFoldingState
129
+ mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
130
+
131
+ from mapFolding.daoOfMapFolding import doTheNeedful
132
+ mapFoldingState = doTheNeedful(mapFoldingState)
133
+ foldsTotal = mapFoldingState.foldsTotal
134
+
135
+ elif flow == 'theorem2' and any((dimension > 2 for dimension in mapShape)):
136
+ from mapFolding.dataBaskets import MapFoldingState
137
+ mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
138
+
139
+ from mapFolding.syntheticModules.initializeCount import initializeGroupsOfFolds
140
+ mapFoldingState = initializeGroupsOfFolds(mapFoldingState)
141
+
142
+ from mapFolding.syntheticModules.theorem2 import count
143
+ mapFoldingState = count(mapFoldingState)
144
+
145
+ foldsTotal = mapFoldingState.foldsTotal
146
+
147
+ elif flow == 'theorem2Trimmed' and any((dimension > 2 for dimension in mapShape)):
148
+ from mapFolding.dataBaskets import MapFoldingState
149
+ mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
150
+
151
+ from mapFolding.syntheticModules.initializeCount import initializeGroupsOfFolds
152
+ mapFoldingState = initializeGroupsOfFolds(mapFoldingState)
153
+
154
+ from mapFolding.syntheticModules.theorem2Trimmed import count
155
+ mapFoldingState = count(mapFoldingState)
156
+
157
+ foldsTotal = mapFoldingState.foldsTotal
158
+
159
+ elif (flow == 'theorem2Numba' or taskDivisions == 0) and any((dimension > 2 for dimension in mapShape)):
160
+ from mapFolding.dataBaskets import MapFoldingState
161
+ mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
162
+
163
+ from mapFolding.syntheticModules.initializeCount import initializeGroupsOfFolds
164
+ mapFoldingState = initializeGroupsOfFolds(mapFoldingState)
165
+
166
+ from mapFolding.syntheticModules.dataPacking import doTheNeedful
167
+ mapFoldingState = doTheNeedful(mapFoldingState)
168
+
169
+ foldsTotal = mapFoldingState.foldsTotal
170
+
171
+ # NOTE treat this as a default?
172
+ # flow based on `The` and `ComputationState` ====================================
173
+
174
+ else:
175
+ computationStateInitialized: ComputationState = outfitCountFolds(mapShape, computationDivisions, concurrencyLimit)
176
+ computationStateComplete: ComputationState = The.dispatcher(computationStateInitialized)
177
+
178
+ computationStateComplete.getFoldsTotal()
179
+ foldsTotal = computationStateComplete.foldsTotal
89
180
 
90
- computationStateComplete.getFoldsTotal()
181
+ # Follow memorialization instructions ===========================================
91
182
 
92
183
  if pathFilenameFoldsTotal is not None:
93
- saveFoldsTotal(pathFilenameFoldsTotal, computationStateComplete.foldsTotal)
184
+ saveFoldsTotal(pathFilenameFoldsTotal, foldsTotal)
94
185
 
95
- return computationStateComplete.foldsTotal
186
+ return foldsTotal
@@ -59,14 +59,12 @@ def getTaskDivisions(computationDivisions: int | str | None, concurrencyLimit: i
59
59
  """
60
60
  Determines whether to divide the computation into tasks and how many divisions.
61
61
 
62
+
62
63
  Parameters
63
64
  ----------
64
65
  computationDivisions: None
65
- Specifies how to divide computations:
66
- - `None`: no division of the computation into tasks; sets task divisions to 0.
67
- - int: directly set the number of task divisions; cannot exceed the map's total leaves.
68
- - `'maximum'`: divides into `leavesTotal`-many `taskDivisions`.
69
- - `'cpu'`: limits the divisions to the number of available CPUs: i.e., `concurrencyLimit`.
66
+ Specifies how to divide computations: Please see the documentation in `countFolds` for details. I know it is
67
+ annoying, but I want to be sure you have the most accurate information.
70
68
  concurrencyLimit
71
69
  Maximum number of concurrent tasks allowed.
72
70
 
@@ -224,7 +222,7 @@ def outfitCountFolds(mapShape: tuple[int, ...], computationDivisions: int | str
224
222
  A tuple of integers representing the dimensions of the map.
225
223
  computationDivisions: None
226
224
  Controls how to divide the computation into parallel tasks. I know it is annoying, but please see
227
- `getTaskDivisions` for details, so that you and I both know you have the most accurate information.
225
+ `countFolds` for details, so that you and I both know you have the most accurate information.
228
226
  concurrencyLimit: 1
229
227
  Maximum number of concurrent processes to use during computation.
230
228
 
@@ -245,19 +243,13 @@ def outfitCountFolds(mapShape: tuple[int, ...], computationDivisions: int | str
245
243
 
246
244
  def setProcessorLimit(CPUlimit: Any | None, concurrencyPackage: str | None = None) -> int:
247
245
  """
248
- Sets processor limit for concurrent operations.
246
+ Whether and how to limit the CPU usage.
249
247
 
250
248
  Parameters
251
249
  ----------
252
250
  CPUlimit: None
253
- Controls processor usage limits:
254
- - `False`, `None`, or `0`: No limits on processor usage; uses all available processors. All other values will
255
- potentially limit processor usage.
256
- - `True`: Yes, limit the processor usage; limits to 1 processor.
257
- - Integer `>= 1`: Limits usage to the specified number of processors.
258
- - Decimal value (`float`) between 0 and 1: Fraction of total processors to use.
259
- - Decimal value (`float`) between -1 and 0: Fraction of processors to _not_ use.
260
- - Integer `<= -1`: Subtract the absolute value from total processors.
251
+ Please see the documentation for in `countFolds` for details. I know it is annoying, but I want to be sure you
252
+ have the most accurate information.
261
253
  concurrencyPackage: None
262
254
  Specifies which concurrency package to use:
263
255
  - `None` or `'multiprocessing'`: Uses standard `multiprocessing`.
@@ -47,3 +47,15 @@ class MapFoldingState:
47
47
  if self.gapRangeStart is None: self.gapRangeStart = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['gapRangeStart'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
48
48
  if self.leafAbove is None: self.leafAbove = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafAbove'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
49
49
  if self.leafBelow is None: self.leafBelow = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafBelow'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
50
+
51
+ @dataclasses.dataclass
52
+ class LeafSequenceState(MapFoldingState):
53
+ leafSequence: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
54
+
55
+ def __post_init__(self) -> None:
56
+ super().__post_init__()
57
+ from mapFolding.oeis import getFoldsTotalKnown
58
+ groupsOfFoldsKnown = getFoldsTotalKnown(self.mapShape) // self.leavesTotal
59
+ if self.leafSequence is None: # pyright: ignore[reportUnnecessaryComparison]
60
+ self.leafSequence = makeDataContainer(groupsOfFoldsKnown, self.__dataclass_fields__['leafSequence'].metadata['dtype'])
61
+ self.leafSequence[self.groupsOfFolds] = self.leaf1ndex
@@ -1,4 +1,4 @@
1
- from numpy import dtype, int64 as numpy_int64, integer, ndarray
1
+ from numpy import dtype, uint8 as numpy_uint8, uint16 as numpy_uint16, uint64 as numpy_uint64, integer, ndarray
2
2
  from typing import Any, TypeAlias, TypeVar
3
3
 
4
4
  # =============================================================================
@@ -7,13 +7,13 @@ from typing import Any, TypeAlias, TypeVar
7
7
  NumPyIntegerType = TypeVar('NumPyIntegerType', bound=integer[Any], covariant=True)
8
8
 
9
9
  DatatypeLeavesTotal: TypeAlias = int
10
- NumPyLeavesTotal: TypeAlias = numpy_int64
10
+ NumPyLeavesTotal: TypeAlias = numpy_uint8
11
11
 
12
12
  DatatypeElephino: TypeAlias = int
13
- NumPyElephino: TypeAlias = numpy_int64
13
+ NumPyElephino: TypeAlias = numpy_uint16
14
14
 
15
15
  DatatypeFoldsTotal: TypeAlias = int
16
- NumPyFoldsTotal: TypeAlias = numpy_int64
16
+ NumPyFoldsTotal: TypeAlias = numpy_uint64
17
17
 
18
18
  Array3D: TypeAlias = ndarray[tuple[int, int, int], dtype[NumPyLeavesTotal]]
19
19
  Array1DLeavesTotal: TypeAlias = ndarray[tuple[int], dtype[NumPyLeavesTotal]]
@@ -20,9 +20,9 @@ mathematical definition in OEIS and the computational implementation in the pack
20
20
  from collections.abc import Callable
21
21
  from datetime import datetime, timedelta
22
22
  from functools import cache
23
- from mapFolding import countFolds, The, writeStringToHere
23
+ from mapFolding import countFolds, The, TypedDict, writeStringToHere
24
24
  from pathlib import Path
25
- from typing import Any, Final, TYPE_CHECKING
25
+ from typing import Any, Final
26
26
  import argparse
27
27
  import random
28
28
  import sys
@@ -31,11 +31,6 @@ import urllib.request
31
31
  import urllib.response
32
32
  import warnings
33
33
 
34
- if TYPE_CHECKING:
35
- from typing import TypedDict
36
- else:
37
- TypedDict = dict[Any, Any]
38
-
39
34
  cacheDays = 30
40
35
 
41
36
  pathCache: Path = The.pathPackage / ".cache"
@@ -1,12 +1,12 @@
1
- from mapFolding.someAssemblyRequired import ShatteredDataclass, ast_Identifier, parsePathFilename2astModule, str_nameDOTname
1
+ from mapFolding.someAssemblyRequired import ShatteredDataclass, ast_Identifier, parseLogicalPath2astModule, parsePathFilename2astModule, str_nameDOTname
2
2
  from mapFolding.someAssemblyRequired.toolboxNumba import theNumbaFlow
3
3
  from mapFolding.someAssemblyRequired.transformationTools import shatter_dataclassesDOTdataclass
4
4
  from mapFolding.theSSOT import ComputationState, DatatypeElephino as TheDatatypeElephino, DatatypeFoldsTotal as TheDatatypeFoldsTotal, DatatypeLeavesTotal as TheDatatypeLeavesTotal
5
5
  from mapFolding.toolboxFilesystem import getPathFilenameFoldsTotal, getPathRootJobDEFAULT
6
-
7
- import dataclasses
6
+ from mapFolding.dataBaskets import MapFoldingState
8
7
  from pathlib import Path, PurePosixPath
9
8
  from typing import TypeAlias
9
+ import dataclasses
10
10
 
11
11
  @dataclasses.dataclass
12
12
  class RecipeJob:
@@ -101,3 +101,97 @@ class RecipeJob:
101
101
  dataclassInstanceTaskDistribution: ast_Identifier = sourceDataclassInstanceTaskDistribution
102
102
  concurrencyManagerNamespace: ast_Identifier = sourceConcurrencyManagerNamespace
103
103
  concurrencyManagerIdentifier: ast_Identifier = sourceConcurrencyManagerIdentifier
104
+
105
+ @dataclasses.dataclass
106
+ class RecipeJobTheorem2Numba:
107
+ state: MapFoldingState
108
+ # TODO create function to calculate `foldsTotalEstimated`
109
+ foldsTotalEstimated: int = 0
110
+ shatteredDataclass: ShatteredDataclass = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
111
+
112
+ # ========================================
113
+ # Source
114
+ source_astModule = parseLogicalPath2astModule('mapFolding.syntheticModules.theorem2Numba')
115
+ sourceCountCallable: ast_Identifier = 'count'
116
+
117
+ sourceLogicalPathModuleDataclass: str_nameDOTname = 'mapFolding.dataBaskets'
118
+ sourceDataclassIdentifier: ast_Identifier = 'MapFoldingState'
119
+ sourceDataclassInstance: ast_Identifier = theNumbaFlow.dataclassInstance
120
+
121
+ sourcePathPackage: PurePosixPath | None = theNumbaFlow.pathPackage
122
+ sourcePackageIdentifier: ast_Identifier | None = theNumbaFlow.packageIdentifier
123
+
124
+ # ========================================
125
+ # Filesystem (names of physical objects)
126
+ pathPackage: PurePosixPath | None = None
127
+ pathModule: PurePosixPath | None = PurePosixPath(getPathRootJobDEFAULT())
128
+ """ `pathModule` will override `pathPackage` and `logicalPathRoot`."""
129
+ fileExtension: str = theNumbaFlow.fileExtension
130
+ pathFilenameFoldsTotal: PurePosixPath = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
131
+
132
+ # ========================================
133
+ # Logical identifiers (as opposed to physical identifiers)
134
+ packageIdentifier: ast_Identifier | None = None
135
+ logicalPathRoot: str_nameDOTname | None = None
136
+ """ `logicalPathRoot` likely corresponds to a physical filesystem directory."""
137
+ moduleIdentifier: ast_Identifier = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType]
138
+ countCallable: ast_Identifier = sourceCountCallable
139
+ dataclassIdentifier: ast_Identifier | None = sourceDataclassIdentifier
140
+ dataclassInstance: ast_Identifier | None = sourceDataclassInstance
141
+ logicalPathModuleDataclass: str_nameDOTname | None = sourceLogicalPathModuleDataclass
142
+
143
+ # ========================================
144
+ # Datatypes
145
+ DatatypeFoldsTotal: TypeAlias = TheDatatypeFoldsTotal
146
+ DatatypeElephino: TypeAlias = TheDatatypeElephino
147
+ DatatypeLeavesTotal: TypeAlias = TheDatatypeLeavesTotal
148
+
149
+ def _makePathFilename(self,
150
+ pathRoot: PurePosixPath | None = None,
151
+ logicalPathINFIX: str_nameDOTname | None = None,
152
+ filenameStem: str | None = None,
153
+ fileExtension: str | None = None,
154
+ ) -> PurePosixPath:
155
+ if pathRoot is None:
156
+ pathRoot = self.pathPackage or PurePosixPath(Path.cwd())
157
+ if logicalPathINFIX:
158
+ whyIsThisStillAThing: list[str] = logicalPathINFIX.split('.')
159
+ pathRoot = pathRoot.joinpath(*whyIsThisStillAThing)
160
+ if filenameStem is None:
161
+ filenameStem = self.moduleIdentifier
162
+ if fileExtension is None:
163
+ fileExtension = self.fileExtension
164
+ filename: str = filenameStem + fileExtension
165
+ return pathRoot.joinpath(filename)
166
+
167
+ @property
168
+ def pathFilenameModule(self) -> PurePosixPath:
169
+ if self.pathModule is None:
170
+ return self._makePathFilename()
171
+ else:
172
+ return self._makePathFilename(pathRoot=self.pathModule, logicalPathINFIX=None)
173
+
174
+ def __post_init__(self):
175
+ pathFilenameFoldsTotal = PurePosixPath(getPathFilenameFoldsTotal(self.state.mapShape))
176
+
177
+ if self.moduleIdentifier is None: # pyright: ignore[reportUnnecessaryComparison]
178
+ self.moduleIdentifier = pathFilenameFoldsTotal.stem
179
+
180
+ if self.pathFilenameFoldsTotal is None: # pyright: ignore[reportUnnecessaryComparison]
181
+ self.pathFilenameFoldsTotal = pathFilenameFoldsTotal
182
+
183
+ if self.shatteredDataclass is None and self.logicalPathModuleDataclass and self.dataclassIdentifier and self.dataclassInstance: # pyright: ignore[reportUnnecessaryComparison]
184
+ self.shatteredDataclass = shatter_dataclassesDOTdataclass(self.logicalPathModuleDataclass, self.dataclassIdentifier, self.dataclassInstance)
185
+
186
+ # ========================================
187
+ # Fields you probably don't need =================================
188
+ # Dispatcher =================================
189
+ sourceDispatcherCallable: ast_Identifier = theNumbaFlow.callableDispatcher
190
+ dispatcherCallable: ast_Identifier = sourceDispatcherCallable
191
+ # Parallel counting =================================
192
+ sourceDataclassInstanceTaskDistribution: ast_Identifier = theNumbaFlow.dataclassInstanceTaskDistribution
193
+ sourceConcurrencyManagerNamespace: ast_Identifier = theNumbaFlow.concurrencyManagerNamespace
194
+ sourceConcurrencyManagerIdentifier: ast_Identifier = theNumbaFlow.concurrencyManagerIdentifier
195
+ dataclassInstanceTaskDistribution: ast_Identifier = sourceDataclassInstanceTaskDistribution
196
+ concurrencyManagerNamespace: ast_Identifier = sourceConcurrencyManagerNamespace
197
+ concurrencyManagerIdentifier: ast_Identifier = sourceConcurrencyManagerIdentifier