mapFolding 0.16.1__py3-none-any.whl → 0.16.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. easyRun/A000682.py +1 -1
  2. easyRun/A005316.py +2 -3
  3. easyRun/NOTcountingFolds.py +6 -5
  4. easyRun/countFolds.py +1 -1
  5. easyRun/generateAllModules.py +14 -0
  6. easyRun/meanders.py +16 -18
  7. mapFolding/__init__.py +1 -0
  8. mapFolding/_theSSOT.py +3 -2
  9. mapFolding/_theTypes.py +3 -0
  10. mapFolding/algorithms/A086345.py +75 -0
  11. mapFolding/algorithms/matrixMeanders.py +15 -28
  12. mapFolding/algorithms/matrixMeandersBeDry.py +34 -116
  13. mapFolding/algorithms/matrixMeandersNumPy.py +117 -70
  14. mapFolding/algorithms/matrixMeandersPandas.py +113 -130
  15. mapFolding/algorithms/oeisIDbyFormula.py +25 -14
  16. mapFolding/algorithms/symmetricFolds.py +36 -0
  17. mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +26 -12
  18. mapFolding/basecamp.py +152 -323
  19. mapFolding/dataBaskets.py +136 -34
  20. mapFolding/filesystemToolkit.py +4 -32
  21. mapFolding/oeis.py +5 -12
  22. mapFolding/reference/A000682facts.py +785 -1264
  23. mapFolding/reference/A005316facts.py +958 -923
  24. mapFolding/reference/A086345Wu.py +25 -0
  25. mapFolding/reference/matrixMeandersAnalysis/signatures.py +2033 -0
  26. mapFolding/someAssemblyRequired/A007822/A007822rawMaterials.py +9 -44
  27. mapFolding/someAssemblyRequired/A007822/_asynchronousAnnex.py +51 -0
  28. mapFolding/someAssemblyRequired/A007822/makeA007822AsynchronousModules.py +39 -136
  29. mapFolding/someAssemblyRequired/A007822/makeA007822Modules.py +44 -45
  30. mapFolding/someAssemblyRequired/RecipeJob.py +78 -18
  31. mapFolding/someAssemblyRequired/__init__.py +3 -8
  32. mapFolding/someAssemblyRequired/_toolkitContainers.py +32 -3
  33. mapFolding/someAssemblyRequired/infoBooth.py +40 -23
  34. mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +75 -154
  35. mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +56 -88
  36. mapFolding/someAssemblyRequired/makingModules_count.py +91 -85
  37. mapFolding/someAssemblyRequired/makingModules_doTheNeedful.py +7 -65
  38. mapFolding/someAssemblyRequired/{mapFolding → mapFoldingModules}/makeMapFoldingModules.py +25 -31
  39. mapFolding/someAssemblyRequired/meanders/makeMeandersModules.py +14 -13
  40. mapFolding/someAssemblyRequired/toolkitMakeModules.py +10 -10
  41. mapFolding/someAssemblyRequired/toolkitNumba.py +1 -1
  42. mapFolding/someAssemblyRequired/transformationTools.py +17 -19
  43. mapFolding/syntheticModules/A007822/algorithm.py +46 -50
  44. mapFolding/syntheticModules/A007822/asynchronous.py +93 -34
  45. mapFolding/syntheticModules/A007822/initializeState.py +15 -21
  46. mapFolding/syntheticModules/A007822/theorem2.py +21 -21
  47. mapFolding/syntheticModules/A007822/theorem2Numba.py +42 -23
  48. mapFolding/syntheticModules/A007822/theorem2Trimmed.py +21 -21
  49. mapFolding/syntheticModules/countParallelNumba.py +3 -7
  50. mapFolding/syntheticModules/daoOfMapFoldingNumba.py +3 -6
  51. mapFolding/syntheticModules/meanders/bigInt.py +15 -25
  52. mapFolding/syntheticModules/theorem2.py +6 -0
  53. mapFolding/syntheticModules/theorem2Numba.py +26 -2
  54. mapFolding/syntheticModules/theorem2Trimmed.py +6 -0
  55. mapFolding/tests/test_computations.py +1 -1
  56. mapFolding/zCuzDocStoopid/makeDocstrings.py +2 -0
  57. {mapfolding-0.16.1.dist-info → mapfolding-0.16.4.dist-info}/METADATA +4 -1
  58. mapfolding-0.16.4.dist-info/RECORD +106 -0
  59. mapFolding/_dataPacking.py +0 -68
  60. mapFolding/reference/meandersDumpingGround/A005316intOptimized.py +0 -122
  61. mapFolding/reference/meandersDumpingGround/A005316optimized128bit.py +0 -79
  62. mapFolding/reference/meandersDumpingGround/matrixMeandersBaseline.py +0 -65
  63. mapFolding/reference/meandersDumpingGround/matrixMeandersBaselineAnnex.py +0 -84
  64. mapFolding/reference/meandersDumpingGround/matrixMeandersSimpleQueue.py +0 -90
  65. mapFolding/syntheticModules/A007822/algorithmNumba.py +0 -94
  66. mapFolding/syntheticModules/A007822/asynchronousAnnex.py +0 -66
  67. mapFolding/syntheticModules/A007822/asynchronousAnnexNumba.py +0 -85
  68. mapFolding/syntheticModules/A007822/asynchronousNumba.py +0 -52
  69. mapFolding/syntheticModules/A007822/asynchronousTheorem2.py +0 -53
  70. mapFolding/syntheticModules/A007822/asynchronousTrimmed.py +0 -47
  71. mapFolding/syntheticModules/dataPacking.py +0 -28
  72. mapFolding/syntheticModules/dataPackingA007822.py +0 -92
  73. mapfolding-0.16.1.dist-info/RECORD +0 -114
  74. /mapFolding/someAssemblyRequired/{mapFolding → mapFoldingModules}/__init__.py +0 -0
  75. {mapfolding-0.16.1.dist-info → mapfolding-0.16.4.dist-info}/WHEEL +0 -0
  76. {mapfolding-0.16.1.dist-info → mapfolding-0.16.4.dist-info}/entry_points.txt +0 -0
  77. {mapfolding-0.16.1.dist-info → mapfolding-0.16.4.dist-info}/licenses/LICENSE +0 -0
  78. {mapfolding-0.16.1.dist-info → mapfolding-0.16.4.dist-info}/top_level.txt +0 -0
