Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-scikit-sparse for
openSUSE:Factory checked in at 2023-09-10 13:09:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-scikit-sparse (Old)
and /work/SRC/openSUSE:Factory/.python-scikit-sparse.new.1766 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-scikit-sparse"
Sun Sep 10 13:09:58 2023 rev:6 rq:1109763 version:0.4.12
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-scikit-sparse/python-scikit-sparse.changes
2021-04-24 23:10:54.755544089 +0200
+++
/work/SRC/openSUSE:Factory/.python-scikit-sparse.new.1766/python-scikit-sparse.changes
2023-09-10 13:10:33.715265391 +0200
@@ -1,0 +2,17 @@
+Fri Sep 8 16:56:21 UTC 2023 - Matej Cepl <[email protected]>
+
+- Clean up the SPEC file.
+- Convert from python_{build,install} to
+ pyproject_{wheel,install} macros.
+
+-------------------------------------------------------------------
+Thu Aug 31 12:37:47 UTC 2023 - Markéta Machová <[email protected]>
+
+- Update to 0.4.12
+ * Allow suitesparse include/library paths to be passed in to
+ pip install through environment variables.
+ * Added support for python 3.11
+ * Fix compilation with Cython>=3.0.0
+- Add upstream scipy111.patch
+
+-------------------------------------------------------------------
Old:
----
scikit-sparse-0.4.5.tar.gz
New:
----
scikit-sparse-0.4.12.tar.gz
scipy111.patch
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-scikit-sparse.spec ++++++
--- /var/tmp/diff_new_pack.gNB3UY/_old 2023-09-10 13:10:34.735301833 +0200
+++ /var/tmp/diff_new_pack.gNB3UY/_new 2023-09-10 13:10:34.739301976 +0200
@@ -1,7 +1,7 @@
#
# spec file for package python-scikit-sparse
#
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -16,34 +16,34 @@
#
-%{?!python_module:%define python_module() python-%{**} python3-%{**}}
-%define skip_python2 1
-%define skip_python36 1
-Name: python-scikit-sparse
-Version: 0.4.5
-Release: 0
# For license file
%define tag c94f8418b6c36c3ff9db4f87e00fc08bd51cfb4b
+Name: python-scikit-sparse
+Version: 0.4.12
+Release: 0
Summary: Scikits sparse matrix package
License: GPL-2.0-or-later AND LGPL-2.1-or-later
Group: Development/Languages/Python
URL: https://github.com/scikit-sparse/scikit-sparse/
Source:
https://files.pythonhosted.org/packages/source/s/scikit-sparse/scikit-sparse-%{version}.tar.gz
+#PATCH-FIX-UPSTREAM https://github.com/scikit-sparse/scikit-sparse/pull/102
Fix breaking changes in isspmatrix of scipy >=1.11.0
+Patch0: scipy111.patch
BuildRequires: %{python_module Cython}
BuildRequires: %{python_module devel}
BuildRequires: %{python_module numpy-devel >= 1.13.3}
+BuildRequires: %{python_module pip}
BuildRequires: %{python_module scipy >= 0.19}
BuildRequires: %{python_module setuptools >= 18.0}
+BuildRequires: %{python_module wheel}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
BuildRequires: suitesparse-devel
-# SECTION test requirements
-BuildRequires: %{python_module pytest}
-# /SECTION
Requires: python-numpy >= 1.12
Requires: python-scipy >= 0.18
ExcludeArch: %{ix86}
-
+# SECTION test requirements
+BuildRequires: %{python_module pytest}
+# /SECTION
%python_subpackages
%description
@@ -57,16 +57,14 @@
decomposition.
%prep
-%setup -q -n scikit-sparse-%{version}
-# no need for nose here -- gh#scikit-sparse/pull#66
-sed -i 's/from nose.tools import assert_raises/from pytest import raises as
assert_raises/' sksparse/test_cholmod.py
+%autosetup -p1 -n scikit-sparse-%{version}
%build
export CFLAGS="%{optflags}"
-%python_build
+%pyproject_wheel
%install
-%python_install
+%pyproject_install
%python_expand %fdupes %{buildroot}%{$python_sitearch}
%check
++++++ scikit-sparse-0.4.5.tar.gz -> scikit-sparse-0.4.12.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/scikit-sparse-0.4.5/PKG-INFO
new/scikit-sparse-0.4.12/PKG-INFO
--- old/scikit-sparse-0.4.5/PKG-INFO 2021-04-03 13:32:43.000000000 +0200
+++ new/scikit-sparse-0.4.12/PKG-INFO 2023-07-21 06:59:19.567062900 +0200
@@ -1,21 +1,11 @@
-Metadata-Version: 1.2
+Metadata-Version: 2.1
Name: scikit-sparse
-Version: 0.4.5
+Version: 0.4.12
Summary: Scikit sparse matrix package
Home-page: https://github.com/scikit-sparse/scikit-sparse
Maintainer: Justin Ellis
Maintainer-email: [email protected]
License: BSD
-Description: Sparse matrix tools.
-
- This is a home for sparse matrix code in Python that plays well with
- scipy.sparse, but that is somehow unsuitable for inclusion in scipy
- proper. Usually this will be because it is released under the GPL.
-
- So far we have a wrapper for the CHOLMOD library for sparse Cholesky
- decomposition. Further contributions are welcome!
-
-Platform: UNKNOWN
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
@@ -29,4 +19,16 @@
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
-Requires-Python: >=3.6, <3.10
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Requires-Python: >=3.6, <3.12
+License-File: LICENSE.txt
+
+Sparse matrix tools.
+
+This is a home for sparse matrix code in Python that plays well with
+scipy.sparse, but that is somehow unsuitable for inclusion in scipy
+proper. Usually this will be because it is released under the GPL.
+
+So far we have a wrapper for the CHOLMOD library for sparse Cholesky
+decomposition. Further contributions are welcome!
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/scikit-sparse-0.4.5/README.md
new/scikit-sparse-0.4.12/README.md
--- old/scikit-sparse-0.4.5/README.md 2021-04-03 13:32:27.000000000 +0200
+++ new/scikit-sparse-0.4.12/README.md 2023-07-21 06:58:55.000000000 +0200
@@ -1,7 +1,8 @@
[](https://github.com/scikit-sparse/scikit-sparse/releases/latest)
[](https://pypi.org/project/scikit-sparse/)
-[](https://github.com/scikit-sparse/scikit-sparse/actions/workflows/ci_test.yml)
-[]()
+[](https://anaconda.org/conda-forge/scikit-sparse)
+[](https://github.com/scikit-sparse/scikit-sparse/actions/workflows/ci_test.yml)
+[]()
[](https://github.com/scikit-sparse/scikit-sparse/blob/master/LICENSE.txt)
# scikit-sparse
@@ -15,6 +16,8 @@
## Installation
+### With `pip`
+
For pip installs of `scikit-sparse` depend on the suite-sparse library which
can be installed via:
```bash
# mac
@@ -29,6 +32,48 @@
pip install scikit-sparse
```
+If you suite-sparse library is installed in a non-standard place and you get
errors when installing with `pip` you can use the environment
+variables:
+* `SUITESPARSE_INCLUDE_DIR`
+* `SUITESPARSE_LIBRARY_DIR`
+
+at runtime so the compiler can find them. For example, lets say your
suite-sparse installation is in `/opt/local` then you can run
+```bash
+SUITESPARSE_INCLUDE_DIR=/opt/local/include
SUITESPARSE_LIBRARY_DIR=/opt/local/lib pip install scikit-sparse
+```
+
+### With `conda`
+The `conda` package comes with `suite-sparse` packaged as a dependency so all
you need to do is:
+
+```bash
+conda install -c conda-forge scikit-sparse
+```
+
+### Windows installation
+This was tested with a Anaconda 3 installation and Python 3.8
+
+0. Install requirements
+ - `conda install -c conda-forge cython` - tested with v0.29.32
+ - `conda install -c conda-forge suitesparse` - tested with v5.4.0
+ - optional (included in the build dependencies of `scikit-sparse`):
+ - `conda install -c conda-forge numpy` - tested with v1.23.2
+ - `conda install -c conda-forge scipy` - tested with v1.9.1
+
+1. Download Microsoft Build Tools for C++ from
https://visualstudio.microsoft.com/de/visual-cpp-build-tools/ (tested with
2022, should work with 2015 or newer)
+
+2. Install Visual Studio Build Tools
+ 1. Choose Workloads
+ 2. Check "Desktop development with C++"
+ 3. Keep standard settings
+
+3. Run in a Powershell
+ - `$env:SUITESPARSE_INCLUDE_DIR='C:/Anaconda3/envs/<YOUR ENVIRONMENT
NAME HERE>/Library/include/suitesparse'`
+ - `$env:SUITESPARSE_LIBRARY_DIR='C:/Anaconda3/envs/<YOUR ENVIRONMENT
NAME HERE>/Library/lib'`
+ - `pip install scikit-sparse`
+
+4. Test `from sksparse.cholmod import cholesky`
+
+
## License
The wrapper code contained in this package is released under a
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/scikit-sparse-0.4.5/pyproject.toml
new/scikit-sparse-0.4.12/pyproject.toml
--- old/scikit-sparse-0.4.5/pyproject.toml 2021-04-03 13:32:27.000000000
+0200
+++ new/scikit-sparse-0.4.12/pyproject.toml 2023-07-21 06:58:55.000000000
+0200
@@ -1,6 +1,6 @@
[tool.black]
line-length = 120
-target_version = ['py36']
+target_version = ['py38']
include = '\.pyi?$'
exclude = '''
@@ -23,11 +23,13 @@
[build-system]
requires = [
"setuptools>=40.8.0",
- "wheel",
+ "wheel",
"Cython>=0.22",
'numpy==1.13.3; python_version=="3.6"',
'numpy==1.14.5; python_version=="3.7"',
'numpy==1.17.3; python_version=="3.8"',
'numpy==1.19.3; python_version=="3.9"',
+ 'numpy==1.23.1; python_version=="3.10"',
+ 'numpy==1.23.5; python_version=="3.11"',
]
build-backend = "setuptools.build_meta"
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/scikit-sparse-0.4.5/scikit_sparse.egg-info/PKG-INFO
new/scikit-sparse-0.4.12/scikit_sparse.egg-info/PKG-INFO
--- old/scikit-sparse-0.4.5/scikit_sparse.egg-info/PKG-INFO 2021-04-03
13:32:43.000000000 +0200
+++ new/scikit-sparse-0.4.12/scikit_sparse.egg-info/PKG-INFO 2023-07-21
06:59:19.000000000 +0200
@@ -1,21 +1,11 @@
-Metadata-Version: 1.2
+Metadata-Version: 2.1
Name: scikit-sparse
-Version: 0.4.5
+Version: 0.4.12
Summary: Scikit sparse matrix package
Home-page: https://github.com/scikit-sparse/scikit-sparse
Maintainer: Justin Ellis
Maintainer-email: [email protected]
License: BSD
-Description: Sparse matrix tools.
-
- This is a home for sparse matrix code in Python that plays well with
- scipy.sparse, but that is somehow unsuitable for inclusion in scipy
- proper. Usually this will be because it is released under the GPL.
-
- So far we have a wrapper for the CHOLMOD library for sparse Cholesky
- decomposition. Further contributions are welcome!
-
-Platform: UNKNOWN
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
@@ -29,4 +19,16 @@
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
-Requires-Python: >=3.6, <3.10
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Requires-Python: >=3.6, <3.12
+License-File: LICENSE.txt
+
+Sparse matrix tools.
+
+This is a home for sparse matrix code in Python that plays well with
+scipy.sparse, but that is somehow unsuitable for inclusion in scipy
+proper. Usually this will be because it is released under the GPL.
+
+So far we have a wrapper for the CHOLMOD library for sparse Cholesky
+decomposition. Further contributions are welcome!
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/scikit-sparse-0.4.5/scikit_sparse.egg-info/SOURCES.txt
new/scikit-sparse-0.4.12/scikit_sparse.egg-info/SOURCES.txt
--- old/scikit-sparse-0.4.5/scikit_sparse.egg-info/SOURCES.txt 2021-04-03
13:32:43.000000000 +0200
+++ new/scikit-sparse-0.4.12/scikit_sparse.egg-info/SOURCES.txt 2023-07-21
06:59:19.000000000 +0200
@@ -19,4 +19,5 @@
sksparse/test_data/well1033.mtx.gz
sksparse/test_data/well1033_rhs1.mtx.gz
sksparse/test_data/well1850.mtx.gz
-sksparse/test_data/well1850_rhs1.mtx.gz
\ No newline at end of file
+sksparse/test_data/well1850_rhs1.mtx.gz
+tests/test_cholmod.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/scikit-sparse-0.4.5/setup.py
new/scikit-sparse-0.4.12/setup.py
--- old/scikit-sparse-0.4.5/setup.py 2021-04-03 13:32:27.000000000 +0200
+++ new/scikit-sparse-0.4.12/setup.py 2023-07-21 06:58:55.000000000 +0200
@@ -10,7 +10,7 @@
# 2016-2017 Joscha Reimer <[email protected]>
# 2021- Justin Ellis <[email protected]>
-"""Sparse matrix tools.
+"""Sparse matrix tools.
This is a home for sparse matrix code in Python that plays well with
scipy.sparse, but that is somehow unsuitable for inclusion in scipy
@@ -20,6 +20,13 @@
decomposition. Further contributions are welcome!
"""
+import os
+import sys
+
+import numpy as np
+from Cython.Build import cythonize
+from setuptools import Extension, find_packages, setup
+
DISTNAME = "scikit-sparse"
DESCRIPTION = "Scikit sparse matrix package"
LONG_DESCRIPTION = __doc__
@@ -28,21 +35,33 @@
URL = "https://github.com/scikit-sparse/scikit-sparse"
LICENSE = "BSD"
-import sys
-import numpy as np
-from Cython.Build import cythonize
-from setuptools import Extension, find_packages, setup
+INCLUDE_DIRS = [
+ np.get_include(),
+ sys.prefix + "/include",
+ # Debian's suitesparse-dev installs to
+ # /usr/include/suitesparse
+ "/usr/include/suitesparse",
+]
+LIBRARY_DIRS = []
+
+user_include_dir = os.getenv("SUITESPARSE_INCLUDE_DIR")
+user_library_dir = os.getenv("SUITESPARSE_LIBRARY_DIR")
+if user_include_dir:
+ INCLUDE_DIRS.append(user_include_dir)
+
+if user_library_dir:
+ LIBRARY_DIRS.append(user_library_dir)
setup(
install_requires=["numpy>=1.13.3", "scipy>=0.19"],
- python_requires=">=3.6, <3.10",
+ python_requires=">=3.6, <3.12",
packages=find_packages(),
package_data={
"": ["test_data/*.mtx.gz"],
},
name=DISTNAME,
- version="0.4.5", # remember to update __init__.py
+ version="0.4.12", # remember to update __init__.py
maintainer=MAINTAINER,
maintainer_email=MAINTAINER_EMAIL,
description=DESCRIPTION,
@@ -63,6 +82,8 @@
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
+ "Programming Language :: Python :: 3.10",
+ "Programming Language :: Python :: 3.11",
],
# You may specify the directory where CHOLMOD is installed using the
# library_dirs and include_dirs keywords in the lines below.
@@ -70,14 +91,8 @@
Extension(
"sksparse.cholmod",
["sksparse/cholmod.pyx"],
- include_dirs=[
- np.get_include(),
- sys.prefix + "/include",
- # Debian's suitesparse-dev installs to
- # /usr/include/suitesparse
- "/usr/include/suitesparse",
- ],
- library_dirs=[],
+ include_dirs=INCLUDE_DIRS,
+ library_dirs=LIBRARY_DIRS,
libraries=["cholmod"],
)
),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/scikit-sparse-0.4.5/sksparse/__init__.py
new/scikit-sparse-0.4.12/sksparse/__init__.py
--- old/scikit-sparse-0.4.5/sksparse/__init__.py 2021-04-03
13:32:27.000000000 +0200
+++ new/scikit-sparse-0.4.12/sksparse/__init__.py 2023-07-21
06:58:55.000000000 +0200
@@ -1 +1 @@
-__version__ = "0.4.5"
+__version__ = "0.4.12"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/scikit-sparse-0.4.5/sksparse/cholmod.pyx
new/scikit-sparse-0.4.12/sksparse/cholmod.pyx
--- old/scikit-sparse-0.4.5/sksparse/cholmod.pyx 2021-04-03
13:32:27.000000000 +0200
+++ new/scikit-sparse-0.4.12/sksparse/cholmod.pyx 2023-07-21
06:58:55.000000000 +0200
@@ -39,6 +39,7 @@
#cython: binding = True
#cython: language_level = 3
+#cython: legacy_implicit_noexcept = True
cimport numpy as np
@@ -624,7 +625,7 @@
def cholesky(self, A, beta=0):
"""The same as :meth:`cholesky_inplace` except that it first creates
- a copy of the current :class:`Factor` and modifes the copy.
+ a copy of the current :class:`Factor` and modifies the copy.
:returns: The new :class:`Factor` object."""
clone = self.copy()
@@ -633,7 +634,7 @@
def cholesky_AAt(self, A, beta=0):
"""The same as :meth:`cholesky_AAt_inplace` except that it first
- creates a copy of the current :class:`Factor` and modifes the copy.
+ creates a copy of the current :class:`Factor` and modifies the copy.
:returns: The new :class:`Factor` object."""
clone = self.copy()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/scikit-sparse-0.4.5/sksparse/test_cholmod.py
new/scikit-sparse-0.4.12/sksparse/test_cholmod.py
--- old/scikit-sparse-0.4.5/sksparse/test_cholmod.py 2021-04-03
13:32:27.000000000 +0200
+++ new/scikit-sparse-0.4.12/sksparse/test_cholmod.py 2023-07-21
06:58:55.000000000 +0200
@@ -40,7 +40,7 @@
from functools import partial
import os.path
-from nose.tools import assert_raises
+from pytest import raises as assert_raises
import numpy as np
from numpy.testing import assert_allclose, assert_array_equal
from scipy import sparse
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/scikit-sparse-0.4.5/tests/test_cholmod.py
new/scikit-sparse-0.4.12/tests/test_cholmod.py
--- old/scikit-sparse-0.4.5/tests/test_cholmod.py 1970-01-01
01:00:00.000000000 +0100
+++ new/scikit-sparse-0.4.12/tests/test_cholmod.py 2023-07-21
06:58:55.000000000 +0200
@@ -0,0 +1,286 @@
+# Test code for the scikits.sparse CHOLMOD wrapper.
+
+# Copyright (C) 2008-2017 The scikit-sparse developers:
+#
+# 2008 David Cournapeau <[email protected]>
+# 2009-2015 Nathaniel Smith <[email protected]>
+# 2010 Dag Sverre Seljebotn <[email protected]>
+# 2014 Leon Barrett <[email protected]>
+# 2015 Yuri <[email protected]>
+# 2016-2017 Antony Lee <[email protected]>
+# 2016 Alex Grigorievskiy <[email protected]>
+# 2016-2017 Joscha Reimer <[email protected]>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+from functools import partial
+import os.path
+
+from pytest import raises as assert_raises
+import numpy as np
+from numpy.testing import assert_allclose, assert_array_equal
+from scipy import sparse
+from sksparse.cholmod import (
+ cholesky,
+ cholesky_AAt,
+ analyze,
+ analyze_AAt,
+ CholmodError,
+ CholmodNotPositiveDefiniteError,
+ _modes,
+ _ordering_methods,
+)
+
+modes = tuple(_modes.keys())
+ordering_methods = tuple(_ordering_methods.keys())
+
+# Match defaults of np.allclose, which were used before (and are needed).
+assert_allclose = partial(assert_allclose, rtol=1e-5, atol=1e-8)
+
+
+def test_cholesky_smoke_test():
+ f = cholesky(sparse.eye(10, 10))
+ d = np.arange(20).reshape(10, 2)
+ print("dense")
+ assert_allclose(f(d), d)
+ print("sparse")
+ s_csc = sparse.csc_matrix(np.eye(10)[:, :2])
+ assert sparse.issparse(f(s_csc))
+ assert_allclose(f(s_csc).todense(), s_csc.todense())
+ print("csr")
+ s_csr = s_csc.tocsr()
+ assert sparse.issparse(f(s_csr))
+ assert_allclose(f(s_csr).todense(), s_csr.todense())
+ print("extract")
+ assert np.all(f.P() == np.arange(10))
+
+
+def test_writeability():
+ t = cholesky(sparse.eye(10, 10))(np.arange(10))
+ assert t.flags["WRITEABLE"]
+
+
+def real_matrix():
+ return sparse.csc_matrix([[10, 0, 3, 0], [0, 5, 0, -2], [3, 0, 5, 0], [0,
-2, 0, 2]])
+
+
+def complex_matrix():
+ return sparse.csc_matrix([[10, 0, 3 - 1j, 0], [0, 5, 0, -2], [3 + 1j, 0,
5, 0], [0, -2, 0, 2]])
+
+
+def factor_of(factor, matrix):
+ return np.allclose(
+ (factor.L() * factor.L().H).todense(), matrix.todense()[factor.P()[:,
np.newaxis], factor.P()[np.newaxis, :]]
+ )
+
+
+def convert_matrix_indices_to_long_indices(matrix):
+ matrix.indices = np.asarray(matrix.indices, dtype=np.int64)
+ matrix.indptr = np.asarray(matrix.indptr, dtype=np.int64)
+ return matrix
+
+
+def test_complex():
+ c = complex_matrix()
+ fc = cholesky(c)
+ r = real_matrix()
+ fr = cholesky(r)
+
+ assert factor_of(fc, c)
+
+ assert_allclose(fc(np.arange(4))[:, None], c.todense().I * np.arange(4)[:,
None])
+ assert_allclose(fc(np.arange(4) * 1j)[:, None], c.todense().I *
(np.arange(4) * 1j)[:, None])
+ assert_allclose(fr(np.arange(4))[:, None], r.todense().I * np.arange(4)[:,
None])
+ # If we did a real factorization, we can't do solves on complex arrays:
+ assert_raises(CholmodError, fr, np.arange(4) * 1j)
+
+
+def test_beta():
+ for matrix in [real_matrix(), complex_matrix()]:
+ for beta in [0, 1, 3.4]:
+ matrix_plus_beta = matrix + beta * sparse.eye(*matrix.shape)
+ for use_long in [False, True]:
+ if use_long:
+ matrix_plus_beta =
convert_matrix_indices_to_long_indices(matrix_plus_beta)
+ for ordering_method in ordering_methods:
+ for mode in modes:
+ f = cholesky(matrix, beta=beta, mode=mode,
ordering_method=ordering_method)
+ L = f.L()
+ assert factor_of(f, matrix_plus_beta)
+
+
+def test_update_downdate():
+ m = real_matrix()
+ f = cholesky(m)
+ L = f.L()[f.P(), :]
+ assert factor_of(f, m)
+ f.update_inplace(L)
+ assert factor_of(f, 2 * m)
+ f.update_inplace(L)
+ assert factor_of(f, 3 * m)
+ f.update_inplace(L, subtract=True)
+ assert factor_of(f, 2 * m)
+ f.update_inplace(L, subtract=True)
+ assert factor_of(f, m)
+
+
+def test_solve_edge_cases():
+ m = real_matrix()
+ f = cholesky(m)
+ # sparse matrices give a sparse back:
+ assert sparse.issparse(f(sparse.eye(*m.shape).tocsc()))
+ # dense matrices give a dense back:
+ assert not sparse.issparse(f(np.eye(*m.shape)))
+ # 1d dense matrices are accepted and a 1d vector is returned (this matches
+ # the behavior of np.dot):
+ assert f(np.arange(m.shape[0])).shape == (m.shape[0],)
+ # 2d dense matrices are also accepted:
+ assert f(np.arange(m.shape[0])[:, np.newaxis]).shape == (m.shape[0], 1)
+ # But not if the dimensions are wrong...:
+ assert_raises(CholmodError, f, np.arange(m.shape[0] + 1)[:, np.newaxis])
+ assert_raises(CholmodError, f, np.arange(m.shape[0])[np.newaxis, :])
+ assert_raises(CholmodError, f, np.arange(m.shape[0])[:, np.newaxis,
np.newaxis])
+ # And ditto for the sparse version:
+ assert_raises(CholmodError, f, sparse.eye(m.shape[0] + 1,
m.shape[1]).tocsc())
+
+
+def mm_matrix(name):
+ from scipy.io import mmread
+
+ # Supposedly, it is better to use resource_stream and pass the resulting
+ # open file object to mmread()... but for some reason this fails?
+ from pkg_resources import resource_filename
+
+ filename = resource_filename(__name__, "test_data/%s.mtx.gz" % name)
+ matrix = mmread(filename)
+ if sparse.issparse(matrix):
+ matrix = matrix.tocsc()
+ return matrix
+
+
+def test_cholesky_matrix_market():
+ for problem in ("well1033", "illc1033", "well1850", "illc1850"):
+ X = mm_matrix(problem)
+ y = mm_matrix(problem + "_rhs1")
+ answer = np.linalg.lstsq(X.todense(), y)[0]
+ XtX = (X.T * X).tocsc()
+ Xty = X.T * y
+ for mode in modes:
+ assert_allclose(cholesky(XtX, mode=mode)(Xty), answer)
+ assert_allclose(cholesky_AAt(X.T, mode=mode)(Xty), answer)
+ assert_allclose(cholesky(XtX, mode=mode).solve_A(Xty), answer)
+ assert_allclose(cholesky_AAt(X.T, mode=mode).solve_A(Xty), answer)
+
+ f1 = analyze(XtX, mode=mode)
+ f2 = f1.cholesky(XtX)
+ assert_allclose(f2(Xty), answer)
+ assert_raises(CholmodError, f1, Xty)
+ assert_raises(CholmodError, f1.solve_A, Xty)
+ assert_raises(CholmodError, f1.solve_LDLt, Xty)
+ assert_raises(CholmodError, f1.solve_LD, Xty)
+ assert_raises(CholmodError, f1.solve_DLt, Xty)
+ assert_raises(CholmodError, f1.solve_L, Xty)
+ assert_raises(CholmodError, f1.solve_D, Xty)
+ assert_raises(CholmodError, f1.apply_P, Xty)
+ assert_raises(CholmodError, f1.apply_Pt, Xty)
+ f1.P()
+ assert_raises(CholmodError, f1.L)
+ assert_raises(CholmodError, f1.LD)
+ assert_raises(CholmodError, f1.L_D)
+ assert_raises(CholmodError, f1.L_D)
+ f1.cholesky_inplace(XtX)
+ assert_allclose(f1(Xty), answer)
+
+ f3 = analyze_AAt(X.T, mode=mode)
+ f4 = f3.cholesky(XtX)
+ assert_allclose(f4(Xty), answer)
+ assert_raises(CholmodError, f3, Xty)
+ f3.cholesky_AAt_inplace(X.T)
+ assert_allclose(f3(Xty), answer)
+
+ print(problem, mode)
+ for f in (f1, f2, f3, f4):
+ pXtX = XtX.todense()[f.P()[:, np.newaxis], f.P()[np.newaxis,
:]]
+ assert_allclose(np.prod(f.D()), np.linalg.det(XtX.todense()))
+ assert_allclose((f.L() * f.L().T).todense(), pXtX)
+ L, D = f.L_D()
+ assert_allclose((L * D * L.T).todense(), pXtX)
+
+ b = np.arange(XtX.shape[0])[:, np.newaxis]
+ assert_allclose(f.solve_A(b), np.dot(XtX.todense().I, b))
+ assert_allclose(f(b), np.dot(XtX.todense().I, b))
+ assert_allclose(f.solve_LDLt(b), np.dot((L * D *
L.T).todense().I, b))
+ assert_allclose(f.solve_LD(b), np.dot((L * D).todense().I, b))
+ assert_allclose(f.solve_DLt(b), np.dot((D * L.T).todense().I,
b))
+ assert_allclose(f.solve_L(b), np.dot(L.todense().I, b))
+ assert_allclose(f.solve_Lt(b), np.dot(L.T.todense().I, b))
+ assert_allclose(f.solve_D(b), np.dot(D.todense().I, b))
+
+ assert_allclose(f.apply_P(b), b[f.P(), :])
+ assert_allclose(f.apply_P(b), b[f.P(), :])
+ # Pt is the inverse of P, and argsort inverts permutation
+ # vectors:
+ assert_allclose(f.apply_Pt(b), b[np.argsort(f.P()), :])
+ assert_allclose(f.apply_Pt(b), b[np.argsort(f.P()), :])
+
+
+def test_convenience():
+ A_dense_seed = np.array([[10, 0, 3, 0], [0, 5, 0, -2], [3, 0, 5, 0], [0,
-2, 0, 2]])
+ for dtype in (float, complex):
+ A_dense = np.array(A_dense_seed, dtype=dtype)
+ A_sp = sparse.csc_matrix(A_dense)
+ for use_long in [False, True]:
+ if use_long:
+ A_sp = convert_matrix_indices_to_long_indices(A_sp)
+ for ordering_method in ordering_methods:
+ for mode in modes:
+ print("----")
+ print(dtype)
+ print(A_sp.indices.dtype)
+ print(use_long)
+ print(ordering_method)
+ print(mode)
+ print("----")
+ f = cholesky(A_sp, mode=mode,
ordering_method=ordering_method)
+ print(f.D())
+ assert_allclose(f.det(), np.linalg.det(A_dense))
+ assert_allclose(f.logdet(), np.log(np.linalg.det(A_dense)))
+ assert_allclose(f.slogdet(), [1,
np.log(np.linalg.det(A_dense))])
+ assert_allclose((f.inv() * A_sp).todense(), np.eye(4))
+
+
+def test_CholmodNotPositiveDefiniteError():
+ A = -sparse.eye(4).tocsc()
+ f = cholesky(A)
+ assert_raises(CholmodNotPositiveDefiniteError, f.L)
+
+
+def test_natural_ordering_method():
+ A = real_matrix()
+ f = cholesky(A, ordering_method="natural")
+ p = f.P()
+ assert_array_equal(p, np.arange(len(p)))
++++++ scipy111.patch ++++++
>From 179e69774584163a7827b5ee23f1e0096d7eeec3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20J=C3=A4ger?= <[email protected]>
Date: Tue, 29 Aug 2023 16:15:42 +0200
Subject: [PATCH] Fix breaking changes in isspmatrix of scipy >=1.11.0,
discontinuing compatibility with csc_array
Details see https://github.com/scipy/scipy/pull/18528
---
sksparse/cholmod.pyx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sksparse/cholmod.pyx b/sksparse/cholmod.pyx
index 861029d..9eceb8c 100644
--- a/sksparse/cholmod.pyx
+++ b/sksparse/cholmod.pyx
@@ -403,12 +403,12 @@ cdef void _error_handler(
warnings.warn(full_msg, CholmodWarning)
def _check_for_csc(m):
- if not sparse.isspmatrix_csc(m):
+ if not sparse.isspmatrix_csc(m) or isinstance(m, sparse.csc_array):
warnings.warn("converting matrix of class %s to CSC format"
% (m.__class__.__name__,),
CholmodTypeConversionWarning)
m = m.tocsc()
- assert sparse.isspmatrix_csc(m)
+ assert sparse.isspmatrix_csc(m) or isinstance(m, sparse.csc_array)
return m
cdef class Common: