mapFolding 0.9.4__tar.gz → 0.10.0__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 (77) hide show
  1. {mapfolding-0.9.4 → mapfolding-0.10.0}/PKG-INFO +2 -1
  2. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/__init__.py +41 -7
  3. mapfolding-0.9.4/mapFolding/Z0Z_flowControl.py → mapfolding-0.10.0/mapFolding/basecamp.py +70 -1
  4. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/beDRY.py +7 -15
  5. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/dataBaskets.py +12 -0
  6. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/datatypes.py +4 -4
  7. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/oeis.py +2 -7
  8. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/someAssemblyRequired/RecipeJob.py +97 -3
  9. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/someAssemblyRequired/Z0Z_makeSomeModules.py +143 -42
  10. mapfolding-0.10.0/mapFolding/someAssemblyRequired/__init__.py +88 -0
  11. mapfolding-0.10.0/mapFolding/someAssemblyRequired/_astTypes.py +117 -0
  12. mapfolding-0.10.0/mapFolding/someAssemblyRequired/_theTypes.py +34 -0
  13. mapfolding-0.10.0/mapFolding/someAssemblyRequired/_toolBe.py +524 -0
  14. mapfolding-0.10.0/mapFolding/someAssemblyRequired/_toolDOT.py +493 -0
  15. mapfolding-0.10.0/mapFolding/someAssemblyRequired/_toolGrab.py +653 -0
  16. mapfolding-0.10.0/mapFolding/someAssemblyRequired/_toolIfThis.py +193 -0
  17. mapfolding-0.10.0/mapFolding/someAssemblyRequired/_toolMake.py +339 -0
  18. mapfolding-0.10.0/mapFolding/someAssemblyRequired/_toolThen.py +63 -0
  19. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/someAssemblyRequired/_toolboxAST.py +3 -3
  20. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/someAssemblyRequired/_toolboxContainers.py +124 -29
  21. mapfolding-0.10.0/mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +274 -0
  22. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +12 -11
  23. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/someAssemblyRequired/toolboxNumba.py +4 -28
  24. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/someAssemblyRequired/transformationTools.py +46 -155
  25. mapfolding-0.10.0/mapFolding/syntheticModules/daoOfMapFolding.py +74 -0
  26. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/syntheticModules/dataPacking.py +1 -1
  27. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/syntheticModules/theorem2Numba.py +2 -8
  28. mapfolding-0.10.0/mapFolding/syntheticModules/theorem2Trimmed.py +43 -0
  29. mapfolding-0.10.0/mapFolding/toolFactory/astFactory.py +493 -0
  30. mapfolding-0.10.0/mapFolding/toolFactory/astFactory_annex.py +63 -0
  31. mapfolding-0.10.0/mapFolding/toolFactory/astFactory_docstrings.py +63 -0
  32. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding.egg-info/PKG-INFO +2 -1
  33. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding.egg-info/SOURCES.txt +13 -4
  34. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding.egg-info/requires.txt +1 -0
  35. {mapfolding-0.9.4 → mapfolding-0.10.0}/pyproject.toml +2 -1
  36. {mapfolding-0.9.4 → mapfolding-0.10.0}/tests/test_computations.py +1 -1
  37. mapfolding-0.9.4/mapFolding/basecamp.py +0 -95
  38. mapfolding-0.9.4/mapFolding/someAssemblyRequired/__init__.py +0 -99
  39. mapfolding-0.9.4/mapFolding/someAssemblyRequired/_theTypes.py +0 -63
  40. mapfolding-0.9.4/mapFolding/someAssemblyRequired/_tool_Make.py +0 -134
  41. mapfolding-0.9.4/mapFolding/someAssemblyRequired/_tool_Then.py +0 -157
  42. mapfolding-0.9.4/mapFolding/someAssemblyRequired/_toolboxAntecedents.py +0 -387
  43. {mapfolding-0.9.4 → mapfolding-0.10.0}/LICENSE +0 -0
  44. {mapfolding-0.9.4 → mapfolding-0.10.0}/README.md +0 -0
  45. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/daoOfMapFolding.py +0 -0
  46. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/py.typed +0 -0
  47. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/reference/__init__.py +0 -0
  48. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/reference/flattened.py +0 -0
  49. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/reference/hunterNumba.py +0 -0
  50. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/reference/irvineJavaPort.py +0 -0
  51. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/reference/jaxCount.py +0 -0
  52. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/reference/jobsCompleted/[2x19]/p2x19.py +0 -0
  53. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/reference/jobsCompleted/__init__.py +0 -0
  54. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/reference/jobsCompleted/p2x19/p2x19.py +0 -0
  55. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/reference/lunnonNumpy.py +0 -0
  56. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/reference/lunnonWhile.py +0 -0
  57. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/reference/rotatedEntryPoint.py +0 -0
  58. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/reference/total_countPlus1vsPlusN.py +0 -0
  59. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/someAssemblyRequired/_toolboxPython.py +0 -0
  60. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/someAssemblyRequired/getLLVMforNoReason.py +0 -0
  61. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/syntheticModules/__init__.py +0 -0
  62. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/syntheticModules/initializeCount.py +0 -0
  63. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/syntheticModules/numbaCount.py +0 -0
  64. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/syntheticModules/theorem2.py +0 -0
  65. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/theDao.py +0 -0
  66. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/theSSOT.py +0 -0
  67. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding/toolboxFilesystem.py +0 -0
  68. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding.egg-info/dependency_links.txt +0 -0
  69. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding.egg-info/entry_points.txt +0 -0
  70. {mapfolding-0.9.4 → mapfolding-0.10.0}/mapFolding.egg-info/top_level.txt +0 -0
  71. {mapfolding-0.9.4 → mapfolding-0.10.0}/setup.cfg +0 -0
  72. {mapfolding-0.9.4 → mapfolding-0.10.0}/tests/__init__.py +0 -0
  73. {mapfolding-0.9.4 → mapfolding-0.10.0}/tests/conftest.py +0 -0
  74. {mapfolding-0.9.4 → mapfolding-0.10.0}/tests/test_filesystem.py +0 -0
  75. {mapfolding-0.9.4 → mapfolding-0.10.0}/tests/test_oeis.py +0 -0
  76. {mapfolding-0.9.4 → mapfolding-0.10.0}/tests/test_other.py +0 -0
  77. {mapfolding-0.9.4 → mapfolding-0.10.0}/tests/test_tasks.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mapFolding