@@ -5,37 +5,33 @@ from mapFolding.syntheticModules.meanders.bigInt import countBigInt
5
5
  from warnings import warn
6
6
  import pandas
7
7
 
8
- # TODO investigate adding another condition to `areIntegersWide`: while dict is faster than pandas, stay in bigInt.
9
-
10
- # ruff: noqa: B023
11
-
12
8
  def countPandas(state: MatrixMeandersNumPyState) -> MatrixMeandersNumPyState:
13
9
  """Count meanders with matrix transfer algorithm using pandas DataFrame.
14
10
 
15
11
  Parameters
16
12
  ----------
17
13
  state : MatrixMeandersState
18
- The algorithm state containing current `kOfMatrix`, `dictionaryMeanders`, and thresholds.
14
+ The algorithm state containing current `boundary`, `dictionaryMeanders`, and thresholds.
19
15
 
20
16
  Returns
21
17
  -------
22
18
  state : MatrixMeandersState
23
- Updated state with new `kOfMatrix` and `dictionaryMeanders`.
19
+ Updated state with new `boundary` and `dictionaryMeanders`.
24
20
  """
25
21
  dataframeAnalyzed = pandas.DataFrame({
26
22
  'analyzed': pandas.Series(name='analyzed', data=state.dictionaryMeanders.keys(), copy=False, dtype=state.datatypeArcCode)
27
23
  , 'crossings': pandas.Series(name='crossings', data=state.dictionaryMeanders.values(), copy=False, dtype=state.datatypeCrossings)
28
- }, dtype=state.datatypeArcCode
24
+ }
29
25
  )
30
26
  state.dictionaryMeanders.clear()
31
27
 
32
- while (state.kOfMatrix > 0 and not areIntegersWide(state, dataframe=dataframeAnalyzed)):
28
+ while (state.boundary > 0 and not areIntegersWide(state, dataframe=dataframeAnalyzed)):
33
29
 
34
30
  def aggregateArcCodes() -> None:
35
31
  nonlocal dataframeAnalyzed
36
32
  dataframeAnalyzed = dataframeAnalyzed.iloc[0:state.indexTarget].groupby('analyzed', sort=False)['crossings'].aggregate('sum').reset_index()
37
33
 
38
- def analyzeArcCodesAligned() -> None:
34
+ def analyzeArcCodesAligned(dataframeMeanders: pandas.DataFrame) -> pandas.DataFrame:
39
35
  """Compute `arcCode` from `bitsAlpha` and `bitsZulu` if at least one is an even number.
40
36
 
41
37
  Before computing `arcCode`, some values of `bitsAlpha` and `bitsZulu` are modified.
@@ -51,84 +47,105 @@ def countPandas(state: MatrixMeandersNumPyState) -> MatrixMeandersNumPyState:
51
47
  arcCode = (bitsAlpha >> 2) | ((bitsZulu >> 2) << 1)
52
48
  ```
53
49
  """
54
- nonlocal dataframeMeanders
55
-
56
50
  # NOTE Step 1 drop unqualified rows
51
+ # ======= > * > bitsAlpha 1 bitsZulu 1 ====================
52
+ dataframeMeanders['analyzed'] = dataframeMeanders['arcCode'].copy() # `bitsAlpha`
53
+ dataframeMeanders['analyzed'] &= state.locatorBits # `bitsAlpha`
57
54
 
58
- bitsTarget: pandas.Series = dataframeMeanders['arcCode'].copy() # `bitsAlpha`
59
- bitsTarget &= state.locatorBits # `bitsAlpha`
55
+ dataframeMeanders['analyzed'] = dataframeMeanders['analyzed'].gt(1) # if bitsAlphaHasArcs
60
56
 
61
- dataframeMeanders = dataframeMeanders.loc[(bitsTarget > 1)] # if bitsAlphaHasCurves
57
+ bitsTarget: pandas.Series = dataframeMeanders['arcCode'].copy() # `bitsZulu`
58
+ bitsTarget //= 2**1 # `bitsZulu` (bitsZulu >> 1)
59
+ bitsTarget &= state.locatorBits # `bitsZulu`
62
60
 
61
+ dataframeMeanders['analyzed'] *= bitsTarget
63
62
  del bitsTarget
63
+ dataframeMeanders = dataframeMeanders.loc[(dataframeMeanders['analyzed'] > 1)] # if (bitsAlphaHasArcs and bitsZuluHasArcs)
64
64
 
65
- bitsTarget = dataframeMeanders['arcCode'].copy() # `bitsZulu`
66
- bitsTarget //= 2**1 # `bitsZulu` (bitsZulu >> 1)
67
- bitsTarget &= state.locatorBits # `bitsZulu`
65
+ # ======= ^ & & bitsAlpha 1 bitsZulu 1 ====================
66
+ dataframeMeanders.loc[:, 'analyzed'] = dataframeMeanders['arcCode'].copy() # `bitsAlpha`
67
+ dataframeMeanders.loc[:, 'analyzed'] &= state.locatorBits # `bitsAlpha`
68
+
69
+ dataframeMeanders.loc[:, 'analyzed'] &= 1 # `bitsAlpha`
68
70
 
