mapFolding 0.8.1__py3-none-any.whl → 0.8.3__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 (32) hide show
  1. mapFolding/__init__.py +5 -1
  2. mapFolding/basecamp.py +2 -2
  3. mapFolding/beDRY.py +24 -31
  4. mapFolding/oeis.py +2 -2
  5. mapFolding/reference/__init__.py +45 -0
  6. mapFolding/reference/flattened.py +20 -2
  7. mapFolding/reference/hunterNumba.py +24 -0
  8. mapFolding/reference/irvineJavaPort.py +12 -0
  9. mapFolding/reference/{jax.py → jaxCount.py} +46 -27
  10. mapFolding/reference/jobsCompleted/[2x19]/p2x19.py +197 -0
  11. mapFolding/reference/jobsCompleted/__init__.py +50 -0
  12. mapFolding/reference/jobsCompleted/p2x19/p2x19.py +29 -0
  13. mapFolding/reference/lunnanNumpy.py +16 -1
  14. mapFolding/reference/lunnanWhile.py +15 -1
  15. mapFolding/reference/rotatedEntryPoint.py +18 -0
  16. mapFolding/reference/total_countPlus1vsPlusN.py +226 -203
  17. mapFolding/someAssemblyRequired/getLLVMforNoReason.py +20 -1
  18. mapFolding/someAssemblyRequired/synthesizeNumbaFlow.py +52 -37
  19. mapFolding/someAssemblyRequired/transformDataStructures.py +11 -5
  20. mapFolding/someAssemblyRequired/transformationTools.py +40 -42
  21. mapFolding/syntheticModules/__init__.py +1 -0
  22. mapFolding/theSSOT.py +69 -127
  23. {mapfolding-0.8.1.dist-info → mapfolding-0.8.3.dist-info}/METADATA +56 -31
  24. mapfolding-0.8.3.dist-info/RECORD +43 -0
  25. {mapfolding-0.8.1.dist-info → mapfolding-0.8.3.dist-info}/WHEEL +1 -1
  26. tests/conftest.py +43 -33
  27. tests/test_computations.py +7 -7
  28. tests/test_other.py +5 -4
  29. mapfolding-0.8.1.dist-info/RECORD +0 -39
  30. {mapfolding-0.8.1.dist-info → mapfolding-0.8.3.dist-info}/entry_points.txt +0 -0
  31. {mapfolding-0.8.1.dist-info → mapfolding-0.8.3.dist-info}/licenses/LICENSE +0 -0
  32. {mapfolding-0.8.1.dist-info → mapfolding-0.8.3.dist-info}/top_level.txt +0 -0
mapFolding/__init__.py CHANGED
@@ -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
  ]
mapFolding/basecamp.py CHANGED
@@ -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()
mapFolding/beDRY.py CHANGED
@@ -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, ...]:
mapFolding/oeis.py CHANGED
@@ -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.
@@ -1,20 +1,39 @@
1
- """I was able to implement the algorithm with JAX, but I didn't see an advantage and it's a pain in the ass.
2
- I don't maintain this module."""
3
- from mapFolding import validateListDimensions, getLeavesTotal, makeConnectionGraph
4
- from typing import List, Tuple
1
+ """
2
+ I was able to implement the algorithm with JAX, but I didn't see an advantage and it's a pain in the ass.
3
+
4
+ Experimental JAX implementation of Lunnon's algorithm for potential GPU acceleration.
5
+
6
+ This implementation explores the use of JAX (Just After eXecution) for potential GPU acceleration
7
+ of the map folding algorithm. It represents an experimental approach that attempts to leverage
8
+ JAX's transformation capabilities and hardware acceleration through XLA compilation.
9
+
10
+ Key characteristics:
11
+ - Uses JAX's functional programming model with lax control flow primitives
12
+ - Attempts to leverage GPU acceleration for numerical operations
13
+ - Demonstrates JAX-specific patterns for handling loops and conditions
14
+ - Supports jit compilation for performance optimization
15
+
16
+ As noted in the file's comment, this implementation didn't demonstrate significant advantages
17
+ over other approaches and presented additional complexity. It serves as a valuable reference
18
+ for exploring alternative acceleration strategies and understanding the limitations of
19
+ different computational frameworks for this specific algorithm.
20
+ """
21
+ from flattened import validateListDimensions, getLeavesTotal, makeConnectionGraph
22
+ from numpy.typing import NDArray
23
+ from typing import Any
5
24
  import jax
6
25
  import jaxtyping
26
+ import numpy
7
27
 
8
28
  dtypeMedium = jax.numpy.uint32
9
29
  dtypeMaximum = jax.numpy.uint32
10
30
 
11
- def countFolds(listDimensions: List[int]) -> int:
12
- listDimensionsPositive: List[int] = validateListDimensions(listDimensions)
31
+ def countFolds(listDimensions: list[int]) -> int:
32
+ listDimensionsPositive: list[int] = validateListDimensions(listDimensions)
13
33
 
14
34
  n: int = getLeavesTotal(listDimensionsPositive)
