From 06910290dc8922f760a4ab1ec9caf705a33ee6e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nico=20Schl=C3=B6mer?= Date: Wed, 2 Feb 2022 18:57:01 +0100 Subject: [PATCH 1/6] use tensordot --- src/npx/_main.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/npx/_main.py b/src/npx/_main.py index bd73634..e84f473 100644 --- a/src/npx/_main.py +++ b/src/npx/_main.py @@ -15,9 +15,7 @@ def dot(a: ArrayLike, b: ArrayLike) -> np.ndarray: """Take arrays `a` and `b` and form the dot product between the last axis of `a` and the first of `b`. """ - a = np.asarray(a) - b = np.asarray(b) - return np.dot(a, b.reshape(b.shape[0], -1)).reshape(a.shape[:-1] + b.shape[1:]) + return np.tensordot(a, b, 1) def outer(a: ArrayLike, b: ArrayLike) -> np.ndarray: From 29369e9a9403852d5eed7ddef0002faa2e11accb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nico=20Schl=C3=B6mer?= Date: Wed, 2 Feb 2022 19:00:59 +0100 Subject: [PATCH 2/6] add doc --- src/npx/_mean.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/npx/_mean.py b/src/npx/_mean.py index ce7471d..a0a57e0 100644 --- a/src/npx/_mean.py +++ b/src/npx/_mean.py @@ -11,6 +11,10 @@ def _logsumexp(x: ArrayLike): def mean(x: ArrayLike, p: float = 1) -> np.ndarray: + """Generalized mean. + + See for the numpy issue. + """ x = np.asarray(x) n = len(x) From 02dd06e261c6aa52d3260086df1d5ceeb35fac68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nico=20Schl=C3=B6mer?= Date: Wed, 2 Feb 2022 19:02:26 +0100 Subject: [PATCH 3/6] new black --- .pre-commit-config.yaml | 2 +- src/npx/_mean.py | 2 +- tests/speedtest.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ff4a3d5..cea1f19 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ repos: - id: isort - repo: https://github.com/psf/black - rev: 21.10b0 + rev: 22.1.0 hooks: - id: black language_version: python3 diff --git a/src/npx/_mean.py b/src/npx/_mean.py index a0a57e0..e58c523 100644 --- a/src/npx/_mean.py +++ b/src/npx/_mean.py @@ -39,4 +39,4 @@ def mean(x: ArrayLike, p: float = 1) -> np.ndarray: # only works for positive x though return np.exp((_logsumexp(p * np.log(x)) - np.log(n)) / p) else: - return (np.sum(x ** p) / n) ** (1.0 / p) + return (np.sum(x**p) / n) ** (1.0 / p) diff --git a/tests/speedtest.py b/tests/speedtest.py index 0291702..8ccc4cc 100644 --- a/tests/speedtest.py +++ b/tests/speedtest.py @@ -37,6 +37,6 @@ def npx_sum_at(data): b = perfplot.bench( setup=setup, kernels=[np_add_at, npx_add_at, npx_sum_at], - n_range=[2 ** k for k in range(23)], + n_range=[2**k for k in range(23)], ) b.save("perf-add-at.svg") From 04eac26a21ff9e5e5c38600b67131fd3c4253418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nico=20Schl=C3=B6mer?= Date: Wed, 2 Feb 2022 19:05:51 +0100 Subject: [PATCH 4/6] use flit --- LICENSE | 2 +- justfile | 17 ++++------------- pyproject.toml | 36 ++++++++++++++++++++++++++++++++++-- setup.cfg | 39 --------------------------------------- src/npx/__about__.py | 1 + src/npx/__init__.py | 2 ++ 6 files changed, 42 insertions(+), 55 deletions(-) delete mode 100644 setup.cfg create mode 100644 src/npx/__about__.py diff --git a/LICENSE b/LICENSE index 1e54017..48e4369 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2021 Nico Schlömer +Copyright 2021-2022 Nico Schlömer Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/justfile b/justfile index 38e14fa..7be5ede 100644 --- a/justfile +++ b/justfile @@ -1,21 +1,12 @@ -version := `python3 -c "from configparser import ConfigParser; p = ConfigParser(); p.read('setup.cfg'); print(p['metadata']['version'])"` -name := `python3 -c "from configparser import ConfigParser; p = ConfigParser(); p.read('setup.cfg'); print(p['metadata']['name'])"` - +version := `python3 -c "from src.npx.__about__ import __version__; print(__version__)"` default: @echo "\"just publish\"?" -tag: - @if [ "$(git rev-parse --abbrev-ref HEAD)" != "main" ]; then exit 1; fi - curl -H "Authorization: token `cat ~/.github-access-token`" -d '{"tag_name": "v{{version}}"}' https://api.github.com/repos/nschloe/{{name}}/releases - -upload: clean +publish: @if [ "$(git rev-parse --abbrev-ref HEAD)" != "main" ]; then exit 1; fi - # https://stackoverflow.com/a/58756491/353337 - python3 -m build --sdist --wheel . - twine upload dist/* - -publish: tag upload + gh release create "v{{version}}" + flit publish clean: @find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf diff --git a/pyproject.toml b/pyproject.toml index 8fe2f47..7d207d1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,35 @@ [build-system] -requires = ["setuptools>=42", "wheel"] -build-backend = "setuptools.build_meta" +requires = ["flit_core >=3.2,<4"] +build-backend = "flit_core.buildapi" + +[tool.isort] +profile = "black" + +[project] +name = "npx" +authors = [{name = "Nico Schlömer", email = "nico.schloemer@gmail.com"}] +description = "Some useful extensions for NumPy" +readme = "README.md" +license = {file = "LICENSE"} +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Topic :: Scientific/Engineering", + "Topic :: Utilities", +] +dynamic = ["version"] +requires-python = ">=3.7" +dependencies = ["numpy >= 1.20.0"] + +[project.urls] +Code = "https://github.com/nschloe/npx" +Issues = "https://github.com/nschloe/npx/issues" +Funding = "https://github.com/sponsors/nschloe" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 48d36a6..0000000 --- a/setup.cfg +++ /dev/null @@ -1,39 +0,0 @@ -[metadata] -name = npx -version = 0.0.25 -author = Nico Schlömer -author_email = nico.schloemer@gmail.com -description = Some useful extensions for NumPy -url = https://github.com/nschloe/npx -project_urls = - Code=https://github.com/nschloe/npx - Issues=https://github.com/nschloe/npx/issues - Funding=https://github.com/sponsors/nschloe -long_description = file: README.md -long_description_content_type = text/markdown -license = BSD-3-Clause -# See for all classifiers. -classifiers = - Development Status :: 4 - Beta - Intended Audience :: Science/Research - License :: OSI Approved :: BSD License - Operating System :: OS Independent - Programming Language :: Python - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.7 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Topic :: Scientific/Engineering - Topic :: Utilities - -[options] -package_dir = - =src -packages = find: -install_requires = - numpy >= 1.20.0 -python_requires = >=3.7 - -[options.packages.find] -where=src diff --git a/src/npx/__about__.py b/src/npx/__about__.py new file mode 100644 index 0000000..5a6b518 --- /dev/null +++ b/src/npx/__about__.py @@ -0,0 +1 @@ +__version__ = "0.0.25" diff --git a/src/npx/__init__.py b/src/npx/__init__.py index e0185b6..decd3c8 100644 --- a/src/npx/__init__.py +++ b/src/npx/__init__.py @@ -1,9 +1,11 @@ +from .__about__ import __version__ from ._isin import isin_rows from ._main import add_at, dot, outer, solve, subtract_at, sum_at from ._mean import mean from ._unique import unique, unique_rows __all__ = [ + "__version__", "dot", "outer", "solve", From ecd26eadda3a33609e0f9aee510753ffdc258051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nico=20Schl=C3=B6mer?= Date: Wed, 2 Feb 2022 19:06:02 +0100 Subject: [PATCH 5/6] version bump --- src/npx/__about__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/npx/__about__.py b/src/npx/__about__.py index 5a6b518..3dc1f76 100644 --- a/src/npx/__about__.py +++ b/src/npx/__about__.py @@ -1 +1 @@ -__version__ = "0.0.25" +__version__ = "0.1.0" From 9242c5e1e7da4b74bb64db835ab8ef3efb668693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nico=20Schl=C3=B6mer?= Date: Wed, 2 Feb 2022 19:50:50 +0100 Subject: [PATCH 6/6] some forth and back with mean() --- src/npx/_mean.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/npx/_mean.py b/src/npx/_mean.py index e58c523..8277194 100644 --- a/src/npx/_mean.py +++ b/src/npx/_mean.py @@ -28,15 +28,17 @@ def mean(x: ArrayLike, p: float = 1) -> np.ndarray: if np.any(x < 0.0): raise ValueError("p=0 only works with nonnegative x.") return np.prod(np.power(x, 1 / n)) + # alternative: + # return np.exp(np.mean(np.log(x))) elif p == np.inf: return np.max(np.abs(x)) - if not isinstance(p, int) and np.any(x < 0.0): - raise ValueError("Non-integer p only work with nonnegative x.") - if np.all(x > 0.0): # logsumexp trick to avoid overflow for large p # only works for positive x though return np.exp((_logsumexp(p * np.log(x)) - np.log(n)) / p) - else: - return (np.sum(x**p) / n) ** (1.0 / p) + + if not isinstance(p, (int, np.integer)): + raise ValueError(f"Non-integer p (={p}) only work with nonnegative x.") + + return (np.sum(x**p) / n) ** (1.0 / p)