69
- dataframeMeanders = dataframeMeanders.loc[(bitsTarget > 1)] # if bitsZuluHasCurves
71
+ bitsTarget: pandas.Series = dataframeMeanders['arcCode'].copy() # `bitsZulu`
72
+ bitsTarget //= 2**1 # `bitsZulu` (bitsZulu >> 1)
73
+ bitsTarget &= state.locatorBits # `bitsZulu`
70
74
 
75
+ dataframeMeanders.loc[:, 'analyzed'] &= bitsTarget
71
76
  del bitsTarget
77
+ dataframeMeanders.loc[:, 'analyzed'] ^= 1
72
78
 
73
- bitsTarget = dataframeMeanders['arcCode'].copy() # `bitsZulu`
74
- bitsTarget &= 0b10 # `bitsZulu`
75
- bitsTarget //= 2**1 # `bitsZulu` (bitsZulu >> 1)
76
- bitsTarget &= 1 # (bitsZulu & 1)
77
- bitsTarget ^= 1 # (1 - (bitsZulu ...))
78
- dataframeMeanders.loc[:, 'analyzed'] = bitsTarget # selectorBitsZuluAtEven
79
+ dataframeMeanders = dataframeMeanders.loc[(dataframeMeanders['analyzed'] > 0)] # if (bitsAlphaIsEven or bitsZuluIsEven)
79
80
 
80
- del bitsTarget
81
+ # NOTE Step 2 modify rows
82
+ # Make a selector for bitsZuluAtOdd, so you can modify bitsAlpha
83
+ dataframeMeanders.loc[:, 'analyzed'] = dataframeMeanders['arcCode'].copy() # `bitsZulu`
84
+ dataframeMeanders.loc[:, 'analyzed'] //= 2**1 # `bitsZulu` (bitsZulu >> 1)
85
+ dataframeMeanders.loc[:, 'analyzed'] &= 1 # selectorBitsZuluAtOdd
81
86
 
82
- bitsTarget = dataframeMeanders['arcCode'].copy() # `bitsAlpha`
83
- bitsTarget &= 1 # (bitsAlpha & 1)
84
- bitsTarget ^= 1 # (1 - (bitsAlpha ...))
85
- bitsTarget = bitsTarget.astype(bool) # selectorBitsAlphaAtODD
87
+ bitsTarget = dataframeMeanders['arcCode'].copy() # `bitsAlpha`
88
+ bitsTarget &= state.locatorBits # `bitsAlpha`
86
89
 
87
- dataframeMeanders = dataframeMeanders.loc[(bitsTarget) | (dataframeMeanders.loc[:, 'analyzed'])] # if (bitsAlphaIsEven or bitsZuluIsEven)
90
+ # if bitsAlphaAtEven and not bitsZuluAtEven, modify bitsAlphaPairedToOdd
91
+ bitsTarget.loc[(dataframeMeanders['analyzed'] > 0)] = state.datatypeArcCode(
92
+ flipTheExtra_0b1AsUfunc(bitsTarget.loc[(dataframeMeanders['analyzed'] > 0)]))
88
93
 
89
- del bitsTarget
94
+ dataframeMeanders.loc[:, 'analyzed'] = dataframeMeanders['arcCode'].copy() # `bitsZulu`
95
+ dataframeMeanders.loc[:, 'analyzed'] //= 2**1 # `bitsZulu` (bitsZulu >> 1)
96
+ dataframeMeanders.loc[:, 'analyzed'] &= state.locatorBits # `bitsZulu`
90
97
 
91
- # NOTE Step 2 modify rows
98
+ # if bitsZuluAtEven and not bitsAlphaAtEven, modify bitsZuluPairedToOdd
99
+ dataframeMeanders.loc[((dataframeMeanders.loc[:, 'arcCode'] & 1) > 0), 'analyzed'] = state.datatypeArcCode(
100
+ flipTheExtra_0b1AsUfunc(dataframeMeanders.loc[((dataframeMeanders.loc[:, 'arcCode'] & 1) > 0), 'analyzed']))
92
101
 
93
- # Make a selector for bitsZuluAtEven, so you can modify bitsAlpha
94
- bitsTarget = dataframeMeanders['arcCode'].copy() # `bitsZulu`
95
- bitsTarget &= 0b10 # `bitsZulu`
96
- bitsTarget //= 2**1 # `bitsZulu` (bitsZulu >> 1)
97
- bitsTarget &= 1 # (bitsZulu & 1)
98
- bitsTarget ^= 1 # (1 - (bitsZulu ...))
99
- bitsTarget = bitsTarget.astype(bool) # selectorBitsZuluAtEven
102
+ # NOTE Step 3 compute arcCode
103
+ # ======= >> | << >> bitsZulu 2 3 bitsAlpha 2 =============
104
+ dataframeMeanders.loc[:, 'analyzed'] //= 2**2 # (bitsZulu >> 2)
105
+ dataframeMeanders.loc[:, 'analyzed'] *= 2**3 # (bitsZulu << 3)
106
+ dataframeMeanders.loc[:, 'analyzed'] |= bitsTarget
107
+ del bitsTarget
108
+ dataframeMeanders.loc[:, 'analyzed'] //= 2**2 # (... >> 2)
100
109
 
101
- dataframeMeanders.loc[:, 'analyzed'] = dataframeMeanders['arcCode'] # `bitsAlpha`
102
- dataframeMeanders.loc[:, 'analyzed'] &= state.locatorBits # `bitsAlpha`
110
+ dataframeMeanders.loc[dataframeMeanders['analyzed'] >= state.MAXIMUMarcCode, 'analyzed'] = 0
103
111
 
