mapFolding 0.16.2__py3-none-any.whl → 0.16.4__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.
Files changed (66) hide show
  1. easyRun/NOTcountingFolds.py +6 -5
  2. easyRun/countFolds.py +1 -1
  3. easyRun/generateAllModules.py +14 -0
  4. easyRun/meanders.py +1 -1
  5. mapFolding/__init__.py +1 -0
  6. mapFolding/_theSSOT.py +3 -2
  7. mapFolding/_theTypes.py +3 -0
  8. mapFolding/algorithms/A086345.py +75 -0
  9. mapFolding/algorithms/oeisIDbyFormula.py +2 -2
  10. mapFolding/algorithms/symmetricFolds.py +36 -0
  11. mapFolding/basecamp.py +80 -149
  12. mapFolding/dataBaskets.py +123 -5
  13. mapFolding/filesystemToolkit.py +4 -32
  14. mapFolding/oeis.py +5 -12
  15. mapFolding/reference/A086345Wu.py +25 -0
  16. mapFolding/reference/matrixMeandersAnalysis/signatures.py +3 -0
  17. mapFolding/someAssemblyRequired/A007822/A007822rawMaterials.py +10 -45
  18. mapFolding/someAssemblyRequired/A007822/_asynchronousAnnex.py +51 -0
  19. mapFolding/someAssemblyRequired/A007822/makeA007822AsynchronousModules.py +36 -195
  20. mapFolding/someAssemblyRequired/A007822/makeA007822Modules.py +42 -44
  21. mapFolding/someAssemblyRequired/RecipeJob.py +78 -18
  22. mapFolding/someAssemblyRequired/__init__.py +3 -8
  23. mapFolding/someAssemblyRequired/_toolkitContainers.py +32 -3
  24. mapFolding/someAssemblyRequired/infoBooth.py +40 -23
  25. mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +74 -153
  26. mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +56 -88
  27. mapFolding/someAssemblyRequired/makingModules_count.py +10 -12
  28. mapFolding/someAssemblyRequired/makingModules_doTheNeedful.py +6 -68
  29. mapFolding/someAssemblyRequired/{mapFolding → mapFoldingModules}/makeMapFoldingModules.py +24 -30
  30. mapFolding/someAssemblyRequired/meanders/makeMeandersModules.py +8 -6
  31. mapFolding/someAssemblyRequired/toolkitMakeModules.py +2 -2
  32. mapFolding/someAssemblyRequired/toolkitNumba.py +1 -1
  33. mapFolding/someAssemblyRequired/transformationTools.py +10 -12
  34. mapFolding/syntheticModules/A007822/algorithm.py +45 -50
  35. mapFolding/syntheticModules/A007822/asynchronous.py +91 -34
  36. mapFolding/syntheticModules/A007822/initializeState.py +15 -21
  37. mapFolding/syntheticModules/A007822/theorem2.py +16 -22
  38. mapFolding/syntheticModules/A007822/theorem2Numba.py +20 -26
  39. mapFolding/syntheticModules/A007822/theorem2Trimmed.py +17 -23
  40. mapFolding/syntheticModules/countParallelNumba.py +3 -7
  41. mapFolding/syntheticModules/daoOfMapFoldingNumba.py +1 -2
  42. mapFolding/syntheticModules/meanders/bigInt.py +9 -9
  43. mapFolding/syntheticModules/theorem2Numba.py +28 -9
  44. mapFolding/syntheticModules/theorem2Trimmed.py +1 -1
  45. mapFolding/tests/test_computations.py +1 -1
  46. {mapfolding-0.16.2.dist-info → mapfolding-0.16.4.dist-info}/METADATA +4 -1
  47. {mapfolding-0.16.2.dist-info → mapfolding-0.16.4.dist-info}/RECORD +52 -61
  48. mapFolding/_dataPacking.py +0 -68
  49. mapFolding/reference/meandersDumpingGround/A005316intOptimized.py +0 -122
  50. mapFolding/reference/meandersDumpingGround/A005316optimized128bit.py +0 -79
  51. mapFolding/reference/meandersDumpingGround/matrixMeandersBaseline.py +0 -65
  52. mapFolding/reference/meandersDumpingGround/matrixMeandersBaselineAnnex.py +0 -84
  53. mapFolding/reference/meandersDumpingGround/matrixMeandersSimpleQueue.py +0 -90
  54. mapFolding/syntheticModules/A007822/algorithmNumba.py +0 -94
  55. mapFolding/syntheticModules/A007822/asynchronousAnnex.py +0 -66
  56. mapFolding/syntheticModules/A007822/asynchronousAnnexNumba.py +0 -70
  57. mapFolding/syntheticModules/A007822/asynchronousNumba.py +0 -79
  58. mapFolding/syntheticModules/A007822/asynchronousTheorem2.py +0 -65
  59. mapFolding/syntheticModules/A007822/asynchronousTrimmed.py +0 -56
  60. mapFolding/syntheticModules/dataPacking.py +0 -26
  61. mapFolding/syntheticModules/dataPackingA007822.py +0 -92
  62. /mapFolding/someAssemblyRequired/{mapFolding → mapFoldingModules}/__init__.py +0 -0
  63. {mapfolding-0.16.2.dist-info → mapfolding-0.16.4.dist-info}/WHEEL +0 -0
  64. {mapfolding-0.16.2.dist-info → mapfolding-0.16.4.dist-info}/entry_points.txt +0 -0
  65. {mapfolding-0.16.2.dist-info → mapfolding-0.16.4.dist-info}/licenses/LICENSE +0 -0
  66. {mapfolding-0.16.2.dist-info → mapfolding-0.16.4.dist-info}/top_level.txt +0 -0
