mapFolding 0.17.1__py3-none-any.whl → 0.18.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.
- easyRun/NOTcountingFolds.py +7 -11
- easyRun/countFolds.py +11 -10
- easyRun/meanders.py +6 -8
- mapFolding/__init__.py +24 -36
- mapFolding/_e/Z0Z_analysisPython/SORTZ0Z_hypothesis.py +189 -0
- mapFolding/_e/Z0Z_analysisPython/SORTZ0Z_p2d6.py +143 -0
- mapFolding/_e/Z0Z_analysisPython/__init__.py +4 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/__init__.py +0 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200.py +369 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/2001.py +694 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/270/211.py +514 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/270/2111.py +480 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/214.py +511 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/2141.py +515 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/214/344/270/211.py +485 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/214/344/270/2111.py +442 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/211.py +313 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/2111.py +343 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/214.py +400 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/2141.py +497 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/214/344/270/211.py +463 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/214/344/270/2111.py +441 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266.py +35 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/2661.py +35 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200.py +382 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/2001.py +630 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/270/211.py +488 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/270/2111.py +475 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/214.py +473 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/2141.py +500 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211.py +465 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111.py +439 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/211.py +599 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/2111.py +536 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/214.py +506 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/2141.py +533 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/214/344/270/211.py +489 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/214/344/270/2111.py +474 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2001.py +2158 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2001Negative.py +2158 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200Negative.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/211.py +1397 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/2111.py +1291 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/2111Negative.py +1291 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/211Negative.py +1397 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214.py +1240 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/2141.py +1420 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/2141Negative.py +1420 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214Negative.py +1240 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/211.py +1366 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/2111.py +1274 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/2111Negative.py +1274 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/211Negative.py +1366 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/211.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2111.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2111Negative.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/211Negative.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214.py +1102 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/2141.py +1422 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/2141Negative.py +1422 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214Negative.py +1102 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/211.py +1240 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/2111.py +1228 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/2111Negative.py +1228 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/211Negative.py +1240 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266.py +32 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/2661.py +1162 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/2661Negative.py +1162 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266Negative.py +32 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2001.py +1926 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2001Negative.py +1926 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200Negative.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/211.py +1291 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/2111.py +1176 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/2111Negative.py +1176 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/211Negative.py +1291 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214.py +1228 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/2141.py +1324 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/2141Negative.py +1324 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214Negative.py +1228 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211.py +1274 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111.py +1038 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111Negative.py +1038 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211Negative.py +1274 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/211.py +2158 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2111.py +1926 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2111Negative.py +1926 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/211Negative.py +2158 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214.py +1422 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/2141.py +1364 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/2141Negative.py +1364 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214Negative.py +1422 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/211.py +1420 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/2111.py +1324 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/2111Negative.py +1324 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/211Negative.py +1420 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200.py +3133 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2001.py +6039 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2001Negative.py +6039 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200Negative.py +3133 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/211.py +3527 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/2111.py +2300 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/2111Negative.py +2300 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/211Negative.py +3527 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214.py +3597 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/2141.py +3317 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/2141Negative.py +3317 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214Negative.py +3597 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/211.py +3161 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/2111.py +2877 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/2111Negative.py +2877 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/211Negative.py +3161 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/211.py +2981 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2111.py +3055 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2111Negative.py +3055 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/211Negative.py +2981 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214.py +3221 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/2141.py +3988 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/2141Negative.py +3988 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214Negative.py +3221 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/211.py +3652 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/2111.py +2863 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/2111Negative.py +2863 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/211Negative.py +3652 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200.py +2485 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2001.py +4566 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2001Negative.py +4566 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200Negative.py +2485 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/211.py +3006 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/2111.py +2485 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/2111Negative.py +2485 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/211Negative.py +3006 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214.py +3304 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/2141.py +3015 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/2141Negative.py +3015 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214Negative.py +3304 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211.py +2939 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111.py +2589 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111Negative.py +2589 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211Negative.py +2939 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/211.py +3899 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2111.py +2996 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2111Negative.py +2996 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/211Negative.py +3899 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214.py +3223 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/2141.py +3020 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/2141Negative.py +3020 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214Negative.py +3223 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/211.py +3250 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/2111.py +2667 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/2111Negative.py +2667 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/211Negative.py +3250 -0
- mapFolding/_e/Z0Z_analysisPython/measure.py +162 -0
- mapFolding/_e/Z0Z_analysisPython/positionAnalysis.py +403 -0
- mapFolding/_e/Z0Z_analysisPython/positionAnalysisPileRanges2d6.py +110 -0
- mapFolding/_e/Z0Z_analysisPython/theExcluderBeast.py +640 -0
- mapFolding/_e/Z0Z_analysisPython/toolkit.py +166 -0
- mapFolding/_e/Z0Z_analysisPython/toolkitCSVsequences.py +188 -0
- mapFolding/_e/Z0Z_analysisPython/workBenchPatternFinder.py +284 -0
- mapFolding/_e/Z0Z_notes/__init__.py +0 -0
- mapFolding/_e/Z0Z_notes/knowledgeDump.py +214 -0
- mapFolding/_e/__init__.py +45 -0
- mapFolding/_e/_beDRY.py +547 -0
- mapFolding/_e/_dataDynamic.py +1164 -0
- mapFolding/_e/_measure.py +579 -0
- mapFolding/_e/_semiotics.py +363 -0
- mapFolding/_e/_theTypes.py +31 -0
- mapFolding/_e/algorithms/__init__.py +1 -0
- mapFolding/_e/algorithms/constraintPropagation.py +158 -0
- mapFolding/_e/algorithms/elimination.py +118 -0
- mapFolding/_e/algorithms/eliminationCrease.py +66 -0
- mapFolding/_e/algorithms/iff.py +584 -0
- mapFolding/_e/basecamp.py +89 -0
- mapFolding/_e/dataBaskets.py +123 -0
- mapFolding/_e/dataRaw/__init__.py +0 -0
- mapFolding/_e/easyRun/__init__.py +0 -0
- mapFolding/_e/easyRun/eliminateFolds.py +72 -0
- mapFolding/_e/easyRun/pinning.py +62 -0
- mapFolding/_e/filters.py +384 -0
- mapFolding/_e/pin2/344/270/212nDimensions.py +882 -0
- mapFolding/_e/pin2/344/270/212nDimensionsAnnex.py +551 -0
- mapFolding/_e/pin2/344/270/212nDimensionsByCrease.py +190 -0
- mapFolding/_e/pin2/344/270/212nDimensionsByDomain.py +459 -0
- mapFolding/_e/pinIt.py +436 -0
- mapFolding/_semiotics.py +42 -0
- mapFolding/_theSSOT.py +11 -56
- mapFolding/_theTypes.py +52 -67
- mapFolding/algorithms/matrixMeandersNumPyndas.py +18 -18
- mapFolding/algorithms/oeisIDbyFormula.py +4 -4
- mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +3 -3
- mapFolding/basecamp.py +11 -80
- mapFolding/beDRY.py +107 -111
- mapFolding/dataBaskets.py +0 -56
- mapFolding/filesystemToolkit.py +15 -11
- mapFolding/oeis.py +17 -16
- mapFolding/reference/matrixMeandersAnalysis/prefixNotationNotes.py +2 -2
- mapFolding/reference/meandersDumpingGround/matrixMeandersBaselineV2.py +0 -1
- mapFolding/reference/meandersDumpingGround/matrixMeandersNumPyV1finalForm.py +8 -10
- mapFolding/someAssemblyRequired/RecipeJob.py +5 -5
- mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +5 -2
- mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +9 -11
- mapFolding/someAssemblyRequired/mapFoldingModules/makeMapFoldingModules.py +2 -1
- mapFolding/someAssemblyRequired/transformationTools.py +1 -1
- mapFolding/tests/Z0Z_test_e_excluder.py +155 -0
- mapFolding/tests/conftest.py +193 -314
- mapFolding/tests/dataSamples/A001417.py +455 -0
- mapFolding/tests/dataSamples/__init__.py +1 -0
- mapFolding/tests/dataSamples/measurementData.py +1818 -0
- mapFolding/tests/dataSamples/p2DnDomain3_2_/351/246/226/344/270/200_/351/246/226/351/233/266/344/270/200.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain3_/351/246/226/344/270/200.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain5_4.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain6_5.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain6_7_5_4.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain7_6.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain/351/246/226/344/272/214_/351/246/226/351/233/266/344/270/200/344/272/214.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain/351/246/226/344/272/214_/351/246/226/351/233/266/344/272/214_/351/246/226/351/233/266/344/270/200/344/272/214_/351/246/226/344/270/200/344/272/214.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain/351/246/226/351/233/266/344/270/200/344/272/214_/351/246/226/344/270/200/344/272/214.py +15 -0
- mapFolding/tests/dataSamples/p2DnDomain/351/246/226/351/233/266/344/272/214_/351/246/226/344/272/214.py +15 -0
- mapFolding/tests/dataSamples/semioticsData.py +135 -0
- mapFolding/tests/test_computations.py +134 -80
- mapFolding/tests/test_e_computations.py +42 -0
- mapFolding/tests/test_e_dataDynamic.py +189 -0
- mapFolding/tests/test_e_measurements.py +257 -0
- mapFolding/tests/test_e_pinning.py +61 -0
- mapFolding/tests/test_e_semiotics.py +128 -0
- mapFolding/tests/test_filesystem.py +39 -17
- mapFolding/tests/{test_other.py → test_parameterValidation.py} +3 -3
- mapFolding/tests/{test_tasks.py → test_taskDivisions.py} +42 -23
- mapFolding/zCuzDocStoopid/makeDocstrings.py +3 -2
- {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/METADATA +11 -8
- mapfolding-0.18.0.dist-info/RECORD +305 -0
- {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/WHEEL +1 -1
- easyRun/eliminateFolds.py +0 -60
- mapFolding/algorithms/constraintPropagation.py +0 -184
- mapFolding/algorithms/elimination.py +0 -131
- mapFolding/algorithms/eliminationCount.py +0 -26
- mapFolding/algorithms/eliminationPinned.py +0 -35
- mapFolding/algorithms/iff.py +0 -206
- mapFolding/algorithms/patternFinder.py +0 -280
- mapFolding/algorithms/pinning2Dn.py +0 -345
- mapFolding/algorithms/pinning2DnAnnex.py +0 -43
- mapFolding/tests/verify.py +0 -323
- mapfolding-0.17.1.dist-info/RECORD +0 -112
- {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/top_level.txt +0 -0
mapFolding/beDRY.py
CHANGED
|
@@ -1,40 +1,103 @@
|
|
|
1
1
|
"""Oft-needed computations or actions, especially for multi-dimensional map folding."""
|
|
2
2
|
|
|
3
|
-
from collections.abc import
|
|
3
|
+
from collections.abc import Sequence
|
|
4
4
|
from functools import cache
|
|
5
|
-
from hunterMakesPy import defineConcurrencyLimit, intInnit, oopsieKwargsie
|
|
6
|
-
from mapFolding import NumPyIntegerType
|
|
7
|
-
from more_itertools import extract
|
|
5
|
+
from hunterMakesPy.parseParameters import defineConcurrencyLimit, intInnit, oopsieKwargsie
|
|
6
|
+
from mapFolding import Array1DLeavesTotal, Array2DLeavesTotal, Array3DLeavesTotal, inclusive, NumPyIntegerType
|
|
8
7
|
from numpy import dtype as numpy_dtype, int64 as numpy_int64, ndarray
|
|
9
8
|
from sys import maxsize as sysMaxsize
|
|
10
9
|
from typing import Any
|
|
11
10
|
import numpy
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
"""Yield items from `iterable` whose positions are not in `indices`."""
|
|
15
|
-
lengthIterable: int = len(iterable)
|
|
16
|
-
def normalizeIndex(index: int) -> int:
|
|
17
|
-
if index < 0:
|
|
18
|
-
index = (index + lengthIterable) % lengthIterable
|
|
19
|
-
return index
|
|
20
|
-
indicesInclude: list[int] = sorted(set(range(lengthIterable)).difference(map(normalizeIndex, indices)))
|
|
21
|
-
return extract(iterable, indicesInclude)
|
|
12
|
+
#======== Flow control ======================================
|
|
22
13
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
14
|
+
def defineProcessorLimit(CPUlimit: Any | None, concurrencyPackage: str | None = None) -> int:
|
|
15
|
+
"""Compute the CPU usage limit for concurrent operations; for `numba` managed concurrency, set the global limit.
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
CPUlimit : Any | None
|
|
20
|
+
Please see the documentation in `countFolds` for details. I know it is annoying, but I want to be sure you
|
|
21
|
+
have the most accurate information.
|
|
22
|
+
concurrencyPackage : str | None = None
|
|
23
|
+
Specifies which concurrency package to use.
|
|
24
|
+
- `None` or `'multiprocessing'`: Uses standard `multiprocessing`.
|
|
25
|
+
- `'numba'`: Uses Numba's threading system.
|
|
26
|
+
|
|
27
|
+
Returns
|
|
28
|
+
-------
|
|
29
|
+
concurrencyLimit : int
|
|
30
|
+
The actual concurrency limit that was set.
|
|
31
|
+
|
|
32
|
+
Raises
|
|
33
|
+
------
|
|
34
|
+
TypeError
|
|
35
|
+
If `CPUlimit` is not of the expected types.
|
|
36
|
+
NotImplementedError
|
|
37
|
+
If `concurrencyPackage` is not supported.
|
|
38
|
+
|
|
39
|
+
Notes
|
|
40
|
+
-----
|
|
41
|
+
If using `'numba'` as the concurrency package, the maximum number of processors is retrieved from
|
|
42
|
+
`numba.get_num_threads()` rather than by polling the hardware. If Numba environment variables limit available
|
|
43
|
+
processors, that will affect this function.
|
|
44
|
+
|
|
45
|
+
When using Numba, this function must be called before importing any Numba-jitted function for this processor limit
|
|
46
|
+
to affect the Numba-jitted function.
|
|
47
|
+
|
|
48
|
+
"""
|
|
49
|
+
# TODO How do I clarify the type and sanitize the value of CPUlimit?
|
|
50
|
+
if not (CPUlimit is None or isinstance(CPUlimit, (bool, int, float))):
|
|
51
|
+
CPUlimit = oopsieKwargsie(CPUlimit)
|
|
52
|
+
|
|
53
|
+
match concurrencyPackage:
|
|
54
|
+
case 'numba':
|
|
55
|
+
from numba import get_num_threads, set_num_threads # noqa: PLC0415
|
|
56
|
+
concurrencyLimit: int = defineConcurrencyLimit(limit=CPUlimit, cpuTotal=get_num_threads())
|
|
57
|
+
set_num_threads(concurrencyLimit)
|
|
58
|
+
concurrencyLimit = get_num_threads()
|
|
59
|
+
case 'multiprocessing' | None | _:
|
|
60
|
+
concurrencyLimit = defineConcurrencyLimit(limit=CPUlimit)
|
|
61
|
+
return concurrencyLimit
|
|
26
62
|
|
|
27
|
-
|
|
63
|
+
#======== map folding ===================================
|
|
64
|
+
|
|
65
|
+
def getConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int, datatype: type[NumPyIntegerType]) -> ndarray[tuple[int, int, int], numpy_dtype[NumPyIntegerType]]:
|
|
66
|
+
"""Create a properly typed connection graph for the map folding algorithm.
|
|
28
67
|
|
|
29
68
|
Parameters
|
|
30
69
|
----------
|
|
31
70
|
mapShape : tuple[int, ...]
|
|
32
71
|
A tuple of integers representing the dimensions of the map.
|
|
72
|
+
leavesTotal : int
|
|
73
|
+
The total number of leaves in the map.
|
|
74
|
+
datatype : type[NumPyIntegerType]
|
|
75
|
+
The NumPy integer type to use for the array elements, ensuring proper memory usage and compatibility with the
|
|
76
|
+
computation state.
|
|
77
|
+
|
|
78
|
+
Returns
|
|
79
|
+
-------
|
|
80
|
+
connectionGraph : ndarray[tuple[int, int, int], numpy_dtype[NumPyIntegerType]]
|
|
81
|
+
A 3D NumPy array with shape (`dimensionsTotal`, `leavesTotal`+1, `leavesTotal`+1) with the specified `datatype`,
|
|
82
|
+
representing all possible connections between leaves.
|
|
83
|
+
|
|
84
|
+
"""
|
|
85
|
+
connectionGraph: Array3DLeavesTotal = _makeConnectionGraph(mapShape, leavesTotal)
|
|
86
|
+
return connectionGraph.astype(datatype)
|
|
87
|
+
|
|
88
|
+
@cache
|
|
89
|
+
def getLeavesTotal(mapShape: tuple[int, ...]) -> int:
|
|
90
|
+
"""The definitive calculation of the total number of leaves in a map with the given dimensions.
|
|
91
|
+
|
|
92
|
+
Parameters
|
|
93
|
+
----------
|
|
94
|
+
mapShape : tuple[int, ...]
|
|
95
|
+
A tuple of integers with the length of each dimension of the map.
|
|
33
96
|
|
|
34
97
|
Returns
|
|
35
98
|
-------
|
|
36
99
|
leavesTotal : int
|
|
37
|
-
The total number of leaves in the map
|
|
100
|
+
The definitive total number of leaves in the map.
|
|
38
101
|
|
|
39
102
|
Raises
|
|
40
103
|
------
|
|
@@ -42,12 +105,18 @@ def getLeavesTotal(mapShape: tuple[int, ...]) -> int:
|
|
|
42
105
|
If the product of dimensions would exceed the system's maximum integer size. This check prevents silent numeric
|
|
43
106
|
overflow issues that could lead to incorrect results.
|
|
44
107
|
|
|
108
|
+
Notes
|
|
109
|
+
-----
|
|
110
|
+
It is impossible to overstate the importance of `leavesTotal` in every algorithm for counting folds. Therefore, in this
|
|
111
|
+
package, this function is the ***only*** permissible way to compute `leavesTotal`.
|
|
112
|
+
|
|
113
|
+
The total number of leaves is the product of all dimensions in `mapShape`.
|
|
45
114
|
"""
|
|
46
115
|
productDimensions = 1
|
|
47
116
|
for dimension in mapShape:
|
|
48
117
|
# NOTE this check is one-degree short of absurd, but three lines of early absurdity is better than invalid output later. I'd add more checks if I could think of more.
|
|
49
118
|
if dimension > sysMaxsize // productDimensions:
|
|
50
|
-
message = f"I received `{dimension = }` in `{mapShape = }`, but the product of the dimensions exceeds the maximum size of an integer on this system."
|
|
119
|
+
message: str = f"I received `{dimension = }` in `{mapShape = }`, but the product of the dimensions exceeds the maximum size of an integer on this system."
|
|
51
120
|
raise OverflowError(message)
|
|
52
121
|
productDimensions *= dimension
|
|
53
122
|
return productDimensions
|
|
@@ -90,18 +159,18 @@ def getTaskDivisions(computationDivisions: int | str | None, concurrencyLimit: i
|
|
|
90
159
|
strComputationDivisions = strComputationDivisions.lower()
|
|
91
160
|
match strComputationDivisions:
|
|
92
161
|
case 'maximum':
|
|
93
|
-
taskDivisions = leavesTotal
|
|
162
|
+
taskDivisions: int = leavesTotal
|
|
94
163
|
case 'cpu':
|
|
95
164
|
taskDivisions = min(concurrencyLimit, leavesTotal)
|
|
96
165
|
case _:
|
|
97
|
-
message = f"I received '{strComputationDivisions}' for the parameter, `computationDivisions`, but the string value is not supported."
|
|
166
|
+
message: str = f"I received '{strComputationDivisions}' for the parameter, `computationDivisions`, but the string value is not supported."
|
|
98
167
|
raise ValueError(message)
|
|
99
168
|
case _:
|
|
100
169
|
message = f"I received {computationDivisions} for the parameter, `computationDivisions`, but the type {type(computationDivisions).__name__} is not supported."
|
|
101
170
|
raise ValueError(message)
|
|
102
171
|
|
|
103
172
|
if taskDivisions > leavesTotal:
|
|
104
|
-
message = f"Problem: `{taskDivisions = }`, is greater than `{leavesTotal = }`, which will cause duplicate counting of the folds.\n\nChallenge: you cannot directly set `taskDivisions` or `leavesTotal`: they are derived from parameters that may or may not be named `computationDivisions`, `CPUlimit` , and `listDimensions` and from my dubious-quality Python code."
|
|
173
|
+
message = f"Problem: `{taskDivisions = }`, is greater than `{leavesTotal = }`, which will cause duplicate counting of the folds.\n\nChallenge: you cannot directly set `taskDivisions` or `leavesTotal`: they are derived from parameters that may or may not be named `computationDivisions`, `CPUlimit` , and `listDimensions` and from my dubious-quality Python code."
|
|
105
174
|
raise ValueError(message)
|
|
106
175
|
return int(max(0, taskDivisions))
|
|
107
176
|
|
|
@@ -130,22 +199,22 @@ def _makeConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int) -> ndarray
|
|
|
130
199
|
conditions, and dimensional constraints.
|
|
131
200
|
|
|
132
201
|
"""
|
|
133
|
-
dimensionsTotal = len(mapShape)
|
|
134
|
-
cumulativeProduct = numpy.multiply.accumulate([1, *list(mapShape)], dtype=numpy_int64)
|
|
135
|
-
arrayDimensions = numpy.array(mapShape, dtype=numpy_int64)
|
|
136
|
-
coordinateSystem = numpy.zeros((dimensionsTotal, leavesTotal + 1), dtype=numpy_int64)
|
|
202
|
+
dimensionsTotal: int = len(mapShape)
|
|
203
|
+
cumulativeProduct: Array1DLeavesTotal = numpy.multiply.accumulate([1, *list(mapShape)], dtype=numpy_int64)
|
|
204
|
+
arrayDimensions: Array1DLeavesTotal = numpy.array(mapShape, dtype=numpy_int64)
|
|
205
|
+
coordinateSystem: Array2DLeavesTotal = numpy.zeros((dimensionsTotal, leavesTotal + 1), dtype=numpy_int64)
|
|
137
206
|
for indexDimension in range(dimensionsTotal):
|
|
138
|
-
for leaf1ndex in range(1, leavesTotal +
|
|
207
|
+
for leaf1ndex in range(1, leavesTotal + inclusive):
|
|
139
208
|
coordinateSystem[indexDimension, leaf1ndex] = (((leaf1ndex - 1) // cumulativeProduct[indexDimension]) % arrayDimensions[indexDimension] + 1)
|
|
140
209
|
|
|
141
|
-
connectionGraph = numpy.zeros((dimensionsTotal, leavesTotal + 1, leavesTotal + 1), dtype=numpy_int64)
|
|
210
|
+
connectionGraph: Array3DLeavesTotal = numpy.zeros((dimensionsTotal, leavesTotal + 1, leavesTotal + 1), dtype=numpy_int64)
|
|
142
211
|
for indexDimension in range(dimensionsTotal):
|
|
143
|
-
for activeLeaf1ndex in range(1, leavesTotal +
|
|
144
|
-
for connectee1ndex in range(1, activeLeaf1ndex +
|
|
145
|
-
isFirstCoord = coordinateSystem[indexDimension, connectee1ndex] == 1
|
|
146
|
-
isLastCoord = coordinateSystem[indexDimension, connectee1ndex] == arrayDimensions[indexDimension]
|
|
147
|
-
exceedsActive = connectee1ndex + cumulativeProduct[indexDimension] > activeLeaf1ndex
|
|
148
|
-
isEvenParity = (coordinateSystem[indexDimension, activeLeaf1ndex] & 1) == (coordinateSystem[indexDimension, connectee1ndex] & 1)
|
|
212
|
+
for activeLeaf1ndex in range(1, leavesTotal + inclusive):
|
|
213
|
+
for connectee1ndex in range(1, activeLeaf1ndex + inclusive):
|
|
214
|
+
isFirstCoord: bool = coordinateSystem[indexDimension, connectee1ndex] == 1
|
|
215
|
+
isLastCoord: bool = coordinateSystem[indexDimension, connectee1ndex] == arrayDimensions[indexDimension]
|
|
216
|
+
exceedsActive: bool = connectee1ndex + cumulativeProduct[indexDimension] > activeLeaf1ndex
|
|
217
|
+
isEvenParity: bool = (coordinateSystem[indexDimension, activeLeaf1ndex] & 1) == (coordinateSystem[indexDimension, connectee1ndex] & 1)
|
|
149
218
|
|
|
150
219
|
if (isEvenParity and isFirstCoord) or (not isEvenParity and (isLastCoord or exceedsActive)):
|
|
151
220
|
connectionGraph[indexDimension, activeLeaf1ndex, connectee1ndex] = connectee1ndex
|
|
@@ -155,29 +224,6 @@ def _makeConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int) -> ndarray
|
|
|
155
224
|
connectionGraph[indexDimension, activeLeaf1ndex, connectee1ndex] = connectee1ndex + cumulativeProduct[indexDimension]
|
|
156
225
|
return connectionGraph
|
|
157
226
|
|
|
158
|
-
def getConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int, datatype: type[NumPyIntegerType]) -> ndarray[tuple[int, int, int], numpy_dtype[NumPyIntegerType]]:
|
|
159
|
-
"""Create a properly typed connection graph for the map folding algorithm.
|
|
160
|
-
|
|
161
|
-
Parameters
|
|
162
|
-
----------
|
|
163
|
-
mapShape : tuple[int, ...]
|
|
164
|
-
A tuple of integers representing the dimensions of the map.
|
|
165
|
-
leavesTotal : int
|
|
166
|
-
The total number of leaves in the map.
|
|
167
|
-
datatype : type[NumPyIntegerType]
|
|
168
|
-
The NumPy integer type to use for the array elements, ensuring proper memory usage and compatibility with the
|
|
169
|
-
computation state.
|
|
170
|
-
|
|
171
|
-
Returns
|
|
172
|
-
-------
|
|
173
|
-
connectionGraph : ndarray[tuple[int, int, int], numpy_dtype[NumPyIntegerType]]
|
|
174
|
-
A 3D NumPy array with shape (`dimensionsTotal`, `leavesTotal`+1, `leavesTotal`+1) with the specified `datatype`,
|
|
175
|
-
representing all possible connections between leaves.
|
|
176
|
-
|
|
177
|
-
"""
|
|
178
|
-
connectionGraph = _makeConnectionGraph(mapShape, leavesTotal)
|
|
179
|
-
return connectionGraph.astype(datatype)
|
|
180
|
-
|
|
181
227
|
def makeDataContainer(shape: int | tuple[int, ...], datatype: type[NumPyIntegerType]) -> ndarray[Any, numpy_dtype[NumPyIntegerType]]:
|
|
182
228
|
"""Create any data container as long as it is a `numpy.ndarray` full of zeroes of type `numpy.integer`.
|
|
183
229
|
|
|
@@ -198,59 +244,6 @@ def makeDataContainer(shape: int | tuple[int, ...], datatype: type[NumPyIntegerT
|
|
|
198
244
|
"""
|
|
199
245
|
return numpy.zeros(shape, dtype=datatype)
|
|
200
246
|
|
|
201
|
-
def setProcessorLimit(CPUlimit: Any | None, concurrencyPackage: str | None = None) -> int:
|
|
202
|
-
"""Set the CPU usage limit for concurrent operations.
|
|
203
|
-
|
|
204
|
-
Parameters
|
|
205
|
-
----------
|
|
206
|
-
CPUlimit : Any | None
|
|
207
|
-
Please see the documentation in `countFolds` for details. I know it is annoying, but I want to be sure you
|
|
208
|
-
have the most accurate information.
|
|
209
|
-
concurrencyPackage : str | None = None
|
|
210
|
-
Specifies which concurrency package to use.
|
|
211
|
-
- `None` or `'multiprocessing'`: Uses standard `multiprocessing`.
|
|
212
|
-
- `'numba'`: Uses Numba's threading system.
|
|
213
|
-
|
|
214
|
-
Returns
|
|
215
|
-
-------
|
|
216
|
-
concurrencyLimit : int
|
|
217
|
-
The actual concurrency limit that was set.
|
|
218
|
-
|
|
219
|
-
Raises
|
|
220
|
-
------
|
|
221
|
-
TypeError
|
|
222
|
-
If `CPUlimit` is not of the expected types.
|
|
223
|
-
NotImplementedError
|
|
224
|
-
If `concurrencyPackage` is not supported.
|
|
225
|
-
|
|
226
|
-
Notes
|
|
227
|
-
-----
|
|
228
|
-
If using `'numba'` as the concurrency package, the maximum number of processors is retrieved from
|
|
229
|
-
`numba.get_num_threads()` rather than by polling the hardware. If Numba environment variables limit available
|
|
230
|
-
processors, that will affect this function.
|
|
231
|
-
|
|
232
|
-
When using Numba, this function must be called before importing any Numba-jitted function for this processor limit
|
|
233
|
-
to affect the Numba-jitted function.
|
|
234
|
-
|
|
235
|
-
"""
|
|
236
|
-
if not (CPUlimit is None or isinstance(CPUlimit, (bool, int, float))):
|
|
237
|
-
CPUlimit = oopsieKwargsie(CPUlimit)
|
|
238
|
-
|
|
239
|
-
match concurrencyPackage:
|
|
240
|
-
case 'multiprocessing' | None:
|
|
241
|
-
# When to use multiprocessing.set_start_method
|
|
242
|
-
# https://github.com/hunterhogan/mapFolding/issues/6 # noqa: ERA001
|
|
243
|
-
concurrencyLimit: int = defineConcurrencyLimit(limit=CPUlimit)
|
|
244
|
-
case 'numba':
|
|
245
|
-
from numba import get_num_threads, set_num_threads # noqa: PLC0415
|
|
246
|
-
concurrencyLimit = defineConcurrencyLimit(limit=CPUlimit, cpuTotal=get_num_threads())
|
|
247
|
-
set_num_threads(concurrencyLimit)
|
|
248
|
-
concurrencyLimit = get_num_threads()
|
|
249
|
-
case _:
|
|
250
|
-
message = f"I received `{concurrencyPackage = }` but I don't know what to do with that."
|
|
251
|
-
raise NotImplementedError(message)
|
|
252
|
-
return concurrencyLimit
|
|
253
|
-
|
|
254
247
|
def validateListDimensions(listDimensions: Sequence[int]) -> tuple[int, ...]:
|
|
255
248
|
"""Validate and normalize dimensions for a map folding problem.
|
|
256
249
|
|
|
@@ -279,7 +272,7 @@ def validateListDimensions(listDimensions: Sequence[int]) -> tuple[int, ...]:
|
|
|
279
272
|
|
|
280
273
|
"""
|
|
281
274
|
if not listDimensions:
|
|
282
|
-
message = "`listDimensions` is a required parameter."
|
|
275
|
+
message: str = "`listDimensions` is a required parameter."
|
|
283
276
|
raise ValueError(message)
|
|
284
277
|
listOFint: list[int] = intInnit(listDimensions, 'listDimensions')
|
|
285
278
|
mapDimensions: list[int] = []
|
|
@@ -307,3 +300,6 @@ def validateListDimensions(listDimensions: Sequence[int]) -> tuple[int, ...]:
|
|
|
307
300
|
"""
|
|
308
301
|
# NOTE Do NOT sort the dimensions.
|
|
309
302
|
return tuple(mapDimensions)
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
|
mapFolding/dataBaskets.py
CHANGED
|
@@ -25,62 +25,6 @@ from mapFolding import (
|
|
|
25
25
|
getConnectionGraph, getLeavesTotal, makeDataContainer)
|
|
26
26
|
import dataclasses
|
|
27
27
|
|
|
28
|
-
@dataclasses.dataclass(slots=True)
|
|
29
|
-
class EliminationState:
|
|
30
|
-
"""Computational state for algorithms to compute foldsTotal by elimination.
|
|
31
|
-
|
|
32
|
-
Attributes
|
|
33
|
-
----------
|
|
34
|
-
mapShape : tuple[DatatypeLeavesTotal, ...]
|
|
35
|
-
Dimensions of the map being analyzed for folding patterns.
|
|
36
|
-
groupsOfFolds : DatatypeFoldsTotal = DatatypeFoldsTotal(0)
|
|
37
|
-
Current count of distinct folding pattern groups: each group has `leavesTotal`-many foldings.
|
|
38
|
-
dimensionsTotal : DatatypeLeavesTotal
|
|
39
|
-
Unchanging total number of dimensions in the map.
|
|
40
|
-
leavesTotal : DatatypeLeavesTotal
|
|
41
|
-
Unchanging total number of leaves in the map.
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
mapShape: tuple[DatatypeLeavesTotal, ...] = dataclasses.field(init=True, metadata={'elementConstructor': 'DatatypeLeavesTotal'})
|
|
45
|
-
"""Dimensions of the map being analyzed for folding patterns."""
|
|
46
|
-
|
|
47
|
-
groupsOfFolds: DatatypeFoldsTotal = dataclasses.field(default=DatatypeFoldsTotal(0), metadata={'theCountingIdentifier': True})
|
|
48
|
-
"""Current count of distinct folding pattern groups: each group has `leavesTotal`-many foldings."""
|
|
49
|
-
|
|
50
|
-
listPinnedLeaves: list[dict[int, int]] = dataclasses.field(default_factory=list[dict[int, int]], init=True)
|
|
51
|
-
"""column: leaf or pile: indexLeaf"""
|
|
52
|
-
pile: DatatypeLeavesTotal = DatatypeLeavesTotal(-1) # noqa: RUF009
|
|
53
|
-
pinnedLeaves: dict[int, int] = dataclasses.field(default_factory=dict[int, int], init=True, metadata={'elementConstructor': 'DatatypeLeavesTotal'})
|
|
54
|
-
"""column: leaf or pile: indexLeaf"""
|
|
55
|
-
|
|
56
|
-
subsetsTheorem2: DatatypeLeavesTotal = DatatypeLeavesTotal(1) # noqa: RUF009
|
|
57
|
-
subsetsTheorem3: DatatypeLeavesTotal = DatatypeLeavesTotal(1) # noqa: RUF009
|
|
58
|
-
subsetsTheorem4: DatatypeLeavesTotal = DatatypeLeavesTotal(1) # noqa: RUF009
|
|
59
|
-
|
|
60
|
-
columnLast: DatatypeLeavesTotal = dataclasses.field(init=False)
|
|
61
|
-
dimensionsTotal: DatatypeLeavesTotal = dataclasses.field(init=False)
|
|
62
|
-
"""Unchanging total number of dimensions in the map."""
|
|
63
|
-
leavesTotal: DatatypeLeavesTotal = dataclasses.field(init=False)
|
|
64
|
-
"""Unchanging total number of leaves in the map."""
|
|
65
|
-
|
|
66
|
-
@property
|
|
67
|
-
def foldsTotal(self) -> DatatypeFoldsTotal:
|
|
68
|
-
"""The total number of possible folding patterns for this map.
|
|
69
|
-
|
|
70
|
-
Returns
|
|
71
|
-
-------
|
|
72
|
-
foldsTotal : DatatypeFoldsTotal
|
|
73
|
-
The complete count of distinct folding patterns achievable with the current map configuration.
|
|
74
|
-
|
|
75
|
-
"""
|
|
76
|
-
return DatatypeFoldsTotal(self.leavesTotal) * self.groupsOfFolds * self.subsetsTheorem2 * self.subsetsTheorem3 * self.subsetsTheorem4
|
|
77
|
-
|
|
78
|
-
def __post_init__(self) -> None:
|
|
79
|
-
"""Ensure all fields have a value."""
|
|
80
|
-
self.dimensionsTotal = DatatypeLeavesTotal(len(self.mapShape))
|
|
81
|
-
self.leavesTotal = DatatypeLeavesTotal(getLeavesTotal(self.mapShape))
|
|
82
|
-
self.columnLast = self.leavesTotal - DatatypeLeavesTotal(1)
|
|
83
|
-
|
|
84
28
|
@dataclasses.dataclass(slots=True)
|
|
85
29
|
class MapFoldingState:
|
|
86
30
|
"""Core computational state for map folding algorithms.
|
mapFolding/filesystemToolkit.py
CHANGED
|
@@ -24,10 +24,14 @@ solutions to their map folding challenges.
|
|
|
24
24
|
from mapFolding import packageSettings
|
|
25
25
|
from os import PathLike
|
|
26
26
|
from pathlib import Path, PurePath
|
|
27
|
-
from sys import modules as sysModules
|
|
27
|
+
from sys import modules as sysModules, stdout
|
|
28
|
+
from typing import TYPE_CHECKING
|
|
28
29
|
import os
|
|
29
30
|
import platformdirs
|
|
30
31
|
|
|
32
|
+
if TYPE_CHECKING:
|
|
33
|
+
from io import TextIOWrapper
|
|
34
|
+
|
|
31
35
|
def getFilenameFoldsTotal(mapShape: tuple[int, ...]) -> str:
|
|
32
36
|
"""Create a standardized filename for a computed `foldsTotal` value.
|
|
33
37
|
|
|
@@ -173,18 +177,18 @@ def saveFoldsTotal(pathFilename: PathLike[str] | PurePath, foldsTotal: int) -> N
|
|
|
173
177
|
_saveFoldsTotal(pathFilename, foldsTotal)
|
|
174
178
|
except Exception as ERRORmessage: # noqa: BLE001
|
|
175
179
|
try:
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
randomnessPlanB = (int(str(foldsTotal).strip()[-1]) + 1) * ['YO_']
|
|
180
|
-
filenameInfixUnique = ''.join(randomnessPlanB)
|
|
181
|
-
pathFilenamePlanB = os.path.join(os.getcwd(), 'foldsTotal' + filenameInfixUnique + '.txt') # noqa: PTH109, PTH118
|
|
182
|
-
writeStreamFallback = open(pathFilenamePlanB, 'w') # noqa: PTH123, SIM115
|
|
180
|
+
stdout.write(f"\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n\n{foldsTotal = }\n\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n")
|
|
181
|
+
stdout.writelines(str(ERRORmessage))
|
|
182
|
+
stdout.write(f"\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n\n{foldsTotal = }\n\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n")
|
|
183
|
+
randomnessPlanB: list[str] = (int(str(foldsTotal).strip()[-1]) + 1) * ['YO_']
|
|
184
|
+
filenameInfixUnique: str = ''.join(randomnessPlanB)
|
|
185
|
+
pathFilenamePlanB: str = os.path.join(os.getcwd(), 'foldsTotal' + filenameInfixUnique + '.txt') # noqa: PTH109, PTH118
|
|
186
|
+
writeStreamFallback: TextIOWrapper = open(pathFilenamePlanB, 'w') # noqa: PTH123, SIM115
|
|
183
187
|
writeStreamFallback.write(str(foldsTotal))
|
|
184
188
|
writeStreamFallback.close()
|
|
185
|
-
|
|
189
|
+
stdout.write(str(pathFilenamePlanB))
|
|
186
190
|
except Exception: # noqa: BLE001
|
|
187
|
-
|
|
191
|
+
stdout.write(str(foldsTotal))
|
|
188
192
|
|
|
189
193
|
def saveFoldsTotalFAILearly(pathFilename: PathLike[str] | PurePath) -> None:
|
|
190
194
|
"""Preemptively test file write capabilities before beginning computation.
|
|
@@ -220,7 +224,7 @@ def saveFoldsTotalFAILearly(pathFilename: PathLike[str] | PurePath) -> None:
|
|
|
220
224
|
|
|
221
225
|
"""
|
|
222
226
|
if Path(pathFilename).exists():
|
|
223
|
-
message = f"`{pathFilename = }` exists: a battle of overwriting might cause tears."
|
|
227
|
+
message: str = f"`{pathFilename = }` exists: a battle of overwriting might cause tears."
|
|
224
228
|
raise FileExistsError(message)
|
|
225
229
|
if not Path(pathFilename).parent.exists():
|
|
226
230
|
message = f"I received `{pathFilename = }` 0.000139 seconds ago from a function that promised it created the parent directory, but the parent directory does not exist. Fix that now, so your computation doesn't get deleted later. And be compassionate to others."
|
mapFolding/oeis.py
CHANGED
|
@@ -25,21 +25,20 @@ completes the journey from configuration foundation to mathematical discovery.
|
|
|
25
25
|
"""
|
|
26
26
|
|
|
27
27
|
from datetime import datetime, timedelta, UTC
|
|
28
|
-
from hunterMakesPy import writeStringToHere
|
|
28
|
+
from hunterMakesPy.filesystemToolkit import writeStringToHere
|
|
29
29
|
from itertools import chain
|
|
30
|
-
from mapFolding import
|
|
30
|
+
from mapFolding import MetadataOEISid, MetadataOEISidMapFolding, packageSettings
|
|
31
31
|
from mapFolding._theSSOT import pathCache
|
|
32
|
+
from mapFolding.basecamp import countFolds
|
|
32
33
|
from pathlib import Path
|
|
33
34
|
from typing import Final
|
|
35
|
+
from urllib.error import HTTPError, URLError
|
|
34
36
|
from urllib.request import urlopen
|
|
35
37
|
import argparse
|
|
36
38
|
import sys
|
|
37
39
|
import time
|
|
38
40
|
import warnings
|
|
39
41
|
|
|
40
|
-
oeisIDsImplemented: Final[list[str]] = sorted([oeisID.upper().strip() for oeisID in packageSettings.OEISidMapFoldingManuallySet])
|
|
41
|
-
"""Directly implemented OEIS IDs; standardized, e.g., 'A001415'."""
|
|
42
|
-
|
|
43
42
|
def _standardizeOEISid(oeisID: str) -> str:
|
|
44
43
|
"""Standardize an OEIS sequence ID to uppercase and without whitespace.
|
|
45
44
|
|
|
@@ -56,6 +55,9 @@ def _standardizeOEISid(oeisID: str) -> str:
|
|
|
56
55
|
"""
|
|
57
56
|
return str(oeisID).upper().strip()
|
|
58
57
|
|
|
58
|
+
oeisIDsImplemented: Final[list[str]] = sorted(map(_standardizeOEISid, packageSettings.OEISidMapFoldingManuallySet))
|
|
59
|
+
"""Directly implemented OEIS IDs; standardized, e.g., 'A001415'."""
|
|
60
|
+
|
|
59
61
|
def _getFilenameOEISbFile(oeisID: str) -> str:
|
|
60
62
|
"""Generate the filename for an OEIS b-file given a sequence ID.
|
|
61
63
|
|
|
@@ -145,10 +147,13 @@ def _getOEISofficial(pathFilenameCache: Path, url: str) -> None | str:
|
|
|
145
147
|
message = "URL must start with 'http:' or 'https:'"
|
|
146
148
|
raise ValueError(message)
|
|
147
149
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
try:
|
|
151
|
+
with urlopen(url) as response: # noqa: S310
|
|
152
|
+
oeisInformationRaw = response.read().decode('utf-8')
|
|
153
|
+
oeisInformation = str(oeisInformationRaw)
|
|
154
|
+
writeStringToHere(oeisInformation, pathFilenameCache)
|
|
155
|
+
except (HTTPError, URLError):
|
|
156
|
+
oeisInformation = pathFilenameCache.read_text(encoding="utf-8")
|
|
152
157
|
|
|
153
158
|
if not oeisInformation:
|
|
154
159
|
warnings.warn(f"Failed to retrieve OEIS sequence information for {pathFilenameCache.stem}.", stacklevel=2)
|
|
@@ -230,7 +235,7 @@ def getOEISidInformation(oeisID: str) -> tuple[str, int]:
|
|
|
230
235
|
listDescriptionDeconstructed: list[str] = []
|
|
231
236
|
offset = None
|
|
232
237
|
for lineOEIS in oeisInformation.splitlines():
|
|
233
|
-
lineOEIS = lineOEIS.strip()
|
|
238
|
+
lineOEIS = lineOEIS.strip()
|
|
234
239
|
if not lineOEIS or len(lineOEIS.split()) < 3:
|
|
235
240
|
continue
|
|
236
241
|
fieldCode, sequenceID, fieldData = lineOEIS.split(maxsplit=2)
|
|
@@ -279,9 +284,6 @@ def _makeDictionaryOEISMapFolding() -> dict[str, MetadataOEISidMapFolding]:
|
|
|
279
284
|
description=descriptionSherpa,
|
|
280
285
|
offset=offsetSherpa,
|
|
281
286
|
getMapShape=packageSettings.OEISidMapFoldingManuallySet[oeisID]['getMapShape'],
|
|
282
|
-
valuesBenchmark=packageSettings.OEISidMapFoldingManuallySet[oeisID]['valuesBenchmark'],
|
|
283
|
-
valuesTestParallelization=packageSettings.OEISidMapFoldingManuallySet[oeisID]['valuesTestParallelization'],
|
|
284
|
-
valuesTestValidation=packageSettings.OEISidMapFoldingManuallySet[oeisID]['valuesTestValidation'] + list(range(offsetSherpa, 2)),
|
|
285
287
|
valuesKnown=valuesKnownSherpa,
|
|
286
288
|
valueUnknown=max(valuesKnownSherpa.keys(), default=0) + 1
|
|
287
289
|
)
|
|
@@ -339,8 +341,8 @@ def _formatHelpText() -> str:
|
|
|
339
341
|
A formatted string containing complete usage information and examples.
|
|
340
342
|
|
|
341
343
|
"""
|
|
342
|
-
exampleOEISid: str =
|
|
343
|
-
exampleN: int =
|
|
344
|
+
exampleOEISid: str = 'A001415'
|
|
345
|
+
exampleN: int = 6
|
|
344
346
|
|
|
345
347
|
return (
|
|
346
348
|
"\nAvailable OEIS sequences:\n"
|
|
@@ -485,7 +487,6 @@ def _makeDictionaryOEIS() -> dict[str, MetadataOEISid]:
|
|
|
485
487
|
description=descriptionSherpa,
|
|
486
488
|
offset=offsetSherpa,
|
|
487
489
|
valuesKnown=valuesKnownSherpa,
|
|
488
|
-
valuesTestValidation=[*(packageSettings.OEISidManuallySet[oeisID]['valuesTestValidation']), offsetSherpa],
|
|
489
490
|
valueUnknown=max(valuesKnownSherpa.keys(), default=0) + 1,
|
|
490
491
|
)
|
|
491
492
|
return dictionary
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ruff: noqa
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
#================== analyze aligned ===================================================================================
|
|
3
|
+
#======== if bitsAlpha > 1 and bitsZulu > 1 and (bitsAlphaIsEven or bitsZuluIsEven) =====
|
|
4
4
|
"""NOTE find `bitsAlpha > 1 and bitsZulu > 1 and (bitsAlphaIsEven or bitsZuluIsEven)` without bitsAlpha or bitsZulu.
|
|
5
5
|
- `bitsAlpha` is even IFF `arcCode` is even.
|
|
6
6
|
- `bitsAlpha` > 1, so arcCode's LSB is irrelevant; locatorBits ends with 0b101, so arcCode's 2° LSB is irrelevant.
|
|
@@ -121,7 +121,6 @@ def count(bridges: int, startingCurveLocations: dict[int, int]) -> int:
|
|
|
121
121
|
bifurcationZulu ^= XOrHere2makePair
|
|
122
122
|
|
|
123
123
|
# Cases 1, 2, and 3 all compute curveLocationAnalysis
|
|
124
|
-
# TODO https://github.com/hunterhogan/mapFolding/issues/19
|
|
125
124
|
curveLocationAnalysis = ((bifurcationZulu >> 2) << 1) | bifurcationAlphaShiftRight2 # pyright: ignore[reportPossiblyUnboundVariable]
|
|
126
125
|
if curveLocationAnalysis < curveLocationsMAXIMUM:
|
|
127
126
|
dictionaryCurveLocations[curveLocationAnalysis] = dictionaryCurveLocations.get(curveLocationAnalysis, 0) + distinctCrossings
|
|
@@ -169,7 +169,7 @@ def count64(bridges: int, arrayCurveGroups: DataArray3columns, bridgesMinimum: i
|
|
|
169
169
|
|
|
170
170
|
allocateBridgesAligned: int = int(numpy.count_nonzero(selectBridgesAligned))
|
|
171
171
|
|
|
172
|
-
|
|
172
|
+
#------------------------------------------------ bridgesSimple -------------------------------------------------------
|
|
173
173
|
curveLocationsBridgesSimpleLessThanMaximum: DataArray1D = arrayCurveGroups[:, columnGroupZulu].copy()
|
|
174
174
|
numpy.left_shift(curveLocationsBridgesSimpleLessThanMaximum, 1, out=curveLocationsBridgesSimpleLessThanMaximum)
|
|
175
175
|
numpy.bitwise_or(curveLocationsBridgesSimpleLessThanMaximum, arrayCurveGroups[:, columnGroupAlpha], out=curveLocationsBridgesSimpleLessThanMaximum)
|
|
@@ -179,14 +179,14 @@ def count64(bridges: int, arrayCurveGroups: DataArray3columns, bridgesMinimum: i
|
|
|
179
179
|
|
|
180
180
|
allocateBridgesSimple: int = int(numpy.count_nonzero(curveLocationsBridgesSimpleLessThanMaximum))
|
|
181
181
|
|
|
182
|
-
|
|
182
|
+
#------------------------------------------------ arrayCurveLocations -------------------------------------------------
|
|
183
183
|
rowsAllocatedTotal: int = allocateGroupAlphaCurves + allocateGroupZuluCurves + allocateBridgesSimple + allocateBridgesAligned
|
|
184
184
|
arrayCurveLocations: DataArray2columns = numpy.zeros((rowsAllocatedTotal, columnsArrayCurveLocations), dtype=arrayCurveGroups.dtype)
|
|
185
185
|
|
|
186
186
|
rowsAggregatedTotal: int = 0
|
|
187
187
|
rowsDeallocatedTotal: int = 0
|
|
188
188
|
|
|
189
|
-
|
|
189
|
+
#------------------------------------------------ bridgesSimple -------------------------------------------------------
|
|
190
190
|
rowsAggregatedTotal = aggregateBridgesSimple2CurveLocations(arrayCurveLocations
|
|
191
191
|
, rowsAggregatedTotal
|
|
192
192
|
, curveLocationsBridgesSimpleLessThanMaximum
|
|
@@ -200,7 +200,7 @@ def count64(bridges: int, arrayCurveGroups: DataArray3columns, bridgesMinimum: i
|
|
|
200
200
|
del allocateBridgesSimple
|
|
201
201
|
goByeBye()
|
|
202
202
|
|
|
203
|
-
|
|
203
|
+
#------------------------------------------------ groupAlpha ----------------------------------------------------------
|
|
204
204
|
selectGroupAlphaCurves: SelectorBoolean = arrayCurveGroups[:, columnGroupAlpha] > numpy.uint64(1)
|
|
205
205
|
curveLocationsGroupAlpha: DataArray1D = arrayCurveGroups[selectGroupAlphaCurves, columnGroupAlpha].copy()
|
|
206
206
|
|
|
@@ -210,7 +210,6 @@ def count64(bridges: int, arrayCurveGroups: DataArray3columns, bridgesMinimum: i
|
|
|
210
210
|
numpy.bitwise_or(curveLocationsGroupAlpha, arrayCurveGroups[selectGroupAlphaCurves, columnGroupAlpha], out=curveLocationsGroupAlpha)
|
|
211
211
|
numpy.right_shift(curveLocationsGroupAlpha, 2, out=curveLocationsGroupAlpha)
|
|
212
212
|
# NOTE (groupAlpha >> 2) | (groupZulu << 3) | ((1 - (groupAlpha & 1)) << 1)
|
|
213
|
-
# TODO eliminate temporary arrayLockbox
|
|
214
213
|
arrayLockbox: numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.uint8]] = numpy.full_like(a=curveLocationsGroupAlpha, fill_value=numpy.uint8(0b111), dtype=numpy.uint8)
|
|
215
214
|
numpy.bitwise_and(arrayLockbox, curveLocationsGroupAlpha, out=arrayLockbox, dtype=numpy.uint8)
|
|
216
215
|
numpy.right_shift(curveLocationsGroupAlpha, 3, out=curveLocationsGroupAlpha)
|
|
@@ -237,14 +236,13 @@ def count64(bridges: int, arrayCurveGroups: DataArray3columns, bridgesMinimum: i
|
|
|
237
236
|
selectGroupAlphaCurves = None; del selectGroupAlphaCurves # pyright: ignore[reportAssignmentType] # noqa: E702
|
|
238
237
|
goByeBye()
|
|
239
238
|
|
|
240
|
-
|
|
239
|
+
#------------------------------------------------ groupZulu -----------------------------------------------------------
|
|
241
240
|
selectGroupZuluCurves: SelectorBoolean = arrayCurveGroups[:, columnGroupZulu] > numpy.uint64(1)
|
|
242
241
|
curveLocationsGroupZulu: DataArray1D = arrayCurveGroups[selectGroupZuluCurves, columnGroupAlpha].copy()
|
|
243
242
|
numpy.left_shift(curveLocationsGroupZulu, 2, out=curveLocationsGroupZulu)
|
|
244
243
|
# NOTE (groupAlpha << 2)
|
|
245
244
|
|
|
246
245
|
numpy.bitwise_or(curveLocationsGroupZulu, numpy.subtract(numpy.uint64(1), numpy.bitwise_and(arrayCurveGroups[selectGroupZuluCurves, columnGroupZulu], 1)), out=curveLocationsGroupZulu)
|
|
247
|
-
# TODO | (1 - (groupZulu & 1))
|
|
248
246
|
|
|
249
247
|
# NOTE | (groupZulu >> 1)
|
|
250
248
|
numpy.left_shift(curveLocationsGroupZulu, 1, out=curveLocationsGroupZulu)
|
|
@@ -267,7 +265,7 @@ def count64(bridges: int, arrayCurveGroups: DataArray3columns, bridgesMinimum: i
|
|
|
267
265
|
selectGroupZuluCurves = None; del selectGroupZuluCurves # pyright: ignore[reportAssignmentType] # noqa: E702
|
|
268
266
|
goByeBye()
|
|
269
267
|
|
|
270
|
-
|
|
268
|
+
#------------------------------------------------ bridgesAligned ------------------------------------------------------
|
|
271
269
|
# `bridgesAligned` = `bridgesGroupAlphaPairedToOdd` UNION WITH `bridgesGroupZuluPairedToOdd` UNION WITH `bridgesAlignedAtEven`
|
|
272
270
|
|
|
273
271
|
# bridgesAligned -------------------------------- bridgesGroupAlphaPairedToOdd ----------------------------------------
|
|
@@ -301,7 +299,7 @@ def count64(bridges: int, arrayCurveGroups: DataArray3columns, bridgesMinimum: i
|
|
|
301
299
|
|
|
302
300
|
# NOTE: All computations for `bridgesAlignedAtEven` are handled by the computations for `bridgesAligned`.
|
|
303
301
|
|
|
304
|
-
|
|
302
|
+
#------------------------------------------------ bridgesAligned ------------------------------------------------------
|
|
305
303
|
|
|
306
304
|
curveLocationsBridgesAlignedLessThanMaximum: DataArray1D = numpy.zeros((selectBridgesAligned.sum(),), dtype=numpy.uint64)
|
|
307
305
|
numpy.right_shift(arrayCurveGroups[selectBridgesAligned, columnGroupZulu], 2, out=curveLocationsBridgesAlignedLessThanMaximum)
|
|
@@ -330,7 +328,7 @@ def count64(bridges: int, arrayCurveGroups: DataArray3columns, bridgesMinimum: i
|
|
|
330
328
|
selectBridgesAligned = None; del selectBridgesAligned # pyright: ignore[reportAssignmentType] # noqa: E702
|
|
331
329
|
goByeBye()
|
|
332
330
|
|
|
333
|
-
|
|
331
|
+
#------------------------------------------------ aggregation ---------------------------------------------------------
|
|
334
332
|
arrayCurveGroups = aggregateCurveLocations2CurveGroups(arrayCurveLocations)
|
|
335
333
|
|
|
336
334
|
arrayCurveLocations = None; del arrayCurveLocations # pyright: ignore[reportAssignmentType] # noqa: E702
|