104
- # if bitsAlphaIsEven and not bitsZuluIsEven, modify bitsAlphaPairedToOdd
105
- dataframeMeanders.loc[(~bitsTarget), 'analyzed'] = state.datatypeArcCode( # pyright: ignore[reportCallIssue, reportArgumentType]
106
- flipTheExtra_0b1AsUfunc(dataframeMeanders.loc[(~bitsTarget), 'analyzed']))
112
+ return dataframeMeanders
107
113
 
108
- del bitsTarget
114
+ def analyzeArcCodesSimple(dataframeMeanders: pandas.DataFrame) -> pandas.DataFrame:
115
+ """Compute arcCode with the 'simple' formula.
109
116
 
110
- # if bitsZuluIsEven and not bitsAlphaIsEven, modify bitsZuluPairedToOdd
111
- bitsTarget = dataframeMeanders['arcCode'].copy() # `bitsZulu`
112
- bitsTarget //= 2**1 # `bitsZulu` (bitsZulu >> 1)
113
- bitsTarget &= state.locatorBits # `bitsZulu`
117
+ Formula
118
+ -------
119
+ ```python
120
+ arcCode = ((bitsAlpha | (bitsZulu << 1)) << 2) | 3
121
+ ```
114
122
 
115
- bitsTarget.loc[(dataframeMeanders.loc[:, 'arcCode'] & 1).astype(bool)] = state.datatypeArcCode( # pyright: ignore[reportArgumentType, reportCallIssue]
116
- flipTheExtra_0b1AsUfunc(bitsTarget.loc[(dataframeMeanders.loc[:, 'arcCode'] & 1).astype(bool)])) # pyright: ignore[reportCallIssue, reportUnknownArgumentType, reportArgumentType]
123
+ Notes
124
+ -----
125
+ Using `+= 3` instead of `|= 3` is valid in this specific case. Left shift by two means the last bits are '0b00'. '0 + 3'
126
+ is '0b11', and '0b00 | 0b11' is also '0b11'.
117
127
 
118
- # NOTE Step 3 compute arcCode
128
+ """
129
+ dataframeMeanders['analyzed'] = dataframeMeanders['arcCode']
130
+ dataframeMeanders.loc[:, 'analyzed'] &= state.locatorBits
119
131
 
120
- dataframeMeanders.loc[:, 'analyzed'] //= 2**2 # (bitsAlpha >> 2)
132
+ bitsZulu: pandas.Series = dataframeMeanders['arcCode'].copy()
133
+ bitsZulu //= 2**1 # (bitsZulu >> 1)
134
+ bitsZulu &= state.locatorBits # `bitsZulu`
121
135
 
122
- bitsTarget //= 2**2 # (bitsZulu >> 2)
123
- bitsTarget *= 2**1 # ((bitsZulu ...) << 1)
136
+ bitsZulu *= 2**1 # (bitsZulu << 1)
124
137
 
125
- dataframeMeanders.loc[:, 'analyzed'] |= bitsTarget # ... | (bitsZulu ...)
138
+ dataframeMeanders.loc[:, 'analyzed'] |= bitsZulu # ((bitsAlpha | (bitsZulu ...))
126
139
 
127
- del bitsTarget
140
+ del bitsZulu
128
141
 
142
+ dataframeMeanders.loc[:, 'analyzed'] *= 2**2 # (... << 2)
143
+ dataframeMeanders.loc[:, 'analyzed'] += 3 # (...) | 3
129
144
  dataframeMeanders.loc[dataframeMeanders['analyzed'] >= state.MAXIMUMarcCode, 'analyzed'] = 0
130
145
 
131
- def analyzeBitsAlpha() -> None:
146
+ return dataframeMeanders
147
+
148
+ def analyzeBitsAlpha(dataframeMeanders: pandas.DataFrame) -> pandas.DataFrame:
132
149
  """Compute `arcCode` from `bitsAlpha`.
133
150
 
134
151
  Formula
@@ -139,7 +156,6 @@ def countPandas(state: MatrixMeandersNumPyState) -> MatrixMeandersNumPyState:
139
156
  # `(1 - (bitsAlpha & 1)` is an evenness test.
140
157
  ```
141
158
  """
142
- nonlocal dataframeMeanders
143
159
  dataframeMeanders['analyzed'] = dataframeMeanders['arcCode']
144
160
  dataframeMeanders.loc[:, 'analyzed'] &= 1 # (bitsAlpha & 1)
145
161
  dataframeMeanders.loc[:, 'analyzed'] ^= 1 # (1 - (bitsAlpha ...))
@@ -177,39 +193,9 @@ def countPandas(state: MatrixMeandersNumPyState) -> MatrixMeandersNumPyState:
177
193
 
178
194
  dataframeMeanders.loc[dataframeMeanders['analyzed'] >= state.MAXIMUMarcCode, 'analyzed'] = 0
179
195
 
