From 537aaf6db0f86c491a6845980fd6f54acd31eb12 Mon Sep 17 00:00:00 2001 From: Deepak Date: Sun, 12 Jul 2020 19:15:19 -0500 Subject: [PATCH] Initial commit --- .gitattributes | 29 +++++ .gitignore | 140 ++++++++++++++++++++ README.md | 3 + poetry.lock | 260 +++++++++++++++++++++++++++++++++++++ pynam/__init__.py | 1 + pynam/complex_quad.py | 16 +++ pynam/low_k_nam.py | 55 ++++++++ pynam/sigma_nam.py | 61 +++++++++ pyproject.toml | 18 +++ tests/__init__.py | 0 tests/test_complex_quad.py | 11 ++ tests/test_low_k_nam.py | 103 +++++++++++++++ tests/test_pynam.py | 5 + tests/test_sigma_nam.py | 120 +++++++++++++++++ 14 files changed, 822 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 README.md create mode 100644 poetry.lock create mode 100644 pynam/__init__.py create mode 100644 pynam/complex_quad.py create mode 100644 pynam/low_k_nam.py create mode 100644 pynam/sigma_nam.py create mode 100644 pyproject.toml create mode 100644 tests/__init__.py create mode 100644 tests/test_complex_quad.py create mode 100644 tests/test_low_k_nam.py create mode 100644 tests/test_pynam.py create mode 100644 tests/test_sigma_nam.py diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..7609af9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,29 @@ +# Basic .gitattributes for a python repo. + +# Source files +# ============ +*.pxd text diff=python +*.py text diff=python +*.py3 text diff=python +*.pyw text diff=python +*.pyx text diff=python +*.pyz text diff=python +*.pyi text diff=python + +# Binary files +# ============ +*.db binary +*.p binary +*.pkl binary +*.pickle binary +*.pyc binary +*.pyd binary +*.pyo binary + +# Jupyter notebook +*.ipynb text + +# Note: .db, .p, and .pkl files are associated +# with the python modules ``pickle``, ``dbm.*``, +# ``shelve``, ``marshal``, ``anydbm``, & ``bsddb`` +# (among others). diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..75aa508 --- /dev/null +++ b/.gitignore @@ -0,0 +1,140 @@ +.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/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..cc6e970 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# pynam + +python port of `nam_analysis` diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..06aa4c7 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,260 @@ +[[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"}, +] diff --git a/pynam/__init__.py b/pynam/__init__.py new file mode 100644 index 0000000..b794fd4 --- /dev/null +++ b/pynam/__init__.py @@ -0,0 +1 @@ +__version__ = '0.1.0' diff --git a/pynam/complex_quad.py b/pynam/complex_quad.py new file mode 100644 index 0000000..fbc0189 --- /dev/null +++ b/pynam/complex_quad.py @@ -0,0 +1,16 @@ +import numpy as np +from scipy.integrate import quad + + +def complex_quadrature(func, a, b, **kwargs): + + def real_func(x): + return np.real(func(x)) + + def imag_func(x): + return np.imag(func(x)) + + 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:] diff --git a/pynam/low_k_nam.py b/pynam/low_k_nam.py new file mode 100644 index 0000000..bed90d0 --- /dev/null +++ b/pynam/low_k_nam.py @@ -0,0 +1,55 @@ +import numpy as np +from numpy.lib.scimath import sqrt as csqrt + +import pynam.complex_quad + + +def g(w, wp): + 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 + + +def i1(w, wp, k, v): + gv = g(w, wp) + e1 = csqrt((w + 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) + + return f_upper + f_lower + + +def i2(w, wp, k, v): + gv = g(w, wp) + e1 = csqrt((w + 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) + + return f_upper + f_lower + + +def a(w, k, v, t): + return pynam.complex_quad.complex_quadrature( + 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)) + + +def b(w, k, v, t, b_max=np.inf): + return pynam.complex_quad.complex_quadrature( + lambda wp: b_int(wp, w, k, v, t), 1, b_max + )[0] + + +def sigma_nam_alk(w, k, v, t): + return -1j * (3 / 4) * (v / w) * (-a(w, k, v, t) + b(w, k, v, t)) diff --git a/pynam/sigma_nam.py b/pynam/sigma_nam.py new file mode 100644 index 0000000..740f94c --- /dev/null +++ b/pynam/sigma_nam.py @@ -0,0 +1,61 @@ +import numpy as np +from numpy.lib.scimath import sqrt as csqrt + +import pynam.complex_quad + + +def g(w, wp): + return ((wp * (w + wp)) + 1) / (csqrt(wp ** 2 - 1) * csqrt((w + wp) ** 2 - 1)) + + +def s(k, e, v): + return (e - 1j * v) / k + + +def f(k, e, v): + sv = s(k, e, v) + logv = np.log(np.real_if_close((sv + 1) / (sv - 1)) + 0j) + return (1 / k) * (2 * sv + ((1 - sv**2) * logv)) + + +def i1(w, wp, k, v): + gv = g(w, wp) + e1 = csqrt((w + 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) + + return f_upper + f_lower + + +def i2(w, wp, k, v): + gv = g(w, wp) + e1 = csqrt((w + 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) + + return f_upper + f_lower + + +def a(w, k, v, t): + return pynam.complex_quad.complex_quadrature( + 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)) + + +def b(w, k, v, t, b_max=np.inf): + return pynam.complex_quad.complex_quadrature( + lambda wp: b_int(wp, w, k, v, t), 1, b_max + )[0] + + +def sigma_nam(w, k, v, t): + return -1j * (3 / 4) * (v / w) * (-a(w, k, v, t) + b(w, k, v, t)) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..da0edbc --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,18 @@ +[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" diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_complex_quad.py b/tests/test_complex_quad.py new file mode 100644 index 0000000..e29b479 --- /dev/null +++ b/tests/test_complex_quad.py @@ -0,0 +1,11 @@ +import numpy as np +import pynam.complex_quad + + +def test_complex_quad(): + actual = pynam.complex_quad.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 + ) diff --git a/tests/test_low_k_nam.py b/tests/test_low_k_nam.py new file mode 100644 index 0000000..38bb966 --- /dev/null +++ b/tests/test_low_k_nam.py @@ -0,0 +1,103 @@ +import pynam.low_k_nam +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)) +]) +def test_g(test_input, expected): + np.testing.assert_almost_equal( + pynam.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) +]) +def test_f(test_input, expected): + np.testing.assert_almost_equal( + pynam.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) +]) +def test_i1(test_input, expected): + np.testing.assert_almost_equal( + pynam.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) +]) +def test_i2(test_input, expected): + np.testing.assert_almost_equal( + pynam.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), +]) +def test_a(test_input, expected): + actual = np.real_if_close(pynam.low_k_nam.a(*test_input)) + np.testing.assert_almost_equal( + 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), +]) +def test_b_int(test_input, expected): + actual = np.real_if_close(pynam.low_k_nam.b_int(*test_input)) + np.testing.assert_almost_equal( + 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), +]) +def test_b(test_input, expected): + actual = np.real_if_close(pynam.low_k_nam.b(*test_input)) + np.testing.assert_almost_equal( + 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), +]) +def test_sigma_alk(test_input, expected): + actual = np.real_if_close(pynam.low_k_nam.sigma_nam_alk(*test_input)) + np.testing.assert_almost_equal( + actual, expected, + decimal=6, err_msg='b function is off' + ) + + +def test_sigma_alk_benchmark(benchmark): + result = benchmark(pynam.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' + ) diff --git a/tests/test_pynam.py b/tests/test_pynam.py new file mode 100644 index 0000000..801087d --- /dev/null +++ b/tests/test_pynam.py @@ -0,0 +1,5 @@ +from pynam import __version__ + + +def test_version(): + assert __version__ == '0.1.0' diff --git a/tests/test_sigma_nam.py b/tests/test_sigma_nam.py new file mode 100644 index 0000000..70bb7fc --- /dev/null +++ b/tests/test_sigma_nam.py @@ -0,0 +1,120 @@ +import pynam.sigma_nam +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)) +]) +def test_g(test_input, expected): + np.testing.assert_almost_equal( + pynam.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) +]) +def test_s(test_input, expected): + np.testing.assert_almost_equal( + pynam.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) +]) +def test_f(test_input, expected): + np.testing.assert_almost_equal( + pynam.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) +]) +def test_i1(test_input, expected): + np.testing.assert_almost_equal( + pynam.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) +]) +def test_i2(test_input, expected): + np.testing.assert_almost_equal( + pynam.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), +]) +def test_a(test_input, expected): + actual = np.real_if_close(pynam.sigma_nam.a(*test_input)) + np.testing.assert_almost_equal( + actual, expected, + decimal=6, 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), +]) +def test_b_int(test_input, expected): + actual = np.real_if_close(pynam.sigma_nam.b_int(*test_input)) + np.testing.assert_almost_equal( + 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), +]) +def test_b(test_input, expected): + actual = np.real_if_close(pynam.sigma_nam.b(*test_input)) + np.testing.assert_almost_equal( + actual, actual, + 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), +]) +def test_sigma_nam(test_input, expected): + actual = np.real_if_close(pynam.sigma_nam.sigma_nam(*test_input)) + np.testing.assert_almost_equal( + actual, expected, + decimal=6, err_msg='sigma_nam function is off' + ) + + +def test_sigma_nam_benchmark(benchmark): + result = benchmark(pynam.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' + )