mapFolding 0.15.4__py3-none-any.whl → 0.16.0__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 (58) hide show
  1. mapFolding/__init__.py +7 -9
  2. mapFolding/_theSSOT.py +1 -0
  3. mapFolding/algorithms/daoOfMapFolding.py +1 -2
  4. mapFolding/algorithms/getBucketsTotal.py +137 -0
  5. mapFolding/algorithms/matrixMeanders.py +457 -286
  6. mapFolding/algorithms/oeisIDbyFormula.py +310 -76
  7. mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +84 -0
  8. mapFolding/basecamp.py +99 -14
  9. mapFolding/dataBaskets.py +74 -0
  10. mapFolding/oeis.py +3 -2
  11. mapFolding/reference/A000682facts.py +662 -0
  12. mapFolding/reference/A005316facts.py +62 -0
  13. mapFolding/reference/matrixMeandersAnalysis/__init__.py +1 -0
  14. mapFolding/reference/matrixMeandersAnalysis/evenEven.py +144 -0
  15. mapFolding/reference/matrixMeandersAnalysis/oddEven.py +54 -0
  16. mapFolding/someAssemblyRequired/A007822/A007822rawMaterials.py +55 -0
  17. mapFolding/someAssemblyRequired/A007822/__init__.py +0 -0
  18. mapFolding/someAssemblyRequired/A007822/makeA007822AsynchronousModules.py +185 -0
  19. mapFolding/someAssemblyRequired/A007822/makeA007822Modules.py +71 -0
  20. mapFolding/someAssemblyRequired/RecipeJob.py +2 -2
  21. mapFolding/someAssemblyRequired/__init__.py +9 -2
  22. mapFolding/someAssemblyRequired/_toolIfThis.py +4 -3
  23. mapFolding/someAssemblyRequired/_toolkitContainers.py +8 -8
  24. mapFolding/someAssemblyRequired/infoBooth.py +27 -30
  25. mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +1 -1
  26. mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +5 -2
  27. mapFolding/someAssemblyRequired/makingModules_count.py +301 -0
  28. mapFolding/someAssemblyRequired/makingModules_doTheNeedful.py +120 -0
  29. mapFolding/someAssemblyRequired/mapFolding/__init__.py +0 -0
  30. mapFolding/someAssemblyRequired/mapFolding/makeMapFoldingModules.py +220 -0
  31. mapFolding/someAssemblyRequired/toolkitMakeModules.py +152 -0
  32. mapFolding/someAssemblyRequired/toolkitNumba.py +1 -1
  33. mapFolding/someAssemblyRequired/transformationTools.py +1 -0
  34. mapFolding/syntheticModules/A007822/__init__.py +1 -0
  35. mapFolding/syntheticModules/{algorithmA007822Numba.py → A007822/algorithmNumba.py} +2 -4
  36. mapFolding/syntheticModules/A007822/asynchronous.py +148 -0
  37. mapFolding/syntheticModules/A007822/asynchronousAnnex.py +68 -0
  38. mapFolding/syntheticModules/A007822/asynchronousTheorem2.py +53 -0
  39. mapFolding/syntheticModules/A007822/asynchronousTrimmed.py +47 -0
  40. mapFolding/syntheticModules/dataPackingA007822.py +1 -1
  41. mapFolding/tests/test_computations.py +2 -2
  42. mapFolding/trim_memory.py +62 -0
  43. mapFolding/zCuzDocStoopid/__init__.py +1 -0
  44. mapFolding/zCuzDocStoopid/makeDocstrings.py +63 -0
  45. {mapfolding-0.15.4.dist-info → mapfolding-0.16.0.dist-info}/METADATA +9 -2
  46. mapfolding-0.16.0.dist-info/RECORD +100 -0
  47. mapFolding/someAssemblyRequired/A007822rawMaterials.py +0 -46
  48. mapFolding/someAssemblyRequired/makeAllModules.py +0 -764
  49. mapfolding-0.15.4.dist-info/RECORD +0 -78
  50. /mapFolding/syntheticModules/{algorithmA007822.py → A007822/algorithm.py} +0 -0
  51. /mapFolding/syntheticModules/{initializeStateA007822.py → A007822/initializeState.py} +0 -0
  52. /mapFolding/syntheticModules/{theorem2A007822.py → A007822/theorem2.py} +0 -0
  53. /mapFolding/syntheticModules/{theorem2A007822Numba.py → A007822/theorem2Numba.py} +0 -0
  54. /mapFolding/syntheticModules/{theorem2A007822Trimmed.py → A007822/theorem2Trimmed.py} +0 -0
  55. {mapfolding-0.15.4.dist-info → mapfolding-0.16.0.dist-info}/WHEEL +0 -0
  56. {mapfolding-0.15.4.dist-info → mapfolding-0.16.0.dist-info}/entry_points.txt +0 -0
  57. {mapfolding-0.15.4.dist-info → mapfolding-0.16.0.dist-info}/licenses/LICENSE +0 -0
  58. {mapfolding-0.15.4.dist-info → mapfolding-0.16.0.dist-info}/top_level.txt +0 -0