180
- def analyzeArcCodesSimple() -> None:
181
- """Compute arcCode with the 'simple' formula.
182
-
183
- Formula
184
- -------
185
- ```python
186
- arcCode = ((bitsAlpha | (bitsZulu << 1)) << 2) | 3
187
- ```
188
-
189
- Notes
190
- -----
191
- Using `+= 3` instead of `|= 3` is valid in this specific case. Left shift by two means the last bits are '0b00'. '0 + 3'
192
- is '0b11', and '0b00 | 0b11' is also '0b11'.
196
+ return dataframeMeanders
193
197
 
194
- """
195
- nonlocal dataframeMeanders
196
- dataframeMeanders['analyzed'] = dataframeMeanders['arcCode']
197
- dataframeMeanders.loc[:, 'analyzed'] &= state.locatorBits
198
-
199
- bitsZulu: pandas.Series = dataframeMeanders['arcCode'].copy()
200
- bitsZulu //= 2**1 # (bitsZulu >> 1)
201
- bitsZulu &= state.locatorBits # `bitsZulu`
202
- bitsZulu *= 2**1 # (bitsZulu << 1)
203
-
204
- dataframeMeanders.loc[:, 'analyzed'] |= bitsZulu # ((bitsAlpha | (bitsZulu ...))
205
-
206
- del bitsZulu
207
-
208
- dataframeMeanders.loc[:, 'analyzed'] *= 2**2 # (... << 2)
209
- dataframeMeanders.loc[:, 'analyzed'] += 3 # (...) | 3
210
- dataframeMeanders.loc[dataframeMeanders['analyzed'] >= state.MAXIMUMarcCode, 'analyzed'] = 0
211
-
212
- def analyzeBitsZulu() -> None:
198
+ def analyzeBitsZulu(dataframeMeanders: pandas.DataFrame) -> pandas.DataFrame:
213
199
  """Compute `arcCode` from `bitsZulu`.
214
200
 
215
201
  Formula
@@ -219,10 +205,10 @@ def countPandas(state: MatrixMeandersNumPyState) -> MatrixMeandersNumPyState:
219
205
  arcCode = (1 - (bitsZulu & 1)) | (bitsAlpha << 2) | (bitsZulu >> 1)
220
206
  ```
221
207
  """
222
- nonlocal dataframeMeanders
208
+ # NOTE `(1 - (bitsZulu & 1))` is an evenness test: we want a single bit as the answer.
223
209
  dataframeMeanders.loc[:, 'analyzed'] = dataframeMeanders['arcCode'] # `bitsZulu`
224
- dataframeMeanders.loc[:, 'analyzed'] &= 0b10 # `bitsZulu`
225
210
  dataframeMeanders.loc[:, 'analyzed'] //= 2**1 # `bitsZulu` (bitsZulu >> 1)
211
+ dataframeMeanders.loc[:, 'analyzed'] &= 1 # `bitsZulu`
226
212
  dataframeMeanders.loc[:, 'analyzed'] &= 1 # (bitsZulu & 1)
227
213
  dataframeMeanders.loc[:, 'analyzed'] ^= 1 # (1 - (bitsZulu ...))
228
214
 
@@ -231,54 +217,56 @@ def countPandas(state: MatrixMeandersNumPyState) -> MatrixMeandersNumPyState:
231
217
 
232
218
  bitsTarget *= 2**2 # (bitsAlpha << 2)
233
219
  dataframeMeanders.loc[:, 'analyzed'] |= bitsTarget # ... | (bitsAlpha ...)
234
-
235
220
  del bitsTarget
236
221
 
237
- # NOTE No, IDK why I didn't use the same trick as in `analyzeBitsAlpha`. I _think_ I wrote this code before I figured out that trick.
238
- bitsTarget = dataframeMeanders['arcCode'].copy() # `bitsZulu`
239
- bitsTarget //= 2**1 # `bitsZulu` (bitsZulu >> 1)
240
- bitsTarget &= state.locatorBits # `bitsZulu`
241
-
242
- bitsTarget //= 2**1 # (bitsZulu >> 1)
243
-
244
- dataframeMeanders.loc[:, 'analyzed'] |= bitsTarget # ... | (bitsZulu ...)
245
-
246
- del bitsTarget
222
+ # NOTE Same trick as in `analyzeBitsAlpha`.
223
+ dataframeMeanders.loc[:, 'analyzed'] *= 2**1 # (... << 1)
247
224
 
248
225
  bitsTarget = dataframeMeanders['arcCode'].copy() # `bitsZulu`
249
226
  bitsTarget //= 2**1 # `bitsZulu` (bitsZulu >> 1)
250
227
  bitsTarget &= state.locatorBits # `bitsZulu`
251
228
 
252
- dataframeMeanders.loc[bitsTarget <= 1, 'analyzed'] = 0 # if bitsZulu > 1
229
+ dataframeMeanders.loc[:, 'analyzed'] |= bitsTarget # ... | (bitsZulu)
230
+ dataframeMeanders.loc[:, 'analyzed'] //= 2**1 # (... >> 1)
253
231
 
232
+ dataframeMeanders.loc[bitsTarget <= 1, 'analyzed'] = 0 # if bitsZulu > 1
254
233
  del bitsTarget
255
234
 
256
235
  dataframeMeanders.loc[dataframeMeanders['analyzed'] >= state.MAXIMUMarcCode, 'analyzed'] = 0
257
236
 
258
- def recordArcCodes() -> None:
237
+ return dataframeMeanders
238
+
239
+ def recordArcCodes(dataframeMeanders: pandas.DataFrame) -> pandas.DataFrame:
259
240
  nonlocal dataframeAnalyzed
260
241
 
261
- indexStopAnalyzed: int = state.indexTarget + int((dataframeMeanders['analyzed'] > 0).sum()) # pyright: ignore[reportUnknownArgumentType, reportUnknownMemberType]
242
+ indexStopAnalyzed: int = state.indexTarget + int((dataframeMeanders['analyzed'] > 0).sum())
262
243
 
263
244
  if indexStopAnalyzed > state.indexTarget:
264
245
  if len(dataframeAnalyzed.index) < indexStopAnalyzed:
