mapFolding 0.16.0__py3-none-any.whl → 0.16.2__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.
- easyRun/A000682.py +25 -0
- easyRun/A005316.py +20 -0
- easyRun/NOTcountingFolds.py +36 -0
- easyRun/__init__.py +0 -0
- easyRun/countFolds.py +41 -0
- easyRun/meanders.py +69 -0
- mapFolding/__init__.py +8 -51
- mapFolding/_dataPacking.py +68 -0
- mapFolding/_theSSOT.py +33 -37
- mapFolding/_theTypes.py +21 -4
- mapFolding/algorithms/matrixMeanders.py +86 -517
- mapFolding/algorithms/matrixMeandersBeDry.py +182 -0
- mapFolding/algorithms/matrixMeandersNumPy.py +333 -0
- mapFolding/algorithms/matrixMeandersPandas.py +334 -0
- mapFolding/algorithms/oeisIDbyFormula.py +50 -29
- mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +51 -29
- mapFolding/basecamp.py +167 -206
- mapFolding/beDRY.py +2 -30
- mapFolding/dataBaskets.py +75 -49
- mapFolding/oeis.py +11 -32
- mapFolding/reference/A000682facts.py +787 -652
- mapFolding/reference/A005316facts.py +961 -3
- mapFolding/reference/matrixMeandersAnalysis/prefixNotationNotes.py +15 -0
- mapFolding/reference/matrixMeandersAnalysis/signatures.py +2030 -0
- mapFolding/reference/meandersDumpingGround/A005316JavaPort.py +1 -1
- mapFolding/reference/meandersDumpingGround/A005316imperative.py +1 -1
- mapFolding/reference/meandersDumpingGround/matrixMeandersNumPyV1finalForm.py +424 -0
- mapFolding/someAssemblyRequired/A007822/A007822rawMaterials.py +3 -4
- mapFolding/someAssemblyRequired/A007822/makeA007822AsynchronousModules.py +103 -29
- mapFolding/someAssemblyRequired/A007822/makeA007822Modules.py +18 -14
- mapFolding/someAssemblyRequired/RecipeJob.py +2 -2
- mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +7 -6
- mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +3 -4
- mapFolding/someAssemblyRequired/makingModules_count.py +88 -87
- mapFolding/someAssemblyRequired/makingModules_doTheNeedful.py +10 -9
- mapFolding/someAssemblyRequired/mapFolding/makeMapFoldingModules.py +3 -3
- mapFolding/someAssemblyRequired/meanders/__init__.py +0 -0
- mapFolding/someAssemblyRequired/meanders/makeMeandersModules.py +63 -0
- mapFolding/someAssemblyRequired/toolkitMakeModules.py +37 -37
- mapFolding/someAssemblyRequired/transformationTools.py +8 -8
- mapFolding/syntheticModules/A007822/algorithm.py +3 -3
- mapFolding/syntheticModules/A007822/algorithmNumba.py +1 -2
- mapFolding/syntheticModules/A007822/asynchronous.py +6 -4
- mapFolding/syntheticModules/A007822/asynchronousAnnex.py +5 -7
- mapFolding/syntheticModules/A007822/asynchronousAnnexNumba.py +70 -0
- mapFolding/syntheticModules/A007822/asynchronousNumba.py +79 -0
- mapFolding/syntheticModules/A007822/asynchronousTheorem2.py +15 -3
- mapFolding/syntheticModules/A007822/asynchronousTrimmed.py +12 -3
- mapFolding/syntheticModules/A007822/initializeState.py +1 -2
- mapFolding/syntheticModules/A007822/theorem2.py +7 -2
- mapFolding/syntheticModules/A007822/theorem2Numba.py +31 -4
- mapFolding/syntheticModules/A007822/theorem2Trimmed.py +8 -3
- mapFolding/syntheticModules/countParallelNumba.py +5 -2
- mapFolding/syntheticModules/dataPacking.py +1 -1
- mapFolding/syntheticModules/dataPackingA007822.py +92 -26
- mapFolding/syntheticModules/meanders/__init__.py +1 -0
- mapFolding/syntheticModules/meanders/bigInt.py +52 -0
- mapFolding/syntheticModules/theorem2.py +6 -0
- mapFolding/syntheticModules/theorem2Numba.py +8 -2
- mapFolding/syntheticModules/theorem2Trimmed.py +6 -0
- mapFolding/tests/conftest.py +28 -13
- mapFolding/tests/test_computations.py +68 -61
- mapFolding/tests/test_oeis.py +6 -6
- mapFolding/zCuzDocStoopid/__init__.py +4 -1
- mapFolding/zCuzDocStoopid/makeDocstrings.py +35 -28
- mapfolding-0.16.2.dist-info/METADATA +99 -0
- mapfolding-0.16.2.dist-info/RECORD +115 -0
- {mapfolding-0.16.0.dist-info → mapfolding-0.16.2.dist-info}/top_level.txt +1 -0
- mapFolding/algorithms/getBucketsTotal.py +0 -137
- mapFolding/reference/matrixMeandersAnalysis/evenEven.py +0 -144
- mapFolding/reference/matrixMeandersAnalysis/oddEven.py +0 -54
- mapFolding/trim_memory.py +0 -62
- mapfolding-0.16.0.dist-info/METADATA +0 -85
- mapfolding-0.16.0.dist-info/RECORD +0 -100
- {mapfolding-0.16.0.dist-info → mapfolding-0.16.2.dist-info}/WHEEL +0 -0
- {mapfolding-0.16.0.dist-info → mapfolding-0.16.2.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.16.0.dist-info → mapfolding-0.16.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,519 +1,88 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
Mathematics
|
|
64
|
-
-----------
|
|
65
|
-
Implements the Dyck path balance verification algorithm from Jensen's transfer matrix
|
|
66
|
-
enumeration. Computes the position where ∑(i=0 to k) (-1)^b_i < 0 for the first time,
|
|
67
|
-
where b_i are the bits of the input at positions 2i.
|
|
68
|
-
|
|
69
|
-
"""
|
|
70
|
-
findTheExtra_0b1: int = 0
|
|
71
|
-
flipExtra_0b1_Here: int = 1
|
|
72
|
-
while True:
|
|
73
|
-
flipExtra_0b1_Here <<= 2
|
|
74
|
-
if (intWithExtra_0b1 & flipExtra_0b1_Here) == 0:
|
|
75
|
-
findTheExtra_0b1 += 1
|
|
76
|
-
else:
|
|
77
|
-
findTheExtra_0b1 -= 1
|
|
78
|
-
if findTheExtra_0b1 < 0:
|
|
79
|
-
break
|
|
80
|
-
return flipExtra_0b1_Here
|
|
81
|
-
|
|
82
|
-
def areIntegersWide(state: MatrixMeandersState, dataframe: pandas.DataFrame | None = None, *, fixedSizeMAXIMUMcurveLocations: bool = False) -> bool:
|
|
83
|
-
"""Check if the largest values are wider than the maximum limits.
|
|
84
|
-
|
|
85
|
-
Parameters
|
|
86
|
-
----------
|
|
87
|
-
state : MatrixMeandersState
|
|
88
|
-
The current state of the computation, including `dictionaryCurveLocations`.
|
|
89
|
-
dataframe : pandas.DataFrame | None = None
|
|
90
|
-
Optional DataFrame containing 'analyzed' and 'distinctCrossings' columns. If provided, use this instead of `state.dictionaryCurveLocations`.
|
|
91
|
-
fixedSizeMAXIMUMcurveLocations : bool = False
|
|
92
|
-
Set this to `True` if you cast `state.MAXIMUMcurveLocations` to the same fixed size integer type as `state.datatypeCurveLocations`.
|
|
93
|
-
|
|
94
|
-
Returns
|
|
95
|
-
-------
|
|
96
|
-
wider : bool
|
|
97
|
-
True if at least one integer is too wide.
|
|
98
|
-
|
|
99
|
-
Notes
|
|
100
|
-
-----
|
|
101
|
-
Casting `state.MAXIMUMcurveLocations` to a fixed-size 64-bit unsigned integer might cause the flow to be a little more
|
|
102
|
-
complicated because `MAXIMUMcurveLocations` is usually 1-bit larger than the `max(curveLocations)` value.
|
|
103
|
-
|
|
104
|
-
If you start the algorithm with very large `curveLocations` in your `dictionaryCurveLocations` (*i.e.,* A000682), then the
|
|
105
|
-
flow will go to a function that does not use fixed size integers. When the integers are below the limits (*e.g.,*
|
|
106
|
-
`bitWidthCurveLocationsMaximum`), the flow will go to a function with fixed size integers. In that case, casting
|
|
107
|
-
`MAXIMUMcurveLocations` to a fixed size merely delays the transition from one function to the other by one iteration.
|
|
108
|
-
|
|
109
|
-
If you start with small values in `dictionaryCurveLocations`, however, then the flow goes to the function with fixed size
|
|
110
|
-
integers and usually stays there until `distinctCrossings` is huge, which is near the end of the computation. If you cast
|
|
111
|
-
`MAXIMUMcurveLocations` into a 64-bit unsigned integer, however, then around `state.kOfMatrix == 28`, the bit width of
|
|
112
|
-
`MAXIMUMcurveLocations` might exceed the limit. That will cause the flow to go to the function that does not have fixed size
|
|
113
|
-
integers for a few iterations before returning to the function with fixed size integers.
|
|
114
|
-
"""
|
|
115
|
-
if dataframe is None:
|
|
116
|
-
curveLocationsWidest: int = max(state.dictionaryCurveLocations.keys()).bit_length()
|
|
117
|
-
distinctCrossingsWidest: int = max(state.dictionaryCurveLocations.values()).bit_length()
|
|
118
|
-
else:
|
|
119
|
-
curveLocationsWidest = int(dataframe['analyzed'].max()).bit_length()
|
|
120
|
-
distinctCrossingsWidest = int(dataframe['distinctCrossings'].max()).bit_length()
|
|
121
|
-
|
|
122
|
-
MAXIMUMcurveLocations: int = 0
|
|
123
|
-
if fixedSizeMAXIMUMcurveLocations:
|
|
124
|
-
MAXIMUMcurveLocations = state.MAXIMUMcurveLocations
|
|
125
|
-
|
|
126
|
-
return (curveLocationsWidest > raiseIfNone(state.bitWidthCurveLocationsMaximum)
|
|
127
|
-
or distinctCrossingsWidest > raiseIfNone(state.bitWidthDistinctCrossingsMaximum)
|
|
128
|
-
or MAXIMUMcurveLocations > raiseIfNone(state.bitWidthCurveLocationsMaximum)
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
def countBigInt(state: MatrixMeandersState) -> MatrixMeandersState:
|
|
132
|
-
"""Count meanders with matrix transfer algorithm using Python primitive `int` contained in a Python primitive `dict`.
|
|
133
|
-
|
|
134
|
-
Parameters
|
|
135
|
-
----------
|
|
136
|
-
state : MatrixMeandersState
|
|
137
|
-
The algorithm state containing current `kOfMatrix`, `dictionaryCurveLocations`, and thresholds.
|
|
138
|
-
|
|
139
|
-
Notes
|
|
140
|
-
-----
|
|
141
|
-
The algorithm is sophisticated, but this implementation is straightforward. Compute each index one at a time, compute each
|
|
142
|
-
`curveLocations` one at a time, and compute each type of analysis one at a time.
|
|
143
|
-
"""
|
|
144
|
-
dictionaryCurveGroups: dict[tuple[int, int], int] = {}
|
|
145
|
-
|
|
146
|
-
while (state.kOfMatrix > 0 and areIntegersWide(state)):
|
|
147
|
-
state.kOfMatrix -= 1
|
|
148
|
-
|
|
149
|
-
dictionaryCurveGroups = outfitDictionaryCurveGroups(state)
|
|
150
|
-
state.dictionaryCurveLocations.clear()
|
|
151
|
-
goByeBye()
|
|
152
|
-
|
|
153
|
-
for (groupAlpha, groupZulu), distinctCrossings in dictionaryCurveGroups.items():
|
|
154
|
-
groupAlphaCurves: bool = groupAlpha > 1
|
|
155
|
-
groupZuluHasCurves: bool = groupZulu > 1
|
|
156
|
-
groupAlphaIsEven = groupZuluIsEven = 0
|
|
157
|
-
|
|
158
|
-
curveLocationAnalysis = ((groupAlpha | (groupZulu << 1)) << 2) | 3
|
|
159
|
-
# simple
|
|
160
|
-
if curveLocationAnalysis < state.MAXIMUMcurveLocations:
|
|
161
|
-
state.dictionaryCurveLocations[curveLocationAnalysis] = state.dictionaryCurveLocations.get(curveLocationAnalysis, 0) + distinctCrossings
|
|
162
|
-
|
|
163
|
-
if groupAlphaCurves:
|
|
164
|
-
curveLocationAnalysis = (groupAlpha >> 2) | (groupZulu << 3) | ((groupAlphaIsEven := 1 - (groupAlpha & 1)) << 1)
|
|
165
|
-
if curveLocationAnalysis < state.MAXIMUMcurveLocations:
|
|
166
|
-
state.dictionaryCurveLocations[curveLocationAnalysis] = state.dictionaryCurveLocations.get(curveLocationAnalysis, 0) + distinctCrossings
|
|
167
|
-
|
|
168
|
-
if groupZuluHasCurves:
|
|
169
|
-
curveLocationAnalysis = (groupZulu >> 1) | (groupAlpha << 2) | (groupZuluIsEven := 1 - (groupZulu & 1))
|
|
170
|
-
if curveLocationAnalysis < state.MAXIMUMcurveLocations:
|
|
171
|
-
state.dictionaryCurveLocations[curveLocationAnalysis] = state.dictionaryCurveLocations.get(curveLocationAnalysis, 0) + distinctCrossings
|
|
172
|
-
|
|
173
|
-
if groupAlphaCurves and groupZuluHasCurves and (groupAlphaIsEven or groupZuluIsEven):
|
|
174
|
-
# aligned
|
|
175
|
-
if groupAlphaIsEven and not groupZuluIsEven:
|
|
176
|
-
groupAlpha ^= walkDyckPath(groupAlpha) # noqa: PLW2901
|
|
177
|
-
elif groupZuluIsEven and not groupAlphaIsEven:
|
|
178
|
-
groupZulu ^= walkDyckPath(groupZulu) # noqa: PLW2901
|
|
179
|
-
|
|
180
|
-
curveLocationAnalysis: int = ((groupZulu >> 2) << 1) | (groupAlpha >> 2)
|
|
181
|
-
if curveLocationAnalysis < state.MAXIMUMcurveLocations:
|
|
182
|
-
state.dictionaryCurveLocations[curveLocationAnalysis] = state.dictionaryCurveLocations.get(curveLocationAnalysis, 0) + distinctCrossings
|
|
183
|
-
|
|
184
|
-
return state
|
|
185
|
-
|
|
186
|
-
# ruff: noqa: B023
|
|
187
|
-
|
|
188
|
-
def countPandas(state: MatrixMeandersState) -> MatrixMeandersState:
|
|
189
|
-
"""Count meanders with matrix transfer algorithm using pandas DataFrame.
|
|
190
|
-
|
|
191
|
-
Parameters
|
|
192
|
-
----------
|
|
193
|
-
state : MatrixMeandersState
|
|
194
|
-
The algorithm state containing current `kOfMatrix`, `dictionaryCurveLocations`, and thresholds.
|
|
195
|
-
|
|
196
|
-
Returns
|
|
197
|
-
-------
|
|
198
|
-
state : MatrixMeandersState
|
|
199
|
-
Updated state with new `kOfMatrix` and `dictionaryCurveLocations`.
|
|
200
|
-
"""
|
|
201
|
-
dataframeAnalyzed = pandas.DataFrame({
|
|
202
|
-
'analyzed': pandas.Series(name='analyzed', data=state.dictionaryCurveLocations.keys(), copy=False, dtype=state.datatypeCurveLocations)
|
|
203
|
-
, 'distinctCrossings': pandas.Series(name='distinctCrossings', data=state.dictionaryCurveLocations.values(), copy=False, dtype=state.datatypeDistinctCrossings)
|
|
204
|
-
}, dtype=state.datatypeCurveLocations
|
|
205
|
-
)
|
|
206
|
-
state.dictionaryCurveLocations.clear()
|
|
207
|
-
|
|
208
|
-
while (state.kOfMatrix > 0 and not areIntegersWide(state, dataframeAnalyzed)):
|
|
209
|
-
|
|
210
|
-
def aggregateCurveLocations() -> None:
|
|
211
|
-
nonlocal dataframeAnalyzed
|
|
212
|
-
dataframeAnalyzed = dataframeAnalyzed.iloc[0:state.indexStartAnalyzed].groupby('analyzed', sort=False)['distinctCrossings'].aggregate('sum').reset_index()
|
|
213
|
-
|
|
214
|
-
def analyzeCurveLocationsAligned() -> None:
|
|
215
|
-
"""Compute `curveLocations` from `groupAlpha` and `groupZulu` if at least one is an even number.
|
|
216
|
-
|
|
217
|
-
Before computing `curveLocations`, some values of `groupAlpha` and `groupZulu` are modified.
|
|
218
|
-
|
|
219
|
-
Warning
|
|
220
|
-
-------
|
|
221
|
-
This function deletes rows from `dataframeCurveLocations`. Always run this analysis last.
|
|
222
|
-
|
|
223
|
-
Formula
|
|
224
|
-
-------
|
|
225
|
-
```python
|
|
226
|
-
if groupAlpha > 1 and groupZulu > 1 and (groupAlphaIsEven or groupZuluIsEven):
|
|
227
|
-
curveLocations = (groupAlpha >> 2) | ((groupZulu >> 2) << 1)
|
|
228
|
-
```
|
|
229
|
-
"""
|
|
230
|
-
nonlocal dataframeCurveLocations
|
|
231
|
-
|
|
232
|
-
# NOTE Step 1 drop unqualified rows
|
|
233
|
-
|
|
234
|
-
ImaGroupZulpha: pandas.Series = dataframeCurveLocations['curveLocations'].copy() # Ima `groupAlpha`.
|
|
235
|
-
ImaGroupZulpha &= state.locatorGroupAlpha # Ima `groupAlpha`.
|
|
236
|
-
|
|
237
|
-
dataframeCurveLocations = dataframeCurveLocations.loc[(ImaGroupZulpha > 1)] # if groupAlphaHasCurves
|
|
238
|
-
|
|
239
|
-
del ImaGroupZulpha
|
|
240
|
-
|
|
241
|
-
ImaGroupZulpha = dataframeCurveLocations['curveLocations'].copy() # Ima `groupZulu`.
|
|
242
|
-
ImaGroupZulpha &= state.locatorGroupZulu # Ima `groupZulu`.
|
|
243
|
-
ImaGroupZulpha //= 2**1 # Ima `groupZulu` (groupZulu >> 1)
|
|
244
|
-
|
|
245
|
-
dataframeCurveLocations = dataframeCurveLocations.loc[(ImaGroupZulpha > 1)] # if groupZuluHasCurves
|
|
246
|
-
|
|
247
|
-
del ImaGroupZulpha
|
|
248
|
-
|
|
249
|
-
ImaGroupZulpha = dataframeCurveLocations['curveLocations'].copy() # Ima `groupZulu`.
|
|
250
|
-
ImaGroupZulpha &= 0b10 # Ima `groupZulu`.
|
|
251
|
-
ImaGroupZulpha //= 2**1 # Ima `groupZulu` (groupZulu >> 1)
|
|
252
|
-
ImaGroupZulpha &= 1 # (groupZulu & 1)
|
|
253
|
-
ImaGroupZulpha ^= 1 # (1 - (groupZulu ...))
|
|
254
|
-
dataframeCurveLocations.loc[:, 'analyzed'] = ImaGroupZulpha # selectorGroupZuluAtEven
|
|
255
|
-
|
|
256
|
-
del ImaGroupZulpha
|
|
257
|
-
|
|
258
|
-
ImaGroupZulpha = dataframeCurveLocations['curveLocations'].copy() # Ima `groupAlpha`.
|
|
259
|
-
ImaGroupZulpha &= 1 # (groupAlpha & 1)
|
|
260
|
-
ImaGroupZulpha ^= 1 # (1 - (groupAlpha ...))
|
|
261
|
-
ImaGroupZulpha = ImaGroupZulpha.astype(bool) # selectorGroupAlphaAtODD
|
|
262
|
-
|
|
263
|
-
dataframeCurveLocations = dataframeCurveLocations.loc[(ImaGroupZulpha) | (dataframeCurveLocations.loc[:, 'analyzed'])] # if (groupAlphaIsEven or groupZuluIsEven)
|
|
264
|
-
|
|
265
|
-
del ImaGroupZulpha
|
|
266
|
-
|
|
267
|
-
# NOTE Step 2 modify rows
|
|
268
|
-
|
|
269
|
-
# Make a selector for groupZuluAtEven, so you can modify groupAlpha
|
|
270
|
-
ImaGroupZulpha = dataframeCurveLocations['curveLocations'].copy() # Ima `groupZulu`.
|
|
271
|
-
ImaGroupZulpha &= 0b10 # Ima `groupZulu`.
|
|
272
|
-
ImaGroupZulpha //= 2**1 # Ima `groupZulu` (groupZulu >> 1)
|
|
273
|
-
ImaGroupZulpha &= 1 # (groupZulu & 1)
|
|
274
|
-
ImaGroupZulpha ^= 1 # (1 - (groupZulu ...))
|
|
275
|
-
ImaGroupZulpha = ImaGroupZulpha.astype(bool) # selectorGroupZuluAtEven
|
|
276
|
-
|
|
277
|
-
dataframeCurveLocations.loc[:, 'analyzed'] = dataframeCurveLocations['curveLocations'] # Ima `groupAlpha`.
|
|
278
|
-
dataframeCurveLocations.loc[:, 'analyzed'] &= state.locatorGroupAlpha # (groupAlpha)
|
|
279
|
-
|
|
280
|
-
# if groupAlphaIsEven and not groupZuluIsEven, modifyGroupAlphaPairedToOdd
|
|
281
|
-
dataframeCurveLocations.loc[(~ImaGroupZulpha), 'analyzed'] = state.datatypeCurveLocations( # pyright: ignore[reportCallIssue, reportArgumentType]
|
|
282
|
-
flipTheExtra_0b1AsUfunc(dataframeCurveLocations.loc[(~ImaGroupZulpha), 'analyzed']))
|
|
283
|
-
|
|
284
|
-
del ImaGroupZulpha
|
|
285
|
-
|
|
286
|
-
# if groupZuluIsEven and not groupAlphaIsEven, modifyGroupZuluPairedToOdd
|
|
287
|
-
ImaGroupZulpha = dataframeCurveLocations['curveLocations'].copy() # Ima `groupZulu`.
|
|
288
|
-
ImaGroupZulpha &= state.locatorGroupZulu # Ima `groupZulu`.
|
|
289
|
-
ImaGroupZulpha //= 2**1 # Ima `groupZulu` (groupZulu >> 1)
|
|
290
|
-
|
|
291
|
-
ImaGroupZulpha.loc[(dataframeCurveLocations.loc[:, 'curveLocations'] & 1).astype(bool)] = state.datatypeCurveLocations( # pyright: ignore[reportArgumentType, reportCallIssue]
|
|
292
|
-
flipTheExtra_0b1AsUfunc(ImaGroupZulpha.loc[(dataframeCurveLocations.loc[:, 'curveLocations'] & 1).astype(bool)])) # pyright: ignore[reportCallIssue, reportUnknownArgumentType, reportArgumentType]
|
|
293
|
-
|
|
294
|
-
# NOTE Step 3 compute curveLocations
|
|
295
|
-
|
|
296
|
-
dataframeCurveLocations.loc[:, 'analyzed'] //= 2**2 # (groupAlpha >> 2)
|
|
297
|
-
|
|
298
|
-
ImaGroupZulpha //= 2**2 # (groupZulu >> 2)
|
|
299
|
-
ImaGroupZulpha *= 2**1 # ((groupZulu ...) << 1)
|
|
300
|
-
|
|
301
|
-
dataframeCurveLocations.loc[:, 'analyzed'] |= ImaGroupZulpha # ... | (groupZulu ...)
|
|
302
|
-
|
|
303
|
-
del ImaGroupZulpha
|
|
304
|
-
|
|
305
|
-
dataframeCurveLocations.loc[dataframeCurveLocations['analyzed'] >= state.MAXIMUMcurveLocations, 'analyzed'] = 0
|
|
306
|
-
|
|
307
|
-
def analyzeCurveLocationsAlpha() -> None:
|
|
308
|
-
"""Compute `curveLocations` from `groupAlpha`.
|
|
309
|
-
|
|
310
|
-
Formula
|
|
311
|
-
-------
|
|
312
|
-
```python
|
|
313
|
-
if groupAlpha > 1:
|
|
314
|
-
curveLocations = ((1 - (groupAlpha & 1)) << 1) | (groupZulu << 3) | (groupAlpha >> 2)
|
|
315
|
-
# `(1 - (groupAlpha & 1)` is an evenness test.
|
|
316
|
-
```
|
|
317
|
-
"""
|
|
318
|
-
nonlocal dataframeCurveLocations
|
|
319
|
-
dataframeCurveLocations['analyzed'] = dataframeCurveLocations['curveLocations']
|
|
320
|
-
dataframeCurveLocations.loc[:, 'analyzed'] &= 1 # (groupAlpha & 1)
|
|
321
|
-
dataframeCurveLocations.loc[:, 'analyzed'] ^= 1 # (1 - (groupAlpha ...))
|
|
322
|
-
|
|
323
|
-
dataframeCurveLocations.loc[:, 'analyzed'] *= 2**1 # ((groupAlpha ...) << 1)
|
|
324
|
-
|
|
325
|
-
ImaGroupZulpha: pandas.Series = dataframeCurveLocations['curveLocations'].copy() # Ima `groupZulu`.
|
|
326
|
-
ImaGroupZulpha &= state.locatorGroupZulu # Ima `groupZulu`.
|
|
327
|
-
ImaGroupZulpha //= 2**1 # Ima `groupZulu` (groupZulu >> 1)
|
|
328
|
-
|
|
329
|
-
ImaGroupZulpha *= 2**3 # (groupZulu << 3)
|
|
330
|
-
dataframeCurveLocations.loc[:, 'analyzed'] |= ImaGroupZulpha # ... | (groupZulu ...)
|
|
331
|
-
|
|
332
|
-
del ImaGroupZulpha
|
|
333
|
-
|
|
334
|
-
dataframeCurveLocations.loc[:, 'analyzed'] *= 2**2 # ... | (groupAlpha >> 2)
|
|
335
|
-
|
|
336
|
-
ImaGroupZulpha = dataframeCurveLocations['curveLocations'].copy() # Ima `groupAlpha`.
|
|
337
|
-
ImaGroupZulpha &= state.locatorGroupAlpha # Ima `groupAlpha`.
|
|
338
|
-
|
|
339
|
-
dataframeCurveLocations.loc[:, 'analyzed'] |= ImaGroupZulpha # ... | (groupAlpha)
|
|
340
|
-
dataframeCurveLocations.loc[:, 'analyzed'] //= 2**2 # (... >> 2)
|
|
341
|
-
|
|
342
|
-
dataframeCurveLocations.loc[(ImaGroupZulpha <= 1), 'analyzed'] = 0 # if groupAlpha > 1
|
|
343
|
-
|
|
344
|
-
del ImaGroupZulpha
|
|
345
|
-
|
|
346
|
-
dataframeCurveLocations.loc[dataframeCurveLocations['analyzed'] >= state.MAXIMUMcurveLocations, 'analyzed'] = 0
|
|
347
|
-
|
|
348
|
-
def analyzeCurveLocationsSimple() -> None:
|
|
349
|
-
"""Compute curveLocations with the 'simple' bridges formula.
|
|
350
|
-
|
|
351
|
-
Formula
|
|
352
|
-
-------
|
|
353
|
-
```python
|
|
354
|
-
curveLocations = ((groupAlpha | (groupZulu << 1)) << 2) | 3
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
Notes
|
|
358
|
-
-----
|
|
359
|
-
Using `+= 3` instead of `|= 3` is valid in this specific case. Left shift by two means the last bits are '0b00'. '0 + 3'
|
|
360
|
-
is '0b11', and '0b00 | 0b11' is also '0b11'.
|
|
361
|
-
|
|
362
|
-
"""
|
|
363
|
-
nonlocal dataframeCurveLocations
|
|
364
|
-
dataframeCurveLocations['analyzed'] = dataframeCurveLocations['curveLocations']
|
|
365
|
-
dataframeCurveLocations.loc[:, 'analyzed'] &= state.locatorGroupAlpha
|
|
366
|
-
|
|
367
|
-
groupZulu: pandas.Series = dataframeCurveLocations['curveLocations'].copy()
|
|
368
|
-
groupZulu &= state.locatorGroupZulu
|
|
369
|
-
groupZulu //= 2**1 # (groupZulu >> 1)
|
|
370
|
-
groupZulu *= 2**1 # (groupZulu << 1)
|
|
371
|
-
|
|
372
|
-
dataframeCurveLocations.loc[:, 'analyzed'] |= groupZulu # ((groupAlpha | (groupZulu ...))
|
|
373
|
-
|
|
374
|
-
del groupZulu
|
|
375
|
-
|
|
376
|
-
dataframeCurveLocations.loc[:, 'analyzed'] *= 2**2 # (... << 2)
|
|
377
|
-
dataframeCurveLocations.loc[:, 'analyzed'] += 3 # (...) | 3
|
|
378
|
-
dataframeCurveLocations.loc[dataframeCurveLocations['analyzed'] >= state.MAXIMUMcurveLocations, 'analyzed'] = 0
|
|
379
|
-
|
|
380
|
-
def analyzeCurveLocationsZulu() -> None:
|
|
381
|
-
"""Compute `curveLocations` from `groupZulu`.
|
|
382
|
-
|
|
383
|
-
Formula
|
|
384
|
-
-------
|
|
385
|
-
```python
|
|
386
|
-
if groupZulu > 1:
|
|
387
|
-
curveLocations = (1 - (groupZulu & 1)) | (groupAlpha << 2) | (groupZulu >> 1)
|
|
388
|
-
```
|
|
389
|
-
"""
|
|
390
|
-
nonlocal dataframeCurveLocations
|
|
391
|
-
dataframeCurveLocations.loc[:, 'analyzed'] = dataframeCurveLocations['curveLocations'] # Ima `groupZulu`.
|
|
392
|
-
dataframeCurveLocations.loc[:, 'analyzed'] &= 0b10 # Ima `groupZulu`.
|
|
393
|
-
dataframeCurveLocations.loc[:, 'analyzed'] //= 2**1 # Ima `groupZulu` (groupZulu >> 1)
|
|
394
|
-
dataframeCurveLocations.loc[:, 'analyzed'] &= 1 # (groupZulu & 1)
|
|
395
|
-
dataframeCurveLocations.loc[:, 'analyzed'] ^= 1 # (1 - (groupZulu ...))
|
|
396
|
-
|
|
397
|
-
ImaGroupZulpha: pandas.Series = dataframeCurveLocations['curveLocations'].copy() # Ima `groupAlpha`.
|
|
398
|
-
ImaGroupZulpha &= state.locatorGroupAlpha # Ima `groupAlpha`.
|
|
399
|
-
|
|
400
|
-
ImaGroupZulpha *= 2**2 # (groupAlpha << 2)
|
|
401
|
-
dataframeCurveLocations.loc[:, 'analyzed'] |= ImaGroupZulpha # ... | (groupAlpha ...)
|
|
402
|
-
|
|
403
|
-
del ImaGroupZulpha
|
|
404
|
-
|
|
405
|
-
ImaGroupZulpha = dataframeCurveLocations['curveLocations'].copy() # Ima `groupZulu`.
|
|
406
|
-
ImaGroupZulpha &= state.locatorGroupZulu # Ima `groupZulu`.
|
|
407
|
-
ImaGroupZulpha //= 2**1 # Ima `groupZulu` (groupZulu >> 1)
|
|
408
|
-
|
|
409
|
-
ImaGroupZulpha //= 2**1 # (groupZulu >> 1)
|
|
410
|
-
|
|
411
|
-
dataframeCurveLocations.loc[:, 'analyzed'] |= ImaGroupZulpha # ... | (groupZulu ...)
|
|
412
|
-
|
|
413
|
-
del ImaGroupZulpha
|
|
414
|
-
|
|
415
|
-
ImaGroupZulpha = dataframeCurveLocations['curveLocations'].copy() # Ima `groupZulu`.
|
|
416
|
-
ImaGroupZulpha &= state.locatorGroupZulu # Ima `groupZulu`.
|
|
417
|
-
ImaGroupZulpha //= 2**1 # Ima `groupZulu` (groupZulu >> 1)
|
|
418
|
-
|
|
419
|
-
dataframeCurveLocations.loc[ImaGroupZulpha <= 1, 'analyzed'] = 0 # if groupZulu > 1
|
|
420
|
-
|
|
421
|
-
del ImaGroupZulpha
|
|
422
|
-
|
|
423
|
-
dataframeCurveLocations.loc[dataframeCurveLocations['analyzed'] >= state.MAXIMUMcurveLocations, 'analyzed'] = 0
|
|
424
|
-
|
|
425
|
-
def recordCurveLocations() -> None:
|
|
426
|
-
nonlocal dataframeAnalyzed
|
|
427
|
-
|
|
428
|
-
indexStopAnalyzed: int = state.indexStartAnalyzed + int((dataframeCurveLocations['analyzed'] > 0).sum()) # pyright: ignore[reportUnknownArgumentType, reportUnknownMemberType]
|
|
429
|
-
|
|
430
|
-
if indexStopAnalyzed > state.indexStartAnalyzed:
|
|
431
|
-
if len(dataframeAnalyzed.index) < indexStopAnalyzed:
|
|
432
|
-
warn(f"Lengthened `dataframeAnalyzed` from {len(dataframeAnalyzed.index)} to {indexStopAnalyzed=}; n={state.n}, {state.kOfMatrix=}.", stacklevel=2)
|
|
433
|
-
dataframeAnalyzed = dataframeAnalyzed.reindex(index=pandas.RangeIndex(indexStopAnalyzed), fill_value=0)
|
|
434
|
-
|
|
435
|
-
dataframeAnalyzed.loc[state.indexStartAnalyzed:indexStopAnalyzed - 1, ['analyzed', 'distinctCrossings']] = (
|
|
436
|
-
dataframeCurveLocations.loc[(dataframeCurveLocations['analyzed'] > 0), ['analyzed', 'distinctCrossings']
|
|
437
|
-
].to_numpy(dtype=state.datatypeCurveLocations, copy=False)
|
|
438
|
-
)
|
|
439
|
-
|
|
440
|
-
state.indexStartAnalyzed = indexStopAnalyzed
|
|
441
|
-
|
|
442
|
-
del indexStopAnalyzed
|
|
443
|
-
|
|
444
|
-
dataframeCurveLocations = pandas.DataFrame({
|
|
445
|
-
'curveLocations': pandas.Series(name='curveLocations', data=dataframeAnalyzed['analyzed'], copy=False, dtype=state.datatypeCurveLocations)
|
|
446
|
-
, 'analyzed': pandas.Series(name='analyzed', data=0, dtype=state.datatypeCurveLocations)
|
|
447
|
-
, 'distinctCrossings': pandas.Series(name='distinctCrossings', data=dataframeAnalyzed['distinctCrossings'], copy=False, dtype=state.datatypeDistinctCrossings)
|
|
448
|
-
} # pyright: ignore[reportUnknownArgumentType]
|
|
449
|
-
)
|
|
450
|
-
|
|
451
|
-
del dataframeAnalyzed
|
|
452
|
-
goByeBye()
|
|
453
|
-
|
|
454
|
-
state.bitWidth = int(dataframeCurveLocations['curveLocations'].max()).bit_length()
|
|
455
|
-
length: int = getBucketsTotal(state)
|
|
456
|
-
dataframeAnalyzed = pandas.DataFrame({
|
|
457
|
-
'analyzed': pandas.Series(0, pandas.RangeIndex(length), dtype=state.datatypeCurveLocations, name='analyzed')
|
|
458
|
-
, 'distinctCrossings': pandas.Series(0, pandas.RangeIndex(length), dtype=state.datatypeDistinctCrossings, name='distinctCrossings')
|
|
459
|
-
}, index=pandas.RangeIndex(length), columns=['analyzed', 'distinctCrossings'], dtype=state.datatypeCurveLocations # pyright: ignore[reportUnknownArgumentType]
|
|
460
|
-
)
|
|
461
|
-
|
|
462
|
-
state.kOfMatrix -= 1
|
|
463
|
-
|
|
464
|
-
state.indexStartAnalyzed = 0
|
|
465
|
-
|
|
466
|
-
analyzeCurveLocationsSimple()
|
|
467
|
-
recordCurveLocations()
|
|
468
|
-
|
|
469
|
-
analyzeCurveLocationsAlpha()
|
|
470
|
-
recordCurveLocations()
|
|
471
|
-
|
|
472
|
-
analyzeCurveLocationsZulu()
|
|
473
|
-
recordCurveLocations()
|
|
474
|
-
|
|
475
|
-
analyzeCurveLocationsAligned()
|
|
476
|
-
recordCurveLocations()
|
|
477
|
-
del dataframeCurveLocations
|
|
478
|
-
goByeBye()
|
|
479
|
-
|
|
480
|
-
aggregateCurveLocations()
|
|
481
|
-
|
|
482
|
-
if state.n >= 45: # for data collection
|
|
483
|
-
print(state.n, state.kOfMatrix+1, state.indexStartAnalyzed, sep=',') # noqa: T201
|
|
484
|
-
|
|
485
|
-
state.dictionaryCurveLocations = dataframeAnalyzed.set_index('analyzed')['distinctCrossings'].to_dict()
|
|
486
|
-
return state
|
|
1
|
+
from mapFolding.algorithms.matrixMeandersBeDry import walkDyckPath
|
|
2
|
+
from mapFolding.dataBaskets import MatrixMeandersState
|
|
3
|
+
|
|
4
|
+
def count(state: MatrixMeandersState) -> MatrixMeandersState:
|
|
5
|
+
"""Count meanders with matrix transfer algorithm using Python `int` (*int*eger) contained in a Python `dict` (*dict*ionary).
|
|
6
|
+
|
|
7
|
+
Parameters
|
|
8
|
+
----------
|
|
9
|
+
state : MatrixMeandersState
|
|
10
|
+
The algorithm state.
|
|
11
|
+
|
|
12
|
+
Notes
|
|
13
|
+
-----
|
|
14
|
+
The matrix transfer algorithm is sophisticated, but this implementation is straightforward: compute each index one at a time,
|
|
15
|
+
compute each `arcCode` one at a time, and compute each type of analysis one at a time.
|
|
16
|
+
"""
|
|
17
|
+
dictionaryArcCodeToCrossings: dict[int, int] = {}
|
|
18
|
+
|
|
19
|
+
while state.boundary > 0:
|
|
20
|
+
state.boundary -= 1
|
|
21
|
+
state.bitWidth = max(state.dictionaryMeanders.keys()).bit_length()
|
|
22
|
+
|
|
23
|
+
dictionaryArcCodeToCrossings = state.dictionaryMeanders.copy()
|
|
24
|
+
state.dictionaryMeanders = {}
|
|
25
|
+
|
|
26
|
+
for arcCode, crossings in dictionaryArcCodeToCrossings.items():
|
|
27
|
+
bitsAlpha: int = arcCode & state.locatorBits
|
|
28
|
+
bitsZulu: int = (arcCode >> 1) & state.locatorBits
|
|
29
|
+
bitsAlphaHasArcs: bool = bitsAlpha > 1
|
|
30
|
+
bitsZuluHasArcs: bool = bitsZulu > 1
|
|
31
|
+
bitsAlphaIsEven: int = bitsAlpha & 1 ^ 1
|
|
32
|
+
bitsZuluIsEven: int = bitsZulu & 1 ^ 1
|
|
33
|
+
|
|
34
|
+
arcCodeAnalysis = ((bitsAlpha | (bitsZulu << 1)) << 2) | 3
|
|
35
|
+
# simple
|
|
36
|
+
if arcCodeAnalysis < state.MAXIMUMarcCode:
|
|
37
|
+
state.dictionaryMeanders[arcCodeAnalysis] = state.dictionaryMeanders.get(arcCodeAnalysis, 0) + crossings
|
|
38
|
+
|
|
39
|
+
if bitsAlphaHasArcs:
|
|
40
|
+
arcCodeAnalysis = (bitsAlpha >> 2) | (bitsZulu << 3) | (bitsAlphaIsEven << 1)
|
|
41
|
+
if arcCodeAnalysis < state.MAXIMUMarcCode:
|
|
42
|
+
state.dictionaryMeanders[arcCodeAnalysis] = state.dictionaryMeanders.get(arcCodeAnalysis, 0) + crossings
|
|
43
|
+
|
|
44
|
+
if bitsZuluHasArcs:
|
|
45
|
+
arcCodeAnalysis = (bitsZulu >> 1) | (bitsAlpha << 2) | bitsZuluIsEven
|
|
46
|
+
if arcCodeAnalysis < state.MAXIMUMarcCode:
|
|
47
|
+
state.dictionaryMeanders[arcCodeAnalysis] = state.dictionaryMeanders.get(arcCodeAnalysis, 0) + crossings
|
|
48
|
+
|
|
49
|
+
if bitsAlphaHasArcs and bitsZuluHasArcs and (bitsAlphaIsEven or bitsZuluIsEven):
|
|
50
|
+
# aligned
|
|
51
|
+
if bitsAlphaIsEven and not bitsZuluIsEven:
|
|
52
|
+
bitsAlpha ^= walkDyckPath(bitsAlpha)
|
|
53
|
+
elif bitsZuluIsEven and not bitsAlphaIsEven:
|
|
54
|
+
bitsZulu ^= walkDyckPath(bitsZulu)
|
|
55
|
+
|
|
56
|
+
arcCodeAnalysis: int = ((bitsZulu >> 2) << 1) | (bitsAlpha >> 2)
|
|
57
|
+
if arcCodeAnalysis < state.MAXIMUMarcCode:
|
|
58
|
+
state.dictionaryMeanders[arcCodeAnalysis] = state.dictionaryMeanders.get(arcCodeAnalysis, 0) + crossings
|
|
59
|
+
|
|
60
|
+
dictionaryArcCodeToCrossings = {}
|
|
61
|
+
|
|
62
|
+
return state
|
|
487
63
|
|
|
488
64
|
def doTheNeedful(state: MatrixMeandersState) -> int:
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
if areIntegersWide(state):
|
|
514
|
-
state = countBigInt(state)
|
|
515
|
-
else:
|
|
516
|
-
state = countPandas(state)
|
|
517
|
-
|
|
518
|
-
return sum(state.dictionaryCurveLocations.values())
|
|
519
|
-
|
|
65
|
+
"""Compute `crossings` with a transfer matrix algorithm.
|
|
66
|
+
|
|
67
|
+
Parameters
|
|
68
|
+
----------
|
|
69
|
+
state : MatrixMeandersState
|
|
70
|
+
The algorithm state.
|
|
71
|
+
|
|
72
|
+
Returns
|
|
73
|
+
-------
|
|
74
|
+
crossings : int
|
|
75
|
+
The computed value of `crossings`.
|
|
76
|
+
|
|
77
|
+
Notes
|
|
78
|
+
-----
|
|
79
|
+
Citation: https://github.com/hunterhogan/mapFolding/blob/main/citations/Jensen.bibtex
|
|
80
|
+
|
|
81
|
+
See Also
|
|
82
|
+
--------
|
|
83
|
+
https://oeis.org/A000682
|
|
84
|
+
https://oeis.org/A005316
|
|
85
|
+
"""
|
|
86
|
+
state = count(state)
|
|
87
|
+
|
|
88
|
+
return sum(state.dictionaryMeanders.values())
|