mapFolding/basecamp.py CHANGED
@@ -1,9 +1,11 @@
1
1
  """Unified interface for map folding computation."""
2
2
 
3
3
  from collections.abc import Sequence
4
+ from functools import cache
4
5
  from mapFolding import (
5
- getPathFilenameFoldsTotal, packageSettings, saveFoldsTotal, saveFoldsTotalFAILearly, setProcessorLimit,
6
- validateListDimensions)
6
+ getPathFilenameFoldsTotal, MatrixMeandersState, packageSettings, saveFoldsTotal, saveFoldsTotalFAILearly,
7
+ setProcessorLimit, validateListDimensions)
8
+ from mapFolding.algorithms.matrixMeanders import doTheNeedful
7
9
  from os import PathLike
8
10
  from pathlib import PurePath
9
11
  import contextlib
@@ -12,11 +14,11 @@ import contextlib
12
14
 
13
15
  algorithms directory
14
16
  manually coded algorithms or formulas
15
- countFolds will be a stable interface for multidimensional map folding, including synthetic modules
17
+ `countFolds` will be a stable interface for multidimensional map folding, including synthetic modules
16
18
  This has special treatment because people may want to call mapShape not defined in OEIS
17
- countMeanders will be a stable interface for meanders
19
+ `countMeanders` will be a stable interface for meanders
18
20
  This has special treatment because people may want to call meanders not defined in OEIS
19
- an enhanced version of oeisIDfor_n will be a stable interface for calling by ID and n
21
+ an enhanced version of `oeisIDfor_n` will be a stable interface for calling by ID and n
20
22
 
21
23
  General flow structure
22
24
  doTheNeedful
@@ -60,6 +62,14 @@ General flow structure
60
62
 
61
63
  """
62
64
 
65
+ # Parameters
66
+ # What you want to compute
67
+ # Memorialization
68
+ # Concurrency
69
+ # How you want to compute it
70
+ # Interpretation of parameters
71
+ # Input data
72
+
63
73
  def countFolds(listDimensions: Sequence[int] | None = None
64
74
  , pathLikeWriteFoldsTotal: PathLike[str] | PurePath | None = None
65
75
  , computationDivisions: int | str | None = None
@@ -198,28 +208,63 @@ def countFolds(listDimensions: Sequence[int] | None = None
198
208
 
199
209
  """
200
210
  match flow:
211
+ case 'asynchronous':
212
+ from mapFolding.dataBaskets import MapFoldingState # noqa: PLC0415
213
+ mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
214
+
215
+ from mapFolding.syntheticModules.A007822.asynchronous import doTheNeedful # noqa: PLC0415
216
+ mapFoldingState = doTheNeedful(mapFoldingState)
217
+
218
+ case 'asynchronousTheorem2':
219
+ from mapFolding.dataBaskets import MapFoldingState # noqa: PLC0415
220
+ mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
221
+
222
+ from mapFolding.syntheticModules.A007822.initializeState import transitionOnGroupsOfFolds # noqa: PLC0415
223
+ mapFoldingState = transitionOnGroupsOfFolds(mapFoldingState)
224
+
225
+ from mapFolding.syntheticModules.A007822.asynchronousAnnex import initializeConcurrencyManager # noqa: PLC0415
226
+ initializeConcurrencyManager(groupsOfFolds=mapFoldingState.groupsOfFolds)
227
+ mapFoldingState.groupsOfFolds = 0
228
+
229
+ from mapFolding.syntheticModules.A007822.asynchronousTheorem2 import count # noqa: PLC0415
230
+ mapFoldingState = count(mapFoldingState)
231
+
232
+ case 'asynchronousTrimmed':
233
+ from mapFolding.dataBaskets import MapFoldingState # noqa: PLC0415
234
+ mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
235
+
236
+ from mapFolding.syntheticModules.A007822.initializeState import transitionOnGroupsOfFolds # noqa: PLC0415
237
+ mapFoldingState = transitionOnGroupsOfFolds(mapFoldingState)
238
+
239
+ from mapFolding.syntheticModules.A007822.asynchronousAnnex import initializeConcurrencyManager # noqa: PLC0415
240
+ initializeConcurrencyManager(groupsOfFolds=mapFoldingState.groupsOfFolds)
241
+ mapFoldingState.groupsOfFolds = 0
242
+
243
+ from mapFolding.syntheticModules.A007822.asynchronousTrimmed import count # noqa: PLC0415
244
+ mapFoldingState = count(mapFoldingState)
245
+
201
246
  case 'numba':
202
247
  from mapFolding.dataBaskets import MapFoldingState # noqa: PLC0415
203
248
  mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
204
249
 
205
- from mapFolding.syntheticModules.algorithmA007822Numba import doTheNeedful # noqa: PLC0415
250
+ from mapFolding.syntheticModules.A007822.algorithmNumba import doTheNeedful # noqa: PLC0415
206
251
  mapFoldingState = doTheNeedful(mapFoldingState)
207
252
 
208
253
  case 'theorem2':
209
254
  from mapFolding.dataBaskets import MapFoldingState # noqa: PLC0415
210
255
  mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
211
256
 
212
- from mapFolding.syntheticModules.initializeStateA007822 import transitionOnGroupsOfFolds # noqa: PLC0415
257
+ from mapFolding.syntheticModules.A007822.initializeState import transitionOnGroupsOfFolds # noqa: PLC0415
213
258
  mapFoldingState = transitionOnGroupsOfFolds(mapFoldingState)
214
259
 
215
- from mapFolding.syntheticModules.theorem2A007822 import count # noqa: PLC0415
260
+ from mapFolding.syntheticModules.A007822.theorem2 import count # noqa: PLC0415
216
261
  mapFoldingState = count(mapFoldingState)
217
262
 
218
263
  case 'theorem2Numba':
219
264
  from mapFolding.dataBaskets import MapFoldingState # noqa: PLC0415
220
265
  mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
221
266
 
222
- from mapFolding.syntheticModules.initializeStateA007822 import transitionOnGroupsOfFolds # noqa: PLC0415
267
+ from mapFolding.syntheticModules.A007822.initializeState import transitionOnGroupsOfFolds # noqa: PLC0415
223
268
  mapFoldingState = transitionOnGroupsOfFolds(mapFoldingState)
224
269
 
225
270
  from mapFolding.syntheticModules.dataPackingA007822 import sequential # noqa: PLC0415