265
- warn(f"Lengthened `dataframeAnalyzed` from {len(dataframeAnalyzed.index)} to {indexStopAnalyzed=}; n={state.n}, {state.kOfMatrix=}.", stacklevel=2)
246
+ warn(f"Lengthened `dataframeAnalyzed` from {len(dataframeAnalyzed.index)} to {indexStopAnalyzed=}; n={state.n}, {state.boundary=}.", stacklevel=2)
266
247
  dataframeAnalyzed = dataframeAnalyzed.reindex(index=pandas.RangeIndex(indexStopAnalyzed), fill_value=0)
267
248
 
268
- dataframeAnalyzed.loc[state.indexTarget:indexStopAnalyzed - 1, ['analyzed', 'crossings']] = (
269
- dataframeMeanders.loc[(dataframeMeanders['analyzed'] > 0), ['analyzed', 'crossings']
249
+ dataframeAnalyzed.loc[state.indexTarget:indexStopAnalyzed - 1, ['analyzed']] = (
250
+ dataframeMeanders.loc[(dataframeMeanders['analyzed'] > 0), ['analyzed']
270
251
  ].to_numpy(dtype=state.datatypeArcCode, copy=False)
271
252
  )
272
253
 
254
+ dataframeAnalyzed.loc[state.indexTarget:indexStopAnalyzed - 1, ['crossings']] = (
255
+ dataframeMeanders.loc[(dataframeMeanders['analyzed'] > 0), ['crossings']
256
+ ].to_numpy(dtype=state.datatypeCrossings, copy=False)
257
+ )
258
+
273
259
  state.indexTarget = indexStopAnalyzed
274
260
 
275
261
  del indexStopAnalyzed
276
262
 
263
+ return dataframeMeanders
264
+
277
265
  dataframeMeanders = pandas.DataFrame({
278
266
  'arcCode': pandas.Series(name='arcCode', data=dataframeAnalyzed['analyzed'], copy=False, dtype=state.datatypeArcCode)
279
267
  , 'analyzed': pandas.Series(name='analyzed', data=0, dtype=state.datatypeArcCode)
280
268
  , 'crossings': pandas.Series(name='crossings', data=dataframeAnalyzed['crossings'], copy=False, dtype=state.datatypeCrossings)
281
- } # pyright: ignore[reportUnknownArgumentType]
269
+ }
282
270
  )
283
271
 
284
272
  del dataframeAnalyzed
@@ -287,35 +275,33 @@ def countPandas(state: MatrixMeandersNumPyState) -> MatrixMeandersNumPyState:
287
275
  state.bitWidth = int(dataframeMeanders['arcCode'].max()).bit_length()
288
276
  length: int = getBucketsTotal(state)
289
277
  dataframeAnalyzed = pandas.DataFrame({
290
- 'analyzed': pandas.Series(0, pandas.RangeIndex(length), dtype=state.datatypeArcCode, name='analyzed')
291
- , 'crossings': pandas.Series(0, pandas.RangeIndex(length), dtype=state.datatypeCrossings, name='crossings')
292
- }, index=pandas.RangeIndex(length), columns=['analyzed', 'crossings'], dtype=state.datatypeArcCode # pyright: ignore[reportUnknownArgumentType]
278
+ 'analyzed': pandas.Series(name='analyzed', data=0, index=pandas.RangeIndex(length), dtype=state.datatypeArcCode)
279
+ , 'crossings': pandas.Series(name='crossings', data=0, index=pandas.RangeIndex(length), dtype=state.datatypeCrossings)
280
+ }, index=pandas.RangeIndex(length)
293
281
  )
294
282
 
295
- state.kOfMatrix -= 1
283
+ state.boundary -= 1
296
284
 
297
285
  state.indexTarget = 0
298
286
 
299
- analyzeArcCodesSimple()
300
- recordArcCodes()
287
+ dataframeMeanders: pandas.DataFrame = analyzeArcCodesSimple(dataframeMeanders)
288
+ dataframeMeanders = recordArcCodes(dataframeMeanders)
301
289
 
302
- analyzeBitsAlpha()
303
- recordArcCodes()
290
+ dataframeMeanders = analyzeBitsAlpha(dataframeMeanders)
291
+ dataframeMeanders = recordArcCodes(dataframeMeanders)
304
292
 
305
- analyzeBitsZulu()
306
- recordArcCodes()
293
+ dataframeMeanders = analyzeBitsZulu(dataframeMeanders)
294
+ dataframeMeanders = recordArcCodes(dataframeMeanders)
307
295
 
308
- analyzeArcCodesAligned()
309
- recordArcCodes()
296
+ dataframeMeanders = analyzeArcCodesAligned(dataframeMeanders)
297
+ dataframeMeanders = recordArcCodes(dataframeMeanders)
310
298
  del dataframeMeanders
311
299
  goByeBye()
312
300
 
313
301
  aggregateArcCodes()
314
302
 
315
- if state.n >= 45: # for data collection
316
- print(state.n, state.kOfMatrix+1, state.indexTarget, sep=',') # noqa: T201
317
-
318
303
  state.dictionaryMeanders = dataframeAnalyzed.set_index('analyzed')['crossings'].to_dict()
304
+ del dataframeAnalyzed
319
305
  return state
320
306
 
321
307
  def doTheNeedful(state: MatrixMeandersNumPyState) -> int:
@@ -340,12 +326,9 @@ def doTheNeedful(state: MatrixMeandersNumPyState) -> int:
340
326
  https://oeis.org/A000682
341
327
  https://oeis.org/A005316
342
328
  """
343
- while state.kOfMatrix > 0:
329
+ while state.boundary > 0:
344
330
  if areIntegersWide(state):
345
331
  state = countBigInt(state)
346
332
  else:
347
333
  state = countPandas(state)
348
-
349
- goByeBye()
350
-
351
334
  return sum(state.dictionaryMeanders.values())
@@ -8,7 +8,7 @@ NOTE: This is a generated file; edit the source file.
8
8
  """
