mapFolding 0.8.1__tar.gz → 0.8.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.
Files changed (51) hide show
  1. {mapfolding-0.8.1 → mapfolding-0.8.3}/PKG-INFO +56 -31
  2. mapfolding-0.8.3/README.md +139 -0
  3. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/__init__.py +5 -1
  4. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/basecamp.py +2 -2
  5. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/beDRY.py +24 -31
  6. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/oeis.py +2 -2
  7. mapfolding-0.8.3/mapFolding/reference/__init__.py +45 -0
  8. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/reference/flattened.py +20 -2
  9. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/reference/hunterNumba.py +24 -0
  10. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/reference/irvineJavaPort.py +12 -0
  11. mapfolding-0.8.1/mapFolding/reference/jax.py → mapfolding-0.8.3/mapFolding/reference/jaxCount.py +46 -27
  12. mapfolding-0.8.3/mapFolding/reference/jobsCompleted/[2x19]/p2x19.py +197 -0
  13. mapfolding-0.8.3/mapFolding/reference/jobsCompleted/__init__.py +50 -0
  14. mapfolding-0.8.3/mapFolding/reference/jobsCompleted/p2x19/p2x19.py +29 -0
  15. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/reference/lunnanNumpy.py +16 -1
  16. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/reference/lunnanWhile.py +15 -1
  17. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/reference/rotatedEntryPoint.py +18 -0
  18. mapfolding-0.8.3/mapFolding/reference/total_countPlus1vsPlusN.py +234 -0
  19. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/getLLVMforNoReason.py +20 -1
  20. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/synthesizeNumbaFlow.py +52 -37
  21. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/transformDataStructures.py +11 -5
  22. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/transformationTools.py +40 -42
  23. mapfolding-0.8.3/mapFolding/syntheticModules/__init__.py +1 -0
  24. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/theSSOT.py +69 -127
  25. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding.egg-info/PKG-INFO +56 -31
  26. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding.egg-info/SOURCES.txt +5 -1
  27. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding.egg-info/top_level.txt +0 -1
  28. {mapfolding-0.8.1 → mapfolding-0.8.3}/pyproject.toml +3 -2
  29. {mapfolding-0.8.1 → mapfolding-0.8.3}/tests/conftest.py +43 -33
  30. {mapfolding-0.8.1 → mapfolding-0.8.3}/tests/test_computations.py +7 -7
  31. {mapfolding-0.8.1 → mapfolding-0.8.3}/tests/test_other.py +5 -4
  32. mapfolding-0.8.1/README.md +0 -114
  33. mapfolding-0.8.1/mapFolding/reference/total_countPlus1vsPlusN.py +0 -211
  34. mapfolding-0.8.1/tests/__init__.py +0 -0
  35. {mapfolding-0.8.1 → mapfolding-0.8.3}/LICENSE +0 -0
  36. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/filesystem.py +0 -0
  37. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/noHomeYet.py +0 -0
  38. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/py.typed +0 -0
  39. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/__init__.py +0 -0
  40. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/ingredientsNumba.py +0 -0
  41. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/synthesizeNumbaJobVESTIGIAL.py +0 -0
  42. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/syntheticModules/numbaCount_doTheNeedful.py +0 -0
  43. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding/theDao.py +0 -0
  44. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding.egg-info/dependency_links.txt +0 -0
  45. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding.egg-info/entry_points.txt +0 -0
  46. {mapfolding-0.8.1 → mapfolding-0.8.3}/mapFolding.egg-info/requires.txt +0 -0
  47. {mapfolding-0.8.1 → mapfolding-0.8.3}/setup.cfg +0 -0
  48. {mapfolding-0.8.1/mapFolding/reference → mapfolding-0.8.3/tests}/__init__.py +0 -0
  49. {mapfolding-0.8.1 → mapfolding-0.8.3}/tests/test_filesystem.py +0 -0
  50. {mapfolding-0.8.1 → mapfolding-0.8.3}/tests/test_oeis.py +0 -0
  51. {mapfolding-0.8.1 → mapfolding-0.8.3}/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.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
@@ -92,58 +92,83 @@ Use `getOEISids` to get the most up-to-date list of available OEIS IDs.
92
92
  (mapFolding) C:\apps\mapFolding> getOEISids
93
93
 
94
94
  Available OEIS sequences:
95
- A001415: Number of ways of folding a 2 X n strip of stamps.
95
+ A001415: Number of ways of folding a 2 X n strip of stamps. (Now extended to n=20!)
96
96
  A001416: Number of ways of folding a 3 X n strip of stamps.
