mapFolding 0.5.1__py3-none-any.whl → 0.7.0__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.
- mapFolding/__init__.py +6 -101
- mapFolding/basecamp.py +12 -10
- mapFolding/beDRY.py +96 -316
- mapFolding/filesystem.py +87 -0
- mapFolding/noHomeYet.py +20 -0
- mapFolding/oeis.py +39 -36
- mapFolding/reference/flattened.py +377 -0
- mapFolding/reference/hunterNumba.py +132 -0
- mapFolding/reference/irvineJavaPort.py +120 -0
- mapFolding/reference/jax.py +208 -0
- mapFolding/reference/lunnan.py +153 -0
- mapFolding/reference/lunnanNumpy.py +123 -0
- mapFolding/reference/lunnanWhile.py +121 -0
- mapFolding/reference/rotatedEntryPoint.py +240 -0
- mapFolding/reference/total_countPlus1vsPlusN.py +211 -0
- mapFolding/someAssemblyRequired/Z0Z_workbench.py +34 -0
- mapFolding/someAssemblyRequired/__init__.py +16 -0
- mapFolding/someAssemblyRequired/getLLVMforNoReason.py +21 -0
- mapFolding/someAssemblyRequired/ingredientsNumba.py +100 -0
- mapFolding/someAssemblyRequired/synthesizeCountingFunctions.py +7 -0
- mapFolding/someAssemblyRequired/synthesizeDataConverters.py +135 -0
- mapFolding/someAssemblyRequired/synthesizeNumba.py +91 -0
- mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +417 -0
- mapFolding/someAssemblyRequired/synthesizeNumbaModules.py +91 -0
- mapFolding/someAssemblyRequired/transformationTools.py +425 -0
- mapFolding/someAssemblyRequired/whatWillBe.py +311 -0
- mapFolding/syntheticModules/__init__.py +0 -0
- mapFolding/syntheticModules/dataNamespaceFlattened.py +30 -0
- mapFolding/syntheticModules/numbaCount.py +90 -0
- mapFolding/syntheticModules/numbaCountExample.py +158 -0
- mapFolding/syntheticModules/numbaCountSequential.py +110 -0
- mapFolding/syntheticModules/numbaCount_doTheNeedful.py +13 -0
- mapFolding/syntheticModules/numba_doTheNeedful.py +12 -0
- mapFolding/syntheticModules/numba_doTheNeedfulExample.py +13 -0
- mapFolding/theDao.py +203 -227
- mapFolding/theSSOT.py +254 -123
- {mapFolding-0.5.1.dist-info → mapfolding-0.7.0.dist-info}/METADATA +10 -8
- mapfolding-0.7.0.dist-info/RECORD +50 -0
- {mapFolding-0.5.1.dist-info → mapfolding-0.7.0.dist-info}/WHEEL +1 -1
- {mapFolding-0.5.1.dist-info → mapfolding-0.7.0.dist-info}/top_level.txt +1 -0
- tests/__init__.py +0 -0
- tests/conftest.py +278 -0
- tests/test_computations.py +49 -0
- tests/test_filesystem.py +52 -0
- tests/test_oeis.py +128 -0
- tests/test_other.py +84 -0
- tests/test_tasks.py +50 -0
- mapFolding/theSSOTdatatypes.py +0 -156
- mapFolding-0.5.1.dist-info/RECORD +0 -14
- {mapFolding-0.5.1.dist-info → mapfolding-0.7.0.dist-info}/LICENSE +0 -0
- {mapFolding-0.5.1.dist-info → mapfolding-0.7.0.dist-info}/entry_points.txt +0 -0
mapFolding/theSSOT.py
CHANGED
|
@@ -1,142 +1,273 @@
|
|
|
1
|
-
from
|
|
2
|
-
from
|
|
3
|
-
from
|
|
4
|
-
from numpy import dtype, integer, ndarray
|
|
1
|
+
from importlib import import_module as importlib_import_module
|
|
2
|
+
from inspect import getfile as inspect_getfile
|
|
3
|
+
from numpy import dtype, int64 as numpy_int64, int16 as numpy_int16, ndarray, signedinteger
|
|
5
4
|
from pathlib import Path
|
|
6
5
|
from sys import modules as sysModules
|
|
6
|
+
from tomli import load as tomli_load
|
|
7
7
|
from types import ModuleType
|
|
8
|
-
from typing import Any, Final,
|
|
8
|
+
from typing import Any, Final, TypeAlias
|
|
9
|
+
import dataclasses
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
"""
|
|
12
|
+
2025 March 11
|
|
13
|
+
Note to self: fundamental concept in Python:
|
|
14
|
+
Identifiers: scope and resolution, LEGB (Local, Enclosing, Global, Builtin)
|
|
15
|
+
- Local: Inside the function
|
|
16
|
+
- Enclosing: Inside enclosing functions
|
|
17
|
+
- Global: At the uppermost level
|
|
18
|
+
- Builtin: Python's built-in names
|
|
19
|
+
"""
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
# I _think_, in theSSOT, I have abstracted the flow settings to only these couple of lines:
|
|
22
|
+
packageFlowSynthetic = 'numba'
|
|
23
|
+
Z0Z_packageFlow = 'algorithm'
|
|
24
|
+
# Z0Z_packageFlow = packageFlowSynthetic
|
|
19
25
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- Lazy Initialization
|
|
24
|
-
- Separation of configuration from business logic
|
|
26
|
+
# =============================================================================
|
|
27
|
+
# The Wrong Way The Wrong Way The Wrong Way The Wrong Way The Wrong Way
|
|
28
|
+
# Evaluate When Packaging Evaluate When Packaging Evaluate When Packaging
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
sourceAlgorithmPACKAGING: str = 'theDao'
|
|
31
|
+
datatypePackagePACKAGING: Final[str] = 'numpy'
|
|
32
|
+
dispatcherCallableAsStrPACKAGING: str = 'doTheNeedful'
|
|
33
|
+
moduleOfSyntheticModulesPACKAGING: Final[str] = 'syntheticModules'
|
|
34
|
+
|
|
35
|
+
dataclassModuleAsStrPACKAGING: str = 'theSSOT'
|
|
36
|
+
dataclassIdentifierAsStrPACKAGING: str = 'ComputationState'
|
|
37
|
+
dataclassInstanceAsStrPACKAGING: str = 'state'
|
|
38
|
+
dataclassInstance_Pre_ParallelAsStrPACKAGING = dataclassInstanceAsStrPACKAGING + 'PARALLEL'
|
|
39
|
+
dataclassInstance_Post_ParallelAsStrPACKAGING = dataclassInstanceAsStrPACKAGING + 'COMPLETE'
|
|
40
|
+
|
|
41
|
+
Z0Z_initializeCallableAsStrPACKAGING = 'countInitialize'
|
|
42
|
+
Z0Z_sequentialCallableAsStrPACKAGING = 'countSequential'
|
|
43
|
+
Z0Z_parallelCallableAsStrPACKAGING = 'countParallel'
|
|
29
44
|
|
|
30
|
-
|
|
45
|
+
try:
|
|
46
|
+
thePackageNameIsPACKAGING: str = tomli_load(Path("../pyproject.toml").open('rb'))["project"]["name"]
|
|
47
|
+
except Exception:
|
|
48
|
+
thePackageNameIsPACKAGING: str = "mapFolding"
|
|
31
49
|
|
|
32
|
-
|
|
33
|
-
#
|
|
34
|
-
|
|
35
|
-
# TODO figure out how to implement this
|
|
36
|
-
dispatcherCallableNameDEFAULT = "doTheNeedful"
|
|
50
|
+
# =============================================================================
|
|
51
|
+
# The Wrong Way The Wrong Way The Wrong Way The Wrong Way The Wrong Way
|
|
52
|
+
# Evaluate When Installing Evaluate When Installing Evaluate When Installing
|
|
37
53
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
54
|
+
fileExtensionINSTALLING: str = '.py'
|
|
55
|
+
|
|
56
|
+
def getPathPackageINSTALLING() -> Path:
|
|
57
|
+
pathPackage: Path = Path(inspect_getfile(importlib_import_module(thePackageNameIsPACKAGING)))
|
|
41
58
|
if pathPackage.is_file():
|
|
42
59
|
pathPackage = pathPackage.parent
|
|
43
60
|
return pathPackage
|
|
44
61
|
|
|
62
|
+
# =============================================================================
|
|
63
|
+
# The Wrong Way The Wrong Way The Wrong Way The Wrong Way The Wrong Way
|
|
64
|
+
# Hardcoding Hardcoding Hardcoding Hardcoding Hardcoding Hardcoding Hardcoding
|
|
65
|
+
|
|
66
|
+
# =============================================================================
|
|
67
|
+
# The right way, perhaps.
|
|
68
|
+
|
|
69
|
+
# =====================
|
|
70
|
+
# Create enduring identifiers from the hopefully transient identifiers above.
|
|
71
|
+
thePackageName: Final[str] = thePackageNameIsPACKAGING
|
|
72
|
+
thePathPackage: Path = getPathPackageINSTALLING()
|
|
73
|
+
|
|
74
|
+
"""
|
|
75
|
+
NOTE on semiotics: `theIdentifier` vs `identifier`
|
|
76
|
+
|
|
77
|
+
- This package has a typical, "hardcoded" algorithm for counting map folds.
|
|
78
|
+
- This package has logic for transforming that algorithm into other forms.
|
|
79
|
+
- The transformation logic can transform other algorithms if 1) they are similar enough to the "hardcoded" algorithm and 2) I have written the transformation logic well enough to handle the differences.
|
|
80
|
+
- To avoid confusion and namespace collisions, I differentiate between, for example, `theSourceAlgorithm` of the package and any other `sourceAlgorithm` being transformed by the package.
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
theSourceAlgorithm: str = sourceAlgorithmPACKAGING
|
|
84
|
+
theDatatypePackage: Final[str] = datatypePackagePACKAGING
|
|
85
|
+
|
|
86
|
+
theDispatcherCallableAsStr: str = dispatcherCallableAsStrPACKAGING
|
|
87
|
+
|
|
88
|
+
theDataclassModuleAsStr: str = dataclassModuleAsStrPACKAGING
|
|
89
|
+
theDataclassIdentifierAsStr: str = dataclassIdentifierAsStrPACKAGING
|
|
90
|
+
theDataclassInstanceAsStr: str = dataclassInstanceAsStrPACKAGING
|
|
91
|
+
theDataclassInstance_Pre_ParallelAsStr: str = dataclassInstance_Pre_ParallelAsStrPACKAGING
|
|
92
|
+
theDataclassInstance_Post_ParallelAsStr: str = dataclassInstance_Post_ParallelAsStrPACKAGING
|
|
93
|
+
|
|
94
|
+
theFileExtension: str = fileExtensionINSTALLING
|
|
95
|
+
|
|
96
|
+
theModuleOfSyntheticModules: Final[str] = moduleOfSyntheticModulesPACKAGING
|
|
97
|
+
|
|
98
|
+
Z0Z_initializeCallableAsStr = Z0Z_initializeCallableAsStrPACKAGING
|
|
99
|
+
Z0Z_sequentialCallableAsStr = Z0Z_sequentialCallableAsStrPACKAGING
|
|
100
|
+
Z0Z_parallelCallableAsStr = Z0Z_parallelCallableAsStrPACKAGING
|
|
101
|
+
|
|
102
|
+
# =============================================================================
|
|
103
|
+
# The right way.
|
|
104
|
+
concurrencyPackage: str = Z0Z_packageFlow
|
|
105
|
+
|
|
106
|
+
# =============================================================================
|
|
107
|
+
# The relatively flexible type system needs a different paradigm, but I don't
|
|
108
|
+
# know what it should be. The system needs to 1) help optimize computation, 2)
|
|
109
|
+
# make it possible to change the basic type of the package (e.g., from numpy
|
|
110
|
+
# to superTypePy), 3) make it possible to synthesize the optimized flow of used
|
|
111
|
+
# by the package, and 4) make it possible to synthesize arbitrary modules with
|
|
112
|
+
# different type systems.
|
|
113
|
+
|
|
114
|
+
DatatypeLeavesTotal: TypeAlias = int
|
|
115
|
+
# this would be uint8, but mapShape (2,2,2,2, 2,2,2,2) has 256 leaves, so generic containers accommodate
|
|
116
|
+
numpyLeavesTotal: TypeAlias = numpy_int16
|
|
117
|
+
|
|
118
|
+
DatatypeElephino: TypeAlias = int
|
|
119
|
+
numpyElephino: TypeAlias = numpy_int16
|
|
120
|
+
|
|
121
|
+
DatatypeFoldsTotal: TypeAlias = int
|
|
122
|
+
numpyFoldsTotal: TypeAlias = numpy_int64
|
|
123
|
+
numpyDtypeDefault = numpyFoldsTotal
|
|
124
|
+
|
|
125
|
+
Array3D: TypeAlias = ndarray[tuple[int, int, int], dtype[numpyLeavesTotal]]
|
|
126
|
+
Array1DLeavesTotal: TypeAlias = ndarray[tuple[int], dtype[numpyLeavesTotal]]
|
|
127
|
+
Array1DElephino: TypeAlias = ndarray[tuple[int], dtype[numpyElephino]]
|
|
128
|
+
Array1DFoldsTotal: TypeAlias = ndarray[tuple[int], dtype[numpyFoldsTotal]]
|
|
129
|
+
|
|
130
|
+
# =============================================================================
|
|
131
|
+
# The right way.
|
|
132
|
+
# (The dataclass, not the typing of the dataclass.)
|
|
133
|
+
# (Also, my noobplementation of the dataclass certainly needs improvement.)
|
|
134
|
+
|
|
135
|
+
@dataclasses.dataclass
|
|
136
|
+
class ComputationState:
|
|
137
|
+
mapShape: tuple[DatatypeLeavesTotal, ...]
|
|
138
|
+
leavesTotal: DatatypeLeavesTotal
|
|
139
|
+
taskDivisions: DatatypeLeavesTotal
|
|
140
|
+
|
|
141
|
+
connectionGraph: Array3D = dataclasses.field(init=False, metadata={'description': 'A 3D array representing the connection graph of the map.'})
|
|
142
|
+
dimensionsTotal: DatatypeLeavesTotal = dataclasses.field(init=False)
|
|
143
|
+
|
|
144
|
+
countDimensionsGapped: Array1DLeavesTotal = dataclasses.field(default=None) # pyright: ignore[reportAssignmentType]
|
|
145
|
+
dimensionsUnconstrained: DatatypeLeavesTotal = dataclasses.field(default=None) # pyright: ignore[reportAssignmentType]
|
|
146
|
+
gapRangeStart: Array1DElephino = dataclasses.field(default=None) # pyright: ignore[reportAssignmentType]
|
|
147
|
+
gapsWhere: Array1DLeavesTotal = dataclasses.field(default=None) # pyright: ignore[reportAssignmentType]
|
|
148
|
+
leafAbove: Array1DLeavesTotal = dataclasses.field(default=None) # pyright: ignore[reportAssignmentType]
|
|
149
|
+
leafBelow: Array1DLeavesTotal = dataclasses.field(default=None) # pyright: ignore[reportAssignmentType]
|
|
150
|
+
foldGroups: Array1DFoldsTotal = dataclasses.field(default=None) # pyright: ignore[reportAssignmentType]
|
|
151
|
+
|
|
152
|
+
foldsTotal: DatatypeFoldsTotal = DatatypeFoldsTotal(0)
|
|
153
|
+
gap1ndex: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
|
|
154
|
+
gap1ndexCeiling: DatatypeElephino = DatatypeElephino(0)
|
|
155
|
+
groupsOfFolds: DatatypeFoldsTotal = DatatypeFoldsTotal(0)
|
|
156
|
+
indexDimension: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
|
|
157
|
+
indexLeaf: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
|
|
158
|
+
indexMiniGap: DatatypeElephino = DatatypeElephino(0)
|
|
159
|
+
leaf1ndex: DatatypeElephino = DatatypeElephino(1)
|
|
160
|
+
leafConnectee: DatatypeElephino = DatatypeElephino(0)
|
|
161
|
+
taskIndex: DatatypeLeavesTotal = dataclasses.field(default=DatatypeLeavesTotal(0), metadata={'myType': DatatypeLeavesTotal})
|
|
162
|
+
# taskIndex: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
|
|
163
|
+
|
|
164
|
+
def __post_init__(self):
|
|
165
|
+
from mapFolding.beDRY import makeConnectionGraph, makeDataContainer
|
|
166
|
+
self.dimensionsTotal = DatatypeLeavesTotal(len(self.mapShape))
|
|
167
|
+
self.connectionGraph = makeConnectionGraph(self.mapShape, self.leavesTotal, numpyLeavesTotal)
|
|
168
|
+
|
|
169
|
+
if self.dimensionsUnconstrained is None: # pyright: ignore[reportUnnecessaryComparison]
|
|
170
|
+
self.dimensionsUnconstrained = DatatypeLeavesTotal(int(self.dimensionsTotal))
|
|
171
|
+
|
|
172
|
+
if self.foldGroups is None:
|
|
173
|
+
self.foldGroups = makeDataContainer(max(2, int(self.taskDivisions) + 1), numpyFoldsTotal)
|
|
174
|
+
self.foldGroups[-1] = self.leavesTotal
|
|
175
|
+
|
|
176
|
+
leavesTotalAsInt = int(self.leavesTotal)
|
|
177
|
+
|
|
178
|
+
if self.countDimensionsGapped is None:
|
|
179
|
+
self.countDimensionsGapped = makeDataContainer(leavesTotalAsInt + 1, numpyElephino)
|
|
180
|
+
if self.gapRangeStart is None:
|
|
181
|
+
self.gapRangeStart = makeDataContainer(leavesTotalAsInt + 1, numpyLeavesTotal)
|
|
182
|
+
if self.gapsWhere is None:
|
|
183
|
+
self.gapsWhere = makeDataContainer(leavesTotalAsInt * leavesTotalAsInt + 1, numpyLeavesTotal)
|
|
184
|
+
if self.leafAbove is None:
|
|
185
|
+
self.leafAbove = makeDataContainer(leavesTotalAsInt + 1, numpyLeavesTotal)
|
|
186
|
+
if self.leafBelow is None:
|
|
187
|
+
self.leafBelow = makeDataContainer(leavesTotalAsInt + 1, numpyLeavesTotal)
|
|
188
|
+
|
|
189
|
+
def getFoldsTotal(self):
|
|
190
|
+
self.foldsTotal = DatatypeFoldsTotal(self.foldGroups[0:-1].sum() * self.leavesTotal)
|
|
191
|
+
|
|
192
|
+
# factory? constructor?
|
|
193
|
+
# state.taskIndex = state.taskIndex.type(indexSherpa)
|
|
194
|
+
# self.fieldName = self.fieldName.fieldType(indexSherpa)
|
|
195
|
+
# state.taskIndex.toMyType(indexSherpa)
|
|
196
|
+
|
|
197
|
+
# =============================================================================
|
|
198
|
+
# The most right way I know how to implement.
|
|
199
|
+
|
|
200
|
+
theLogicalPathModuleSourceAlgorithm: str = '.'.join([thePackageName, theSourceAlgorithm])
|
|
201
|
+
theLogicalPathModuleDispatcher: str = theLogicalPathModuleSourceAlgorithm
|
|
202
|
+
theLogicalPathModuleDataclass: str = '.'.join([thePackageName, theDataclassModuleAsStr])
|
|
203
|
+
|
|
204
|
+
def getSourceAlgorithm() -> ModuleType:
|
|
205
|
+
moduleImported: ModuleType = importlib_import_module(theLogicalPathModuleSourceAlgorithm)
|
|
206
|
+
return moduleImported
|
|
207
|
+
|
|
208
|
+
def getAlgorithmDispatcher():
|
|
209
|
+
moduleImported: ModuleType = getSourceAlgorithm()
|
|
210
|
+
# TODO I think I need to use `inspect` to type the return value
|
|
211
|
+
dispatcherCallable = getattr(moduleImported, theDispatcherCallableAsStr)
|
|
212
|
+
return dispatcherCallable
|
|
213
|
+
|
|
214
|
+
def getPathSyntheticModules() -> Path:
|
|
215
|
+
return thePathPackage / theModuleOfSyntheticModules
|
|
216
|
+
|
|
217
|
+
# TODO learn how to see this from the user's perspective
|
|
45
218
|
def getPathJobRootDEFAULT() -> Path:
|
|
46
219
|
if 'google.colab' in sysModules:
|
|
47
|
-
pathJobDEFAULT = Path("/content/drive/MyDrive") / "jobs"
|
|
220
|
+
pathJobDEFAULT: Path = Path("/content/drive/MyDrive") / "jobs"
|
|
48
221
|
else:
|
|
49
|
-
pathJobDEFAULT =
|
|
222
|
+
pathJobDEFAULT = thePathPackage / "jobs"
|
|
50
223
|
return pathJobDEFAULT
|
|
51
224
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
#
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
Z0Z_identifierCountFolds = 'groupsOfFolds'
|
|
102
|
-
|
|
103
|
-
class ParametersNumba(TypedDict):
|
|
104
|
-
_dbg_extend_lifetimes: NotRequired[bool]
|
|
105
|
-
_dbg_optnone: NotRequired[bool]
|
|
106
|
-
_nrt: NotRequired[bool]
|
|
107
|
-
boundscheck: NotRequired[bool]
|
|
108
|
-
cache: bool
|
|
109
|
-
debug: NotRequired[bool]
|
|
110
|
-
error_model: str
|
|
111
|
-
fastmath: bool
|
|
112
|
-
forceinline: bool
|
|
113
|
-
forceobj: NotRequired[bool]
|
|
114
|
-
inline: str
|
|
115
|
-
locals: NotRequired[dict[str, Any]]
|
|
116
|
-
looplift: bool
|
|
117
|
-
no_cfunc_wrapper: bool
|
|
118
|
-
no_cpython_wrapper: bool
|
|
119
|
-
no_rewrites: NotRequired[bool]
|
|
120
|
-
nogil: NotRequired[bool]
|
|
121
|
-
nopython: bool
|
|
122
|
-
parallel: bool
|
|
123
|
-
pipeline_class: NotRequired[type[numbaCompilerBase]]
|
|
124
|
-
signature_or_function: NotRequired[Any | Callable[..., Any] | str | tuple[Any, ...]]
|
|
125
|
-
target: NotRequired[str]
|
|
126
|
-
|
|
127
|
-
parametersNumbaFailEarly: Final[ParametersNumba] = { '_nrt': True, 'boundscheck': True, 'cache': True, 'error_model': 'python', 'fastmath': False, 'forceinline': True, 'inline': 'always', 'looplift': False, 'no_cfunc_wrapper': False, 'no_cpython_wrapper': False, 'nopython': True, 'parallel': False, }
|
|
128
|
-
"""For a production function: speed is irrelevant, error discovery is paramount, must be compatible with anything downstream."""
|
|
129
|
-
|
|
130
|
-
parametersNumbaDEFAULT: Final[ParametersNumba] = { '_nrt': True, 'boundscheck': False, 'cache': True, 'error_model': 'numpy', 'fastmath': True, 'forceinline': True, 'inline': 'always', 'looplift': False, 'no_cfunc_wrapper': False, 'no_cpython_wrapper': False, 'nopython': True, 'parallel': False, }
|
|
131
|
-
"""Middle of the road: fast, lean, but will talk to non-jitted functions."""
|
|
132
|
-
|
|
133
|
-
parametersNumbaParallelDEFAULT: Final[ParametersNumba] = { **parametersNumbaDEFAULT, '_nrt': True, 'parallel': True, }
|
|
134
|
-
"""Middle of the road: fast, lean, but will talk to non-jitted functions."""
|
|
135
|
-
|
|
136
|
-
parametersNumbaSuperJit: Final[ParametersNumba] = { **parametersNumbaDEFAULT, 'no_cfunc_wrapper': True, 'no_cpython_wrapper': True, }
|
|
137
|
-
"""Speed, no helmet, no talking to non-jitted functions."""
|
|
138
|
-
|
|
139
|
-
parametersNumbaSuperJitParallel: Final[ParametersNumba] = { **parametersNumbaSuperJit, '_nrt': True, 'parallel': True, }
|
|
140
|
-
"""Speed, no helmet, concurrency, no talking to non-jitted functions."""
|
|
141
|
-
|
|
142
|
-
parametersNumbaMinimum: Final[ParametersNumba] = { '_nrt': True, 'boundscheck': True, 'cache': True, 'error_model': 'numpy', 'fastmath': True, 'forceinline': False, 'inline': 'always', 'looplift': False, 'no_cfunc_wrapper': False, 'no_cpython_wrapper': False, 'nopython': False, 'forceobj': True, 'parallel': False, }
|
|
225
|
+
_datatypePackage: str = ''
|
|
226
|
+
def getDatatypePackage() -> str:
|
|
227
|
+
global _datatypePackage
|
|
228
|
+
if not _datatypePackage:
|
|
229
|
+
_datatypePackage = theDatatypePackage
|
|
230
|
+
return _datatypePackage
|
|
231
|
+
|
|
232
|
+
def getNumpyDtypeDefault() -> type[signedinteger[Any]]:
|
|
233
|
+
return numpyDtypeDefault
|
|
234
|
+
|
|
235
|
+
# =============================================================================
|
|
236
|
+
# The coping way.
|
|
237
|
+
|
|
238
|
+
class FREAKOUT(Exception): pass
|
|
239
|
+
|
|
240
|
+
# =============================================================================
|
|
241
|
+
# Temporary or transient or something; probably still the wrong way
|
|
242
|
+
|
|
243
|
+
# THIS IS A STUPID SYSTEM BUT I CAN'T FIGURE OUT AN IMPROVEMENT
|
|
244
|
+
theFormatStrModuleSynthetic = "{packageFlow}Count"
|
|
245
|
+
theFormatStrModuleForCallableSynthetic = theFormatStrModuleSynthetic + "_{callableTarget}"
|
|
246
|
+
|
|
247
|
+
theModuleDispatcherSynthetic: str = theFormatStrModuleForCallableSynthetic.format(packageFlow=packageFlowSynthetic, callableTarget=theDispatcherCallableAsStr)
|
|
248
|
+
theLogicalPathModuleDispatcherSynthetic: str = '.'.join([thePackageName, theModuleOfSyntheticModules, theModuleDispatcherSynthetic])
|
|
249
|
+
|
|
250
|
+
# =============================================================================
|
|
251
|
+
# The most right way I know how to implement.
|
|
252
|
+
|
|
253
|
+
if Z0Z_packageFlow == packageFlowSynthetic: # pyright: ignore [reportUnnecessaryComparison]
|
|
254
|
+
theLogicalPathModuleDispatcher = theLogicalPathModuleDispatcherSynthetic
|
|
255
|
+
|
|
256
|
+
def getPackageDispatcher():
|
|
257
|
+
moduleImported: ModuleType = importlib_import_module(theLogicalPathModuleDispatcher)
|
|
258
|
+
dispatcherCallable = getattr(moduleImported, theDispatcherCallableAsStr)
|
|
259
|
+
from mapFolding.syntheticModules.numbaCountSequential import flattenData
|
|
260
|
+
dispatcherCallable = flattenData
|
|
261
|
+
return dispatcherCallable
|
|
262
|
+
|
|
263
|
+
"""Technical concepts I am likely using and likely want to use more effectively:
|
|
264
|
+
- Configuration Registry
|
|
265
|
+
- Write-Once, Read-Many (WORM) / Immutable Initialization
|
|
266
|
+
- Lazy Initialization
|
|
267
|
+
- Separate configuration from business logic
|
|
268
|
+
|
|
269
|
+
theSSOT and yourSSOT
|
|
270
|
+
|
|
271
|
+
delay realization/instantiation until a concrete value is desired
|
|
272
|
+
moment of truth: when the value is needed, not when the value is defined
|
|
273
|
+
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: mapFolding
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Count distinct ways to fold a map (or a strip of stamps)
|
|
5
5
|
Author-email: Hunter Hogan <HunterHogan@pm.me>
|
|
6
6
|
License: CC-BY-NC-4.0
|
|
@@ -8,7 +8,7 @@ Project-URL: Donate, https://www.patreon.com/integrated
|
|
|
8
8
|
Project-URL: Homepage, https://github.com/hunterhogan/mapFolding
|
|
9
9
|
Project-URL: Repository, https://github.com/hunterhogan/mapFolding.git
|
|
10
10
|
Keywords: A001415,A001416,A001417,A001418,A195646,combinatorics,folding,map folding,OEIS,optimization,stamp folding
|
|
11
|
-
Classifier: Development Status ::
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
12
|
Classifier: Environment :: Console
|
|
13
13
|
Classifier: Intended Audience :: Education
|
|
14
14
|
Classifier: Intended Audience :: End Users/Desktop
|
|
@@ -16,30 +16,32 @@ Classifier: Intended Audience :: Other Audience
|
|
|
16
16
|
Classifier: Intended Audience :: Science/Research
|
|
17
17
|
Classifier: Natural Language :: English
|
|
18
18
|
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
21
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
22
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
23
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
24
|
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
-
Classifier: Programming Language :: Python :: 3
|
|
24
|
-
Classifier: Programming Language :: Python
|
|
25
25
|
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
26
26
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
27
27
|
Classifier: Typing :: Typed
|
|
28
28
|
Requires-Python: >=3.10
|
|
29
29
|
Description-Content-Type: text/markdown
|
|
30
30
|
License-File: LICENSE
|
|
31
|
+
Requires-Dist: autoflake
|
|
32
|
+
Requires-Dist: more_itertools
|
|
33
|
+
Requires-Dist: numba_progress
|
|
31
34
|
Requires-Dist: numba
|
|
32
35
|
Requires-Dist: numpy
|
|
36
|
+
Requires-Dist: python_minifier
|
|
37
|
+
Requires-Dist: tomli
|
|
33
38
|
Requires-Dist: Z0Z_tools
|
|
34
39
|
Provides-Extra: testing
|
|
35
|
-
Requires-Dist: autoflake; extra == "testing"
|
|
36
40
|
Requires-Dist: mypy; extra == "testing"
|
|
37
|
-
Requires-Dist: more_itertools; extra == "testing"
|
|
38
41
|
Requires-Dist: pytest-cov; extra == "testing"
|
|
39
42
|
Requires-Dist: pytest-env; extra == "testing"
|
|
40
43
|
Requires-Dist: pytest-xdist; extra == "testing"
|
|
41
44
|
Requires-Dist: pytest; extra == "testing"
|
|
42
|
-
Requires-Dist: python_minifier; extra == "testing"
|
|
43
45
|
Requires-Dist: pyupgrade; extra == "testing"
|
|
44
46
|
Requires-Dist: updateCitation; extra == "testing"
|
|
45
47
|
|
|
@@ -153,4 +155,4 @@ Available OEIS sequences:
|
|
|
153
155
|
[](https://HunterThinks.com/support)
|
|
154
156
|
[](https://www.youtube.com/@HunterHogan)
|
|
155
157
|
|
|
156
|
-
[](https://creativecommons.org/licenses/by-nc/4.0/)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
mapFolding/__init__.py,sha256=dg1pzBxbhIY8FRtS2uphqL7YwUwR5uxZ5epduKhl3Y8,189
|
|
2
|
+
mapFolding/basecamp.py,sha256=H-cZeoDhKftRwZu1Q_Xo66lCweVEtB0ChqJY_GNEfdI,3835
|
|
3
|
+
mapFolding/beDRY.py,sha256=WsXAPbjFfjO0bVFq8GGbEdEP9lmrYTaZxzIWpO9s3ok,8209
|
|
4
|
+
mapFolding/filesystem.py,sha256=TfvvIXnlLU6NNZrrY9T9Wk9cIGksvDjeI-JgsKHdsLY,3767
|
|
5
|
+
mapFolding/noHomeYet.py,sha256=HjxLP-7BGVkKL66T50q4BWnC0Cg2gHUeCKMFuwR2mEQ,785
|
|
6
|
+
mapFolding/oeis.py,sha256=xqnL_VyhwRBET-Kdpnf59K5W5metGbW0JiufTlVw7g0,11853
|
|
7
|
+
mapFolding/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
mapFolding/theDao.py,sha256=Bcd-VmZfarxdsdyFh40XdURrMPjV2QIO0WoMJ6AS6hw,8054
|
|
9
|
+
mapFolding/theSSOT.py,sha256=1-trVx4JHT2twT5gmKY5cCdZ2gLSKjScMBzE9QiyIXo,12594
|
|
10
|
+
mapFolding/reference/flattened.py,sha256=S6D9wiFTlbeoetEqaMLOcA-R22BHOzjqPRujffNxxUM,14875
|
|
11
|
+
mapFolding/reference/hunterNumba.py,sha256=jDS0ORHkIhcJ1rzA5hT49sZHKf3rgJOoGesUCcbKFFY,6054
|
|
12
|
+
mapFolding/reference/irvineJavaPort.py,sha256=7GvBU0tnS6wpFgkYad3465do9jBQW-2bYvbCYyABPHM,3341
|
|
13
|
+
mapFolding/reference/jax.py,sha256=7ji9YWia6Kof0cjcNdiS1GG1rMbC5SBjcyVr_07AeUk,13845
|
|
14
|
+
mapFolding/reference/lunnan.py,sha256=iAbJELfW6RKNMdPcBY9b6rGQ-z1zoRf-1XCurCRMOo8,3951
|
|
15
|
+
mapFolding/reference/lunnanNumpy.py,sha256=rwVP3WIDXimpAuaxhRIuBYU56nVDTKlfGiclw_FkgUU,3765
|
|
16
|
+
mapFolding/reference/lunnanWhile.py,sha256=uRrMT23jTJvoQDlD_FzeIQe_pfMXJG6_bRvs7uhC8z0,3271
|
|
17
|
+
mapFolding/reference/rotatedEntryPoint.py,sha256=USZY3n3zwhSE68ATscUuN66t1qShuEbMI790Gz9JFTw,9352
|
|
18
|
+
mapFolding/reference/total_countPlus1vsPlusN.py,sha256=wpgay-uqPOBd64Z4Pg6tg40j7-4pzWHGMM6v0bnmjhE,6288
|
|
19
|
+
mapFolding/someAssemblyRequired/Z0Z_workbench.py,sha256=wkTqYlzi-okXloPCg4IHpThq97vuyCzrLSn1wsF6-_0,1627
|
|
20
|
+
mapFolding/someAssemblyRequired/__init__.py,sha256=pYkG-1LM8emzTeQbGtOfiZsAiklm5DU92-WE63qB-9s,602
|
|
21
|
+
mapFolding/someAssemblyRequired/getLLVMforNoReason.py,sha256=sGDzg5HG21Q42M0upRD1NWzOUsd7mZ_9wUKJIQHI13o,1000
|
|
22
|
+
mapFolding/someAssemblyRequired/ingredientsNumba.py,sha256=HnWgo1KwIoevUrE5A1WZh4AVFXKQllt8L6RL46JTXEg,2787
|
|
23
|
+
mapFolding/someAssemblyRequired/synthesizeCountingFunctions.py,sha256=77iNPPsN8BmwHaYKdXcDKCwoZKS1g41CJNenQB0W-eg,252
|
|
24
|
+
mapFolding/someAssemblyRequired/synthesizeDataConverters.py,sha256=qNedUaXxU107x3OBx1AHcSEQPM3bMe5ym-GfpJ9O0bc,6237
|
|
25
|
+
mapFolding/someAssemblyRequired/synthesizeNumba.py,sha256=cKXvp0BxmYayUBMQ2RJLkVoJUSvzPI1S4Wy_APRM5cI,4788
|
|
26
|
+
mapFolding/someAssemblyRequired/synthesizeNumbaJob.py,sha256=w7zLUzLrLXf2N6O75jKvXDoyTJemWB8GOdK4ryqSWbs,22700
|
|
27
|
+
mapFolding/someAssemblyRequired/synthesizeNumbaModules.py,sha256=zUclYPmAr6X5qFO3nQK1_HHqdiRq6j3EIBXjeax_b8c,4388
|
|
28
|
+
mapFolding/someAssemblyRequired/transformationTools.py,sha256=FwaZlwMnfzoGvtax5GQSjkyBWr5atMo2VFxPHaBwuNA,21019
|
|
29
|
+
mapFolding/someAssemblyRequired/whatWillBe.py,sha256=ue_NsFN3Z6IxlTgVOaikG8GCiXz9Dk1dvNlypOWMcG0,12188
|
|
30
|
+
mapFolding/syntheticModules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
+
mapFolding/syntheticModules/dataNamespaceFlattened.py,sha256=vsU4PDEMoEcZ424AzsXOJoXoVlX_bSk-pXSTlDsSN9k,2939
|
|
32
|
+
mapFolding/syntheticModules/numbaCount.py,sha256=znFV9RhZ0WqPA-r-DT92WDgZXUyhdQlrsKmnsGySuKc,4561
|
|
33
|
+
mapFolding/syntheticModules/numbaCountExample.py,sha256=Oo0Xeex89sLD15iRt3N76OKRFScKl9qwO84-d5sv6lM,11871
|
|
34
|
+
mapFolding/syntheticModules/numbaCountSequential.py,sha256=iJ-IyzXv0c41uugceJGIHutdzJpkhqbTj0ic_3DqHEM,4326
|
|
35
|
+
mapFolding/syntheticModules/numbaCount_doTheNeedful.py,sha256=J9wZ9PW5EVduOQWVze7CgpTHkUjRIvBPG8fNuT3IVpA,1145
|
|
36
|
+
mapFolding/syntheticModules/numba_doTheNeedful.py,sha256=8kgV2GGjy_nxVi9o_aAtrZzRSxsYr8HVNsVXesf4Kec,767
|
|
37
|
+
mapFolding/syntheticModules/numba_doTheNeedfulExample.py,sha256=J9wZ9PW5EVduOQWVze7CgpTHkUjRIvBPG8fNuT3IVpA,1145
|
|
38
|
+
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
+
tests/conftest.py,sha256=oPc1IS4RXhLQIBskhuawi4GEWhy6kXbM6D2MdX9kDhw,10833
|
|
40
|
+
tests/test_computations.py,sha256=s4ce78iEa9axlknR83NqwXwluX8Z5HN1GtTJ3RyXuzQ,3240
|
|
41
|
+
tests/test_filesystem.py,sha256=7Ova6f4R6lI9rwnnu8SkZgficTYlKEhSzLp-nBRWESM,3183
|
|
42
|
+
tests/test_oeis.py,sha256=uxvwmgbnylSDdsVJfuAT0LuYLbIVFwSgdLxHm-xUGBM,5043
|
|
43
|
+
tests/test_other.py,sha256=CS64h5NACYmXhG3owBpPDcXv3BpYlXNeLqPcqT4quwg,4303
|
|
44
|
+
tests/test_tasks.py,sha256=nsrNuGYk49EnTUslZIQTgqEONwuCSlQaPCpoQTkE08k,2849
|
|
45
|
+
mapfolding-0.7.0.dist-info/LICENSE,sha256=NxH5Y8BdC-gNU-WSMwim3uMbID2iNDXJz7fHtuTdXhk,19346
|
|
46
|
+
mapfolding-0.7.0.dist-info/METADATA,sha256=xR40gKDQ001BELktPxoyqtsdz7b6zFVmqdU8zV2qoRg,7696
|
|
47
|
+
mapfolding-0.7.0.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
|
48
|
+
mapfolding-0.7.0.dist-info/entry_points.txt,sha256=F3OUeZR1XDTpoH7k3wXuRb3KF_kXTTeYhu5AGK1SiOQ,146
|
|
49
|
+
mapfolding-0.7.0.dist-info/top_level.txt,sha256=1gP2vFaqPwHujGwb3UjtMlLEGN-943VSYFR7V4gDqW8,17
|
|
50
|
+
mapfolding-0.7.0.dist-info/RECORD,,
|
tests/__init__.py
ADDED
|
File without changes
|