9
9
  from functools import cache
10
10
  from mapFolding import dictionaryOEIS
11
- from mapFolding.basecamp import A000682, A005316, NOTcountingFolds
11
+ from mapFolding.basecamp import NOTcountingFolds
12
12
 
13
13
  @cache
14
14
  def A000136(n: int) -> int:
@@ -35,13 +35,13 @@ def A000136(n: int) -> int:
35
35
  OEIS : webpage
36
36
  https://oeis.org/A000136
37
37
  """
38
- return n * A000682(n)
38
+ return n * _A000682(n)
39
39
 
40
40
  def A000560(n: int) -> int:
41
41
  """
42
42
  Compute A000560(n) as a function of A000682.
43
43
 
44
- *The On-Line Encyclopedia of Integer Sequences* (OEIS) description of A000560 is: "Number of ways of folding a strip of n labeled stamps."
44
+ *The On-Line Encyclopedia of Integer Sequences* (OEIS) description of A000560 is: "Number of symmetric ways of folding a strip of n labeled stamps."
45
45
 
46
46
  The domain of A000560 starts at 2, therefore for values of `n` < 2, a(n) is undefined. The smallest value of n for which a(n)
47
47
  has not yet been computed is 45.
@@ -54,14 +54,14 @@ def A000560(n: int) -> int:
54
54
  Returns
55
55
  -------
56
56
  a(n) : int
57
- Number of ways of folding a strip of n labeled stamps.
57
+ Number of symmetric ways of folding a strip of n labeled stamps.
58
58
 
59
59
  Would You Like to Know More?
60
60
  ----------------------------
61
61
  OEIS : webpage
62
62
  https://oeis.org/A000560
63
63
  """
64
- return A000682(n + 1) // 2
64
+ return _A000682(n + 1) // 2
65
65
 
66
66
  def A001010(n: int) -> int:
67
67
  """
@@ -90,9 +90,9 @@ def A001010(n: int) -> int:
90
90
  if n == 1:
91
91
  countTotal = 1
92
92
  elif n & 1:
