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
mapFolding/dataBaskets.py
CHANGED
|
@@ -23,10 +23,12 @@ access patterns that enable efficient result persistence and retrieval.
|
|
|
23
23
|
from mapFolding import (
|
|
24
24
|
Array1DElephino, Array1DLeavesTotal, Array3DLeavesTotal, DatatypeElephino, DatatypeFoldsTotal, DatatypeLeavesTotal,
|
|
25
25
|
getConnectionGraph, getLeavesTotal, makeDataContainer)
|
|
26
|
+
from numpy.typing import NDArray
|
|
27
|
+
from typing import TypeAlias
|
|
26
28
|
import dataclasses
|
|
27
29
|
import numpy
|
|
28
30
|
|
|
29
|
-
@dataclasses.dataclass
|
|
31
|
+
@dataclasses.dataclass(slots=True)
|
|
30
32
|
class MapFoldingState:
|
|
31
33
|
"""Core computational state for map folding algorithms.
|
|
32
34
|
|
|
@@ -155,8 +157,8 @@ class MapFoldingState:
|
|
|
155
157
|
if self.leafComparison is None: self.leafComparison = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafComparison'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
|
|
156
158
|
|
|
157
159
|
@dataclasses.dataclass
|
|
158
|
-
class ParallelMapFoldingState(MapFoldingState):
|
|
159
|
-
"""
|
|
160
|
+
class ParallelMapFoldingState(MapFoldingState): # This identifier because of `dataclassIdentifierParallel: identifierDotAttribute = 'Parallel' + dataclassIdentifier`.
|
|
161
|
+
"""Computational state for task division operations.
|
|
160
162
|
|
|
161
163
|
(AI generated docstring)
|
|
162
164
|
|
|
@@ -270,75 +272,99 @@ class LeafSequenceState(MapFoldingState):
|
|
|
270
272
|
self.leafSequence = makeDataContainer(groupsOfFoldsKnown, self.__dataclass_fields__['leafSequence'].metadata['dtype'])
|
|
271
273
|
self.leafSequence[self.groupsOfFolds] = self.leaf1ndex
|
|
272
274
|
|
|
273
|
-
|
|
274
|
-
@dataclasses.dataclass
|
|
275
|
+
@dataclasses.dataclass(slots=True)
|
|
275
276
|
class MatrixMeandersState:
|
|
276
|
-
"""
|
|
277
|
+
"""Hold the state of a meanders transfer matrix algorithm computation."""
|
|
277
278
|
|
|
278
279
|
n: int
|
|
280
|
+
"""The index of the meanders problem being solved."""
|
|
279
281
|
oeisID: str
|
|
280
|
-
|
|
281
|
-
|
|
282
|
+
"""'A000682', semi-meanders, or 'A005316', meanders."""
|
|
283
|
+
boundary: int
|
|
284
|
+
"""The algorithm analyzes `n` boundaries starting at `boundary = n - 1`."""
|
|
285
|
+
dictionaryMeanders: dict[int, int]
|
|
286
|
+
"""A Python `dict` (*dict*ionary) of `arcCode` to `crossings`. The values are stored as Python `int`
|
|
287
|
+
(*int*eger), which may be arbitrarily large. Because of that property, `int` may also be called a 'bignum' (big *num*ber) or
|
|
288
|
+
'bigint' (big *int*eger)."""
|
|
282
289
|
|
|
283
|
-
|
|
284
|
-
|
|
290
|
+
bitWidth: int = 0
|
|
291
|
+
"""At the start of an iteration enumerated by `boundary`, the number of bits of the largest value `arcCode`. The
|
|
292
|
+
`dataclass` computes a `property` from `bitWidth`."""
|
|
285
293
|
|
|
286
|
-
|
|
287
|
-
|
|
294
|
+
@property
|
|
295
|
+
def MAXIMUMarcCode(self) -> int:
|
|
296
|
+
"""Compute the maximum value of `arcCode` for the current iteration of the transfer matrix."""
|
|
297
|
+
return 1 << (2 * self.boundary + 4)
|
|
288
298
|
|
|
289
|
-
|
|
290
|
-
|
|
299
|
+
@property
|
|
300
|
+
def locatorBits(self) -> int:
|
|
301
|
+
"""Compute an odd-parity bit-mask with `bitWidth` bits.
|
|
302
|
+
|
|
303
|
+
Notes
|
|
304
|
+
-----
|
|
305
|
+
In binary, `locatorBitsAlpha` has alternating 0s and 1s and ends with a 1, such as '101', '0101', and '10101'. The last
|
|
306
|
+
digit is in the 1's column, but programmers usually call it the "least significant bit" (LSB). If we count the columns
|
|
307
|
+
from the right, the 1's column is column 1, the 2's column is column 2, the 4's column is column 3, and so on. When
|
|
308
|
+
counting this way, `locatorBitsAlpha` has 1s in the columns with odd index numbers. Mathematicians and programmers,
|
|
309
|
+
therefore, tend to call `locatorBitsAlpha` something like the "odd bit-mask", the "odd-parity numbers", or simply "odd
|
|
310
|
+
mask" or "odd numbers". In addition to "odd" being inherently ambiguous in this context, this algorithm also segregates
|
|
311
|
+
odd numbers from even numbers, so I avoid using "odd" and "even" in the names of these bit-masks.
|
|
312
|
+
|
|
313
|
+
"""
|
|
314
|
+
return sum(1 << one for one in range(0, self.bitWidth, 2))
|
|
315
|
+
|
|
316
|
+
@dataclasses.dataclass(slots=True)
|
|
317
|
+
class MatrixMeandersNumPyState(MatrixMeandersState):
|
|
318
|
+
"""Hold the state of a meanders transfer matrix algorithm computation."""
|
|
319
|
+
|
|
320
|
+
arrayArcCodes: NDArray[numpy.uint64] = dataclasses.field(default_factory=lambda: numpy.empty((0,), dtype=numpy.uint64))
|
|
321
|
+
arrayCrossings: NDArray[numpy.uint64] = dataclasses.field(default_factory=lambda: numpy.empty((0,), dtype=numpy.uint64))
|
|
322
|
+
|
|
323
|
+
bitWidthLimitArcCode: int | None = None
|
|
324
|
+
bitWidthLimitCrossings: int | None = None
|
|
325
|
+
|
|
326
|
+
datatypeArcCode: TypeAlias = numpy.uint64 # noqa: UP040
|
|
327
|
+
"""The fixed-size integer type used to store `arcCode`."""
|
|
328
|
+
datatypeCrossings: TypeAlias = numpy.uint64 # noqa: UP040
|
|
329
|
+
"""The fixed-size integer type used to store `crossings`."""
|
|
330
|
+
|
|
331
|
+
indexTarget: int = 0
|
|
332
|
+
"""What is being indexed depends on the algorithm flavor."""
|
|
291
333
|
|
|
292
334
|
def __post_init__(self) -> None:
|
|
293
335
|
"""Post init."""
|
|
294
|
-
if self.
|
|
295
|
-
_bitWidthOfFixedSizeInteger: int = numpy.dtype(self.
|
|
336
|
+
if self.bitWidthLimitArcCode is None:
|
|
337
|
+
_bitWidthOfFixedSizeInteger: int = numpy.dtype(self.datatypeArcCode).itemsize * 8 # bits
|
|
296
338
|
|
|
297
|
-
_offsetNecessary: int = 3 # For example, `
|
|
339
|
+
_offsetNecessary: int = 3 # For example, `bitsZulu << 3`.
|
|
298
340
|
_offsetSafety: int = 1 # I don't have mathematical proof of how many extra bits I need.
|
|
299
341
|
_offset: int = _offsetNecessary + _offsetSafety
|
|
300
342
|
|
|
301
|
-
self.
|
|
343
|
+
self.bitWidthLimitArcCode = _bitWidthOfFixedSizeInteger - _offset
|
|
302
344
|
|
|
303
345
|
del _bitWidthOfFixedSizeInteger, _offsetNecessary, _offsetSafety, _offset
|
|
304
346
|
|
|
305
|
-
if self.
|
|
306
|
-
_bitWidthOfFixedSizeInteger: int = numpy.dtype(self.
|
|
347
|
+
if self.bitWidthLimitCrossings is None:
|
|
348
|
+
_bitWidthOfFixedSizeInteger: int = numpy.dtype(self.datatypeCrossings).itemsize * 8 # bits
|
|
307
349
|
|
|
308
350
|
_offsetNecessary: int = 0 # I don't know of any.
|
|
309
351
|
_offsetEstimation: int = 3 # See reference directory.
|
|
310
352
|
_offsetSafety: int = 1
|
|
311
353
|
_offset: int = _offsetNecessary + _offsetEstimation + _offsetSafety
|
|
312
354
|
|
|
313
|
-
self.
|
|
355
|
+
self.bitWidthLimitCrossings = _bitWidthOfFixedSizeInteger - _offset
|
|
314
356
|
|
|
315
357
|
del _bitWidthOfFixedSizeInteger, _offsetNecessary, _offsetEstimation, _offsetSafety, _offset
|
|
316
358
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
def
|
|
324
|
-
"""
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
digit is in the 1's column, but programmers usually call it the "least significant bit" (LSB). If we count the columns
|
|
330
|
-
from the right, the 1's column is column 1, the 2's column is column 2, the 4's column is column 3, and so on. When
|
|
331
|
-
counting this way, `locatorGroupAlpha` has 1s in the columns with odd index numbers. Mathematicians and programmers,
|
|
332
|
-
therefore, tend to call `locatorGroupAlpha` something like the "odd bit-mask", the "odd-parity numbers", or simply "odd
|
|
333
|
-
mask" or "odd numbers". In addition to "odd" being inherently ambiguous in this context, this algorithm also segregates
|
|
334
|
-
odd numbers from even numbers, so I avoid using "odd" and "even" in the names of these bit-masks.
|
|
335
|
-
|
|
336
|
-
"""
|
|
337
|
-
return sum(1 << one for one in range(0, self.bitWidth, 2))
|
|
338
|
-
|
|
339
|
-
@property
|
|
340
|
-
def locatorGroupZulu(self) -> int:
|
|
341
|
-
"""Compute an even-parity bit-mask with `bitWidth` bits."""
|
|
342
|
-
return sum(1 << one for one in range(1, self.bitWidth, 2))
|
|
343
|
-
|
|
344
|
-
|
|
359
|
+
def makeDictionary(self) -> None:
|
|
360
|
+
"""Convert from NumPy `ndarray` (*Num*erical *Py*thon *n-d*imensional array) to Python `dict` (*dict*ionary)."""
|
|
361
|
+
self.dictionaryMeanders = {int(key): int(value) for key, value in zip(self.arrayArcCodes, self.arrayCrossings, strict=True)}
|
|
362
|
+
self.arrayArcCodes = numpy.empty((0,), dtype=self.datatypeArcCode)
|
|
363
|
+
self.arrayCrossings = numpy.empty((0,), dtype=self.datatypeCrossings)
|
|
364
|
+
|
|
365
|
+
def makeArray(self) -> None:
|
|
366
|
+
"""Convert from Python `dict` (*dict*ionary) to NumPy `ndarray` (*Num*erical *Py*thon *n-d*imensional array)."""
|
|
367
|
+
self.arrayArcCodes = numpy.array(list(self.dictionaryMeanders.keys()), dtype=self.datatypeArcCode)
|
|
368
|
+
self.arrayCrossings = numpy.array(list(self.dictionaryMeanders.values()), dtype=self.datatypeCrossings)
|
|
369
|
+
self.bitWidth = int(self.arrayArcCodes.max()).bit_length()
|
|
370
|
+
self.dictionaryMeanders = {}
|
mapFolding/oeis.py
CHANGED
|
@@ -27,7 +27,7 @@ completes the journey from configuration foundation to mathematical discovery.
|
|
|
27
27
|
from datetime import datetime, timedelta, UTC
|
|
28
28
|
from hunterMakesPy import writeStringToHere
|
|
29
29
|
from itertools import chain
|
|
30
|
-
from mapFolding import countFolds,
|
|
30
|
+
from mapFolding import countFolds, MetadataOEISid, MetadataOEISidMapFolding, packageSettings
|
|
31
31
|
from mapFolding._theSSOT import pathCache
|
|
32
32
|
from pathlib import Path
|
|
33
33
|
from typing import Final
|
|
@@ -248,7 +248,7 @@ def getOEISidInformation(oeisID: str) -> tuple[str, int]:
|
|
|
248
248
|
description: str = ' '.join(listDescriptionDeconstructed)
|
|
249
249
|
return description, offset
|
|
250
250
|
|
|
251
|
-
def
|
|
251
|
+
def _makeDictionaryOEISMapFolding() -> dict[str, MetadataOEISidMapFolding]:
|
|
252
252
|
"""Construct the comprehensive settings dictionary for all implemented OEIS sequences.
|
|
253
253
|
|
|
254
254
|
(AI generated docstring)
|
|
@@ -287,8 +287,8 @@ def _makeDictionaryOEIS() -> dict[str, MetadataOEISidMapFolding]:
|
|
|
287
287
|
)
|
|
288
288
|
return dictionaryOEIS
|
|
289
289
|
|
|
290
|
-
dictionaryOEISMapFolding: dict[str, MetadataOEISidMapFolding] =
|
|
291
|
-
"""Metadata for each OEIS
|
|
290
|
+
dictionaryOEISMapFolding: dict[str, MetadataOEISidMapFolding] = _makeDictionaryOEISMapFolding()
|
|
291
|
+
"""Metadata for each MapFolding OEIS ID."""
|
|
292
292
|
|
|
293
293
|
def makeDictionaryFoldsTotalKnown() -> dict[tuple[int, ...], int]:
|
|
294
294
|
"""Make a `mapShape` to known `foldsTotal` dictionary.
|
|
@@ -419,7 +419,7 @@ def oeisIDfor_n(oeisID: str, n: int) -> int:
|
|
|
419
419
|
raise ArithmeticError(message)
|
|
420
420
|
foldsTotal: int = dictionaryOEISMapFolding[oeisID]['valuesKnown'][n]
|
|
421
421
|
else:
|
|
422
|
-
foldsTotal = countFolds(
|
|
422
|
+
foldsTotal = countFolds(mapShape=mapShape)
|
|
423
423
|
|
|
424
424
|
return foldsTotal
|
|
425
425
|
|
|
@@ -467,27 +467,6 @@ def OEIS_for_n() -> None:
|
|
|
467
467
|
timeElapsed: float = time.perf_counter() - timeStart
|
|
468
468
|
print(f"Time elapsed: {timeElapsed:.3f} seconds") # noqa: T201
|
|
469
469
|
|
|
470
|
-
def clearOEIScache() -> None:
|
|
471
|
-
"""Delete all cached OEIS sequence files from the local cache directory.
|
|
472
|
-
|
|
473
|
-
(AI generated docstring)
|
|
474
|
-
|
|
475
|
-
This function removes all cached OEIS data files, including both sequence value files (b-files)
|
|
476
|
-
and metadata files, forcing fresh retrieval from the OEIS website on the next access. This is
|
|
477
|
-
useful for clearing stale cache data or troubleshooting network-related issues.
|
|
478
|
-
|
|
479
|
-
The function safely handles missing files and provides user feedback about the cache clearing
|
|
480
|
-
operation. If the cache directory does not exist, an informative message is displayed.
|
|
481
|
-
|
|
482
|
-
"""
|
|
483
|
-
if not pathCache.exists():
|
|
484
|
-
print(f"Cache directory, {pathCache}, not found - nothing to clear.") # noqa: T201
|
|
485
|
-
return
|
|
486
|
-
for oeisID in dictionaryOEISMapFolding:
|
|
487
|
-
( pathCache / f"{oeisID}.txt" ).unlink(missing_ok=True)
|
|
488
|
-
( pathCache / _getFilenameOEISbFile(oeisID) ).unlink(missing_ok=True)
|
|
489
|
-
print(f"Cache cleared from {pathCache}") # noqa: T201
|
|
490
|
-
|
|
491
470
|
def getOEISids() -> None:
|
|
492
471
|
"""Display comprehensive information about all implemented OEIS sequences.
|
|
493
472
|
|
|
@@ -504,21 +483,21 @@ def getOEISids() -> None:
|
|
|
504
483
|
"""
|
|
505
484
|
print(_formatHelpText()) # noqa: T201
|
|
506
485
|
|
|
507
|
-
def
|
|
508
|
-
dictionary: dict[str,
|
|
509
|
-
for oeisID in packageSettings.
|
|
486
|
+
def _makeDictionaryOEIS() -> dict[str, MetadataOEISid]:
|
|
487
|
+
dictionary: dict[str, MetadataOEISid] = {}
|
|
488
|
+
for oeisID in packageSettings.OEISidManuallySet:
|
|
510
489
|
valuesKnownSherpa: dict[int, int] = getOEISidValues(oeisID)
|
|
511
490
|
descriptionSherpa, offsetSherpa = getOEISidInformation(oeisID)
|
|
512
|
-
dictionary[oeisID] =
|
|
491
|
+
dictionary[oeisID] = MetadataOEISid(
|
|
513
492
|
description=descriptionSherpa,
|
|
514
493
|
offset=offsetSherpa,
|
|
515
494
|
valuesKnown=valuesKnownSherpa,
|
|
516
|
-
valuesTestValidation=packageSettings.
|
|
495
|
+
valuesTestValidation=[*(packageSettings.OEISidManuallySet[oeisID]['valuesTestValidation']), offsetSherpa],
|
|
517
496
|
valueUnknown=max(valuesKnownSherpa.keys(), default=0) + 1,
|
|
518
497
|
)
|
|
519
498
|
return dictionary
|
|
520
499
|
|
|
521
|
-
|
|
500
|
+
dictionaryOEIS: dict[str, MetadataOEISid] = _makeDictionaryOEIS()
|
|
522
501
|
|
|
523
502
|
if __name__ == "__main__":
|
|
524
503
|
getOEISids()
|