3
- Version: 0.9.4
3
+ Version: 0.10.0
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
@@ -41,6 +41,7 @@ Requires-Dist: platformdirs
41
41
  Requires-Dist: python_minifier
42
42
  Requires-Dist: sympy
43
43
  Requires-Dist: tomli
44
+ Requires-Dist: typeshed_client
44
45
  Requires-Dist: Z0Z_tools
45
46
  Provides-Extra: testing
46
47
  Requires-Dist: mypy; extra == "testing"
@@ -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,
@@ -1,3 +1,14 @@
1
+ """
2
+ Public API for the map folding algorithm with simplified interface.
3
+
4
+ This module provides the main entry point for users of the mapFolding package, abstracting away the complexities of the
5
+ computational algorithm. It offers a high-level interface to count the total number of possible ways to fold a
6
+ rectangular map of specified dimensions, with options for customizing the computation process and saving results.
7
+
8
+ The primary function is countFolds, which handles parameter validation, computation state management, dispatching to the
9
+ appropriate algorithm implementation, and optional persistence of results.
10
+ """
11
+
1
12
  from collections.abc import Sequence
2
13
  from mapFolding import (
3
14
  ComputationState,
@@ -22,7 +33,53 @@ def countFolds(listDimensions: Sequence[int] | None = None
22
33
  , oeis_n: int | None = None
23
34
  , flow: str | None = None
24
35
  ) -> int:
25
-
36
+ """
37
+ Count the total number of possible foldings for a given map dimensions.
38
+
39
+ This function serves as the main public interface to the map folding algorithm, handling all parameter validation,
40
+ computation state management, and result persistence in a user-friendly way.
41
+
42
+ Parameters
43
+ ----------
44
+ listDimensions
45
+ List of integers representing the dimensions of the map to be folded.
46
+ pathLikeWriteFoldsTotal: None
47
+ Path, filename, or pathFilename to write the total fold count to. If a directory is provided, creates a file
48
+ with a default name based on map dimensions.
49
+ computationDivisions: None
50
+ Whether and how to divide the computational work.
51
+ - `None`: no division of the computation into tasks; sets task divisions to 0.
52
+ - int: directly set the number of task divisions; cannot exceed the map's total leaves.
53
+ - `'maximum'`: divides into `leavesTotal`-many `taskDivisions`.
54
+ - `'cpu'`: limits the divisions to the number of available CPUs: i.e., `concurrencyLimit`.
55
+ CPUlimit: None
56
+ This is only relevant if there are `computationDivisions`: whether and how to limit the CPU usage.
57
+ - `False`, `None`, or `0`: No limits on processor usage; uses all available processors. All other values will
58
+ potentially limit processor usage.
59
+ - `True`: Yes, limit the processor usage; limits to 1 processor.
60
+ - Integer `>= 1`: Limits usage to the specified number of processors.
61
+ - Decimal value (`float`) between 0 and 1: Fraction of total processors to use.
62
+ - Decimal value (`float`) between -1 and 0: Fraction of processors to _not_ use.
63
+ - Integer `<= -1`: Subtract the absolute value from total processors.
64
+
65
+ Returns
66
+ -------
67
+ foldsTotal: Total number of distinct ways to fold a map of the given dimensions.
68
+
69
+ Note well
70
+ ---------
71
+ You probably do not want to divide your computation into tasks.
72
+
73
+ If you want to compute a large `foldsTotal`, dividing the computation into tasks is usually a bad idea. Dividing the
74
+ algorithm into tasks is inherently inefficient: efficient division into tasks means there would be no overlap in the
75
+ work performed by each task. When dividing this algorithm, the amount of overlap is between 50% and 90% by all
76
+ tasks: at least 50% of the work done by every task must be done by _all_ tasks. If you improve the computation time,
77
+ it will only change by -10 to -50% depending on (at the very least) the ratio of the map dimensions and the number
78
+ of leaves. If an undivided computation would take 10 hours on your computer, for example, the computation will still
79
+ take at least 5 hours but you might reduce the time to 9 hours. Most of the time, however, you will increase the
80
+ computation time. If logicalCores >= `leavesTotal`, it will probably be faster. If logicalCores <= 2 * `leavesTotal`, it
81
+ will almost certainly be slower for all map dimensions.
82
+ """
26
83
  # mapShape =====================================================================
27
84
 
28
85
  if mapShape:
@@ -87,6 +144,18 @@ def countFolds(listDimensions: Sequence[int] | None = None
87
144
 
88
145
  foldsTotal = mapFoldingState.foldsTotal
89
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
+
90
159
  elif (flow == 'theorem2Numba' or taskDivisions == 0) and any((dimension > 2 for dimension in mapShape)):
91
160
  from mapFolding.dataBaskets import MapFoldingState
92
161
  mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
@@ -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