15
35
  d: int = len(listDimensions)
16
- import numpy
17
- D: numpy.ndarray = makeConnectionGraph(listDimensionsPositive)
36
+ D: NDArray[numpy.integer[Any]] = makeConnectionGraph(listDimensionsPositive)
18
37
  connectionGraph = jax.numpy.asarray(D, dtype=dtypeMedium)
19
38
  del listDimensionsPositive
20
39
 
@@ -22,14 +41,14 @@ def countFolds(listDimensions: List[int]) -> int:
22
41
 
23
42
  def foldingsJAX(leavesTotal: jaxtyping.UInt32, dimensionsTotal: jaxtyping.UInt32, connectionGraph: jaxtyping.Array) -> jaxtyping.UInt32:
24
43
 
25
- def doNothing(argument):
44
+ def doNothing(argument: Any):
26
45
  return argument
27
46
 
28
- def while_activeLeaf1ndex_greaterThan_0(comparisonValues: Tuple):
47
+ def while_activeLeaf1ndex_greaterThan_0(comparisonValues: tuple):
29
48
  comparand = comparisonValues[6]
30
49
  return comparand > 0
31
50
 
32
- def countFoldings(allValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32, jaxtyping.UInt32]):
51
+ def countFoldings(allValues: tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32, jaxtyping.UInt32]):
33
52
  _0, leafBelow, _2, _3, _4, _5, activeLeaf1ndex, _7 = allValues
34
53
 
35
54
  sentinel = leafBelow.at[0].get().astype(jax.numpy.uint32)
@@ -44,24 +63,24 @@ def foldingsJAX(leavesTotal: jaxtyping.UInt32, dimensionsTotal: jaxtyping.UInt32
44
63
  def findGapsCondition(leafBelowSentinel, activeLeafNumber):
45
64
  return jax.numpy.logical_or(jax.numpy.logical_and(leafBelowSentinel == 1, activeLeafNumber <= leavesTotal), activeLeafNumber <= 1)
46
65
 
47
- def findGapsDo(allValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32, jaxtyping.UInt32]):
48
- def for_dimension1ndex_in_range_1_to_dimensionsTotalPlus1(comparisonValues: Tuple):
66
+ def findGapsDo(allValues: tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32, jaxtyping.UInt32]):
67
+ def for_dimension1ndex_in_range_1_to_dimensionsTotalPlus1(comparisonValues: tuple):
49
68
  return comparisonValues[-1] <= dimensionsTotal
50
69
 
51
- def for_dimension1ndex_in_range_1_to_dimensionsTotalPlus1_do(for_dimension1ndex_in_range_1_to_dimensionsTotalPlus1Values: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32, jaxtyping.UInt32]):
70
+ def for_dimension1ndex_in_range_1_to_dimensionsTotalPlus1_do(for_dimension1ndex_in_range_1_to_dimensionsTotalPlus1Values: tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32, jaxtyping.UInt32]):
52
71
  def ifLeafIsUnconstrainedCondition(comparand):
53
72
  return jax.numpy.equal(connectionGraph[comparand, activeLeaf1ndex, activeLeaf1ndex], activeLeaf1ndex)
54
73
 