@@ -15,20 +15,21 @@ if __name__ == '__main__':
15
15
  "\033[0m\n"
16
16
  )
17
17
 
18
- CPUlimit: bool | float | int | None = -2
18
+ CPUlimit: bool | float | int | None = 3
19
19
  # oeisID: str | None = None
20
20
  oeis_n: int | None = None
21
21
  flow: str | None = None
22
22
 
23
+ oeisID = 'A001010'
23
24
  oeisID = 'A007822'
24
25
 
25
- flow = 'asynchronous'
26
26
  flow = 'algorithm'
27
- flow = 'asynchronousNumba'
27
+ flow = 'asynchronous'
28
28
  flow = 'theorem2Numba'
29
- flow = 'asynchronousTrimmed'
29
+ flow = 'theorem2Trimmed'
30
30
 
31
- for n in range(3,9):
31
+ # for n in range(7,10):
32
+ for n in range(3,8):
32
33
 
33
34
  timeStart = time.perf_counter()
34
35
  countTotal = NOTcountingFolds(oeisID, n, flow, CPUlimit)
easyRun/countFolds.py CHANGED
@@ -25,7 +25,7 @@ if __name__ == '__main__':
25
25
  # mapShape: tuple[int, ...] | None = None
26
26
  flow: str | None = 'theorem2Numba'
27
27
 
28
- oeisID: str = 'A001415'
28
+ oeisID: str = 'A001416'
29
29
  for n in range(3,8):
30
30
 
31
31
  mapShape: tuple[int, ...] = dictionaryOEISMapFolding[oeisID]['getMapShape'](n)
@@ -0,0 +1,14 @@
1
+ """Generate all modules that require some assembly."""
2
+ from mapFolding.someAssemblyRequired.A007822.makeA007822AsynchronousModules import makeA007822AsynchronousModules
3
+ from mapFolding.someAssemblyRequired.A007822.makeA007822Modules import makeA007822Modules
4
+ from mapFolding.someAssemblyRequired.mapFoldingModules.makeMapFoldingModules import makeMapFoldingModules
5
+ from mapFolding.someAssemblyRequired.meanders.makeMeandersModules import makeMeandersModules
6
+
7
+ # TODO from mapFolding.zCuzDocStoopid import makeDocstrings
8
+
9
+ makeMapFoldingModules()
10
+
11
+ makeA007822Modules()
12
+ makeA007822AsynchronousModules()
13
+
14
+ makeMeandersModules()
easyRun/meanders.py CHANGED
@@ -29,7 +29,7 @@ if __name__ == '__main__':
29
29
  flow = 'matrixNumPy'
30
30
 
31
31
  for oeisID in [
32
- # 'A005316',
32
+ 'A005316',
33
33
  'A000682',
34
34
  ]:
35
35
  sys.stdout.write(f"\n{oeisID}\n")