97
97
  A001417: Number of ways of folding a 2 X 2 X ... X 2 n-dimensional map.
98
98
  A001418: Number of ways of folding an n X n sheet of stamps.
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`)
122
+ - **New Computations**: First-ever calculations for 2×19 and 2×20 maps in the `reference/jobsCompleted/` directory
123
123
 
124
- ### 4. **Customization and Extension Guide**
124
+ The `reference` directory serves as both a historical archive and an educational resource for understanding algorithm evolution.
125
125
 
126
- The package architecture supports multiple levels of customization:
126
+ ### 3. **Algorithmic Transformation: From Readability to Speed** 🔬
127
127
 
128
- - **Basic Usage**: Work with the high-level API in `basecamp.py` for standard computations
129
- - **Algorithm Modification**:
128
+ The package provides a sophisticated transformation framework that bridges the gap between human-readable algorithms and high-performance computation:
129
+
130
+ - **Core Algorithm Understanding**:
131
+ - Study the functional state-transformation approach in `theDao.py` with clear, isolated functions
132
+ - Explore the semantic decomposition in `reference/flattened.py` to understand algorithm sections
133
+
134
+ - **Code Transformation Pipeline**:
135
+ - **AST Manipulation**: Analyzes and transforms the algorithm's abstract syntax tree
136
+ - **Dataclass "Shattering"**: Decomposes complex state objects into primitive components
137
+ - **Optimization Applications**: Applies domain-specific optimizations for numerical computation
138
+ - **LLVM Integration**: Extracts LLVM IR for low-level algorithmic analysis
139
+
140
+ - **Performance Breakthroughs**:
141
+ - Learn why nearly identical algorithms can have dramatically different performance (`total_countPlus1vsPlusN.py`)
142
+ - See how memory layout and increment strategy impact computation speed
143
+ - Understand the batching technique that yields order-of-magnitude improvements
144
+
145
+ ### 4. **Multi-Level Architecture: From Simple API to Full Customization**
146
+
147
+ The package's architecture supports multiple levels of engagement:
148
+
149
+ - **Basic Usage**:
150
+ - Work with the high-level API in `basecamp.py` for standard computations
151
+ - Access OEIS sequence calculations with minimal code
152
+
153
+ - **Algorithm Exploration**:
154
+ - Compare different implementations in the `reference` directory to understand trade-offs
130
155
  - Modify the core algorithm in `theDao.py` while preserving its functional approach
131
156
  - 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
157
 
134
158
  - **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
159
+ - Use the `someAssemblyRequired` package to transform algorithms at the AST level
160
+ - Create optimized variants with different compilation settings using:
161
+ - `transformationTools.py` for AST manipulation
162
+ - `transformDataStructures.py` for complex data structure transformations
163
+ - `ingredientsNumba.py` for Numba-specific optimization profiles
164
+ - `synthesizeNumbaFlow.py` to orchestrate the transformation process
140
165
 
141
166
  - **Custom Deployment**:
142
167
  - 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
168
+ - Create optimized standalone modules for production use
169
+ - Extract LLVM IR for further analysis and optimization
145
170
 
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.
171
+ 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
172
 
148
173
  ## Map-folding Video
149
174
 
@@ -0,0 +1,139 @@
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. (Now extended to n=20!)
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
+ - **New Computations**: First-ever calculations for 2×19 and 2×20 maps in the `reference/jobsCompleted/` directory
74
+
75
+ The `reference` directory serves as both a historical archive and an educational resource for understanding algorithm evolution.
76
+
77
+ ### 3. **Algorithmic Transformation: From Readability to Speed** 🔬
78
+
79
+ The package provides a sophisticated transformation framework that bridges the gap between human-readable algorithms and high-performance computation:
80
+
81
+ - **Core Algorithm Understanding**:
82
+ - Study the functional state-transformation approach in `theDao.py` with clear, isolated functions
83
+ - Explore the semantic decomposition in `reference/flattened.py` to understand algorithm sections
84
+
85
+ - **Code Transformation Pipeline**:
86
+ - **AST Manipulation**: Analyzes and transforms the algorithm's abstract syntax tree
87
+ - **Dataclass "Shattering"**: Decomposes complex state objects into primitive components
88
+ - **Optimization Applications**: Applies domain-specific optimizations for numerical computation
89
+ - **LLVM Integration**: Extracts LLVM IR for low-level algorithmic analysis
90
+
91
+ - **Performance Breakthroughs**:
92
+ - Learn why nearly identical algorithms can have dramatically different performance (`total_countPlus1vsPlusN.py`)
93
+ - See how memory layout and increment strategy impact computation speed
94
+ - Understand the batching technique that yields order-of-magnitude improvements
95
+
96
+ ### 4. **Multi-Level Architecture: From Simple API to Full Customization**
97
+
98
+ The package's architecture supports multiple levels of engagement:
99
+
100
+ - **Basic Usage**:
101
+ - Work with the high-level API in `basecamp.py` for standard computations
102
+ - Access OEIS sequence calculations with minimal code
103
+
104
+ - **Algorithm Exploration**:
105
+ - Compare different implementations in the `reference` directory to understand trade-offs
106
+ - Modify the core algorithm in `theDao.py` while preserving its functional approach
107
+ - Configure system-wide settings in `theSSOT.py` to adjust data types and performance characteristics
108
+
109
+ - **Advanced Transformation**:
110
+ - Use the `someAssemblyRequired` package to transform algorithms at the AST level
111
+ - Create optimized variants with different compilation settings using:
112
+ - `transformationTools.py` for AST manipulation
113
+ - `transformDataStructures.py` for complex data structure transformations
114
+ - `ingredientsNumba.py` for Numba-specific optimization profiles
115
+ - `synthesizeNumbaFlow.py` to orchestrate the transformation process
116
+
117
+ - **Custom Deployment**:
118
+ - Generate specialized implementations for specific dimensions
119
+ - Create optimized standalone modules for production use
120
+ - Extract LLVM IR for further analysis and optimization
121
+
122
+ 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.
123
+
124
+ ## Map-folding Video
125
+
126
+ ~~This caused my neurosis:~~ I enjoyed the following video, which is what introduced me to map folding.
127
+
128
+ "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)
129
+
130
+ [![How Many Ways Can You Fold a Map?](https://i.ytimg.com/vi/sfH9uIY3ln4/hq720.jpg)](https://www.youtube.com/watch?v=sfH9uIY3ln4)
131
+
132
+ ---
133
+
134
+ ## My recovery
135
+
136
+ [![Static Badge](https://img.shields.io/badge/2011_August-Homeless_since-blue?style=flat)](https://HunterThinks.com/support)
137
+ [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UC3Gx7kz61009NbhpRtPP7tw)](https://www.youtube.com/@HunterHogan)
138
+
139
+ [![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/)
@@ -22,17 +22,21 @@ Special directories:
22
22
  - .cache/: Stores cached data from external sources like OEIS to improve performance
23
23
  - syntheticModules/: Contains dynamically generated, optimized implementations of the
24
24
  core algorithm created by the code transformation framework
25
+ - reference/: Historical implementations and educational resources for algorithm exploration
26
+ - reference/jobsCompleted/: Contains successful computations for previously unknown values,
27
+ including first-ever calculations for 2×19 and 2×20 maps (OEIS A001415)
25
28
 
26
29
  This package strives to balance algorithm readability and understandability with
27
30
  high-performance computation capabilities, allowing users to compute map folding
28
31
  totals for larger dimensions than previously feasible.
29
32
  """
30
33
  from mapFolding.basecamp import countFolds as countFolds
31
- from mapFolding.oeis import clearOEIScache, getOEISids, OEIS_for_n
34
+ from mapFolding.oeis import clearOEIScache, getOEISids, OEIS_for_n, oeisIDfor_n
32
35
 
33
36
  __all__ = [
34
37
  'clearOEIScache',
35
38
  'countFolds',
36
39
  'getOEISids',
37
40
  'OEIS_for_n',
41
+ 'oeisIDfor_n',
38
42
  ]
@@ -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,45 @@
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
+ 5. Published computations:
30
+ - jobsCompleted/ - Contains the source code and results of significant new computations:
31
+ - [2,19] - First-ever computation of the 2x19 map (completed Jan 2025)
32
+ - [2,20] - First-ever computation of the 2x20 map (completed Jan 2025)
33
+ - These calculations extend the known values for OEIS sequence A001415
34
+
35
+ These reference implementations are valuable for:
36
+ - Understanding the algorithm's historical development
37
+ - Comparing performance characteristics across implementation strategies
38
+ - Studying optimization techniques and their effects
39
+ - Verifying the correctness of the core algorithm against known solutions
40
+ - Reproducing published computational results that extend mathematical knowledge
41
+
42
+ Note: These implementations are for reference only and not used in the production
43
+ code path of the package. The active implementation resides in theDao.py with
44
+ optimized variants generated by the someAssemblyRequired framework.
45
+ """
@@ -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.