mapFolding 0.9.1__tar.gz → 0.9.3__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.
- {mapfolding-0.9.1 → mapfolding-0.9.3}/PKG-INFO +4 -3
- {mapfolding-0.9.1 → mapfolding-0.9.3}/README.md +1 -1
- mapfolding-0.9.3/mapFolding/Z0Z_flowControl.py +99 -0
- mapfolding-0.9.3/mapFolding/__init__.py +96 -0
- mapfolding-0.9.3/mapFolding/basecamp.py +95 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/beDRY.py +72 -66
- mapfolding-0.9.3/mapFolding/dataBaskets.py +49 -0
- mapfolding-0.9.3/mapFolding/datatypes.py +21 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/oeis.py +57 -75
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/reference/__init__.py +2 -2
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/someAssemblyRequired/__init__.py +6 -4
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/someAssemblyRequired/_theTypes.py +9 -1
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/someAssemblyRequired/_tool_Make.py +0 -1
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/someAssemblyRequired/_tool_Then.py +16 -8
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/someAssemblyRequired/_toolboxAntecedents.py +111 -35
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/someAssemblyRequired/_toolboxContainers.py +58 -49
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/someAssemblyRequired/synthesizeNumbaJob.py +42 -42
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/someAssemblyRequired/toolboxNumba.py +3 -11
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/someAssemblyRequired/transformationTools.py +94 -70
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/syntheticModules/numbaCount.py +9 -11
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/theDao.py +19 -21
- mapfolding-0.9.3/mapFolding/theDaoOfMapFolding.py +142 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/theSSOT.py +36 -58
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/toolboxFilesystem.py +29 -38
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding.egg-info/PKG-INFO +4 -3
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding.egg-info/SOURCES.txt +6 -2
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding.egg-info/requires.txt +1 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/pyproject.toml +4 -2
- {mapfolding-0.9.1 → mapfolding-0.9.3}/tests/__init__.py +2 -2
- {mapfolding-0.9.1 → mapfolding-0.9.3}/tests/conftest.py +7 -7
- {mapfolding-0.9.1 → mapfolding-0.9.3}/tests/test_computations.py +15 -13
- {mapfolding-0.9.1 → mapfolding-0.9.3}/tests/test_other.py +0 -7
- {mapfolding-0.9.1 → mapfolding-0.9.3}/tests/test_tasks.py +2 -2
- mapfolding-0.9.1/mapFolding/__init__.py +0 -93
- mapfolding-0.9.1/mapFolding/basecamp.py +0 -90
- {mapfolding-0.9.1 → mapfolding-0.9.3}/LICENSE +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/py.typed +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/reference/flattened.py +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/reference/hunterNumba.py +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/reference/irvineJavaPort.py +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/reference/jaxCount.py +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/reference/jobsCompleted/[2x19]/p2x19.py +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/reference/jobsCompleted/__init__.py +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/reference/jobsCompleted/p2x19/p2x19.py +0 -0
- /mapfolding-0.9.1/mapFolding/reference/lunnanNumpy.py → /mapfolding-0.9.3/mapFolding/reference/lunnonNumpy.py +0 -0
- /mapfolding-0.9.1/mapFolding/reference/lunnanWhile.py → /mapfolding-0.9.3/mapFolding/reference/lunnonWhile.py +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/reference/rotatedEntryPoint.py +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/reference/total_countPlus1vsPlusN.py +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/someAssemblyRequired/RecipeJob.py +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/someAssemblyRequired/_toolboxPython.py +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/someAssemblyRequired/getLLVMforNoReason.py +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding/syntheticModules/__init__.py +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding.egg-info/dependency_links.txt +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding.egg-info/entry_points.txt +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/mapFolding.egg-info/top_level.txt +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/setup.cfg +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/tests/test_filesystem.py +0 -0
- {mapfolding-0.9.1 → mapfolding-0.9.3}/tests/test_oeis.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mapFolding
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.3
|
|
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
|
|
@@ -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
|
Project-URL: Issues, https://github.com/hunterhogan/mapFolding/issues
|
|
11
|
-
Keywords: A001415,A001416,A001417,A001418,A195646,algorithmic optimization,AST manipulation,code generation,code transformation,combinatorics,computational geometry,dataclass transformation,folding pattern enumeration,just-in-time compilation,map folding,Numba optimization,OEIS,performance optimization,source code analysis,stamp folding
|
|
11
|
+
Keywords: A000136,A001415,A001416,A001417,A001418,A195646,algorithmic optimization,AST manipulation,code generation,code transformation,combinatorics,computational geometry,dataclass transformation,folding pattern enumeration,just-in-time compilation,map folding,Numba optimization,OEIS,performance optimization,source code analysis,stamp folding
|
|
12
12
|
Classifier: Development Status :: 4 - Beta
|
|
13
13
|
Classifier: Environment :: Console
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
@@ -38,6 +38,7 @@ Requires-Dist: numba
|
|
|
38
38
|
Requires-Dist: numpy
|
|
39
39
|
Requires-Dist: platformdirs
|
|
40
40
|
Requires-Dist: python_minifier
|
|
41
|
+
Requires-Dist: sympy
|
|
41
42
|
Requires-Dist: tomli
|
|
42
43
|
Requires-Dist: Z0Z_tools
|
|
43
44
|
Provides-Extra: testing
|
|
@@ -105,7 +106,7 @@ def countFolds_optimized(shape_param):
|
|
|
105
106
|
|
|
106
107
|
### 2. Code Generation Framework
|
|
107
108
|
|
|
108
|
-
Study and extend a complete Python code transformation
|
|
109
|
+
Study and extend a complete Python code transformation assembly line:
|
|
109
110
|
|
|
110
111
|
- AST analysis and manipulation
|
|
111
112
|
- Dataclass decomposition ("shattering")
|
|
@@ -53,7 +53,7 @@ def countFolds_optimized(shape_param):
|
|
|
53
53
|
|
|
54
54
|
### 2. Code Generation Framework
|
|
55
55
|
|
|
56
|
-
Study and extend a complete Python code transformation
|
|
56
|
+
Study and extend a complete Python code transformation assembly line:
|
|
57
57
|
|
|
58
58
|
- AST analysis and manipulation
|
|
59
59
|
- Dataclass decomposition ("shattering")
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
from collections.abc import Sequence
|
|
2
|
+
from mapFolding import (
|
|
3
|
+
ComputationState,
|
|
4
|
+
getPathFilenameFoldsTotal,
|
|
5
|
+
outfitCountFolds,
|
|
6
|
+
saveFoldsTotal,
|
|
7
|
+
saveFoldsTotalFAILearly,
|
|
8
|
+
setProcessorLimit,
|
|
9
|
+
The,
|
|
10
|
+
validateListDimensions,
|
|
11
|
+
)
|
|
12
|
+
from os import PathLike
|
|
13
|
+
from pathlib import PurePath
|
|
14
|
+
|
|
15
|
+
def countFolds(listDimensions: Sequence[int] | None = None
|
|
16
|
+
, pathLikeWriteFoldsTotal: PathLike[str] | PurePath | None = None
|
|
17
|
+
, computationDivisions: int | str | None = None
|
|
18
|
+
, CPUlimit: int | float | bool | None = None
|
|
19
|
+
# , * I need to improve `standardizedEqualToCallableReturn` so it will work with keyword arguments
|
|
20
|
+
, mapShape: tuple[int, ...] | None = None
|
|
21
|
+
, oeisID: str | None = None
|
|
22
|
+
, oeis_n: int | None = None
|
|
23
|
+
, flow: str | None = None
|
|
24
|
+
) -> int:
|
|
25
|
+
"""
|
|
26
|
+
To select the execution path, I need at least:
|
|
27
|
+
- mapShape
|
|
28
|
+
- task division instructions
|
|
29
|
+
- memorialization instructions
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
# mapShape =====================================================================
|
|
33
|
+
|
|
34
|
+
if mapShape:
|
|
35
|
+
pass
|
|
36
|
+
else:
|
|
37
|
+
if oeisID and oeis_n:
|
|
38
|
+
from mapFolding.oeis import settingsOEIS
|
|
39
|
+
try:
|
|
40
|
+
mapShape = settingsOEIS[oeisID]['getMapShape'](oeis_n)
|
|
41
|
+
except KeyError:
|
|
42
|
+
pass
|
|
43
|
+
if not mapShape and listDimensions:
|
|
44
|
+
mapShape = validateListDimensions(listDimensions)
|
|
45
|
+
|
|
46
|
+
if mapShape is None:
|
|
47
|
+
raise ValueError(f"""I received these values:
|
|
48
|
+
`{listDimensions = }`,
|
|
49
|
+
`{mapShape = }`,
|
|
50
|
+
`{oeisID = }` and `{oeis_n = }`,
|
|
51
|
+
but I was unable to select a map for which to count the folds.""")
|
|
52
|
+
|
|
53
|
+
# task division instructions ===============================================
|
|
54
|
+
|
|
55
|
+
if computationDivisions:
|
|
56
|
+
# NOTE `The.concurrencyPackage`
|
|
57
|
+
concurrencyLimit: int = setProcessorLimit(CPUlimit, The.concurrencyPackage)
|
|
58
|
+
from mapFolding.beDRY import getLeavesTotal, getTaskDivisions
|
|
59
|
+
leavesTotal: int = getLeavesTotal(mapShape)
|
|
60
|
+
taskDivisions = getTaskDivisions(computationDivisions, concurrencyLimit, leavesTotal)
|
|
61
|
+
del leavesTotal
|
|
62
|
+
else:
|
|
63
|
+
concurrencyLimit = 1
|
|
64
|
+
taskDivisions = 0
|
|
65
|
+
|
|
66
|
+
# memorialization instructions ===========================================
|
|
67
|
+
|
|
68
|
+
if pathLikeWriteFoldsTotal is not None:
|
|
69
|
+
pathFilenameFoldsTotal = getPathFilenameFoldsTotal(mapShape, pathLikeWriteFoldsTotal)
|
|
70
|
+
saveFoldsTotalFAILearly(pathFilenameFoldsTotal)
|
|
71
|
+
else:
|
|
72
|
+
pathFilenameFoldsTotal = None
|
|
73
|
+
|
|
74
|
+
# Flow control until I can figure out a good way ===============================
|
|
75
|
+
|
|
76
|
+
if flow == 'theDaoOfMapFolding':
|
|
77
|
+
from mapFolding.dataBaskets import MapFoldingState
|
|
78
|
+
mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
|
|
79
|
+
|
|
80
|
+
from mapFolding.theDaoOfMapFolding import doTheNeedful
|
|
81
|
+
mapFoldingState = doTheNeedful(mapFoldingState)
|
|
82
|
+
foldsTotal = mapFoldingState.foldsTotal
|
|
83
|
+
|
|
84
|
+
# NOTE treat this as a default?
|
|
85
|
+
# flow based on `The` and `ComputationState` ====================================
|
|
86
|
+
|
|
87
|
+
else:
|
|
88
|
+
computationStateInitialized: ComputationState = outfitCountFolds(mapShape, computationDivisions, concurrencyLimit)
|
|
89
|
+
computationStateComplete: ComputationState = The.dispatcher(computationStateInitialized)
|
|
90
|
+
|
|
91
|
+
computationStateComplete.getFoldsTotal()
|
|
92
|
+
foldsTotal = computationStateComplete.foldsTotal
|
|
93
|
+
|
|
94
|
+
# Follow memorialization instructions ===========================================
|
|
95
|
+
|
|
96
|
+
if pathFilenameFoldsTotal is not None:
|
|
97
|
+
saveFoldsTotal(pathFilenameFoldsTotal, foldsTotal)
|
|
98
|
+
|
|
99
|
+
return foldsTotal
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Map folding enumeration and counting algorithms with advanced optimization capabilities.
|
|
3
|
+
|
|
4
|
+
This package implements algorithms to count and enumerate the distinct ways a rectangular map can be folded, based on
|
|
5
|
+
the mathematical problem described in Lunnon's 1971 paper. It provides multiple layers of functionality, from high-level
|
|
6
|
+
user interfaces to sophisticated algorithmic optimizations and code transformation tools.
|
|
7
|
+
|
|
8
|
+
Core modules:
|
|
9
|
+
- basecamp: Public API with simplified interfaces for end users
|
|
10
|
+
- theDao: Core computational algorithm using a functional state-transformation approach
|
|
11
|
+
- beDRY: Core utility functions implementing consistent data handling, validation, and resource management across the
|
|
12
|
+
package's computational assembly-line
|
|
13
|
+
- theSSOT: Single Source of Truth for configuration, types, and state management
|
|
14
|
+
- toolboxFilesystem: Cross-platform file management services for storing and retrieving computation results with robust
|
|
15
|
+
error handling and fallback mechanisms
|
|
16
|
+
- oeis: Interface to the Online Encyclopedia of Integer Sequences for known results
|
|
17
|
+
|
|
18
|
+
Extended functionality:
|
|
19
|
+
- someAssemblyRequired: Code transformation framework that optimizes the core algorithm through AST manipulation,
|
|
20
|
+
dataclass transformation, and compilation techniques
|
|
21
|
+
- The system converts readable code into high-performance implementations through a systematic analysis and
|
|
22
|
+
transformation assembly line
|
|
23
|
+
- Provides tools to "shatter" complex dataclasses into primitive components, enabling compatibility with Numba and
|
|
24
|
+
other optimization frameworks
|
|
25
|
+
- Creates specialized implementations tailored for specific input parameters
|
|
26
|
+
|
|
27
|
+
Testing and extension:
|
|
28
|
+
- tests: Comprehensive test suite designed for both verification and extension
|
|
29
|
+
- Provides fixtures and utilities that simplify testing of custom implementations
|
|
30
|
+
- Enables users to validate their own recipes and job configurations with minimal code
|
|
31
|
+
- Offers standardized testing patterns that maintain consistency across the codebase
|
|
32
|
+
- See tests/__init__.py for detailed documentation on extending the test suite
|
|
33
|
+
|
|
34
|
+
Special directories:
|
|
35
|
+
- .cache/: Stores cached data from external sources like OEIS to improve performance
|
|
36
|
+
- syntheticModules/: Contains dynamically generated, optimized implementations of the core algorithm created by the code
|
|
37
|
+
transformation framework
|
|
38
|
+
- reference/: Historical implementations and educational resources for algorithm exploration
|
|
39
|
+
- reference/jobsCompleted/: Contains successful computations for previously unknown values, including first-ever
|
|
40
|
+
calculations for 2x19 and 2x20 maps (OEIS A001415)
|
|
41
|
+
|
|
42
|
+
This package balances algorithm readability and understandability with high-performance computation capabilities,
|
|
43
|
+
allowing users to compute map folding totals for larger dimensions than previously feasible while also providing a
|
|
44
|
+
foundation for exploring advanced code transformation techniques.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
from mapFolding.datatypes import (
|
|
48
|
+
Array1DElephino as Array1DElephino,
|
|
49
|
+
Array1DFoldsTotal as Array1DFoldsTotal,
|
|
50
|
+
Array1DLeavesTotal as Array1DLeavesTotal,
|
|
51
|
+
Array3D as Array3D,
|
|
52
|
+
DatatypeElephino as DatatypeElephino,
|
|
53
|
+
DatatypeFoldsTotal as DatatypeFoldsTotal,
|
|
54
|
+
DatatypeLeavesTotal as DatatypeLeavesTotal,
|
|
55
|
+
NumPyElephino as NumPyElephino,
|
|
56
|
+
NumPyFoldsTotal as NumPyFoldsTotal,
|
|
57
|
+
NumPyIntegerType as NumPyIntegerType,
|
|
58
|
+
NumPyLeavesTotal as NumPyLeavesTotal,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
from mapFolding.theSSOT import (
|
|
62
|
+
ComputationState as ComputationState,
|
|
63
|
+
raiseIfNoneGitHubIssueNumber3 as raiseIfNoneGitHubIssueNumber3,
|
|
64
|
+
The as The,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
from mapFolding.theDao import (
|
|
68
|
+
countInitialize as countInitialize,
|
|
69
|
+
doTheNeedful as doTheNeedful,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
from mapFolding.beDRY import (
|
|
73
|
+
getLeavesTotal as getLeavesTotal,
|
|
74
|
+
getTaskDivisions as getTaskDivisions,
|
|
75
|
+
outfitCountFolds as outfitCountFolds,
|
|
76
|
+
setProcessorLimit as setProcessorLimit,
|
|
77
|
+
validateListDimensions as validateListDimensions,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
from mapFolding.toolboxFilesystem import (
|
|
81
|
+
getPathFilenameFoldsTotal as getPathFilenameFoldsTotal,
|
|
82
|
+
getPathRootJobDEFAULT as getPathRootJobDEFAULT,
|
|
83
|
+
saveFoldsTotal as saveFoldsTotal,
|
|
84
|
+
saveFoldsTotalFAILearly as saveFoldsTotalFAILearly,
|
|
85
|
+
writeStringToHere as writeStringToHere,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
from mapFolding.Z0Z_flowControl import countFolds
|
|
89
|
+
|
|
90
|
+
from mapFolding.oeis import (
|
|
91
|
+
clearOEIScache as clearOEIScache,
|
|
92
|
+
getFoldsTotalKnown as getFoldsTotalKnown,
|
|
93
|
+
getOEISids as getOEISids,
|
|
94
|
+
OEIS_for_n as OEIS_for_n,
|
|
95
|
+
oeisIDfor_n as oeisIDfor_n,
|
|
96
|
+
)
|
|
@@ -0,0 +1,95 @@
|
|
|
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
|
+
|
|
12
|
+
from collections.abc import Sequence
|
|
13
|
+
from mapFolding import (
|
|
14
|
+
ComputationState,
|
|
15
|
+
getPathFilenameFoldsTotal,
|
|
16
|
+
outfitCountFolds,
|
|
17
|
+
saveFoldsTotal,
|
|
18
|
+
saveFoldsTotalFAILearly,
|
|
19
|
+
setProcessorLimit,
|
|
20
|
+
The,
|
|
21
|
+
validateListDimensions,
|
|
22
|
+
)
|
|
23
|
+
from os import PathLike
|
|
24
|
+
from pathlib import PurePath
|
|
25
|
+
|
|
26
|
+
def countFolds(listDimensions: Sequence[int]
|
|
27
|
+
, pathLikeWriteFoldsTotal: PathLike[str] | PurePath | None = None
|
|
28
|
+
, computationDivisions: int | str | None = None
|
|
29
|
+
, CPUlimit: int | float | bool | None = None
|
|
30
|
+
) -> int:
|
|
31
|
+
"""
|
|
32
|
+
Count the total number of possible foldings for a given map dimensions.
|
|
33
|
+
|
|
34
|
+
This function serves as the main public interface to the map folding algorithm, handling all parameter validation,
|
|
35
|
+
computation state management, and result persistence in a user-friendly way.
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
listDimensions
|
|
40
|
+
List of integers representing the dimensions of the map to be folded.
|
|
41
|
+
pathLikeWriteFoldsTotal: None
|
|
42
|
+
Path, filename, or pathFilename to write the total fold count to. If a directory is provided, creates a file
|
|
43
|
+
with a default name based on map dimensions.
|
|
44
|
+
computationDivisions: None
|
|
45
|
+
Whether and how to divide the computational work.
|
|
46
|
+
- `None`: no division of the computation into tasks; sets task divisions to 0.
|
|
47
|
+
- int: directly set the number of task divisions; cannot exceed the map's total leaves.
|
|
48
|
+
- `'maximum'`: divides into `leavesTotal`-many `taskDivisions`.
|
|
49
|
+
- `'cpu'`: limits the divisions to the number of available CPUs: i.e., `concurrencyLimit`.
|
|
50
|
+
CPUlimit: None
|
|
51
|
+
This is only relevant if there are `computationDivisions`: whether and how to limit the CPU usage.
|
|
52
|
+
- `False`, `None`, or `0`: No limits on processor usage; uses all available processors. All other values will
|
|
53
|
+
potentially limit processor usage.
|
|
54
|
+
- `True`: Yes, limit the processor usage; limits to 1 processor.
|
|
55
|
+
- Integer `>= 1`: Limits usage to the specified number of processors.
|
|
56
|
+
- Decimal value (`float`) between 0 and 1: Fraction of total processors to use.
|
|
57
|
+
- Decimal value (`float`) between -1 and 0: Fraction of processors to _not_ use.
|
|
58
|
+
- Integer `<= -1`: Subtract the absolute value from total processors.
|
|
59
|
+
|
|
60
|
+
Returns
|
|
61
|
+
-------
|
|
62
|
+
foldsTotal: Total number of distinct ways to fold a map of the given dimensions.
|
|
63
|
+
|
|
64
|
+
Note well
|
|
65
|
+
---------
|
|
66
|
+
You probably do not want to divide your computation into tasks.
|
|
67
|
+
|
|
68
|
+
If you want to compute a large `foldsTotal`, dividing the computation into tasks is usually a bad idea. Dividing the
|
|
69
|
+
algorithm into tasks is inherently inefficient: efficient division into tasks means there would be no overlap in the
|
|
70
|
+
work performed by each task. When dividing this algorithm, the amount of overlap is between 50% and 90% by all
|
|
71
|
+
tasks: at least 50% of the work done by every task must be done by _all_ tasks. If you improve the computation time,
|
|
72
|
+
it will only change by -10 to -50% depending on (at the very least) the ratio of the map dimensions and the number
|
|
73
|
+
of leaves. If an undivided computation would take 10 hours on your computer, for example, the computation will still
|
|
74
|
+
take at least 5 hours but you might reduce the time to 9 hours. Most of the time, however, you will increase the
|
|
75
|
+
computation time. If logicalCores >= `leavesTotal`, it will probably be faster. If logicalCores <= 2 * `leavesTotal`, it
|
|
76
|
+
will almost certainly be slower for all map dimensions.
|
|
77
|
+
"""
|
|
78
|
+
mapShape: tuple[int, ...] = validateListDimensions(listDimensions)
|
|
79
|
+
concurrencyLimit: int = setProcessorLimit(CPUlimit, The.concurrencyPackage)
|
|
80
|
+
computationStateInitialized: ComputationState = outfitCountFolds(mapShape, computationDivisions, concurrencyLimit)
|
|
81
|
+
|
|
82
|
+
if pathLikeWriteFoldsTotal is not None:
|
|
83
|
+
pathFilenameFoldsTotal = getPathFilenameFoldsTotal(computationStateInitialized.mapShape, pathLikeWriteFoldsTotal)
|
|
84
|
+
saveFoldsTotalFAILearly(pathFilenameFoldsTotal)
|
|
85
|
+
else:
|
|
86
|
+
pathFilenameFoldsTotal = None
|
|
87
|
+
|
|
88
|
+
computationStateComplete: ComputationState = The.dispatcher(computationStateInitialized)
|
|
89
|
+
|
|
90
|
+
computationStateComplete.getFoldsTotal()
|
|
91
|
+
|
|
92
|
+
if pathFilenameFoldsTotal is not None:
|
|
93
|
+
saveFoldsTotal(pathFilenameFoldsTotal, computationStateComplete.foldsTotal)
|
|
94
|
+
|
|
95
|
+
return computationStateComplete.foldsTotal
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Core utility functions implementing DRY (Don't Repeat Yourself) principles for the mapFolding package.
|
|
3
3
|
|
|
4
|
-
This module serves as the foundation for consistent data management and parameter validation
|
|
5
|
-
|
|
4
|
+
This module serves as the foundation for consistent data management and parameter validation across the entire
|
|
5
|
+
mapFolding computation assembly-line. It provides critical utility functions that:
|
|
6
6
|
|
|
7
7
|
1. Calculate and validate fundamental computational parameters such as leaves total and task divisions.
|
|
8
8
|
2. Generate specialized connection graphs that define the folding algorithm's constraints.
|
|
@@ -10,13 +10,12 @@ across the entire mapFolding computation assembly-line. It provides critical uti
|
|
|
10
10
|
4. Construct and manage uniform data structures for the computation state.
|
|
11
11
|
5. Ensure parameter validation and safe type conversion.
|
|
12
12
|
|
|
13
|
-
The functions in this module maintain a clear separation between data initialization and algorithm
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
The functions in this module maintain a clear separation between data initialization and algorithm implementation,
|
|
14
|
+
enabling the package to support multiple computational strategies (sequential, parallel, and JIT-compiled) while
|
|
15
|
+
ensuring consistent input handling and state management.
|
|
16
16
|
|
|
17
|
-
These utilities form a stable internal API that other modules depend on, particularly theSSOT
|
|
18
|
-
|
|
19
|
-
produce optimized implementations.
|
|
17
|
+
These utilities form a stable internal API that other modules depend on, particularly theSSOT (Single Source of Truth),
|
|
18
|
+
theDao (core algorithm), and the synthetic module generators that produce optimized implementations.
|
|
20
19
|
"""
|
|
21
20
|
from collections.abc import Sequence
|
|
22
21
|
from mapFolding import ComputationState, NumPyIntegerType
|
|
@@ -31,8 +30,6 @@ def getLeavesTotal(mapShape: tuple[int, ...]) -> int:
|
|
|
31
30
|
Calculate the total number of leaves in a map with the given dimensions.
|
|
32
31
|
|
|
33
32
|
The total number of leaves is the product of all dimensions in the map shape.
|
|
34
|
-
This value is foundational for initializing the computation state and determining
|
|
35
|
-
task divisions.
|
|
36
33
|
|
|
37
34
|
Parameters
|
|
38
35
|
----------
|
|
@@ -47,8 +44,8 @@ def getLeavesTotal(mapShape: tuple[int, ...]) -> int:
|
|
|
47
44
|
Raises
|
|
48
45
|
------
|
|
49
46
|
OverflowError
|
|
50
|
-
If the product of dimensions would exceed the system's maximum integer size.
|
|
51
|
-
|
|
47
|
+
If the product of dimensions would exceed the system's maximum integer size. This check prevents silent numeric
|
|
48
|
+
overflow issues that could lead to incorrect results.
|
|
52
49
|
"""
|
|
53
50
|
productDimensions = 1
|
|
54
51
|
for dimension in mapShape:
|
|
@@ -113,10 +110,9 @@ def _makeConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int) -> ndarray
|
|
|
113
110
|
"""
|
|
114
111
|
Implementation of connection graph generation for map folding.
|
|
115
112
|
|
|
116
|
-
This is the internal implementation that calculates all possible connections between
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
dimension of the map.
|
|
113
|
+
This is the internal implementation that calculates all possible connections between leaves in a map folding problem
|
|
114
|
+
based on Lunnon's algorithm. The function constructs a three-dimensional array representing which leaves can be
|
|
115
|
+
connected to each other for each dimension of the map.
|
|
120
116
|
|
|
121
117
|
Parameters
|
|
122
118
|
----------
|
|
@@ -128,17 +124,16 @@ def _makeConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int) -> ndarray
|
|
|
128
124
|
Returns
|
|
129
125
|
-------
|
|
130
126
|
connectionGraph
|
|
131
|
-
A 3D NumPy array with shape (`dimensionsTotal`, `leavesTotal`+1, `leavesTotal`+1)
|
|
132
|
-
|
|
133
|
-
when inserting leaf i in dimension d.
|
|
127
|
+
A 3D NumPy array with shape (`dimensionsTotal`, `leavesTotal`+1, `leavesTotal`+1) where each entry [d,i,j]
|
|
128
|
+
represents the leaf that would be connected to leaf j when inserting leaf i in dimension d.
|
|
134
129
|
|
|
135
130
|
Notes
|
|
136
131
|
-----
|
|
137
|
-
This is an implementation detail and shouldn't be called directly by external code.
|
|
138
|
-
|
|
132
|
+
This is an implementation detail and shouldn't be called directly by external code. Use `getConnectionGraph`
|
|
133
|
+
instead, which applies proper typing.
|
|
139
134
|
|
|
140
|
-
The algorithm calculates a coordinate system first, then determines connections
|
|
141
|
-
|
|
135
|
+
The algorithm calculates a coordinate system first, then determines connections based on parity rules, boundary
|
|
136
|
+
conditions, and dimensional constraints.
|
|
142
137
|
"""
|
|
143
138
|
dimensionsTotal = len(mapShape)
|
|
144
139
|
cumulativeProduct = numpy.multiply.accumulate([1] + list(mapShape), dtype=numpy_int64)
|
|
@@ -169,9 +164,9 @@ def getConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int, datatype: ty
|
|
|
169
164
|
"""
|
|
170
165
|
Create a properly typed connection graph for the map folding algorithm.
|
|
171
166
|
|
|
172
|
-
This function serves as a typed wrapper around the internal implementation that
|
|
173
|
-
|
|
174
|
-
|
|
167
|
+
This function serves as a typed wrapper around the internal implementation that generates connection graphs. It
|
|
168
|
+
provides the correct type information for the returned array, ensuring consistency throughout the computation
|
|
169
|
+
assembly-line.
|
|
175
170
|
|
|
176
171
|
Parameters
|
|
177
172
|
----------
|
|
@@ -180,14 +175,14 @@ def getConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int, datatype: ty
|
|
|
180
175
|
leavesTotal
|
|
181
176
|
The total number of leaves in the map.
|
|
182
177
|
datatype
|
|
183
|
-
The NumPy integer type to use for the array elements, ensuring proper
|
|
184
|
-
|
|
178
|
+
The NumPy integer type to use for the array elements, ensuring proper memory usage and compatibility with the
|
|
179
|
+
computation state.
|
|
185
180
|
|
|
186
181
|
Returns
|
|
187
182
|
-------
|
|
188
183
|
connectionGraph
|
|
189
|
-
A 3D NumPy array with shape (`dimensionsTotal`, `leavesTotal`+1, `leavesTotal`+1)
|
|
190
|
-
|
|
184
|
+
A 3D NumPy array with shape (`dimensionsTotal`, `leavesTotal`+1, `leavesTotal`+1) with the specified `datatype`,
|
|
185
|
+
representing all possible connections between leaves.
|
|
191
186
|
"""
|
|
192
187
|
connectionGraph = _makeConnectionGraph(mapShape, leavesTotal)
|
|
193
188
|
connectionGraph = connectionGraph.astype(datatype)
|
|
@@ -197,18 +192,16 @@ def makeDataContainer(shape: int | tuple[int, ...], datatype: type[NumPyIntegerT
|
|
|
197
192
|
"""
|
|
198
193
|
Create a typed NumPy array container with initialized values.
|
|
199
194
|
|
|
200
|
-
This function centralizes the creation of data containers used throughout the
|
|
201
|
-
|
|
202
|
-
or implementation strategies if needed in the future.
|
|
195
|
+
This function centralizes the creation of data containers used throughout the computation assembly-line, enabling
|
|
196
|
+
easy switching between different container types or implementation strategies if needed in the future.
|
|
203
197
|
|
|
204
198
|
Parameters
|
|
205
199
|
----------
|
|
206
200
|
shape
|
|
207
|
-
Either an integer (for 1D arrays) or a tuple of integers (for multi-dimensional arrays)
|
|
208
|
-
|
|
201
|
+
Either an integer (for 1D arrays) or a tuple of integers (for multi-dimensional arrays) specifying the
|
|
202
|
+
dimensions of the array.
|
|
209
203
|
datatype
|
|
210
|
-
The NumPy integer type to use for the array elements, ensuring proper type
|
|
211
|
-
consistency and memory efficiency.
|
|
204
|
+
The NumPy integer type to use for the array elements, ensuring proper type consistency and memory efficiency.
|
|
212
205
|
|
|
213
206
|
Returns
|
|
214
207
|
-------
|
|
@@ -221,18 +214,17 @@ def outfitCountFolds(mapShape: tuple[int, ...], computationDivisions: int | str
|
|
|
221
214
|
"""
|
|
222
215
|
Initialize a `ComputationState` with validated parameters for map folding calculation.
|
|
223
216
|
|
|
224
|
-
This function serves as the central initialization point for creating a properly
|
|
225
|
-
|
|
226
|
-
|
|
217
|
+
This function serves as the central initialization point for creating a properly configured `ComputationState`
|
|
218
|
+
object, ensuring consistent calculation of the fundamental parameters (`leavesTotal` and `taskDivisions`) across the
|
|
219
|
+
entire package.
|
|
227
220
|
|
|
228
221
|
Parameters
|
|
229
222
|
----------
|
|
230
223
|
mapShape
|
|
231
224
|
A tuple of integers representing the dimensions of the map.
|
|
232
225
|
computationDivisions: None
|
|
233
|
-
Controls how to divide the computation into parallel tasks. I know it is annoying,
|
|
234
|
-
|
|
235
|
-
accurate information.
|
|
226
|
+
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.
|
|
236
228
|
concurrencyLimit: 1
|
|
237
229
|
Maximum number of concurrent processes to use during computation.
|
|
238
230
|
|
|
@@ -243,9 +235,8 @@ def outfitCountFolds(mapShape: tuple[int, ...], computationDivisions: int | str
|
|
|
243
235
|
|
|
244
236
|
Notes
|
|
245
237
|
-----
|
|
246
|
-
This function maintains the Single Source of Truth principle for `leavesTotal`
|
|
247
|
-
|
|
248
|
-
throughout the package.
|
|
238
|
+
This function maintains the Single Source of Truth principle for `leavesTotal` and `taskDivisions` calculation,
|
|
239
|
+
ensuring these values are derived consistently throughout the package.
|
|
249
240
|
"""
|
|
250
241
|
leavesTotal = getLeavesTotal(mapShape)
|
|
251
242
|
taskDivisions = getTaskDivisions(computationDivisions, concurrencyLimit, leavesTotal)
|
|
@@ -260,7 +251,8 @@ def setProcessorLimit(CPUlimit: Any | None, concurrencyPackage: str | None = Non
|
|
|
260
251
|
----------
|
|
261
252
|
CPUlimit: None
|
|
262
253
|
Controls processor usage limits:
|
|
263
|
-
- `False`, `None`, or `0`: No limits on processor usage; uses all available processors. All other values will
|
|
254
|
+
- `False`, `None`, or `0`: No limits on processor usage; uses all available processors. All other values will
|
|
255
|
+
potentially limit processor usage.
|
|
264
256
|
- `True`: Yes, limit the processor usage; limits to 1 processor.
|
|
265
257
|
- Integer `>= 1`: Limits usage to the specified number of processors.
|
|
266
258
|
- Decimal value (`float`) between 0 and 1: Fraction of total processors to use.
|
|
@@ -285,12 +277,12 @@ def setProcessorLimit(CPUlimit: Any | None, concurrencyPackage: str | None = Non
|
|
|
285
277
|
|
|
286
278
|
Notes
|
|
287
279
|
-----
|
|
288
|
-
If using `'numba'` as the concurrency package, the maximum number of processors is
|
|
289
|
-
|
|
290
|
-
|
|
280
|
+
If using `'numba'` as the concurrency package, the maximum number of processors is retrieved from
|
|
281
|
+
`numba.get_num_threads()` rather than by polling the hardware. If Numba environment variables limit available
|
|
282
|
+
processors, that will affect this function.
|
|
291
283
|
|
|
292
|
-
When using Numba, this function must be called before importing any Numba-jitted
|
|
293
|
-
|
|
284
|
+
When using Numba, this function must be called before importing any Numba-jitted function for this processor limit
|
|
285
|
+
to affect the Numba-jitted function.
|
|
294
286
|
"""
|
|
295
287
|
if not (CPUlimit is None or isinstance(CPUlimit, (bool, int, float))):
|
|
296
288
|
CPUlimit = oopsieKwargsie(CPUlimit)
|
|
@@ -312,9 +304,9 @@ def validateListDimensions(listDimensions: Sequence[int]) -> tuple[int, ...]:
|
|
|
312
304
|
"""
|
|
313
305
|
Validate and normalize dimensions for a map folding problem.
|
|
314
306
|
|
|
315
|
-
This function serves as the gatekeeper for dimension inputs, ensuring that all
|
|
316
|
-
|
|
317
|
-
|
|
307
|
+
This function serves as the gatekeeper for dimension inputs, ensuring that all map dimensions provided to the
|
|
308
|
+
package meet the requirements for valid computation. It performs multiple validation steps and normalizes the
|
|
309
|
+
dimensions into a consistent format.
|
|
318
310
|
|
|
319
311
|
Parameters
|
|
320
312
|
----------
|
|
@@ -323,8 +315,8 @@ def validateListDimensions(listDimensions: Sequence[int]) -> tuple[int, ...]:
|
|
|
323
315
|
|
|
324
316
|
Returns
|
|
325
317
|
-------
|
|
326
|
-
|
|
327
|
-
|
|
318
|
+
mapShape
|
|
319
|
+
An _unsorted_ tuple of positive integers representing the validated dimensions.
|
|
328
320
|
|
|
329
321
|
Raises
|
|
330
322
|
------
|
|
@@ -335,13 +327,27 @@ def validateListDimensions(listDimensions: Sequence[int]) -> tuple[int, ...]:
|
|
|
335
327
|
"""
|
|
336
328
|
if not listDimensions:
|
|
337
329
|
raise ValueError("`listDimensions` is a required parameter.")
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
for dimension in
|
|
341
|
-
if dimension
|
|
342
|
-
raise ValueError(f"`{dimension = }` in `{listDimensions = }`, must be a non-negative integer.")
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
if len(dimensionsValid) < 2:
|
|
330
|
+
listOFint: list[int] = intInnit(listDimensions, 'listDimensions')
|
|
331
|
+
mapDimensions: list[int] = []
|
|
332
|
+
for dimension in listOFint:
|
|
333
|
+
if dimension <= 0:
|
|
334
|
+
raise ValueError(f"I received `{dimension = }` in `{listDimensions = }`, but all dimensions must be a non-negative integer.")
|
|
335
|
+
mapDimensions.append(dimension)
|
|
336
|
+
if len(mapDimensions) < 2:
|
|
346
337
|
raise NotImplementedError(f"This function requires `{listDimensions = }` to have at least two dimensions greater than 0. You may want to look at https://oeis.org/.")
|
|
347
|
-
|
|
338
|
+
|
|
339
|
+
"""
|
|
340
|
+
I previously sorted the dimensions for a few reasons that may or may not be valid:
|
|
341
|
+
1. After empirical testing, I believe that (2,10), for example, computes significantly faster than (10,2).
|
|
342
|
+
2. Standardization, generally.
|
|
343
|
+
3. If I recall correctly, after empirical testing, I concluded that sorted dimensions always leads to
|
|
344
|
+
non-negative values in the connection graph, but if the dimensions are not in ascending order of magnitude,
|
|
345
|
+
the connection graph might have negative values, which as far as I know, is not an inherent problem, but the
|
|
346
|
+
negative values propagate into other data structures, which requires the datatypes to hold negative values,
|
|
347
|
+
which means I cannot optimize the bit-widths of the datatypes as easily. (And optimized bit-widths helps with
|
|
348
|
+
performance.)
|
|
349
|
+
|
|
350
|
+
Furthermore, now that the package includes OEIS A000136, 1 x N stamps/maps, sorting could distort results.
|
|
351
|
+
"""
|
|
352
|
+
# NOTE Do NOT sort the dimensions.
|
|
353
|
+
return tuple(mapDimensions)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from mapFolding.beDRY import getConnectionGraph, getLeavesTotal, makeDataContainer
|
|
2
|
+
from mapFolding.datatypes import Array3D, Array1DElephino, Array1DLeavesTotal, DatatypeElephino, DatatypeFoldsTotal, DatatypeLeavesTotal
|
|
3
|
+
import dataclasses
|
|
4
|
+
|
|
5
|
+
@dataclasses.dataclass
|
|
6
|
+
class MapFoldingState:
|
|
7
|
+
mapShape: tuple[DatatypeLeavesTotal, ...] = dataclasses.field(init=True, metadata={'elementConstructor': 'DatatypeLeavesTotal'})
|
|
8
|
+
|
|
9
|
+
groupsOfFolds: DatatypeFoldsTotal = dataclasses.field(default=DatatypeFoldsTotal(0), metadata={'theCountingIdentifier': True})
|
|
10
|
+
|
|
11
|
+
gap1ndex: DatatypeElephino = DatatypeElephino(0)
|
|
12
|
+
gap1ndexCeiling: DatatypeElephino = DatatypeElephino(0)
|
|
13
|
+
indexDimension: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
|
|
14
|
+
indexLeaf: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
|
|
15
|
+
indexMiniGap: DatatypeElephino = DatatypeElephino(0)
|
|
16
|
+
leaf1ndex: DatatypeLeavesTotal = DatatypeLeavesTotal(1)
|
|
17
|
+
leafConnectee: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
|
|
18
|
+
|
|
19
|
+
dimensionsUnconstrained: DatatypeLeavesTotal = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
|
|
20
|
+
|
|
21
|
+
countDimensionsGapped: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
|
|
22
|
+
gapRangeStart: Array1DElephino = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DElephino.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
|
|
23
|
+
gapsWhere: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
|
|
24
|
+
leafAbove: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
|
|
25
|
+
leafBelow: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
|
|
26
|
+
|
|
27
|
+
connectionGraph: Array3D = dataclasses.field(init=False, metadata={'dtype': Array3D.__args__[1].__args__[0]}) # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue]
|
|
28
|
+
dimensionsTotal: DatatypeLeavesTotal = dataclasses.field(init=False)
|
|
29
|
+
leavesTotal: DatatypeLeavesTotal = dataclasses.field(init=False)
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def foldsTotal(self) -> DatatypeFoldsTotal:
|
|
33
|
+
_foldsTotal = DatatypeFoldsTotal(self.leavesTotal) * self.groupsOfFolds
|
|
34
|
+
return _foldsTotal
|
|
35
|
+
|
|
36
|
+
def __post_init__(self) -> None:
|
|
37
|
+
self.dimensionsTotal = DatatypeLeavesTotal(len(self.mapShape))
|
|
38
|
+
self.leavesTotal = DatatypeLeavesTotal(getLeavesTotal(self.mapShape))
|
|
39
|
+
|
|
40
|
+
leavesTotalAsInt = int(self.leavesTotal)
|
|
41
|
+
|
|
42
|
+
self.connectionGraph = getConnectionGraph(self.mapShape, leavesTotalAsInt, self.__dataclass_fields__['connectionGraph'].metadata['dtype'])
|
|
43
|
+
|
|
44
|
+
if self.dimensionsUnconstrained is None: self.dimensionsUnconstrained = DatatypeLeavesTotal(int(self.dimensionsTotal)) # pyright: ignore[reportUnnecessaryComparison]
|
|
45
|
+
if self.gapsWhere is None: self.gapsWhere = makeDataContainer(leavesTotalAsInt * leavesTotalAsInt + 1, self.__dataclass_fields__['gapsWhere'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
46
|
+
if self.countDimensionsGapped is None: self.countDimensionsGapped = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['countDimensionsGapped'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
47
|
+
if self.gapRangeStart is None: self.gapRangeStart = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['gapRangeStart'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
48
|
+
if self.leafAbove is None: self.leafAbove = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafAbove'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
49
|
+
if self.leafBelow is None: self.leafBelow = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafBelow'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|