93
- countTotal = 2 * NOTcountingFolds(oeisID='A007822', oeis_n=(n - 1) // 2 + 1, flow='theorem2Numba')
93
+ countTotal = 2 * _A007822((n - 1) // 2 + 1)
94
94
  else:
95
- countTotal = 2 * A000682(n // 2 + 1)
95
+ countTotal = 2 * _A000682(n // 2 + 1)
96
96
  return countTotal
97
97
 
98
98
  def A001011(n: int) -> int:
@@ -153,7 +153,7 @@ def A005315(n: int) -> int:
153
153
  if n in {0, 1}:
154
154
  countTotal = 1
155
155
  else:
156
- countTotal = A005316(2 * n - 1)
156
+ countTotal = _A005316(2 * n - 1)
157
157
  return countTotal
158
158
 
159
159
  def A060206(n: int) -> int:
@@ -180,7 +180,7 @@ def A060206(n: int) -> int:
180
180
  OEIS : webpage
181
181
  https://oeis.org/A060206
182
182
  """
183
- return A000682(2 * n + 1)
183
+ return _A000682(2 * n + 1)
184
184
 
185
185
  def A077460(n: int) -> int:
186
186
  """
@@ -209,9 +209,9 @@ def A077460(n: int) -> int:
209
209
  if n in {0, 1}:
210
210
  countTotal = 1
211
211
  elif n & 1:
212
- countTotal = (A005315(n) + A005316(n) + A060206((n - 1) // 2)) // 4
212
+ countTotal = (A005315(n) + _A005316(n) + A060206((n - 1) // 2)) // 4
213
213
  else:
214
- countTotal = (A005315(n) + 2 * A005316(n)) // 4
214
+ countTotal = (A005315(n) + 2 * _A005316(n)) // 4
215
215
  return countTotal
216
216
 
217
217
  def A078591(n: int) -> int:
@@ -298,7 +298,7 @@ def A223094(n: int) -> int:
298
298
  OEIS : webpage
299
299
  https://oeis.org/A223094
300
300
  """
301
- return A000136(n) - A000682(n + 1)
301
+ return A000136(n) - _A000682(n + 1)
302
302
 
303
303
  def A259702(n: int) -> int:
304
304
  """
@@ -327,7 +327,7 @@ def A259702(n: int) -> int:
327
327
  if n == 2:
328
328
  countTotal = 0
329
329
  else:
330
- countTotal = A000682(n) // 2 - A000682(n - 1)
330
+ countTotal = _A000682(n) // 2 - _A000682(n - 1)
331
331
  return countTotal
332
332
 
333
333
  def A301620(n: int) -> int:
@@ -354,4 +354,15 @@ def A301620(n: int) -> int:
354
354
  OEIS : webpage
355
355
  https://oeis.org/A301620
356
356
  """
357
- return A000682(n + 2) - 2 * A000682(n + 1)
357
+ return _A000682(n + 2) - 2 * _A000682(n + 1)
358
+
359
+ @cache
360
+ def _A000682(n: int) -> int:
361
+ return NOTcountingFolds('A000682', n)
362
+
363
+ def _A007822(n: int) -> int:
364
+ return NOTcountingFolds('A007822', n)
365
+
366
+ @cache
367
+ def _A005316(n: int) -> int:
368
+ return NOTcountingFolds('A005316', n)
@@ -0,0 +1,36 @@
1
+ """Count the number of symmetric folds in the group of folds defined by `leafBelow`.
2
+
3
+ Notes
4
+ -----
5
+ - About constructing `leafComparison`:
6
+ - This branch of the algorithm executes IFF `leafBelow[0] == 1`.
7
+ - Therefore, `leafComparison[0]` must be `1`.
8
+ - Therefore, the first iteration of the loop is hardcoded to save processing time.
9
+ - I _feel_ there must be a more efficient way to do this.
10
+ - Some implementation details are based on Numba compatibility. Incompatible:
11
+ - `numpy.take(..., out=...)`
12
+ - `numpy.all(..., axis=...)`
13
+ """
14
+ from mapFolding.dataBaskets import SymmetricFoldsState
15
+ import numpy
16
+
17
+ def filterAsymmetricFolds(state: SymmetricFoldsState) -> SymmetricFoldsState:
18
+ state.indexLeaf = 1
19
+ state.leafComparison[0] = 1
20
+ state.leafConnectee = 1
21
+
22
+ while state.leafConnectee < state.leavesTotal + 1:
23
+ state.indexMiniGap = state.leafBelow[state.indexLeaf]
24
+ state.leafComparison[state.leafConnectee] = (state.indexMiniGap - state.indexLeaf + state.leavesTotal) % state.leavesTotal
25
+ state.indexLeaf = state.indexMiniGap
26
+
27
+ state.leafConnectee += 1
28
+
29
+ state.arrayGroupOfFolds = numpy.take(state.leafComparison, state.indicesArrayGroupOfFolds)
30
+ compared = state.arrayGroupOfFolds[..., 0:state.leavesTotal // 2] == state.arrayGroupOfFolds[..., state.leavesTotal // 2:None]
31
+
32
+ for indexRow in range(len(compared)):
33
+ state.groupsOfFolds += compared[indexRow].all()
34
+
35
+ return state
36
+
@@ -6,25 +6,26 @@ TODO A301620 a(n) = Sum_{k=3..floor((n+3)/2)} (A259689(n+1,k)*(k-2)). - _Roger F
6
6
  """
7
7
  from functools import cache
8
8
  from mapFolding import dictionaryOEIS
9
- from mapFolding.basecamp import A000682, A005316, NOTcountingFolds
9
+ from mapFolding.basecamp import NOTcountingFolds
10
10
 
11
+ # ruff: noqa: D400
11
12
  @cache
12
13
  def A000136(n: int) -> int:
13
14
  """A000682"""
14
- return n * A000682(n)
15
+ return n * _A000682(n)
15
16
 
16
17
  def A000560(n: int) -> int:
17
18
  """A000682"""
18
- return A000682(n + 1) // 2
19
+ return _A000682(n + 1) // 2
19
20
 
20
21
  def A001010(n: int) -> int:
21
22
  """A000682 or A007822"""
22
23
  if n == 1:
23
24
  countTotal = 1
24
25
  elif n & 0b1:
25
- countTotal = 2 * NOTcountingFolds(oeisID='A007822', oeis_n=(n - 1)//2 + 1, flow='theorem2Numba')
26
+ countTotal = 2 * _A007822((n - 1)//2 + 1)
26
27
  else:
27
- countTotal = 2 * A000682(n // 2 + 1)
28
+ countTotal = 2 * _A000682(n // 2 + 1)
28
29
  return countTotal
29
30
 
30
31
  def A001011(n: int) -> int:
@@ -41,21 +42,21 @@ def A005315(n: int) -> int:
41
42
  if n in {0, 1}:
42
43
  countTotal = 1
43
44
  else:
44
- countTotal = A005316(2 * n - 1)
45
+ countTotal = _A005316(2 * n - 1)
45
46
  return countTotal
46
47
 
47
48
  def A060206(n: int) -> int:
48
49
  """A000682"""
49
- return A000682(2 * n + 1)
50
+ return _A000682(2 * n + 1)
50
51
 
51
52
  def A077460(n: int) -> int:
52
53
  """A005315, A005316, and A060206"""
53
54
  if n in {0, 1}:
54
55
  countTotal = 1
55
56
  elif n & 0b1:
56
- countTotal = (A005315(n) + A005316(n) + A060206((n - 1) // 2)) // 4
57
+ countTotal = (A005315(n) + _A005316(n) + A060206((n - 1) // 2)) // 4
57
58
  else:
58
- countTotal = (A005315(n) + 2 * A005316(n)) // 4
59
+ countTotal = (A005315(n) + 2 * _A005316(n)) // 4
59
60
 
60
61
  return countTotal
61
62
 
@@ -77,16 +78,29 @@ def A178961(n: int) -> int:
77
78
 
78
79
  def A223094(n: int) -> int:
79
80
  """A000136 and A000682"""
80
- return A000136(n) - A000682(n + 1)
81
+ return A000136(n) - _A000682(n + 1)
81
82
 
82
83
  def A259702(n: int) -> int:
83
84
  """A000682"""
84
85
  if n == 2:
85
86
  countTotal = 0
86
87
  else:
87
- countTotal = A000682(n) // 2 - A000682(n - 1)
88
+ countTotal = _A000682(n) // 2 - _A000682(n - 1)
88
89
  return countTotal
89
90
 
90
91
  def A301620(n: int) -> int:
91
92
  """A000682"""
92
- return A000682(n + 2) - 2 * A000682(n + 1)
93
+ return _A000682(n + 2) - 2 * _A000682(n + 1)
94
+
95
+ # ================= Not formulas ==========================
96
+
97
+ @cache
98
+ def _A000682(n: int) -> int:
99
+ return NOTcountingFolds('A000682', n)
100
+
101
+ def _A007822(n: int) -> int:
102
+ return NOTcountingFolds('A007822', n)
103
+
104
+ @cache
105
+ def _A005316(n: int) -> int:
106
+ return NOTcountingFolds('A005316', n)