sciris 3.2.6__tar.gz → 3.2.8__tar.gz
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.
- {sciris-3.2.6 → sciris-3.2.8}/.github/workflows/schedule_tests.yaml +1 -1
- {sciris-3.2.6 → sciris-3.2.8}/CHANGELOG.rst +9 -0
- {sciris-3.2.6/sciris.egg-info → sciris-3.2.8}/PKG-INFO +1 -1
- sciris-3.2.8/context7.json +4 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/sc_asd.py +185 -128
- {sciris-3.2.6 → sciris-3.2.8}/sciris/sc_odict.py +25 -25
- {sciris-3.2.6 → sciris-3.2.8}/sciris/sc_profiling.py +15 -3
- {sciris-3.2.6 → sciris-3.2.8}/sciris/sc_version.py +2 -2
- {sciris-3.2.6 → sciris-3.2.8/sciris.egg-info}/PKG-INFO +1 -1
- {sciris-3.2.6 → sciris-3.2.8}/sciris.egg-info/SOURCES.txt +1 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_odict.py +1 -1
- {sciris-3.2.6 → sciris-3.2.8}/.github/workflows/pypi_release.yaml +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/.github/workflows/test_downstream.yaml +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/.github/workflows/test_sciris.yaml +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/.gitignore +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/.pylintrc +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/.readthedocs.yaml +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/CLAUDE.md +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/CODE_OF_CONDUCT.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/CONTRIBUTING.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/LICENSE +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/MANIFEST.in +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/README.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/STYLE_GUIDE.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/.gitignore +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/Makefile +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/README.md +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/_build/html/_static/scripts/bootstrap.js.LICENSE.txt +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/_build/html/_static/scripts/fontawesome.js.LICENSE.txt +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/_static/theme_overrides.css +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/_templates/custom-class-template.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/_templates/custom-function-template.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/_templates/custom-module-template.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/_templates/footer.html +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/_templates/page.html +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_asd.asd.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_asd.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.alpinecolormap.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.arraycolors.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.bandedcolormap.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.bicolormap.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.colormapdemo.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.gridcolors.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.hex2rgb.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.hsv2rgb.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.manualcolorbar.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.midpointnorm.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.orangebluecolormap.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.parulacolormap.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.rgb2hex.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.rgb2hsv.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.sanitizecolor.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.shifthue.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.turbocolormap.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_colors.vectocolor.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_dataframe.dataframe.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_dataframe.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.Timer.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.date.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.datedelta.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.daterange.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.datetoyear.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.day.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.daydiff.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.elapsedtimestr.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.getdate.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.now.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.randsleep.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.readdate.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.tic.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.time.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.timedsleep.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.timer.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.toc.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.toctic.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_datetime.yeartodate.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.Blobject.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.Failed.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.Spreadsheet.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.UnpicklingError.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.UnpicklingWarning.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.dumpstr.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.getfilelist.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.getfilepaths.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.glob.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.ispath.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.jsonify.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.jsonpickle.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.jsonunpickle.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.load.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.loadany.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.loadjson.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.loadobj.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.loadspreadsheet.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.loadstr.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.loadtext.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.loadyaml.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.loadzip.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.makefilepath.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.makepath.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.path.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.printjson.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.readjson.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.readyaml.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.rmpath.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.sanitizefilename.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.sanitizejson.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.sanitizepath.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.save.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.savejson.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.saveobj.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.savespreadsheet.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.savetext.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.saveyaml.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.savezip.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.thisdir.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.thisfile.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.thispath.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.unzip.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_fileio.zsave.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.approx.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.cat.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.convolve.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.count.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.dataindex.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.fillnans.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.findfirst.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.findinds.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.findlast.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.findnans.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.findnearest.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.gauss1d.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.gauss2d.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.getvaliddata.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.getvalidinds.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.inclusiverange.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.isprime.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.linregress.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.nanequal.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.normalize.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.normsum.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.numdigits.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.perturb.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.randround.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.rmnans.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.rolling.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.safedivide.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.sanitize.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.sem.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.similarity.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.smooth.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_math.smoothinterp.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_nested.Equal.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_nested.IterObj.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_nested.equal.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_nested.flattendict.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_nested.getnested.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_nested.iternested.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_nested.iterobj.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_nested.makenested.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_nested.mergenested.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_nested.nestedloop.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_nested.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_nested.search.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_nested.setnested.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_odict.argparse.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_odict.asobj.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_odict.counter.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_odict.ddict.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_odict.dictobj.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_odict.objdict.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_odict.odict.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_odict.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_parallel.Parallel.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_parallel.cpu_count.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_parallel.cpuload.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_parallel.loadbalancer.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_parallel.memload.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_parallel.parallelize.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_parallel.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.SIticks.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.ScirisDateFormatter.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.animation.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.ax3d.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.bar3d.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.boxoff.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.commaticks.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.dateformatter.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.datenumformatter.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.emptyfig.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.fig3d.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.figlayout.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.fonts.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.get_rows_cols.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.getrowscols.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.loadfig.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.maximize.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.movelegend.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.orderlegend.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.plot3d.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.savefig.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.savefigs.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.savemovie.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.scatter3d.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.separatelegend.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.setaxislim.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.setxlim.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.setylim.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.stackedbar.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_plotting.surf3d.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.arraymean.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.arraymedian.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.blank.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.capture.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.classatt.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.colorize.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.createcollist.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.heading.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.humanize_bytes.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.indent.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.objatt.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.objectid.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.objmeth.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.objprop.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.objrepr.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.percentcomplete.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.pr.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.prepr.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.prettyobj.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.printarr.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.printblue.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.printcyan.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.printdata.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.printgreen.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.printmagenta.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.printmean.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.printmedian.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.printred.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.printtologfile.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.printv.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.printvars.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.printyellow.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.progressbar.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.progressbars.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.quickobj.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.sigfig.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.sigfiground.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.sigfigs.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_printing.slacknotification.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_profiling.LimitExceeded.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_profiling.benchmark.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_profiling.checkmem.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_profiling.checkram.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_profiling.cprofile.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_profiling.listfuncs.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_profiling.mprofile.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_profiling.profile.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_profiling.resourcemonitor.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_profiling.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_profiling.tracecalls.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_settings.ScirisOptions.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_settings.help.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_settings.parse_env.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_settings.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.KeyNotFoundError.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.LazyModule.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.Link.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.LinkException.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.asciify.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.autolist.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.checktype.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.cp.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.dcp.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.download.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.fast_uuid.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.flexstr.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.getplatform.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.getuser.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.htmlify.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.ifelse.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.importbyname.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.importbypath.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.isarray.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.isfunc.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.isiterable.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.isjupyter.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.islinux.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.ismac.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.ismodule.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.isnumber.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.isstring.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.iswindows.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.mergedicts.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.mergelists.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.newlinejoin.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.pp.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.promotetoarray.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.promotetolist.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.robust_dcp.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.runcommand.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.sanitizestr.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.sha.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.strjoin.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.strsplit.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.suggest.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.swapdict.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.toarray.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.tolist.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.traceback.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.transposelist.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.tryexcept.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.uniquename.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.urlopen.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.uuid.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_utils.wget.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_version.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_versioning.compareversions.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_versioning.freeze.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_versioning.getcaller.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_versioning.gitinfo.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_versioning.loadarchive.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_versioning.loadmetadata.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_versioning.metadata.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_versioning.require.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_versioning.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/_autosummary/sciris.sc_versioning.savearchive.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/all.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/containers.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/files.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/index.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/math.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/parallel.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/printing.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/api/utils.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/build_docs +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/conf.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/contributing.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/favicon.ico +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/freeze_env +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/index.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/overview.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/requirements.txt +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/sciris-citation.bib +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/sciris-logo-grey-small.png +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/sciris-logo-grey.png +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/sciris-logo-white-small.png +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/sciris-logo.png +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/sciris-showcase-code.png +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/sciris-showcase-output.png +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/README.md +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/clean_outputs +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/dancing_lines.gif +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/img-advanced.gif +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/img-arrays.png +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/img-dates.png +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/img-dicts.png +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/img-files.png +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/img-intro.png +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/img-parallel.png +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/img-plotting.png +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/img-printing.png +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/img-utils.png +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/index.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/run_tutorials +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/sim1/sim.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/sim2/sim.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/tut_advanced.ipynb +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/tut_arrays.ipynb +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/tut_dates.ipynb +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/tut_dicts.ipynb +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/tut_files.ipynb +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/tut_intro.ipynb +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/tut_parallel.ipynb +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/tut_plotting.ipynb +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/tut_printing.ipynb +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/tutorials/tut_utils.ipynb +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/docs/whatsnew.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/pyproject.toml +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/README.md +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/__init__.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/_extras/README.md +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/_extras/__init__.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/_extras/ansicolors.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/_extras/legacy.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/fancy.mplstyle +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/sc_colors.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/sc_dataframe.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/sc_datetime.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/sc_fileio.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/sc_math.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/sc_nested.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/sc_parallel.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/sc_plotting.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/sc_printing.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/sc_settings.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/sc_utils.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/sc_versioning.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris/simple.mplstyle +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris.egg-info/dependency_links.txt +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris.egg-info/requires.txt +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/sciris.egg-info/top_level.txt +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/setup.cfg +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/.coveragerc +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/README.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/check_coverage +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/check_style +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/files/archive_2023-04-19.zip +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/files/deadclass.obj +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/files/deadclass.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/files/exampledata.xlsx +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/files/examplefont.ttf +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/files/make_archive.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/files/make_deadclass.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/files/pickle_2021-01-01.obj +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/files/pickle_2022-01-01.obj +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/pylint_report.txt +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/pytest.ini +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/regression/README.rst +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/regression/run_downstream +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/regression/run_regression +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/regression/sciris2021-01-01.yml +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/regression/sciris2022-01-01.yml +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/regression/sciris2023-01-01.yml +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/regression/setup_envs +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/requirements.txt +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/run_tests +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/sc_test_utils.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/showcase_sciris.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/showcase_vanilla.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_asd.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_both_parallelizers.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_colors.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_dataframe.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_datetime.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_fileio.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_math.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_mp_objdict.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_nested.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_objdict_pickle_detailed.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_parallel.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_parallel_mp.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_parallel_odict.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_pickle_objdict.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_plotting.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_printing.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_profiling.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_settings.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_utils.py +0 -0
- {sciris-3.2.6 → sciris-3.2.8}/tests/test_versioning.py +0 -0
|
@@ -7,6 +7,15 @@ All major updates to Sciris are documented here.
|
|
|
7
7
|
|
|
8
8
|
By import convention, components of the Sciris library are listed beginning with ``sc.``, e.g. ``sc.odict()``.
|
|
9
9
|
|
|
10
|
+
Version 3.2.8 (2026-02-28)
|
|
11
|
+
--------------------------
|
|
12
|
+
#. Changed resolution order in :class:`sc.objdict() <sc_odict.objdict>` so that dunder attributes (e.g. ``__await__``) are never accidentally set as dict keys. Attempting to set an existing attribute as a key now raises ``KeyError`` instead of ``ValueError``.
|
|
13
|
+
#. Fixed a bug in :class:`sc.profile() <sc_profiling.profile>` that prevented profiling information from being printed for certain combinations of filenames.
|
|
14
|
+
|
|
15
|
+
Version 3.2.7 (2026-02-18)
|
|
16
|
+
--------------------------
|
|
17
|
+
#. Refactored :class:`sc.asd() <sc_asd.asd>` to be more robust to different parameter inputs and different objective function return values.
|
|
18
|
+
|
|
10
19
|
Version 3.2.6 (2026-02-12)
|
|
11
20
|
--------------------------
|
|
12
21
|
#. Added :class:`sc.argparse() <sc_odict.argparse>`, a simple argument parser based on ``sc.objdict``.
|
|
@@ -9,23 +9,55 @@ This algorithm is published as:
|
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
import time
|
|
12
|
+
import warnings
|
|
12
13
|
import numpy as np
|
|
13
14
|
import sciris as sc
|
|
14
15
|
|
|
15
16
|
__all__ = ['asd']
|
|
16
17
|
|
|
17
18
|
|
|
19
|
+
def _consistent_shape(userinput, origshape=False):
|
|
20
|
+
""" Ensure inputs have the right shape and data type. """
|
|
21
|
+
output = np.reshape(np.array(userinput, dtype='float'), -1)
|
|
22
|
+
if origshape:
|
|
23
|
+
return output, np.shape(userinput)
|
|
24
|
+
return output
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _improvement_ratio(fval_old, fval_new, eps=1e-12):
|
|
28
|
+
""" Compute improvement ratio with divide-by-zero guard
|
|
29
|
+
|
|
30
|
+
Returns fval_old/fval_new, or 1 when both near zero, or a large value when only fval_new is near zero.
|
|
31
|
+
"""
|
|
32
|
+
if abs(fval_new) < eps and abs(fval_old) < eps:
|
|
33
|
+
return 1.0
|
|
34
|
+
if abs(fval_new) < eps:
|
|
35
|
+
return 1.0 / eps
|
|
36
|
+
return fval_old / float(fval_new)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _validate_fval(fval, die=True):
|
|
40
|
+
""" Validate that the objective function returns a scalar """
|
|
41
|
+
if not sc.isnumber(fval):
|
|
42
|
+
if isinstance(fval, np.ndarray) and fval.size == 1: # Automatically convert size-1 arrays to scalars
|
|
43
|
+
fval = fval[0]
|
|
44
|
+
else:
|
|
45
|
+
errormsg = f'ASD: The objective function should return a scalar, not: {fval} (type: {type(fval)})'
|
|
46
|
+
raise ValueError(errormsg)
|
|
47
|
+
return fval
|
|
48
|
+
|
|
49
|
+
|
|
18
50
|
def asd(function, x, args=None, stepsize=0.1, sinc=2, sdec=2, pinc=2, pdec=2,
|
|
19
51
|
pinitial=None, sinitial=None, xmin=None, xmax=None, maxiters=None, maxtime=None,
|
|
20
52
|
abstol=1e-6, reltol=1e-3, stalliters=None, stoppingfunc=None, randseed=None,
|
|
21
|
-
label=None, verbose=1, minval=0, **kwargs):
|
|
53
|
+
label=None, verbose=1, minval=0, die=True, **kwargs):
|
|
22
54
|
"""
|
|
23
55
|
Optimization using adaptive stochastic descent (ASD). Can be used as a faster
|
|
24
56
|
and more powerful alternative to e.g. :func:`scipy.optimize.minimize()`.
|
|
25
57
|
|
|
26
|
-
ASD starts at ``
|
|
27
|
-
``
|
|
28
|
-
``
|
|
58
|
+
ASD starts at ``x`` and attempts to find a local minimizer of the function ``function()``.
|
|
59
|
+
``function()`` accepts input ``x`` and returns a scalar function value evaluated at ``x``.
|
|
60
|
+
``x`` can be a scalar, list, or Numpy array of any size.
|
|
29
61
|
|
|
30
62
|
Args:
|
|
31
63
|
function (func): The function to minimize
|
|
@@ -51,6 +83,7 @@ def asd(function, x, args=None, stepsize=0.1, sinc=2, sdec=2, pinc=2, pdec=2,
|
|
|
51
83
|
label (None): A label to use to annotate the output
|
|
52
84
|
verbose (1): How much information to print during the run (max 3); less than one will print out once every 1/verbose steps
|
|
53
85
|
minval (0): Minimum value the objective function can take
|
|
86
|
+
die (True): If True, raise when the objective function raises; if False, treat that trial as np.inf and continue
|
|
54
87
|
|
|
55
88
|
Returns:
|
|
56
89
|
objdict (see below)
|
|
@@ -78,13 +111,13 @@ def asd(function, x, args=None, stepsize=0.1, sinc=2, sdec=2, pinc=2, pdec=2,
|
|
|
78
111
|
result = sc.asd(np.linalg.norm, [1, 2, 3])
|
|
79
112
|
print(result.x)
|
|
80
113
|
|
|
81
|
-
# With arguments
|
|
82
|
-
def my_func(x, scale=1.0, weight=1.0):
|
|
114
|
+
# With arguments: positional via args, or dict of keywords, or keyword arguments
|
|
115
|
+
def my_func(x, scale=1.0, weight=1.0): # Example function with keywords
|
|
83
116
|
return abs((x[0] - 1)) + abs(x[1] + 2)*scale + abs(x[2] + 3)*weight
|
|
84
117
|
|
|
85
118
|
result = sc.asd(my_func, x=[0, 0, 1], args=[0.5, 0.1]) # Option 1 for passing arguments
|
|
86
|
-
result = sc.asd(my_func, x=[0, 0, 1], args=dict(scale=0.5, weight=0.1)) # Option
|
|
87
|
-
result = sc.asd(my_func, x=[0, 0, 1], scale=0.5, weight=0.1) # Option
|
|
119
|
+
result = sc.asd(my_func, x=[0, 0, 1], args=dict(scale=0.5, weight=0.1)) # Option 2 for passing arguments
|
|
120
|
+
result = sc.asd(my_func, x=[0, 0, 1], scale=0.5, weight=0.1) # Option 3 for passing arguments
|
|
88
121
|
|
|
89
122
|
Please use the following citation for this method:
|
|
90
123
|
|
|
@@ -97,82 +130,104 @@ def asd(function, x, args=None, stepsize=0.1, sinc=2, sdec=2, pinc=2, pdec=2,
|
|
|
97
130
|
rng = np.random.default_rng(randseed)
|
|
98
131
|
if verbose >= 2: print(f'ASD: Launching with random seed {randseed}')
|
|
99
132
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
133
|
+
# Reshape initial point and get parameter count
|
|
134
|
+
x, origshape = _consistent_shape(x, origshape=True)
|
|
135
|
+
nparams = len(x)
|
|
136
|
+
maxrangeiters = 100 # Number of times to try generating a new parameter
|
|
137
|
+
|
|
138
|
+
# Set defaults in one place
|
|
139
|
+
if maxtime is None:
|
|
140
|
+
maxtime = 3600
|
|
141
|
+
if maxiters is None:
|
|
142
|
+
maxiters = 1000
|
|
143
|
+
if label is None:
|
|
144
|
+
label = ''
|
|
145
|
+
if stalliters is None:
|
|
146
|
+
stalliters = 10 * nparams
|
|
147
|
+
stalliters = int(stalliters)
|
|
148
|
+
maxiters = int(maxiters)
|
|
149
|
+
eps = 1e-12
|
|
150
|
+
|
|
151
|
+
# Validate input vector length
|
|
152
|
+
if not nparams:
|
|
115
153
|
errormsg = 'ASD: The length of the input vector cannot be zero'
|
|
116
154
|
raise ValueError(errormsg)
|
|
117
|
-
|
|
118
|
-
|
|
155
|
+
|
|
156
|
+
# Validate learning rates (must be >= 1)
|
|
157
|
+
if sinc < 1:
|
|
158
|
+
errormsg = 'ASD: sinc cannot be less than 1; resetting to 2'
|
|
159
|
+
if die:
|
|
160
|
+
raise ValueError(errormsg)
|
|
161
|
+
warnings.warn(errormsg)
|
|
119
162
|
sinc = 2
|
|
120
|
-
if sdec<1:
|
|
121
|
-
|
|
163
|
+
if sdec < 1:
|
|
164
|
+
errormsg = 'ASD: sdec cannot be less than 1; resetting to 2'
|
|
165
|
+
if die:
|
|
166
|
+
raise ValueError(errormsg)
|
|
167
|
+
warnings.warn(errormsg)
|
|
122
168
|
sdec = 2
|
|
123
|
-
if pinc<1:
|
|
124
|
-
|
|
169
|
+
if pinc < 1:
|
|
170
|
+
errormsg = 'ASD: pinc cannot be less than 1; resetting to 2'
|
|
171
|
+
if die:
|
|
172
|
+
raise ValueError(errormsg)
|
|
173
|
+
warnings.warn(errormsg)
|
|
125
174
|
pinc = 2
|
|
126
|
-
if pdec<1:
|
|
127
|
-
|
|
175
|
+
if pdec < 1:
|
|
176
|
+
errormsg = 'ASD: pdec cannot be less than 1; resetting to 2'
|
|
177
|
+
if die:
|
|
178
|
+
raise ValueError(errormsg)
|
|
179
|
+
warnings.warn(errormsg)
|
|
128
180
|
pdec = 2
|
|
129
181
|
|
|
130
|
-
# Set initial parameter selection probabilities
|
|
131
|
-
if pinitial is None:
|
|
132
|
-
|
|
133
|
-
|
|
182
|
+
# Set initial parameter selection probabilities (uniform by default)
|
|
183
|
+
if pinitial is None:
|
|
184
|
+
probabilities = np.ones(2 * nparams)
|
|
185
|
+
else:
|
|
186
|
+
probabilities = _consistent_shape(pinitial)
|
|
187
|
+
if not sum(probabilities):
|
|
134
188
|
errormsg = 'ASD: The sum of input probabilities cannot be zero'
|
|
135
189
|
raise ValueError(errormsg)
|
|
136
190
|
|
|
137
|
-
#
|
|
191
|
+
# Step sizes
|
|
138
192
|
if sinitial is None:
|
|
139
193
|
stepsizes = abs(stepsize * x)
|
|
140
|
-
stepsizes = np.concatenate((stepsizes, stepsizes))
|
|
194
|
+
stepsizes = np.concatenate((stepsizes, stepsizes)) # Two entries per parameter (up/down)
|
|
141
195
|
else:
|
|
142
|
-
stepsizes =
|
|
196
|
+
stepsizes = _consistent_shape(sinitial)
|
|
143
197
|
|
|
144
|
-
#
|
|
145
|
-
xmin = np.zeros(nparams) - np.inf if xmin is None else
|
|
146
|
-
xmax = np.zeros(nparams) + np.inf if xmax is None else
|
|
198
|
+
# Parameter bounds
|
|
199
|
+
xmin = np.zeros(nparams) - np.inf if xmin is None else _consistent_shape(xmin)
|
|
200
|
+
xmax = np.zeros(nparams) + np.inf if xmax is None else _consistent_shape(xmax)
|
|
147
201
|
|
|
148
|
-
#
|
|
149
|
-
if sum(np.isnan(x)):
|
|
202
|
+
# Reject NaN in starting point
|
|
203
|
+
if sum(np.isnan(x)):
|
|
150
204
|
errormsg = f'ASD: At least one value in the vector of starting points is NaN:\n{x}'
|
|
151
205
|
raise ValueError(errormsg)
|
|
152
|
-
if label is None: label = ''
|
|
153
|
-
if stalliters is None: stalliters = 10 * nparams # By default, try 10 times per parameter on average
|
|
154
|
-
stalliters = int(stalliters)
|
|
155
|
-
maxiters = int(maxiters)
|
|
156
206
|
|
|
157
207
|
# Initialization
|
|
158
|
-
if all(stepsizes == 0):
|
|
159
|
-
|
|
160
|
-
if
|
|
208
|
+
if all(stepsizes == 0):
|
|
209
|
+
stepsizes += stepsize
|
|
210
|
+
if any(stepsizes == 0):
|
|
211
|
+
stepsizes[stepsizes == 0] = np.mean(stepsizes[stepsizes != 0])
|
|
212
|
+
if args is None:
|
|
161
213
|
args = []
|
|
162
|
-
elif isinstance(args, dict):
|
|
214
|
+
elif isinstance(args, dict):
|
|
163
215
|
kwargs = sc.mergedicts(args, kwargs)
|
|
164
216
|
args = []
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
217
|
+
|
|
218
|
+
# Get initial function value
|
|
219
|
+
fval = function(x, *args, **kwargs)
|
|
220
|
+
fval = _validate_fval(fval, die=die)
|
|
221
|
+
fvalorig = fval
|
|
222
|
+
xorig = x.copy()
|
|
223
|
+
|
|
224
|
+
# Allocate history arrays
|
|
225
|
+
abserrorhistory = np.zeros(stalliters)
|
|
226
|
+
relerrorhistory = np.zeros(stalliters)
|
|
227
|
+
fvals = np.zeros(maxiters + 1)
|
|
228
|
+
allsteps = np.zeros((maxiters + 1, nparams))
|
|
229
|
+
fvals[0] = fvalorig
|
|
230
|
+
allsteps[0, :] = xorig
|
|
176
231
|
|
|
177
232
|
# Prepare for the loop
|
|
178
233
|
count = 0 # Keep track of how many iterations have occurred
|
|
@@ -180,23 +235,23 @@ def asd(function, x, args=None, stepsize=0.1, sinc=2, sdec=2, pinc=2, pdec=2,
|
|
|
180
235
|
offset = ' ' * 4 # Offset the print statements
|
|
181
236
|
exitreason = 'Unknown exit reason' # Catch everything else
|
|
182
237
|
|
|
183
|
-
#
|
|
238
|
+
# Main optimization loop
|
|
184
239
|
while True:
|
|
185
240
|
|
|
186
|
-
#
|
|
241
|
+
# Skip if already at minimum
|
|
187
242
|
if fvalorig == minval:
|
|
188
243
|
exitreason = f'Objective function already at minimum value ({fvalorig}), skipping optimization'
|
|
189
244
|
break
|
|
190
|
-
|
|
245
|
+
if fvalorig < 0 and verbose:
|
|
191
246
|
print(f'ASD: Warning, negative objective function starting value ({fvalorig:n}) could lead to unexpected behavior')
|
|
192
247
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
248
|
+
count += 1
|
|
249
|
+
if verbose >= 3:
|
|
250
|
+
print(f'\n\n Count={count} \n x={x} \n probabilities={probabilities} \n stepsizes={stepsizes}')
|
|
196
251
|
|
|
197
|
-
#
|
|
198
|
-
probabilities = probabilities / sum(probabilities)
|
|
199
|
-
cumprobs = np.cumsum(probabilities)
|
|
252
|
+
# Normalize probabilities and sample a parameter/direction
|
|
253
|
+
probabilities = probabilities / sum(probabilities)
|
|
254
|
+
cumprobs = np.cumsum(probabilities)
|
|
200
255
|
inrange = False
|
|
201
256
|
for r in range(maxrangeiters): # Try to find parameters within range
|
|
202
257
|
choice = np.flatnonzero(cumprobs > rng.random())[0] # Choose a parameter and upper/lower at random
|
|
@@ -206,93 +261,95 @@ def asd(function, x, args=None, stepsize=0.1, sinc=2, sdec=2, pinc=2, pdec=2,
|
|
|
206
261
|
if newval<xmin[par]: newval = xmin[par] # Reset to the lower limit
|
|
207
262
|
if newval>xmax[par]: newval = xmax[par] # Reset to the upper limit
|
|
208
263
|
inrange = (newval != x[par])
|
|
209
|
-
if verbose >= 3:
|
|
210
|
-
|
|
264
|
+
if verbose >= 3:
|
|
265
|
+
print(offset*2 + f'count={count} r={r}, choice={choice}, par={par}, x[par]={x[par]}, pm={(-1)**pm}, step={stepsizes[choice]}, newval={newval}, xmin={xmin[par]}, xmax={xmax[par]}, inrange={inrange}')
|
|
266
|
+
if inrange:
|
|
211
267
|
break
|
|
212
268
|
if not inrange: # Treat it as a failure if a value in range can't be found
|
|
213
269
|
probabilities[choice] = probabilities[choice] / pdec
|
|
214
270
|
stepsizes[choice] = stepsizes[choice] / sdec
|
|
215
271
|
|
|
216
|
-
#
|
|
217
|
-
xnew = x.copy()
|
|
218
|
-
xnew[par] = newval
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
272
|
+
# Evaluate objective at proposed point
|
|
273
|
+
xnew = x.copy()
|
|
274
|
+
xnew[par] = newval
|
|
275
|
+
try:
|
|
276
|
+
fvalnew = function(xnew, *args, **kwargs)
|
|
277
|
+
fvalnew = _validate_fval(fvalnew, die=die)
|
|
278
|
+
except Exception as e:
|
|
279
|
+
if die:
|
|
280
|
+
raise
|
|
281
|
+
warnings.warn(f'ASD: Objective function raised on step {count}; treating trial as np.inf. Error: {e}')
|
|
282
|
+
fvalnew = np.inf
|
|
283
|
+
ratio = _improvement_ratio(fval, fvalnew, eps)
|
|
284
|
+
|
|
285
|
+
# Update improvement history
|
|
286
|
+
abserrorhistory[count % stalliters] = max(0, fval - fvalnew)
|
|
287
|
+
relerrorhistory[count % stalliters] = max(0, ratio - 1.0)
|
|
288
|
+
if verbose >= 2:
|
|
289
|
+
print(offset + f'step={count} choice={choice}, par={par}, pm={pm}, origval={x[par]}, newval={xnew[par]}')
|
|
227
290
|
if newval < 0 and verbose:
|
|
228
291
|
print(f'ASD: Warning, negative objective function ({newval:n}) on step {count} could lead to unexpected behavior')
|
|
229
292
|
|
|
230
|
-
#
|
|
231
|
-
fvalold = fval
|
|
232
|
-
if fvalnew < fvalold:
|
|
233
|
-
probabilities[choice] = probabilities[choice] * pinc
|
|
234
|
-
stepsizes[choice] = stepsizes[choice] * sinc
|
|
235
|
-
x = xnew
|
|
236
|
-
fval = fvalnew
|
|
237
|
-
flag = '++'
|
|
238
|
-
else:
|
|
239
|
-
probabilities[choice] = probabilities[choice] / pdec
|
|
240
|
-
stepsizes[choice] = stepsizes[choice] / sdec
|
|
241
|
-
flag = '--'
|
|
242
|
-
if np.isnan(fvalnew):
|
|
243
|
-
|
|
244
|
-
if verbose > 0 and not (count % max(1, int(1.0/verbose))):
|
|
245
|
-
orig, best, new, diff = sc.sigfig([fvalorig, fvalold, fvalnew, fvalnew-fvalold])
|
|
293
|
+
# Accept or reject step and update learning state
|
|
294
|
+
fvalold = fval
|
|
295
|
+
if fvalnew < fvalold:
|
|
296
|
+
probabilities[choice] = probabilities[choice] * pinc
|
|
297
|
+
stepsizes[choice] = stepsizes[choice] * sinc
|
|
298
|
+
x = xnew
|
|
299
|
+
fval = fvalnew
|
|
300
|
+
flag = '++'
|
|
301
|
+
else:
|
|
302
|
+
probabilities[choice] = probabilities[choice] / pdec
|
|
303
|
+
stepsizes[choice] = stepsizes[choice] / sdec
|
|
304
|
+
flag = '--'
|
|
305
|
+
if np.isnan(fvalnew) and verbose >= 1:
|
|
306
|
+
print('ASD: Warning, objective function returned NaN')
|
|
307
|
+
if verbose > 0 and not (count % max(1, int(1.0/verbose))):
|
|
308
|
+
orig, best, new, diff = sc.sigfig([fvalorig, fvalold, fvalnew, fvalnew - fvalold])
|
|
246
309
|
print(offset + label + f' step {count} ({time.time()-start:0.1f} s) {flag} (orig:{orig} | best:{best} | new:{new} | diff:{diff})')
|
|
247
310
|
|
|
248
|
-
#
|
|
249
|
-
fvals[count] = fval
|
|
250
|
-
allsteps[count, :] = x
|
|
311
|
+
# Record history for this iteration
|
|
312
|
+
fvals[count] = fval
|
|
313
|
+
allsteps[count, :] = x
|
|
251
314
|
|
|
252
315
|
# Stopping criteria
|
|
253
316
|
if count >= maxiters: # Stop if the iteration limit is exceeded # pragma: no cover
|
|
254
317
|
exitreason = 'Maximum iterations reached'
|
|
255
318
|
break
|
|
256
|
-
if (time.time() - start) > maxtime: # pragma: no cover
|
|
319
|
+
if (time.time() - start) > maxtime: # Stop if the time limit is exceeded # pragma: no cover
|
|
257
320
|
strtime, strmax = sc.sigfig([(time.time()-start), maxtime])
|
|
258
321
|
exitreason = f'Time limit reached ({strtime} > {strmax})'
|
|
259
322
|
break
|
|
260
|
-
if (count > stalliters) and (abs(np.mean(abserrorhistory)) < abstol): # Stop if improvement is too small
|
|
323
|
+
if (count > stalliters) and (abs(np.mean(abserrorhistory)) < abstol): # Stop if absolute improvement is too small
|
|
261
324
|
strabs, strtol = sc.sigfig([np.mean(abserrorhistory), abstol])
|
|
262
325
|
exitreason = f'Absolute improvement too small ({strabs} < {strtol})'
|
|
263
326
|
break
|
|
264
|
-
if (count > stalliters) and (sum(relerrorhistory) < reltol): # Stop if
|
|
327
|
+
if (count > stalliters) and (sum(relerrorhistory) < reltol): # Stop if relativeimprovement is too small
|
|
265
328
|
strrel, strtol = sc.sigfig([np.mean(relerrorhistory), reltol])
|
|
266
329
|
exitreason = f'Relative improvement too small ({strrel} < {strtol})'
|
|
267
330
|
break
|
|
268
|
-
if stoppingfunc and stoppingfunc(): # pragma: no cover
|
|
331
|
+
if stoppingfunc and stoppingfunc(): # Stop if explicitly requested # pragma: no cover
|
|
269
332
|
exitreason = 'Stopping function called'
|
|
270
333
|
break
|
|
271
|
-
if fval == minval:
|
|
334
|
+
if fval == minval: # Stop if the objective function value is at the minimum
|
|
272
335
|
exitreason = f'Minimum objective function value reached ({fval})'
|
|
273
336
|
break
|
|
274
337
|
|
|
275
|
-
#
|
|
338
|
+
# Build and return result
|
|
276
339
|
if verbose > 0:
|
|
277
340
|
orig, best = sc.sigfig([fvals[0], fvals[count]])
|
|
278
|
-
|
|
279
|
-
if abs(fvals[count])<eps and abs(fvals[0])<eps:
|
|
280
|
-
ratio = 1 # They're both zero: set the ratio to 1
|
|
281
|
-
elif abs(fvals[0])<eps:
|
|
282
|
-
ratio = 1.0/eps # Only the denominator is zero: reset to the maximum ratio
|
|
283
|
-
else:
|
|
284
|
-
ratio = fvals[count]/float(fvals[0]) # The normal situation: calculate the real ratio
|
|
285
|
-
|
|
341
|
+
ratio = _improvement_ratio(fvals[0], fvals[count], eps)
|
|
286
342
|
print(f'=== {label} {exitreason} ({count} steps, orig: {orig} | best: {best} | ratio: {ratio}) ===')
|
|
287
343
|
|
|
288
|
-
output = sc.objdict(
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
344
|
+
output = sc.objdict(
|
|
345
|
+
x = np.reshape(x, origshape), # Parameters
|
|
346
|
+
fval = fvals[count],
|
|
347
|
+
exitreason = exitreason,
|
|
348
|
+
details = sc.objdict(
|
|
349
|
+
fvals = fvals[:count+1], # Function evaluations
|
|
350
|
+
xvals = allsteps[:count+1, :],
|
|
351
|
+
probabilities = probabilities,
|
|
352
|
+
stepsizes = stepsizes
|
|
353
|
+
)
|
|
354
|
+
)
|
|
355
|
+
return output
|
|
@@ -5,11 +5,6 @@ Highlights:
|
|
|
5
5
|
- :class:`sc.odict() <odict>`: flexible container representing the best-of-all-worlds across dicts, lists, and arrays
|
|
6
6
|
- :class:`objdict`: like an odict, but allows get/set via e.g. ``foo.bar`` instead of ``foo['bar']``
|
|
7
7
|
"""
|
|
8
|
-
|
|
9
|
-
##############################################################################
|
|
10
|
-
#%% odict class
|
|
11
|
-
##############################################################################
|
|
12
|
-
|
|
13
8
|
import re
|
|
14
9
|
import sys
|
|
15
10
|
import json
|
|
@@ -67,6 +62,11 @@ class counter(co.Counter):
|
|
|
67
62
|
raise AttributeError(errormsg) from e
|
|
68
63
|
|
|
69
64
|
|
|
65
|
+
##############################################################################
|
|
66
|
+
#%% odict class
|
|
67
|
+
##############################################################################
|
|
68
|
+
|
|
69
|
+
|
|
70
70
|
class odict(dict):
|
|
71
71
|
"""
|
|
72
72
|
Ordered dictionary with integer indexing
|
|
@@ -138,7 +138,7 @@ class odict(dict):
|
|
|
138
138
|
if defaultdict != 'nested' and not callable(defaultdict): # pragma: no cover
|
|
139
139
|
errormsg = f'The defaultdict argument must be either "nested" or callable, not {type(defaultdict)}'
|
|
140
140
|
raise TypeError(errormsg)
|
|
141
|
-
self._setattr('_defaultdict', defaultdict) # Use
|
|
141
|
+
self._setattr('_defaultdict', defaultdict) # Use object.__setattr__() since setattr() is overridden by sc.objdict()
|
|
142
142
|
|
|
143
143
|
self._cache_keys()
|
|
144
144
|
return
|
|
@@ -158,8 +158,8 @@ class odict(dict):
|
|
|
158
158
|
|
|
159
159
|
|
|
160
160
|
def _setattr(self, key, value):
|
|
161
|
-
""" Shortcut to
|
|
162
|
-
return
|
|
161
|
+
""" Shortcut to object method """
|
|
162
|
+
return object.__setattr__(self, key, value)
|
|
163
163
|
|
|
164
164
|
|
|
165
165
|
def _setitem(self, key, value):
|
|
@@ -179,7 +179,7 @@ class odict(dict):
|
|
|
179
179
|
if isinstance(key, sc._stringtypes) or isinstance(key, tuple): # Normal use case: just use a string key
|
|
180
180
|
if isinstance(E, KeyError): # We already encountered an exception, usually a KeyError
|
|
181
181
|
try: # Handle defaultdict behavior by first checking if it exists
|
|
182
|
-
_defaultdict =
|
|
182
|
+
_defaultdict = object.__getattribute__(self, '_defaultdict')
|
|
183
183
|
except:
|
|
184
184
|
_defaultdict = None
|
|
185
185
|
if _defaultdict is not None and allow_default: # If it does, use it, then get the key again
|
|
@@ -1208,8 +1208,8 @@ class objdict(odict):
|
|
|
1208
1208
|
nested_parent = kwargs.pop('_nested_parent', None)
|
|
1209
1209
|
nested_attr = kwargs.pop('_nested_attr', None)
|
|
1210
1210
|
if nested_parent is not None:
|
|
1211
|
-
|
|
1212
|
-
|
|
1211
|
+
object.__setattr__(self, '_nested_parent', nested_parent)
|
|
1212
|
+
object.__setattr__(self, '_nested_attr', nested_attr)
|
|
1213
1213
|
odict.__init__(self, *args, **kwargs) # Standard init
|
|
1214
1214
|
return
|
|
1215
1215
|
|
|
@@ -1226,22 +1226,22 @@ class objdict(odict):
|
|
|
1226
1226
|
return object.__getattribute__(self, attr)
|
|
1227
1227
|
else:
|
|
1228
1228
|
try: # First, try to get the attribute as an attribute
|
|
1229
|
-
return
|
|
1229
|
+
return object.__getattribute__(self, attr)
|
|
1230
1230
|
except Exception as E: # If that fails, try to get it as a dict item, but pass along the original exception
|
|
1231
1231
|
return self.__getitem__(attr, exception=E)
|
|
1232
1232
|
|
|
1233
1233
|
|
|
1234
1234
|
def __setattr__(self, name, value):
|
|
1235
1235
|
""" Set key in dict, not attribute! """
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1236
|
+
if name[:2] == '__': # If it starts with a double underscore, it's almost certainly an attribute, not a key
|
|
1237
|
+
return object.__setattr__(self, name, value)
|
|
1238
|
+
else:
|
|
1239
|
+
try:
|
|
1240
|
+
object.__getattribute__(self, name) # Try retrieving this as an attribute, expect AttributeError...
|
|
1241
1241
|
errormsg = f'"{name}" exists as an attribute, so cannot be set as key; use setattribute() instead'
|
|
1242
|
-
raise
|
|
1243
|
-
|
|
1244
|
-
|
|
1242
|
+
raise KeyError(errormsg)
|
|
1243
|
+
except AttributeError:
|
|
1244
|
+
return self.__setitem__(name, value) # If so, simply return
|
|
1245
1245
|
|
|
1246
1246
|
|
|
1247
1247
|
def __getitem__(self, attr, exception=None):
|
|
@@ -1250,7 +1250,7 @@ class objdict(odict):
|
|
|
1250
1250
|
return odict.__getitem__(self, attr, allow_default=False) # Do not allow odict to handle default
|
|
1251
1251
|
except Exception as E2: # If that fails, raise the original exception
|
|
1252
1252
|
try: # Handle defaultdict behavior by first checking if it exists
|
|
1253
|
-
_defaultdict =
|
|
1253
|
+
_defaultdict = object.__getattribute__(self, '_defaultdict')
|
|
1254
1254
|
except:
|
|
1255
1255
|
_defaultdict = None
|
|
1256
1256
|
if _defaultdict is not None: # If it does, use it, then get the key again
|
|
@@ -1288,13 +1288,13 @@ class objdict(odict):
|
|
|
1288
1288
|
try:
|
|
1289
1289
|
del self[name]
|
|
1290
1290
|
except: # pragma: no cover
|
|
1291
|
-
|
|
1291
|
+
object.__delattr__(self, name)
|
|
1292
1292
|
return
|
|
1293
1293
|
|
|
1294
1294
|
|
|
1295
1295
|
def getattribute(self, name):
|
|
1296
1296
|
""" Get attribute if truly desired """
|
|
1297
|
-
return
|
|
1297
|
+
return object.__getattribute__(self, name)
|
|
1298
1298
|
|
|
1299
1299
|
|
|
1300
1300
|
def setattribute(self, name, value, force=False):
|
|
@@ -1302,12 +1302,12 @@ class objdict(odict):
|
|
|
1302
1302
|
if hasattr(self.__class__, name) and not force:
|
|
1303
1303
|
errormsg = f'objdict attribute "{name}" is read-only'
|
|
1304
1304
|
raise AttributeError(errormsg)
|
|
1305
|
-
return
|
|
1305
|
+
return object.__setattr__(self, name, value)
|
|
1306
1306
|
|
|
1307
1307
|
|
|
1308
1308
|
def delattribute(self, name):
|
|
1309
1309
|
""" Delete attribute if truly desired """
|
|
1310
|
-
return
|
|
1310
|
+
return object.__delattr__(self, name)
|
|
1311
1311
|
|
|
1312
1312
|
|
|
1313
1313
|
class dictobj(dict):
|
|
@@ -580,7 +580,10 @@ class profile(sc.prettyobj):
|
|
|
580
580
|
context_stack.pop()
|
|
581
581
|
|
|
582
582
|
def visit_FunctionDef(self, node):
|
|
583
|
-
|
|
583
|
+
# Check def line and decorator lines; in Python 3.11+,
|
|
584
|
+
# co_firstlineno points to the first decorator, not the def
|
|
585
|
+
match_lines = {node.lineno} | {d.lineno for d in node.decorator_list}
|
|
586
|
+
if lineno in match_lines:
|
|
584
587
|
context_stack.append(node.name)
|
|
585
588
|
nonlocal name
|
|
586
589
|
name = '.'.join(context_stack)
|
|
@@ -656,8 +659,17 @@ class profile(sc.prettyobj):
|
|
|
656
659
|
)
|
|
657
660
|
self.output[name] = entry
|
|
658
661
|
|
|
659
|
-
#
|
|
660
|
-
|
|
662
|
+
# Determine the name of the run function from the actual function object
|
|
663
|
+
# (can't assume the last chunk since line_profiler may sort by filename)
|
|
664
|
+
run_func = self.run_func
|
|
665
|
+
if hasattr(run_func, '__func__'):
|
|
666
|
+
run_func = run_func.__func__
|
|
667
|
+
if hasattr(run_func, '__code__'):
|
|
668
|
+
run_file = run_func.__code__.co_filename
|
|
669
|
+
run_lineno = run_func.__code__.co_firstlineno
|
|
670
|
+
self.run_func_name = self._path_to_name(run_file, run_lineno)
|
|
671
|
+
else:
|
|
672
|
+
self.run_func_name = name # Fallback to last chunk
|
|
661
673
|
|
|
662
674
|
# Sort and convert to dataframe
|
|
663
675
|
self.sort()
|
|
@@ -4,6 +4,6 @@ Version and license information.
|
|
|
4
4
|
|
|
5
5
|
__all__ = ['__version__', '__versiondate__', '__license__']
|
|
6
6
|
|
|
7
|
-
__version__ = '3.2.
|
|
8
|
-
__versiondate__ = '2026-02-
|
|
7
|
+
__version__ = '3.2.8'
|
|
8
|
+
__versiondate__ = '2026-02-28'
|
|
9
9
|
__license__ = f'Sciris {__version__} ({__versiondate__}) – © 2014-2026 by the Sciris Development Team'
|