diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..cddfd28 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +# insert_final_newline = true +indent_style = tab diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..cd33aba --- /dev/null +++ b/.flake8 @@ -0,0 +1,3 @@ +[flake8] +ignore = W191, E501, W503, W504 +max-line-length = 120 diff --git a/.gitignore b/.gitignore index 75aa508..125bfe3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,140 +1,142 @@ -.idea/**/* - -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ -cover/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -.pybuilder/ -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# pytype static type analyzer -.pytype/ - -# Cython debug symbols -cython_debug/ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +pytest.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +.csv +.idea diff --git a/.versionrc b/.versionrc new file mode 100644 index 0000000..7889a88 --- /dev/null +++ b/.versionrc @@ -0,0 +1,10 @@ +{ + "bumpFiles": [ + { + "filename": "pyproject.toml", + "updater": "scripts/standard-version/pyproject-updater.js" + } + ], + "sign": true, + "tag-prefix": "" +} diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..f40513d --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,81 @@ +pipeline { + agent { + kubernetes { + label 'pynam' // all your pods will be named with this prefix, followed by a unique id + idleMinutes 5 // how long the pod will live after no jobs have run on it + yamlFile 'jenkins/ci-agent-pod.yaml' // path to the pod definition relative to the root of our project + defaultContainer 'poetry' // define a default container if more than a few stages use it, will default to jnlp container + } + } + + options { + parallelsAlwaysFailFast() + } + + stages { + stage('Build') { + steps { + echo 'Building...' + sh 'python --version' + sh 'poetry --version' + sh 'poetry install' + } + } + stage('Test') { + parallel{ + stage('pytest') { + steps { + sh 'poetry run pytest --benchmark-skip' + } + } + stage('lint') { + steps { + sh 'poetry run flake8 pynam tests' + } + } + stage('mypy') { + steps { + sh 'poetry run mypy pynam' + } + } + } + } + + stage('Deploy') { + environment { + PYPI=credentials("pypi-pynam") + } + + when { + buildingTag() + } + steps { + echo 'Deploying...' + sh 'poetry publish -u ${PYPI_USR} -p ${PYPI_PSW} --build' + } + } + + } + post { + always { + echo 'This will always run' + junit 'pytest.xml' + cobertura coberturaReportFile: 'coverage.xml' + mail (bcc: '', + body: "Project: ${env.JOB_NAME}
Build Number: ${env.BUILD_NUMBER}
Build URL: ${env.BUILD_URL}", cc: '', charset: 'UTF-8', from: 'jenkins@jenkins.deepak.science', mimeType: 'text/html', replyTo: 'dmallubhotla+jenkins@gmail.com', subject: "${env.JOB_NAME} #${env.BUILD_NUMBER}: Build ${currentBuild.currentResult}", to: "dmallubhotla+ci@gmail.com") + } + success { + echo 'This will run only if successful' + } + failure { + echo 'This will run only if failed' + } + unstable { + echo 'This will run only if the run was marked as unstable' + } + changed { + echo 'This will run only if the state of the Pipeline has changed' + echo 'For example, if the Pipeline was previously failing but is now successful' + } + } +} diff --git a/do.sh b/do.sh new file mode 100644 index 0000000..2ab1420 --- /dev/null +++ b/do.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Do - The Simplest Build Tool on Earth. +# Documentation and examples see https://github.com/8gears/do + +set -Eeuo pipefail # -e "Automatic exit from bash shell script on error" -u "Treat unset variables and parameters as errors" + +build() { + echo "I am ${FUNCNAME[0]}ing" + poetry build +} + +fmt() { + poetry run black . + find . -type f -name "*.py" -exec sed -i -e 's/ /\t/g' {} \; +} + +test() { + echo "I am ${FUNCNAME[0]}ing" + poetry run flake8 pynam tests + poetry run mypy pynam + poetry run pytest +} + +htmlcov() { + poetry run pytest --cov-report=html +} + +release() { + ./scripts/release.sh +} + +all() { + build && test +} + +"$@" # <- execute the task + +[ "$#" -gt 0 ] || printf "Usage:\n\t./do.sh %s\n" "($(compgen -A function | grep '^[^_]' | paste -sd '|' -))" diff --git a/jenkins/ci-agent-pod.yaml b/jenkins/ci-agent-pod.yaml new file mode 100644 index 0000000..f3ed483 --- /dev/null +++ b/jenkins/ci-agent-pod.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +spec: + imagePullSecrets: + - name: regcreds + containers: # list of containers that you want present for your build, you can define a default container in the Jenkinsfile + - name: poetry + image: ghcr.io/dmallubhotla/poetry-image:1 + command: ["tail", "-f", "/dev/null"] # this or any command that is bascially a noop is required, this is so that you don't overwrite the entrypoint of the base container + imagePullPolicy: Always # use cache or pull image for agent + resources: # limits the resources your build contaienr + requests: + memory: "2Gi" + cpu: "500m" + limits: + memory: "2Gi" diff --git a/poetry.lock b/poetry.lock index 06aa4c7..ee55f54 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,260 +1,539 @@ -[[package]] -category = "dev" -description = "Atomic file writes." -name = "atomicwrites" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.4.0" - -[[package]] -category = "dev" -description = "Classes Without Boilerplate" -name = "attrs" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "19.3.0" - -[package.extras] -azure-pipelines = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "pytest-azurepipelines"] -dev = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "pre-commit"] -docs = ["sphinx", "zope.interface"] -tests = ["coverage", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] - -[[package]] -category = "dev" -description = "Cross-platform colored terminal text." -marker = "sys_platform == \"win32\"" -name = "colorama" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "0.4.3" - -[[package]] -category = "dev" -description = "Read metadata from Python packages" -marker = "python_version < \"3.8\"" -name = "importlib-metadata" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" -version = "1.7.0" - -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -docs = ["sphinx", "rst.linker"] -testing = ["packaging", "pep517", "importlib-resources (>=1.3)"] - -[[package]] -category = "dev" -description = "More routines for operating on iterables, beyond itertools" -name = "more-itertools" -optional = false -python-versions = ">=3.5" -version = "8.4.0" - -[[package]] -category = "main" -description = "NumPy is the fundamental package for array computing with Python." -name = "numpy" -optional = false -python-versions = ">=3.6" -version = "1.19.0" - -[[package]] -category = "dev" -description = "plugin and hook calling mechanisms for python" -name = "pluggy" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "0.13.1" - -[package.dependencies] -[package.dependencies.importlib-metadata] -python = "<3.8" -version = ">=0.12" - -[package.extras] -dev = ["pre-commit", "tox"] - -[[package]] -category = "dev" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -name = "py" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "1.9.0" - -[[package]] -category = "dev" -description = "Get CPU info with pure Python 2 & 3" -name = "py-cpuinfo" -optional = false -python-versions = "*" -version = "7.0.0" - -[[package]] -category = "dev" -description = "pytest: simple powerful testing with Python" -name = "pytest" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -version = "3.10.1" - -[package.dependencies] -atomicwrites = ">=1.0" -attrs = ">=17.4.0" -colorama = "*" -more-itertools = ">=4.0.0" -pluggy = ">=0.7" -py = ">=1.5.0" -setuptools = "*" -six = ">=1.10.0" - -[[package]] -category = "dev" -description = "A ``pytest`` fixture for benchmarking code. It will group the tests into rounds that are calibrated to the chosen timer. See calibration_ and FAQ_." -name = "pytest-benchmark" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -version = "3.2.3" - -[package.dependencies] -py-cpuinfo = "*" -pytest = ">=3.8" - -[package.extras] -aspect = ["aspectlib"] -elasticsearch = ["elasticsearch"] -histogram = ["pygal", "pygaljs"] - -[[package]] -category = "main" -description = "SciPy: Scientific Library for Python" -name = "scipy" -optional = false -python-versions = ">=3.6" -version = "1.5.1" - -[package.dependencies] -numpy = ">=1.14.5" - -[[package]] -category = "dev" -description = "Python 2 and 3 compatibility utilities" -name = "six" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -version = "1.15.0" - -[[package]] -category = "dev" -description = "Backport of pathlib-compatible object wrapper for zip files" -marker = "python_version < \"3.8\"" -name = "zipp" -optional = false -python-versions = ">=3.6" -version = "3.1.0" - -[package.extras] -docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] -testing = ["jaraco.itertools", "func-timeout"] - -[metadata] -content-hash = "02f8a795ac396fe3c5adcc163c673e4e53b1c63fb5d0840c5319169093cd3a5f" -python-versions = "^3.7" - -[metadata.files] -atomicwrites = [ - {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, - {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, -] -attrs = [ - {file = "attrs-19.3.0-py2.py3-none-any.whl", hash = "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c"}, - {file = "attrs-19.3.0.tar.gz", hash = "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"}, -] -colorama = [ - {file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"}, - {file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"}, -] -importlib-metadata = [ - {file = "importlib_metadata-1.7.0-py2.py3-none-any.whl", hash = "sha256:dc15b2969b4ce36305c51eebe62d418ac7791e9a157911d58bfb1f9ccd8e2070"}, - {file = "importlib_metadata-1.7.0.tar.gz", hash = "sha256:90bb658cdbbf6d1735b6341ce708fc7024a3e14e99ffdc5783edea9f9b077f83"}, -] -more-itertools = [ - {file = "more-itertools-8.4.0.tar.gz", hash = "sha256:68c70cc7167bdf5c7c9d8f6954a7837089c6a36bf565383919bb595efb8a17e5"}, - {file = "more_itertools-8.4.0-py3-none-any.whl", hash = "sha256:b78134b2063dd214000685165d81c154522c3ee0a1c0d4d113c80361c234c5a2"}, -] -numpy = [ - {file = "numpy-1.19.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:63d971bb211ad3ca37b2adecdd5365f40f3b741a455beecba70fd0dde8b2a4cb"}, - {file = "numpy-1.19.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:b6aaeadf1e4866ca0fdf7bb4eed25e521ae21a7947c59f78154b24fc7abbe1dd"}, - {file = "numpy-1.19.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:13af0184177469192d80db9bd02619f6fa8b922f9f327e077d6f2a6acb1ce1c0"}, - {file = "numpy-1.19.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:356f96c9fbec59974a592452ab6a036cd6f180822a60b529a975c9467fcd5f23"}, - {file = "numpy-1.19.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa1fe75b4a9e18b66ae7f0b122543c42debcf800aaafa0212aaff3ad273c2596"}, - {file = "numpy-1.19.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:cbe326f6d364375a8e5a8ccb7e9cd73f4b2f6dc3b2ed205633a0db8243e2a96a"}, - {file = "numpy-1.19.0-cp36-cp36m-win32.whl", hash = "sha256:a2e3a39f43f0ce95204beb8fe0831199542ccab1e0c6e486a0b4947256215632"}, - {file = "numpy-1.19.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7b852817800eb02e109ae4a9cef2beda8dd50d98b76b6cfb7b5c0099d27b52d4"}, - {file = "numpy-1.19.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d97a86937cf9970453c3b62abb55a6475f173347b4cde7f8dcdb48c8e1b9952d"}, - {file = "numpy-1.19.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:a86c962e211f37edd61d6e11bb4df7eddc4a519a38a856e20a6498c319efa6b0"}, - {file = "numpy-1.19.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d34fbb98ad0d6b563b95de852a284074514331e6b9da0a9fc894fb1cdae7a79e"}, - {file = "numpy-1.19.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:658624a11f6e1c252b2cd170d94bf28c8f9410acab9f2fd4369e11e1cd4e1aaf"}, - {file = "numpy-1.19.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:4d054f013a1983551254e2379385e359884e5af105e3efe00418977d02f634a7"}, - {file = "numpy-1.19.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:26a45798ca2a4e168d00de75d4a524abf5907949231512f372b217ede3429e98"}, - {file = "numpy-1.19.0-cp37-cp37m-win32.whl", hash = "sha256:3c40c827d36c6d1c3cf413694d7dc843d50997ebffbc7c87d888a203ed6403a7"}, - {file = "numpy-1.19.0-cp37-cp37m-win_amd64.whl", hash = "sha256:be62aeff8f2f054eff7725f502f6228298891fd648dc2630e03e44bf63e8cee0"}, - {file = "numpy-1.19.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dd53d7c4a69e766e4900f29db5872f5824a06827d594427cf1a4aa542818b796"}, - {file = "numpy-1.19.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:30a59fb41bb6b8c465ab50d60a1b298d1cd7b85274e71f38af5a75d6c475d2d2"}, - {file = "numpy-1.19.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:df1889701e2dfd8ba4dc9b1a010f0a60950077fb5242bb92c8b5c7f1a6f2668a"}, - {file = "numpy-1.19.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:33c623ef9ca5e19e05991f127c1be5aeb1ab5cdf30cb1c5cf3960752e58b599b"}, - {file = "numpy-1.19.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:26f509450db547e4dfa3ec739419b31edad646d21fb8d0ed0734188b35ff6b27"}, - {file = "numpy-1.19.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:7b57f26e5e6ee2f14f960db46bd58ffdca25ca06dd997729b1b179fddd35f5a3"}, - {file = "numpy-1.19.0-cp38-cp38-win32.whl", hash = "sha256:a8705c5073fe3fcc297fb8e0b31aa794e05af6a329e81b7ca4ffecab7f2b95ef"}, - {file = "numpy-1.19.0-cp38-cp38-win_amd64.whl", hash = "sha256:c2edbb783c841e36ca0fa159f0ae97a88ce8137fb3a6cd82eae77349ba4b607b"}, - {file = "numpy-1.19.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:8cde829f14bd38f6da7b2954be0f2837043e8b8d7a9110ec5e318ae6bf706610"}, - {file = "numpy-1.19.0.zip", hash = "sha256:76766cc80d6128750075378d3bb7812cf146415bd29b588616f72c943c00d598"}, -] -pluggy = [ - {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, - {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, -] -py = [ - {file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"}, - {file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"}, -] -py-cpuinfo = [ - {file = "py-cpuinfo-7.0.0.tar.gz", hash = "sha256:9aa2e49675114959697d25cf57fec41c29b55887bff3bc4809b44ac6f5730097"}, -] -pytest = [ - {file = "pytest-3.10.1-py2.py3-none-any.whl", hash = "sha256:3f193df1cfe1d1609d4c583838bea3d532b18d6160fd3f55c9447fdca30848ec"}, - {file = "pytest-3.10.1.tar.gz", hash = "sha256:e246cf173c01169b9617fc07264b7b1316e78d7a650055235d6d897bc80d9660"}, -] -pytest-benchmark = [ - {file = "pytest-benchmark-3.2.3.tar.gz", hash = "sha256:ad4314d093a3089701b24c80a05121994c7765ce373478c8f4ba8d23c9ba9528"}, - {file = "pytest_benchmark-3.2.3-py2.py3-none-any.whl", hash = "sha256:01f79d38d506f5a3a0a9ada22ded714537bbdfc8147a881a35c1655db07289d9"}, -] -scipy = [ - {file = "scipy-1.5.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:058e84930407927f71963a4ad8c1dc96c4d2d075636a68578195648c81f78810"}, - {file = "scipy-1.5.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:7908c85854c5b5b6d3ce7fefafac1ca3e23ff9ac41edabc2d46ae5dc9fa070ac"}, - {file = "scipy-1.5.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8302d69fb1528ea7c7f2a1ea640d354c981b6eb8192d1c175349874209397604"}, - {file = "scipy-1.5.1-cp36-cp36m-win32.whl", hash = "sha256:35d042d6499caf1a5d171baed0ebf01eb665b7af2ad98a8ff1b0e6e783654540"}, - {file = "scipy-1.5.1-cp36-cp36m-win_amd64.whl", hash = "sha256:5e0bb43ff581811ab7f27425f6b96c1ddf7591ccad2e486c9af0b910c18f7185"}, - {file = "scipy-1.5.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b4858ccbd88f4b53950fb9fc0069c1d9fea83d7cff2382e1d8b023d3f4883014"}, - {file = "scipy-1.5.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:eb46d8b5947ca27b0bc972cecfba8130f088a83ab3d08c1a6033d9070b3046b3"}, - {file = "scipy-1.5.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:fff15df01bef1243468be60c55178ed7576270b200aab08a7ffd5b8e0bbc340c"}, - {file = "scipy-1.5.1-cp37-cp37m-win32.whl", hash = "sha256:81859ed3aad620752dd2c07c32b5d3a80a0d47c5e3813904621954a78a0ae899"}, - {file = "scipy-1.5.1-cp37-cp37m-win_amd64.whl", hash = "sha256:c05c6fe76228cc13c5214e9faf5f2a871a1da54473bc417ab9da310d0e5fff8b"}, - {file = "scipy-1.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:71742889393a724dfce755b6b61228677873d269a4234e51ddaf08b998433c91"}, - {file = "scipy-1.5.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:9323d268775991b79690f7b9a28a4e8b8c4f2b160ed9f8a90123127314e2d3c1"}, - {file = "scipy-1.5.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:06b19a650471781056c1a2172eeeeb777b8b516e9434005dd392a4559e0938b9"}, - {file = "scipy-1.5.1-cp38-cp38-win32.whl", hash = "sha256:57a0f2be3063dbe1e3daf31ec9005576e8fd1022a28159d0db71d14566899d16"}, - {file = "scipy-1.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:c06e731aa46c0dfc563cc636155758178ebc019ef78b9b0f4370effe2ac0f0e6"}, - {file = "scipy-1.5.1.tar.gz", hash = "sha256:039572f0ca9578a466683558c5bf1e65d442860ec6e13307d528749cfe6d07b8"}, -] -six = [ - {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, - {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, -] -zipp = [ - {file = "zipp-3.1.0-py3-none-any.whl", hash = "sha256:aa36550ff0c0b7ef7fa639055d797116ee891440eac1a56f378e2d3179e0320b"}, - {file = "zipp-3.1.0.tar.gz", hash = "sha256:c599e4d75c98f6798c509911d08a22e6c021d074469042177c8c86fb92eefd96"}, -] +[[package]] +name = "atomicwrites" +version = "1.4.0" +description = "Atomic file writes." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "attrs" +version = "21.4.0" +description = "Classes Without Boilerplate" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.extras] +dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] +docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] +tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] +tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] + +[[package]] +name = "black" +version = "22.3.0" +description = "The uncompromising code formatter." +category = "dev" +optional = false +python-versions = ">=3.6.2" + +[package.dependencies] +click = ">=8.0.0" +mypy-extensions = ">=0.4.3" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} + +[package.extras] +colorama = ["colorama (>=0.4.3)"] +d = ["aiohttp (>=3.7.4)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] + +[[package]] +name = "click" +version = "8.1.0" +description = "Composable command line interface toolkit" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.4" +description = "Cross-platform colored terminal text." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "coverage" +version = "6.3.2" +description = "Code coverage measurement for Python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "extra == \"toml\""} + +[package.extras] +toml = ["tomli"] + +[[package]] +name = "flake8" +version = "4.0.1" +description = "the modular source code checker: pep8 pyflakes and co" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +mccabe = ">=0.6.0,<0.7.0" +pycodestyle = ">=2.8.0,<2.9.0" +pyflakes = ">=2.4.0,<2.5.0" + +[[package]] +name = "iniconfig" +version = "1.1.1" +description = "iniconfig: brain-dead simple config-ini parsing" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "mccabe" +version = "0.6.1" +description = "McCabe checker, plugin for flake8" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "mypy" +version = "0.942" +description = "Optional static typing for Python" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +mypy-extensions = ">=0.4.3" +tomli = ">=1.1.0" +typing-extensions = ">=3.10" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +python2 = ["typed-ast (>=1.4.0,<2)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "0.4.3" +description = "Experimental type system extensions for programs checked with the mypy typechecker." +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "numpy" +version = "1.22.3" +description = "NumPy is the fundamental package for array computing with Python." +category = "main" +optional = false +python-versions = ">=3.8" + +[[package]] +name = "packaging" +version = "21.3" +description = "Core utilities for Python packages" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" + +[[package]] +name = "pathspec" +version = "0.9.0" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[[package]] +name = "platformdirs" +version = "2.5.1" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] +test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] + +[[package]] +name = "pluggy" +version = "1.0.0" +description = "plugin and hook calling mechanisms for python" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "py" +version = "1.11.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "py-cpuinfo" +version = "8.0.0" +description = "Get CPU info with pure Python 2 & 3" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "pycodestyle" +version = "2.8.0" +description = "Python style guide checker" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "pyflakes" +version = "2.4.0" +description = "passive checker of Python programs" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" + +[[package]] +name = "pyparsing" +version = "3.0.7" +description = "Python parsing module" +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.extras] +diagrams = ["jinja2", "railroad-diagrams"] + +[[package]] +name = "pytest" +version = "7.1.1" +description = "pytest: simple powerful testing with Python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} +attrs = ">=19.2.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +py = ">=1.8.2" +tomli = ">=1.0.0" + +[package.extras] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] + +[[package]] +name = "pytest-benchmark" +version = "3.4.1" +description = "A ``pytest`` fixture for benchmarking code. It will group the tests into rounds that are calibrated to the chosen timer." +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +py-cpuinfo = "*" +pytest = ">=3.8" + +[package.extras] +aspect = ["aspectlib"] +elasticsearch = ["elasticsearch"] +histogram = ["pygal", "pygaljs"] + +[[package]] +name = "pytest-cov" +version = "3.0.0" +description = "Pytest plugin for measuring coverage." +category = "dev" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] + +[[package]] +name = "scipy" +version = "1.8.0" +description = "SciPy: Scientific Library for Python" +category = "main" +optional = false +python-versions = ">=3.8,<3.11" + +[package.dependencies] +numpy = ">=1.17.3,<1.25.0" + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +category = "dev" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "typing-extensions" +version = "4.1.1" +description = "Backported and Experimental Type Hints for Python 3.6+" +category = "dev" +optional = false +python-versions = ">=3.6" + +[metadata] +lock-version = "1.1" +python-versions = "^3.8,<3.10" +content-hash = "d7ee7d61a1643514f418ae5fd9d76c6557a597bc9bf43355ed335db8f1fdda7d" + +[metadata.files] +atomicwrites = [ + {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, + {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, +] +attrs = [ + {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, + {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, +] +black = [ + {file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"}, + {file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"}, + {file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"}, + {file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"}, + {file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"}, + {file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"}, + {file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"}, + {file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"}, + {file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"}, + {file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"}, + {file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"}, + {file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"}, + {file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"}, + {file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"}, + {file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"}, + {file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"}, + {file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"}, + {file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"}, + {file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"}, + {file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"}, + {file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"}, + {file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"}, + {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"}, +] +click = [ + {file = "click-8.1.0-py3-none-any.whl", hash = "sha256:19a4baa64da924c5e0cd889aba8e947f280309f1a2ce0947a3e3a7bcb7cc72d6"}, + {file = "click-8.1.0.tar.gz", hash = "sha256:977c213473c7665d3aa092b41ff12063227751c41d7b17165013e10069cc5cd2"}, +] +colorama = [ + {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, + {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, +] +coverage = [ + {file = "coverage-6.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9b27d894748475fa858f9597c0ee1d4829f44683f3813633aaf94b19cb5453cf"}, + {file = "coverage-6.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37d1141ad6b2466a7b53a22e08fe76994c2d35a5b6b469590424a9953155afac"}, + {file = "coverage-6.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9987b0354b06d4df0f4d3e0ec1ae76d7ce7cbca9a2f98c25041eb79eec766f1"}, + {file = "coverage-6.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:26e2deacd414fc2f97dd9f7676ee3eaecd299ca751412d89f40bc01557a6b1b4"}, + {file = "coverage-6.3.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dd8bafa458b5c7d061540f1ee9f18025a68e2d8471b3e858a9dad47c8d41903"}, + {file = "coverage-6.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:46191097ebc381fbf89bdce207a6c107ac4ec0890d8d20f3360345ff5976155c"}, + {file = "coverage-6.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6f89d05e028d274ce4fa1a86887b071ae1755082ef94a6740238cd7a8178804f"}, + {file = "coverage-6.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:58303469e9a272b4abdb9e302a780072c0633cdcc0165db7eec0f9e32f901e05"}, + {file = "coverage-6.3.2-cp310-cp310-win32.whl", hash = "sha256:2fea046bfb455510e05be95e879f0e768d45c10c11509e20e06d8fcaa31d9e39"}, + {file = "coverage-6.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:a2a8b8bcc399edb4347a5ca8b9b87e7524c0967b335fbb08a83c8421489ddee1"}, + {file = "coverage-6.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f1555ea6d6da108e1999b2463ea1003fe03f29213e459145e70edbaf3e004aaa"}, + {file = "coverage-6.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5f4e1edcf57ce94e5475fe09e5afa3e3145081318e5fd1a43a6b4539a97e518"}, + {file = "coverage-6.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a15dc0a14008f1da3d1ebd44bdda3e357dbabdf5a0b5034d38fcde0b5c234b7"}, + {file = "coverage-6.3.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21b7745788866028adeb1e0eca3bf1101109e2dc58456cb49d2d9b99a8c516e6"}, + {file = "coverage-6.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8ce257cac556cb03be4a248d92ed36904a59a4a5ff55a994e92214cde15c5bad"}, + {file = "coverage-6.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b0be84e5a6209858a1d3e8d1806c46214e867ce1b0fd32e4ea03f4bd8b2e3359"}, + {file = "coverage-6.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:acf53bc2cf7282ab9b8ba346746afe703474004d9e566ad164c91a7a59f188a4"}, + {file = "coverage-6.3.2-cp37-cp37m-win32.whl", hash = "sha256:8bdde1177f2311ee552f47ae6e5aa7750c0e3291ca6b75f71f7ffe1f1dab3dca"}, + {file = "coverage-6.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b31651d018b23ec463e95cf10070d0b2c548aa950a03d0b559eaa11c7e5a6fa3"}, + {file = "coverage-6.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:07e6db90cd9686c767dcc593dff16c8c09f9814f5e9c51034066cad3373b914d"}, + {file = "coverage-6.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c6dbb42f3ad25760010c45191e9757e7dce981cbfb90e42feef301d71540059"}, + {file = "coverage-6.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c76aeef1b95aff3905fb2ae2d96e319caca5b76fa41d3470b19d4e4a3a313512"}, + {file = "coverage-6.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cf5cfcb1521dc3255d845d9dca3ff204b3229401994ef8d1984b32746bb45ca"}, + {file = "coverage-6.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fbbdc8d55990eac1b0919ca69eb5a988a802b854488c34b8f37f3e2025fa90d"}, + {file = "coverage-6.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ec6bc7fe73a938933d4178c9b23c4e0568e43e220aef9472c4f6044bfc6dd0f0"}, + {file = "coverage-6.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9baff2a45ae1f17c8078452e9e5962e518eab705e50a0aa8083733ea7d45f3a6"}, + {file = "coverage-6.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd9e830e9d8d89b20ab1e5af09b32d33e1a08ef4c4e14411e559556fd788e6b2"}, + {file = "coverage-6.3.2-cp38-cp38-win32.whl", hash = "sha256:f7331dbf301b7289013175087636bbaf5b2405e57259dd2c42fdcc9fcc47325e"}, + {file = "coverage-6.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:68353fe7cdf91f109fc7d474461b46e7f1f14e533e911a2a2cbb8b0fc8613cf1"}, + {file = "coverage-6.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b78e5afb39941572209f71866aa0b206c12f0109835aa0d601e41552f9b3e620"}, + {file = "coverage-6.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4e21876082ed887baed0146fe222f861b5815455ada3b33b890f4105d806128d"}, + {file = "coverage-6.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34626a7eee2a3da12af0507780bb51eb52dca0e1751fd1471d0810539cefb536"}, + {file = "coverage-6.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1ebf730d2381158ecf3dfd4453fbca0613e16eaa547b4170e2450c9707665ce7"}, + {file = "coverage-6.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd6fe30bd519694b356cbfcaca9bd5c1737cddd20778c6a581ae20dc8c04def2"}, + {file = "coverage-6.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:96f8a1cb43ca1422f36492bebe63312d396491a9165ed3b9231e778d43a7fca4"}, + {file = "coverage-6.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:dd035edafefee4d573140a76fdc785dc38829fe5a455c4bb12bac8c20cfc3d69"}, + {file = "coverage-6.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ca5aeb4344b30d0bec47481536b8ba1181d50dbe783b0e4ad03c95dc1296684"}, + {file = "coverage-6.3.2-cp39-cp39-win32.whl", hash = "sha256:f5fa5803f47e095d7ad8443d28b01d48c0359484fec1b9d8606d0e3282084bc4"}, + {file = "coverage-6.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:9548f10d8be799551eb3a9c74bbf2b4934ddb330e08a73320123c07f95cc2d92"}, + {file = "coverage-6.3.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:18d520c6860515a771708937d2f78f63cc47ab3b80cb78e86573b0a760161faf"}, + {file = "coverage-6.3.2.tar.gz", hash = "sha256:03e2a7826086b91ef345ff18742ee9fc47a6839ccd517061ef8fa1976e652ce9"}, +] +flake8 = [ + {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"}, + {file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"}, +] +iniconfig = [ + {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, + {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, +] +mccabe = [ + {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, + {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, +] +mypy = [ + {file = "mypy-0.942-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5bf44840fb43ac4074636fd47ee476d73f0039f4f54e86d7265077dc199be24d"}, + {file = "mypy-0.942-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dcd955f36e0180258a96f880348fbca54ce092b40fbb4b37372ae3b25a0b0a46"}, + {file = "mypy-0.942-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6776e5fa22381cc761df53e7496a805801c1a751b27b99a9ff2f0ca848c7eca0"}, + {file = "mypy-0.942-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:edf7237137a1a9330046dbb14796963d734dd740a98d5e144a3eb1d267f5f9ee"}, + {file = "mypy-0.942-cp310-cp310-win_amd64.whl", hash = "sha256:64235137edc16bee6f095aba73be5334677d6f6bdb7fa03cfab90164fa294a17"}, + {file = "mypy-0.942-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b840cfe89c4ab6386c40300689cd8645fc8d2d5f20101c7f8bd23d15fca14904"}, + {file = "mypy-0.942-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2b184db8c618c43c3a31b32ff00cd28195d39e9c24e7c3b401f3db7f6e5767f5"}, + {file = "mypy-0.942-cp36-cp36m-win_amd64.whl", hash = "sha256:1a0459c333f00e6a11cbf6b468b870c2b99a906cb72d6eadf3d1d95d38c9352c"}, + {file = "mypy-0.942-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4c3e497588afccfa4334a9986b56f703e75793133c4be3a02d06a3df16b67a58"}, + {file = "mypy-0.942-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f6ad963172152e112b87cc7ec103ba0f2db2f1cd8997237827c052a3903eaa6"}, + {file = "mypy-0.942-cp37-cp37m-win_amd64.whl", hash = "sha256:0e2dd88410937423fba18e57147dd07cd8381291b93d5b1984626f173a26543e"}, + {file = "mypy-0.942-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:246e1aa127d5b78488a4a0594bd95f6d6fb9d63cf08a66dafbff8595d8891f67"}, + {file = "mypy-0.942-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d8d3ba77e56b84cd47a8ee45b62c84b6d80d32383928fe2548c9a124ea0a725c"}, + {file = "mypy-0.942-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2bc249409a7168d37c658e062e1ab5173300984a2dada2589638568ddc1db02b"}, + {file = "mypy-0.942-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9521c1265ccaaa1791d2c13582f06facf815f426cd8b07c3a485f486a8ffc1f3"}, + {file = "mypy-0.942-cp38-cp38-win_amd64.whl", hash = "sha256:e865fec858d75b78b4d63266c9aff770ecb6a39dfb6d6b56c47f7f8aba6baba8"}, + {file = "mypy-0.942-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6ce34a118d1a898f47def970a2042b8af6bdcc01546454726c7dd2171aa6dfca"}, + {file = "mypy-0.942-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:10daab80bc40f84e3f087d896cdb53dc811a9f04eae4b3f95779c26edee89d16"}, + {file = "mypy-0.942-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3841b5433ff936bff2f4dc8d54cf2cdbfea5d8e88cedfac45c161368e5770ba6"}, + {file = "mypy-0.942-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6f7106cbf9cc2f403693bf50ed7c9fa5bb3dfa9007b240db3c910929abe2a322"}, + {file = "mypy-0.942-cp39-cp39-win_amd64.whl", hash = "sha256:7742d2c4e46bb5017b51c810283a6a389296cda03df805a4f7869a6f41246534"}, + {file = "mypy-0.942-py3-none-any.whl", hash = "sha256:a1b383fe99678d7402754fe90448d4037f9512ce70c21f8aee3b8bf48ffc51db"}, + {file = "mypy-0.942.tar.gz", hash = "sha256:17e44649fec92e9f82102b48a3bf7b4a5510ad0cd22fa21a104826b5db4903e2"}, +] +mypy-extensions = [ + {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, + {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, +] +numpy = [ + {file = "numpy-1.22.3-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:92bfa69cfbdf7dfc3040978ad09a48091143cffb778ec3b03fa170c494118d75"}, + {file = "numpy-1.22.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8251ed96f38b47b4295b1ae51631de7ffa8260b5b087808ef09a39a9d66c97ab"}, + {file = "numpy-1.22.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48a3aecd3b997bf452a2dedb11f4e79bc5bfd21a1d4cc760e703c31d57c84b3e"}, + {file = "numpy-1.22.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3bae1a2ed00e90b3ba5f7bd0a7c7999b55d609e0c54ceb2b076a25e345fa9f4"}, + {file = "numpy-1.22.3-cp310-cp310-win32.whl", hash = "sha256:f950f8845b480cffe522913d35567e29dd381b0dc7e4ce6a4a9f9156417d2430"}, + {file = "numpy-1.22.3-cp310-cp310-win_amd64.whl", hash = "sha256:08d9b008d0156c70dc392bb3ab3abb6e7a711383c3247b410b39962263576cd4"}, + {file = "numpy-1.22.3-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:201b4d0552831f7250a08d3b38de0d989d6f6e4658b709a02a73c524ccc6ffce"}, + {file = "numpy-1.22.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8c1f39caad2c896bc0018f699882b345b2a63708008be29b1f355ebf6f933fe"}, + {file = "numpy-1.22.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:568dfd16224abddafb1cbcce2ff14f522abe037268514dd7e42c6776a1c3f8e5"}, + {file = "numpy-1.22.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ca688e1b9b95d80250bca34b11a05e389b1420d00e87a0d12dc45f131f704a1"}, + {file = "numpy-1.22.3-cp38-cp38-win32.whl", hash = "sha256:e7927a589df200c5e23c57970bafbd0cd322459aa7b1ff73b7c2e84d6e3eae62"}, + {file = "numpy-1.22.3-cp38-cp38-win_amd64.whl", hash = "sha256:07a8c89a04997625236c5ecb7afe35a02af3896c8aa01890a849913a2309c676"}, + {file = "numpy-1.22.3-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:2c10a93606e0b4b95c9b04b77dc349b398fdfbda382d2a39ba5a822f669a0123"}, + {file = "numpy-1.22.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fade0d4f4d292b6f39951b6836d7a3c7ef5b2347f3c420cd9820a1d90d794802"}, + {file = "numpy-1.22.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bfb1bb598e8229c2d5d48db1860bcf4311337864ea3efdbe1171fb0c5da515d"}, + {file = "numpy-1.22.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97098b95aa4e418529099c26558eeb8486e66bd1e53a6b606d684d0c3616b168"}, + {file = "numpy-1.22.3-cp39-cp39-win32.whl", hash = "sha256:fdf3c08bce27132395d3c3ba1503cac12e17282358cb4bddc25cc46b0aca07aa"}, + {file = "numpy-1.22.3-cp39-cp39-win_amd64.whl", hash = "sha256:639b54cdf6aa4f82fe37ebf70401bbb74b8508fddcf4797f9fe59615b8c5813a"}, + {file = "numpy-1.22.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c34ea7e9d13a70bf2ab64a2532fe149a9aced424cd05a2c4ba662fd989e3e45f"}, + {file = "numpy-1.22.3.zip", hash = "sha256:dbc7601a3b7472d559dc7b933b18b4b66f9aa7452c120e87dfb33d02008c8a18"}, +] +packaging = [ + {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, + {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, +] +pathspec = [ + {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, + {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, +] +platformdirs = [ + {file = "platformdirs-2.5.1-py3-none-any.whl", hash = "sha256:bcae7cab893c2d310a711b70b24efb93334febe65f8de776ee320b517471e227"}, + {file = "platformdirs-2.5.1.tar.gz", hash = "sha256:7535e70dfa32e84d4b34996ea99c5e432fa29a708d0f4e394bbcb2a8faa4f16d"}, +] +pluggy = [ + {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, +] +py = [ + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] +py-cpuinfo = [ + {file = "py-cpuinfo-8.0.0.tar.gz", hash = "sha256:5f269be0e08e33fd959de96b34cd4aeeeacac014dd8305f70eb28d06de2345c5"}, +] +pycodestyle = [ + {file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"}, + {file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"}, +] +pyflakes = [ + {file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"}, + {file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"}, +] +pyparsing = [ + {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, + {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, +] +pytest = [ + {file = "pytest-7.1.1-py3-none-any.whl", hash = "sha256:92f723789a8fdd7180b6b06483874feca4c48a5c76968e03bb3e7f806a1869ea"}, + {file = "pytest-7.1.1.tar.gz", hash = "sha256:841132caef6b1ad17a9afde46dc4f6cfa59a05f9555aae5151f73bdf2820ca63"}, +] +pytest-benchmark = [ + {file = "pytest-benchmark-3.4.1.tar.gz", hash = "sha256:40e263f912de5a81d891619032983557d62a3d85843f9a9f30b98baea0cd7b47"}, + {file = "pytest_benchmark-3.4.1-py2.py3-none-any.whl", hash = "sha256:36d2b08c4882f6f997fd3126a3d6dfd70f3249cde178ed8bbc0b73db7c20f809"}, +] +pytest-cov = [ + {file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"}, + {file = "pytest_cov-3.0.0-py3-none-any.whl", hash = "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6"}, +] +scipy = [ + {file = "scipy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:87b01c7d5761e8a266a0fbdb9d88dcba0910d63c1c671bdb4d99d29f469e9e03"}, + {file = "scipy-1.8.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:ae3e327da323d82e918e593460e23babdce40d7ab21490ddf9fc06dec6b91a18"}, + {file = "scipy-1.8.0-cp310-cp310-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:16e09ef68b352d73befa8bcaf3ebe25d3941fe1a58c82909d5589856e6bc8174"}, + {file = "scipy-1.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c17a1878d00a5dd2797ccd73623ceca9d02375328f6218ee6d921e1325e61aff"}, + {file = "scipy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:937d28722f13302febde29847bbe554b89073fbb924a30475e5ed7b028898b5f"}, + {file = "scipy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:8f4d059a97b29c91afad46b1737274cb282357a305a80bdd9e8adf3b0ca6a3f0"}, + {file = "scipy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:38aa39b6724cb65271e469013aeb6f2ce66fd44f093e241c28a9c6bc64fd79ed"}, + {file = "scipy-1.8.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:559a8a4c03a5ba9fe3232f39ed24f86457e4f3f6c0abbeae1fb945029f092720"}, + {file = "scipy-1.8.0-cp38-cp38-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:f4a6d3b9f9797eb2d43938ac2c5d96d02aed17ef170c8b38f11798717523ddba"}, + {file = "scipy-1.8.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:92b2c2af4183ed09afb595709a8ef5783b2baf7f41e26ece24e1329c109691a7"}, + {file = "scipy-1.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a279e27c7f4566ef18bab1b1e2c37d168e365080974758d107e7d237d3f0f484"}, + {file = "scipy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad5be4039147c808e64f99c0e8a9641eb5d2fa079ff5894dcd8240e94e347af4"}, + {file = "scipy-1.8.0-cp38-cp38-win32.whl", hash = "sha256:3d9dd6c8b93a22bf9a3a52d1327aca7e092b1299fb3afc4f89e8eba381be7b59"}, + {file = "scipy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:5e73343c5e0d413c1f937302b2e04fb07872f5843041bcfd50699aef6e95e399"}, + {file = "scipy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:de2e80ee1d925984c2504812a310841c241791c5279352be4707cdcd7c255039"}, + {file = "scipy-1.8.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:c2bae431d127bf0b1da81fc24e4bba0a84d058e3a96b9dd6475dfcb3c5e8761e"}, + {file = "scipy-1.8.0-cp39-cp39-macosx_12_0_universal2.macosx_10_9_x86_64.whl", hash = "sha256:723b9f878095ed994756fa4ee3060c450e2db0139c5ba248ee3f9628bd64e735"}, + {file = "scipy-1.8.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:011d4386b53b933142f58a652aa0f149c9b9242abd4f900b9f4ea5fbafc86b89"}, + {file = "scipy-1.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6f0cd9c0bd374ef834ee1e0f0999678d49dcc400ea6209113d81528958f97c7"}, + {file = "scipy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3720d0124aced49f6f2198a6900304411dbbeed12f56951d7c66ebef05e3df6"}, + {file = "scipy-1.8.0-cp39-cp39-win32.whl", hash = "sha256:3d573228c10a3a8c32b9037be982e6440e411b443a6267b067cac72f690b8d56"}, + {file = "scipy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:bb7088e89cd751acf66195d2f00cf009a1ea113f3019664032d9075b1e727b6c"}, + {file = "scipy-1.8.0.tar.gz", hash = "sha256:31d4f2d6b724bc9a98e527b5849b8a7e589bf1ea630c33aa563eda912c9ff0bd"}, +] +tomli = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] +typing-extensions = [ + {file = "typing_extensions-4.1.1-py3-none-any.whl", hash = "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"}, + {file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"}, +] diff --git a/pynam/__init__.py b/pynam/__init__.py index b794fd4..3dc1f76 100644 --- a/pynam/__init__.py +++ b/pynam/__init__.py @@ -1 +1 @@ -__version__ = '0.1.0' +__version__ = "0.1.0" diff --git a/pynam/baskets.py b/pynam/baskets.py index 0cf069a..2f36e47 100644 --- a/pynam/baskets.py +++ b/pynam/baskets.py @@ -1,8 +1,13 @@ class CalculationConstants(object): - """Holds physical constants, in SI units - """ + """Holds physical constants, in SI units""" - def __init__(self, epsilon_0=8.854e-12, h_bar=1.0546e-34, c_light=3e8, electron_mass=9.10938356e-31): + def __init__( + self, + epsilon_0=8.854e-12, + h_bar=1.0546e-34, + c_light=3e8, + electron_mass=9.10938356e-31, + ): """Initialises constants in SI units, with sensible defaults :param epsilon_0: @@ -18,11 +23,18 @@ class CalculationConstants(object): class CalculationParams(object): - """Holds the parameters describing a calculation, in SI units. - """ + """Holds the parameters describing a calculation, in SI units.""" - def __init__(self, omega: float = None, omega_p: float = None, tau: float = None, v_f: float = None, - t_rel: float = None, t_c: float = None, dipole_moment: float = None): + def __init__( + self, + omega: float = None, + omega_p: float = None, + tau: float = None, + v_f: float = None, + t_rel: float = None, + t_c: float = None, + dipole_moment: float = None, + ): """Creates parameter object, SI units :param omega: diff --git a/pynam/dielectric/__init__.py b/pynam/dielectric/__init__.py index 7aa8786..bc84679 100644 --- a/pynam/dielectric/__init__.py +++ b/pynam/dielectric/__init__.py @@ -1,2 +1,4 @@ from pynam.dielectric.nam_dielectric_coefficient_approximator import get_nam_dielectric from pynam.dielectric.lindhard_dielectric import get_lindhard_dielectric + +__all__ = ["get_nam_dielectric", "get_lindhard_dielectric"] diff --git a/pynam/dielectric/lindhard_dielectric.py b/pynam/dielectric/lindhard_dielectric.py index b38b3c7..a7c34c4 100644 --- a/pynam/dielectric/lindhard_dielectric.py +++ b/pynam/dielectric/lindhard_dielectric.py @@ -5,10 +5,21 @@ LINDHARD_SERIES_THRESHOLD = 1e4 class LindhardDielectric(object): - def __init__(self, - params: CalculationParams, - constants: CalculationConstants = CalculationConstants(), - thres=LINDHARD_SERIES_THRESHOLD): + def __init__( + self, + params: CalculationParams, + constants: CalculationConstants = CalculationConstants(), + thres=LINDHARD_SERIES_THRESHOLD, + ): + if params.omega is None: + raise ValueError("omega expected to not be None") + if params.v_f is None: + raise ValueError("v_f expected to not be None") + if params.omega_p is None: + raise ValueError("omega_p expected to not be None") + if params.tau is None: + raise ValueError("tau expected to not be None") + self.series_threshold = thres self.omega = params.omega self.v_f = params.v_f @@ -17,12 +28,11 @@ class LindhardDielectric(object): self.c_light = constants.c_light self.s = 1 / (self.tau * self.omega) - self.prefactor = 3 * (self.omega_p ** 2) / (self.omega ** 2) + self.prefactor = 3 * (self.omega_p**2) / (self.omega**2) def get_eps(self): - def eps_lindhard(u_inverse_wavelength: float) -> complex: - """ the lindhard dielectric function + """the lindhard dielectric function :param u_inverse_wavelength: u is in units of the reciprocal vacuum wavelength (omega / c_light) :return: returns the value of epsilon, dimensionless @@ -37,22 +47,26 @@ class LindhardDielectric(object): return eps_full_lindhard(u) def eps_series(u: float) -> complex: - rel_value = ( - (1j / (3 * (self.s - 1j))) + u ** 2 * ((-9j + 5 * self.s) / (45 * (-1j + self.s) ** 3)) + rel_value = (1j / (3 * (self.s - 1j))) + ( + u**2 * ((-9j + 5 * self.s) / (45 * (-1j + self.s) ** 3)) ) + return 1 + (self.prefactor * rel_value) def eps_full_lindhard(u: float) -> complex: log_value = np.log((1 - u + (self.s * 1j)) / (1 + u + (self.s * 1j))) - rel_value = (1 + ((1 + (self.s * 1j)) / (2 * u)) * log_value) / (1 + ((self.s * 1j) / (2 * u)) * log_value) + rel_value = (1 + ((1 + (self.s * 1j)) / (2 * u)) * log_value) / ( + 1 + ((self.s * 1j) / (2 * u)) * log_value + ) - return 1 + (self.prefactor / (u ** 2)) * rel_value + return 1 + (self.prefactor / (u**2)) * rel_value return eps_lindhard -def get_lindhard_dielectric(params: CalculationParams, - constants: CalculationConstants = CalculationConstants()): +def get_lindhard_dielectric( + params: CalculationParams, constants: CalculationConstants = CalculationConstants() +): return LindhardDielectric(params, constants).get_eps() diff --git a/pynam/dielectric/low_k_nam.py b/pynam/dielectric/low_k_nam.py index 02c4ba8..318cdfe 100644 --- a/pynam/dielectric/low_k_nam.py +++ b/pynam/dielectric/low_k_nam.py @@ -5,17 +5,17 @@ import pynam.util def g(w, wp): - return ((wp * (w + wp)) + 1) / (csqrt(wp ** 2 - 1) * csqrt((w + wp) ** 2 - 1)) + return ((wp * (w + wp)) + 1) / (csqrt(wp**2 - 1) * csqrt((w + wp) ** 2 - 1)) def f(k, e, v): - return ((4 / 3) * 1 / (e - 1j * v)) + (4 / 15) * (1 / ((e - 1j * v) ** 3)) * k ** 2 + return ((4 / 3) * 1 / (e - 1j * v)) + (4 / 15) * (1 / ((e - 1j * v) ** 3)) * k**2 def i1(w, wp, k, v): gv = g(w, wp) e1 = csqrt((w + wp) ** 2 - 1) - e2 = csqrt(wp ** 2 - 1) + e2 = csqrt(wp**2 - 1) f_upper = f(k, np.real(e1 - e2), np.imag(e1 + e2) + 2 * v) * (gv + 1) f_lower = f(k, np.real(-e1 - e2), np.imag(e1 + e2) + 2 * v) * (gv - 1) @@ -26,7 +26,7 @@ def i1(w, wp, k, v): def i2(w, wp, k, v): gv = g(w, wp) e1 = csqrt((w + wp) ** 2 - 1) - e2 = csqrt(wp ** 2 - 1) + e2 = csqrt(wp**2 - 1) f_upper = f(k, np.real(e1 - e2), np.imag(e1 + e2) + 2 * v) * (gv + 1) f_lower = f(k, np.real(e1 + e2), np.imag(e1 + e2) + 2 * v) * (gv - 1) @@ -36,19 +36,18 @@ def i2(w, wp, k, v): def a(w, k, v, t): return pynam.util.complex_quad( - lambda wp: np.tanh((w + wp) / (2 * t)) * (i1(w, wp, k, v)), - 1 - w, 1 + lambda wp: np.tanh((w + wp) / (2 * t)) * (i1(w, wp, k, v)), 1 - w, 1 )[0] def b_int(wp, w, k, v, t): - return (np.tanh((w + wp) / (2 * t)) * i1(w, wp, k, v)) - (np.tanh(wp / (2 * t)) * i2(w, wp, k, v)) + return (np.tanh((w + wp) / (2 * t)) * i1(w, wp, k, v)) - ( + np.tanh(wp / (2 * t)) * i2(w, wp, k, v) + ) def b(w, k, v, t, b_max=np.inf): - return pynam.util.complex_quad( - lambda wp: b_int(wp, w, k, v, t), 1, b_max - )[0] + return pynam.util.complex_quad(lambda wp: b_int(wp, w, k, v, t), 1, b_max)[0] def sigma_nam_alk(w, k, v, t): diff --git a/pynam/dielectric/nam_dielectric_coefficient_approximator.py b/pynam/dielectric/nam_dielectric_coefficient_approximator.py index 2dad7a9..951c803 100644 --- a/pynam/dielectric/nam_dielectric_coefficient_approximator.py +++ b/pynam/dielectric/nam_dielectric_coefficient_approximator.py @@ -11,14 +11,15 @@ FIXED_LARGE_MOMENTUM = 1e8 class DedimensionalisedParameters(object): def __init__( - self, - omega: float, - sigma_n: float, - tau: float, - v_f: float, - temp: float, - critical_temp: float, - c_light: float): + self, + omega: float, + sigma_n: float, + tau: float, + v_f: float, + temp: float, + critical_temp: float, + c_light: float, + ): gap = 0 if temp < critical_temp: # else, problems will happen @@ -39,7 +40,6 @@ class NamDielectricCoefficients(object): self.u_l = np.real((-self.c + 1j * self.d) / (-self.a + 1j * self.b)) def eps(self, u_c: float): - def piecewise_eps(u: float): # todo add check for u_c vs u_l if u < self.u_l: @@ -53,41 +53,50 @@ class NamDielectricCoefficients(object): def get_dedimensionalised_parameters( - omega: float, - sigma_n: float, - tau: float, - v_f: float, - temp: float, - critical_temp: float, - c_light: float) -> DedimensionalisedParameters: - return DedimensionalisedParameters(omega, sigma_n, tau, v_f, temp, critical_temp, c_light) + omega: float, + sigma_n: float, + tau: float, + v_f: float, + temp: float, + critical_temp: float, + c_light: float, +) -> DedimensionalisedParameters: + return DedimensionalisedParameters( + omega, sigma_n, tau, v_f, temp, critical_temp, c_light + ) -def get_small_momentum_coefficients(dedim_params: DedimensionalisedParameters) -> Tuple[float, float]: +def get_small_momentum_coefficients( + dedim_params: DedimensionalisedParameters, +) -> Tuple[float, float]: prefactor = 4j * np.pi * dedim_params.b - s = pynam.dielectric.low_k_nam.sigma_nam_alk(dedim_params.xi, 0, dedim_params.nu, dedim_params.t) + s = pynam.dielectric.low_k_nam.sigma_nam_alk( + dedim_params.xi, 0, dedim_params.nu, dedim_params.t + ) conductivity = prefactor * s return -np.real(conductivity), np.imag(conductivity) -def get_big_momentum_coefficients(dedim_params: DedimensionalisedParameters) -> Tuple[float, float]: +def get_big_momentum_coefficients( + dedim_params: DedimensionalisedParameters, +) -> Tuple[float, float]: prefactor = 4j * np.pi * dedim_params.b * FIXED_LARGE_MOMENTUM / dedim_params.a - s = pynam.dielectric.sigma_nam.sigma_nam(dedim_params.xi, - FIXED_LARGE_MOMENTUM, - dedim_params.nu, - dedim_params.t) + s = pynam.dielectric.sigma_nam.sigma_nam( + dedim_params.xi, FIXED_LARGE_MOMENTUM, dedim_params.nu, dedim_params.t + ) conductivity = prefactor * s return -np.real(conductivity), np.imag(conductivity) def get_nam_dielectric_coefficients( - omega: float, - sigma_n: float, - tau: float, - v_f: float, - temp: float, - crit_temp: float, - c_light: float) -> NamDielectricCoefficients: + omega: float, + sigma_n: float, + tau: float, + v_f: float, + temp: float, + crit_temp: float, + c_light: float, +) -> NamDielectricCoefficients: """Gets a NamDielectricCoefficients object, using SI unit parameters :param omega: frequency @@ -100,20 +109,40 @@ def get_nam_dielectric_coefficients( :return: """ - dedim = get_dedimensionalised_parameters(omega, sigma_n, tau, v_f, temp, crit_temp, c_light) + dedim = get_dedimensionalised_parameters( + omega, sigma_n, tau, v_f, temp, crit_temp, c_light + ) a, b = get_small_momentum_coefficients(dedim) c, d = get_big_momentum_coefficients(dedim) return NamDielectricCoefficients(a, b, c, d) -def get_nam_dielectric(u_c: float, params: CalculationParams, constants: CalculationConstants = CalculationConstants()): +def get_nam_dielectric( + u_c: float, + params: CalculationParams, + constants: CalculationConstants = CalculationConstants(), +): + if params.omega is None: + raise ValueError("omega expected to not be None") + if params.v_f is None: + raise ValueError("v_f expected to not be None") + if params.omega_p is None: + raise ValueError("omega_p expected to not be None") + if params.tau is None: + raise ValueError("tau expected to not be None") + if params.t_rel is None: + raise ValueError("relative temp expected to not be None") + if params.t_c is None: + raise ValueError("critical temp expected to not be None") sigma_n = params.omega_p**2 * params.tau / (4 * np.pi) - coeffs = get_nam_dielectric_coefficients(params.omega, - sigma_n, - params.tau, - params.v_f, - params.t_rel * params.t_c, - params.t_c, - constants.c_light) + coeffs = get_nam_dielectric_coefficients( + params.omega, + sigma_n, + params.tau, + params.v_f, + params.t_rel * params.t_c, + params.t_c, + constants.c_light, + ) return coeffs.eps(u_c) diff --git a/pynam/dielectric/sigma_nam.py b/pynam/dielectric/sigma_nam.py index 2b4d4cb..e194928 100644 --- a/pynam/dielectric/sigma_nam.py +++ b/pynam/dielectric/sigma_nam.py @@ -5,7 +5,7 @@ import pynam.util def g(w, wp): - return ((wp * (w + wp)) + 1) / (csqrt(wp ** 2 - 1) * csqrt((w + wp) ** 2 - 1)) + return ((wp * (w + wp)) + 1) / (csqrt(wp**2 - 1) * csqrt((w + wp) ** 2 - 1)) def s(k, e, v): @@ -21,7 +21,7 @@ def f(k, e, v): def i1(w, wp, k, v): gv = g(w, wp) e1 = csqrt((w + wp) ** 2 - 1) - e2 = csqrt(wp ** 2 - 1) + e2 = csqrt(wp**2 - 1) f_upper = f(k, np.real(e1 - e2), np.imag(e1 + e2) + 2 * v) * (gv + 1) f_lower = f(k, np.real(-e1 - e2), np.imag(e1 + e2) + 2 * v) * (gv - 1) @@ -32,7 +32,7 @@ def i1(w, wp, k, v): def i2(w, wp, k, v): gv = g(w, wp) e1 = csqrt((w + wp) ** 2 - 1) - e2 = csqrt(wp ** 2 - 1) + e2 = csqrt(wp**2 - 1) f_upper = f(k, np.real(e1 - e2), np.imag(e1 + e2) + 2 * v) * (gv + 1) f_lower = f(k, np.real(e1 + e2), np.imag(e1 + e2) + 2 * v) * (gv - 1) @@ -43,21 +43,22 @@ def i2(w, wp, k, v): def a(w, k, v, t): result = pynam.util.complex_quad( lambda wp: np.tanh((w + wp) / (2 * t)) * (i1(w, wp, k, v)), - 1 - w, 1, - epsabs=1e-10 + 1 - w, + 1, + epsabs=1e-10, ) return result[0] def b_int(wp, w, k, v, t): - return (np.tanh((w + wp) / (2 * t)) * i1(w, wp, k, v)) - (np.tanh(wp / (2 * t)) * i2(w, wp, k, v)) + return (np.tanh((w + wp) / (2 * t)) * i1(w, wp, k, v)) - ( + np.tanh(wp / (2 * t)) * i2(w, wp, k, v) + ) def b(w, k, v, t, b_max=np.inf): - return pynam.util.complex_quad( - lambda wp: b_int(wp, w, k, v, t), 1, b_max - )[0] + return pynam.util.complex_quad(lambda wp: b_int(wp, w, k, v, t), 1, b_max)[0] def sigma_nam(w, k, v, t): diff --git a/pynam/noise/chi.py b/pynam/noise/chi.py index 68e51fa..22e2a5a 100644 --- a/pynam/noise/chi.py +++ b/pynam/noise/chi.py @@ -10,10 +10,12 @@ def get_chi_zz_e(eps: Callable[[float], complex]) -> Callable[[float], float]: im_ref_p = pynam.noise.im_ref.get_im_ref_p(eps) def chi_zz_e(z: float) -> float: - def integrand(y: float) -> float: return (y**2) * im_ref_p(y / z) * np.exp(-2 * y) - return scipy.integrate.quad(integrand, 0, np.inf, epsabs=1e-10, epsrel=1e-10)[0] / (z**3) + integral = scipy.integrate.quad( + integrand, 0, np.inf, epsabs=1e-10, epsrel=1e-10 + ) + return integral[0] / (z**3) return chi_zz_e diff --git a/pynam/noise/zeta.py b/pynam/noise/zeta.py index e9ff7fe..b8858af 100644 --- a/pynam/noise/zeta.py +++ b/pynam/noise/zeta.py @@ -6,8 +6,10 @@ import numpy as np SMALL_X_BOUNDARY = 1e3 -def get_zeta_p_integrand(eps: Callable[[float], complex]) -> Callable[[float, float], complex]: - """ Gets the integrand function zeta_p_integrand(u, y). +def get_zeta_p_integrand( + eps: Callable[[float], complex] +) -> Callable[[float, float], complex]: + """Gets the integrand function zeta_p_integrand(u, y). Returns zeta_p_integrand(u, y), a complex valued function of two momenta in units of vacuum wavelength. @@ -22,8 +24,8 @@ def get_zeta_p_integrand(eps: Callable[[float], complex]) -> Callable[[float, fl :param y: :return: """ - u2 = u ** 2 - y2 = y ** 2 + u2 = u**2 + y2 = y**2 k2 = u2 + y2 k = np.sqrt(k2) eps_value = eps(k) @@ -36,36 +38,44 @@ def get_zeta_p_integrand(eps: Callable[[float], complex]) -> Callable[[float, fl def get_zeta_p_function(eps: Callable[[float], complex]): def integrand1_small_x(x: float, u: float) -> complex: - u2 = u ** 2 - x2 = x ** 2 - eps_value = eps(u * np.sqrt(1 + x ** 2)) + u2 = u**2 + x2 = x**2 + eps_value = eps(u * np.sqrt(1 + x**2)) return (x2 / (eps_value - 1 - x2)) / ((1 + x2) * u2) def integrand1_big_x(x: float, u: float) -> complex: - u2 = u ** 2 - x2 = x ** 2 + u2 = u**2 + x2 = x**2 eps_value = eps(u * x) return 1 / ((eps_value - x2) * u2) # 1 / (eps(u * sqrt(1 + x^2))) * 1 / (1 + x^2) def integrand2_small_x(x: float, u: float) -> complex: - x2 = x ** 2 - eps_value = eps(u * np.sqrt(1 + x ** 2)) + x2 = x**2 + eps_value = eps(u * np.sqrt(1 + x**2)) return 1 / (eps_value * (1 + x2)) def integrand2_big_x(x: float, u: float) -> complex: - x2 = x ** 2 + x2 = x**2 eps_value = eps(u * x) return 1 / (eps_value * x2) def zeta_p(u: float) -> complex: - zeta_p_integrand = get_zeta_p_integrand(eps) + # zeta_p_integrand = get_zeta_p_integrand(eps) - i1_small = pynam.util.complex_quad(lambda x: integrand1_small_x(x, u), 0, SMALL_X_BOUNDARY, epsabs=1e-12) - i1_big = pynam.util.complex_quad(lambda x: integrand1_big_x(x, u), SMALL_X_BOUNDARY, np.inf, epsabs=1e-12) - i2_small = pynam.util.complex_quad(lambda x: integrand2_small_x(x, u), 0, SMALL_X_BOUNDARY, epsabs=1e-12) - i2_big = pynam.util.complex_quad(lambda x: integrand2_big_x(x, u), SMALL_X_BOUNDARY, np.inf, epsabs=1e-12) + i1_small = pynam.util.complex_quad( + lambda x: integrand1_small_x(x, u), 0, SMALL_X_BOUNDARY, epsabs=1e-12 + ) + i1_big = pynam.util.complex_quad( + lambda x: integrand1_big_x(x, u), SMALL_X_BOUNDARY, np.inf, epsabs=1e-12 + ) + i2_small = pynam.util.complex_quad( + lambda x: integrand2_small_x(x, u), 0, SMALL_X_BOUNDARY, epsabs=1e-12 + ) + i2_big = pynam.util.complex_quad( + lambda x: integrand2_big_x(x, u), SMALL_X_BOUNDARY, np.inf, epsabs=1e-12 + ) integral = sum(term[0] for term in [i1_small, i2_small, i1_big, i2_big]) diff --git a/pynam/util/__init__.py b/pynam/util/__init__.py index 4a4cfcb..39dccdb 100644 --- a/pynam/util/__init__.py +++ b/pynam/util/__init__.py @@ -1 +1,3 @@ from pynam.util.complex_integrate import complex_quad, complex_quadrature + +__all__ = ["complex_quad", "complex_quadrature"] diff --git a/pynam/util/complex_integrate.py b/pynam/util/complex_integrate.py index cf1540c..0bbc857 100644 --- a/pynam/util/complex_integrate.py +++ b/pynam/util/complex_integrate.py @@ -3,7 +3,6 @@ from scipy.integrate import quad, quadrature def complex_quad(func, a, b, **kwargs): - def real_func(x): return np.real(func(x)) @@ -13,11 +12,14 @@ def complex_quad(func, a, b, **kwargs): real_integral = quad(real_func, a, b, **kwargs) imag_integral = quad(imag_func, a, b, **kwargs) - return real_integral[0] + 1j * imag_integral[0], real_integral[1:], imag_integral[1:] + return ( + real_integral[0] + 1j * imag_integral[0], + real_integral[1:], + imag_integral[1:], + ) def complex_quadrature(func, a, b, **kwargs): - def real_func(x): return np.real(func(x)) @@ -27,4 +29,8 @@ def complex_quadrature(func, a, b, **kwargs): real_integral = quadrature(real_func, a, b, **kwargs) imag_integral = quadrature(imag_func, a, b, **kwargs) - return real_integral[0] + 1j * imag_integral[0], real_integral[1:], imag_integral[1:] + return ( + real_integral[0] + 1j * imag_integral[0], + real_integral[1:], + imag_integral[1:], + ) diff --git a/pyproject.toml b/pyproject.toml index da0edbc..89e0efb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,18 +1,37 @@ -[tool.poetry] -name = "pynam" -version = "0.1.1" -description = "" -authors = ["Deepak "] - -[tool.poetry.dependencies] -python = "^3.7" -numpy = "^1.19" -scipy = "^1.5" - -[tool.poetry.dev-dependencies] -pytest = "^3.0" -pytest-benchmark = "^3.2.3" - -[build-system] -requires = ["poetry>=0.12"] -build-backend = "poetry.masonry.api" +[tool.poetry] +name = "pynam" +version = "0.1.1" +description = "" +authors = ["Deepak "] + +[tool.poetry.dependencies] +python = "^3.8,<3.10" +numpy = "^1.21.1" +scipy = "~1.8" + +[tool.poetry.dev-dependencies] +pytest = ">=6" +flake8 = "^4.0.0" +pytest-cov = "^3.0.0" +mypy = "^0.942" +pytest-benchmark = "^3.4.1" +black = "^22.3.0" + +[build-system] +requires = ["poetry>=0.12"] +build-backend = "poetry.masonry.api" + +[tool.pytest.ini_options] +testpaths = ["tests"] +addopts = "--junitxml pytest.xml --cov pynam --cov-report=xml:coverage.xml --cov-fail-under=50 --cov-report=html" +junit_family = "xunit1" + +[tool.mypy] +plugins = "numpy.typing.mypy_plugin" + +[[tool.mypy.overrides]] +module = [ + "scipy", + "scipy.integrate" +] +ignore_missing_imports = true diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..344c613 --- /dev/null +++ b/renovate.json @@ -0,0 +1,3 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json" +} diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100644 index 0000000..1152a43 --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +if [ -z "$(git status --porcelain)" ]; then + branch_name=$(git symbolic-ref -q HEAD) + branch_name=${branch_name##refs/heads/} + branch_name=${branch_name:-HEAD} + if [ $branch_name != "master" ]; then + echo "The current branch is not master!" + echo "I'd feel uncomfortable releasing from here..." + exit 3 + fi + + release_needed=false + if \ + { git log "$( git describe --tags --abbrev=0 )..HEAD" --format='%s' | cut -d: -f1 | sort -u | sed -e 's/([^)]*)//' | grep -q -i -E '^feat|fix|perf|refactor|revert$' ; } || \ + { git log "$( git describe --tags --abbrev=0 )..HEAD" --format='%s' | cut -d: -f1 | sort -u | sed -e 's/([^)]*)//' | grep -q -E '\!$' ; } || \ + { git log "$( git describe --tags --abbrev=0 )..HEAD" --format='%b' | grep -q -E '^BREAKING CHANGE:' ; } + then + release_needed=true + fi + + if ! [ "$release_needed" = true ]; then + echo "No release needed..." + exit 0 + fi + + # Working directory clean + echo "Doing a dry run..." + npx standard-version --dry-run + read -p "Does that look good? [y/N] " -n 1 -r + echo # (optional) move to a new line + if [[ $REPLY =~ ^[Yy]$ ]] + then + # do dangerous stuff + npx standard-version + git push --follow-tags origin master + else + echo "okay, never mind then..." + exit 2 + fi +else + echo "Can't create release, working tree unclean..." + exit 1 +fi diff --git a/scripts/standard-version/pyproject-updater.js b/scripts/standard-version/pyproject-updater.js new file mode 100644 index 0000000..1c8c8ab --- /dev/null +++ b/scripts/standard-version/pyproject-updater.js @@ -0,0 +1,11 @@ +const pattern = /(\[tool\.poetry\]\nname = "pytest"\nversion = ")(?\d+\.\d+\.\d)(")/mg; + +module.exports.readVersion = function (contents) { + const result = pattern.exec(contents); + return result.groups.vers; +} + +module.exports.writeVersion = function (contents, version) { + const newContents = contents.replace(pattern, `$1${version}$3`); + return newContents; +} diff --git a/tests/dielectric/test_lindhard_dielectric.py b/tests/dielectric/test_lindhard_dielectric.py index 39a7e97..541bb43 100644 --- a/tests/dielectric/test_lindhard_dielectric.py +++ b/tests/dielectric/test_lindhard_dielectric.py @@ -9,38 +9,47 @@ def get_common_lindhard_dielectric(): return pynam.dielectric.get_lindhard_dielectric(params) -@pytest.mark.parametrize("test_input,expected", [ - (10, -1222.185185062794 + 1.2249999998777178e8j), - (1000, 16924.14814718176 + 1.2250000020552777e8j), - (1e8, 83.687499999706 + 0.00022417398943752126j) -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + (10, -1222.185185062794 + 1.2249999998777178e8j), + (1000, 16924.14814718176 + 1.2250000020552777e8j), + (1e8, 83.687499999706 + 0.00022417398943752126j), + ], +) def test_lindhard_dielectric(test_input, expected): eps_to_test = get_common_lindhard_dielectric() np.testing.assert_almost_equal( - eps_to_test(test_input), expected, - decimal=6, err_msg='b function is off' + eps_to_test(test_input), expected, decimal=6, err_msg="b function is off" ) -@pytest.mark.parametrize("test_input,expected", [ - ((100, 100), -883.3001542404703 + 1.2566370613549341e8j), - ((100, 1e5), 5.827225842825694e7 + 3.933446612656656e7j), - ((100, 1e10), 1.0084823001646925 + 2.0013975538629039e-10j), - ((100, 1e7), 8483.300121667038 + 0.6340397839154446) -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + ((100, 100), -883.3001542404703 + 1.2566370613549341e8j), + ((100, 1e5), 5.827225842825694e7 + 3.933446612656656e7j), + ((100, 1e10), 1.0084823001646925 + 2.0013975538629039e-10j), + ((100, 1e7), 8483.300121667038 + 0.6340397839154446), + ], +) def test_zeta_pi_lindhard_dielectric(zeta_p_i_epsilon, test_input, expected): u, y = test_input actual = zeta_p_i_epsilon(np.sqrt(u**2 + y**2)) np.testing.assert_allclose( - actual, expected, - rtol=10**3.8, err_msg='lindhard dielectric differs from Mathematica' + actual, + expected, + rtol=10**3.8, + err_msg="lindhard dielectric differs from Mathematica", ) @pytest.fixture def zeta_p_i_epsilon(): - params = CalculationParams(omega=1e9, omega_p=3.544907701811032e15, tau=1e-14, v_f=2e6) + params = CalculationParams( + omega=1e9, omega_p=3.544907701811032e15, tau=1e-14, v_f=2e6 + ) return pynam.dielectric.get_lindhard_dielectric(params) diff --git a/tests/dielectric/test_low_k_nam.py b/tests/dielectric/test_low_k_nam.py index 73b64db..784f79f 100644 --- a/tests/dielectric/test_low_k_nam.py +++ b/tests/dielectric/test_low_k_nam.py @@ -3,101 +3,115 @@ import numpy as np import pytest -@pytest.mark.parametrize("test_input,expected", [ - ((1, 2), 7 / (2 * np.sqrt(6))), - ((2, 0.25), -5j / np.sqrt(39)) -]) +@pytest.mark.parametrize( + "test_input,expected", + [((1, 2), 7 / (2 * np.sqrt(6))), ((2, 0.25), -5j / np.sqrt(39))], +) def test_g(test_input, expected): np.testing.assert_almost_equal( - pynam.dielectric.low_k_nam.g(*test_input), expected, - decimal=7, err_msg='g function is off' + pynam.dielectric.low_k_nam.g(*test_input), + expected, + decimal=7, + err_msg="g function is off", ) -@pytest.mark.parametrize("test_input,expected", [ - ((1, 1, 0), 8 / 5), - ((1, 1, 1), 3 / 5 + 11j / 15), - ((1, 0, 1), 16j / 15) -]) +@pytest.mark.parametrize( + "test_input,expected", + [((1, 1, 0), 8 / 5), ((1, 1, 1), 3 / 5 + 11j / 15), ((1, 0, 1), 16j / 15)], +) def test_f(test_input, expected): np.testing.assert_almost_equal( - pynam.dielectric.low_k_nam.f(*test_input), expected, - decimal=7, err_msg='f function is off' + pynam.dielectric.low_k_nam.f(*test_input), + expected, + decimal=7, + err_msg="f function is off", ) -@pytest.mark.parametrize("test_input,expected", [ - ((2, 3, 1, 0), 1.42546694754), - ((1, 2, 3, 4), 0.0206212167 + 0.4411134527j) -]) +@pytest.mark.parametrize( + "test_input,expected", + [((2, 3, 1, 0), 1.42546694754), ((1, 2, 3, 4), 0.0206212167 + 0.4411134527j)], +) def test_i1(test_input, expected): np.testing.assert_almost_equal( - pynam.dielectric.low_k_nam.i1(*test_input), expected, - decimal=7, err_msg='i1 function is off' + pynam.dielectric.low_k_nam.i1(*test_input), + expected, + decimal=7, + err_msg="i1 function is off", ) -@pytest.mark.parametrize("test_input,expected", [ - ((2, 3, 1, 0), 1.47903168398), - ((1, 2, 3, 4), 0.079491440779 + 0.441113452718j) -]) +@pytest.mark.parametrize( + "test_input,expected", + [((2, 3, 1, 0), 1.47903168398), ((1, 2, 3, 4), 0.079491440779 + 0.441113452718j)], +) def test_i2(test_input, expected): np.testing.assert_almost_equal( - pynam.dielectric.low_k_nam.i2(*test_input), expected, - decimal=7, err_msg='i1 function is off' + pynam.dielectric.low_k_nam.i2(*test_input), + expected, + decimal=7, + err_msg="i1 function is off", ) -@pytest.mark.parametrize("test_input,expected", [ - ((1, 2, 3, 4), 0.228292), -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + ((1, 2, 3, 4), 0.228292), + ], +) def test_a(test_input, expected): actual = np.real_if_close(pynam.dielectric.low_k_nam.a(*test_input)) np.testing.assert_almost_equal( - actual, expected, - decimal=6, err_msg='a function is off' + actual, expected, decimal=6, err_msg="a function is off" ) -@pytest.mark.parametrize("test_input,expected", [ - ((2, 1, 2, 0, 4), 0.479529593125), - ((100, 1, 2, 3, 4), -2.62529549942e-6 + 2.60588e-12j), -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + ((2, 1, 2, 0, 4), 0.479529593125), + ((100, 1, 2, 3, 4), -2.62529549942e-6 + 2.60588e-12j), + ], +) def test_b_int(test_input, expected): actual = np.real_if_close(pynam.dielectric.low_k_nam.b_int(*test_input)) np.testing.assert_almost_equal( - actual, expected, - decimal=6, err_msg='b int function is off' + actual, expected, decimal=6, err_msg="b int function is off" ) -@pytest.mark.parametrize("test_input,expected", [ - ((1, 2, 0, 4), 3.514889721181435), - ((1, 2, 3, 4), -0.0598057 + 0.437146j), -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + ((1, 2, 0, 4), 3.514889721181435), + ((1, 2, 3, 4), -0.0598057 + 0.437146j), + ], +) def test_b(test_input, expected): actual = np.real_if_close(pynam.dielectric.low_k_nam.b(*test_input)) np.testing.assert_almost_equal( - actual, expected, - decimal=6, err_msg='b function is off' + actual, expected, decimal=6, err_msg="b function is off" ) -@pytest.mark.parametrize("test_input,expected", [ - ((1, 2, 0, 4), 0), - ((1, 2, 3, 4), 0.98358 + 0.648221j), -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + ((1, 2, 0, 4), 0), + ((1, 2, 3, 4), 0.98358 + 0.648221j), + ], +) def test_sigma_alk(test_input, expected): actual = np.real_if_close(pynam.dielectric.low_k_nam.sigma_nam_alk(*test_input)) np.testing.assert_almost_equal( - actual, expected, - decimal=6, err_msg='b function is off' + actual, expected, decimal=6, err_msg="b function is off" ) def test_sigma_alk_benchmark(benchmark): result = benchmark(pynam.dielectric.low_k_nam.sigma_nam_alk, 1, 2, 3, 4) np.testing.assert_almost_equal( - result, 0.98358 + 0.648221j, - decimal=6, err_msg='b function is off' + result, 0.98358 + 0.648221j, decimal=6, err_msg="b function is off" ) diff --git a/tests/dielectric/test_nam_dielectric_coefficient_approximator.py b/tests/dielectric/test_nam_dielectric_coefficient_approximator.py index 72aba86..365ab26 100644 --- a/tests/dielectric/test_nam_dielectric_coefficient_approximator.py +++ b/tests/dielectric/test_nam_dielectric_coefficient_approximator.py @@ -4,102 +4,136 @@ import pynam.dielectric.nam_dielectric_coefficient_approximator from pynam.baskets import CalculationParams -@pytest.mark.parametrize("test_input,expected", [ - # ( - # (omega, sigma_n, tau, v_f, T, T_c, c_light), - # (xi, nu, t, A, B) - # ) - ( +@pytest.mark.parametrize( + "test_input,expected", + [ + # ( + # (omega, sigma_n, tau, v_f, T, T_c, c_light), + # (xi, nu, t, A, B) + # ) + ( (1e9, 1e16, 1e-14, 2e6, 0.8e11, 1e11, 3e8), - (0.007307411691175783, 730.7411691175784, 0.5845929352940626, 0.00004871607794117188, 10000000) - ) -]) + ( + 0.007307411691175783, + 730.7411691175784, + 0.5845929352940626, + 0.00004871607794117188, + 10000000, + ), + ) + ], +) def test_dedimensionalise_parameters(test_input, expected): actual_parameters = pynam.dielectric.nam_dielectric_coefficient_approximator.get_dedimensionalised_parameters( - *test_input) - - np.testing.assert_almost_equal( - actual_parameters.xi, expected[0], - decimal=6, err_msg='xi incorrectly calculated' + *test_input ) np.testing.assert_almost_equal( - actual_parameters.nu, expected[1], - decimal=6, err_msg='nu incorrectly calculated' + actual_parameters.xi, + expected[0], + decimal=6, + err_msg="xi incorrectly calculated", + ) + + np.testing.assert_almost_equal( + actual_parameters.nu, + expected[1], + decimal=6, + err_msg="nu incorrectly calculated", ) np.testing.assert_almost_equal( - actual_parameters.t, expected[2], - decimal=6, err_msg='t incorrectly calculated' + actual_parameters.t, expected[2], decimal=6, err_msg="t incorrectly calculated" ) np.testing.assert_almost_equal( - actual_parameters.a, expected[3], - decimal=6, err_msg='A incorrectly calculated' + actual_parameters.a, expected[3], decimal=6, err_msg="A incorrectly calculated" ) np.testing.assert_almost_equal( - actual_parameters.b, expected[4], - decimal=6, err_msg='B incorrectly calculated' + actual_parameters.b, expected[4], decimal=6, err_msg="B incorrectly calculated" ) -@pytest.mark.parametrize("test_input,expected", [ - # ( - # (omega, sigma_n, tau, v_f, T, T_c, c_light), - # (a, b, c, d, u_l) - # ) - ( +@pytest.mark.parametrize( + "test_input,expected", + [ + # ( + # (omega, sigma_n, tau, v_f, T, T_c, c_light), + # (a, b, c, d, u_l) + # ) + ( (1e9, 1e16, 1e-14, 2e6, 0.8e11, 1e11, 3e8), - (3.789672906817707e10, 3.257134605133221e8, 2.655709897616547e18, 2.15e16, 7.007759408279888e7) - ) -]) + ( + 3.789672906817707e10, + 3.257134605133221e8, + 2.655709897616547e18, + 2.15e16, + 7.007759408279888e7, + ), + ) + ], +) def test_nam_coefficients(test_input, expected): actual_coefficients = pynam.dielectric.nam_dielectric_coefficient_approximator.get_nam_dielectric_coefficients( - *test_input) - - np.testing.assert_allclose( - actual_coefficients.a, expected[0], - rtol=1e-6, err_msg='a incorrectly calculated' + *test_input ) np.testing.assert_allclose( - actual_coefficients.b, expected[1], - rtol=1e-6, err_msg='b incorrectly calculated' + actual_coefficients.a, + expected[0], + rtol=1e-6, + err_msg="a incorrectly calculated", + ) + + np.testing.assert_allclose( + actual_coefficients.b, + expected[1], + rtol=1e-6, + err_msg="b incorrectly calculated", ) np.testing.assert_allclose( - actual_coefficients.c, expected[2], - rtol=1e-2, err_msg='c incorrectly calculated' + actual_coefficients.c, + expected[2], + rtol=1e-2, + err_msg="c incorrectly calculated", ) np.testing.assert_allclose( - actual_coefficients.d, expected[3], - rtol=1e-2, err_msg='d incorrectly calculated' + actual_coefficients.d, + expected[3], + rtol=1e-2, + err_msg="d incorrectly calculated", ) np.testing.assert_allclose( - actual_coefficients.u_l, expected[4], - rtol=1e-5, err_msg='u_l incorrectly calculated' + actual_coefficients.u_l, + expected[4], + rtol=1e-5, + err_msg="u_l incorrectly calculated", ) def test_nam_eps(): u_c = 1e15 - eps_to_test = pynam.dielectric.nam_dielectric_coefficient_approximator.get_nam_dielectric(u_c, CalculationParams( - omega=1e9, - omega_p=3.54491e15, - tau=1e-14, - v_f=2e6, - t_rel=0.8, - t_c=1e11 - )) - - np.testing.assert_allclose( - eps_to_test(10), -3.789672906817707e10 + 3.257134605133221e8j, - rtol=1e-3, err_msg='below u_l bad' + eps_to_test = ( + pynam.dielectric.nam_dielectric_coefficient_approximator.get_nam_dielectric( + u_c, + CalculationParams( + omega=1e9, omega_p=3.54491e15, tau=1e-14, v_f=2e6, t_rel=0.8, t_c=1e11 + ), + ) ) np.testing.assert_allclose( - eps_to_test(1e10), -2.655709887616547e8 + 2.302290450767144e6j, - rtol=1e-3, err_msg='linear region bad' + eps_to_test(10), + -3.789672906817707e10 + 3.257134605133221e8j, + rtol=1e-3, + err_msg="below u_l bad", ) np.testing.assert_allclose( - eps_to_test(1e17), 1, - rtol=1e-6, err_msg='above cutoff bad' + eps_to_test(1e10), + -2.655709887616547e8 + 2.302290450767144e6j, + rtol=1e-3, + err_msg="linear region bad", + ) + + np.testing.assert_allclose( + eps_to_test(1e17), 1, rtol=1e-6, err_msg="above cutoff bad" ) diff --git a/tests/dielectric/test_sigma_nam.py b/tests/dielectric/test_sigma_nam.py index b54f743..4a3d594 100644 --- a/tests/dielectric/test_sigma_nam.py +++ b/tests/dielectric/test_sigma_nam.py @@ -3,120 +3,163 @@ import numpy as np import pytest -@pytest.mark.parametrize("test_input,expected", [ - ((1, 2), 7 / (2 * np.sqrt(6))), - ((2, 0.25), -5j / np.sqrt(39)) -]) +@pytest.mark.parametrize( + "test_input,expected", + [((1, 2), 7 / (2 * np.sqrt(6))), ((2, 0.25), -5j / np.sqrt(39))], +) def test_g(test_input, expected): np.testing.assert_almost_equal( - pynam.dielectric.sigma_nam.g(*test_input), expected, - decimal=7, err_msg='g function is off' + pynam.dielectric.sigma_nam.g(*test_input), + expected, + decimal=7, + err_msg="g function is off", ) -@pytest.mark.parametrize("test_input,expected", [ - ((1, 2, 0), 2), - ((1, 2, 3), 2 - 3j), - ((1, 0, 3), -3j) -]) +@pytest.mark.parametrize( + "test_input,expected", [((1, 2, 0), 2), ((1, 2, 3), 2 - 3j), ((1, 0, 3), -3j)] +) def test_s(test_input, expected): np.testing.assert_almost_equal( - pynam.dielectric.sigma_nam.s(*test_input), expected, - decimal=7, err_msg='s function is off' + pynam.dielectric.sigma_nam.s(*test_input), + expected, + decimal=7, + err_msg="s function is off", ) -@pytest.mark.parametrize("test_input,expected", [ - ((1, 2, 0), 4 - 3 * np.log(3)), - ((1, 1, 0.1), 1.7258022209219421 + 0.4146045220413866j), - ((1, 2, 1), 0.535971651563 + 0.291580606867j), - ((1, 0, 1), (np.pi - 2)*1j), - ((2, 1.09637631718, 0), 0.97892512273 + 1.09875591859j), - ((2, 1, 0), 0.91197960825 + 1.17809724510j) -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + ((1, 2, 0), 4 - 3 * np.log(3)), + ((1, 1, 0.1), 1.7258022209219421 + 0.4146045220413866j), + ((1, 2, 1), 0.535971651563 + 0.291580606867j), + ((1, 0, 1), (np.pi - 2) * 1j), + ((2, 1.09637631718, 0), 0.97892512273 + 1.09875591859j), + ((2, 1, 0), 0.91197960825 + 1.17809724510j), + ], +) def test_f(test_input, expected): np.testing.assert_almost_equal( - pynam.dielectric.sigma_nam.f(*test_input), expected, - decimal=7, err_msg='f function is off' + pynam.dielectric.sigma_nam.f(*test_input), + expected, + decimal=7, + err_msg="f function is off", ) -@pytest.mark.parametrize("test_input,expected", [ - ((2, 3, 1, 0), 1.43292419807), - ((1, 2, 3, 4), 0.020963572915 + 0.441546735048j), - ((1, 2, 2, 0), 2.24702466263660598724031013350450660504 + 2.6687342075059525776833106878900822165j) -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + ((2, 3, 1, 0), 1.43292419807), + ((1, 2, 3, 4), 0.020963572915 + 0.441546735048j), + ( + (1, 2, 2, 0), + 2.24702466263660598724031013350450660504 + + 2.6687342075059525776833106878900822165j, + ), + ], +) def test_i1(test_input, expected): np.testing.assert_almost_equal( - pynam.dielectric.sigma_nam.i1(*test_input), expected, - decimal=7, err_msg='i1 function is off' + pynam.dielectric.sigma_nam.i1(*test_input), + expected, + decimal=7, + err_msg="i1 function is off", ) -@pytest.mark.parametrize("test_input,expected", [ - ((2, 3, 1, 0), 1.48649022993), - ((1, 2, 3, 4), 0.079899419983 + 0.441546735048j), - ((1, 2, 2, 0), 2.5083371377336783093007366990156440969 + 2.6687342075059525776833106878900822165j) -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + ((2, 3, 1, 0), 1.48649022993), + ((1, 2, 3, 4), 0.079899419983 + 0.441546735048j), + ( + (1, 2, 2, 0), + 2.5083371377336783093007366990156440969 + + 2.6687342075059525776833106878900822165j, + ), + ], +) def test_i2(test_input, expected): np.testing.assert_almost_equal( - pynam.dielectric.sigma_nam.i2(*test_input), expected, - decimal=7, err_msg='i1 function is off' + pynam.dielectric.sigma_nam.i2(*test_input), + expected, + decimal=7, + err_msg="i1 function is off", ) -@pytest.mark.parametrize("test_input,expected", [ - ((1, 2, 3, 4), 0.228396), - ((0.007307411691175783, 1e8, 730.7411691175784, 0.5845929352940626), 1.37272e-7) -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + ((1, 2, 3, 4), 0.228396), + ( + (0.007307411691175783, 1e8, 730.7411691175784, 0.5845929352940626), + 1.37272e-7, + ), + ], +) def test_a(test_input, expected): actual = np.real_if_close(pynam.dielectric.sigma_nam.a(*test_input)) - np.testing.assert_allclose( - actual, expected, - rtol=1e-5, err_msg='a function is off' - ) + np.testing.assert_allclose(actual, expected, rtol=1e-5, err_msg="a function is off") -@pytest.mark.parametrize("test_input,expected", [ - ((2, 1, 2, 0, 4), 0.19089933550122580816258795500979108668 + 0.30273783507819906415704926284048453889j), - ((100, 1, 2, 3, 4), -2.62529549976e-6 + 2.60765e-12j), -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + ( + (2, 1, 2, 0, 4), + 0.19089933550122580816258795500979108668 + + 0.30273783507819906415704926284048453889j, + ), + ((100, 1, 2, 3, 4), -2.62529549976e-6 + 2.60765e-12j), + ], +) def test_b_int(test_input, expected): actual = np.real_if_close(pynam.dielectric.sigma_nam.b_int(*test_input)) np.testing.assert_almost_equal( - actual, expected, - decimal=6, err_msg='b int function is off' + actual, expected, decimal=6, err_msg="b int function is off" ) -@pytest.mark.parametrize("test_input,expected", [ - ((1, 2, 0, 4), 1.23149 + 2.08627j), - ((1, 2, 3, 4), -0.0595819 + 0.437385j), -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + ((1, 2, 0, 4), 1.23149 + 2.08627j), + ((1, 2, 3, 4), -0.0595819 + 0.437385j), + ], +) def test_b(test_input, expected): actual = np.real_if_close(pynam.dielectric.sigma_nam.b(*test_input)) np.testing.assert_almost_equal( - actual, expected, - decimal=6, err_msg='b function is off' + actual, expected, decimal=6, err_msg="b function is off" ) -@pytest.mark.parametrize("test_input,expected", [ - ((1, 2, 0, 4), 0), - ((1, 2, 3, 4), 0.984117 + 0.647951j), - ((0.007307411691175783, 1e8, 730.7411691175784, 0.5845929352940626), 0.00008925294700016892 + 0.0102953966846717j) -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + ((1, 2, 0, 4), 0), + ((1, 2, 3, 4), 0.984117 + 0.647951j), + ( + (0.007307411691175783, 1e8, 730.7411691175784, 0.5845929352940626), + 0.00008925294700016892 + 0.0102953966846717j, + ), + ], +) def test_sigma_nam(test_input, expected): actual = np.real_if_close(pynam.dielectric.sigma_nam.sigma_nam(*test_input)) np.testing.assert_allclose( - actual, expected, - rtol=1e-3, err_msg='sigma_nam function is off' + actual, expected, rtol=1e-3, err_msg="sigma_nam function is off" ) def test_sigma_nam_benchmark(benchmark): result = benchmark(pynam.dielectric.sigma_nam.sigma_nam, 1, 2, 3, 4) np.testing.assert_almost_equal( - result, 0.984117 + 0.647951j, - decimal=6, err_msg='sigma nam benchmrak function is off' + result, + 0.984117 + 0.647951j, + decimal=6, + err_msg="sigma nam benchmrak function is off", ) diff --git a/tests/noise/test_chi.py b/tests/noise/test_chi.py index 92ac296..84ad9e6 100644 --- a/tests/noise/test_chi.py +++ b/tests/noise/test_chi.py @@ -8,34 +8,50 @@ from pynam.baskets import CalculationParams @pytest.fixture def chi_zz_e_lindhard(): - params = CalculationParams(omega=1e9, v_f=2e6, omega_p=3.544907701811032e15, tau=1e-14) + params = CalculationParams( + omega=1e9, v_f=2e6, omega_p=3.544907701811032e15, tau=1e-14 + ) eps_l = pynam.dielectric.get_lindhard_dielectric(params) return pynam.noise.chi.get_chi_zz_e(eps_l) -@pytest.mark.parametrize("test_input,expected", [ - # z chi_zz_e_lindhard(z) - (1e-5, 4.0249088868003124e6), - (1e-6, 4.400474453780887e9), - (1e-7, 7.768467746685921e12), - (1e-8, 1.8541895525296864e16), -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + # z chi_zz_e_lindhard(z) + (1e-5, 4.0249088868003124e6), + (1e-6, 4.400474453780887e9), + (1e-7, 7.768467746685921e12), + (1e-8, 1.8541895525296864e16), + ], +) def test_chi_zz_e_lindhard(chi_zz_e_lindhard, test_input, expected): actual = chi_zz_e_lindhard(test_input) np.testing.assert_allclose( - actual, expected, - rtol=1e-3, err_msg='chi_zz_e is inaccurate for Lindhard case', verbose=True + actual, + expected, + rtol=1e-3, + err_msg="chi_zz_e is inaccurate for Lindhard case", + verbose=True, ) -@pytest.mark.parametrize("test_input,expected", [ - # z chi_zz_e_lindhard(z) - (1e-6, 4.400474453780887e9), -]) -def test_chi_zz_e_lindhard_benchmark(benchmark, chi_zz_e_lindhard, test_input, expected): +@pytest.mark.parametrize( + "test_input,expected", + [ + # z chi_zz_e_lindhard(z) + (1e-6, 4.400474453780887e9), + ], +) +def test_chi_zz_e_lindhard_benchmark( + benchmark, chi_zz_e_lindhard, test_input, expected +): actual = benchmark(chi_zz_e_lindhard, test_input) np.testing.assert_allclose( - actual, expected, - rtol=1e-3, err_msg='chi_zz_e is inaccurate for Lindhard case', verbose=True + actual, + expected, + rtol=1e-3, + err_msg="chi_zz_e is inaccurate for Lindhard case", + verbose=True, ) diff --git a/tests/noise/test_im_ref.py b/tests/noise/test_im_ref.py index 4da1dc8..6304d09 100644 --- a/tests/noise/test_im_ref.py +++ b/tests/noise/test_im_ref.py @@ -8,24 +8,32 @@ from pynam.baskets import CalculationParams @pytest.fixture def im_ref_p_lindhard(): - params = CalculationParams(omega=1e9, v_f=2e6, omega_p=3.544907701811032e15, tau=1e-14) + params = CalculationParams( + omega=1e9, v_f=2e6, omega_p=3.544907701811032e15, tau=1e-14 + ) eps_l = pynam.dielectric.get_lindhard_dielectric(params) return pynam.noise.im_ref.get_im_ref_p(eps_l) -@pytest.mark.parametrize("test_input,expected", [ - # u im_ref_p_l(u) - # needs to be close in range around 1/z, so from 1e4 to 1e8 - # (1e4, 1.821722334939806e-8), 1e4 is too far off still - (1e5, 1.602855764970752e-8), - (1e6, 1.704326041013161e-8), - (1e7, 2.674124312031195e-8), - (1e8, 7.441319151047531e-8), -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + # u im_ref_p_l(u) + # needs to be close in range around 1/z, so from 1e4 to 1e8 + # (1e4, 1.821722334939806e-8), 1e4 is too far off still + (1e5, 1.602855764970752e-8), + (1e6, 1.704326041013161e-8), + (1e7, 2.674124312031195e-8), + (1e8, 7.441319151047531e-8), + ], +) def test_im_ref_p_lindhard(im_ref_p_lindhard, test_input, expected): actual = im_ref_p_lindhard(test_input) np.testing.assert_allclose( - actual, expected, - rtol=1e-4, err_msg='imrp is inaccurate for Lindhard case', verbose=True + actual, + expected, + rtol=1e-4, + err_msg="imrp is inaccurate for Lindhard case", + verbose=True, ) diff --git a/tests/noise/test_zeta.py b/tests/noise/test_zeta.py index 72a51dd..7315581 100644 --- a/tests/noise/test_zeta.py +++ b/tests/noise/test_zeta.py @@ -8,49 +8,65 @@ from pynam.baskets import CalculationParams @pytest.fixture def zeta_p_integrand_lindhard(): - params = CalculationParams(omega=1e9, v_f=2e6, omega_p=3.544907701811032e15, tau=1e-14) + params = CalculationParams( + omega=1e9, v_f=2e6, omega_p=3.544907701811032e15, tau=1e-14 + ) eps_l = pynam.dielectric.get_lindhard_dielectric(params) return pynam.noise.zeta.get_zeta_p_integrand(eps_l) -@pytest.mark.parametrize("test_input,expected", [ - # y u zeta_p_i(u, y) - ((100, 100), -6.891930153028566e-13 - 7.957747045025948e-9j), - ((1e5, 100), -1.0057257267146669e-10 - 4.0591966623027983e-13j), - ((100, 1e5), 1.1789175285399862e-8 - 7.957833322596519e-9j) -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + # y u zeta_p_i(u, y) + ((100, 100), -6.891930153028566e-13 - 7.957747045025948e-9j), + ((1e5, 100), -1.0057257267146669e-10 - 4.0591966623027983e-13j), + ((100, 1e5), 1.1789175285399862e-8 - 7.957833322596519e-9j), + ], +) def test_zeta_p_integrand_lindhard(zeta_p_integrand_lindhard, test_input, expected): actual = zeta_p_integrand_lindhard(*test_input) np.testing.assert_allclose( - actual, expected, - rtol=1e-7, err_msg='Zeta_p is inaccurate for Lindhard case', verbose=True + actual, + expected, + rtol=1e-7, + err_msg="Zeta_p is inaccurate for Lindhard case", + verbose=True, ) @pytest.fixture def zeta_p_lindhard(): - params = CalculationParams(omega=1e9, v_f=2e6, omega_p=3.544907701811032e15, tau=1e-14) + params = CalculationParams( + omega=1e9, v_f=2e6, omega_p=3.544907701811032e15, tau=1e-14 + ) eps_l = pynam.dielectric.get_lindhard_dielectric(params) return pynam.noise.zeta.get_zeta_p_function(eps_l) -@pytest.mark.parametrize("test_input,expected", [ - # u zeta_p(u) - (1, 0.000199609 - 0.000199608j), - # (10, 0.00019960929309663014 - 0.00019927000998506335j), - # (100, 0.0001996175250684056 - 0.0001654898843938523j), - # (1e3, 0.0002003339895748246 + 0.003212370020888438j), - # (1e4, 0.00028616168676982363 + 0.34096962141224463j), - (1e5, 0.0025183067257958545 + 34.11087430547122j), - (1e6, 0.026829658454640887 + 3411.0870128247902j), - (1e7, 0.4292211181081069 + 341088.797211291j), - (1e8, 14.348462224076096 + 3.391157983312813e7j) -]) +@pytest.mark.parametrize( + "test_input,expected", + [ + # u zeta_p(u) + (1, 0.000199609 - 0.000199608j), + # (10, 0.00019960929309663014 - 0.00019927000998506335j), + # (100, 0.0001996175250684056 - 0.0001654898843938523j), + # (1e3, 0.0002003339895748246 + 0.003212370020888438j), + # (1e4, 0.00028616168676982363 + 0.34096962141224463j), + (1e5, 0.0025183067257958545 + 34.11087430547122j), + (1e6, 0.026829658454640887 + 3411.0870128247902j), + (1e7, 0.4292211181081069 + 341088.797211291j), + (1e8, 14.348462224076096 + 3.391157983312813e7j), + ], +) def test_zeta_p(zeta_p_lindhard, test_input, expected): actual = zeta_p_lindhard(test_input) np.testing.assert_allclose( - actual, expected, - rtol=1e-4, err_msg='Zeta_p is inaccurate for Lindhard case', verbose=True + actual, + expected, + rtol=1e-4, + err_msg="Zeta_p is inaccurate for Lindhard case", + verbose=True, ) diff --git a/tests/test_pynam.py b/tests/test_pynam.py index 801087d..d5628b3 100644 --- a/tests/test_pynam.py +++ b/tests/test_pynam.py @@ -2,4 +2,4 @@ from pynam import __version__ def test_version(): - assert __version__ == '0.1.0' + assert __version__ == "0.1.0" diff --git a/tests/util/test_complex_integrate.py b/tests/util/test_complex_integrate.py index 6088896..3068b25 100644 --- a/tests/util/test_complex_integrate.py +++ b/tests/util/test_complex_integrate.py @@ -3,18 +3,28 @@ import pynam.util.complex_integrate def test_complex_quad(): - actual = pynam.util.complex_integrate.complex_quad(lambda x: x ** 2 + 1j * x ** 3, 0, 6)[0] + actual = pynam.util.complex_integrate.complex_quad( + lambda x: x**2 + 1j * x**3, 0, 6 + )[0] # int_1^6 dx x^2 + i x^3 should equal (1/3)6^3 + (i/4)6^4 np.testing.assert_almost_equal( - actual, (6**3)/3 + 1j*(6**4)/4, - decimal=7, err_msg='complex quadrature is broken', verbose=True + actual, + (6**3) / 3 + 1j * (6**4) / 4, + decimal=7, + err_msg="complex quadrature is broken", + verbose=True, ) def test_complex_quadrature(): - actual = pynam.util.complex_integrate.complex_quadrature(lambda x: x ** 2 + 1j * x ** 3, 0, 6)[0] + actual = pynam.util.complex_integrate.complex_quadrature( + lambda x: x**2 + 1j * x**3, 0, 6 + )[0] # int_1^6 dx x^2 + i x^3 should equal (1/3)6^3 + (i/4)6^4 np.testing.assert_almost_equal( - actual, (6**3)/3 + 1j*(6**4)/4, - decimal=7, err_msg='complex quadrature is broken', verbose=True + actual, + (6**3) / 3 + 1j * (6**4) / 4, + decimal=7, + err_msg="complex quadrature is broken", + verbose=True, )