mapFolding 0.12.0__py3-none-any.whl → 0.12.2__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 +42 -18
- mapFolding/_theSSOT.py +137 -0
- mapFolding/basecamp.py +28 -18
- mapFolding/beDRY.py +21 -19
- mapFolding/dataBaskets.py +170 -18
- mapFolding/datatypes.py +109 -1
- mapFolding/filesystemToolkit.py +38 -33
- mapFolding/oeis.py +209 -93
- mapFolding/someAssemblyRequired/RecipeJob.py +120 -9
- mapFolding/someAssemblyRequired/__init__.py +35 -38
- mapFolding/someAssemblyRequired/_toolIfThis.py +80 -18
- mapFolding/someAssemblyRequired/_toolkitContainers.py +123 -45
- mapFolding/someAssemblyRequired/infoBooth.py +37 -2
- mapFolding/someAssemblyRequired/makeAllModules.py +712 -0
- mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +111 -48
- mapFolding/someAssemblyRequired/toolkitNumba.py +171 -19
- mapFolding/someAssemblyRequired/transformationTools.py +93 -49
- mapfolding-0.12.2.dist-info/METADATA +167 -0
- mapfolding-0.12.2.dist-info/RECORD +53 -0
- {mapfolding-0.12.0.dist-info → mapfolding-0.12.2.dist-info}/WHEEL +1 -1
- tests/__init__.py +28 -44
- tests/conftest.py +66 -61
- tests/test_computations.py +39 -82
- tests/test_filesystem.py +25 -1
- tests/test_oeis.py +30 -1
- tests/test_other.py +27 -0
- tests/test_tasks.py +31 -1
- mapFolding/someAssemblyRequired/Z0Z_makeAllModules.py +0 -433
- mapFolding/theSSOT.py +0 -34
- mapfolding-0.12.0.dist-info/METADATA +0 -184
- mapfolding-0.12.0.dist-info/RECORD +0 -53
- {mapfolding-0.12.0.dist-info → mapfolding-0.12.2.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.12.0.dist-info → mapfolding-0.12.2.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.12.0.dist-info → mapfolding-0.12.2.dist-info}/top_level.txt +0 -0
mapFolding/__init__.py
CHANGED
|
@@ -1,20 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
"""Computational toolkit for analyzing multi-dimensional map folding patterns.
|
|
2
|
+
|
|
3
|
+
The mapFolding package provides a complete implementation of Lunnon's 1971 algorithm
|
|
4
|
+
for counting distinct folding patterns in multi-dimensional maps. This toolkit
|
|
5
|
+
transforms the complex combinatorial mathematics of map folding into accessible
|
|
6
|
+
computational tools, enabling researchers and practitioners to analyze folding
|
|
7
|
+
patterns across dimensions from simple 2D strips to complex multi-dimensional
|
|
8
|
+
hypercubes.
|
|
9
|
+
|
|
10
|
+
The package architecture follows Domain-Driven Design principles, organizing
|
|
11
|
+
functionality around mathematical concepts rather than implementation details.
|
|
12
|
+
The computational framework integrates type safety, persistent result storage,
|
|
13
|
+
and mathematical validation through OEIS sequence integration.
|
|
14
|
+
|
|
15
|
+
Core Transformation Tools:
|
|
16
|
+
countFolds: Primary interface for computing folding pattern counts
|
|
17
|
+
MapFoldingState: Computational state management for recursive analysis
|
|
18
|
+
Connection graph generation: Mathematical foundation for folding relationships
|
|
19
|
+
Task division utilities: Experimental parallel computation options
|
|
20
|
+
OEIS integration: Mathematical validation and sequence discovery
|
|
21
|
+
|
|
22
|
+
Primary Use Cases:
|
|
23
|
+
Mathematical research into folding pattern properties and relationships
|
|
24
|
+
Educational exploration of combinatorial mathematics concepts
|
|
25
|
+
Computational validation of theoretical results
|
|
26
|
+
Extension of known mathematical sequences through new discoveries
|
|
27
|
+
|
|
28
|
+
The package handles the full spectrum of map folding analysis, from simple
|
|
29
|
+
educational examples to research-grade computations requiring multi-day processing
|
|
30
|
+
time. Results integrate seamlessly with the mathematical community through
|
|
31
|
+
comprehensive OEIS connectivity and standardized result persistence.
|
|
32
|
+
|
|
33
|
+
For researchers: The computational foundation supports both replication of
|
|
34
|
+
established results and discovery of new mathematical relationships.
|
|
35
|
+
|
|
36
|
+
For educators: The clear interfaces and type safety enable confident exploration
|
|
37
|
+
of combinatorial concepts without computational complexity barriers.
|
|
38
|
+
|
|
39
|
+
For practitioners: The robust result persistence and type safety ensure
|
|
40
|
+
reliable completion of complex analytical tasks.
|
|
41
|
+
"""
|
|
18
42
|
|
|
19
43
|
from mapFolding.datatypes import (
|
|
20
44
|
Array1DElephino as Array1DElephino,
|
|
@@ -30,7 +54,7 @@ from mapFolding.datatypes import (
|
|
|
30
54
|
NumPyLeavesTotal as NumPyLeavesTotal,
|
|
31
55
|
)
|
|
32
56
|
|
|
33
|
-
from mapFolding.
|
|
57
|
+
from mapFolding._theSSOT import PackageSettings as PackageSettings, packageSettings as packageSettings
|
|
34
58
|
|
|
35
59
|
from mapFolding.beDRY import (
|
|
36
60
|
getConnectionGraph as getConnectionGraph,
|
mapFolding/_theSSOT.py
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Foundation layer for the map folding computational ecosystem.
|
|
3
|
+
|
|
4
|
+
This module establishes the fundamental configuration infrastructure that underpins
|
|
5
|
+
all map folding operations. Map folding, as defined by Lunnon's 1971 algorithm,
|
|
6
|
+
requires precise coordination of computational resources, type systems, and data
|
|
7
|
+
flow management to solve the complex combinatorial problem of counting distinct
|
|
8
|
+
folding patterns across multi-dimensional maps.
|
|
9
|
+
|
|
10
|
+
The Single Source Of Truth (SSOT) principle governs this foundation, ensuring that
|
|
11
|
+
package identity, filesystem locations, and concurrency configuration remain
|
|
12
|
+
consistent across all computational phases. During packaging, static metadata is
|
|
13
|
+
resolved from pyproject.toml. During installation, filesystem-dependent paths are
|
|
14
|
+
dynamically discovered. During runtime, the `packageSettings` instance provides
|
|
15
|
+
unified access to all configuration values, enabling the sophisticated computational
|
|
16
|
+
framework that follows.
|
|
17
|
+
|
|
18
|
+
This configuration foundation supports the type system definition, core utility
|
|
19
|
+
functions, computational state management, result persistence, and ultimately the
|
|
20
|
+
main computational interface that users interact with to solve map folding problems.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from importlib import import_module as importlib_import_module
|
|
24
|
+
from inspect import getfile as inspect_getfile
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
from tomli import load as tomli_load
|
|
27
|
+
import dataclasses
|
|
28
|
+
|
|
29
|
+
packageNamePACKAGING_HARDCODED = "mapFolding"
|
|
30
|
+
"""
|
|
31
|
+
Hardcoded package name used as fallback when dynamic resolution fails.
|
|
32
|
+
|
|
33
|
+
This constant serves as the ultimate fallback for package name resolution,
|
|
34
|
+
ensuring the package can function even when pyproject.toml is not accessible
|
|
35
|
+
during packaging or when module introspection fails during installation.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
concurrencyPackageHARDCODED = 'multiprocessing'
|
|
39
|
+
"""
|
|
40
|
+
Default package identifier for concurrent execution operations.
|
|
41
|
+
|
|
42
|
+
Specifies which Python concurrency package should be used as the default
|
|
43
|
+
for parallel computations. This can be overridden through PackageSettings
|
|
44
|
+
to use alternative packages like 'numba' for specialized performance scenarios.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
# Evaluate When Packaging
|
|
48
|
+
# https://github.com/hunterhogan/mapFolding/issues/18
|
|
49
|
+
try:
|
|
50
|
+
packageNamePACKAGING: str = tomli_load(Path("../pyproject.toml").open('rb'))["project"]["name"]
|
|
51
|
+
"""
|
|
52
|
+
Package name dynamically resolved from pyproject.toml during packaging.
|
|
53
|
+
|
|
54
|
+
This value is determined by reading the project configuration file during
|
|
55
|
+
the packaging process, ensuring consistency between the package metadata
|
|
56
|
+
and runtime identification. Falls back to hardcoded value if resolution fails.
|
|
57
|
+
"""
|
|
58
|
+
except Exception:
|
|
59
|
+
packageNamePACKAGING = packageNamePACKAGING_HARDCODED
|
|
60
|
+
|
|
61
|
+
# Evaluate When Installing
|
|
62
|
+
# https://github.com/hunterhogan/mapFolding/issues/18
|
|
63
|
+
def getPathPackageINSTALLING() -> Path:
|
|
64
|
+
"""
|
|
65
|
+
Resolve the absolute filesystem path to the installed package directory.
|
|
66
|
+
|
|
67
|
+
This function determines the package location at runtime by introspecting
|
|
68
|
+
the imported module's file location. It handles both regular Python files
|
|
69
|
+
and package directories, ensuring reliable path resolution across different
|
|
70
|
+
installation methods and environments.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
pathPackage: Absolute path to the package directory containing the module files.
|
|
74
|
+
|
|
75
|
+
Notes:
|
|
76
|
+
The function automatically handles the case where module introspection
|
|
77
|
+
returns a file path by extracting the parent directory, ensuring the
|
|
78
|
+
returned path always points to the package directory itself.
|
|
79
|
+
"""
|
|
80
|
+
pathPackage: Path = Path(inspect_getfile(importlib_import_module(packageNamePACKAGING)))
|
|
81
|
+
if pathPackage.is_file():
|
|
82
|
+
pathPackage = pathPackage.parent
|
|
83
|
+
return pathPackage
|
|
84
|
+
|
|
85
|
+
@dataclasses.dataclass
|
|
86
|
+
class PackageSettings:
|
|
87
|
+
"""
|
|
88
|
+
Centralized configuration container for all package-wide settings.
|
|
89
|
+
|
|
90
|
+
This dataclass serves as the single source of truth for package configuration,
|
|
91
|
+
providing both static and dynamically-resolved values needed throughout the
|
|
92
|
+
package lifecycle. The metadata on each field indicates when that value is
|
|
93
|
+
determined - either during packaging or at installation/runtime.
|
|
94
|
+
|
|
95
|
+
The design supports different evaluation phases to optimize performance and
|
|
96
|
+
reliability:
|
|
97
|
+
- Packaging-time: Values that can be determined during package creation
|
|
98
|
+
- Installing-time: Values that require filesystem access or module introspection
|
|
99
|
+
|
|
100
|
+
Attributes:
|
|
101
|
+
fileExtension: Standard file extension for Python modules in this package.
|
|
102
|
+
packageName: Canonical name of the package as defined in project configuration.
|
|
103
|
+
pathPackage: Absolute filesystem path to the installed package directory.
|
|
104
|
+
concurrencyPackage: Package to use for concurrent execution operations.
|
|
105
|
+
"""
|
|
106
|
+
fileExtension: str = dataclasses.field(default='.py', metadata={'evaluateWhen': 'installing'})
|
|
107
|
+
packageName: str = dataclasses.field(default = packageNamePACKAGING, metadata={'evaluateWhen': 'packaging'})
|
|
108
|
+
pathPackage: Path = dataclasses.field(default_factory=getPathPackageINSTALLING, metadata={'evaluateWhen': 'installing'})
|
|
109
|
+
concurrencyPackage: str | None = None
|
|
110
|
+
"""
|
|
111
|
+
Package identifier for concurrent execution operations.
|
|
112
|
+
|
|
113
|
+
Specifies which Python package should be used for parallel processing
|
|
114
|
+
in computationally intensive operations. When None, the default concurrency
|
|
115
|
+
package specified in the module constants is used. Accepted values include
|
|
116
|
+
'multiprocessing' for standard parallel processing and 'numba' for
|
|
117
|
+
specialized numerical computations.
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
concurrencyPackage = concurrencyPackageHARDCODED
|
|
121
|
+
"""
|
|
122
|
+
Active concurrency package configuration for the current session.
|
|
123
|
+
|
|
124
|
+
This module-level variable holds the currently selected concurrency package
|
|
125
|
+
identifier, initialized from the hardcoded default but available for runtime
|
|
126
|
+
modification through the package settings system.
|
|
127
|
+
"""
|
|
128
|
+
|
|
129
|
+
packageSettings = PackageSettings(concurrencyPackage=concurrencyPackage)
|
|
130
|
+
"""
|
|
131
|
+
Global package settings instance providing access to all configuration values.
|
|
132
|
+
|
|
133
|
+
This singleton instance serves as the primary interface for accessing package
|
|
134
|
+
configuration throughout the codebase. It combines statically-defined defaults
|
|
135
|
+
with dynamically-resolved values to provide a complete configuration profile
|
|
136
|
+
for the current package installation and runtime environment.
|
|
137
|
+
"""
|
mapFolding/basecamp.py
CHANGED
|
@@ -1,22 +1,30 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
This module
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
Unified interface for map folding computation orchestration.
|
|
3
|
+
|
|
4
|
+
This module represents the culmination of the computational ecosystem, providing
|
|
5
|
+
the primary entry point where users interact with the complete map folding analysis
|
|
6
|
+
system. It orchestrates all preceding layers: the configuration foundation,
|
|
7
|
+
type system, core utilities, state management, and persistent storage to deliver
|
|
8
|
+
a seamless computational experience.
|
|
9
|
+
|
|
10
|
+
The interface handles multiple computation flows including sequential algorithms,
|
|
11
|
+
experimental task division strategies, and various mathematical theorem implementations.
|
|
12
|
+
It provides flexible parameter validation, computation method selection, task
|
|
13
|
+
division management, processor utilization control, and automatic result persistence.
|
|
14
|
+
Integration with OEIS sequences enables research validation and mathematical
|
|
15
|
+
verification of computed results.
|
|
16
|
+
|
|
17
|
+
Through this unified interface, researchers and practitioners can access the full
|
|
18
|
+
power of Lunnon's algorithm implementation while the underlying computational
|
|
19
|
+
complexity remains elegantly abstracted. The interface ensures that whether
|
|
20
|
+
solving simple 2D problems or complex multi-dimensional challenges, users receive
|
|
21
|
+
consistent, reliable, and efficiently computed folding pattern counts.
|
|
10
22
|
"""
|
|
11
23
|
|
|
12
24
|
from collections.abc import Sequence
|
|
13
25
|
from mapFolding import (
|
|
14
|
-
getPathFilenameFoldsTotal,
|
|
15
|
-
|
|
16
|
-
saveFoldsTotal,
|
|
17
|
-
saveFoldsTotalFAILearly,
|
|
18
|
-
setProcessorLimit,
|
|
19
|
-
validateListDimensions,
|
|
26
|
+
getPathFilenameFoldsTotal, packageSettings, saveFoldsTotal, saveFoldsTotalFAILearly,
|
|
27
|
+
setProcessorLimit, validateListDimensions,
|
|
20
28
|
)
|
|
21
29
|
from os import PathLike
|
|
22
30
|
from pathlib import PurePath
|
|
@@ -129,7 +137,7 @@ def countFolds(listDimensions: Sequence[int] | None = None
|
|
|
129
137
|
mapFoldingState = doTheNeedful(mapFoldingState)
|
|
130
138
|
foldsTotal = mapFoldingState.foldsTotal
|
|
131
139
|
|
|
132
|
-
elif flow == 'theorem2' and any(
|
|
140
|
+
elif flow == 'theorem2' and any(dimension > 2 for dimension in mapShape):
|
|
133
141
|
from mapFolding.dataBaskets import MapFoldingState
|
|
134
142
|
mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
|
|
135
143
|
|
|
@@ -141,7 +149,7 @@ def countFolds(listDimensions: Sequence[int] | None = None
|
|
|
141
149
|
|
|
142
150
|
foldsTotal = mapFoldingState.foldsTotal
|
|
143
151
|
|
|
144
|
-
elif flow == 'theorem2Trimmed' and any(
|
|
152
|
+
elif flow == 'theorem2Trimmed' and any(dimension > 2 for dimension in mapShape):
|
|
145
153
|
from mapFolding.dataBaskets import MapFoldingState
|
|
146
154
|
mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
|
|
147
155
|
|
|
@@ -153,7 +161,7 @@ def countFolds(listDimensions: Sequence[int] | None = None
|
|
|
153
161
|
|
|
154
162
|
foldsTotal = mapFoldingState.foldsTotal
|
|
155
163
|
|
|
156
|
-
elif (flow == 'theorem2Numba' or taskDivisions == 0) and any(
|
|
164
|
+
elif (flow == 'theorem2Numba' or taskDivisions == 0) and any(dimension > 2 for dimension in mapShape):
|
|
157
165
|
from mapFolding.dataBaskets import MapFoldingState
|
|
158
166
|
mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
|
|
159
167
|
|
|
@@ -170,7 +178,9 @@ def countFolds(listDimensions: Sequence[int] | None = None
|
|
|
170
178
|
parallelMapFoldingState: ParallelMapFoldingState = ParallelMapFoldingState(mapShape, taskDivisions=taskDivisions)
|
|
171
179
|
|
|
172
180
|
from mapFolding.syntheticModules.countParallel import doTheNeedful
|
|
173
|
-
|
|
181
|
+
|
|
182
|
+
# `listStatesParallel` exists in case you want to research the parallel computation.
|
|
183
|
+
foldsTotal, listStatesParallel = doTheNeedful(parallelMapFoldingState, concurrencyLimit) # pyright: ignore[reportUnusedVariable]
|
|
174
184
|
|
|
175
185
|
else:
|
|
176
186
|
from mapFolding.dataBaskets import MapFoldingState
|
mapFolding/beDRY.py
CHANGED
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Core
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
These utilities
|
|
18
|
-
|
|
2
|
+
Core computational utilities implementing Lunnon's map folding algorithm.
|
|
3
|
+
|
|
4
|
+
With the configuration foundation established and the type system defined, this
|
|
5
|
+
module provides the essential building blocks that transform mathematical theory
|
|
6
|
+
into executable computation. These utilities implement the fundamental operations
|
|
7
|
+
required by Lunnon's 1971 algorithm, handling dimension validation, connection
|
|
8
|
+
graph generation, and computational resource management.
|
|
9
|
+
|
|
10
|
+
The connection graph generation represents the mathematical heart of the algorithm,
|
|
11
|
+
calculating how leaves connect across dimensions using coordinate systems, parity
|
|
12
|
+
rules, and boundary conditions. This graph becomes the foundation upon which the
|
|
13
|
+
recursive folding analysis operates. Validation functions ensure computational
|
|
14
|
+
of large-scale problems. Validation functions ensure computational
|
|
15
|
+
integrity, while task division management enables experimental task division strategies.
|
|
16
|
+
|
|
17
|
+
These utilities follow DRY and SSOT principles, providing reusable functions that
|
|
18
|
+
serve as the computational assembly-line components. They prepare the essential
|
|
19
|
+
data structures and computational parameters that the state management system
|
|
20
|
+
requires to orchestrate the complex recursive algorithms.
|
|
19
21
|
"""
|
|
22
|
+
|
|
20
23
|
from collections.abc import Sequence
|
|
21
|
-
from mapFolding import
|
|
24
|
+
from mapFolding import NumPyIntegerType
|
|
22
25
|
from numpy import dtype as numpy_dtype, int64 as numpy_int64, ndarray
|
|
23
26
|
from sys import maxsize as sysMaxsize
|
|
24
27
|
from typing import Any
|
|
25
28
|
from Z0Z_tools import defineConcurrencyLimit, intInnit, oopsieKwargsie
|
|
26
29
|
import numpy
|
|
27
|
-
import dataclasses
|
|
28
30
|
|
|
29
31
|
def getLeavesTotal(mapShape: tuple[int, ...]) -> int:
|
|
30
32
|
"""
|
mapFolding/dataBaskets.py
CHANGED
|
@@ -1,18 +1,72 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Computational state orchestration for map folding analysis.
|
|
3
|
+
|
|
4
|
+
Building upon the core utilities and their generated data structures, this module
|
|
5
|
+
orchestrates the complex computational state required for Lunnon's recursive
|
|
6
|
+
algorithm execution. The state classes serve as both data containers and computational
|
|
7
|
+
interfaces, managing the intricate arrays, indices, and control structures that
|
|
8
|
+
guide the folding pattern discovery process.
|
|
9
|
+
|
|
10
|
+
Each state class encapsulates a specific computational scenario: sequential processing
|
|
11
|
+
for standard analysis, experimental task division for research applications, and specialized
|
|
12
|
+
leaf sequence tracking for mathematical exploration. The automatic initialization
|
|
13
|
+
integrates seamlessly with the type system and core utilities, ensuring proper
|
|
14
|
+
array allocation and connection graph integration.
|
|
15
|
+
|
|
16
|
+
These state management classes bridge the gap between the foundational computational
|
|
17
|
+
building blocks and the persistent storage system. They maintain computational
|
|
18
|
+
integrity throughout the recursive analysis while providing the structured data
|
|
19
|
+
access patterns that enable efficient result persistence and retrieval.
|
|
20
|
+
"""
|
|
1
21
|
from mapFolding import (
|
|
2
|
-
Array1DElephino,
|
|
3
|
-
|
|
4
|
-
Array3D,
|
|
5
|
-
DatatypeElephino,
|
|
6
|
-
DatatypeFoldsTotal,
|
|
7
|
-
DatatypeLeavesTotal,
|
|
8
|
-
getConnectionGraph,
|
|
9
|
-
getLeavesTotal,
|
|
10
|
-
makeDataContainer,
|
|
22
|
+
Array1DElephino, Array1DLeavesTotal, Array3D, DatatypeElephino, DatatypeFoldsTotal,
|
|
23
|
+
DatatypeLeavesTotal, getConnectionGraph, getLeavesTotal, makeDataContainer,
|
|
11
24
|
)
|
|
12
25
|
import dataclasses
|
|
13
26
|
|
|
14
27
|
@dataclasses.dataclass
|
|
15
28
|
class MapFoldingState:
|
|
29
|
+
"""
|
|
30
|
+
Core computational state for map folding algorithms.
|
|
31
|
+
|
|
32
|
+
This class encapsulates all data needed to perform map folding computations,
|
|
33
|
+
from the basic map dimensions through the complex internal arrays needed
|
|
34
|
+
for efficient algorithmic processing. It serves as both a data container
|
|
35
|
+
and a computational interface, providing properties and methods that
|
|
36
|
+
abstract the underlying complexity.
|
|
37
|
+
|
|
38
|
+
The class handles automatic initialization of all computational arrays
|
|
39
|
+
based on the map dimensions, ensuring consistent sizing and type usage
|
|
40
|
+
throughout the computation. It also manages the relationship between
|
|
41
|
+
different data domains (leaves, elephino, folds) defined in the type system.
|
|
42
|
+
|
|
43
|
+
Key Design Features:
|
|
44
|
+
- Automatic array sizing based on map dimensions
|
|
45
|
+
- Type-safe access to computational data
|
|
46
|
+
- Lazy initialization of expensive arrays
|
|
47
|
+
- Integration with NumPy for performance
|
|
48
|
+
- Metadata preservation for code generation
|
|
49
|
+
|
|
50
|
+
Attributes:
|
|
51
|
+
mapShape: Dimensions of the map being analyzed for folding patterns.
|
|
52
|
+
groupsOfFolds: Current count of distinct folding pattern groups discovered.
|
|
53
|
+
gap1ndex: Current position in gap enumeration algorithms.
|
|
54
|
+
gap1ndexCeiling: Upper bound for gap enumeration operations.
|
|
55
|
+
indexDimension: Current dimension being processed in multi-dimensional algorithms.
|
|
56
|
+
indexLeaf: Current leaf being processed in sequential algorithms.
|
|
57
|
+
indexMiniGap: Current position within a gap subdivision.
|
|
58
|
+
leaf1ndex: One-based leaf index for algorithmic compatibility.
|
|
59
|
+
leafConnectee: Target leaf for connection operations.
|
|
60
|
+
dimensionsUnconstrained: Count of dimensions not subject to folding constraints.
|
|
61
|
+
countDimensionsGapped: Array tracking gap counts across dimensions.
|
|
62
|
+
gapRangeStart: Array of starting positions for gap ranges.
|
|
63
|
+
gapsWhere: Array indicating locations of gaps in the folding pattern.
|
|
64
|
+
leafAbove: Array mapping each leaf to the leaf above it in the folding.
|
|
65
|
+
leafBelow: Array mapping each leaf to the leaf below it in the folding.
|
|
66
|
+
connectionGraph: Three-dimensional representation of leaf connectivity.
|
|
67
|
+
dimensionsTotal: Total number of dimensions in the map.
|
|
68
|
+
leavesTotal: Total number of individual leaves in the map.
|
|
69
|
+
"""
|
|
16
70
|
mapShape: tuple[DatatypeLeavesTotal, ...] = dataclasses.field(init=True, metadata={'elementConstructor': 'DatatypeLeavesTotal'})
|
|
17
71
|
|
|
18
72
|
groupsOfFolds: DatatypeFoldsTotal = dataclasses.field(default=DatatypeFoldsTotal(0), metadata={'theCountingIdentifier': True})
|
|
@@ -36,13 +90,37 @@ class MapFoldingState:
|
|
|
36
90
|
connectionGraph: Array3D = dataclasses.field(init=False, metadata={'dtype': Array3D.__args__[1].__args__[0]}) # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue]
|
|
37
91
|
dimensionsTotal: DatatypeLeavesTotal = dataclasses.field(init=False)
|
|
38
92
|
leavesTotal: DatatypeLeavesTotal = dataclasses.field(init=False)
|
|
39
|
-
|
|
40
93
|
@property
|
|
41
94
|
def foldsTotal(self) -> DatatypeFoldsTotal:
|
|
95
|
+
"""
|
|
96
|
+
Calculate the total number of possible folding patterns for this map.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
totalFoldingPatterns: The complete count of distinct folding patterns
|
|
100
|
+
achievable with the current map configuration.
|
|
101
|
+
|
|
102
|
+
Notes:
|
|
103
|
+
This represents the fundamental result of map folding analysis - the total
|
|
104
|
+
number of unique ways a map can be folded given its dimensional constraints.
|
|
105
|
+
"""
|
|
42
106
|
_foldsTotal = DatatypeFoldsTotal(self.leavesTotal) * self.groupsOfFolds
|
|
43
107
|
return _foldsTotal
|
|
44
108
|
|
|
45
109
|
def __post_init__(self) -> None:
|
|
110
|
+
"""
|
|
111
|
+
Initialize all computational arrays and derived values after dataclass construction.
|
|
112
|
+
|
|
113
|
+
This method performs the expensive operations needed to prepare the state
|
|
114
|
+
for computation, including array allocation, dimension calculation, and
|
|
115
|
+
connection graph generation. It runs automatically after the dataclass
|
|
116
|
+
constructor completes.
|
|
117
|
+
|
|
118
|
+
Notes:
|
|
119
|
+
Arrays that are not explicitly provided (None) are automatically
|
|
120
|
+
allocated with appropriate sizes based on the map dimensions.
|
|
121
|
+
The connection graph is always regenerated to ensure consistency
|
|
122
|
+
with the provided map shape.
|
|
123
|
+
"""
|
|
46
124
|
self.dimensionsTotal = DatatypeLeavesTotal(len(self.mapShape))
|
|
47
125
|
self.leavesTotal = DatatypeLeavesTotal(getLeavesTotal(self.mapShape))
|
|
48
126
|
|
|
@@ -50,31 +128,105 @@ class MapFoldingState:
|
|
|
50
128
|
|
|
51
129
|
self.connectionGraph = getConnectionGraph(self.mapShape, leavesTotalAsInt, self.__dataclass_fields__['connectionGraph'].metadata['dtype'])
|
|
52
130
|
|
|
53
|
-
if self.dimensionsUnconstrained is None: self.dimensionsUnconstrained = DatatypeLeavesTotal(int(self.dimensionsTotal)) # pyright: ignore[reportUnnecessaryComparison]
|
|
54
|
-
if self.gapsWhere is None: self.gapsWhere = makeDataContainer(leavesTotalAsInt * leavesTotalAsInt + 1, self.__dataclass_fields__['gapsWhere'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
55
|
-
if self.countDimensionsGapped is None: self.countDimensionsGapped = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['countDimensionsGapped'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
56
|
-
if self.gapRangeStart is None: self.gapRangeStart = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['gapRangeStart'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
57
|
-
if self.leafAbove is None: self.leafAbove = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafAbove'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
58
|
-
if self.leafBelow is None: self.leafBelow = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafBelow'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison]
|
|
131
|
+
if self.dimensionsUnconstrained is None: self.dimensionsUnconstrained = DatatypeLeavesTotal(int(self.dimensionsTotal)) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
|
|
132
|
+
if self.gapsWhere is None: self.gapsWhere = makeDataContainer(leavesTotalAsInt * leavesTotalAsInt + 1, self.__dataclass_fields__['gapsWhere'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
|
|
133
|
+
if self.countDimensionsGapped is None: self.countDimensionsGapped = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['countDimensionsGapped'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
|
|
134
|
+
if self.gapRangeStart is None: self.gapRangeStart = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['gapRangeStart'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
|
|
135
|
+
if self.leafAbove is None: self.leafAbove = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafAbove'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
|
|
136
|
+
if self.leafBelow is None: self.leafBelow = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafBelow'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
|
|
59
137
|
|
|
60
138
|
@dataclasses.dataclass
|
|
61
139
|
class ParallelMapFoldingState(MapFoldingState):
|
|
140
|
+
"""
|
|
141
|
+
Experimental computational state for task division operations.
|
|
142
|
+
|
|
143
|
+
This class extends the base MapFoldingState with additional attributes
|
|
144
|
+
needed for experimental task division of map folding computations. It manages
|
|
145
|
+
task division state while inheriting all the core computational arrays and
|
|
146
|
+
properties from the base class.
|
|
147
|
+
|
|
148
|
+
The task division model attempts to divide the total computation space into
|
|
149
|
+
discrete tasks that can be processed independently, then combined to
|
|
150
|
+
produce the final result. However, the map folding problem is inherently
|
|
151
|
+
sequential and task division typically results in significant computational
|
|
152
|
+
overhead due to work overlap between tasks.
|
|
153
|
+
|
|
154
|
+
Attributes:
|
|
155
|
+
taskDivisions: Number of tasks into which the computation is divided.
|
|
156
|
+
taskIndex: Current task identifier when processing in task division mode.
|
|
157
|
+
"""
|
|
62
158
|
taskDivisions: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
|
|
63
|
-
"""
|
|
159
|
+
"""
|
|
160
|
+
Number of tasks into which to divide the computation.
|
|
161
|
+
|
|
162
|
+
If this value exceeds `leavesTotal`, the computation will produce incorrect
|
|
163
|
+
results. When set to 0 (default), the value is automatically set to
|
|
164
|
+
`leavesTotal` during initialization, providing optimal task granularity.
|
|
165
|
+
"""
|
|
64
166
|
|
|
65
167
|
taskIndex: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
|
|
66
|
-
"""
|
|
168
|
+
"""
|
|
169
|
+
Index of the current task when using task divisions.
|
|
170
|
+
|
|
171
|
+
This value identifies which specific task is being processed in the
|
|
172
|
+
parallel computation. It ranges from 0 to `taskDivisions - 1` and
|
|
173
|
+
determines which portion of the total computation space this instance
|
|
174
|
+
is responsible for analyzing.
|
|
175
|
+
"""
|
|
67
176
|
|
|
68
177
|
def __post_init__(self) -> None:
|
|
178
|
+
"""
|
|
179
|
+
Initialize parallel-specific state after base initialization.
|
|
180
|
+
This method calls the parent initialization to set up all base
|
|
181
|
+
computational arrays, then configures the task division
|
|
182
|
+
parameters. If `taskDivisions` is 0, it automatically sets the
|
|
183
|
+
value to `leavesTotal` for optimal parallelization.
|
|
184
|
+
"""
|
|
69
185
|
super().__post_init__()
|
|
70
186
|
if self.taskDivisions == 0:
|
|
71
187
|
self.taskDivisions = DatatypeLeavesTotal(int(self.leavesTotal))
|
|
72
188
|
|
|
73
189
|
@dataclasses.dataclass
|
|
74
190
|
class LeafSequenceState(MapFoldingState):
|
|
191
|
+
"""
|
|
192
|
+
Specialized computational state for tracking leaf sequences during analysis.
|
|
193
|
+
|
|
194
|
+
This class extends the base MapFoldingState with additional capability
|
|
195
|
+
for recording and analyzing the sequence of leaf connections discovered
|
|
196
|
+
during map folding computations. It integrates with the OEIS (Online
|
|
197
|
+
Encyclopedia of Integer Sequences) system to leverage known sequence
|
|
198
|
+
data for optimization and validation.
|
|
199
|
+
|
|
200
|
+
The leaf sequence tracking is particularly valuable for research and
|
|
201
|
+
verification purposes, allowing detailed analysis of how folding patterns
|
|
202
|
+
emerge and enabling comparison with established mathematical sequences.
|
|
203
|
+
|
|
204
|
+
Attributes:
|
|
205
|
+
leafSequence: Array storing the sequence of leaf connections discovered.
|
|
206
|
+
"""
|
|
75
207
|
leafSequence: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
|
|
208
|
+
"""
|
|
209
|
+
Array storing the sequence of leaf connections discovered during computation.
|
|
210
|
+
|
|
211
|
+
This array records the order in which leaf connections are established
|
|
212
|
+
during the folding analysis. The sequence provides insights into the
|
|
213
|
+
algorithmic progression and can be compared against known mathematical
|
|
214
|
+
sequences for validation and optimization purposes.
|
|
215
|
+
"""
|
|
76
216
|
|
|
77
217
|
def __post_init__(self) -> None:
|
|
218
|
+
"""
|
|
219
|
+
Initialize sequence tracking arrays with OEIS integration.
|
|
220
|
+
|
|
221
|
+
This method performs base initialization then sets up the leaf sequence
|
|
222
|
+
tracking array. It queries the OEIS system for known fold totals
|
|
223
|
+
corresponding to the current map shape, using this information to
|
|
224
|
+
optimally size the sequence tracking array.
|
|
225
|
+
|
|
226
|
+
Notes:
|
|
227
|
+
The sequence array is automatically initialized to record the starting
|
|
228
|
+
leaf connection, providing a foundation for subsequent sequence tracking.
|
|
229
|
+
"""
|
|
78
230
|
super().__post_init__()
|
|
79
231
|
from mapFolding.oeis import getFoldsTotalKnown
|
|
80
232
|
groupsOfFoldsKnown = getFoldsTotalKnown(self.mapShape) // self.leavesTotal
|