mapFolding 0.8.1__tar.gz → 0.8.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. {mapfolding-0.8.1 → mapfolding-0.8.2}/PKG-INFO +54 -30
  2. mapfolding-0.8.2/README.md +138 -0
  3. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/basecamp.py +2 -2
  4. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/beDRY.py +24 -31
  5. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/oeis.py +2 -2
  6. mapfolding-0.8.2/mapFolding/reference/__init__.py +38 -0
  7. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/reference/flattened.py +20 -2
  8. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/reference/hunterNumba.py +24 -0
  9. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/reference/irvineJavaPort.py +12 -0
  10. mapfolding-0.8.1/mapFolding/reference/jax.py → mapfolding-0.8.2/mapFolding/reference/jaxCount.py +46 -27
  11. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/reference/lunnanNumpy.py +16 -1
  12. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/reference/lunnanWhile.py +15 -1
  13. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/reference/rotatedEntryPoint.py +18 -0
  14. mapfolding-0.8.2/mapFolding/reference/total_countPlus1vsPlusN.py +234 -0
  15. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/someAssemblyRequired/synthesizeNumbaFlow.py +5 -8
  16. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/someAssemblyRequired/transformDataStructures.py +10 -4
  17. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/someAssemblyRequired/transformationTools.py +19 -28
  18. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/theSSOT.py +70 -121
  19. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding.egg-info/PKG-INFO +54 -30
  20. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding.egg-info/SOURCES.txt +1 -1
  21. {mapfolding-0.8.1 → mapfolding-0.8.2}/pyproject.toml +1 -1
  22. {mapfolding-0.8.1 → mapfolding-0.8.2}/tests/conftest.py +43 -33
  23. {mapfolding-0.8.1 → mapfolding-0.8.2}/tests/test_computations.py +7 -7
  24. {mapfolding-0.8.1 → mapfolding-0.8.2}/tests/test_other.py +2 -2
  25. mapfolding-0.8.1/README.md +0 -114
  26. mapfolding-0.8.1/mapFolding/reference/total_countPlus1vsPlusN.py +0 -211
  27. mapfolding-0.8.1/tests/__init__.py +0 -0
  28. {mapfolding-0.8.1 → mapfolding-0.8.2}/LICENSE +0 -0
  29. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/__init__.py +0 -0
  30. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/filesystem.py +0 -0
  31. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/noHomeYet.py +0 -0
  32. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/py.typed +0 -0
  33. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/someAssemblyRequired/__init__.py +0 -0
  34. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/someAssemblyRequired/getLLVMforNoReason.py +0 -0
  35. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/someAssemblyRequired/ingredientsNumba.py +0 -0
  36. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/someAssemblyRequired/synthesizeNumbaJobVESTIGIAL.py +0 -0
  37. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/syntheticModules/numbaCount_doTheNeedful.py +0 -0
  38. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding/theDao.py +0 -0
  39. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding.egg-info/dependency_links.txt +0 -0
  40. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding.egg-info/entry_points.txt +0 -0
  41. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding.egg-info/requires.txt +0 -0
  42. {mapfolding-0.8.1 → mapfolding-0.8.2}/mapFolding.egg-info/top_level.txt +0 -0
  43. {mapfolding-0.8.1 → mapfolding-0.8.2}/setup.cfg +0 -0
  44. {mapfolding-0.8.1/mapFolding/reference → mapfolding-0.8.2/tests}/__init__.py +0 -0
  45. {mapfolding-0.8.1 → mapfolding-0.8.2}/tests/test_filesystem.py +0 -0
  46. {mapfolding-0.8.1 → mapfolding-0.8.2}/tests/test_oeis.py +0 -0
  47. {mapfolding-0.8.1 → mapfolding-0.8.2}/tests/test_tasks.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mapFolding
3
- Version: 0.8.1
3
+ Version: 0.8.2
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
@@ -99,51 +99,75 @@ Available OEIS sequences:
99
99
  A195646: Number of ways of folding a 3 X 3 X ... X 3 n-dimensional map.