@@ -229,17 +274,17 @@ def countFolds(listDimensions: Sequence[int] | None = None
229
274
  from mapFolding.dataBaskets import MapFoldingState # noqa: PLC0415
230
275
  mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
231
276
 
232
- from mapFolding.syntheticModules.initializeStateA007822 import transitionOnGroupsOfFolds # noqa: PLC0415
277
+ from mapFolding.syntheticModules.A007822.initializeState import transitionOnGroupsOfFolds # noqa: PLC0415
233
278
  mapFoldingState = transitionOnGroupsOfFolds(mapFoldingState)
234
279
 
235
- from mapFolding.syntheticModules.theorem2A007822Trimmed import count # noqa: PLC0415
280
+ from mapFolding.syntheticModules.A007822.theorem2Trimmed import count # noqa: PLC0415
236
281
  mapFoldingState = count(mapFoldingState)
237
282
 
238
283
  case _:
239
284
  from mapFolding.dataBaskets import MapFoldingState # noqa: PLC0415
240
285
  mapFoldingState: MapFoldingState = MapFoldingState(mapShape)
241
286
 
242
- from mapFolding.syntheticModules.algorithmA007822 import doTheNeedful # noqa: PLC0415
287
+ from mapFolding.syntheticModules.A007822.algorithm import doTheNeedful # noqa: PLC0415
243
288
  mapFoldingState = doTheNeedful(mapFoldingState)
244
289
 
245
290
  foldsTotal = mapFoldingState.groupsOfFolds
@@ -302,8 +347,8 @@ def countFolds(listDimensions: Sequence[int] | None = None
302
347
 
303
348
  from mapFolding.syntheticModules.countParallelNumba import doTheNeedful # noqa: PLC0415
304
349
 
305
- # `listStatesParallel` exists in case you want to research the parallel computation.
306
- foldsTotal, listStatesParallel = doTheNeedful(parallelMapFoldingState, concurrencyLimit) # pyright: ignore[reportUnusedVariable]
350
+ # `listStatesParallel` exists so you can research the parallel computation.
351
+ foldsTotal, listStatesParallel = doTheNeedful(parallelMapFoldingState, concurrencyLimit) # pyright: ignore[reportUnusedVariable] # noqa: RUF059
307
352
 
308
353
  else:
309
354
  from mapFolding.dataBaskets import MapFoldingState # noqa: PLC0415
@@ -319,3 +364,43 @@ def countFolds(listDimensions: Sequence[int] | None = None
319
364
  saveFoldsTotal(pathFilenameFoldsTotal, foldsTotal)
320
365
 
321
366
  return foldsTotal
367
+
368
+ @cache
369
+ def A000682(n: int) -> int:
370
+ """Compute A000682(n)."""
371
+ oeisID = 'A000682'
372
+
373
+ kOfMatrix: int = n - 1
374
+
375
+ if n & 0b1:
376
+ curveLocations: int = 5
377
+ else:
378
+ curveLocations = 1
379
+ listCurveLocations: list[int] = [(curveLocations << 1) | curveLocations]
380
+
381
+ MAXIMUMcurveLocations: int = 1 << (2 * kOfMatrix + 4)
382
+ while listCurveLocations[-1] < MAXIMUMcurveLocations:
383
+ curveLocations = (curveLocations << 4) | 0b101 # == curveLocations * 2**4 + 5
384
+ listCurveLocations.append((curveLocations << 1) | curveLocations)
385
+
386
+ dictionaryCurveLocations=dict.fromkeys(listCurveLocations, 1)
387
+
388
+ state = MatrixMeandersState(n, oeisID, kOfMatrix, dictionaryCurveLocations)
389
+
390
+ return doTheNeedful(state)
391
+
392
+ @cache
393
+ def A005316(n: int) -> int:
394
+ """Compute A005316(n)."""
395
+ oeisID = 'A005316'
396
+
397
+ kOfMatrix: int = n - 1
398
+
399
+ if n & 0b1:
400
+ dictionaryCurveLocations: dict[int, int] = {15: 1}
401
+ else:
402
+ dictionaryCurveLocations = {22: 1}
403
+
404
+ state = MatrixMeandersState(n, oeisID, kOfMatrix, dictionaryCurveLocations)
405
+
406
+ return doTheNeedful(state)
mapFolding/dataBaskets.py CHANGED
@@ -24,6 +24,7 @@ from mapFolding import (
24
24
  Array1DElephino, Array1DLeavesTotal, Array3DLeavesTotal, DatatypeElephino, DatatypeFoldsTotal, DatatypeLeavesTotal,
25
25
  getConnectionGraph, getLeavesTotal, makeDataContainer)
26
26
  import dataclasses
27
+ import numpy
27
28
 
28
29
  @dataclasses.dataclass
29
30
  class MapFoldingState:
@@ -268,3 +269,76 @@ class LeafSequenceState(MapFoldingState):
268
269
  if self.leafSequence is None: # pyright: ignore[reportUnnecessaryComparison]
269
270
  self.leafSequence = makeDataContainer(groupsOfFoldsKnown, self.__dataclass_fields__['leafSequence'].metadata['dtype'])
270
271
  self.leafSequence[self.groupsOfFolds] = self.leaf1ndex
272
+
273
+
274
+ @dataclasses.dataclass
275
+ class MatrixMeandersState:
276
+ """State."""
277
+
278
+ n: int
279
+ oeisID: str
280
+ kOfMatrix: int
281
+ dictionaryCurveLocations: dict[int, int]
282
+
283
+ datatypeCurveLocations: type = numpy.uint64
284
+ datatypeDistinctCrossings: type = numpy.uint64
285
+
286
+ bitWidthCurveLocationsMaximum: int | None = None
287
+ bitWidthDistinctCrossingsMaximum: int | None = None
288
+
289
+ bitWidth: int = 0
290
+ indexStartAnalyzed: int = 0
291
+
292
+ def __post_init__(self) -> None:
293
+ """Post init."""
294
+ if self.bitWidthCurveLocationsMaximum is None:
295
+ _bitWidthOfFixedSizeInteger: int = numpy.dtype(self.datatypeCurveLocations).itemsize * 8 # bits
296
+
297
+ _offsetNecessary: int = 3 # For example, `groupZulu << 3`.
298
+ _offsetSafety: int = 1 # I don't have mathematical proof of how many extra bits I need.
299
+ _offset: int = _offsetNecessary + _offsetSafety
300
+
301
+ self.bitWidthCurveLocationsMaximum = _bitWidthOfFixedSizeInteger - _offset
302
+
303
+ del _bitWidthOfFixedSizeInteger, _offsetNecessary, _offsetSafety, _offset
304
+
305
+ if self.bitWidthDistinctCrossingsMaximum is None:
306
+ _bitWidthOfFixedSizeInteger: int = numpy.dtype(self.datatypeDistinctCrossings).itemsize * 8 # bits
307
+
308
+ _offsetNecessary: int = 0 # I don't know of any.
309
+ _offsetEstimation: int = 3 # See reference directory.
310
+ _offsetSafety: int = 1
311
+ _offset: int = _offsetNecessary + _offsetEstimation + _offsetSafety
312
+
313
+ self.bitWidthDistinctCrossingsMaximum = _bitWidthOfFixedSizeInteger - _offset
314
+
315
+ del _bitWidthOfFixedSizeInteger, _offsetNecessary, _offsetEstimation, _offsetSafety, _offset
316
+
317
+ @property
318
+ def MAXIMUMcurveLocations(self) -> int:
319
+ """Compute the maximum value of `curveLocations` for the current iteration of the transfer matrix."""
320
+ return 1 << (2 * self.kOfMatrix + 4)
321
+
322
+ @property
323
+ def locatorGroupAlpha(self) -> int:
324
+ """Compute an odd-parity bit-mask with `bitWidth` bits.
325
+
326
+ Notes
327
+ -----
328
+ In binary, `locatorGroupAlpha` has alternating 0s and 1s and ends with a 1, such as '101', '0101', and '10101'. The last
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
+
mapFolding/oeis.py CHANGED
@@ -418,9 +418,10 @@ def oeisIDfor_n(oeisID: str, n: int) -> int:
418
418
  message = f"OEIS sequence {oeisID} is not defined at {n = }."
419
419
  raise ArithmeticError(message)
420
420
  foldsTotal: int = dictionaryOEISMapFolding[oeisID]['valuesKnown'][n]
421
- return foldsTotal
421
+ else:
422
+ foldsTotal = countFolds(oeisID=oeisID, oeis_n=n)
422
423
 
423
- return countFolds(mapShape, oeisID=oeisID)
424
+ return foldsTotal
424
425
 
425
426
  def OEIS_for_n() -> None:
426
427
  """Command-line interface for calculating OEIS sequence values.