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,4 +1,5 @@
|
|
|
1
1
|
from mapFolding.dataBaskets import MapFoldingState
|
|
2
|
+
from mapFolding.syntheticModules.initializeState import transitionOnGroupsOfFolds
|
|
2
3
|
|
|
3
4
|
def count(state: MapFoldingState) -> MapFoldingState:
|
|
4
5
|
while state.leaf1ndex > 4:
|
|
@@ -47,4 +48,9 @@ def count(state: MapFoldingState) -> MapFoldingState:
|
|
|
47
48
|
state.leaf1ndex += 1
|
|
48
49
|
else:
|
|
49
50
|
state.groupsOfFolds *= 2
|
|
51
|
+
return state
|
|
52
|
+
|
|
53
|
+
def doTheNeedful(state: MapFoldingState) -> MapFoldingState:
|
|
54
|
+
state = transitionOnGroupsOfFolds(state)
|
|
55
|
+
state = count(state)
|
|
50
56
|
return state
|
|
@@ -2,7 +2,7 @@ from mapFolding.dataBaskets import Array1DElephino, Array1DLeavesTotal, Array3DL
|
|
|
2
2
|
from numba import jit
|
|
3
3
|
|
|
4
4
|
@jit(cache=True, error_model='numpy', fastmath=True, forceinline=True)
|
|
5
|
-
def count(groupsOfFolds: DatatypeFoldsTotal, gap1ndex: DatatypeElephino, gap1ndexCeiling: DatatypeElephino, indexDimension: DatatypeLeavesTotal, indexMiniGap: DatatypeElephino, leaf1ndex: DatatypeLeavesTotal, leafConnectee: DatatypeLeavesTotal, dimensionsUnconstrained: DatatypeLeavesTotal, countDimensionsGapped: Array1DLeavesTotal, gapRangeStart: Array1DElephino, gapsWhere: Array1DLeavesTotal, leafAbove: Array1DLeavesTotal, leafBelow: Array1DLeavesTotal, connectionGraph: Array3DLeavesTotal, dimensionsTotal: DatatypeLeavesTotal, leavesTotal: DatatypeLeavesTotal) -> tuple[DatatypeFoldsTotal, DatatypeElephino, DatatypeElephino, DatatypeLeavesTotal, DatatypeElephino, DatatypeLeavesTotal, DatatypeLeavesTotal, DatatypeLeavesTotal, Array1DLeavesTotal, Array1DElephino, Array1DLeavesTotal, Array1DLeavesTotal, Array1DLeavesTotal, Array3DLeavesTotal, DatatypeLeavesTotal, DatatypeLeavesTotal]:
|
|
5
|
+
def count(groupsOfFolds: DatatypeFoldsTotal, gap1ndex: DatatypeElephino, gap1ndexCeiling: DatatypeElephino, indexDimension: DatatypeLeavesTotal, indexLeaf: DatatypeLeavesTotal, indexMiniGap: DatatypeElephino, leaf1ndex: DatatypeLeavesTotal, leafConnectee: DatatypeLeavesTotal, dimensionsUnconstrained: DatatypeLeavesTotal, countDimensionsGapped: Array1DLeavesTotal, gapRangeStart: Array1DElephino, gapsWhere: Array1DLeavesTotal, leafAbove: Array1DLeavesTotal, leafBelow: Array1DLeavesTotal, connectionGraph: Array3DLeavesTotal, dimensionsTotal: DatatypeLeavesTotal, leavesTotal: DatatypeLeavesTotal) -> tuple[DatatypeFoldsTotal, DatatypeElephino, DatatypeElephino, DatatypeLeavesTotal, DatatypeLeavesTotal, DatatypeElephino, DatatypeLeavesTotal, DatatypeLeavesTotal, DatatypeLeavesTotal, Array1DLeavesTotal, Array1DElephino, Array1DLeavesTotal, Array1DLeavesTotal, Array1DLeavesTotal, Array3DLeavesTotal, DatatypeLeavesTotal, DatatypeLeavesTotal]:
|
|
6
6
|
while leaf1ndex > 4:
|
|
7
7
|
if leafBelow[0] == 1:
|
|
8
8
|
if leaf1ndex > leavesTotal:
|
|
@@ -23,6 +23,12 @@ def count(groupsOfFolds: DatatypeFoldsTotal, gap1ndex: DatatypeElephino, gap1nde
|
|
|
23
23
|
countDimensionsGapped[leafConnectee] += 1
|
|
24
24
|
leafConnectee = connectionGraph[indexDimension, leaf1ndex, leafBelow[leafConnectee]]
|
|
25
25
|
indexDimension += 1
|
|
26
|
+
if not dimensionsUnconstrained:
|
|
27
|
+
indexLeaf = 0
|
|
28
|
+
while indexLeaf < leaf1ndex:
|
|
29
|
+
gapsWhere[gap1ndexCeiling] = indexLeaf
|
|
30
|
+
gap1ndexCeiling += 1
|
|
31
|
+
indexLeaf += 1
|
|
26
32
|
indexMiniGap = gap1ndex
|
|
27
33
|
while indexMiniGap < gap1ndexCeiling:
|
|
28
34
|
gapsWhere[gap1ndex] = gapsWhere[indexMiniGap]
|
|
@@ -43,4 +49,4 @@ def count(groupsOfFolds: DatatypeFoldsTotal, gap1ndex: DatatypeElephino, gap1nde
|
|
|
43
49
|
leaf1ndex += 1
|
|
44
50
|
else:
|
|
45
51
|
groupsOfFolds *= 2
|
|
46
|
-
return (groupsOfFolds, gap1ndex, gap1ndexCeiling, indexDimension, indexMiniGap, leaf1ndex, leafConnectee, dimensionsUnconstrained, countDimensionsGapped, gapRangeStart, gapsWhere, leafAbove, leafBelow, connectionGraph, dimensionsTotal, leavesTotal)
|
|
52
|
+
return (groupsOfFolds, gap1ndex, gap1ndexCeiling, indexDimension, indexLeaf, indexMiniGap, leaf1ndex, leafConnectee, dimensionsUnconstrained, countDimensionsGapped, gapRangeStart, gapsWhere, leafAbove, leafBelow, connectionGraph, dimensionsTotal, leavesTotal)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from mapFolding.dataBaskets import MapFoldingState
|
|
2
|
+
from mapFolding.syntheticModules.initializeState import transitionOnGroupsOfFolds
|
|
2
3
|
|
|
3
4
|
def count(state: MapFoldingState) -> MapFoldingState:
|
|
4
5
|
while state.leaf1ndex > 4:
|
|
@@ -41,4 +42,9 @@ def count(state: MapFoldingState) -> MapFoldingState:
|
|
|
41
42
|
state.leaf1ndex += 1
|
|
42
43
|
else:
|
|
43
44
|
state.groupsOfFolds *= 2
|
|
45
|
+
return state
|
|
46
|
+
|
|
47
|
+
def doTheNeedful(state: MapFoldingState, /) -> MapFoldingState:
|
|
48
|
+
state = transitionOnGroupsOfFolds(state)
|
|
49
|
+
state = count(state)
|
|
44
50
|
return state
|
mapFolding/tests/conftest.py
CHANGED
|
@@ -25,7 +25,7 @@ research domain.
|
|
|
25
25
|
|
|
26
26
|
from collections.abc import Callable, Generator, Sequence
|
|
27
27
|
from mapFolding import _theSSOT, getLeavesTotal, makeDataContainer, packageSettings, validateListDimensions
|
|
28
|
-
from mapFolding.oeis import
|
|
28
|
+
from mapFolding.oeis import dictionaryOEIS, dictionaryOEISMapFolding, oeisIDsImplemented
|
|
29
29
|
from pathlib import Path
|
|
30
30
|
from typing import Any
|
|
31
31
|
import numpy
|
|
@@ -223,7 +223,7 @@ def oneTestCuzTestsOverwritingTests(oeisID_1random: str) -> tuple[int, ...]:
|
|
|
223
223
|
pass
|
|
224
224
|
|
|
225
225
|
@pytest.fixture
|
|
226
|
-
def mapShapeTestCountFolds(
|
|
226
|
+
def mapShapeTestCountFolds(oeisIDmapFolding: str) -> tuple[int, ...]:
|
|
227
227
|
"""For each `oeisID` from the `pytest.fixture`, returns `listDimensions` from `valuesTestValidation` if
|
|
228
228
|
`validateListDimensions` approves. Each `listDimensions` is suitable for testing counts.
|
|
229
229
|
|
|
@@ -239,10 +239,10 @@ def mapShapeTestCountFolds(oeisID: str) -> tuple[int, ...]:
|
|
|
239
239
|
|
|
240
240
|
"""
|
|
241
241
|
while True:
|
|
242
|
-
n = random.choice(dictionaryOEISMapFolding[
|
|
242
|
+
n = random.choice(dictionaryOEISMapFolding[oeisIDmapFolding]['valuesTestValidation'])
|
|
243
243
|
if n < 2:
|
|
244
244
|
continue
|
|
245
|
-
listDimensionsCandidate = list(dictionaryOEISMapFolding[
|
|
245
|
+
listDimensionsCandidate = list(dictionaryOEISMapFolding[oeisIDmapFolding]['getMapShape'](n))
|
|
246
246
|
|
|
247
247
|
try:
|
|
248
248
|
return validateListDimensions(listDimensionsCandidate)
|
|
@@ -278,7 +278,7 @@ def mapShapeTestFunctionality(oeisID_1random: str) -> tuple[int, ...]:
|
|
|
278
278
|
pass
|
|
279
279
|
|
|
280
280
|
@pytest.fixture
|
|
281
|
-
def mapShapeTestParallelization(
|
|
281
|
+
def mapShapeTestParallelization(oeisIDmapFolding: str) -> tuple[int, ...]:
|
|
282
282
|
"""For each `oeisID` from the `pytest.fixture`, returns `listDimensions` from `valuesTestParallelization`.
|
|
283
283
|
|
|
284
284
|
Parameters
|
|
@@ -292,8 +292,8 @@ def mapShapeTestParallelization(oeisID: str) -> tuple[int, ...]:
|
|
|
292
292
|
Map dimensions suitable for testing parallelization features.
|
|
293
293
|
|
|
294
294
|
"""
|
|
295
|
-
n = random.choice(dictionaryOEISMapFolding[
|
|
296
|
-
return dictionaryOEISMapFolding[
|
|
295
|
+
n = random.choice(dictionaryOEISMapFolding[oeisIDmapFolding]['valuesTestParallelization'])
|
|
296
|
+
return dictionaryOEISMapFolding[oeisIDmapFolding]['getMapShape'](n)
|
|
297
297
|
|
|
298
298
|
@pytest.fixture
|
|
299
299
|
def mockBenchmarkTimer() -> Generator[unittest.mock.MagicMock | unittest.mock.AsyncMock, Any, None]:
|
|
@@ -332,7 +332,7 @@ def mockFoldingFunction() -> Callable[..., Callable[..., None]]:
|
|
|
332
332
|
return make_mock
|
|
333
333
|
|
|
334
334
|
@pytest.fixture(params=oeisIDsImplemented)
|
|
335
|
-
def
|
|
335
|
+
def oeisIDmapFolding(request: pytest.FixtureRequest) -> Any:
|
|
336
336
|
"""Parametrized fixture providing all implemented OEIS sequence identifiers.
|
|
337
337
|
|
|
338
338
|
(AI generated docstring)
|
|
@@ -350,11 +350,26 @@ def oeisID(request: pytest.FixtureRequest) -> Any:
|
|
|
350
350
|
"""
|
|
351
351
|
return request.param
|
|
352
352
|
|
|
353
|
-
@pytest.fixture(params=
|
|
354
|
-
def
|
|
355
|
-
"""Parametrized fixture providing all
|
|
353
|
+
@pytest.fixture(params=('A000682', 'A005316'))
|
|
354
|
+
def oeisIDmeanders(request: pytest.FixtureRequest) -> Any:
|
|
355
|
+
"""Parametrized fixture providing all Meanders OEIS sequence identifiers.
|
|
356
356
|
|
|
357
|
-
|
|
357
|
+
Parameters
|
|
358
|
+
----------
|
|
359
|
+
request : pytest.FixtureRequest
|
|
360
|
+
The pytest request object containing the current parameter value.
|
|
361
|
+
|
|
362
|
+
Returns
|
|
363
|
+
-------
|
|
364
|
+
sequenceIdentifier : Any
|
|
365
|
+
OEIS sequence identifier for testing across all Meanders sequences.
|
|
366
|
+
|
|
367
|
+
"""
|
|
368
|
+
return request.param
|
|
369
|
+
|
|
370
|
+
@pytest.fixture(params=tuple(dictionaryOEIS.keys()))
|
|
371
|
+
def oeisIDother(request: pytest.FixtureRequest) -> Any:
|
|
372
|
+
"""Parametrized fixture providing all other OEIS sequence identifiers.
|
|
358
373
|
|
|
359
374
|
Parameters
|
|
360
375
|
----------
|
|
@@ -364,7 +379,7 @@ def oeisIDMeanders(request: pytest.FixtureRequest) -> Any:
|
|
|
364
379
|
Returns
|
|
365
380
|
-------
|
|
366
381
|
sequenceIdentifier : Any
|
|
367
|
-
OEIS sequence identifier for testing across all
|
|
382
|
+
OEIS sequence identifier for testing across all other sequences.
|
|
368
383
|
|
|
369
384
|
"""
|
|
370
385
|
return request.param
|
|
@@ -25,67 +25,48 @@ The `test_writeJobNumba` function shows how to test dynamically generated code,
|
|
|
25
25
|
which is useful if you're working with the code synthesis features of the package.
|
|
26
26
|
"""
|
|
27
27
|
|
|
28
|
-
from mapFolding import countFolds,
|
|
29
|
-
from mapFolding.
|
|
28
|
+
from mapFolding import countFolds, dictionaryOEIS, dictionaryOEISMapFolding, getFoldsTotalKnown, oeisIDfor_n
|
|
29
|
+
from mapFolding.basecamp import NOTcountingFolds
|
|
30
30
|
from mapFolding.dataBaskets import MapFoldingState
|
|
31
31
|
from mapFolding.someAssemblyRequired.RecipeJob import RecipeJobTheorem2
|
|
32
32
|
from mapFolding.someAssemblyRequired.toolkitNumba import parametersNumbaLight
|
|
33
33
|
from mapFolding.syntheticModules.initializeState import transitionOnGroupsOfFolds
|
|
34
34
|
from mapFolding.tests.conftest import registrarRecordsTemporaryFilesystemObject, standardizedEqualToCallableReturn
|
|
35
35
|
from pathlib import Path, PurePosixPath
|
|
36
|
-
from typing import TYPE_CHECKING
|
|
37
36
|
import importlib.util
|
|
38
37
|
import multiprocessing
|
|
39
38
|
import pytest
|
|
40
39
|
|
|
41
|
-
if TYPE_CHECKING:
|
|
42
|
-
from collections.abc import Callable
|
|
43
|
-
|
|
44
40
|
if __name__ == '__main__':
|
|
45
41
|
multiprocessing.set_start_method('spawn')
|
|
46
42
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
Tests the `oeisIDfor_n` function by comparing its calculated output against
|
|
51
|
-
known correct values from the OEIS database. This ensures that sequence
|
|
52
|
-
value computations remain mathematically accurate across code changes.
|
|
53
|
-
|
|
54
|
-
The test iterates through validation test cases defined in `settingsOEIS`
|
|
55
|
-
for the given OEIS sequence identifier, verifying that each computed value
|
|
56
|
-
matches its corresponding known reference value.
|
|
43
|
+
@pytest.mark.parametrize('flow', ['algorithm', 'asynchronous', 'asynchronousTheorem2', 'asynchronousTrimmed', 'numba', 'theorem2', 'theorem2Numba', 'theorem2Trimmed'])
|
|
44
|
+
def test_A007822(flow: str) -> None:
|
|
45
|
+
"""Test A007822 flow options.
|
|
57
46
|
|
|
58
47
|
Parameters
|
|
59
48
|
----------
|
|
60
|
-
|
|
61
|
-
The
|
|
49
|
+
flow : str
|
|
50
|
+
The computational flow algorithm to validate.
|
|
62
51
|
|
|
63
52
|
"""
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def test_aOFn_calculate_value_meanders(oeisIDMeanders: str) -> None:
|
|
68
|
-
"""Verify Meanders OEIS sequence value calculations against known reference values.
|
|
53
|
+
oeisID = 'A007822'
|
|
54
|
+
CPUlimit = .5
|
|
69
55
|
|
|
70
|
-
|
|
71
|
-
|
|
56
|
+
oeis_n = 2
|
|
57
|
+
for oeis_n in dictionaryOEIS[oeisID]['valuesTestValidation']:
|
|
58
|
+
if oeis_n < 2:
|
|
59
|
+
continue
|
|
72
60
|
|
|
73
|
-
|
|
74
|
-
----------
|
|
75
|
-
oeisIDMeanders : str
|
|
76
|
-
The Meanders OEIS sequence identifier to test calculations for.
|
|
61
|
+
expected = dictionaryOEIS[oeisID]['valuesKnown'][oeis_n]
|
|
77
62
|
|
|
78
|
-
"""
|
|
79
|
-
oeisIDcallable: Callable[[int], int] = getattr(oeisIDbyFormula, oeisIDMeanders)
|
|
80
|
-
for n in dictionaryOEISMeanders[oeisIDMeanders]['valuesTestValidation']:
|
|
81
63
|
standardizedEqualToCallableReturn(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
)
|
|
64
|
+
expected
|
|
65
|
+
, NOTcountingFolds, oeisID, oeis_n, flow, CPUlimit
|
|
66
|
+
)
|
|
86
67
|
|
|
87
68
|
@pytest.mark.parametrize('flow', ['daoOfMapFolding', 'numba', 'theorem2', 'theorem2Numba', 'theorem2Trimmed'])
|
|
88
|
-
def
|
|
69
|
+
def test_countFolds(mapShapeTestCountFolds: tuple[int, ...], flow: str) -> None:
|
|
89
70
|
"""Validate that different computational flows produce valid results.
|
|
90
71
|
|
|
91
72
|
(AI generated docstring)
|
|
@@ -105,40 +86,66 @@ def test_flowControl(mapShapeTestCountFolds: tuple[int, ...], flow: str) -> None
|
|
|
105
86
|
The computational flow algorithm to validate.
|
|
106
87
|
|
|
107
88
|
"""
|
|
108
|
-
standardizedEqualToCallableReturn(getFoldsTotalKnown(mapShapeTestCountFolds), countFolds, None, None, None, None, mapShapeTestCountFolds,
|
|
89
|
+
standardizedEqualToCallableReturn(getFoldsTotalKnown(mapShapeTestCountFolds), countFolds, None, None, None, None, mapShapeTestCountFolds, flow)
|
|
109
90
|
|
|
110
|
-
@pytest.mark.parametrize('flow', ['
|
|
111
|
-
def
|
|
112
|
-
"""
|
|
91
|
+
@pytest.mark.parametrize('flow', ['matrixNumPy', 'matrixPandas'])
|
|
92
|
+
def test_meanders(oeisIDmeanders: str, flow: str) -> None:
|
|
93
|
+
"""Verify Meanders OEIS sequence value calculations against known reference values.
|
|
94
|
+
|
|
95
|
+
Tests the functions in `mapFolding.algorithms.oeisIDbyFormula` by comparing their
|
|
96
|
+
calculated output against known correct values from the OEIS database for Meanders IDs.
|
|
113
97
|
|
|
114
98
|
Parameters
|
|
115
99
|
----------
|
|
116
|
-
|
|
117
|
-
The OEIS sequence identifier to test.
|
|
118
|
-
flow : str
|
|
119
|
-
The computational flow algorithm to validate.
|
|
100
|
+
oeisIDMeanders : str
|
|
101
|
+
The Meanders OEIS sequence identifier to test calculations for.
|
|
120
102
|
|
|
121
103
|
"""
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
104
|
+
dictionary = dictionaryOEISMapFolding if oeisIDmeanders in dictionaryOEISMapFolding else dictionaryOEIS
|
|
105
|
+
for n in dictionary[oeisIDmeanders]['valuesTestValidation']:
|
|
106
|
+
standardizedEqualToCallableReturn(
|
|
107
|
+
dictionary[oeisIDmeanders]['valuesKnown'][n]
|
|
108
|
+
, NOTcountingFolds, oeisIDmeanders, n, flow, None
|
|
109
|
+
)
|
|
127
110
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if oeis_n < 2:
|
|
131
|
-
continue
|
|
111
|
+
def test_NOTcountingFolds(oeisIDother: str) -> None:
|
|
112
|
+
"""Verify Meanders OEIS sequence value calculations against known reference values.
|
|
132
113
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
114
|
+
Tests the functions in `mapFolding.algorithms.oeisIDbyFormula` by comparing their
|
|
115
|
+
calculated output against known correct values from the OEIS database for Meanders IDs.
|
|
116
|
+
|
|
117
|
+
Parameters
|
|
118
|
+
----------
|
|
119
|
+
oeisIDMeanders : str
|
|
120
|
+
The Meanders OEIS sequence identifier to test calculations for.
|
|
137
121
|
|
|
122
|
+
"""
|
|
123
|
+
dictionary = dictionaryOEISMapFolding if oeisIDother in dictionaryOEISMapFolding else dictionaryOEIS
|
|
124
|
+
for n in dictionary[oeisIDother]['valuesTestValidation']:
|
|
138
125
|
standardizedEqualToCallableReturn(
|
|
139
|
-
|
|
140
|
-
,
|
|
141
|
-
|
|
126
|
+
dictionary[oeisIDother]['valuesKnown'][n]
|
|
127
|
+
, NOTcountingFolds, oeisIDother, n, None, None
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
def test_oeisIDfor_n(oeisIDmapFolding: str) -> None:
|
|
131
|
+
"""Verify OEIS sequence value calculations against known reference values.
|
|
132
|
+
|
|
133
|
+
Tests the `oeisIDfor_n` function by comparing its calculated output against
|
|
134
|
+
known correct values from the OEIS database. This ensures that sequence
|
|
135
|
+
value computations remain mathematically accurate across code changes.
|
|
136
|
+
|
|
137
|
+
The test iterates through validation test cases defined in `settingsOEIS`
|
|
138
|
+
for the given OEIS sequence identifier, verifying that each computed value
|
|
139
|
+
matches its corresponding known reference value.
|
|
140
|
+
|
|
141
|
+
Parameters
|
|
142
|
+
----------
|
|
143
|
+
oeisID : str
|
|
144
|
+
The OEIS sequence identifier to test calculations for.
|
|
145
|
+
|
|
146
|
+
"""
|
|
147
|
+
for n in dictionaryOEISMapFolding[oeisIDmapFolding]['valuesTestValidation']:
|
|
148
|
+
standardizedEqualToCallableReturn(dictionaryOEISMapFolding[oeisIDmapFolding]['valuesKnown'][n], oeisIDfor_n, oeisIDmapFolding, n)
|
|
142
149
|
|
|
143
150
|
@pytest.mark.parametrize('pathFilename_tmpTesting', ['.py'], indirect=True)
|
|
144
151
|
def test_writeJobNumba(oneTestCuzTestsOverwritingTests: tuple[int, ...], pathFilename_tmpTesting: Path) -> None:
|
mapFolding/tests/test_oeis.py
CHANGED
|
@@ -35,13 +35,13 @@ import random
|
|
|
35
35
|
import re as regex
|
|
36
36
|
import unittest.mock
|
|
37
37
|
|
|
38
|
-
def test__validateOEISid_valid_id(
|
|
39
|
-
standardizedEqualToCallableReturn(
|
|
38
|
+
def test__validateOEISid_valid_id(oeisIDmapFolding: str) -> None:
|
|
39
|
+
standardizedEqualToCallableReturn(oeisIDmapFolding, _standardizeOEISid, oeisIDmapFolding)
|
|
40
40
|
|
|
41
|
-
def test__validateOEISid_valid_id_case_insensitive(
|
|
42
|
-
standardizedEqualToCallableReturn(
|
|
43
|
-
standardizedEqualToCallableReturn(
|
|
44
|
-
standardizedEqualToCallableReturn(
|
|
41
|
+
def test__validateOEISid_valid_id_case_insensitive(oeisIDmapFolding: str) -> None:
|
|
42
|
+
standardizedEqualToCallableReturn(oeisIDmapFolding.upper(), _standardizeOEISid, oeisIDmapFolding.lower())
|
|
43
|
+
standardizedEqualToCallableReturn(oeisIDmapFolding.upper(), _standardizeOEISid, oeisIDmapFolding.upper())
|
|
44
|
+
standardizedEqualToCallableReturn(oeisIDmapFolding.upper(), _standardizeOEISid, oeisIDmapFolding.swapcase())
|
|
45
45
|
|
|
46
46
|
parameters_test_aOFn_invalid_n = [
|
|
47
47
|
(-random.randint(1, 100), "randomNegative"), # noqa: S311
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
"""I mean, you must write docstrings after you write the code because you don't know what the code will do until after you write it.
|
|
1
|
+
"""I mean, you must write docstrings after you write the code because you don't know what the code will do until after you write it.
|
|
2
|
+
|
|
3
|
+
I strongly suspect this directory will slowly evolve into an entire ecosystem of docstring tools.
|
|
4
|
+
"""
|
|
@@ -2,38 +2,37 @@
|
|
|
2
2
|
from astToolkit import Grab, IfThis, Make, NodeChanger, parsePathFilename2astModule, Then
|
|
3
3
|
from astToolkit.transformationTools import makeDictionaryFunctionDef
|
|
4
4
|
from hunterMakesPy import raiseIfNone, writeStringToHere
|
|
5
|
-
from mapFolding import
|
|
5
|
+
from mapFolding import dictionaryOEIS, dictionaryOEISMapFolding, packageSettings
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
import ast
|
|
8
8
|
|
|
9
|
+
# ----------------- General Settings ----------------------------------------------------------------------------------
|
|
9
10
|
sourcePrefix: str = 'zCuzDocStoopid'
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
pathFilenameSource: Path = next(iter(pathRoot.glob(f"{sourcePrefix}*.py"))).absolute()
|
|
14
|
-
pathFilenameWrite: Path = pathFilenameSource.with_stem(pathFilenameSource.stem.removeprefix(sourcePrefix))
|
|
15
|
-
|
|
16
|
-
astModule: ast.Module = parsePathFilename2astModule(pathFilenameSource)
|
|
17
|
-
dictionaryFunctionDef: dict[str, ast.FunctionDef] = makeDictionaryFunctionDef(astModule)
|
|
12
|
+
moduleWarning = "NOTE: This is a generated file; edit the source file."
|
|
18
13
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
def transformOEISidByFormula(pathFilenameSource: Path) -> None:
|
|
15
|
+
"""Transform the docstrings of functions corresponding to OEIS sequences."""
|
|
16
|
+
pathFilenameWrite: Path = pathFilenameSource.with_stem(pathFilenameSource.stem.removeprefix(sourcePrefix))
|
|
17
|
+
astModule: ast.Module = parsePathFilename2astModule(pathFilenameSource)
|
|
18
|
+
dictionaryFunctionDef: dict[str, ast.FunctionDef] = makeDictionaryFunctionDef(astModule)
|
|
22
19
|
|
|
23
|
-
oeisID = 'Error during transformation' # `ast.FunctionDef.name` of function in `pathFilenameSource`.
|
|
24
|
-
functionOf: str = 'Error during transformation' # The value of `functionOf` is in the docstring of function `oeisID` in `pathFilenameSource`.
|
|
20
|
+
oeisID = 'Error during transformation' # `ast.FunctionDef.name` of function in `pathFilenameSource`.
|
|
21
|
+
functionOf: str = 'Error during transformation' # The value of `functionOf` is in the docstring of function `oeisID` in `pathFilenameSource`.
|
|
25
22
|
|
|
26
|
-
for oeisID, FunctionDef in dictionaryFunctionDef.items():
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
for oeisID, FunctionDef in dictionaryFunctionDef.items():
|
|
24
|
+
if not oeisID.startswith('A') or not oeisID[1:7].isdigit():
|
|
25
|
+
continue
|
|
26
|
+
dictionary = dictionaryOEISMapFolding if oeisID in dictionaryOEISMapFolding else dictionaryOEIS
|
|
27
|
+
functionOf = raiseIfNone(ast.get_docstring(FunctionDef))
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
ImaDocstring= f"""
|
|
31
30
|
Compute {oeisID}(n) as a function of {functionOf}.
|
|
32
31
|
|
|
33
|
-
*The On-Line Encyclopedia of Integer Sequences* (OEIS) description of {oeisID} is: "{
|
|
32
|
+
*The On-Line Encyclopedia of Integer Sequences* (OEIS) description of {oeisID} is: "{dictionary[oeisID]['description']}"
|
|
34
33
|
|
|
35
|
-
The domain of {oeisID} starts at {
|
|
36
|
-
has not yet been computed is {
|
|
34
|
+
The domain of {oeisID} starts at {dictionary[oeisID]['offset']}, therefore for values of `n` < {dictionary[oeisID]['offset']}, a(n) is undefined. The smallest value of n for which a(n)
|
|
35
|
+
has not yet been computed is {dictionary[oeisID]['valueUnknown']}.
|
|
37
36
|
|
|
38
37
|
Parameters
|
|
39
38
|
----------
|
|
@@ -43,7 +42,7 @@ for oeisID, FunctionDef in dictionaryFunctionDef.items():
|
|
|
43
42
|
Returns
|
|
44
43
|
-------
|
|
45
44
|
a(n) : int
|
|
46
|
-
{
|
|
45
|
+
{dictionary[oeisID]['description']}
|
|
47
46
|
|
|
48
47
|
Would You Like to Know More?
|
|
49
48
|
----------------------------
|
|
@@ -51,13 +50,21 @@ for oeisID, FunctionDef in dictionaryFunctionDef.items():
|
|
|
51
50
|
https://oeis.org/{oeisID}
|
|
52
51
|
"""
|
|
53
52
|
|
|
54
|
-
|
|
53
|
+
astExprDocstring = Make.Expr(Make.Constant(ImaDocstring))
|
|
55
54
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
NodeChanger(
|
|
56
|
+
findThis = IfThis.isFunctionDefIdentifier(oeisID)
|
|
57
|
+
, doThat = Grab.bodyAttribute(Grab.index(0, Then.replaceWith(astExprDocstring)))
|
|
58
|
+
).visit(astModule)
|
|
60
59
|
|
|
61
|
-
ast.fix_missing_locations(astModule)
|
|
60
|
+
ast.fix_missing_locations(astModule)
|
|
62
61
|
|
|
63
|
-
|
|
62
|
+
docstringModule = raiseIfNone(ast.get_docstring(astModule))
|
|
63
|
+
moduleAsString = ast.unparse(astModule) + "\n"
|
|
64
|
+
moduleAsString = moduleAsString.replace(docstringModule,docstringModule + "\n\n" + moduleWarning)
|
|
65
|
+
|
|
66
|
+
writeStringToHere(moduleAsString, pathFilenameWrite)
|
|
67
|
+
|
|
68
|
+
pathRoot: Path = packageSettings.pathPackage / "algorithms"
|
|
69
|
+
pathFilenameSource: Path = next(iter(pathRoot.glob(f"{sourcePrefix}*.py"))).absolute()
|
|
70
|
+
transformOEISidByFormula(pathFilenameSource)
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mapFolding
|
|
3
|
+
Version: 0.16.2
|
|
4
|
+
Summary: Map folding, meanders, stamp folding, semi-meanders. Experiment with algorithm transformations, and analyze computational states.
|
|
5
|
+
Author-email: Hunter Hogan <HunterHogan@pm.me>
|
|
6
|
+
License: CC-BY-NC-4.0
|
|
7
|
+
Project-URL: Donate, https://www.patreon.com/integrated
|
|
8
|
+
Project-URL: Homepage, https://github.com/hunterhogan/mapFolding
|
|
9
|
+
Project-URL: Issues, https://github.com/hunterhogan/mapFolding/issues
|
|
10
|
+
Project-URL: Repository, https://github.com/hunterhogan/mapFolding.git
|
|
11
|
+
Keywords: A000136,A000560,A000682,A001010,A001011,A001415,A001416,A001417,A001418,A005315,A005316,A007822,A178961,A195646,A223094,A259702,A301620,AST manipulation,JIT compilation,Numba optimization,OEIS,Python optimization,abstract syntax tree,algorithmic combinatorics,algorithmic optimization,arch configurations,automated code generation,bit-packed arrays,bitwise state machines,cache-efficient algorithms,closed meandric numbers,code generation,code optimization,code synthesis,code transformation,codon optimization,combinatorial computing,combinatorial enumeration,combinatorial geometry,combinatorial mathematics,combinatorial problem solver,combinatorics,computational combinatorics,computational geometry,crossing patterns,curve crossings,dataclass transformation,discrete mathematics,dynamic compilation,enumerative combinatorics,folding pattern enumeration,folding problems,high-performance computing,integer sequences,just-in-time compilation,kernel optimization,labeled stamp folding,low-level computation,map folding,mapFolding,mathematical algorithms,mathematical modeling,mathematical optimization,mathematical patterns,mathematical software,mathematical tool,mathematical visualization,meander enumeration,meanders,meandric systems,memory-efficient enumeration,metaprogramming,numerical algorithms,numerical computation,open meandric systems,paper folding mathematics,parallel computing,pattern recognition,performance optimization,permutation patterns,permutations,post-setup optimization,pyproject,scientific computing,semi-meanders,sequence analysis,sequence calculator,sequence enumeration,sequence explorer,sequence generation,source code analysis,stamp folding,symbolic computation,symmetric foldings,topological combinatorics,topological patterns,typed Python
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: Education
|
|
16
|
+
Classifier: Intended Audience :: Science/Research
|
|
17
|
+
Classifier: Natural Language :: English
|
|
18
|
+
Classifier: Operating System :: MacOS
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
21
|
+
Classifier: Programming Language :: Python
|
|
22
|
+
Classifier: Programming Language :: Python :: 3
|
|
23
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
26
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
27
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
28
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
29
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
30
|
+
Classifier: Topic :: Software Development :: Compilers
|
|
31
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
32
|
+
Classifier: Topic :: Software Development :: Pre-processors
|
|
33
|
+
Classifier: Typing :: Typed
|
|
34
|
+
Requires-Python: >=3.12
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
License-File: LICENSE
|
|
37
|
+
Requires-Dist: astToolkit
|
|
38
|
+
Requires-Dist: autoflake
|
|
39
|
+
Requires-Dist: hunterMakesPy
|
|
40
|
+
Requires-Dist: isort
|
|
41
|
+
Requires-Dist: numpy
|
|
42
|
+
Requires-Dist: platformdirs
|
|
43
|
+
Provides-Extra: development
|
|
44
|
+
Requires-Dist: memray; sys_platform == "linux" and extra == "development"
|
|
45
|
+
Requires-Dist: mypy; extra == "development"
|
|
46
|
+
Requires-Dist: pyupgrade; extra == "development"
|
|
47
|
+
Requires-Dist: py-spy; extra == "development"
|
|
48
|
+
Requires-Dist: setuptools-scm; extra == "development"
|
|
49
|
+
Provides-Extra: numba
|
|
50
|
+
Requires-Dist: numba; extra == "numba"
|
|
51
|
+
Requires-Dist: numba_progress; extra == "numba"
|
|
52
|
+
Provides-Extra: pandas
|
|
53
|
+
Requires-Dist: pandas; extra == "pandas"
|
|
54
|
+
Requires-Dist: pyarrow; extra == "pandas"
|
|
55
|
+
Requires-Dist: pyarrow-stubs; extra == "pandas"
|
|
56
|
+
Provides-Extra: testing
|
|
57
|
+
Requires-Dist: numba; extra == "testing"
|
|
58
|
+
Requires-Dist: pandas; extra == "testing"
|
|
59
|
+
Requires-Dist: pyarrow; extra == "testing"
|
|
60
|
+
Requires-Dist: pytest-cov; extra == "testing"
|
|
61
|
+
Requires-Dist: pytest-env; extra == "testing"
|
|
62
|
+
Requires-Dist: pytest-xdist; extra == "testing"
|
|
63
|
+
Requires-Dist: pytest; extra == "testing"
|
|
64
|
+
Dynamic: license-file
|
|
65
|
+
|
|
66
|
+
# mapFolding
|
|
67
|
+
|
|
68
|
+
[](https://pypi.org/project/mapFolding/)
|
|
69
|
+
|
|
70
|
+
Map folding, meanders, stamp folding, semi-meanders. Experiment with algorithm transformations and code optimization.
|
|
71
|
+
|
|
72
|
+
I don't know how to write a README.md. Furthermore, the package used to be focused on multidimensional map folding and tools for transforming the algorithm to experiment with optimizations or to explore the algorithm.
|
|
73
|
+
|
|
74
|
+
First, the tools for transforming algorithms became far more sophisticated and powerful than this package. So I moved them to [astToolkit](https://github.com/hunterhogan/astToolkit). But those got so sophisticated, that I create more than half of that package through another layer of meta-programming: [astToolFactory](https://github.com/hunterhogan/astToolFactory).
|
|
75
|
+
|
|
76
|
+
Second, when I finally understood the connections between map folding and meanders, I added meanders to this package, and applied my transformation tools to that algorithm.
|
|
77
|
+
|
|
78
|
+
I used a weaker form of this package to [compute new terms for OEIS A001415](https://oeis.org/A001415), "Number of ways of folding a 2 X n strip of stamps."
|
|
79
|
+
There are cool and powerful tools in here, but as of 2025 September 17, I am dissatisfied with the organization and documentation. It's annoying.
|
|
80
|
+
|
|
81
|
+
## Finding stuff
|
|
82
|
+
|
|
83
|
+
1. At the moment, almost every algorithm version eventually runs through "mapFolding/basecamp.py", so it's sort of an overview and you can work backwards to find more details.
|
|
84
|
+
2. The directory "mapFolding/algorithms" only has "handmade" algorithms. Therefore, most logic for most computations is based on something in that directory.
|
|
85
|
+
3. The directory "mapFolding/syntheticModules" has code that is generated by the transformation tools.
|
|
86
|
+
4. Transformation functions are in "mapFolding/someAssemblyRequired."
|
|
87
|
+
5. The directory "mapFolding/reference" has "reference" materials.
|
|
88
|
+
6. "mapFolding/tests" has the tests, and I have tried to make it easy for you to add _your_ versions of the algorithms to the tests. Is it actually easy? I'll say it this way: if you were to create your own subclass of `ast.AST` it would be impossible for you to add your subclass to all of the `ast` module tests with just a few lines of code. In contrast, it is possible to fully test your algorithm with in my tests by adding between three and 25 lines of code. So, yeah, it's easy.
|
|
89
|
+
|
|
90
|
+
## Math and programming
|
|
91
|
+
|
|
92
|
+
I'm not a mathematician. I don't have training in or professional experience as a programmer. I'm not stupid: I'm ignorant.
|
|
93
|
+
|
|
94
|
+
## My recovery
|
|
95
|
+
|
|
96
|
+
[](https://HunterThinks.com/support)
|
|
97
|
+
[](https://www.youtube.com/@HunterHogan)
|
|
98
|
+
|
|
99
|
+
[](https://creativecommons.org/licenses/by-nc/4.0/)
|