From d74ebe4dfc0b571e6a56a41748521e2a2747f754 Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Mon, 16 Dec 2019 19:04:04 +0100 Subject: [PATCH 01/24] Travis-CI: Make using python3 explicit --- .travis.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 113bf3b1..85c09b8c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,13 +11,15 @@ addons: - pandoc - ffmpeg install: - - pip install . - - pip install -r tests/requirements.txt - - pip install -r doc/requirements.txt + - python3 --version + - python3 -m pip --version + - python3 -m pip install . + - python3 -m pip install -r tests/requirements.txt + - python3 -m pip install -r doc/requirements.txt # This is needed in example scripts: - - pip install pillow + - python3 -m pip install pillow script: - - python -m pytest - - python doc/examples/run_all.py + - python3 -m pytest + - python3 doc/examples/run_all.py # This executes the example notebooks and runs the doctests: - - python -m sphinx doc/ _build/ -b doctest + - python3 -m sphinx doc/ _build/ -b doctest From 45f2c28794c83b42b778be6ea77243c80d3615b7 Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Mon, 16 Dec 2019 18:08:42 +0100 Subject: [PATCH 02/24] Travis-CI: Add test on macOS --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.travis.yml b/.travis.yml index 85c09b8c..bf641f3e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,11 +5,18 @@ matrix: - python: "3.5" - python: "3.6" - python: "3.7" + - os: osx + language: generic + python: "" addons: apt: packages: - pandoc - ffmpeg + homebrew: + packages: + - pandoc + - ffmpeg install: - python3 --version - python3 -m pip --version From f11970f582dab527ada81d33f70340535ca3e90d Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Mon, 16 Dec 2019 18:03:21 +0100 Subject: [PATCH 03/24] Travis-CI: Add Python 3.8 to test matrix --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index bf641f3e..03c40e9a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ matrix: - python: "3.5" - python: "3.6" - python: "3.7" + - python: "3.8" - os: osx language: generic python: "" From cdb7b347e6d724fcd327744108c2dd9976455b1a Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Mon, 16 Dec 2019 18:04:39 +0100 Subject: [PATCH 04/24] Travis-CI: Upgrade to Ubuntu Bionic Beaver --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 03c40e9a..11dc995a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: python -dist: xenial +dist: bionic matrix: include: - python: "3.5" From 84de59f6d920e6b697378649b882a860a4e6361f Mon Sep 17 00:00:00 2001 From: Matthias Geier Date: Sun, 22 Dec 2019 11:52:54 +0100 Subject: [PATCH 05/24] DOC: autodoc_default_flags -> autodoc_default_options Former has been deprecated and it stopped working in Sphinx's master branch: https://github.com/sphinx-doc/sphinx/issues/6930 --- doc/conf.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/conf.py b/doc/conf.py index a319efa1..07b7c4f8 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -56,7 +56,10 @@ autoclass_content = 'init' autodoc_member_order = 'bysource' -autodoc_default_flags = ['members', 'undoc-members'] +autodoc_default_options = { + 'members': True, + 'undoc-members': True, +} autosummary_generate = ['api'] From 2bc70e99edc7479cb924cc8eedca8c34136cd639 Mon Sep 17 00:00:00 2001 From: Sascha Spors Date: Mon, 24 Feb 2020 16:17:42 +0100 Subject: [PATCH 06/24] Consistent nomenclature for secondary source distance --- sfs/array.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/sfs/array.py b/sfs/array.py index 899075cb..17274757 100644 --- a/sfs/array.py +++ b/sfs/array.py @@ -289,7 +289,7 @@ def rectangular(N, spacing, *, center=[0, 0, 0], orientation=[1, 0, 0]): return SecondarySourceDistribution(positions, normals, weights) -def rounded_edge(Nxy, Nr, dx, *, center=[0, 0, 0], orientation=[1, 0, 0]): +def rounded_edge(Nxy, Nr, spacing, *, center=[0, 0, 0], orientation=[1, 0, 0]): """Return SSD along the xy-axis with rounded edge at the origin. Parameters @@ -299,6 +299,8 @@ def rounded_edge(Nxy, Nr, dx, *, center=[0, 0, 0], orientation=[1, 0, 0]): Nr : int Number of secondary sources in rounded edge. Radius of edge is adjusted to equdistant sampling along entire array. + spacing : float + Distance (in metres) between secondary sources. center : (3,) array_like, optional Position of edge. orientation : (3,) array_like, optional @@ -323,10 +325,11 @@ def rounded_edge(Nxy, Nr, dx, *, center=[0, 0, 0], orientation=[1, 0, 0]): """ # radius of rounded edge Nr += 1 - R = 2/_np.pi * Nr * dx + R = 2/_np.pi * Nr * spacing # array along y-axis - x00, n00, a00 = linear(Nxy, dx, center=[0, Nxy//2*dx+dx/2+R, 0]) + x00, n00, a00 = linear(Nxy, spacing, + center=[0, Nxy//2*spacing+spacing/2+R, 0]) x00 = _np.flipud(x00) positions = x00 directions = n00 @@ -342,13 +345,14 @@ def rounded_edge(Nxy, Nr, dx, *, center=[0, 0, 0], orientation=[1, 0, 0]): x00[n, 1] = R * (1 - _np.sin(alpha)) n00[n, 0] = _np.cos(alpha) n00[n, 1] = _np.sin(alpha) - a00[n] = dx + a00[n] = spacing positions = _np.concatenate((positions, x00)) directions = _np.concatenate((directions, n00)) weights = _np.concatenate((weights, a00)) # array along x-axis - x00, n00, a00 = linear(Nxy, dx, center=[Nxy//2*dx-dx/2+R, 0, 0], + x00, n00, a00 = linear(Nxy, spacing, + center=[Nxy//2*spacing-spacing/2+R, 0, 0], orientation=[0, 1, 0]) x00 = _np.flipud(x00) positions = _np.concatenate((positions, x00)) @@ -363,13 +367,15 @@ def rounded_edge(Nxy, Nr, dx, *, center=[0, 0, 0], orientation=[1, 0, 0]): return SecondarySourceDistribution(positions, directions, weights) -def edge(Nxy, dx, *, center=[0, 0, 0], orientation=[1, 0, 0]): +def edge(Nxy, spacing, *, center=[0, 0, 0], orientation=[1, 0, 0]): """Return SSD along the xy-axis with sharp edge at the origin. Parameters ---------- Nxy : int Number of secondary sources along x- and y-axis. + spacing : float + Distance (in metres) between secondary sources. center : (3,) array_like, optional Position of edge. orientation : (3,) array_like, optional @@ -393,14 +399,16 @@ def edge(Nxy, dx, *, center=[0, 0, 0], orientation=[1, 0, 0]): """ # array along y-axis - x00, n00, a00 = linear(Nxy, dx, center=[0, Nxy//2*dx+dx/2, 0]) + x00, n00, a00 = linear(Nxy, spacing, + center=[0, Nxy//2*spacing+spacing/2, 0]) x00 = _np.flipud(x00) positions = x00 directions = n00 weights = a00 # array along x-axis - x00, n00, a00 = linear(Nxy, dx, center=[Nxy//2*dx-dx/2, 0, 0], + x00, n00, a00 = linear(Nxy, spacing, + center=[Nxy//2*spacing-spacing/2, 0, 0], orientation=[0, 1, 0]) x00 = _np.flipud(x00) positions = _np.concatenate((positions, x00)) From 4d55ff05a1d77438ae914ab3b7b5370bfa9dda98 Mon Sep 17 00:00:00 2001 From: Sascha Spors Date: Thu, 5 Mar 2020 16:39:33 +0100 Subject: [PATCH 07/24] Added optional parameter for size and documentation --- sfs/plot2d.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/sfs/plot2d.py b/sfs/plot2d.py index f05936e5..ae2a348c 100644 --- a/sfs/plot2d.py +++ b/sfs/plot2d.py @@ -72,8 +72,20 @@ def reference(xref, *, size=0.1, ax=None): ax.plot((xref[0]-size, xref[0]+size), (xref[1]+size, xref[1]-size), 'k-') -def secondary_sources(x0, n0, *, grid=None): - """Simple plot of secondary source locations.""" +def secondary_sources(x0, n0, *, size=0.05, grid=None): + """Simple visualization of secondary source locations. + + Parameters + ---------- + x0 : (N, 3) array_like + Loudspeaker positions. + n0 : (N, 3) or (3,) array_like + Normal vector(s) of loudspeakers. + size : float, optional + Size of loudspeakers in metres. + grid : triple of array_like, optional + If specified, only loudspeakers within the *grid* are shown. + """ x0 = _np.asarray(x0) n0 = _np.asarray(n0) ax = _plt.gca() @@ -84,7 +96,7 @@ def secondary_sources(x0, n0, *, grid=None): # plot symbols for x00 in x0: - ss = _plt.Circle(x00[0:2], .05, edgecolor='k', facecolor='k') + ss = _plt.Circle(x00[0:2], size, edgecolor='k', facecolor='k') ax.add_artist(ss) From 21553ec9a1fbeddc766bd114c2789137123f7c08 Mon Sep 17 00:00:00 2001 From: Frank Schultz Date: Fri, 25 Sep 2020 10:56:47 +0200 Subject: [PATCH 08/24] bugfix: xref same dim as x0 to create reference curves not only a single point --- sfs/fd/wfs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sfs/fd/wfs.py b/sfs/fd/wfs.py index 817b4eb8..e134227d 100644 --- a/sfs/fd/wfs.py +++ b/sfs/fd/wfs.py @@ -223,7 +223,7 @@ def point_25d(omega, x0, n0, xs, xref=[0, 0, 0], c=None, omalias=None): x0 = _util.asarray_of_rows(x0) n0 = _util.asarray_of_rows(n0) xs = _util.asarray_1d(xs) - xref = _util.asarray_1d(xref) + xref = _util.asarray_of_rows(xref) k = _util.wavenumber(omega, c) ds = x0 - xs From bc0eb0fe9fa39e9e9d29c6e579f3677f0237cc23 Mon Sep 17 00:00:00 2001 From: Sascha Spors Date: Wed, 11 Nov 2020 13:34:28 +0100 Subject: [PATCH 09/24] API changes in matplotlib.pyplot.scatter, added docstring --- sfs/plot2d.py | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/sfs/plot2d.py b/sfs/plot2d.py index ae2a348c..efadb9c0 100644 --- a/sfs/plot2d.py +++ b/sfs/plot2d.py @@ -330,8 +330,38 @@ def level(p, grid, *, xnorm=None, power=False, cmap=None, vmax=3, vmin=-50, def particles(x, *, trim=None, ax=None, xlabel='x (m)', ylabel='y (m)', - edgecolor='', marker='.', s=15, **kwargs): - """Plot particle positions as scatter plot""" + edgecolors=None, marker='.', s=15, **kwargs): + """Plot particle positions as scatter plot. + + Parameters + ---------- + x : triple or pair of array_like + x, y and optionally z components of particle positions. The z + components are ignored. + If the values are complex, the imaginary parts are ignored. + + Returns + ------- + Scatter + See :func:`matplotlib.pyplot.scatter`. + + Other Parameters + ---------------- + trim : array of float, optional + xmin, xmax, ymin, ymax limits for which the particles are plotted. + ax : Axes, optional + If given, the plot is created on *ax* instead of the current + axis (see :func:`matplotlib.pyplot.gca`). + xlabel, ylabel : str + Overwrite default x/y labels. Use ``xlabel=''`` and + ``ylabel=''`` to remove x/y labels. The labels can be changed + afterwards with :func:`matplotlib.pyplot.xlabel` and + :func:`matplotlib.pyplot.ylabel`. + edgecolors, markr, s, **kwargs + All further parameters are forwarded to + :func:`matplotlib.pyplot.scatter`. + + """ XX, YY = [_np.real(c) for c in x[:2]] if trim is not None: @@ -348,7 +378,7 @@ def particles(x, *, trim=None, ax=None, xlabel='x (m)', ylabel='y (m)', ax.set_xlabel(xlabel) if ylabel: ax.set_ylabel(ylabel) - return ax.scatter(XX, YY, edgecolor=edgecolor, marker=marker, s=s, + return ax.scatter(XX, YY, edgecolors=edgecolors, marker=marker, s=s, **kwargs) From 2622d7099833aa21a0817a2053948b4dd4c8ca4e Mon Sep 17 00:00:00 2001 From: Hagen Wierstorf Date: Tue, 1 Dec 2020 11:03:58 +0100 Subject: [PATCH 10/24] Replace travis with GitHub for running CI jobs (#166) * use Github Action for executing CI jobs * removed travis CI jobs * removed support for Python 3.5 --- .github/workflows/test.yml | 45 ++++++++++++++++++++++++++++++++++++++ .travis.yml | 33 ---------------------------- setup.py | 3 +-- 3 files changed, 46 insertions(+), 35 deletions(-) create mode 100644 .github/workflows/test.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..22d7f47c --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,45 @@ +name: Test + +on: [push, pull_request] + +jobs: + build: + + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macOS-latest, windows-latest] + python-version: [3.6, 3.7, 3.8] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Prepare Ubuntu + run: | + sudo apt-get update + sudo apt-get install --no-install-recommends -y pandoc ffmpeg + if: matrix.os == 'ubuntu-latest' + - name: Prepare OSX + run: brew install pandoc ffmpeg + if: matrix.os == 'macOS-latest' + - name: prepare Windows + run: choco install pandoc ffmpeg + if: matrix.os == 'windows-latest' + - name: Install dependencies + run: | + python -V + python -m pip install --upgrade pip + python -m pip install . + python -m pip install -r tests/requirements.txt + python -m pip install -r doc/requirements.txt + # This is needed in example scripts: + python -m pip install pillow + - name: Test + run: python -m pytest + - name: Test examples + run: python doc/examples/run_all.py + - name: Test documentation + run: python -m sphinx doc/ _build/ -b doctest diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 11dc995a..00000000 --- a/.travis.yml +++ /dev/null @@ -1,33 +0,0 @@ -language: python -dist: bionic -matrix: - include: - - python: "3.5" - - python: "3.6" - - python: "3.7" - - python: "3.8" - - os: osx - language: generic - python: "" -addons: - apt: - packages: - - pandoc - - ffmpeg - homebrew: - packages: - - pandoc - - ffmpeg -install: - - python3 --version - - python3 -m pip --version - - python3 -m pip install . - - python3 -m pip install -r tests/requirements.txt - - python3 -m pip install -r doc/requirements.txt - # This is needed in example scripts: - - python3 -m pip install pillow -script: - - python3 -m pytest - - python3 doc/examples/run_all.py - # This executes the example notebooks and runs the doctests: - - python3 -m sphinx doc/ _build/ -b doctest diff --git a/setup.py b/setup.py index fc2bee52..9a7d8701 100644 --- a/setup.py +++ b/setup.py @@ -24,14 +24,13 @@ keywords="audio SFS WFS Ambisonics".split(), url="http://github.com/sfstoolbox/", platforms='any', - python_requires='>=3.5', + python_requires='>=3.6', classifiers=[ "Development Status :: 3 - Alpha", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3 :: Only", From 2391e1edeeab522abb62122692b34021e6f94045 Mon Sep 17 00:00:00 2001 From: Sascha Spors Date: Tue, 1 Dec 2020 12:50:22 +0100 Subject: [PATCH 11/24] Release 0.6.0 (#167) --- NEWS.rst | 5 +++++ sfs/__init__.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/NEWS.rst b/NEWS.rst index 6df799c6..be8f405b 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -1,6 +1,11 @@ Version History =============== + +Version 0.6.0 (2020-12-01): + * New function `sfs.fd.source.line_bandlimited()` computing the sound field of a spatially bandlimited line source + * Drop support for Python 3.5 + Version 0.5.0 (2019-03-18): * Switching to separate `sfs.plot2d` and `sfs.plot3d` for plotting functions * Move `sfs.util.displacement()` to `sfs.fd.displacement()` diff --git a/sfs/__init__.py b/sfs/__init__.py index 2072d811..85d02d71 100644 --- a/sfs/__init__.py +++ b/sfs/__init__.py @@ -16,7 +16,7 @@ util """ -__version__ = "0.5.0" +__version__ = "0.6.0" class default: From 17ab94d0d349daf1539f7b320e542aab0568d595 Mon Sep 17 00:00:00 2001 From: Frank Schultz Date: Fri, 4 Dec 2020 09:37:18 +0100 Subject: [PATCH 12/24] Fix doc string of synthesize() (#165) --- sfs/fd/__init__.py | 3 +-- sfs/td/__init__.py | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/sfs/fd/__init__.py b/sfs/fd/__init__.py index 2d9555e4..1dfe2cb6 100644 --- a/sfs/fd/__init__.py +++ b/sfs/fd/__init__.py @@ -53,8 +53,7 @@ def synthesize(d, weights, ssd, secondary_source_function, **kwargs): This signature is expected:: secondary_source_function( - position, normal_vector, weight, driving_function_weight, - **kwargs) -> numpy.ndarray + position, normal_vector, **kwargs) -> numpy.ndarray **kwargs All keyword arguments are forwarded to *secondary_source_function*. diff --git a/sfs/td/__init__.py b/sfs/td/__init__.py index 5efb20a5..a786ea54 100644 --- a/sfs/td/__init__.py +++ b/sfs/td/__init__.py @@ -37,8 +37,7 @@ def synthesize(signals, weights, ssd, secondary_source_function, **kwargs): This signature is expected:: secondary_source_function( - position, normal_vector, weight, driving_signal, - **kwargs) -> numpy.ndarray + position, normal_vector, **kwargs) -> numpy.ndarray **kwargs All keyword arguments are forwarded to *secondary_source_function*. From 002a967c92d1ca6fc904ffdefffcebaa10c49748 Mon Sep 17 00:00:00 2001 From: Hagen Wierstorf Date: Mon, 18 Jan 2021 17:18:23 +0100 Subject: [PATCH 13/24] DOC: add compatibility for sphinxcontrib-bibtex>=2 --- doc/conf.py | 2 ++ doc/references.rst | 2 +- doc/requirements.txt | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 07b7c4f8..caec59ae 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -46,6 +46,8 @@ 'nbsphinx', ] +bibtex_bibfiles = ['references.bib'] + nbsphinx_execute_arguments = [ "--InlineBackend.figure_formats={'svg', 'pdf'}", "--InlineBackend.rc={'figure.dpi': 96}", diff --git a/doc/references.rst b/doc/references.rst index 4b3db95d..d08e90e6 100644 --- a/doc/references.rst +++ b/doc/references.rst @@ -1,6 +1,6 @@ References ========== -.. bibliography:: references.bib +.. bibliography:: :style: alpha :all: diff --git a/doc/requirements.txt b/doc/requirements.txt index e2e3ce91..4f038ca3 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -2,7 +2,7 @@ Sphinx>=1.3.6 Sphinx-RTD-Theme nbsphinx ipykernel -sphinxcontrib-bibtex +sphinxcontrib-bibtex>=2.1.4 NumPy SciPy From 230e2e21901d802d8e52f7ef4a800c2e955c0eb1 Mon Sep 17 00:00:00 2001 From: Hagen Wierstorf Date: Tue, 19 Jan 2021 13:32:14 +0100 Subject: [PATCH 14/24] Fix reference in max_order_circular_harmonics() --- sfs/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sfs/util.py b/sfs/util.py index b054346a..c15358fa 100644 --- a/sfs/util.py +++ b/sfs/util.py @@ -610,7 +610,7 @@ def max_order_circular_harmonics(N): r"""Maximum order of 2D/2.5D HOA. It returns the maximum order for which no spatial aliasing appears. - It is given on page 132 of [Ahrens2012]_ as + It is given on page 132 of :cite:`Ahrens2012` as .. math:: \mathtt{max\_order} = From 21bd666e9babb09df10dac0228b0fb077eee82ff Mon Sep 17 00:00:00 2001 From: Hagen Wierstorf Date: Tue, 19 Jan 2021 13:35:57 +0100 Subject: [PATCH 15/24] DOC: include only cited references --- doc/references.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/references.rst b/doc/references.rst index d08e90e6..8905446f 100644 --- a/doc/references.rst +++ b/doc/references.rst @@ -3,4 +3,3 @@ References .. bibliography:: :style: alpha - :all: From efdda38a9fb44d5a529c1deec56b27e44f5f785c Mon Sep 17 00:00:00 2001 From: Frank Schultz Date: Sat, 16 Jan 2021 16:28:44 +0100 Subject: [PATCH 16/24] introduce new wfs 2.5D point source time domain driving function --- sfs/td/wfs.py | 117 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 109 insertions(+), 8 deletions(-) diff --git a/sfs/td/wfs.py b/sfs/td/wfs.py index ab2531f6..d0aa1f41 100644 --- a/sfs/td/wfs.py +++ b/sfs/td/wfs.py @@ -39,7 +39,8 @@ def plot(d, selection, secondary_source, t=0): p = sfs.td.synthesize(d, selection, array, secondary_source, grid=grid, observation_time=t) sfs.plot2d.level(p, grid) - sfs.plot2d.loudspeakers(array.x, array.n, selection * array.a, size=0.15) + sfs.plot2d.loudspeakers(array.x, array.n, + selection * array.a, size=0.15) """ import numpy as _np @@ -92,9 +93,9 @@ def plane_25d(x0, n0, n=[0, 1, 0], xref=[0, 0, 0], c=None): .. math:: - d_{2.5D}(x_0,t) = h(t) + d_{2.5D}(x_0,t) = 2 g_0 \scalarprod{n}{n_0} - \dirac{t - \frac{1}{c} \scalarprod{n}{x_0}} + \dirac{t - \frac{1}{c} \scalarprod{n}{x_0}} \ast_t h(t) with wfs(2.5D) prefilter h(t), which is not implemented yet. @@ -125,7 +126,101 @@ def plane_25d(x0, n0, n=[0, 1, 0], xref=[0, 0, 0], c=None): def point_25d(x0, n0, xs, xref=[0, 0, 0], c=None): - r"""Point source by 2.5-dimensional WFS. + r"""Driving function for 2.5-dimensional WFS of a virtual point source. + + .. versionchanged:: 0.61 + see notes, old handling of `point_25d()` is now `point_25d_legacy()` + + Parameters + ---------- + x0 : (N, 3) array_like + Sequence of secondary source positions. + n0 : (N, 3) array_like + Sequence of secondary source orientations. + xs : (3,) array_like + Virtual source position. + xref : (N, 3) array_like or (3,) array_like + Reference curve of correct amplitude xref(x0) + c : float, optional + Speed of sound + + Returns + ------- + delays : (N,) numpy.ndarray + Delays of secondary sources in seconds. + weights: (N,) numpy.ndarray + Weights of secondary sources. + selection : (N,) numpy.ndarray + Boolean array containing ``True`` or ``False`` depending on + whether the corresponding secondary source is "active" or not. + secondary_source_function : callable + A function that can be used to create the sound field of a + single secondary source. See `sfs.td.synthesize()`. + + Notes + ----- + + Eq. (2.138) in :cite:`Schultz2016`: + + .. math:: + + d_{2.5D}(x_0, x_{ref}, t) = + \sqrt{8\pi} + \frac{\scalarprod{(x_0 - x_s)}{n_0}}{|x_0 - x_s|} + \sqrt{\frac{|x_0 - x_s||x_0 - x_{ref}|}{|x_0 - x_s|+|x_0 - x_{ref}|}} + \cdot + \frac{\dirac{t - \frac{|x_0 - x_s|}{c}}}{4\pi |x_0 - x_s|} \ast_t h(t) + + .. math:: + + h(t) = F^{-1}(\sqrt{\frac{j \omega}{c}}) + + with wfs(2.5D) prefilter h(t), which is not implemented yet. + + `point_25d()` derives WFS from 3D to 2.5D via the stationary phase + approximation approach (i.e. the Delft approach). + The theoretical link of `point_25d()` and `point_25d_legacy()` was + introduced as *unified WFS framework* in :cite:`Firtha2017`. + + Examples + -------- + .. plot:: + :context: close-figs + + delays, weights, selection, secondary_source = \ + sfs.td.wfs.point_25d(array.x, array.n, xs) + d = sfs.td.wfs.driving_signals(delays, weights, signal) + plot(d, selection, secondary_source, t=ts) + + """ + if c is None: + c = _default.c + x0 = _util.asarray_of_rows(x0) + n0 = _util.asarray_of_rows(n0) + xs = _util.asarray_1d(xs) + xref = _util.asarray_of_rows(xref) + + x0xs = x0 - xs + x0xref = x0 - xref + x0xs_n = _np.linalg.norm(x0xs, axis=1) + x0xref_n = _np.linalg.norm(x0xref, axis=1) + + g0 = 1/(_np.sqrt(2*_np.pi)*x0xs_n**2) + g0 *= _np.sqrt((x0xs_n*x0xref_n)/(x0xs_n+x0xref_n)) + + delays = x0xs_n/c + weights = g0*_inner1d(x0xs, n0) + selection = _util.source_selection_point(n0, x0, xs) + return delays, weights, selection, _secondary_source_point(c) + + +def point_25d_legacy(x0, n0, xs, xref=[0, 0, 0], c=None): + r"""Driving function for 2.5-dimensional WFS of a virtual point source. + + .. versionadded:: 0.61 + `point_25d()` was renamed to `point_25d_legacy()` (and a new + function with the name `point_25d()` was introduced). See notes below + for further details. Parameters ---------- @@ -166,15 +261,21 @@ def point_25d(x0, n0, xs, xref=[0, 0, 0], c=None): .. math:: - d_{2.5D}(x_0,t) = h(t) + d_{2.5D}(x_0,t) = \frac{g_0 \scalarprod{(x_0 - x_s)}{n_0}} {2\pi |x_0 - x_s|^{3/2}} - \dirac{t - \frac{|x_0 - x_s|}{c}} + \dirac{t - \frac{|x_0 - x_s|}{c}} \ast_t h(t) with wfs(2.5D) prefilter h(t), which is not implemented yet. See :sfs:`d_wfs/#equation-td-wfs-point-25d` + `point_25d_legacy()` derives 2.5D WFS from the 2D + Neumann-Rayleigh integral (i.e. the approach by Rabenstein & Spors), cf. + :cite:`Spors2008`. + The theoretical link of `point_25d()` and `point_25d_legacy()` was + introduced as *unified WFS framework* in :cite:`Firtha2017`. + Examples -------- .. plot:: @@ -248,10 +349,10 @@ def focused_25d(x0, n0, xs, ns, xref=[0, 0, 0], c=None): .. math:: - d_{2.5D}(x_0,t) = h(t) + d_{2.5D}(x_0,t) = \frac{g_0 \scalarprod{(x_0 - x_s)}{n_0}} {|x_0 - x_s|^{3/2}} - \dirac{t + \frac{|x_0 - x_s|}{c}} + \dirac{t + \frac{|x_0 - x_s|}{c}} \ast_t h(t) with wfs(2.5D) prefilter h(t), which is not implemented yet. From 834c69749ed7ae47487faf95dea3171511bc6a72 Mon Sep 17 00:00:00 2001 From: Frank Schultz Date: Sat, 5 Jun 2021 13:22:44 +0200 Subject: [PATCH 17/24] Release 0.6.1 --- NEWS.rst | 3 +++ sfs/__init__.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS.rst b/NEWS.rst index be8f405b..457f5217 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -2,6 +2,9 @@ Version History =============== +Version 0.6.1 (2021-06-05): + * New default driving function for `sfs.td.wfs.point_25d()` for reference curve + Version 0.6.0 (2020-12-01): * New function `sfs.fd.source.line_bandlimited()` computing the sound field of a spatially bandlimited line source * Drop support for Python 3.5 diff --git a/sfs/__init__.py b/sfs/__init__.py index 85d02d71..2c6c16f7 100644 --- a/sfs/__init__.py +++ b/sfs/__init__.py @@ -16,7 +16,7 @@ util """ -__version__ = "0.6.0" +__version__ = "0.6.1" class default: From 8c787f3bbaeae9fb06a2e75d57a2103badd83cf5 Mon Sep 17 00:00:00 2001 From: Frank Schultz Date: Sat, 5 Jun 2021 18:16:01 +0200 Subject: [PATCH 18/24] build doc fix, use sphinx4, mathjax2, html_css_files --- doc/conf.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index caec59ae..35b28742 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -35,7 +35,6 @@ extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.autosummary', - 'sphinx.ext.mathjax', 'sphinx.ext.viewcode', 'sphinx.ext.napoleon', # support for NumPy-style docstrings 'sphinx.ext.intersphinx', @@ -95,7 +94,22 @@ } plot_formats = ['svg', 'pdf'] -mathjax_config = { +# use mathjax2 with +# https://github.com/spatialaudio/nbsphinx/issues/572#issuecomment-853389268 +# and 'TeX' dictionary +# in future we might switch to mathjax3 once the +# 'begingroup' extension is available +# http://docs.mathjax.org/en/latest/input/tex/extensions/begingroup.html#begingroup +# https://mathjax.github.io/MathJax-demos-web/convert-configuration/convert-configuration.html +mathjax_path = ('https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js' + '?config=TeX-AMS-MML_HTMLorMML') +mathjax2_config = { + 'tex2jax': { + 'inlineMath': [['$', '$'], ['\\(', '\\)']], + 'processEscapes': True, + 'ignoreClass': 'document', + 'processClass': 'math|output_area', + }, 'TeX': { 'extensions': ['newcommand.js', 'begingroup.js'], # Support for \gdef }, @@ -219,9 +233,7 @@ # -- Options for HTML output ---------------------------------------------- -def setup(app): - """Include custom theme files to sphinx HTML header""" - app.add_stylesheet('css/title.css') +html_css_files = ['css/title.css'] # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. From 51d8493b39db63d01012688326d2a3fff95bf357 Mon Sep 17 00:00:00 2001 From: Frank Schultz Date: Sat, 5 Jun 2021 20:12:04 +0200 Subject: [PATCH 19/24] Release 0.6.2 --- NEWS.rst | 3 +++ sfs/__init__.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS.rst b/NEWS.rst index 457f5217..0a1d06d2 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -2,6 +2,9 @@ Version History =============== +Version 0.6.2 (2021-06-05): + * build doc fix, use sphinx4, mathjax2, html_css_files + Version 0.6.1 (2021-06-05): * New default driving function for `sfs.td.wfs.point_25d()` for reference curve diff --git a/sfs/__init__.py b/sfs/__init__.py index 2c6c16f7..6e3d57c5 100644 --- a/sfs/__init__.py +++ b/sfs/__init__.py @@ -16,7 +16,7 @@ util """ -__version__ = "0.6.1" +__version__ = "0.6.2" class default: From 043e9dd0f6aae5eeebbed8357968a2669d29fc40 Mon Sep 17 00:00:00 2001 From: Frank Schultz Date: Thu, 21 Jan 2021 11:50:34 +0100 Subject: [PATCH 20/24] docstring mods wfs.py in td/fd follow up #168, reference to v0.6.1 --- sfs/fd/wfs.py | 5 ++--- sfs/td/wfs.py | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/sfs/fd/wfs.py b/sfs/fd/wfs.py index e134227d..44fb2c6a 100644 --- a/sfs/fd/wfs.py +++ b/sfs/fd/wfs.py @@ -171,9 +171,8 @@ def point_25d(omega, x0, n0, xs, xref=[0, 0, 0], c=None, omalias=None): Sequence of normal vectors of secondary sources. xs : (3,) array_like Position of virtual point source. - xref : (3,) array_like, optional - Reference point xref or contour xref(x0) for amplitude correct - synthesis. + xref : (N, 3) array_like or (3,) array_like + Contour xref(x0) for amplitude correct synthesis, reference point xref. c : float, optional Speed of sound in m/s. omalias: float, optional diff --git a/sfs/td/wfs.py b/sfs/td/wfs.py index d0aa1f41..3b59301e 100644 --- a/sfs/td/wfs.py +++ b/sfs/td/wfs.py @@ -128,7 +128,7 @@ def plane_25d(x0, n0, n=[0, 1, 0], xref=[0, 0, 0], c=None): def point_25d(x0, n0, xs, xref=[0, 0, 0], c=None): r"""Driving function for 2.5-dimensional WFS of a virtual point source. - .. versionchanged:: 0.61 + .. versionchanged:: 0.6.1 see notes, old handling of `point_25d()` is now `point_25d_legacy()` Parameters @@ -140,7 +140,7 @@ def point_25d(x0, n0, xs, xref=[0, 0, 0], c=None): xs : (3,) array_like Virtual source position. xref : (N, 3) array_like or (3,) array_like - Reference curve of correct amplitude xref(x0) + Contour xref(x0) for amplitude correct synthesis, reference point xref. c : float, optional Speed of sound @@ -159,7 +159,6 @@ def point_25d(x0, n0, xs, xref=[0, 0, 0], c=None): Notes ----- - Eq. (2.138) in :cite:`Schultz2016`: .. math:: @@ -217,7 +216,7 @@ def point_25d(x0, n0, xs, xref=[0, 0, 0], c=None): def point_25d_legacy(x0, n0, xs, xref=[0, 0, 0], c=None): r"""Driving function for 2.5-dimensional WFS of a virtual point source. - .. versionadded:: 0.61 + .. versionadded:: 0.6.1 `point_25d()` was renamed to `point_25d_legacy()` (and a new function with the name `point_25d()` was introduced). See notes below for further details. From eff86e7b2b541a099822096313eea29c003450db Mon Sep 17 00:00:00 2001 From: Hagen Wierstorf Date: Tue, 8 Jul 2025 19:11:54 +0200 Subject: [PATCH 21/24] Replace Python 3.6, 3.7 with 3.9, 3.10 (#180) * Replace Python 3.6, 3.7 with 3.9, 3.10 * Fix definition of Python version * Try to fix readthedocs config * Fix Python version in readthedocs config * Replace removed inner1d * Try changes from #179 * Fix remaining inner1d errors * Fix ptp() error * Don't limit numpy version * Fix _np import * Try to fix readthedocs config * Update test.yml * Update test.yml check with ubuntu only, current python only * Update test.yml redo * Update test.yml redo2 * Update test.yml go for 3.11, 3.12 there is still some code that is not working, but we merged into the main branch, such that most of the toolbox can be used out of the main branch --------- Co-authored-by: Frank Schultz --- .github/workflows/test.yml | 8 ++++---- doc/readthedocs-environment.yml | 14 -------------- readthedocs.yml | 13 ++++++++++--- setup.py | 7 ++++--- sfs/fd/wfs.py | 13 ++++++------- sfs/plot2d.py | 14 +++++++++----- sfs/td/wfs.py | 11 +++++------ sfs/util.py | 10 +++++++--- 8 files changed, 45 insertions(+), 45 deletions(-) delete mode 100644 doc/readthedocs-environment.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 22d7f47c..54f10553 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,12 +9,12 @@ jobs: strategy: matrix: os: [ubuntu-latest, macOS-latest, windows-latest] - python-version: [3.6, 3.7, 3.8] - + python-version: ['3.11', '3.12'] + steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Prepare Ubuntu diff --git a/doc/readthedocs-environment.yml b/doc/readthedocs-environment.yml deleted file mode 100644 index d5ff0570..00000000 --- a/doc/readthedocs-environment.yml +++ /dev/null @@ -1,14 +0,0 @@ -channels: - - conda-forge -dependencies: - - python>=3 - - sphinx>=1.3.6 - - sphinx_rtd_theme - - sphinxcontrib-bibtex - - numpy - - scipy - - matplotlib>=1.5 - - ipykernel - - pandoc - - pip: - - nbsphinx diff --git a/readthedocs.yml b/readthedocs.yml index 65bb0f41..7ff6f6a9 100644 --- a/readthedocs.yml +++ b/readthedocs.yml @@ -1,4 +1,11 @@ -conda: - file: doc/readthedocs-environment.yml +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.8" + python: - pip_install: true + install: + - requirements: requirements.txt + - requirements: doc/requirements.txt diff --git a/setup.py b/setup.py index 9a7d8701..e0f01888 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ version=__version__, packages=find_packages(), install_requires=[ - 'numpy!=1.11.0', # https://github.com/sfstoolbox/sfs-python/issues/11 + 'numpy', 'scipy', ], author="SFS Toolbox Developers", @@ -31,8 +31,9 @@ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3 :: Only", "Topic :: Scientific/Engineering", ], diff --git a/sfs/fd/wfs.py b/sfs/fd/wfs.py index 44fb2c6a..840b59e9 100644 --- a/sfs/fd/wfs.py +++ b/sfs/fd/wfs.py @@ -32,7 +32,6 @@ def plot(d, selection, secondary_source): """ import numpy as _np -from numpy.core.umath_tests import inner1d as _inner1d from scipy.special import hankel2 as _hankel2 from . import secondary_source_line as _secondary_source_line @@ -91,7 +90,7 @@ def line_2d(omega, x0, n0, xs, *, c=None): k = _util.wavenumber(omega, c) ds = x0 - xs r = _np.linalg.norm(ds, axis=1) - d = -1j/2 * k * _inner1d(ds, n0) / r * _hankel2(1, k * r) + d = -1j/2 * k * _util._inner1d(ds, n0) / r * _hankel2(1, k * r) selection = _util.source_selection_line(n0, x0, xs) return d, selection, _secondary_source_line(omega, c) @@ -147,7 +146,7 @@ def _point(omega, x0, n0, xs, *, c=None): k = _util.wavenumber(omega, c) ds = x0 - xs r = _np.linalg.norm(ds, axis=1) - d = 1j * k * _inner1d(ds, n0) / r ** (3 / 2) * _np.exp(-1j * k * r) + d = 1j * k * _util._inner1d(ds, n0) / r ** (3 / 2) * _np.exp(-1j * k * r) selection = _util.source_selection_point(n0, x0, xs) return d, selection, _secondary_source_point(omega, c) @@ -234,7 +233,7 @@ def point_25d(omega, x0, n0, xs, xref=[0, 0, 0], c=None, omalias=None): preeq_25d(omega, omalias, c) * _np.sqrt(8 * _np.pi) * _np.sqrt((r * s) / (r + s)) * - _inner1d(n0, ds) / s * + _util._inner1d(n0, ds) / s * _np.exp(-1j * k * s) / (4 * _np.pi * s)) selection = _util.source_selection_point(n0, x0, xs) return d, selection, _secondary_source_point(omega, c) @@ -316,7 +315,7 @@ def point_25d_legacy(omega, x0, n0, xs, xref=[0, 0, 0], c=None, omalias=None): r = _np.linalg.norm(ds, axis=1) d = ( preeq_25d(omega, omalias, c) * - _np.sqrt(_np.linalg.norm(xref - x0)) * _inner1d(ds, n0) / + _np.sqrt(_np.linalg.norm(xref - x0)) * _util._inner1d(ds, n0) / r ** (3 / 2) * _np.exp(-1j * k * r)) selection = _util.source_selection_point(n0, x0, xs) return d, selection, _secondary_source_point(omega, c) @@ -499,7 +498,7 @@ def _focused(omega, x0, n0, xs, ns, *, c=None): k = _util.wavenumber(omega, c) ds = x0 - xs r = _np.linalg.norm(ds, axis=1) - d = 1j * k * _inner1d(ds, n0) / r ** (3 / 2) * _np.exp(1j * k * r) + d = 1j * k * _util._inner1d(ds, n0) / r ** (3 / 2) * _np.exp(1j * k * r) selection = _util.source_selection_focused(ns, x0, xs) return d, selection, _secondary_source_point(omega, c) @@ -569,7 +568,7 @@ def focused_25d(omega, x0, n0, xs, ns, *, xref=[0, 0, 0], c=None, r = _np.linalg.norm(ds, axis=1) d = ( preeq_25d(omega, omalias, c) * - _np.sqrt(_np.linalg.norm(xref - x0)) * _inner1d(ds, n0) / + _np.sqrt(_np.linalg.norm(xref - x0)) * _util._inner1d(ds, n0) / r ** (3 / 2) * _np.exp(1j * k * r)) selection = _util.source_selection_focused(ns, x0, xs) return d, selection, _secondary_source_point(omega, c) diff --git a/sfs/plot2d.py b/sfs/plot2d.py index efadb9c0..63f69966 100644 --- a/sfs/plot2d.py +++ b/sfs/plot2d.py @@ -18,13 +18,17 @@ def _register_cmap_clip(name, original_cmap, alpha): cmap = LinearSegmentedColormap.from_list(name, cdata) cmap.set_over([alpha * c + 1 - alpha for c in cmap(1.0)[:3]]) cmap.set_under([alpha * c + 1 - alpha for c in cmap(0.0)[:3]]) - _plt.cm.register_cmap(cmap=cmap) + _plt.colormaps.register(cmap=cmap) # The 'coolwarm' colormap is based on the paper # "Diverging Color Maps for Scientific Visualization" by Kenneth Moreland # http://www.sandia.gov/~kmorel/documents/ColorMaps/ -_register_cmap_clip('coolwarm_clip', 'coolwarm', 0.7) +# already registered in MPL 3.9.0 +try: + _register_cmap_clip('coolwarm_clip', 'coolwarm', 0.7) +except ImportError: + pass def _register_cmap_transparent(name, color): @@ -36,7 +40,7 @@ def _register_cmap_transparent(name, color): 'blue': ((0, blue, blue), (1, blue, blue)), 'alpha': ((0, 0, 0), (1, 1, 1))} cmap = LinearSegmentedColormap(name, cdict) - _plt.cm.register_cmap(cmap=cmap) + _plt.colormaps.register(cmap=cmap) _register_cmap_transparent('blacktransparent', 'black') @@ -285,8 +289,8 @@ def amplitude(p, grid, *, xnorm=None, cmap='coolwarm_clip', elif plotting_plane == 'yz': x, y = grid[[1, 2]] - dx = 0.5 * x.ptp() / p.shape[0] - dy = 0.5 * y.ptp() / p.shape[1] + dx = 0.5 * _np.ptp(x) / p.shape[0] + dy = 0.5 * _np.ptp(y) / p.shape[1] if ax is None: ax = _plt.gca() diff --git a/sfs/td/wfs.py b/sfs/td/wfs.py index 3b59301e..3e112082 100644 --- a/sfs/td/wfs.py +++ b/sfs/td/wfs.py @@ -44,7 +44,6 @@ def plot(d, selection, secondary_source, t=0): """ import numpy as _np -from numpy.core.umath_tests import inner1d as _inner1d from . import apply_delays as _apply_delays from . import secondary_source_point as _secondary_source_point @@ -119,8 +118,8 @@ def plane_25d(x0, n0, n=[0, 1, 0], xref=[0, 0, 0], c=None): n = _util.normalize_vector(n) xref = _util.asarray_1d(xref) g0 = _np.sqrt(2 * _np.pi * _np.linalg.norm(xref - x0, axis=1)) - delays = _inner1d(n, x0) / c - weights = 2 * g0 * _inner1d(n, n0) + delays = _util._inner1d(n, x0) / c + weights = 2 * g0 * _util._inner1d(n, n0) selection = _util.source_selection_plane(n0, n) return delays, weights, selection, _secondary_source_point(c) @@ -208,7 +207,7 @@ def point_25d(x0, n0, xs, xref=[0, 0, 0], c=None): g0 *= _np.sqrt((x0xs_n*x0xref_n)/(x0xs_n+x0xref_n)) delays = x0xs_n/c - weights = g0*_inner1d(x0xs, n0) + weights = g0 * _util._inner1d(x0xs, n0) selection = _util.source_selection_point(n0, x0, xs) return delays, weights, selection, _secondary_source_point(c) @@ -296,7 +295,7 @@ def point_25d_legacy(x0, n0, xs, xref=[0, 0, 0], c=None): ds = x0 - xs r = _np.linalg.norm(ds, axis=1) delays = r/c - weights = g0 * _inner1d(ds, n0) / (2 * _np.pi * r**(3/2)) + weights = g0 * _util._inner1d(ds, n0) / (2 * _np.pi * r**(3/2)) selection = _util.source_selection_point(n0, x0, xs) return delays, weights, selection, _secondary_source_point(c) @@ -379,7 +378,7 @@ def focused_25d(x0, n0, xs, ns, xref=[0, 0, 0], c=None): g0 = _np.sqrt(_np.linalg.norm(xref - x0, axis=1) / (_np.linalg.norm(xref - x0, axis=1) + r)) delays = -r/c - weights = g0 * _inner1d(ds, n0) / (2 * _np.pi * r**(3/2)) + weights = g0 * _util._inner1d(ds, n0) / (2 * _np.pi * r**(3/2)) selection = _util.source_selection_focused(ns, x0, xs) return delays, weights, selection, _secondary_source_point(c) diff --git a/sfs/util.py b/sfs/util.py index c15358fa..de2ead57 100644 --- a/sfs/util.py +++ b/sfs/util.py @@ -6,7 +6,6 @@ import collections import numpy as np -from numpy.core.umath_tests import inner1d from scipy.special import spherical_jn, spherical_yn from . import default @@ -576,7 +575,7 @@ def source_selection_point(n0, x0, xs): x0 = asarray_of_rows(x0) xs = asarray_1d(xs) ds = x0 - xs - return inner1d(ds, n0) >= default.selection_tolerance + return _inner1d(ds, n0) >= default.selection_tolerance def source_selection_line(n0, x0, xs): @@ -598,7 +597,7 @@ def source_selection_focused(ns, x0, xs): xs = asarray_1d(xs) ns = normalize_vector(ns) ds = xs - x0 - return inner1d(ns, ds) >= default.selection_tolerance + return _inner1d(ns, ds) >= default.selection_tolerance def source_selection_all(N): @@ -646,3 +645,8 @@ def max_order_spherical_harmonics(N): """ return int(np.sqrt(N) - 1) + + +def _inner1d(arr1, arr2): + # https://github.com/numpy/numpy/issues/10815#issuecomment-376847774 + return (arr1 * arr2).sum(axis=1) From 4f6bf52afa6f8da7851affbadd621af5794401c3 Mon Sep 17 00:00:00 2001 From: Frank Schultz Date: Tue, 8 Jul 2025 19:41:17 +0200 Subject: [PATCH 22/24] Update time_domain_nfchoa.py reduce order due to Exception: Zeros failed to converge in newer scipy version?! --- doc/examples/time_domain_nfchoa.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/examples/time_domain_nfchoa.py b/doc/examples/time_domain_nfchoa.py index 929c1ef8..19563a00 100644 --- a/doc/examples/time_domain_nfchoa.py +++ b/doc/examples/time_domain_nfchoa.py @@ -33,7 +33,7 @@ plt.savefig('impulse_pw_nfchoa_25d.png') # Point source -max_order = 100 +max_order = 80 xs = [1.5, 1.5, 0] # position t = np.linalg.norm(xs) / sfs.default.c # observation time delay, weight, sos, phaseshift, selection, secondary_source = \ From c060b93e9c38bd5e9819a2b7e73fbcccd8419d96 Mon Sep 17 00:00:00 2001 From: Frank Schultz Date: Tue, 8 Jul 2025 19:48:10 +0200 Subject: [PATCH 23/24] vstack url formating doctest numpy2 float64 issue --- doc/conf.py | 2 +- sfs/array.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 35b28742..00865f9b 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -83,7 +83,7 @@ } extlinks = {'sfs': ('https://sfs.readthedocs.io/en/3.2/%s', - 'https://sfs.rtfd.io/')} + 'https://sfs.rtfd.io/%s')} plot_include_source = True plot_html_show_source_link = False diff --git a/sfs/array.py b/sfs/array.py index 17274757..148a5b5f 100644 --- a/sfs/array.py +++ b/sfs/array.py @@ -664,7 +664,7 @@ def weights_midpoint(positions, *, closed): >>> x0, n0, a0 = sfs.array.circular(2**5, 1) >>> a = sfs.array.weights_midpoint(x0, closed=True) >>> max(abs(a0-a)) - 0.0003152601902411123 + np.float64(0.0003152601902411123) """ positions = _util.asarray_of_rows(positions) @@ -672,7 +672,7 @@ def weights_midpoint(positions, *, closed): before, after = -1, 0 # cyclic else: before, after = 1, -2 # mirrored - positions = _np.row_stack((positions[before], positions, positions[after])) + positions = _np.vstack((positions[before], positions, positions[after])) distances = _np.linalg.norm(_np.diff(positions, axis=0), axis=1) return (distances[:-1] + distances[1:]) / 2 From 8f637707cc0dd897d7fae1d7e0b8a8db0f62f998 Mon Sep 17 00:00:00 2001 From: Frank Schultz Date: Wed, 16 Jul 2025 19:58:09 +0200 Subject: [PATCH 24/24] examples: animations numpy2.x related changes --- doc/examples/animations-pulsating-sphere.ipynb | 10 +++++++--- doc/examples/animations_pulsating_sphere.py | 6 ++++-- doc/examples/plot_particle_density.py | 4 +++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/doc/examples/animations-pulsating-sphere.ipynb b/doc/examples/animations-pulsating-sphere.ipynb index f8b1e22f..3ed8d990 100644 --- a/doc/examples/animations-pulsating-sphere.ipynb +++ b/doc/examples/animations-pulsating-sphere.ipynb @@ -147,7 +147,10 @@ "metadata": {}, "outputs": [], "source": [ - "grid = hex_grid([xmin, xmax], [ymin, ymax], 0.0125, 'vertical')\n", + "grid = sfs.util.as_xyz_components(hex_grid([xmin, xmax],\n", + " [ymin, ymax],\n", + " 0.0125,\n", + " 'vertical'))\n", "ani = animation.particle_displacement(\n", " omega, center, radius, amplitude, grid, frames, figsize, c='Gray')\n", "plt.close()\n", @@ -167,8 +170,9 @@ "metadata": {}, "outputs": [], "source": [ - "grid = [np.random.uniform(xmin, xmax, 4000),\n", - " np.random.uniform(ymin, ymax, 4000), 0]\n", + "grid = sfs.util.as_xyz_components([np.random.uniform(xmin, xmax, 4000),\n", + " np.random.uniform(ymin, ymax, 4000),\n", + " 0])\n", "ani = animation.particle_displacement(\n", " omega, center, radius, amplitude, grid, frames, figsize, c='Gray')\n", "plt.close()\n", diff --git a/doc/examples/animations_pulsating_sphere.py b/doc/examples/animations_pulsating_sphere.py index a4150679..a5fae46c 100644 --- a/doc/examples/animations_pulsating_sphere.py +++ b/doc/examples/animations_pulsating_sphere.py @@ -3,6 +3,8 @@ import numpy as np from matplotlib import pyplot as plt from matplotlib import animation +import warnings +warnings.simplefilter("ignore", np.exceptions.ComplexWarning) def particle_displacement(omega, center, radius, amplitude, grid, frames, @@ -18,7 +20,7 @@ def particle_displacement(omega, center, radius, amplitude, grid, frames, scat = sfs.plot2d.particles(grid + displacement, **kwargs) def update_frame_displacement(i): - position = (grid + displacement * phasor**i).apply(np.real) + position = np.real((grid + displacement * phasor**i)) position = np.column_stack([position[0].flatten(), position[1].flatten()]) scat.set_offsets(position) @@ -43,7 +45,7 @@ def particle_velocity(omega, center, radius, amplitude, grid, frames, **kwargs) def update_frame_velocity(i): - quiv.set_UVC(*(velocity[:2] * phasor**i).apply(np.real)) + np.real(quiv.set_UVC(*(velocity[:2] * phasor**i))) return [quiv] return animation.FuncAnimation( diff --git a/doc/examples/plot_particle_density.py b/doc/examples/plot_particle_density.py index b21cd20c..85471199 100644 --- a/doc/examples/plot_particle_density.py +++ b/doc/examples/plot_particle_density.py @@ -14,7 +14,9 @@ # normal vector of plane wave npw = sfs.util.direction_vector(np.radians(pw_angle)) # random grid for velocity -grid = [np.random.uniform(-3, 3, 40000), np.random.uniform(-3, 3, 40000), 0] +grid = sfs.util.as_xyz_components([np.random.uniform(-3, 3, 40000), + np.random.uniform(-3, 3, 40000), + 0]) def plot_particle_displacement(title):