From bcba22a5a8039938b24c374049c2609035f94a12 Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Mon, 1 Aug 2022 09:16:48 +0200 Subject: [PATCH 01/15] BLD: install missing `.pxd` files, and update TODOs/FIXMEs in meson.build files (#16749) * BLD: remove a warning suppression flag for HiGHS extension This is no longer necessary, the PR linked in the removed comment is included in our `highs` git submodule now. * BLD: remove an outdated FIXME from the scipy/integrate/meson.build This was fixed I believe (there are no skipped or xfailed tests either), and the comment isn't very informative. * BLD: remove another FIXME in `cython_optimize/meson.build`, it's not broken The code can be simplified once the upstream feature is added, but that's not a FIXME. * BLD: remove comments about c++14/c++11 support We can rely on C++14 unconditionally since 2021, see http://scipy.github.io/devdocs/dev/toolchain.html#c-language-standards * BLD: update info on including all license files as separate files * BLD: install missing `scipy/*.pxd` files No tests were failing, so something is fairly badly wrong in the test suite. Also add `optimize.cython_optimize` to the list of submodules that are public API. * BLD: remove FIXME about version string generation This was fixed when adding `--git-dir` to the git invocation, that made the result independent from the current directory when invoking the build. * BLD: remove TODO about `-fallow-argument-mismatch` This flag is added implicitly via 'fortran_std=legacy' in the top-level `meson.build`. Warnings that show up are silenced in multiple modules, so there's no need for a separate TODO here. * BLD: remove TODO for UNU.RAN version string This isn't a very useful today, given that we don't use this version string. The corresponding `setup.py` file also does the same and doesn't have a TODO. * BLD: update FIXME to a TODO in `linalg/meson.build` --- doc/API.rst.txt | 2 ++ meson.build | 2 +- pyproject.toml | 2 ++ scipy/_lib/_uarray/meson.build | 6 +----- scipy/fft/_pocketfft/meson.build | 2 +- scipy/integrate/meson.build | 2 -- scipy/linalg/meson.build | 5 ++--- scipy/meson.build | 11 +++++++---- scipy/optimize/_highs/meson.build | 3 --- scipy/optimize/cython_optimize/meson.build | 3 +-- scipy/optimize/meson.build | 1 + scipy/stats/_unuran/meson.build | 2 +- 12 files changed, 19 insertions(+), 22 deletions(-) diff --git a/doc/API.rst.txt b/doc/API.rst.txt index f0b7b51f4546..915c6bf03246 100644 --- a/doc/API.rst.txt +++ b/doc/API.rst.txt @@ -125,6 +125,8 @@ change is made. * `scipy.optimize` + - `scipy.optimize.cython_optimize + * `scipy.signal` - `scipy.signal.windows` diff --git a/meson.build b/meson.build index b23afa7a5ae9..6b254f0ba0ee 100644 --- a/meson.build +++ b/meson.build @@ -10,7 +10,7 @@ project( default_options: [ 'buildtype=debugoptimized', 'c_std=c99', - 'cpp_std=c++14', # TODO: use c++11 if 14 is not available + 'cpp_std=c++14', # TODO: the below -Wno flags are all needed to silence warnings in # f2py-generated code. This should be fixed in f2py itself. 'c_args=-Wno-unused-function -Wno-conversion -Wno-misleading-indentation -Wno-incompatible-pointer-types', diff --git a/pyproject.toml b/pyproject.toml index 1cf1a1d6f33e..27a244106f87 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,6 +55,8 @@ requires = [ [project] name = "SciPy" +# TODO: add `license-files` once PEP 639 is accepted (see meson-python#88) +# at that point, no longer include them in `py3.install_sources()` license = {file = "LICENSE.txt"} description = "Fundamental algorithms for scientific computing in Python" maintainers = [ diff --git a/scipy/_lib/_uarray/meson.build b/scipy/_lib/_uarray/meson.build index 88986370b23f..dd66899fc654 100644 --- a/scipy/_lib/_uarray/meson.build +++ b/scipy/_lib/_uarray/meson.build @@ -1,8 +1,3 @@ -# TODO: add_data_files('license') - -# TODO: this used -std=c++14 if available, add c++11 otherwise -# can we now rely on c++14 unconditionally? - py3.extension_module('_uarray', ['_uarray_dispatch.cxx', 'vectorcall.cxx'], cpp_args: ['-Wno-terminate', '-Wno-unused-function'], @@ -15,6 +10,7 @@ py3.extension_module('_uarray', python_sources = [ '__init__.py', '_backend.py', + 'LICENSE' ] py3.install_sources( diff --git a/scipy/fft/_pocketfft/meson.build b/scipy/fft/_pocketfft/meson.build index b3be2c206ab5..4147c8c7853d 100644 --- a/scipy/fft/_pocketfft/meson.build +++ b/scipy/fft/_pocketfft/meson.build @@ -16,7 +16,6 @@ else pocketfft_threads += ['-DPOCKETFFT_NO_MULTITHREADING'] endif -#TODO: add the equivalent of set_cxx_flags_hook py3.extension_module('pypocketfft', 'pypocketfft.cxx', cpp_args: pocketfft_threads, @@ -32,6 +31,7 @@ python_sources = [ '__init__.py', 'basic.py', 'helper.py', + 'LICENSE.md', 'realtransforms.py' ] diff --git a/scipy/integrate/meson.build b/scipy/integrate/meson.build index d0765b6d19bc..651890758473 100644 --- a/scipy/integrate/meson.build +++ b/scipy/integrate/meson.build @@ -190,8 +190,6 @@ py3.extension_module('_test_multivariate', subdir: 'scipy/integrate' ) -# FIXME: something is wrong with the signature file, subroutines are not used -# _test_odeint_banded _test_odeint_banded_module = custom_target('_test_odeint_banded_module', output: ['_test_odeint_bandedmodule.c', '_test_odeint_banded-f2pywrappers.f'], input: 'tests/banded5x5.pyf', diff --git a/scipy/linalg/meson.build b/scipy/linalg/meson.build index ff0e8394cf90..5e14298d7813 100644 --- a/scipy/linalg/meson.build +++ b/scipy/linalg/meson.build @@ -25,8 +25,8 @@ cython_linalg = custom_target('cython_linalg', ], input: '_generate_pyx.py', command: [py3, '@INPUT@', '-o', '@OUTDIR@'], - # FIXME - we only want to install the .pxd files! See comments for - # `pxd_files` further down. + # TODO - we only want to install the .pxd files! See comments for + # `pxd_files` further down. install: true, install_dir: py3.get_install_dir() + 'scipy/linalg' ) @@ -166,7 +166,6 @@ py3.extension_module('_interpolative', '-Wno-tabs', '-Wno-conversion', '-Wno-argument-mismatch', '-Wno-unused-dummy-argument', '-Wno-maybe-uninitialized' ], - # TODO: add -fallow-argument-mismatch for gfortran >= 10, see gh-11842 include_directories: [inc_np, inc_f2py], dependencies: [py3_dep, lapack], install: true, diff --git a/scipy/meson.build b/scipy/meson.build index a1e97b2ddaa9..1d3ab05a08f5 100644 --- a/scipy/meson.build +++ b/scipy/meson.build @@ -140,8 +140,6 @@ generate_config = custom_target( install_dir: py3.get_install_dir() + '/scipy' ) -#FIXME: the git revision is Unknown; script works when invoked directly, but -# not when it's run by Ninja. See https://github.com/rgommers/scipy/pull/57 generate_version = custom_target( 'generate-version', install: true, @@ -156,7 +154,10 @@ generate_version = custom_target( python_sources = [ '__init__.py', '_distributor_init.py', - 'conftest.py' + 'conftest.py', + 'linalg.pxd', + 'optimize.pxd', + 'special.pxd' ] py3.install_sources( @@ -176,14 +177,16 @@ _cython_tree = custom_target('_cython_tree', output: [ '__init__.py', 'linalg.pxd', + 'optimize.pxd', 'special.pxd' ], input: [ '__init__.py', 'linalg.pxd', + 'optimize.pxd', 'special.pxd' ], - command: [copier, '@INPUT@', '@OUTDIR@'] + command: [copier, '@INPUT@', '@OUTDIR@'], ) cython_tree = declare_dependency(sources: _cython_tree) diff --git a/scipy/optimize/_highs/meson.build b/scipy/optimize/_highs/meson.build index 53420ddba024..6cb930a92cf1 100644 --- a/scipy/optimize/_highs/meson.build +++ b/scipy/optimize/_highs/meson.build @@ -262,9 +262,6 @@ _highs_wrapper = py3.extension_module('_highs_wrapper', '-Wno-format-truncation', '-Wno-non-virtual-dtor', '-Wno-class-memaccess', - # Pass despite __STDC_FORMAT_MACROS redefinition warning. - # Remove after merge of https://github.com/ERGO-Code/HiGHS/pull/674 - '-Wp,-w', Wno_unused_but_set, highs_define_macros, cython_c_args, diff --git a/scipy/optimize/cython_optimize/meson.build b/scipy/optimize/cython_optimize/meson.build index d91e547cfea4..af03d9c71de3 100644 --- a/scipy/optimize/cython_optimize/meson.build +++ b/scipy/optimize/cython_optimize/meson.build @@ -1,4 +1,5 @@ # Needed to trick Cython, it won't do a relative import outside a package +# (see https://github.com/mesonbuild/meson/issues/8961) _dummy_init_cyoptimize = custom_target('_dummy_init_cyoptimize', output: [ '__init__.py', @@ -13,8 +14,6 @@ _dummy_init_cyoptimize = custom_target('_dummy_init_cyoptimize', command: [copier, '@INPUT@', '@OUTDIR@'] ) -# FIXME: generated .pyx which has relative cimport in it doesn't work yet (see -# https://github.com/mesonbuild/meson/issues/8961) _zeros_pyx = custom_target('_zeros_pyx', output: '_zeros.pyx', input: '_zeros.pyx.in', diff --git a/scipy/optimize/meson.build b/scipy/optimize/meson.build index 0bb8bfe07458..e4718ac4e13e 100644 --- a/scipy/optimize/meson.build +++ b/scipy/optimize/meson.build @@ -316,6 +316,7 @@ py3.install_sources([ '_tstutils.py', '_zeros_py.py', 'cobyla.py', + 'cython_optimize.pxd', 'lbfgsb.py', 'linesearch.py', 'minpack.py', diff --git a/scipy/stats/_unuran/meson.build b/scipy/stats/_unuran/meson.build index 0d55b18f3a0b..338aa3763200 100644 --- a/scipy/stats/_unuran/meson.build +++ b/scipy/stats/_unuran/meson.build @@ -164,7 +164,7 @@ unuran_include_dirs = [ '../../_lib/unuran/unuran/src/tests' ] -unuran_version = '16:0:0' # TODO: grab from configure.ac file +unuran_version = '16:0:0' # taken from `_lib/unuran/unuran/configure.ac` unuran_defines = [ '-DHAVE_ALARM=1', From 3b6160128ea36334c17fa42a834171344febee2b Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Mon, 1 Aug 2022 10:06:18 +0200 Subject: [PATCH 02/15] BLD: make OpenBLAS detection work with CMake (#16750) This is a fallback detection path, in case pkg-config fails to find `openblas`. CMake uses the camelcase version of the name. If CMake is installed and it finds OpenBLAS, the result looks like: ``` Determining dependency 'OpenBLAS' with pkg-config executable '/home/rgommers/anaconda3/envs/scipy-dev/bin/pkg-config' env[PKG_CONFIG_PATH]: Called `/home/rgommers/anaconda3/envs/scipy-dev/bin/pkg-config --modversion OpenBLAS` -> 1 CMake binary for 1 is cached. Determining dependency 'OpenBLAS' with CMake executable '/home/rgommers/anaconda3/envs/scipy-dev/bin/cmake' Try CMake generator: auto Calling CMake (['/home/rgommers/anaconda3/envs/scipy-dev/bin/cmake']) in /home/rgommers/code/scipy/build/meson-private/cmake_OpenBLAS with: - "-DNAME=OpenBLAS" - "-DARCHS=libpyldb-util.cpython-310-x86-64-linux-gnu.so;libpyldb-util.cpython-310-x86-64-linux-gnu.so.2;libpyldb-util.cpython-310-x86-64-linux-gnu.so.2.5.0;libpytalloc-util.cpython-310-x86-64-linux-gnu.so;libpytalloc-util.cpython-310-x86-64-linux-gnu.so.2;libpytalloc-util.cpython-310-x86-64-linux-gnu.so.2.3.3;libsamba-policy.cpython-310-x86-64-linux-gnu.so;libsamba-policy.cpython-310-x86-64-linux-gnu.so.0;libsamba-policy.cpython-310-x86-64-linux-gnu.so.0.0.1" - "-DVERSION=" - "-DCOMPS=" - "--trace-expand" - "--trace-format=json-v1" - "--no-warn-unused-cli" - "--trace-redirect=cmake_trace.txt" - "-DCMAKE_TOOLCHAIN_FILE=/home/rgommers/code/scipy/build/meson-private/cmake_OpenBLAS/CMakeMesonToolchainFile.cmake" - "." - "-DCMAKE_PREFIX_PATH=/home/rgommers/anaconda3/envs/scipy-dev;/home/rgommers/anaconda3/envs/scipy-dev/x86_64-conda-linux-gnu/sysroot/usr" using old-style CMake variables for dependency OpenBLAS Include Dirs: ['/home/rgommers/anaconda3/envs/scipy-dev/include'] Compiler Definitions: [] Libraries: ['/home/rgommers/anaconda3/envs/scipy-dev/lib/libopenblas.so'] Run-time dependency openblas found: YES 0.3.20 ``` This follows up on comments in gh-16308 --- scipy/meson.build | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/scipy/meson.build b/scipy/meson.build index 1d3ab05a08f5..5ff4ff721592 100644 --- a/scipy/meson.build +++ b/scipy/meson.build @@ -117,8 +117,18 @@ numpy_nodepr_api = '-DNPY_NO_DEPRECATED_API=NPY_1_9_API_VERSION' # For MKL and for auto-detecting one of multiple libs, we'll need a custom # dependency in Meson (like is done for scalapack) - see # https://github.com/mesonbuild/meson/issues/2835 -blas = dependency(get_option('blas')) -lapack = dependency(get_option('lapack')) +blas_name = get_option('blas') +lapack_name = get_option('lapack') +# pkg-config uses a lower-case name while CMake uses a capitalized name, so try +# that too to make the fallback detection with CMake work +if blas_name == 'openblas' + blas_name = ['openblas', 'OpenBLAS'] +endif +if lapack_name == 'openblas' + lapack_name = ['openblas', 'OpenBLAS'] +endif +blas = dependency(blas_name) +lapack = dependency(lapack_name) if blas.name() == 'mkl' or lapack.name() == 'mkl' or get_option('use-g77-abi') g77_abi_wrappers = files([ From 6ca618a0eef275c46130dd339543f27eafb0df06 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Tue, 2 Aug 2022 14:43:47 -0400 Subject: [PATCH 03/15] BLD: use a bit more idiomatic approach to constructing paths in meson Instead of string concatenation, use Meson's path operator, which was designed based on the same concept as pathlib.Path and uses the / operator overload (but effectively using .as_posix() for consistency). This guarantees consistent handling, and also avoids e.g. introspection files containing duplicated path separators such as `.../site-packages//scipy/...` This is also required in order for Meson to internally track when an install_dir string comes from py3.get_install_dir() after path-based joining semantics, which is needed for improvements to the mesonpy build backend. --- scipy/linalg/meson.build | 6 +++--- scipy/meson.build | 4 ++-- scipy/special/meson.build | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/scipy/linalg/meson.build b/scipy/linalg/meson.build index 5e14298d7813..4cb4a3634220 100644 --- a/scipy/linalg/meson.build +++ b/scipy/linalg/meson.build @@ -28,7 +28,7 @@ cython_linalg = custom_target('cython_linalg', # TODO - we only want to install the .pxd files! See comments for # `pxd_files` further down. install: true, - install_dir: py3.get_install_dir() + 'scipy/linalg' + install_dir: py3.get_install_dir() / 'scipy/linalg' ) # pyx -> c, pyx -> cpp generators, depending on __init__.py here. @@ -331,7 +331,7 @@ py3.install_sources( # https://mesonbuild.com/Installing.html says is for build targets to # use: # `custom_target(..., install: true, install_dir: ...) -# # should use `py3.get_install_dir() + 'scipy/linalg'` ? +# # should use `py3.get_install_dir() / 'scipy/linalg'` ? # see https://github.com/mesonbuild/meson/issues/3206 # # For the below code to work, the script generating the files should use @@ -349,7 +349,7 @@ py3.install_sources( # output : ['cython_blas2.pxd', 'cython_lapack2.pxd'], # command : ['cp', '@INPUT0@', '@OUTPUT0@', '&&', 'cp', '@INPUT1@', '@OUTPUT1@'], # install : true, -# install_dir: py3.get_install_dir() + 'scipy/linalg' +# install_dir: py3.get_install_dir() / 'scipy/linalg' #) subdir('tests') diff --git a/scipy/meson.build b/scipy/meson.build index 5ff4ff721592..086a44779d25 100644 --- a/scipy/meson.build +++ b/scipy/meson.build @@ -147,7 +147,7 @@ generate_config = custom_target( output: '__config__.py', input: '../tools/config_utils.py', command: [py3, '@INPUT@', '@OUTPUT@'], - install_dir: py3.get_install_dir() + '/scipy' + install_dir: py3.get_install_dir() / 'scipy' ) generate_version = custom_target( @@ -158,7 +158,7 @@ generate_version = custom_target( output: 'version.py', input: '../tools/version_utils.py', command: [py3, '@INPUT@', '--source-root', '@SOURCE_ROOT@'], - install_dir: py3.get_install_dir() + '/scipy' + install_dir: py3.get_install_dir() / 'scipy' ) python_sources = [ diff --git a/scipy/special/meson.build b/scipy/special/meson.build index 60aa384ae52b..72beba8764f0 100644 --- a/scipy/special/meson.build +++ b/scipy/special/meson.build @@ -347,7 +347,7 @@ cython_special = custom_target('cython_special', input: ['_generate_pyx.py', 'functions.json', '_add_newdocs.py'], command: [py3, '@INPUT0@', '-o', '@OUTDIR@'], install: true, - install_dir: py3.get_install_dir() + '/scipy/special' + install_dir: py3.get_install_dir() / 'scipy/special' ) # pyx -> c, pyx -> cpp generators, depending on copied pxi, pxd files. @@ -494,7 +494,7 @@ foreach npz_file: npz_files '--use-timestamp', npz_file[2], '-o', '@OUTDIR@' ], install: true, - install_dir: py3.get_install_dir() + '/scipy/special/tests/data' + install_dir: py3.get_install_dir() / 'scipy/special/tests/data' ) endforeach From 12d13582270842a62b315980fc6ad107ffb33e1e Mon Sep 17 00:00:00 2001 From: Matt Haberland Date: Thu, 4 Aug 2022 02:42:11 -0700 Subject: [PATCH 04/15] DOC: stats.skew/kurtosis: returns NaN when input has only one unique value (#16768) --- scipy/stats/_continuous_distns.py | 2 ++ scipy/stats/_stats_py.py | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/scipy/stats/_continuous_distns.py b/scipy/stats/_continuous_distns.py index d30c12c5adb6..1ec0d570d933 100644 --- a/scipy/stats/_continuous_distns.py +++ b/scipy/stats/_continuous_distns.py @@ -9151,6 +9151,8 @@ class rv_histogram(rv_continuous): The second containing the (n+1) bin boundaries In particular the return value np.histogram is accepted + .. versionadded:: 1.10.0 + Notes ----- There are no additional shape parameters except for the loc and scale. diff --git a/scipy/stats/_stats_py.py b/scipy/stats/_stats_py.py index a78dea60595c..be4b0e1b7320 100644 --- a/scipy/stats/_stats_py.py +++ b/scipy/stats/_stats_py.py @@ -1283,8 +1283,8 @@ def skew(a, axis=0, bias=True, nan_policy='propagate'): Returns ------- skewness : ndarray - The skewness of values along an axis, returning 0 where all values are - equal. + The skewness of values along an axis, returning NaN where all values + are equal. Notes ----- @@ -1392,8 +1392,8 @@ def kurtosis(a, axis=0, fisher=True, bias=True, nan_policy='propagate'): Returns ------- kurtosis : array - The kurtosis of values along an axis. If all values are equal, - return -3 for Fisher's definition and 0 for Pearson's definition. + The kurtosis of values along an axis, returning NaN where all values + are equal. References ---------- From 5fa16e6efdce95826c3ba02f8a18b5a598b13bb9 Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Sat, 6 Aug 2022 12:42:11 +0200 Subject: [PATCH 05/15] BLD/REL: on Windows use numpy 1.22.3 as the version to build wheels against Closes gh-16787 [ci skip] --- pyproject.toml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 27a244106f87..546b9aedc5bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,13 +37,18 @@ requires = [ # loongarch64 requires numpy>=1.22.0 "numpy==1.22.0; platform_machine=='loongarch64'", + # On Windows we need to avoid 1.21.6, 1.22.0 and 1.22.1 because they were + # built with vc142. 1.22.3 is the first version that has 32-bit Windows + # wheels *and* was built with vc141. So use that: + "numpy==1.22.3; python_version=='3.10' and platform_machine=='win32' and platform_python_implementation != 'PyPy'", + # default numpy requirements "numpy==1.18.5; python_version=='3.8' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_machine!='aarch64' and platform_machine!='loongarch64' and platform_python_implementation != 'PyPy'", "numpy==1.19.3; python_version=='3.9' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_machine!='loongarch64' and platform_python_implementation != 'PyPy'", # Note that 1.21.3 was the first version with a complete set of 3.10 wheels, - # however macOS was broken and it's safe to build against 1.21.6 on all platforms + # however macOS was broken and it's safe C API/ABI-wise to build against 1.21.6 # (see oldest-supported-numpy issues gh-28 and gh-45) - "numpy==1.21.6; python_version=='3.10' and platform_machine!='loongarch64' and platform_python_implementation != 'PyPy'", + "numpy==1.21.6; python_version=='3.10' and (platform_machine!='win32' and platform_machine!='loongarch64') and platform_python_implementation != 'PyPy'", # For Python versions which aren't yet officially supported, # we specify an unpinned NumPy which allows source distributions From b4122a3174617799dfd1d19d5be6cc1bc18155b1 Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Tue, 16 Aug 2022 06:52:49 +0300 Subject: [PATCH 06/15] BLD: add Python 3.11 numpy version to pyproject.toml This mirrors the change in https://github.com/scipy/oldest-supported-numpy/pull/61 NumPy 1.23.3 is the first numpy version with 3.11 wheels on PyPI. --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 546b9aedc5bb..eadf88c8bbbe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,12 +49,13 @@ requires = [ # however macOS was broken and it's safe C API/ABI-wise to build against 1.21.6 # (see oldest-supported-numpy issues gh-28 and gh-45) "numpy==1.21.6; python_version=='3.10' and (platform_machine!='win32' and platform_machine!='loongarch64') and platform_python_implementation != 'PyPy'", + "numpy==1.23.2; python_version=='3.11' and platform_python_implementation != 'PyPy'", # For Python versions which aren't yet officially supported, # we specify an unpinned NumPy which allows source distributions # to be used and allows wheels to be used as soon as they # become available. - "numpy; python_version>='3.11'", + "numpy; python_version>='3.12'", "numpy; python_version>='3.8' and platform_python_implementation=='PyPy'", ] From 630c04a243e14c3748e21dcaed6961b983f5d75d Mon Sep 17 00:00:00 2001 From: warren Date: Wed, 10 Aug 2022 20:34:40 -0400 Subject: [PATCH 07/15] BUG/TST: linalg: Check the results of 'schur' more carefully. The Schur decomposition is not unique, so testing the result of linalg.schur against hard-coded matrices is not reliable. The updated tests check that the desired properties of the result are satisfied, and that the order of the diagonal elements of the triangular matrix agrees with the given 'sort' parameter. Closes gh-14517 --- scipy/linalg/tests/test_decomp.py | 95 +++++++++---------------------- 1 file changed, 27 insertions(+), 68 deletions(-) diff --git a/scipy/linalg/tests/test_decomp.py b/scipy/linalg/tests/test_decomp.py index 93d62e9d7b2e..bfee385e6cd2 100644 --- a/scipy/linalg/tests/test_decomp.py +++ b/scipy/linalg/tests/test_decomp.py @@ -1899,84 +1899,43 @@ def test_check_finite(self): class TestSchur: + def check_schur(self, a, t, u, rtol, atol): + # Check that the Schur decomposition is correct. + assert_allclose(u @ t @ u.conj().T, a, rtol=rtol, atol=atol, + err_msg="Schur decomposition does not match 'a'") + # The expected value of u @ u.H - I is all zeros, so test + # with absolute tolerance only. + assert_allclose(u @ u.conj().T - np.eye(len(u)), 0, rtol=0, atol=atol, + err_msg="u is not unitary") + def test_simple(self): a = [[8, 12, 3], [2, 9, 3], [10, 3, 6]] t, z = schur(a) - assert_array_almost_equal(z @ t @ z.conj().T, a) + self.check_schur(a, t, z, rtol=1e-14, atol=5e-15) tc, zc = schur(a, 'complex') assert_(np.any(ravel(iscomplex(zc))) and np.any(ravel(iscomplex(tc)))) - assert_array_almost_equal(zc @ tc @ zc.conj().T, a) + self.check_schur(a, tc, zc, rtol=1e-14, atol=5e-15) tc2, zc2 = rsf2csf(tc, zc) - assert_array_almost_equal(zc2 @ tc2 @ zc2.conj().T, a) - - def test_sort(self): + self.check_schur(a, tc2, zc2, rtol=1e-14, atol=5e-15) + + @pytest.mark.parametrize( + 'sort, expected_diag', + [('lhp', [-np.sqrt(2), -0.5, np.sqrt(2), 0.5]), + ('rhp', [np.sqrt(2), 0.5, -np.sqrt(2), -0.5]), + ('iuc', [-0.5, 0.5, np.sqrt(2), -np.sqrt(2)]), + ('ouc', [np.sqrt(2), -np.sqrt(2), -0.5, 0.5]), + (lambda x: x >= 0.0, [np.sqrt(2), 0.5, -np.sqrt(2), -0.5])] + ) + def test_sort(self, sort, expected_diag): + # The exact eigenvalues of this matrix are + # -sqrt(2), sqrt(2), -1/2, 1/2. a = [[4., 3., 1., -1.], [-4.5, -3.5, -1., 1.], [9., 6., -4., 4.5], [6., 4., -3., 3.5]] - s, u, sdim = schur(a, sort='lhp') - assert_array_almost_equal([[0.1134, 0.5436, 0.8316, 0.], - [-0.1134, -0.8245, 0.5544, 0.], - [-0.8213, 0.1308, 0.0265, -0.5547], - [-0.5475, 0.0872, 0.0177, 0.8321]], - u, 3) - assert_array_almost_equal([[-1.4142, 0.1456, -11.5816, -7.7174], - [0., -0.5000, 9.4472, -0.7184], - [0., 0., 1.4142, -0.1456], - [0., 0., 0., 0.5]], - s, 3) - assert_equal(2, sdim) - - s, u, sdim = schur(a, sort='rhp') - assert_array_almost_equal([[0.4862, -0.4930, 0.1434, -0.7071], - [-0.4862, 0.4930, -0.1434, -0.7071], - [0.6042, 0.3944, -0.6924, 0.], - [0.4028, 0.5986, 0.6924, 0.]], - u, 3) - assert_array_almost_equal([[1.4142, -0.9270, 4.5368, -14.4130], - [0., 0.5, 6.5809, -3.1870], - [0., 0., -1.4142, 0.9270], - [0., 0., 0., -0.5]], - s, 3) - assert_equal(2, sdim) - - s, u, sdim = schur(a, sort='iuc') - assert_array_almost_equal([[0.5547, 0., -0.5721, -0.6042], - [-0.8321, 0., -0.3814, -0.4028], - [0., 0.7071, -0.5134, 0.4862], - [0., 0.7071, 0.5134, -0.4862]], - u, 3) - assert_array_almost_equal([[-0.5000, 0.0000, -6.5809, -4.0974], - [0., 0.5000, -3.3191, -14.4130], - [0., 0., 1.4142, 2.1573], - [0., 0., 0., -1.4142]], - s, 3) - assert_equal(2, sdim) - - s, u, sdim = schur(a, sort='ouc') - assert_array_almost_equal([[0.4862, -0.5134, 0.7071, 0.], - [-0.4862, 0.5134, 0.7071, 0.], - [0.6042, 0.5721, 0., -0.5547], - [0.4028, 0.3814, 0., 0.8321]], - u, 3) - assert_array_almost_equal([[1.4142, -2.1573, 14.4130, 4.0974], - [0., -1.4142, 3.3191, 6.5809], - [0., 0., -0.5000, 0.], - [0., 0., 0., 0.5000]], - s, 3) - assert_equal(2, sdim) - - s, u, sdim = schur(a, sort=lambda x: x >= 0.0) - assert_array_almost_equal([[0.4862, -0.4930, 0.1434, -0.7071], - [-0.4862, 0.4930, -0.1434, -0.7071], - [0.6042, 0.3944, -0.6924, 0.], - [0.4028, 0.5986, 0.6924, 0.]], - u, 3) - assert_array_almost_equal([[1.4142, -0.9270, 4.5368, -14.4130], - [0., 0.5, 6.5809, -3.1870], - [0., 0., -1.4142, 0.9270], - [0., 0., 0., -0.5]], - s, 3) + t, u, sdim = schur(a, sort=sort) + self.check_schur(a, t, u, rtol=1e-14, atol=5e-15) + assert_allclose(np.diag(t), expected_diag, rtol=1e-12) assert_equal(2, sdim) def test_sort_errors(self): From 42b4660b608b0e5fb19f44f01f1f6e4179c507dd Mon Sep 17 00:00:00 2001 From: Atsushi Sakai Date: Thu, 11 Aug 2022 22:09:40 +0900 Subject: [PATCH 08/15] BUG: interpolate: fix previous and next extrapolate logic error. --- scipy/interpolate/_interpolate.py | 6 +- scipy/interpolate/tests/test_interpolate.py | 82 +++++++++++++++++++++ 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/scipy/interpolate/_interpolate.py b/scipy/interpolate/_interpolate.py index 59a1e1592c38..f5013cc7a1e6 100644 --- a/scipy/interpolate/_interpolate.py +++ b/scipy/interpolate/_interpolate.py @@ -519,7 +519,8 @@ def __init__(self, x, y, kind='linear', axis=-1, self._call = self.__class__._call_previousnext if _do_extrapolate(fill_value): self._check_and_update_bounds_error_for_extrapolation() - fill_value = (np.nan, self.y.max(axis=axis)) + # assume y is sorted by x ascending order here. + fill_value = (np.nan, np.take(self.y, -1, axis)) elif kind == 'next': self._side = 'right' self._ind = 1 @@ -528,7 +529,8 @@ def __init__(self, x, y, kind='linear', axis=-1, self._call = self.__class__._call_previousnext if _do_extrapolate(fill_value): self._check_and_update_bounds_error_for_extrapolation() - fill_value = (self.y.min(axis=axis), np.nan) + # assume y is sorted by x ascending order here. + fill_value = (np.take(self.y, 0, axis), np.nan) else: # Check if we can delegate to numpy.interp (2x-10x faster). np_types = (np.float_, np.int_) diff --git a/scipy/interpolate/tests/test_interpolate.py b/scipy/interpolate/tests/test_interpolate.py index 3031650a747c..22a479f7d2f0 100644 --- a/scipy/interpolate/tests/test_interpolate.py +++ b/scipy/interpolate/tests/test_interpolate.py @@ -122,6 +122,28 @@ def setup_method(self): self.y235 = np.arange(30.).reshape((2, 3, 5)) self.y325 = np.arange(30.).reshape((3, 2, 5)) + # Edge updated test matrix 1 + # array([[ 30, 1, 2, 3, 4, 5, 6, 7, 8, -30], + # [ 30, 11, 12, 13, 14, 15, 16, 17, 18, -30]]) + self.y210_edge_updated = np.arange(20.).reshape((2, 10)) + self.y210_edge_updated[:, 0] = 30 + self.y210_edge_updated[:, -1] = -30 + + # Edge updated test matrix 2 + # array([[ 30, 30], + # [ 2, 3], + # [ 4, 5], + # [ 6, 7], + # [ 8, 9], + # [ 10, 11], + # [ 12, 13], + # [ 14, 15], + # [ 16, 17], + # [-30, -30]]) + self.y102_edge_updated = np.arange(20.).reshape((10, 2)) + self.y102_edge_updated[0, :] = 30 + self.y102_edge_updated[-1, :] = -30 + self.fill_value = -100.0 def test_validation(self): @@ -386,6 +408,36 @@ def test_previous(self): bounds_error=True) assert_raises(ValueError, interp1d, self.x10, self.y10, **opts) + # Tests for gh-16813 + interpolator1D = interp1d([0, 1, 2], + [0, 1, -1], kind="previous", + fill_value='extrapolate', + assume_sorted=True) + assert_allclose(interpolator1D([-2, -1, 0, 1, 2, 3, 5]), + [np.nan, np.nan, 0, 1, -1, -1, -1]) + + interpolator1D = interp1d([2, 0, 1], # x is not ascending + [-1, 0, 1], kind="previous", + fill_value='extrapolate', + assume_sorted=False) + assert_allclose(interpolator1D([-2, -1, 0, 1, 2, 3, 5]), + [np.nan, np.nan, 0, 1, -1, -1, -1]) + + interpolator2D = interp1d(self.x10, self.y210_edge_updated, + kind="previous", + fill_value='extrapolate') + assert_allclose(interpolator2D([-1, -2, 5, 8, 12, 25]), + [[np.nan, np.nan, 5, 8, -30, -30], + [np.nan, np.nan, 15, 18, -30, -30]]) + + interpolator2DAxis0 = interp1d(self.x10, self.y102_edge_updated, + kind="previous", + axis=0, fill_value='extrapolate') + assert_allclose(interpolator2DAxis0([-2, 5, 12]), + [[np.nan, np.nan], + [10, 11], + [-30, -30]]) + def test_next(self): # Check the actual implementation of next interpolation. interp10 = interp1d(self.x10, self.y10, kind='next') @@ -425,6 +477,36 @@ def test_next(self): bounds_error=True) assert_raises(ValueError, interp1d, self.x10, self.y10, **opts) + # Tests for gh-16813 + interpolator1D = interp1d([0, 1, 2], + [0, 1, -1], kind="next", + fill_value='extrapolate', + assume_sorted=True) + assert_allclose(interpolator1D([-2, -1, 0, 1, 2, 3, 5]), + [0, 0, 0, 1, -1, np.nan, np.nan]) + + interpolator1D = interp1d([2, 0, 1], # x is not ascending + [-1, 0, 1], kind="next", + fill_value='extrapolate', + assume_sorted=False) + assert_allclose(interpolator1D([-2, -1, 0, 1, 2, 3, 5]), + [0, 0, 0, 1, -1, np.nan, np.nan]) + + interpolator2D = interp1d(self.x10, self.y210_edge_updated, + kind="next", + fill_value='extrapolate') + assert_allclose(interpolator2D([-1, -2, 5, 8, 12, 25]), + [[30, 30, 5, 8, np.nan, np.nan], + [30, 30, 15, 18, np.nan, np.nan]]) + + interpolator2DAxis0 = interp1d(self.x10, self.y102_edge_updated, + kind="next", + axis=0, fill_value='extrapolate') + assert_allclose(interpolator2DAxis0([-2, 5, 12]), + [[30, 30], + [10, 11], + [np.nan, np.nan]]) + def test_zero(self): # Check the actual implementation of zero-order spline interpolation. interp10 = interp1d(self.x10, self.y10, kind='zero') From e8bb60a907d171bbf0798a7afe2328441623a1a1 Mon Sep 17 00:00:00 2001 From: Anirudh Dagar Date: Fri, 19 Aug 2022 12:05:59 +0200 Subject: [PATCH 09/15] BUG, DOC: Fix sphinx autosummary generation for `odr` and `czt` (#16862) --- doc/source/conf.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/source/conf.py b/doc/source/conf.py index 578a9e3e482e..ad17e99c8d75 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -261,6 +261,16 @@ autosummary_generate = True +# maps functions with a name same as a class name that is indistinguishable +# Ex: scipy.signal.czt and scipy.signal.CZT or scipy.odr.odr and scipy.odr.ODR +# Otherwise, the stubs are overwritten when the name is same for +# OS (like MacOS) which has a filesystem that ignores the case +# See https://github.com/sphinx-doc/sphinx/pull/7927 +autosummary_filename_map = { + "scipy.odr.odr": "odr-function", + "scipy.signal.czt": "czt-function", +} + # ----------------------------------------------------------------------------- # Autodoc From eb318818d5d7ce677a3ed0996f7ea47f5d99acfa Mon Sep 17 00:00:00 2001 From: Matt Haberland Date: Mon, 22 Aug 2022 19:11:53 -0700 Subject: [PATCH 10/15] MAINT: optimize.milp: fix input validation when three constraints are passed --- scipy/optimize/_constraints.py | 15 +++++++++++---- scipy/optimize/_milp.py | 2 +- scipy/optimize/tests/test_milp.py | 25 +++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/scipy/optimize/_constraints.py b/scipy/optimize/_constraints.py index d4db74270912..2bcd270ce1e4 100644 --- a/scipy/optimize/_constraints.py +++ b/scipy/optimize/_constraints.py @@ -4,7 +4,7 @@ from ._differentiable_functions import ( VectorFunction, LinearVectorFunction, IdentityVectorFunction) from ._optimize import OptimizeWarning -from warnings import warn +from warnings import warn, catch_warnings, simplefilter from numpy.testing import suppress_warnings from scipy.sparse import issparse @@ -165,11 +165,18 @@ def _input_validation(self): def __init__(self, A, lb=-np.inf, ub=np.inf, keep_feasible=False): if not issparse(A): - self.A = np.atleast_2d(A) + # In some cases, if the constraint is not valid, this emits a + # VisibleDeprecationWarning about ragged nested sequences + # before eventually causing an error. `scipy.optimize.milp` would + # prefer that this just error out immediately so it can handle it + # rather than concerning the user. + with catch_warnings(): + simplefilter("error") + self.A = np.atleast_2d(A).astype(np.float64) else: self.A = A - self.lb = np.atleast_1d(lb) - self.ub = np.atleast_1d(ub) + self.lb = np.atleast_1d(lb).astype(np.float64) + self.ub = np.atleast_1d(ub).astype(np.float64) self.keep_feasible = np.atleast_1d(keep_feasible).astype(bool) self._input_validation() diff --git a/scipy/optimize/_milp.py b/scipy/optimize/_milp.py index 041cf7c3e849..99836bd9697f 100644 --- a/scipy/optimize/_milp.py +++ b/scipy/optimize/_milp.py @@ -43,7 +43,7 @@ def _constraints_to_components(constraints): # argument could be a single tuple representing a LinearConstraint try: constraints = [LinearConstraint(*constraints)] - except TypeError: + except (TypeError, ValueError, np.VisibleDeprecationWarning): # argument was not a tuple representing a LinearConstraint pass diff --git a/scipy/optimize/tests/test_milp.py b/scipy/optimize/tests/test_milp.py index e66354f0181d..f179029e0b60 100644 --- a/scipy/optimize/tests/test_milp.py +++ b/scipy/optimize/tests/test_milp.py @@ -270,3 +270,28 @@ def test_infeasible_prob_16609(): res = milp(c, integrality=integrality, bounds=bounds, constraints=constraints) np.testing.assert_equal(res.status, 2) + + +def test_three_constraints_16878(): + # `milp` failed when exactly three constraints were passed + # Ensure that this is no longer the case. + rng = np.random.default_rng(5123833489170494244) + A = rng.integers(0, 5, size=(6, 6)) + bl = np.full(6, fill_value=-np.inf) + bu = np.full(6, fill_value=10) + constraints = [LinearConstraint(A[:2], bl[:2], bu[:2]), + LinearConstraint(A[2:4], bl[2:4], bu[2:4]), + LinearConstraint(A[4:], bl[4:], bu[4:])] + constraints2 = [(A[:2], bl[:2], bu[:2]), + (A[2:4], bl[2:4], bu[2:4]), + (A[4:], bl[4:], bu[4:])] + lb = np.zeros(6) + ub = np.ones(6) + variable_bounds = Bounds(lb, ub) + c = -np.ones(6) + res1 = milp(c, bounds=variable_bounds, constraints=constraints) + res2 = milp(c, bounds=variable_bounds, constraints=constraints2) + ref = milp(c, bounds=variable_bounds, constraints=(A, bl, bu)) + assert res1.success and res2.success + assert_allclose(res1.x, ref.x) + assert_allclose(res2.x, ref.x) From 3e9c15d8945edceaa0ac6b6e99dec10c158f5d8c Mon Sep 17 00:00:00 2001 From: Tyler Reddy Date: Thu, 25 Aug 2022 15:44:11 -0600 Subject: [PATCH 11/15] DOC: update 1.9.1 relnotes --- doc/release/1.9.1-notes.rst | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/doc/release/1.9.1-notes.rst b/doc/release/1.9.1-notes.rst index 5fc910facbdd..f061897e1af8 100644 --- a/doc/release/1.9.1-notes.rst +++ b/doc/release/1.9.1-notes.rst @@ -5,15 +5,44 @@ SciPy 1.9.1 Release Notes .. contents:: SciPy 1.9.1 is a bug-fix release with no new features -compared to 1.9.0. +compared to 1.9.0. Notably, some important meson build +fixes are included. Authors ======= +* Anirudh Dagar (1) +* Ralf Gommers (4) +* Matt Haberland (2) +* Tyler Reddy (10) +* Atsushi Sakai (1) +* Eli Schwartz (1) +* Warren Weckesser (1) + +A total of 7 people contributed to this release. +People with a "+" by their names contributed a patch for the first time. +This list of names is automatically generated, and may not be fully complete. Issues closed for 1.9.1 ----------------------- +* `#14517 `__: scipy/linalg/tests/test_decomp.py::TestSchur::test_sort test... +* `#16765 `__: DOC: \`scipy.stats.skew\` no longer returns 0 on constant input +* `#16787 `__: BUG: Can't build 1.10 with mingw-w64 toolchain and numpy 1.21.6... +* `#16813 `__: BUG: scipy.interpolate interp1d extrapolate behaviour change... +* `#16878 `__: BUG: optimize.milp fails to execute when given exactly 3 constraints + Pull requests for 1.9.1 ----------------------- + +* `#16736 `__: REL: prep for SciPy 1.9.1 +* `#16749 `__: BLD: install missing \`.pxd\` files, and update TODOs/FIXMEs... +* `#16750 `__: BLD: make OpenBLAS detection work with CMake +* `#16760 `__: BLD: use a bit more idiomatic approach to constructing paths... +* `#16768 `__: DOC: stats.skew/kurtosis: returns NaN when input has only one... +* `#16794 `__: BLD/REL: on Windows use numpy 1.22.3 as the version to build... +* `#16822 `__: BUG/TST: linalg: Check the results of 'schur' more carefully. +* `#16825 `__: BUG: interpolate: fix "previous" and "next" extrapolate logic... +* `#16862 `__: BUG, DOC: Fix sphinx autosummary generation for \`odr\` and \`czt\` +* `#16881 `__: MAINT: optimize.milp: fix input validation when three constraints... From ec9b0adf68c575f1941f7e2689db9669eccb185f Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Fri, 26 Aug 2022 10:50:03 +0300 Subject: [PATCH 12/15] MAINT: fixes for small issues in backports to v1.9.1 --- doc/API.rst.txt | 2 +- environment.yml | 2 +- scipy/stats/_continuous_distns.py | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/doc/API.rst.txt b/doc/API.rst.txt index 915c6bf03246..538554dd8906 100644 --- a/doc/API.rst.txt +++ b/doc/API.rst.txt @@ -125,7 +125,7 @@ change is made. * `scipy.optimize` - - `scipy.optimize.cython_optimize + - `scipy.optimize.cython_optimize` * `scipy.signal` diff --git a/environment.yml b/environment.yml index e33f3c9b8fa1..cf99b7a0d74d 100644 --- a/environment.yml +++ b/environment.yml @@ -45,4 +45,4 @@ dependencies: - rich-click - click - doit>=0.36.0 - - pydevtool==0.2.0 + - pydevtool diff --git a/scipy/stats/_continuous_distns.py b/scipy/stats/_continuous_distns.py index 1ec0d570d933..d30c12c5adb6 100644 --- a/scipy/stats/_continuous_distns.py +++ b/scipy/stats/_continuous_distns.py @@ -9151,8 +9151,6 @@ class rv_histogram(rv_continuous): The second containing the (n+1) bin boundaries In particular the return value np.histogram is accepted - .. versionadded:: 1.10.0 - Notes ----- There are no additional shape parameters except for the loc and scale. From c055c31f4b5ad837ed1a4df96454bd13f2794446 Mon Sep 17 00:00:00 2001 From: Andrew Nelson Date: Fri, 26 Aug 2022 10:54:15 +0300 Subject: [PATCH 13/15] BLD: cp310 needs numpy==1.22.3 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index eadf88c8bbbe..f0ede132507d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,7 +40,7 @@ requires = [ # On Windows we need to avoid 1.21.6, 1.22.0 and 1.22.1 because they were # built with vc142. 1.22.3 is the first version that has 32-bit Windows # wheels *and* was built with vc141. So use that: - "numpy==1.22.3; python_version=='3.10' and platform_machine=='win32' and platform_python_implementation != 'PyPy'", + "numpy==1.22.3; python_version=='3.10' and platform_system=='Windows' and platform_python_implementation != 'PyPy'", # default numpy requirements "numpy==1.18.5; python_version=='3.8' and (platform_machine!='arm64' or platform_system!='Darwin') and platform_machine!='aarch64' and platform_machine!='loongarch64' and platform_python_implementation != 'PyPy'", From cc0a2bf1be31deba86bc51425d391cc2461f8fb2 Mon Sep 17 00:00:00 2001 From: Warren Weckesser Date: Tue, 2 Aug 2022 05:03:55 -0400 Subject: [PATCH 14/15] TST: sparse.linalg: Loosen tolerance for the lobpcg test 'test_tolerance_float32' (#16755) This test has been failing occasionally in CI, with errors slightly greater than the requested tolerances. (cherry picked from commit f71e7fad717801c4476312fe1e23f2dfbb4c9d7f) --- scipy/sparse/linalg/_eigen/lobpcg/tests/test_lobpcg.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scipy/sparse/linalg/_eigen/lobpcg/tests/test_lobpcg.py b/scipy/sparse/linalg/_eigen/lobpcg/tests/test_lobpcg.py index d1b1817898d2..5c24bb826576 100644 --- a/scipy/sparse/linalg/_eigen/lobpcg/tests/test_lobpcg.py +++ b/scipy/sparse/linalg/_eigen/lobpcg/tests/test_lobpcg.py @@ -351,8 +351,8 @@ def test_tolerance_float32(): A = A.astype(np.float32) X = rnd.standard_normal((n, m)) X = X.astype(np.float32) - eigvals, _ = lobpcg(A, X, tol=1e-5, maxiter=50, verbosityLevel=0) - assert_allclose(eigvals, -np.arange(1, 1 + m), atol=1.5e-5) + eigvals, _ = lobpcg(A, X, tol=1.25e-5, maxiter=50, verbosityLevel=0) + assert_allclose(eigvals, -np.arange(1, 1 + m), atol=2e-5, rtol=1e-5) def test_random_initial_float32(): From 8b97528128f01e8ec633820ca39ba800f8ea6221 Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Wed, 27 Jul 2022 15:35:19 +0200 Subject: [PATCH 15/15] BLD: make the way we count commits for version numbering more robust I think this will fix the issue with commit count being zero reported in gh-16702. (cherry picked from commit 97ee16d7d37fc094f2468b4cc4c7c855cf8df86a) --- tools/version_utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/version_utils.py b/tools/version_utils.py index 9bb5e14aa222..ba088dd0cb64 100644 --- a/tools/version_utils.py +++ b/tools/version_utils.py @@ -98,7 +98,8 @@ def _minimal_ext_cmd(cmd): # point from the current branch (assuming a full `git clone`, it may be # less if `--depth` was used - commonly the default in CI): prev_version_tag = '^v{}.{}.0'.format(MAJOR, MINOR - 2) - out = _minimal_ext_cmd(['git', 'rev-list', 'HEAD', prev_version_tag, + out = _minimal_ext_cmd(['git', '--git-dir', git_dir, + 'rev-list', 'HEAD', prev_version_tag, '--count']) COMMIT_COUNT = out.strip().decode('ascii') COMMIT_COUNT = '0' if not COMMIT_COUNT else COMMIT_COUNT