55
- def ifLeafIsUnconstrainedDo(unconstrainedValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
74
+ def ifLeafIsUnconstrainedDo(unconstrainedValues: tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
56
75
  unconstrained_unconstrainedLeaf = unconstrainedValues[3]
57
76
  unconstrained_unconstrainedLeaf = 1 + unconstrained_unconstrainedLeaf
58
77
  return (unconstrainedValues[0], unconstrainedValues[1], unconstrainedValues[2], unconstrained_unconstrainedLeaf)
59
78
 
60
- def ifLeafIsUnconstrainedElse(unconstrainedValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
61
- def while_leaf1ndexConnectee_notEquals_activeLeaf1ndex(comparisonValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
79
+ def ifLeafIsUnconstrainedElse(unconstrainedValues: tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
80
+ def while_leaf1ndexConnectee_notEquals_activeLeaf1ndex(comparisonValues: tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
62
81
  return comparisonValues[-1] != activeLeaf1ndex
63
82
 
64
- def countGaps(countGapsDoValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
83
+ def countGaps(countGapsDoValues: tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
65
84
  countGapsCountDimensionsGapped, countGapsPotentialGaps, countGapsGap1ndexLowerBound, countGapsLeaf1ndexConnectee = countGapsDoValues
66
85
 
67
86
  countGapsPotentialGaps = countGapsPotentialGaps.at[countGapsGap1ndexLowerBound].set(countGapsLeaf1ndexConnectee)
@@ -93,11 +112,11 @@ def foldingsJAX(leavesTotal: jaxtyping.UInt32, dimensionsTotal: jaxtyping.UInt32
93
112
  def almostUselessCondition(comparand):
94
113
  return comparand == dimensionsTotal
95
114
 
96
- def almostUselessConditionDo(for_leaf1ndex_in_range_activeLeaf1ndexValues: Tuple[jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
115
+ def almostUselessConditionDo(for_leaf1ndex_in_range_activeLeaf1ndexValues: tuple[jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
97
116
  def for_leaf1ndex_in_range_activeLeaf1ndex(comparisonValues):
98
117
  return comparisonValues[-1] < activeLeaf1ndex
99
118
 
100
- def for_leaf1ndex_in_range_activeLeaf1ndex_do(for_leaf1ndex_in_range_activeLeaf1ndexValues: Tuple[jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
119
+ def for_leaf1ndex_in_range_activeLeaf1ndex_do(for_leaf1ndex_in_range_activeLeaf1ndexValues: tuple[jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
101
120
  leafInRangePotentialGaps, gapNumberLowerBound, leafNumber = for_leaf1ndex_in_range_activeLeaf1ndexValues
102
121
  leafInRangePotentialGaps = leafInRangePotentialGaps.at[gapNumberLowerBound].set(leafNumber)
103
122
  gapNumberLowerBound = 1 + gapNumberLowerBound
@@ -105,10 +124,10 @@ def foldingsJAX(leavesTotal: jaxtyping.UInt32, dimensionsTotal: jaxtyping.UInt32
105
124
  return (leafInRangePotentialGaps, gapNumberLowerBound, leafNumber)
106
125
  return jax.lax.while_loop(for_leaf1ndex_in_range_activeLeaf1ndex, for_leaf1ndex_in_range_activeLeaf1ndex_do, for_leaf1ndex_in_range_activeLeaf1ndexValues)
107
126
 
108
- def for_range_from_activeGap1ndex_to_gap1ndexCeiling(comparisonValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
127
+ def for_range_from_activeGap1ndex_to_gap1ndexCeiling(comparisonValues: tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
109
128
  return comparisonValues[-1] < gap1ndexCeiling
110
129
 
111
- def miniGapDo(gapToGapValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
130
+ def miniGapDo(gapToGapValues: tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
112
131
  gapToGapCountDimensionsGapped, gapToGapPotentialGaps, activeGapNumber, index = gapToGapValues
113
132
  gapToGapPotentialGaps = gapToGapPotentialGaps.at[activeGapNumber].set(gapToGapPotentialGaps.at[index].get())
114
133
  activeGapNumber = jax.numpy.where(jax.numpy.equal(gapToGapCountDimensionsGapped.at[gapToGapPotentialGaps.at[index].get()].get(), dimensionsTotal - unconstrainedLeaf), activeGapNumber + 1, activeGapNumber).astype(jax.numpy.uint32)
@@ -144,17 +163,17 @@ def foldingsJAX(leavesTotal: jaxtyping.UInt32, dimensionsTotal: jaxtyping.UInt32
144
163
  def incrementCondition(leafBelowSentinel, activeLeafNumber):
145
164
  return jax.numpy.logical_and(activeLeafNumber > leavesTotal, leafBelowSentinel == 1)
146
165
 
147
- def incrementDo(allValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32, jaxtyping.UInt32]):
166
+ def incrementDo(allValues: tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32, jaxtyping.UInt32]):
148
167
  foldingsSubTotal = allValues[5]
149
168
  foldingsSubTotal = leavesTotal + foldingsSubTotal
150
169
  return (allValues[0], allValues[1], allValues[2], allValues[3], allValues[4], foldingsSubTotal, allValues[6], allValues[7])
151
170
 
152
- def dao(allValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32, jaxtyping.UInt32]):
153
- def whileBacktrackingCondition(backtrackingValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32]):
171
+ def dao(allValues: tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32, jaxtyping.UInt32]):
172
+ def whileBacktrackingCondition(backtrackingValues: tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32]):
154
173
  comparand = backtrackingValues[2]
155
174
  return jax.numpy.logical_and(comparand > 0, jax.numpy.equal(activeGap1ndex, gapRangeStart.at[comparand - 1].get()))
156
175
 
157
- def whileBacktrackingDo(backtrackingValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32]):
176
+ def whileBacktrackingDo(backtrackingValues: tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32]):
158
177
  backtrackAbove, backtrackBelow, activeLeafNumber = backtrackingValues
159
178
 
160
179
  activeLeafNumber = activeLeafNumber - 1
@@ -166,7 +185,7 @@ def foldingsJAX(leavesTotal: jaxtyping.UInt32, dimensionsTotal: jaxtyping.UInt32
166
185
  def if_activeLeaf1ndex_greaterThan_0(activeLeafNumber):
167
186
  return activeLeafNumber > 0
168
187
 
169
- def if_activeLeaf1ndex_greaterThan_0_do(leafPlacementValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
188
+ def if_activeLeaf1ndex_greaterThan_0_do(leafPlacementValues: tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
170
189
  placeLeafAbove, placeLeafBelow, placeGapRangeStart, activeLeafNumber, activeGapNumber = leafPlacementValues
171
190
  activeGapNumber = activeGapNumber - 1
172
191
  placeLeafAbove = placeLeafAbove.at[activeLeafNumber].set(gapsWhere.at[activeGapNumber].get())