mapFolding 0.2.0__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 (33) hide show
  1. mapfolding-0.2.0/PKG-INFO +170 -0
  2. mapfolding-0.2.0/README.md +145 -0
  3. mapfolding-0.2.0/mapFolding/JAX/lunnanJAX.py +206 -0
  4. mapfolding-0.2.0/mapFolding/JAX/taskJAX.py +313 -0
  5. mapfolding-0.2.0/mapFolding/__init__.py +21 -0
  6. mapfolding-0.2.0/mapFolding/babbage.py +12 -0
  7. mapfolding-0.2.0/mapFolding/beDRY.py +219 -0
  8. mapfolding-0.2.0/mapFolding/benchmarks/benchmarking.py +66 -0
  9. mapfolding-0.2.0/mapFolding/benchmarks/test_benchmarks.py +74 -0
  10. mapfolding-0.2.0/mapFolding/importPackages.py +5 -0
  11. mapfolding-0.2.0/mapFolding/lovelace.py +121 -0
  12. mapfolding-0.2.0/mapFolding/oeis.py +299 -0
  13. mapfolding-0.2.0/mapFolding/reference/hunterNumba.py +132 -0
  14. mapfolding-0.2.0/mapFolding/reference/irvineJavaPort.py +120 -0
  15. mapfolding-0.2.0/mapFolding/reference/lunnan.py +153 -0
  16. mapfolding-0.2.0/mapFolding/reference/lunnanNumpy.py +123 -0
  17. mapfolding-0.2.0/mapFolding/reference/lunnanWhile.py +121 -0
  18. mapfolding-0.2.0/mapFolding/reference/rotatedEntryPoint.py +240 -0
  19. mapfolding-0.2.0/mapFolding/startHere.py +54 -0
  20. mapfolding-0.2.0/mapFolding/theSSOT.py +62 -0
  21. mapfolding-0.2.0/mapFolding.egg-info/PKG-INFO +170 -0
  22. mapfolding-0.2.0/mapFolding.egg-info/SOURCES.txt +31 -0
  23. mapfolding-0.2.0/mapFolding.egg-info/dependency_links.txt +1 -0
  24. mapfolding-0.2.0/mapFolding.egg-info/entry_points.txt +4 -0
  25. mapfolding-0.2.0/mapFolding.egg-info/requires.txt +19 -0
  26. mapfolding-0.2.0/mapFolding.egg-info/top_level.txt +3 -0
  27. mapfolding-0.2.0/pyproject.toml +46 -0
  28. mapfolding-0.2.0/setup.cfg +4 -0
  29. mapfolding-0.2.0/tests/__init__.py +1 -0
  30. mapfolding-0.2.0/tests/conftest.py +262 -0
  31. mapfolding-0.2.0/tests/test_oeis.py +195 -0
  32. mapfolding-0.2.0/tests/test_other.py +71 -0
  33. mapfolding-0.2.0/tests/test_tasks.py +18 -0
