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.
- mapfolding-0.2.0/PKG-INFO +170 -0
- mapfolding-0.2.0/README.md +145 -0
- mapfolding-0.2.0/mapFolding/JAX/lunnanJAX.py +206 -0
- mapfolding-0.2.0/mapFolding/JAX/taskJAX.py +313 -0
- mapfolding-0.2.0/mapFolding/__init__.py +21 -0
- mapfolding-0.2.0/mapFolding/babbage.py +12 -0
- mapfolding-0.2.0/mapFolding/beDRY.py +219 -0
- mapfolding-0.2.0/mapFolding/benchmarks/benchmarking.py +66 -0
- mapfolding-0.2.0/mapFolding/benchmarks/test_benchmarks.py +74 -0
- mapfolding-0.2.0/mapFolding/importPackages.py +5 -0
- mapfolding-0.2.0/mapFolding/lovelace.py +121 -0
- mapfolding-0.2.0/mapFolding/oeis.py +299 -0
- mapfolding-0.2.0/mapFolding/reference/hunterNumba.py +132 -0
- mapfolding-0.2.0/mapFolding/reference/irvineJavaPort.py +120 -0
- mapfolding-0.2.0/mapFolding/reference/lunnan.py +153 -0
- mapfolding-0.2.0/mapFolding/reference/lunnanNumpy.py +123 -0
- mapfolding-0.2.0/mapFolding/reference/lunnanWhile.py +121 -0
- mapfolding-0.2.0/mapFolding/reference/rotatedEntryPoint.py +240 -0
- mapfolding-0.2.0/mapFolding/startHere.py +54 -0
- mapfolding-0.2.0/mapFolding/theSSOT.py +62 -0
- mapfolding-0.2.0/mapFolding.egg-info/PKG-INFO +170 -0
- mapfolding-0.2.0/mapFolding.egg-info/SOURCES.txt +31 -0
- mapfolding-0.2.0/mapFolding.egg-info/dependency_links.txt +1 -0
- mapfolding-0.2.0/mapFolding.egg-info/entry_points.txt +4 -0
- mapfolding-0.2.0/mapFolding.egg-info/requires.txt +19 -0
- mapfolding-0.2.0/mapFolding.egg-info/top_level.txt +3 -0
- mapfolding-0.2.0/pyproject.toml +46 -0
- mapfolding-0.2.0/setup.cfg +4 -0
- mapfolding-0.2.0/tests/__init__.py +1 -0
- mapfolding-0.2.0/tests/conftest.py +262 -0
- mapfolding-0.2.0/tests/test_oeis.py +195 -0
- mapfolding-0.2.0/tests/test_other.py +71 -0
- 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
|
+
[](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
|
+
[](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
|
+
[](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
|
+
[](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))
|