mapFolding/__init__.py CHANGED
@@ -4,6 +4,7 @@ from mapFolding._theTypes import (
4
4
  Array1DElephino as Array1DElephino,
5
5
  Array1DFoldsTotal as Array1DFoldsTotal,
6
6
  Array1DLeavesTotal as Array1DLeavesTotal,
7
+ Array2DLeavesTotal as Array2DLeavesTotal,
7
8
  Array3DLeavesTotal as Array3DLeavesTotal,
8
9
  axisOfLength as axisOfLength,
9
10
  DatatypeElephino as DatatypeElephino,
mapFolding/_theSSOT.py CHANGED
@@ -43,7 +43,7 @@ class mapFoldingPackageSettings(PackageSettings):
43
43
  concurrencyPackage: str = 'multiprocessing'
44
44
  """Package identifier for concurrent execution operations."""
45
45
  # ruff: noqa: S311
46
- # TODO I made a `TypedDict` before I knew how to make dataclasses and classes. Think about other data structures.
46
+ # TODO I made this a `TypedDict` before I knew how to make dataclasses and classes. Think about other data structures.
47
47
  OEISidMapFoldingManuallySet: dict[str, MetadataOEISidMapFoldingManuallySet] = {
48
48
  'A000136': {
49
49
  'getMapShape': lambda n: (1, n),
@@ -89,7 +89,6 @@ identifierPackageFALLBACK = "mapFolding"
89
89
  packageSettings = mapFoldingPackageSettings(identifierPackageFALLBACK=identifierPackageFALLBACK, OEISidMapFoldingManuallySet=OEISidMapFoldingManuallySet)
90
90
  """Global package settings."""
91
91
 
92
- """Local directory path for storing cached OEIS sequence data and metadata."""
93
92
  OEISidManuallySet: dict[str, MetadataOEISidManuallySet] = {
94
93
  'A000560': {'valuesTestValidation': [random.randint(3, 12)]},
95
94
  'A000682': {'valuesTestValidation': [random.randint(3, 12), 32]},
@@ -101,6 +100,7 @@ OEISidManuallySet: dict[str, MetadataOEISidManuallySet] = {
101
100
  'A060206': {'valuesTestValidation': [random.randint(3, 9)]},
102
101
  'A077460': {'valuesTestValidation': [3, 4, random.randint(5, 8)]},
103
102
  'A078591': {'valuesTestValidation': [random.randint(3, 10)]},
103
+ 'A086345': {'valuesTestValidation': [random.randint(3, 10), random.randint(11, 20), random.randint(21, 30), random.randint(31, 40)]},
104
104
  'A178961': {'valuesTestValidation': [random.randint(3, 11)]},
105
105
  'A223094': {'valuesTestValidation': [random.randint(3, 11)]},
106
106
  'A259702': {'valuesTestValidation': [random.randint(3, 13)]},
@@ -117,3 +117,4 @@ packageSettings = mapFoldingPackageSettings(
117
117
 
118
118
  # TODO integrate into packageSettings
119
119
  pathCache: Path = packageSettings.pathPackage / ".cache"
120
+ """Local directory path for storing cached OEIS sequence data and metadata."""
mapFolding/_theTypes.py CHANGED
@@ -44,6 +44,9 @@ different data structure."""
44
44
  Array3DLeavesTotal: TypeAlias = ndarray[tuple[int, int, int], dtype[NumPyLeavesTotal]] # noqa: UP040 The TypeAlias may be used to construct ("cast") a value to the type. And the identifier may be changed to a different type.
45
45
  """A `numpy.ndarray` with three axes and elements of type `NumPyLeavesTotal`."""
46
46
 
47
+ Array2DLeavesTotal: TypeAlias = ndarray[tuple[int, int], dtype[NumPyLeavesTotal]] # noqa: UP040 The TypeAlias may be used to construct ("cast") a value to the type. And the identifier may be changed to a different type.
48
+ """A `numpy.ndarray` with two axes and elements of type `NumPyLeavesTotal`."""
49
+
47
50
  Array1DLeavesTotal: TypeAlias = ndarray[tuple[int], dtype[NumPyLeavesTotal]] # noqa: UP040 The TypeAlias may be used to construct ("cast") a value to the type. And the identifier may be changed to a different type.
48
51
  """A `numpy.ndarray` with one axis and elements of type `NumPyLeavesTotal`."""
49
52
 
@@ -0,0 +1,75 @@
1
+ """Directly based on code Chai Wah Wu, https://oeis.org/wiki/User:Chai_Wah_Wu, posted on OEIS."""
2
+ from fractions import Fraction
3
+ from functools import cache
4
+ from itertools import combinations
5
+ from math import factorial, gcd
6
+ from sympy import divisors
7
+ from sympy.functions.combinatorial.numbers import mobius
8
+ from sympy.utilities.iterables import partitions
9
+
10
+ @cache
11
+ def _GoCountryDancing(romeo: int, copiesRomeo: int, sierra: int, copiesSierra: int) -> int:
12
+ return copiesRomeo * copiesSierra * gcd(romeo, sierra)
13
+
14
+ @cache
15
+ def _goRight(integer: int, copies: int) -> int:
16
+ return ((integer - 1) >> 1) * copies + (integer * copies * (copies - 1) >> 1)
17
+
18
+ @cache
19
+ def _deFactorial(integer: int, copies: int) -> int:
20
+ return integer ** copies * factorial(copies)
21
+
22
+ @cache
23
+ def _blender(n: int) -> int:
24
+ sumReBletionary: int = 0
25
+ for partitionary in partitions(n):
26
+ numbinations: int = 0
27
+ nummaNumma: int = 0
28
+ denominator: int = 1
29
+ for (romeo, copiesRomeo), (sierra, copiesSierra) in combinations(partitionary.items(), 2):
30
+ numbinations += _GoCountryDancing(romeo, copiesRomeo, sierra, copiesSierra)
31
+ for integer, copies in partitionary.items():
32
+ nummaNumma += _goRight(integer, copies)
33
+ denominator *= _deFactorial(integer, copies)
34
+ numerator: int = 3 ** (numbinations + nummaNumma)
35
+ sumReBletionary += Fraction(numerator, denominator)
36
+ return sumReBletionary
37
+
38
+ @cache
39
+ def _recurser(n: int) -> int:
40
+ sumReBlender: int = 0
41
+ for k in range(1, n):
42
+ sumReBlender += _recurser(k) * _blender(n - k)
43
+ return n * _blender(n) - sumReBlender
44
+
45
+ def A086345(n: int) -> int:
46
+ """Compute 'Number of connected oriented graphs (i.e., connected directed graphs with no bidirected edges) on n nodes'.
47
+
48
+ Parameters
49
+ ----------
50
+ n : int
51
+ Index (n-dex) for a(n) in the sequence of values. "n" (lower case) and "a(n)" are conventions in mathematics.
52
+
53
+ Returns
54
+ -------
55
+ a(n) : int
56
+ Number of connected oriented graphs (i.e., connected directed graphs with no bidirected edges) on n nodes.
57
+
58
+ Notes
59
+ -----
60
+ - The largest performance gains are from caching the recursion and `sympy.utilities.iterables.partitions` functions.
61
+ - Interestingly, there is a small but noticeable penalty for choosing comprehension instead of `for`.
62
+
63
+ Would You Like to Know More?
64
+ ----------------------------
65
+ OEIS : webpage
66
+ https://oeis.org/A086345
67
+ """
68
+ if n == 0:
69
+ aOFn: int = 1
70
+ else:
71
+ aOFn: int = 0
72
+ for aDivisor in divisors(n, generator=True):
73
+ aOFn += mobius(aDivisor) * _recurser(n//aDivisor)
74
+ aOFn //= n
75
+ return aOFn
@@ -41,7 +41,7 @@ def A000560(n: int) -> int:
41
41
  """
42
42
  Compute A000560(n) as a function of A000682.
43
43
 
44
- *The On-Line Encyclopedia of Integer Sequences* (OEIS) description of A000560 is: "Number of ways of folding a strip of n labeled stamps."
44
+ *The On-Line Encyclopedia of Integer Sequences* (OEIS) description of A000560 is: "Number of symmetric ways of folding a strip of n labeled stamps."
45
45
 
46
46
  The domain of A000560 starts at 2, therefore for values of `n` < 2, a(n) is undefined. The smallest value of n for which a(n)
47
47
  has not yet been computed is 45.
@@ -54,7 +54,7 @@ def A000560(n: int) -> int:
54
54
  Returns
55
55
  -------
56
56
  a(n) : int
57
- Number of ways of folding a strip of n labeled stamps.
57
+ Number of symmetric ways of folding a strip of n labeled stamps.
58
58
 
59
59
  Would You Like to Know More?
60
60
  ----------------------------
@@ -0,0 +1,36 @@
1
+ """Count the number of symmetric folds in the group of folds defined by `leafBelow`.
2
+
3
+ Notes
4
+ -----
5
+ - About constructing `leafComparison`:
6
+ - This branch of the algorithm executes IFF `leafBelow[0] == 1`.
7
+ - Therefore, `leafComparison[0]` must be `1`.
8
+ - Therefore, the first iteration of the loop is hardcoded to save processing time.
9
+ - I _feel_ there must be a more efficient way to do this.
10
+ - Some implementation details are based on Numba compatibility. Incompatible:
11
+ - `numpy.take(..., out=...)`
12
+ - `numpy.all(..., axis=...)`
13
+ """
14
+ from mapFolding.dataBaskets import SymmetricFoldsState
15
+ import numpy
16
+
17
+ def filterAsymmetricFolds(state: SymmetricFoldsState) -> SymmetricFoldsState:
18
+ state.indexLeaf = 1
19
+ state.leafComparison[0] = 1
20
+ state.leafConnectee = 1
21
+
22
+ while state.leafConnectee < state.leavesTotal + 1:
23
+ state.indexMiniGap = state.leafBelow[state.indexLeaf]
24
+ state.leafComparison[state.leafConnectee] = (state.indexMiniGap - state.indexLeaf + state.leavesTotal) % state.leavesTotal
25
+ state.indexLeaf = state.indexMiniGap
26
+
27
+ state.leafConnectee += 1
28
+
29
+ state.arrayGroupOfFolds = numpy.take(state.leafComparison, state.indicesArrayGroupOfFolds)
30
+ compared = state.arrayGroupOfFolds[..., 0:state.leavesTotal // 2] == state.arrayGroupOfFolds[..., state.leavesTotal // 2:None]
31
+
32
+ for indexRow in range(len(compared)):
33
+ state.groupsOfFolds += compared[indexRow].all()
34
+
35
+ return state
36
+
mapFolding/basecamp.py CHANGED
@@ -4,37 +4,39 @@ from collections.abc import Sequence
4
4
  from mapFolding import (
5
5
  getPathFilenameFoldsTotal, packageSettings, saveFoldsTotal, saveFoldsTotalFAILearly, validateListDimensions)
6
6
  from os import PathLike
7
- from pathlib import PurePath
7
+ from pathlib import Path, PurePath
8
8
  from typing import Literal
9
9
 
10
10
  # ruff: noqa: PLC0415
11
11
  """TODO new flow paradigm, incomplete
12
12
 
13
- I don't want to FORCE people to use the meaningless OEIS ids without providing the definition of the ID at the same time.
14
-
15
- On the other hand, I don't have any evidence that anyone is using this package except me.
16
-
17
- algorithms directory
18
- manually coded algorithms or formulas
19
- `countFolds` will be a stable interface for multidimensional map folding, including synthetic modules
20
- This has special treatment because people may want to call mapShape not defined in OEIS
21
- `countMeanders` will be a stable interface for meanders
22
- This has special treatment because people may want to call meanders not defined in OEIS
23
- an enhanced version of `oeisIDfor_n` will be a stable interface for calling by ID and n
24
-
25
- General flow structure
26
- basecamp should call `doTheNeedful` instead of `count` and `doTheNeedful` should handle things like `initializeState`.
27
- doTheNeedful
28
- specific to that version of that algorithm
29
- abstracts the API for that algorithm, so that algorithm (such as multidimensional map folding) has a stable interface
30
- The last place to do defensive programming
31
-
32
- - Incomplete: how to count
33
- - currently in parameters computationDivisions, CPUlimit, and flow
34
-
35
- - Flow in count______
36
- - DEFENSIVE PROGRAMMING
37
- - FAIL EARLY
13
+ - I don't want to FORCE people to use the meaningless OEIS ids without providing the definition of the ID at the same time.
14
+ - On the other hand, I don't have any evidence that anyone is using this package except me.
15
+ - algorithms directory: manually coded algorithms or formulas.
16
+ - 'basecamp' should be able to call any algorithm version.
17
+ - Quickly call the algorithm or the algorithm's dispatcher, i.e., `doTheNeedful`.
18
+ - `countFolds` will be a stable interface for multidimensional map folding, including synthetic modules.
19
+ - `NOTcountingFolds` is sufficient for now. I'll make an analogue to `countFolds` for some algorithms if it would be useful.
20
+
21
+ - state vs ? environment?
22
+ In multidimensional map folding, computationDivisions is part of the state because it is used in the algorithm during a module
23
+ operation. In contrast, CPUlimit is not used in the algorithm, so I feel like it is not part of the state. Storing the state
24
+ in a databasket (i.e., a dataclass) makes things much easier.
25
+
26
+ Environment settings that I sometimes need:
27
+ Concurrency
28
+ CPUlimit.
29
+ Package for concurrency operations.
30
+ Settings for that package, if it were a GPU, for example.
31
+ Memorialization
32
+ Path
33
+ Filename standardization
34
+ Record only a(n), the entire state, or something else?
35
+ Status updates, such as tqdm.
36
+
37
+ - Flow in basecamp
38
+ - Interpret parameters
39
+ - DEFENSIVE PROGRAMMING; FAIL EARLY
38
40
  - Implement "common foundational logic".
39
41
  - IDK what the correct technical term is, but I'm sure other people have researched excellent ways to do this.
40
42
  - Example: in `countFolds`, every possible flow path needs `mapShape`. Therefore, `mapShape` is foundational logic that
@@ -42,37 +44,17 @@ General flow structure
42
44
  - Example: in `countFolds`, some flow paths have more than one "task division" (i.e., the computation is divided into
43
45
  multiple tasks), while other flow paths only have one task division. One reasonable perspective is that computing task
44
46
  divisions is NOT "common foundational logic". My perspective for this example: to compute whether or not there are
45
- task divisions and if so, how many task divisions is identical for all flow paths. Therefore, I handle computing task
46
- divisions as "common foundational logic".
47
- - Incomplete
48
- - Initialize memorialization instructions, if asked
49
- - MORE DEFENSIVE PROGRAMMING
50
- - FAIL EARLIER THAN EARLY
51
- - Incomplete
52
- - DEFENSIVE PROGRAMMING ON BEHALF of downstream modules and functions
53
- - FAIL SO EARLY IT IS BEFORE THE USER INSTALLS THE APP
54
- - Incomplete
55
- - REPEAT MANY OR ALL OF THE DEFENSIVE PROGRAMMING YOU HAVE ALREADY DONE
56
-
57
- - Incomplete
47
+ task divisions is identical for all flow paths. Therefore, it is "common foundational logic".
48
+ - Initialize memorialization instructions, if asked.
58
49
  - Pass control to the correct `doTheNeedful`
59
- - I don't know how to "elegantly" pass control without putting `doTheNeedful` over `count______` in the stack, therefore,
50
+ - I don't know how to "elegantly" pass control without putting `doTheNeedful` on `count______` in the stack, therefore,
60
51
  control will come back here.
61
- - DO NOT, for the love of puppies and cookies, DO NOT use defensive programming here. Defensive programming AFTER a
62
- four-week-long computation is a tacit admission of incompetent programming.
63
- - Follow memorialization instructions: which means pass control to a function will tenaciously follow the instructions.
64
- - return "a(n)" (as OEIS calls it), such as foldsTotal
65
-
52
+ - DO NOT, for the love of puppies and cookies, DO NOT use defensive programming when control returns here. Defensive
53
+ programming AFTER a four-week-long computation is a tacit admission of incompetent programming.
54
+ - Follow memorialization instructions: which means pass control to a function that will tenaciously follow the instructions.
55
+ - return "a(n)" (as OEIS calls it), such as foldsTotal.
66
56
  """
67
57
 
68
- # Parameters
69
- # What you want to compute
70
- # Memorialization
71
- # Concurrency
72
- # How you want to compute it
73
- # Interpretation of parameters
74
- # Input data
75
-
76
58
  def countFolds(listDimensions: Sequence[int] | None = None
77
59
  , pathLikeWriteFoldsTotal: PathLike[str] | PurePath | None = None
78
60
  , computationDivisions: int | str | None = None
@@ -82,7 +64,7 @@ def countFolds(listDimensions: Sequence[int] | None = None
82
64
  , flow: str | None = None
83
65
  ) -> int:
84
66
  """
85
- Count the total number of distinct ways to fold a map.
67
+ Count the number of distinct ways to fold a map.
86
68
 
87
69
  Mathematicians also describe this as folding a strip of stamps, and they usually call the total "number of distinct ways to
88
70
  fold" a map the map's "foldings."
@@ -129,7 +111,8 @@ def countFolds(listDimensions: Sequence[int] | None = None
129
111
 
130
112
  Returns
131
113
  -------
132
- foldsTotal: Total number of distinct ways to fold a map of the given dimensions.
114
+ foldsTotal : int
115
+ Number of distinct ways to fold a map of the given dimensions.
133
116
 
134
117
  Note well
135
118
  ---------
@@ -145,7 +128,7 @@ def countFolds(listDimensions: Sequence[int] | None = None
145
128
  computation time. If logicalCores >= `leavesTotal`, it will probably be faster. If logicalCores <= 2 * `leavesTotal`, it
146
129
  will almost certainly be slower for all map dimensions.
147
130
  """
148
- # mapShape ---------------------------------------------------------------------
131
+ # ------- mapShape ---------------------------------------------------------------------
149
132
 
150
133
  if mapShape:
151
134
  pass
@@ -159,7 +142,7 @@ def countFolds(listDimensions: Sequence[int] | None = None
159
142
  )
160
143
  raise ValueError(message)
161
144
 
162
- # task division instructions -----------------------------------------------------
145
+ # ------- task division instructions -----------------------------------------------------
163
146
 
164
147
  if computationDivisions:
165
148
  from mapFolding.beDRY import getLeavesTotal, getTaskDivisions, setProcessorLimit
@@ -171,59 +154,40 @@ def countFolds(listDimensions: Sequence[int] | None = None
171
154
  concurrencyLimit = 1
172
155
  taskDivisions = 0
173
156
 
174
- # memorialization instructions ---------------------------------------------
157
+ # ------- memorialization instructions ---------------------------------------------
175
158
 
176
159
  if pathLikeWriteFoldsTotal is not None:
177
- pathFilenameFoldsTotal = getPathFilenameFoldsTotal(mapShape, pathLikeWriteFoldsTotal)
160
+ pathFilenameFoldsTotal: Path | None = getPathFilenameFoldsTotal(mapShape, pathLikeWriteFoldsTotal)
178
161
  saveFoldsTotalFAILearly(pathFilenameFoldsTotal)
179
162
  else:
180
163
  pathFilenameFoldsTotal = None
181
164
 
182
- # Flow control until I can figure out a good way ---------------------------------
183
-
165
+ # ------- Algorithm version -----------------------------------------------------
184
166
  if taskDivisions > 1:
185
167
  from mapFolding.dataBaskets import ParallelMapFoldingState
186
- mapFoldingParallelState: ParallelMapFoldingState = ParallelMapFoldingState(mapShape, taskDivisions=taskDivisions)
187
-
188
168
  from mapFolding.syntheticModules.countParallelNumba import doTheNeedful
189
169
 
170
+ mapFoldingParallelState: ParallelMapFoldingState = ParallelMapFoldingState(mapShape, taskDivisions=taskDivisions)
171
+
190
172
  # `listStatesParallel` exists so you can research the parallel computation.
191
- foldsTotal, listStatesParallel = doTheNeedful(mapFoldingParallelState, concurrencyLimit) # pyright: ignore[reportUnusedVariable] # noqa: RUF059
173
+ foldsTotal, _listStatesParallel = doTheNeedful(mapFoldingParallelState, concurrencyLimit)
192
174
 
175
+ # ruff: noqa: E701
193
176
  else:
177
+ match flow:
178
+ case 'daoOfMapFolding': from mapFolding.algorithms.daoOfMapFolding import doTheNeedful
179
+ case 'numba': from mapFolding.syntheticModules.daoOfMapFoldingNumba import doTheNeedful
180
+ case 'theorem2': from mapFolding.syntheticModules.theorem2 import doTheNeedful
181
+ case 'theorem2Numba': from mapFolding.syntheticModules.theorem2Numba import doTheNeedful
182
+ case 'theorem2Trimmed': from mapFolding.syntheticModules.theorem2Trimmed import doTheNeedful
183
+ case _: from mapFolding.algorithms.daoOfMapFolding import doTheNeedful
184
+
194
185
  from mapFolding.dataBaskets import MapFoldingState
195
186
  mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
196
-
197
- if flow == 'daoOfMapFolding':
198
- from mapFolding.algorithms.daoOfMapFolding import doTheNeedful
199
- mapFoldingState = doTheNeedful(mapFoldingState)
200
-
201
- elif flow == 'numba':
202
- from mapFolding.syntheticModules.daoOfMapFoldingNumba import doTheNeedful
203
- mapFoldingState = doTheNeedful(mapFoldingState)
204
-
205
- elif flow == 'theorem2' and any(dimension > 2 for dimension in mapShape):
206
- from mapFolding.syntheticModules.theorem2 import doTheNeedful
207
- mapFoldingState = doTheNeedful(mapFoldingState)
208
-
209
- elif (flow == 'theorem2Numba' or taskDivisions == 0) and any(dimension > 2 for dimension in mapShape):
210
- from mapFolding.syntheticModules.initializeState import transitionOnGroupsOfFolds
211
- mapFoldingState = transitionOnGroupsOfFolds(mapFoldingState)
212
-
213
- from mapFolding.syntheticModules.dataPacking import sequential
214
- mapFoldingState = sequential(mapFoldingState)
215
-
216
- elif flow == 'theorem2Trimmed' and any(dimension > 2 for dimension in mapShape):
217
- from mapFolding.syntheticModules.theorem2Trimmed import doTheNeedful
218
- mapFoldingState = doTheNeedful(mapFoldingState)
219
-
220
- else:
221
- from mapFolding.algorithms.daoOfMapFolding import doTheNeedful
222
- mapFoldingState = doTheNeedful(mapFoldingState)
223
-
187
+ mapFoldingState = doTheNeedful(mapFoldingState)
224
188
  foldsTotal = mapFoldingState.foldsTotal
225
189
 
226
- # Follow memorialization instructions ---------------------------------------------
190
+ # ------- Follow memorialization instructions ---------------------------------------------
227
191
 
228
192
  if pathFilenameFoldsTotal is not None:
229
193
  saveFoldsTotal(pathFilenameFoldsTotal, foldsTotal)
@@ -231,7 +195,7 @@ def countFolds(listDimensions: Sequence[int] | None = None
231
195
  return foldsTotal
232
196
 
233
197
  def NOTcountingFolds(oeisID: str, oeis_n: int, flow: str | None = None
234
- # , pathLikeWriteFoldsTotal: PathLike[str] | PurePath | None = None # noqa: ERA001
198
+ # TODO , pathLikeWriteFoldsTotal: PathLike[str] | PurePath | None = None
235
199
  , CPUlimit: bool | float | int | None = None # noqa: FBT001
236
200
  ) -> int:
237
201
  """Do stuff."""
@@ -239,32 +203,20 @@ def NOTcountingFolds(oeisID: str, oeis_n: int, flow: str | None = None
239
203
  matched_oeisID: bool = True
240
204
 
241
205
  match oeisID:
242
- case 'A000136':
243
- from mapFolding.algorithms.oeisIDbyFormula import A000136 as doTheNeedful
244
- case 'A000560':
245
- from mapFolding.algorithms.oeisIDbyFormula import A000560 as doTheNeedful
246
- case 'A001010':
247
- from mapFolding.algorithms.oeisIDbyFormula import A001010 as doTheNeedful
248
- case 'A001011':
249
- from mapFolding.algorithms.oeisIDbyFormula import A001011 as doTheNeedful
250
- case 'A005315':
251
- from mapFolding.algorithms.oeisIDbyFormula import A005315 as doTheNeedful
252
- case 'A060206':
253
- from mapFolding.algorithms.oeisIDbyFormula import A060206 as doTheNeedful
254
- case 'A077460':
255
- from mapFolding.algorithms.oeisIDbyFormula import A077460 as doTheNeedful
256
- case 'A078591':
257
- from mapFolding.algorithms.oeisIDbyFormula import A078591 as doTheNeedful
258
- case 'A178961':
259
- from mapFolding.algorithms.oeisIDbyFormula import A178961 as doTheNeedful
260
- case 'A223094':
261
- from mapFolding.algorithms.oeisIDbyFormula import A223094 as doTheNeedful
262
- case 'A259702':
263
- from mapFolding.algorithms.oeisIDbyFormula import A259702 as doTheNeedful
264
- case 'A301620':
265
- from mapFolding.algorithms.oeisIDbyFormula import A301620 as doTheNeedful
266
- case _:
267
- matched_oeisID = False
206
+ case 'A000136': from mapFolding.algorithms.oeisIDbyFormula import A000136 as doTheNeedful
207
+ case 'A000560': from mapFolding.algorithms.oeisIDbyFormula import A000560 as doTheNeedful
208
+ case 'A001010': from mapFolding.algorithms.oeisIDbyFormula import A001010 as doTheNeedful
209
+ case 'A001011': from mapFolding.algorithms.oeisIDbyFormula import A001011 as doTheNeedful
210
+ case 'A005315': from mapFolding.algorithms.oeisIDbyFormula import A005315 as doTheNeedful
211
+ case 'A060206': from mapFolding.algorithms.oeisIDbyFormula import A060206 as doTheNeedful
212
+ case 'A077460': from mapFolding.algorithms.oeisIDbyFormula import A077460 as doTheNeedful
213
+ case 'A078591': from mapFolding.algorithms.oeisIDbyFormula import A078591 as doTheNeedful
214
+ case 'A086345': from mapFolding.algorithms.A086345 import A086345 as doTheNeedful
215
+ case 'A178961': from mapFolding.algorithms.oeisIDbyFormula import A178961 as doTheNeedful
216
+ case 'A223094': from mapFolding.algorithms.oeisIDbyFormula import A223094 as doTheNeedful
217
+ case 'A259702': from mapFolding.algorithms.oeisIDbyFormula import A259702 as doTheNeedful
218
+ case 'A301620': from mapFolding.algorithms.oeisIDbyFormula import A301620 as doTheNeedful
219
+ case _: matched_oeisID = False
268
220
  if matched_oeisID:
269
221
  countTotal = doTheNeedful(oeis_n) # pyright: ignore[reportPossiblyUnboundVariable]
270
222
  else:
@@ -319,49 +271,28 @@ def NOTcountingFolds(oeisID: str, oeis_n: int, flow: str | None = None
319
271
  from mapFolding import setProcessorLimit
320
272
  concurrencyLimit: int = setProcessorLimit(CPUlimit)
321
273
 
322
- from mapFolding.dataBaskets import MapFoldingState
323
- mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
274
+ from mapFolding.dataBaskets import SymmetricFoldsState
275
+ symmetricState: SymmetricFoldsState = SymmetricFoldsState(mapShape)
324
276
 
325
277
  match flow:
326
278
  case 'asynchronous':
327
279
  from mapFolding.syntheticModules.A007822.asynchronous import doTheNeedful
328
- mapFoldingState = doTheNeedful(mapFoldingState, concurrencyLimit)
329
-
330
- case 'asynchronousNumba':
331
- from mapFolding.syntheticModules.A007822.asynchronousNumba import doTheNeedful
332
- mapFoldingState = doTheNeedful(mapFoldingState, concurrencyLimit)
333
-
334
- case 'asynchronousTheorem2':
335
- from mapFolding.syntheticModules.A007822.asynchronousTheorem2 import doTheNeedful
336
- mapFoldingState = doTheNeedful(mapFoldingState, concurrencyLimit)
337
-
338
- case 'asynchronousTrimmed':
339
- from mapFolding.syntheticModules.A007822.asynchronousTrimmed import doTheNeedful
340
- mapFoldingState = doTheNeedful(mapFoldingState, concurrencyLimit)
341
-
342
- case 'numba':
343
- from mapFolding.syntheticModules.A007822.algorithmNumba import doTheNeedful
344
- mapFoldingState = doTheNeedful(mapFoldingState)
345
-
280
+ symmetricState = doTheNeedful(symmetricState, concurrencyLimit)
346
281
  case 'theorem2':
347
282
  from mapFolding.syntheticModules.A007822.theorem2 import doTheNeedful
348
- mapFoldingState = doTheNeedful(mapFoldingState)
349
-
283
+ symmetricState = doTheNeedful(symmetricState)
350
284
  case 'theorem2Numba':
351
285
  from mapFolding.syntheticModules.A007822.theorem2Numba import doTheNeedful
352
- mapFoldingState = doTheNeedful(mapFoldingState)
353
-
286
+ symmetricState = doTheNeedful(symmetricState)
354
287
  case 'theorem2Trimmed':
355
288
  from mapFolding.syntheticModules.A007822.theorem2Trimmed import doTheNeedful
356
- mapFoldingState = doTheNeedful(mapFoldingState)
357
-
289
+ symmetricState = doTheNeedful(symmetricState)
358
290
  case _:
359
291
  from mapFolding.syntheticModules.A007822.algorithm import doTheNeedful
360
- mapFoldingState = doTheNeedful(mapFoldingState)
292
+ symmetricState = doTheNeedful(symmetricState)
361
293
 
362
- countTotal = mapFoldingState.groupsOfFolds
294
+ countTotal = symmetricState.groupsOfFolds
363
295
  case _:
364
296
  matched_oeisID = False
365
297
 
366
298
  return countTotal
367
-