@@ -0,0 +1,170 @@
1
+ Metadata-Version: 2.2
2
+ Name: mapFolding
3
+ Version: 0.2.0
4
+ Summary: Algorithm(s) for counting distinct ways to fold a map (or a strip of stamps)
5
+ Author-email: Hunter Hogan <HunterHogan@pm.me>
6
+ Project-URL: homepage, https://github.com/hunterhogan/mapFolding
7
+ Requires-Python: <3.13,>=3.10
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: numba
10
+ Requires-Dist: numpy
11
+ Requires-Dist: Z0Z-tools
12
+ Provides-Extra: benchmark
13
+ Requires-Dist: pandas; extra == "benchmark"
14
+ Requires-Dist: jupyter; extra == "benchmark"
15
+ Requires-Dist: ipywidgets; extra == "benchmark"
16
+ Requires-Dist: tqdm; extra == "benchmark"
17
+ Provides-Extra: jax
18
+ Requires-Dist: jax; extra == "jax"
19
+ Requires-Dist: jaxtyping; extra == "jax"
20
+ Provides-Extra: testing
21
+ Requires-Dist: pytest; extra == "testing"
22
+ Requires-Dist: pytest-cov; extra == "testing"
23
+ Requires-Dist: pytest-env; extra == "testing"
24
+ Requires-Dist: pytest-xdist; extra == "testing"
25
+
26
+ # Algorithm(s) for counting distinct ways to fold a map (or a strip of stamps)
27
+
28
+ `mapFolding.countFolds()` will accept arbitrary values for the map's dimensions.
29
+
30
+ ```python
31
+ from mapFolding import countFolds
32
+ foldsTotal = countFolds( [2,10] )
33
+ ```
34
+
35
+ The directory `mapFolding/reference` has
36
+
37
+ - a verbatim transcription of the "procedure" published in _The Computer Journal_,
38
+ - multiple referential versions of the procedure with explanatory comments including
39
+ - `hunterNumba.py` a one-size-fits-all, self-contained, reasonably fast, contemporary algorithm that is nevertheless infected by _noobaceae ignorancium_, and
40
+ - miscellaneous notes.
41
+
42
+ [![Python Tests](https://github.com/hunterhogan/mapFolding/actions/workflows/unittests.yml/badge.svg)](https://github.com/hunterhogan/mapFolding/actions/workflows/unittests.yml)
43
+
44
+ ## Simple, easy usage based on OEIS IDs
45
+
46
+ `mapFolding` directly implements some IDs from _The On-Line Encyclopedia of Integer Sequences_.
47
+
48
+ ### Usage: command line
49
+
50
+ After installing (see below), `OEIS_for_n` will run a computation from the command line.
51
+
52
+ ```cmd
53
+ (mapFolding) C:\apps\mapFolding> OEIS_for_n A001418 5
54
+ 186086600 distinct folding patterns.
55
+ Time elapsed: 1.605 seconds
56
+ ```
57
+
58
+ Use `getOEISids` to get the most up-to-date list of available OEIS IDs.
59
+
60
+ ```cmd
61
+ (mapFolding) C:\apps\mapFolding> getOEISids
62
+
63
+ Available OEIS sequences:
64
+ A001415: Number of ways of folding a 2 X n strip of stamps.
65
+ A001416: Number of ways of folding a 3 X n strip of stamps.
66
+ A001417: Number of ways of folding a 2 X 2 X ... X 2 n-dimensional map.
67
+ A001418: Number of ways of folding an n X n sheet of stamps.
68
+ A195646: Number of ways of folding a 3 X 3 X ... X 3 n-dimensional map.
69
+
70
+ Usage examples:
71
+ Command line:
72
+ OEIS_for_n A001415 8
73
+ Python:
74
+ from mapFolding import oeisIDfor_n
75
+ foldsTotal = oeisIDfor_n('A001415', 8)
76
+ ```
77
+
78
+ ### Usage: Python module or REPL
79
+
80
+ Use `mapFolding.oeisIDfor_n()` to compute a(n) for an OEIS ID.
81
+
82
+ ```python
83
+ from mapFolding import oeisIDfor_n
84
+ foldsTotal = oeisIDfor_n( 'A001418', 4 )
85
+ ```
86
+
87
+ ### An "advanced" and likely unnecessary feature: clear `mapFolding`'s cache of OEIS data
88
+
89
+ Clear _The On-Line Encyclopedia of Integer Sequences_ data from the `mapFolding` cache:
90
+
91
+ ```sh
92
+ (mapFolding) C:\apps\mapFolding> clearOEIScache
93
+ Cache cleared from C:\apps\mapFolding\mapFolding\.cache
94
+ ```
95
+
96
+ ## Connections to "Multi-dimensional map-folding" by W. F. Lunnon
97
+
98
+ ### The typo-laden algorithm published in 1971
99
+
100
+ The full paper, W. F. Lunnon, Multi-dimensional map-folding, _The Computer Journal_, Volume 14, Issue 1, 1971, Pages 75–80, [https://doi.org/10.1093/comjnl/14.1.75](https://doi.org/10.1093/comjnl/14.1.75) ([BibTex](mapFolding/citations/Lunnon.bibtex) citation) is available at the DOI link. (As of 3 January 2025, the paper is a PDF of images, not text, and can be accessed without cost or login.)
101
+
102
+ In [`foldings.txt`](mapFolding/reference/foldings.txt), you can find a text transcription of the algorithm as it was printed in 1971. In [`foldings.AA`](mapFolding/reference/foldings.AA), I have corrected obvious transcription errors, documented with comments, and I have reformatted line breaks and indentation. For contemporary readers, the result is likely easier to read than the text transcription or the original paper are easy to read. This is especially true if you view the document with semantic highlighting, such as with [Algol 60 syntax highlighter](https://github.com/PolariTOON/language-algol60).
103
+
104
+ ### Java implementation(s) and improvements
105
+
106
+ [archmageirvine](https://github.com/archmageirvine/joeis/blob/80e3e844b11f149704acbab520bc3a3a25ac34ff/src/irvine/oeis/a001/A001415.java) ([BibTex](mapFolding/citations/jOEIS.bibtex) citation) says about the Java code:
107
+
108
+ ```java
109
+ /**
110
+ * A001415 Number of ways of folding a 2 X n strip of stamps.
111
+ * @author Fred Lunnon (ALGOL68, C versions)
112
+ * @author Sean A. Irvine (Java port)
113
+ */
114
+ ...
115
+ // Implements algorithm as described in "Multi-dimensional map-folding",
116
+ // by W. F. Lunnon, The Computer J, 14, 1, pp. 75--80. Note the original
117
+ // paper contains a few omissions, so this actual code is based on a C
118
+ // implementation by Fred Lunnon.
119
+ ```
120
+
121
+ ## Map-folding Video
122
+
123
+ ~~This caused my neurosis:~~ I enjoyed the following video, which is what introduced me to map folding.
124
+
125
+ "How Many Ways Can You Fold a Map?" by Physics for the Birds, 2024 November 13 ([BibTex](mapFolding/citations/Physics_for_the_Birds.bibtex) citation)
126
+
127
+ [![How Many Ways Can You Fold a Map?](https://i.ytimg.com/vi/sfH9uIY3ln4/hq720.jpg)](https://www.youtube.com/watch?v=sfH9uIY3ln4)
128
+
129
+ ## Install this package
130
+
131
+ ### From Github
132
+
133
+ ```sh
134
+ pip install mapFolding@git+https://github.com/hunterhogan/mapFolding.git
135
+ ```
136
+
137
+ ### From a local directory
138
+
139
+ #### Windows
140
+
141
+ ```powershell
142
+ git clone https://github.com/hunterhogan/mapFolding.git \path\to\mapFolding
143
+ pip install mapFolding@file:\path\to\mapFolding
144
+ ```
145
+
146
+ #### POSIX
147
+
148
+ ```bash
149
+ git clone https://github.com/hunterhogan/mapFolding.git /path/to/mapFolding
150
+ pip install mapFolding@file:/path/to/mapFolding
151
+ ```
152
+
153
+ ## Install updates
154
+
155
+ ```sh
156
+ pip install --upgrade mapFolding@git+https://github.com/hunterhogan/mapFolding.git
157
+ ```
158
+
159
+ ## Creating a virtual environment before installation
160
+
161
+ You can isolate `mapFolding` in a virtual environment. For example, use the following commands to create a directory for the virtual environment, activate the virtual environment, and install the package. In the future, you will likely need to activate the virtual environment before using `mapFolding` again. From the command line, in a directory you want to install in.
162
+
163
+ ```sh
164
+ py -m venv mapFolding
165
+ cd mapFolding
166
+ cd Scripts
167
+ activate
168
+ cd ..
169
+ pip install mapFolding@git+https://github.com/hunterhogan/mapFolding.git
170
+ ```
@@ -0,0 +1,145 @@
1
+ # Algorithm(s) for counting distinct ways to fold a map (or a strip of stamps)
2
+
3
+ `mapFolding.countFolds()` will accept arbitrary values for the map's dimensions.
4
+
5
+ ```python
6
+ from mapFolding import countFolds
7
+ foldsTotal = countFolds( [2,10] )
8
+ ```
9
+
10
+ The directory `mapFolding/reference` has
11
+
12
+ - a verbatim transcription of the "procedure" published in _The Computer Journal_,
13
+ - multiple referential versions of the procedure with explanatory comments including
14
+ - `hunterNumba.py` a one-size-fits-all, self-contained, reasonably fast, contemporary algorithm that is nevertheless infected by _noobaceae ignorancium_, and
15
+ - miscellaneous notes.
16
+
17
+ [![Python Tests](https://github.com/hunterhogan/mapFolding/actions/workflows/unittests.yml/badge.svg)](https://github.com/hunterhogan/mapFolding/actions/workflows/unittests.yml)
18
+
19
+ ## Simple, easy usage based on OEIS IDs
20
+
21
+ `mapFolding` directly implements some IDs from _The On-Line Encyclopedia of Integer Sequences_.
22
+
23
+ ### Usage: command line
24
+
25
+ After installing (see below), `OEIS_for_n` will run a computation from the command line.
26
+
27
+ ```cmd
28
+ (mapFolding) C:\apps\mapFolding> OEIS_for_n A001418 5
29
+ 186086600 distinct folding patterns.
30
+ Time elapsed: 1.605 seconds
31
+ ```
32
+
33
+ Use `getOEISids` to get the most up-to-date list of available OEIS IDs.
34
+
35
+ ```cmd
36
+ (mapFolding) C:\apps\mapFolding> getOEISids
37
+
38
+ Available OEIS sequences:
39
+ A001415: Number of ways of folding a 2 X n strip of stamps.
40
+ A001416: Number of ways of folding a 3 X n strip of stamps.
41
+ A001417: Number of ways of folding a 2 X 2 X ... X 2 n-dimensional map.
42
+ A001418: Number of ways of folding an n X n sheet of stamps.
43
+ A195646: Number of ways of folding a 3 X 3 X ... X 3 n-dimensional map.
44
+
45
+ Usage examples:
46
+ Command line:
47
+ OEIS_for_n A001415 8
48
+ Python:
49
+ from mapFolding import oeisIDfor_n
50
+ foldsTotal = oeisIDfor_n('A001415', 8)
51
+ ```
52
+
53
+ ### Usage: Python module or REPL
54
+
55
+ Use `mapFolding.oeisIDfor_n()` to compute a(n) for an OEIS ID.
56
+
57
+ ```python
58
+ from mapFolding import oeisIDfor_n
59
+ foldsTotal = oeisIDfor_n( 'A001418', 4 )
60
+ ```
61
+
62
+ ### An "advanced" and likely unnecessary feature: clear `mapFolding`'s cache of OEIS data
63
+
64
+ Clear _The On-Line Encyclopedia of Integer Sequences_ data from the `mapFolding` cache:
65
+
66
+ ```sh
67
+ (mapFolding) C:\apps\mapFolding> clearOEIScache
68
+ Cache cleared from C:\apps\mapFolding\mapFolding\.cache
69
+ ```
70
+
71
+ ## Connections to "Multi-dimensional map-folding" by W. F. Lunnon
72
+
73
+ ### The typo-laden algorithm published in 1971
74
+
75
+ The full paper, W. F. Lunnon, Multi-dimensional map-folding, _The Computer Journal_, Volume 14, Issue 1, 1971, Pages 75–80, [https://doi.org/10.1093/comjnl/14.1.75](https://doi.org/10.1093/comjnl/14.1.75) ([BibTex](mapFolding/citations/Lunnon.bibtex) citation) is available at the DOI link. (As of 3 January 2025, the paper is a PDF of images, not text, and can be accessed without cost or login.)
76
+
77
+ In [`foldings.txt`](mapFolding/reference/foldings.txt), you can find a text transcription of the algorithm as it was printed in 1971. In [`foldings.AA`](mapFolding/reference/foldings.AA), I have corrected obvious transcription errors, documented with comments, and I have reformatted line breaks and indentation. For contemporary readers, the result is likely easier to read than the text transcription or the original paper are easy to read. This is especially true if you view the document with semantic highlighting, such as with [Algol 60 syntax highlighter](https://github.com/PolariTOON/language-algol60).
78
+
79
+ ### Java implementation(s) and improvements
80
+
81
+ [archmageirvine](https://github.com/archmageirvine/joeis/blob/80e3e844b11f149704acbab520bc3a3a25ac34ff/src/irvine/oeis/a001/A001415.java) ([BibTex](mapFolding/citations/jOEIS.bibtex) citation) says about the Java code:
82
+
83
+ ```java
84
+ /**
85
+ * A001415 Number of ways of folding a 2 X n strip of stamps.
86
+ * @author Fred Lunnon (ALGOL68, C versions)
87
+ * @author Sean A. Irvine (Java port)
88
+ */
89
+ ...
90
+ // Implements algorithm as described in "Multi-dimensional map-folding",
91
+ // by W. F. Lunnon, The Computer J, 14, 1, pp. 75--80. Note the original
92
+ // paper contains a few omissions, so this actual code is based on a C
93
+ // implementation by Fred Lunnon.
94
+ ```
95
+
96
+ ## Map-folding Video
97
+
98
+ ~~This caused my neurosis:~~ I enjoyed the following video, which is what introduced me to map folding.
99
+
100
+ "How Many Ways Can You Fold a Map?" by Physics for the Birds, 2024 November 13 ([BibTex](mapFolding/citations/Physics_for_the_Birds.bibtex) citation)
101
+
102
+ [![How Many Ways Can You Fold a Map?](https://i.ytimg.com/vi/sfH9uIY3ln4/hq720.jpg)](https://www.youtube.com/watch?v=sfH9uIY3ln4)
103
+
104
+ ## Install this package
105
+
106
+ ### From Github
107
+
108
+ ```sh
109
+ pip install mapFolding@git+https://github.com/hunterhogan/mapFolding.git
110
+ ```
111
+
112
+ ### From a local directory
113
+
114
+ #### Windows
115
+
116
+ ```powershell
117
+ git clone https://github.com/hunterhogan/mapFolding.git \path\to\mapFolding
118
+ pip install mapFolding@file:\path\to\mapFolding
119
+ ```
120
+
121
+ #### POSIX
122
+
123
+ ```bash
124
+ git clone https://github.com/hunterhogan/mapFolding.git /path/to/mapFolding
125
+ pip install mapFolding@file:/path/to/mapFolding
126
+ ```
127
+
128
+ ## Install updates
129
+
130
+ ```sh
131
+ pip install --upgrade mapFolding@git+https://github.com/hunterhogan/mapFolding.git
132
+ ```
133
+
134
+ ## Creating a virtual environment before installation
135
+
136
+ You can isolate `mapFolding` in a virtual environment. For example, use the following commands to create a directory for the virtual environment, activate the virtual environment, and install the package. In the future, you will likely need to activate the virtual environment before using `mapFolding` again. From the command line, in a directory you want to install in.
137
+
138
+ ```sh
139
+ py -m venv mapFolding
140
+ cd mapFolding
141
+ cd Scripts
142
+ activate
143
+ cd ..
144
+ pip install mapFolding@git+https://github.com/hunterhogan/mapFolding.git
145
+ ```
@@ -0,0 +1,206 @@
1
+ from mapFolding import validateListDimensions, getLeavesTotal, makeConnectionGraph
2
+ from typing import List, Tuple
3
+ import jax
4
+ import jaxtyping
5
+
6
+ dtypeDefault = jax.numpy.uint32
7
+ dtypeMaximum = jax.numpy.uint32
8
+
9
+ def countFolds(listDimensions: List[int]) -> int:
10
+ listDimensionsPositive: List[int] = validateListDimensions(listDimensions)
11
+
12
+ n: int = getLeavesTotal(listDimensionsPositive)
13
+ d: int = len(listDimensions)
14
+ import numpy
15
+ D: numpy.ndarray = makeConnectionGraph(listDimensionsPositive)
16
+ connectionGraph = jax.numpy.asarray(D, dtype=dtypeDefault)
17
+ del listDimensionsPositive
18
+
19
+ return foldingsJAX(n, d, connectionGraph)
20
+
21
+ def foldingsJAX(leavesTotal: jaxtyping.UInt32, dimensionsTotal: jaxtyping.UInt32, connectionGraph: jaxtyping.Array) -> jaxtyping.UInt32:
22
+
23
+ def doNothing(argument):
24
+ return argument
25
+
26
+ def while_activeLeaf1ndex_greaterThan_0(comparisonValues: Tuple):
27
+ comparand = comparisonValues[6]
28
+ return comparand > 0
29
+
30
+ def countFoldings(allValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32, jaxtyping.UInt32]):
31
+ _0, leafBelow, _2, _3, _4, _5, activeLeaf1ndex, _7 = allValues
32
+
33
+ sentinel = leafBelow.at[0].get().astype(jax.numpy.uint32)
34
+
35
+ allValues = jax.lax.cond(findGapsCondition(sentinel, activeLeaf1ndex),
36
+ lambda argumentX: dao(findGapsDo(argumentX)),
37
+ lambda argumentY: jax.lax.cond(incrementCondition(sentinel, activeLeaf1ndex), lambda argumentZ: dao(incrementDo(argumentZ)), dao, argumentY),
38
+ allValues)
39
+
40
+ return allValues
41
+
42
+ def findGapsCondition(leafBelowSentinel, activeLeafNumber):
43
+ return jax.numpy.logical_or(jax.numpy.logical_and(leafBelowSentinel == 1, activeLeafNumber <= leavesTotal), activeLeafNumber <= 1)
44
+
45
+ def findGapsDo(allValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32, jaxtyping.UInt32]):
46
+ def for_dimension1ndex_in_range_1_to_dimensionsTotalPlus1(comparisonValues: Tuple):
47
+ return comparisonValues[-1] <= dimensionsTotal
48
+
49
+ 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]):
50
+ def ifLeafIsUnconstrainedCondition(comparand):
51
+ return jax.numpy.equal(connectionGraph[comparand, activeLeaf1ndex, activeLeaf1ndex], activeLeaf1ndex)
52
+
53
+ def ifLeafIsUnconstrainedDo(unconstrainedValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
54
+ unconstrained_unconstrainedLeaf = unconstrainedValues[3]
55
+ unconstrained_unconstrainedLeaf = 1 + unconstrained_unconstrainedLeaf
56
+ return (unconstrainedValues[0], unconstrainedValues[1], unconstrainedValues[2], unconstrained_unconstrainedLeaf)
57
+
58
+ def ifLeafIsUnconstrainedElse(unconstrainedValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
59
+ def while_leaf1ndexConnectee_notEquals_activeLeaf1ndex(comparisonValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
60
+ return comparisonValues[-1] != activeLeaf1ndex
61
+
62
+ def countGaps(countGapsDoValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
63
+ countGapsCountDimensionsGapped, countGapsPotentialGaps, countGapsGap1ndexLowerBound, countGapsLeaf1ndexConnectee = countGapsDoValues
64
+
65
+ countGapsPotentialGaps = countGapsPotentialGaps.at[countGapsGap1ndexLowerBound].set(countGapsLeaf1ndexConnectee)
66
+ countGapsGap1ndexLowerBound = jax.numpy.where(jax.numpy.equal(countGapsCountDimensionsGapped[countGapsLeaf1ndexConnectee], 0), countGapsGap1ndexLowerBound + 1, countGapsGap1ndexLowerBound)
67
+ countGapsCountDimensionsGapped = countGapsCountDimensionsGapped.at[countGapsLeaf1ndexConnectee].add(1)
68
+ countGapsLeaf1ndexConnectee = connectionGraph.at[dimensionNumber, activeLeaf1ndex, leafBelow.at[countGapsLeaf1ndexConnectee].get()].get().astype(jax.numpy.uint32)
69
+
70
+ return (countGapsCountDimensionsGapped, countGapsPotentialGaps, countGapsGap1ndexLowerBound, countGapsLeaf1ndexConnectee)
71
+
72
+ unconstrained_countDimensionsGapped, unconstrained_gapsWhere, unconstrained_gap1ndexCeiling, unconstrained_unconstrainedLeaf = unconstrainedValues
73
+
74
+ leaf1ndexConnectee = connectionGraph.at[dimensionNumber, activeLeaf1ndex, activeLeaf1ndex].get().astype(jax.numpy.uint32)
75
+
76
+ countGapsValues = (unconstrained_countDimensionsGapped, unconstrained_gapsWhere, unconstrained_gap1ndexCeiling, leaf1ndexConnectee)
77
+ countGapsValues = jax.lax.while_loop(while_leaf1ndexConnectee_notEquals_activeLeaf1ndex, countGaps, countGapsValues)
78
+ unconstrained_countDimensionsGapped, unconstrained_gapsWhere, unconstrained_gap1ndexCeiling, leaf1ndexConnectee = countGapsValues
79
+
80
+ return (unconstrained_countDimensionsGapped, unconstrained_gapsWhere, unconstrained_gap1ndexCeiling, unconstrained_unconstrainedLeaf)
81
+
82
+ dimensions_countDimensionsGapped, dimensions_gapsWhere, dimensions_gap1ndexCeiling, dimensions_unconstrainedLeaf, dimensionNumber = for_dimension1ndex_in_range_1_to_dimensionsTotalPlus1Values
83
+
84
+ ifLeafIsUnconstrainedValues = (dimensions_countDimensionsGapped, dimensions_gapsWhere, dimensions_gap1ndexCeiling, dimensions_unconstrainedLeaf)
85
+ ifLeafIsUnconstrainedValues = jax.lax.cond(ifLeafIsUnconstrainedCondition(dimensionNumber), ifLeafIsUnconstrainedDo, ifLeafIsUnconstrainedElse, ifLeafIsUnconstrainedValues)
86
+ dimensions_countDimensionsGapped, dimensions_gapsWhere, dimensions_gap1ndexCeiling, dimensions_unconstrainedLeaf = ifLeafIsUnconstrainedValues
87
+
88
+ dimensionNumber = 1 + dimensionNumber
89
+ return (dimensions_countDimensionsGapped, dimensions_gapsWhere, dimensions_gap1ndexCeiling, dimensions_unconstrainedLeaf, dimensionNumber)
90
+
91
+ def almostUselessCondition(comparand):
92
+ return comparand == dimensionsTotal
93
+
94
+ def almostUselessConditionDo(for_leaf1ndex_in_range_activeLeaf1ndexValues: Tuple[jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
95
+ def for_leaf1ndex_in_range_activeLeaf1ndex(comparisonValues):
96
+ return comparisonValues[-1] < activeLeaf1ndex
97
+
98
+ def for_leaf1ndex_in_range_activeLeaf1ndex_do(for_leaf1ndex_in_range_activeLeaf1ndexValues: Tuple[jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
99
+ leafInRangePotentialGaps, gapNumberLowerBound, leafNumber = for_leaf1ndex_in_range_activeLeaf1ndexValues
100
+ leafInRangePotentialGaps = leafInRangePotentialGaps.at[gapNumberLowerBound].set(leafNumber)
101
+ gapNumberLowerBound = 1 + gapNumberLowerBound
102
+ leafNumber = 1 + leafNumber
103
+ return (leafInRangePotentialGaps, gapNumberLowerBound, leafNumber)
104
+ return jax.lax.while_loop(for_leaf1ndex_in_range_activeLeaf1ndex, for_leaf1ndex_in_range_activeLeaf1ndex_do, for_leaf1ndex_in_range_activeLeaf1ndexValues)
105
+
106
+ def for_range_from_activeGap1ndex_to_gap1ndexCeiling(comparisonValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
107
+ return comparisonValues[-1] < gap1ndexCeiling
108
+
109
+ def miniGapDo(gapToGapValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
110
+ gapToGapCountDimensionsGapped, gapToGapPotentialGaps, activeGapNumber, index = gapToGapValues
111
+ gapToGapPotentialGaps = gapToGapPotentialGaps.at[activeGapNumber].set(gapToGapPotentialGaps.at[index].get())
112
+ activeGapNumber = jax.numpy.where(jax.numpy.equal(gapToGapCountDimensionsGapped.at[gapToGapPotentialGaps.at[index].get()].get(), dimensionsTotal - unconstrainedLeaf), activeGapNumber + 1, activeGapNumber).astype(jax.numpy.uint32)
113
+ gapToGapCountDimensionsGapped = gapToGapCountDimensionsGapped.at[gapToGapPotentialGaps.at[index].get()].set(0)
114
+ index = 1 + index
115
+ return (gapToGapCountDimensionsGapped, gapToGapPotentialGaps, activeGapNumber, index)
116
+
117
+ _0, leafBelow, countDimensionsGapped, gapRangeStart, gapsWhere, _5, activeLeaf1ndex, activeGap1ndex = allValues
118
+
119
+ unconstrainedLeaf = jax.numpy.uint32(0)
120
+ dimension1ndex = jax.numpy.uint32(1)
121
+ gap1ndexCeiling = gapRangeStart.at[activeLeaf1ndex - 1].get().astype(jax.numpy.uint32)
122
+ activeGap1ndex = gap1ndexCeiling
123
+ for_dimension1ndex_in_range_1_to_dimensionsTotalPlus1Values = (countDimensionsGapped, gapsWhere, gap1ndexCeiling, unconstrainedLeaf, dimension1ndex)
124
+ for_dimension1ndex_in_range_1_to_dimensionsTotalPlus1Values = jax.lax.while_loop(for_dimension1ndex_in_range_1_to_dimensionsTotalPlus1, for_dimension1ndex_in_range_1_to_dimensionsTotalPlus1_do, for_dimension1ndex_in_range_1_to_dimensionsTotalPlus1Values)
125
+ countDimensionsGapped, gapsWhere, gap1ndexCeiling, unconstrainedLeaf, dimension1ndex = for_dimension1ndex_in_range_1_to_dimensionsTotalPlus1Values
126
+ del dimension1ndex
127
+
128
+ leaf1ndex = jax.numpy.uint32(0)
129
+ for_leaf1ndex_in_range_activeLeaf1ndexValues = (gapsWhere, gap1ndexCeiling, leaf1ndex)
130
+ for_leaf1ndex_in_range_activeLeaf1ndexValues = jax.lax.cond(almostUselessCondition(unconstrainedLeaf), almostUselessConditionDo, doNothing, for_leaf1ndex_in_range_activeLeaf1ndexValues)
131
+ gapsWhere, gap1ndexCeiling, leaf1ndex = for_leaf1ndex_in_range_activeLeaf1ndexValues
132
+ del leaf1ndex
133
+
134
+ indexMiniGap = activeGap1ndex
135
+ miniGapValues = (countDimensionsGapped, gapsWhere, activeGap1ndex, indexMiniGap)
136
+ miniGapValues = jax.lax.while_loop(for_range_from_activeGap1ndex_to_gap1ndexCeiling, miniGapDo, miniGapValues)
137
+ countDimensionsGapped, gapsWhere, activeGap1ndex, indexMiniGap = miniGapValues
138
+ del indexMiniGap
139
+
140
+ return (allValues[0], leafBelow, countDimensionsGapped, gapRangeStart, gapsWhere, allValues[5], activeLeaf1ndex, activeGap1ndex)
141
+
142
+ def incrementCondition(leafBelowSentinel, activeLeafNumber):
143
+ return jax.numpy.logical_and(activeLeafNumber > leavesTotal, leafBelowSentinel == 1)
144
+
145
+ def incrementDo(allValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32, jaxtyping.UInt32]):
146
+ foldingsSubTotal = allValues[5]
147
+ foldingsSubTotal = leavesTotal + foldingsSubTotal
148
+ return (allValues[0], allValues[1], allValues[2], allValues[3], allValues[4], foldingsSubTotal, allValues[6], allValues[7])
149
+
150
+ def dao(allValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32, jaxtyping.UInt32]):
151
+ def whileBacktrackingCondition(backtrackingValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32]):
152
+ comparand = backtrackingValues[2]
153
+ return jax.numpy.logical_and(comparand > 0, jax.numpy.equal(activeGap1ndex, gapRangeStart.at[comparand - 1].get()))
154
+
155
+ def whileBacktrackingDo(backtrackingValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32]):
156
+ backtrackAbove, backtrackBelow, activeLeafNumber = backtrackingValues
157
+
158
+ activeLeafNumber = activeLeafNumber - 1
159
+ backtrackBelow = backtrackBelow.at[backtrackAbove.at[activeLeafNumber].get()].set(backtrackBelow.at[activeLeafNumber].get())
160
+ backtrackAbove = backtrackAbove.at[backtrackBelow.at[activeLeafNumber].get()].set(backtrackAbove.at[activeLeafNumber].get())
161
+
162
+ return (backtrackAbove, backtrackBelow, activeLeafNumber)
163
+
164
+ def if_activeLeaf1ndex_greaterThan_0(activeLeafNumber):
165
+ return activeLeafNumber > 0
166
+
167
+ def if_activeLeaf1ndex_greaterThan_0_do(leafPlacementValues: Tuple[jaxtyping.Array, jaxtyping.Array, jaxtyping.Array, jaxtyping.UInt32, jaxtyping.UInt32]):
168
+ placeLeafAbove, placeLeafBelow, placeGapRangeStart, activeLeafNumber, activeGapNumber = leafPlacementValues
169
+ activeGapNumber = activeGapNumber - 1
170
+ placeLeafAbove = placeLeafAbove.at[activeLeafNumber].set(gapsWhere.at[activeGapNumber].get())
171
+ placeLeafBelow = placeLeafBelow.at[activeLeafNumber].set(placeLeafBelow.at[placeLeafAbove.at[activeLeafNumber].get()].get())
172
+ placeLeafBelow = placeLeafBelow.at[placeLeafAbove.at[activeLeafNumber].get()].set(activeLeafNumber)
173
+ placeLeafAbove = placeLeafAbove.at[placeLeafBelow.at[activeLeafNumber].get()].set(activeLeafNumber)
174
+ placeGapRangeStart = placeGapRangeStart.at[activeLeafNumber].set(activeGapNumber)
175
+
176
+ activeLeafNumber = 1 + activeLeafNumber
177
+ return (placeLeafAbove, placeLeafBelow, placeGapRangeStart, activeLeafNumber, activeGapNumber)
178
+
179
+ leafAbove, leafBelow, _2, gapRangeStart, gapsWhere, _5, activeLeaf1ndex, activeGap1ndex = allValues
180
+
181
+ whileBacktrackingValues = (leafAbove, leafBelow, activeLeaf1ndex)
182
+ whileBacktrackingValues = jax.lax.while_loop(whileBacktrackingCondition, whileBacktrackingDo, whileBacktrackingValues)
183
+ leafAbove, leafBelow, activeLeaf1ndex = whileBacktrackingValues
184
+
185
+ if_activeLeaf1ndex_greaterThan_0_values = (leafAbove, leafBelow, gapRangeStart, activeLeaf1ndex, activeGap1ndex)
186
+ if_activeLeaf1ndex_greaterThan_0_values = jax.lax.cond(if_activeLeaf1ndex_greaterThan_0(activeLeaf1ndex), if_activeLeaf1ndex_greaterThan_0_do, doNothing, if_activeLeaf1ndex_greaterThan_0_values)
187
+ leafAbove, leafBelow, gapRangeStart, activeLeaf1ndex, activeGap1ndex = if_activeLeaf1ndex_greaterThan_0_values
188
+
189
+ return (leafAbove, leafBelow, allValues[2], gapRangeStart, gapsWhere, allValues[5], activeLeaf1ndex, activeGap1ndex)
190
+
191
+ # Dynamic values
192
+ A = jax.numpy.zeros(leavesTotal + 1, dtype=dtypeDefault)
193
+ B = jax.numpy.zeros(leavesTotal + 1, dtype=dtypeDefault)
194
+ count = jax.numpy.zeros(leavesTotal + 1, dtype=dtypeDefault)
195
+ gapter = jax.numpy.zeros(leavesTotal + 1, dtype=dtypeDefault)
196
+ gap = jax.numpy.zeros(leavesTotal * leavesTotal + 1, dtype=dtypeMaximum)
197
+
198
+ foldingsTotal = jax.numpy.uint32(0)
199
+ l = jax.numpy.uint32(1)
200
+ g = jax.numpy.uint32(0)
201
+
202
+ foldingsValues = (A, B, count, gapter, gap, foldingsTotal, l, g)
203
+ foldingsValues = jax.lax.while_loop(while_activeLeaf1ndex_greaterThan_0, countFoldings, foldingsValues)
204
+ return foldingsValues[5]
205
+
206
+ foldingsJAX = jax.jit(foldingsJAX, static_argnums=(0, 1))