100
100
  ```
101
101
 
102
- ### 2. **Algorithm Zoo** 🦒
102
+ ### 2. **Algorithm Zoo: A Historical and Performance Journey** 🦒
103
103
 
104
- - **Lunnon's 1971 Algorithm**: A painstakingly debugged version of [the original typo-riddled code](https://github.com/hunterhogan/mapFolding/blob/mapFolding/reference/foldings.txt)
105
- - The /reference directory.
106
- - **Numba-JIT Accelerated**: Up to 1000× faster than pure Python ([benchmarks](https://github.com/hunterhogan/mapFolding/blob/mapFolding/notes/Speed%20highlights.md))
104
+ This package offers a comprehensive collection of map folding algorithm implementations that showcase its evolution from historical origins to high-performance computation:
107
105
 
108
- ### 3. **For Researchers and Power Users** 🔬
106
+ - **Historical Implementations**:
107
+ - Carefully restored versions of Lunnon's 1971 original [algorithm](https://github.com/hunterhogan/mapFolding/blob/mapFolding/reference/foldings.txt) with corrections
108
+ - Atlas Autocode reconstruction in the `reference/foldings.AA` file
109
109
 
110
- This package provides a sophisticated code transformation framework that can turn readable algorithm implementations into highly-optimized computational engines:
110
+ - **Direct Translations**:
111
+ - Python translations following the original control flow (`lunnanWhile.py`)
112
+ - NumPy-based vectorized implementations (`lunnanNumpy.py`)
111
113
 
112
- - **Algorithmic Exploration**: Study the core algorithm in `theDao.py`, which uses a functional state-transformation approach with clear, isolated functions
113
- - **Performance Optimization**: Generate specialized implementations with the `someAssemblyRequired` transformation pipeline:
114
- - AST-based code analysis and manipulation
115
- - Dataclass "shattering" to decompose complex state objects into primitive components
116
- - Just-in-time compilation with Numba and various optimization profiles
117
- - LLVM IR extraction for low-level algorithmic analysis
114
+ - **Modern Implementations**:
115
+ - Java port adaptations (`irvineJavaPort.py`) providing cleaner procedural implementations
116
+ - Experimental JAX version (`jaxCount.py`) exploring GPU acceleration potential
117
+ - Semantically decomposed version (`flattened.py`) with clear function boundaries
118
118
 
119
- - **Extensible Design**: The transformation framework is abstract and generic, enabling:
120
- - Creation of new optimization targets beyond the included Numba implementation
121
- - Customization of compilation parameters and optimization levels
122
- - Development of specialized algorithms for specific map dimensions
119
+ - **Performance Optimized**:
120
+ - Numba-JIT accelerated implementations up to 1000× faster than pure Python (see [benchmarks](https://github.com/hunterhogan/mapFolding/blob/mapFolding/notes/Speed%20highlights.md))
121
+ - Algorithmic optimizations showcasing subtle yet powerful performance differences (`total_countPlus1vsPlusN.py`)
123
122
 
124
- ### 4. **Customization and Extension Guide**
123
+ The `reference` directory serves as both a historical archive and an educational resource for understanding algorithm evolution.
125
124
 
126
- The package architecture supports multiple levels of customization:
125
+ ### 3. **Algorithmic Transformation: From Readability to Speed** 🔬
127
126
 
128
- - **Basic Usage**: Work with the high-level API in `basecamp.py` for standard computations
129
- - **Algorithm Modification**:
127
+ The package provides a sophisticated transformation framework that bridges the gap between human-readable algorithms and high-performance computation:
128
+
129
+ - **Core Algorithm Understanding**:
130
+ - Study the functional state-transformation approach in `theDao.py` with clear, isolated functions
131
+ - Explore the semantic decomposition in `reference/flattened.py` to understand algorithm sections
132
+
133
+ - **Code Transformation Pipeline**:
134
+ - **AST Manipulation**: Analyzes and transforms the algorithm's abstract syntax tree
135
+ - **Dataclass "Shattering"**: Decomposes complex state objects into primitive components
136
+ - **Optimization Applications**: Applies domain-specific optimizations for numerical computation
137
+ - **LLVM Integration**: Extracts LLVM IR for low-level algorithmic analysis
138
+
139
+ - **Performance Breakthroughs**:
140
+ - Learn why nearly identical algorithms can have dramatically different performance (`total_countPlus1vsPlusN.py`)
141
+ - See how memory layout and increment strategy impact computation speed
142
+ - Understand the batching technique that yields order-of-magnitude improvements
143
+
144
+ ### 4. **Multi-Level Architecture: From Simple API to Full Customization**
145
+
146
+ The package's architecture supports multiple levels of engagement:
147
+
148
+ - **Basic Usage**:
149
+ - Work with the high-level API in `basecamp.py` for standard computations
150
+ - Access OEIS sequence calculations with minimal code
151
+
152
+ - **Algorithm Exploration**:
153
+ - Compare different implementations in the `reference` directory to understand trade-offs
130
154
  - Modify the core algorithm in `theDao.py` while preserving its functional approach
131
155
  - Configure system-wide settings in `theSSOT.py` to adjust data types and performance characteristics
132
- - Use utility functions in `beDRY.py` for common operations
133
156
 
134
157
  - **Advanced Transformation**:
135
- - The `someAssemblyRequired` package provides tools to transform code at the AST level:
136
- - `transformationTools.py` contains utilities for AST manipulation and code generation
137
- - `transformDataStructures.py` handles complex data structure transformations
138
- - `ingredientsNumba.py` provides Numba-specific configuration profiles
139
- - `synthesizeNumbaFlow.py` orchestrates the transformation process
158
+ - Use the `someAssemblyRequired` package to transform algorithms at the AST level
159
+ - Create optimized variants with different compilation settings using:
160
+ - `transformationTools.py` for AST manipulation
161
+ - `transformDataStructures.py` for complex data structure transformations
162
+ - `ingredientsNumba.py` for Numba-specific optimization profiles
163
+ - `synthesizeNumbaFlow.py` to orchestrate the transformation process
140
164
 
141
165
  - **Custom Deployment**:
142
166
  - Generate specialized implementations for specific dimensions
143
- - Create optimized modules that can be executed as standalone scripts
144
- - Extract LLVM IR for further analysis or optimization
167
+ - Create optimized standalone modules for production use
168
+ - Extract LLVM IR for further analysis and optimization
145
169
 
146
- The package's multi-level design allows you to start with simple API calls and progressively delve deeper into optimization as your computational needs grow.
170
+ The package's multi-level design allows you to start with simple API calls and progressively explore deeper optimization techniques as your computational needs grow.
147
171
 
148
172
  ## Map-folding Video
149
173
 
@@ -0,0 +1,138 @@
1
+ # mapFolding: Algorithms for enumerating distinct map/stamp folding patterns 🗺️
2
+
3
+ [![pip install mapFolding](https://img.shields.io/badge/pip%20install-mapFolding-gray.svg?colorB=3b434b)](https://pypi.org/project/mapFolding/)
4
+ [![Static Badge](https://img.shields.io/badge/stinkin'%20badges-don't%20need-b98e5e)](https://youtu.be/g6f_miE91mk&t=4)
5
+ [![Python Tests](https://github.com/hunterhogan/mapFolding/actions/workflows/pythonTests.yml/badge.svg)](https://github.com/hunterhogan/mapFolding/actions/workflows/pythonTests.yml)
6
+ ![Static Badge](https://img.shields.io/badge/issues-I%20have%20them-brightgreen)
7
+ [![License: CC-BY-NC-4.0](https://img.shields.io/badge/License-CC_BY--NC_4.0-3b434b)](https://creativecommons.org/licenses/by-nc/4.0/)
8
+
9
+ ---
10
+
11
+ ## Quick start
12
+
13
+ ```sh
14
+ pip install mapFolding
15
+ ```
16
+
17
+ `OEIS_for_n` will run a computation from the command line.
18
+
19
+ ```cmd
20
+ (mapFolding) C:\apps\mapFolding> OEIS_for_n A001418 5
21
+ 186086600 distinct folding patterns.
22
+ Time elapsed: 1.605 seconds
23
+ ```
24
+
25
+ Use `mapFolding.oeisIDfor_n()` to compute a(n) for an OEIS ID.
26
+
27
+ ```python
28
+ from mapFolding import oeisIDfor_n
29
+ foldsTotal = oeisIDfor_n( 'A001418', 4 )
30
+ ```
31
+
32
+ ---
33
+
34
+ ## Features
35
+
36
+ ### 1. Simple, easy usage based on OEIS IDs
37
+
38
+ `mapFolding` directly implements some IDs from [_The On-Line Encyclopedia of Integer Sequences_](https://oeis.org/) ([BibTex](https://github.com/hunterhogan/mapFolding/blob/main/citations/oeis.bibtex) citation).
39
+
40
+ Use `getOEISids` to get the most up-to-date list of available OEIS IDs.
41
+
42
+ ```cmd
43
+ (mapFolding) C:\apps\mapFolding> getOEISids
44
+
45
+ Available OEIS sequences:
46
+ A001415: Number of ways of folding a 2 X n strip of stamps.
47
+ A001416: Number of ways of folding a 3 X n strip of stamps.
48
+ A001417: Number of ways of folding a 2 X 2 X ... X 2 n-dimensional map.
49
+ A001418: Number of ways of folding an n X n sheet of stamps.
50
+ A195646: Number of ways of folding a 3 X 3 X ... X 3 n-dimensional map.
51
+ ```
52
+
53
+ ### 2. **Algorithm Zoo: A Historical and Performance Journey** 🦒
54
+
55
+ This package offers a comprehensive collection of map folding algorithm implementations that showcase its evolution from historical origins to high-performance computation:
56
+
57
+ - **Historical Implementations**:
58
+ - Carefully restored versions of Lunnon's 1971 original [algorithm](https://github.com/hunterhogan/mapFolding/blob/mapFolding/reference/foldings.txt) with corrections
59
+ - Atlas Autocode reconstruction in the `reference/foldings.AA` file
60
+
61
+ - **Direct Translations**:
62
+ - Python translations following the original control flow (`lunnanWhile.py`)
63
+ - NumPy-based vectorized implementations (`lunnanNumpy.py`)
64
+
65
+ - **Modern Implementations**:
66
+ - Java port adaptations (`irvineJavaPort.py`) providing cleaner procedural implementations
67
+ - Experimental JAX version (`jaxCount.py`) exploring GPU acceleration potential
68
+ - Semantically decomposed version (`flattened.py`) with clear function boundaries
69
+
70
+ - **Performance Optimized**:
71
+ - Numba-JIT accelerated implementations up to 1000× faster than pure Python (see [benchmarks](https://github.com/hunterhogan/mapFolding/blob/mapFolding/notes/Speed%20highlights.md))
72
+ - Algorithmic optimizations showcasing subtle yet powerful performance differences (`total_countPlus1vsPlusN.py`)
73
+
74
+ The `reference` directory serves as both a historical archive and an educational resource for understanding algorithm evolution.
75
+
76
+ ### 3. **Algorithmic Transformation: From Readability to Speed** 🔬
77
+
78
+ The package provides a sophisticated transformation framework that bridges the gap between human-readable algorithms and high-performance computation:
79
+
80
+ - **Core Algorithm Understanding**:
81
+ - Study the functional state-transformation approach in `theDao.py` with clear, isolated functions
82
+ - Explore the semantic decomposition in `reference/flattened.py` to understand algorithm sections
83
+
84
+ - **Code Transformation Pipeline**:
85
+ - **AST Manipulation**: Analyzes and transforms the algorithm's abstract syntax tree
86
+ - **Dataclass "Shattering"**: Decomposes complex state objects into primitive components
87
+ - **Optimization Applications**: Applies domain-specific optimizations for numerical computation
88
+ - **LLVM Integration**: Extracts LLVM IR for low-level algorithmic analysis
89
+
90
+ - **Performance Breakthroughs**:
91
+ - Learn why nearly identical algorithms can have dramatically different performance (`total_countPlus1vsPlusN.py`)
92
+ - See how memory layout and increment strategy impact computation speed
93
+ - Understand the batching technique that yields order-of-magnitude improvements
94
+
95
+ ### 4. **Multi-Level Architecture: From Simple API to Full Customization**
96
+
97
+ The package's architecture supports multiple levels of engagement:
98
+
99
+ - **Basic Usage**:
100
+ - Work with the high-level API in `basecamp.py` for standard computations
101
+ - Access OEIS sequence calculations with minimal code
102
+
103
+ - **Algorithm Exploration**:
104
+ - Compare different implementations in the `reference` directory to understand trade-offs
105
+ - Modify the core algorithm in `theDao.py` while preserving its functional approach
106
+ - Configure system-wide settings in `theSSOT.py` to adjust data types and performance characteristics
107
+
108
+ - **Advanced Transformation**:
109
+ - Use the `someAssemblyRequired` package to transform algorithms at the AST level
110
+ - Create optimized variants with different compilation settings using:
111
+ - `transformationTools.py` for AST manipulation
112
+ - `transformDataStructures.py` for complex data structure transformations
113
+ - `ingredientsNumba.py` for Numba-specific optimization profiles
114
+ - `synthesizeNumbaFlow.py` to orchestrate the transformation process
115
+
116
+ - **Custom Deployment**:
117
+ - Generate specialized implementations for specific dimensions
118
+ - Create optimized standalone modules for production use
119
+ - Extract LLVM IR for further analysis and optimization
120
+
121
+ The package's multi-level design allows you to start with simple API calls and progressively explore deeper optimization techniques as your computational needs grow.
122
+
123
+ ## Map-folding Video
124
+
125
+ ~~This caused my neurosis:~~ I enjoyed the following video, which is what introduced me to map folding.
126
+
127
+ "How Many Ways Can You Fold a Map?" by Physics for the Birds, 2024 November 13 ([BibTex](https://github.com/hunterhogan/mapFolding/blob/main/citations/Physics_for_the_Birds.bibtex) citation)
128
+
129
+ [![How Many Ways Can You Fold a Map?](https://i.ytimg.com/vi/sfH9uIY3ln4/hq720.jpg)](https://www.youtube.com/watch?v=sfH9uIY3ln4)
130
+
131
+ ---
132
+
133
+ ## My recovery
134
+
135
+ [![Static Badge](https://img.shields.io/badge/2011_August-Homeless_since-blue?style=flat)](https://HunterThinks.com/support)
136
+ [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UC3Gx7kz61009NbhpRtPP7tw)](https://www.youtube.com/@HunterHogan)
137
+
138
+ [![CC-BY-NC-4.0](https://github.com/hunterhogan/mapFolding/blob/main/CC-BY-NC-4.0.svg)](https://creativecommons.org/licenses/by-nc/4.0/)
@@ -15,7 +15,7 @@ implementation, and optional persistence of results.
15
15
  from collections.abc import Sequence
16
16
  from mapFolding.beDRY import outfitCountFolds, setCPUlimit, validateListDimensions
17
17
  from mapFolding.filesystem import getPathFilenameFoldsTotal, saveFoldsTotal
18
- from mapFolding.theSSOT import ComputationState, getPackageDispatcher
18
+ from mapFolding.theSSOT import ComputationState, getPackageDispatcher, The
19
19
  from os import PathLike
20
20
  from pathlib import Path
21
21
 
@@ -54,7 +54,7 @@ def countFolds(listDimensions: Sequence[int]
54
54
  If you want to compute a large `foldsTotal`, dividing the computation into tasks is usually a bad idea. Dividing the algorithm into tasks is inherently inefficient: efficient division into tasks means there would be no overlap in the work performed by each task. When dividing this algorithm, the amount of overlap is between 50% and 90% by all tasks: at least 50% of the work done by every task must be done by _all_ tasks. If you improve the computation time, it will only change by -10 to -50% depending on (at the very least) the ratio of the map dimensions and the number of leaves. If an undivided computation would take 10 hours on your computer, for example, the computation will still take at least 5 hours but you might reduce the time to 9 hours. Most of the time, however, you will increase the computation time. If logicalCores >= leavesTotal, it will probably be faster. If logicalCores <= 2 * leavesTotal, it will almost certainly be slower for all map dimensions.
55
55
  """
56
56
  mapShape: tuple[int, ...] = validateListDimensions(listDimensions)
57
- concurrencyLimit: int = setCPUlimit(CPUlimit)
57
+ concurrencyLimit: int = setCPUlimit(CPUlimit, The.concurrencyPackage)
58
58
  computationStateInitialized: ComputationState = outfitCountFolds(mapShape, computationDivisions, concurrencyLimit)
59
59
 
60
60
  dispatcherCallableProxy = getPackageDispatcher()
@@ -15,12 +15,15 @@ particularly for initializing computation state, validating inputs, and creating
15
15
  structures needed by the folding algorithms.
16
16
  """
17
17
  from collections.abc import Sequence
18
- from mapFolding.theSSOT import Array3D, ComputationState, getDatatypePackage, getNumpyDtypeDefault
18
+ from mapFolding.theSSOT import ComputationState
19
+ from numpy import dtype as numpy_dtype, integer, ndarray
19
20
  from sys import maxsize as sysMaxsize
20
- from typing import Any
21
+ from typing import Any, TypeVar
21
22
  from Z0Z_tools import defineConcurrencyLimit, intInnit, oopsieKwargsie
22
23
  import numpy
23
24
 
25
+ numpyIntegerType = TypeVar('numpyIntegerType', bound=integer[Any])
26
+
24
27
  def getLeavesTotal(mapShape: tuple[int, ...]) -> int:
25
28
  productDimensions = 1
26
29
  for dimension in mapShape:
@@ -81,25 +84,16 @@ def getTaskDivisions(computationDivisions: int | str | None, concurrencyLimit: i
81
84
  raise ValueError(f"Problem: `taskDivisions`, ({taskDivisions}), is greater than `leavesTotal`, ({leavesTotal}), which will cause duplicate counting of the folds.\n\nChallenge: you cannot directly set `taskDivisions` or `leavesTotal`. They are derived from parameters that may or may not still be named `computationDivisions`, `CPUlimit` , and `listDimensions` and from dubious-quality Python code.")
82
85
  return int(max(0, taskDivisions))
83
86
 
84
- def interpretParameter_datatype(datatype: type[numpy.signedinteger[Any]] | None = None) -> type[numpy.signedinteger[Any]]:
85
- """An imperfect way to reduce code duplication."""
86
- if 'numpy' == getDatatypePackage():
87
- numpyDtype = datatype or getNumpyDtypeDefault()
88
- else:
89
- raise NotImplementedError("Somebody done broke it.")
90
- return numpyDtype
91
-
92
- def makeConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int, datatype: type[numpy.signedinteger[Any]] | None = None) -> Array3D:
93
- numpyDtype = interpretParameter_datatype(datatype)
87
+ def makeConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int, datatype: type[numpyIntegerType]) -> ndarray[tuple[int, int, int], numpy_dtype[numpyIntegerType]]:
94
88
  dimensionsTotal = len(mapShape)
95
- cumulativeProduct = numpy.multiply.accumulate([1] + list(mapShape), dtype=numpyDtype)
96
- arrayDimensions = numpy.array(mapShape, dtype=numpyDtype)
97
- coordinateSystem = numpy.zeros((dimensionsTotal, leavesTotal + 1), dtype=numpyDtype)
89
+ cumulativeProduct = numpy.multiply.accumulate([1] + list(mapShape), dtype=datatype)
90
+ arrayDimensions = numpy.array(mapShape, dtype=datatype)
91
+ coordinateSystem = numpy.zeros((dimensionsTotal, leavesTotal + 1), dtype=datatype)
98
92
  for indexDimension in range(dimensionsTotal):
99
93
  for leaf1ndex in range(1, leavesTotal + 1):
100
94
  coordinateSystem[indexDimension, leaf1ndex] = (((leaf1ndex - 1) // cumulativeProduct[indexDimension]) % arrayDimensions[indexDimension] + 1)
101
95
 
102
- connectionGraph = numpy.zeros((dimensionsTotal, leavesTotal + 1, leavesTotal + 1), dtype=numpyDtype)
96
+ connectionGraph = numpy.zeros((dimensionsTotal, leavesTotal + 1, leavesTotal + 1), dtype=datatype)
103
97
  for indexDimension in range(dimensionsTotal):
104
98
  for activeLeaf1ndex in range(1, leavesTotal + 1):
105
99
  for connectee1ndex in range(1, activeLeaf1ndex + 1):
@@ -116,9 +110,8 @@ def makeConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int, datatype: t
116
110
  connectionGraph[indexDimension, activeLeaf1ndex, connectee1ndex] = connectee1ndex + cumulativeProduct[indexDimension]
117
111
  return connectionGraph
118
112
 
119
- def makeDataContainer(shape: int | tuple[int, ...], datatype: type[numpy.signedinteger[Any]] | None = None) -> numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]:
120
- numpyDtype = interpretParameter_datatype(datatype)
121
- return numpy.zeros(shape, dtype=numpyDtype)
113
+ def makeDataContainer(shape: int | tuple[int, ...], datatype: type[numpyIntegerType]) -> ndarray[Any, numpy_dtype[numpyIntegerType]]:
114
+ return numpy.zeros(shape, dtype=datatype)
122
115
 
123
116
  def outfitCountFolds(mapShape: tuple[int, ...], computationDivisions: int | str | None = None, concurrencyLimit: int = 1) -> ComputationState:
124
117
  leavesTotal = getLeavesTotal(mapShape)
@@ -126,7 +119,7 @@ def outfitCountFolds(mapShape: tuple[int, ...], computationDivisions: int | str
126
119
  computationStateInitialized = ComputationState(mapShape, leavesTotal, taskDivisions, concurrencyLimit)
127
120
  return computationStateInitialized
128
121
 
129
- def setCPUlimit(CPUlimit: Any | None) -> int:
122
+ def setCPUlimit(CPUlimit: Any | None, concurrencyPackage: str | None = None) -> int:
130
123
  """Sets CPU limit for concurrent operations.
131
124
 
132
125
  If the concurrency is managed by `numba`, the maximum number of CPUs is retrieved from `numba.get_num_threads()` and not by polling the hardware. Therefore, if there are
@@ -154,17 +147,17 @@ def setCPUlimit(CPUlimit: Any | None) -> int:
154
147
  if not (CPUlimit is None or isinstance(CPUlimit, (bool, int, float))):
155
148
  CPUlimit = oopsieKwargsie(CPUlimit)
156
149
 
157
- from mapFolding.theSSOT import concurrencyPackage
158
- if concurrencyPackage == 'numba':
159
- from numba import get_num_threads, set_num_threads
160
- concurrencyLimit: int = defineConcurrencyLimit(CPUlimit, get_num_threads())
161
- set_num_threads(concurrencyLimit)
162
- concurrencyLimit = get_num_threads()
163
- elif concurrencyPackage == 'multiprocessing':
164
- # When to use multiprocessing.set_start_method https://github.com/hunterhogan/mapFolding/issues/6
165
- concurrencyLimit = defineConcurrencyLimit(CPUlimit)
166
- else:
167
- raise NotImplementedError(f"I received {concurrencyPackage=} but I don't know what to do with that.")
150
+ match concurrencyPackage:
151
+ case 'multiprocessing' | None:
152
+ # When to use multiprocessing.set_start_method https://github.com/hunterhogan/mapFolding/issues/6
153
+ concurrencyLimit: int = defineConcurrencyLimit(CPUlimit)
154
+ case 'numba':
155
+ from numba import get_num_threads, set_num_threads
156
+ concurrencyLimit = defineConcurrencyLimit(CPUlimit, get_num_threads())
157
+ set_num_threads(concurrencyLimit)
158
+ concurrencyLimit = get_num_threads()
159
+ case _:
160
+ raise NotImplementedError(f"I received {concurrencyPackage=} but I don't know what to do with that.")
168
161
  return concurrencyLimit
169
162
 
170
163
  def validateListDimensions(listDimensions: Sequence[int]) -> tuple[int, ...]:
@@ -16,7 +16,7 @@ literature and extend sequences beyond their currently known terms.
16
16
  """
17
17
  from collections.abc import Callable
18
18
  from datetime import datetime, timedelta
19
- from mapFolding.theSSOT import thePathPackage
19
+ from mapFolding.theSSOT import The
20
20
  from pathlib import Path
21
21
  from typing import Any, Final, TYPE_CHECKING
22
22
  import argparse
@@ -38,7 +38,7 @@ cacheDays = 7
38
38
  """
39
39
  Section: make `settingsOEIS`"""
40
40
 
41
- pathCache: Path = thePathPackage / ".cache"
41
+ pathCache: Path = The.pathPackage / ".cache"
42
42
 
43
43
  class SettingsOEIS(TypedDict):
44
44
  description: str
@@ -0,0 +1,38 @@
1
+ """
2
+ Historical and reference implementations of map-folding algorithms.
3
+
4
+ This directory contains various implementations of the map-folding algorithm,
5
+ serving both as historical references and as benchmarks for performance comparison.
6
+ These implementations range from direct translations of Lunnon's original 1971 code
7
+ to highly specialized versions using modern optimization techniques.
8
+
9
+ Categories of reference implementations:
10
+
11
+ 1. Historical transcripts:
12
+ - foldings.txt - Original algorithm from Lunnon's 1971 paper
13
+ - foldings.AA - Reconstructed Atlas Autocode version with corrections
14
+
15
+ 2. Direct translations:
16
+ - lunnanWhile.py - Python translation using while loops
17
+ - lunnanNumpy.py - NumPy-based translation with array operations
18
+
19
+ 3. Alternative implementations:
20
+ - irvineJavaPort.py - Port from Sean A. Irvine's Java implementation
21
+ - hunterNumba.py - Numba-optimized implementation
22
+ - jaxCount.py - JAX implementation for GPU acceleration
23
+ - flattened.py - Semantically decomposed version with operation grouping
24
+
25
+ 4. Specialized variants:
26
+ - total_countPlus1vsPlusN.py - Optimized counting with different increment strategies
27
+ - rotatedEntryPoint.py - Alternative entry point implementation (demonstration)
28
+
29
+ These reference implementations are valuable for:
30
+ - Understanding the algorithm's historical development
31
+ - Comparing performance characteristics across implementation strategies
32
+ - Studying optimization techniques and their effects
33
+ - Verifying the correctness of the core algorithm against known solutions
34
+
35
+ Note: These implementations are for reference only and not used in the production
36
+ code path of the package. The active implementation resides in theDao.py with
37
+ optimized variants generated by the someAssemblyRequired framework.
38
+ """
@@ -1,5 +1,23 @@
1
- """The algorithm flattened into semantic sections.
2
- This version is not maintained, so you may see differences from the current version."""
1
+ """
2
+ Semantically decomposed implementation of Lunnon's algorithm with operation grouping.
3
+
4
+ This implementation restructures the map folding algorithm into semantic sections with
5
+ clear function boundaries, making the algorithm more readable and understandable. Each
6
+ operation is isolated into its own named function, providing a clear mapping between
7
+ the mathematical concepts and their implementation.
8
+
9
+ Key characteristics:
10
+ - Breaks down the algorithm into small, single-purpose functions
11
+ - Uses descriptive function names that explain what each part does
12
+ - Clearly separates logical sections of the algorithm
13
+ - Provides a more maintainable and educational view of the algorithm
14
+ - Uses Python's type hints for better code understanding
15
+
16
+ This implementation serves as a bridge between the historical implementations and the
17
+ modern functional approach used in the main package. It's particularly valuable for
18
+ understanding the algorithm's operation before diving into the highly optimized versions.
19
+ """
20
+
3
21
  from collections.abc import Sequence
4
22
  from numpy import integer
5
23
  from numpy.typing import NDArray
@@ -1,3 +1,27 @@
1
+ """
2
+ High-performance Numba-accelerated implementation of Lunnon's algorithm.
3
+
4
+ This implementation focuses on maximum computational performance by leveraging Numba's
5
+ just-in-time (JIT) compilation capabilities to generate native machine code. It represents
6
+ a manually optimized version that served as inspiration for the automated transformation
7
+ framework in the someAssemblyRequired package.
8
+
9
+ Key characteristics:
10
+ - Optimized data structures using NumPy typed arrays with appropriate data types
11
+ - Function decorators for Numba JIT compilation with performance-oriented settings
12
+ - Memory-efficient implementation with careful type management
13
+ - Reduced Python overhead through native code execution
14
+ - Algorithmic optimizations tailored for numerical computation
15
+
16
+ Performance considerations:
17
+ - Up to 1000× faster than pure Python implementations
18
+ - Optimized for larger map dimensions where computational demands increase exponentially
19
+ - Incorporates lessons from multiple implementation strategies
20
+
21
+ Note: This serves as a reference for manually-optimized code before the development of
22
+ the automated transformation pipeline in the main package.
23
+ """
24
+
1
25
  from typing import Any
2
26
  import numba
3
27
  import numpy
@@ -2,8 +2,20 @@
2
2
  Ported from the Java version by Sean A. Irvine:
3
3
  https://github.com/archmageirvine/joeis/blob/80e3e844b11f149704acbab520bc3a3a25ac34ff/src/irvine/oeis/a001/A001415.java
4
4
 
5
+ This implementation is a conversion from a well-known Java implementation of Lunnon's algorithm
6
+ by Sean A. Irvine, a contributor to the OEIS project. It provides a clean, procedural implementation
7
+ with straightforward variable naming and control flow that may be more approachable for
8
+ programmers familiar with modern languages.
9
+
10
+ Key characteristics:
11
+ - Clear variable naming following modern programming conventions
12
+ - Procedural implementation style similar to Java but adapted for Python
13
+ - Follows the same algorithmic structure as Lunnon's original but with cleaner organization
14
+ - Uses primitive Python data structures (lists) without NumPy dependencies
15
+
5
16
  Citation: https://github.com/hunterhogan/mapFolding/blob/134f2e6ecdf59fb6f6829c775475544a6aaaa800/citations/jOEIS.bibtex
6
17
  """
18
+
7
19
  def foldings(p: list[int], res: int = 0, mod: int = 0) -> int:
8
20
  """
9
21
  Compute the total number of foldings for a map with dimensions specified in p.