scikit-sparse 0.4.7__tar.gz → 0.4.11__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/PKG-INFO +3 -2
  2. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/pyproject.toml +2 -1
  3. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/scikit_sparse.egg-info/PKG-INFO +3 -2
  4. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/scikit_sparse.egg-info/SOURCES.txt +2 -1
  5. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/setup.py +3 -2
  6. scikit-sparse-0.4.11/sksparse/__init__.py +1 -0
  7. scikit-sparse-0.4.11/tests/test_cholmod.py +286 -0
  8. scikit-sparse-0.4.7/sksparse/__init__.py +0 -1
  9. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/LICENSE.txt +0 -0
  10. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/MANIFEST.in +0 -0
  11. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/README.md +0 -0
  12. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/scikit_sparse.egg-info/dependency_links.txt +0 -0
  13. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/scikit_sparse.egg-info/requires.txt +0 -0
  14. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/scikit_sparse.egg-info/top_level.txt +0 -0
  15. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/setup.cfg +0 -0
  16. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/sksparse/cholmod.pyx +0 -0
  17. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/sksparse/cholmod_backward_compatible.h +0 -0
  18. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/sksparse/test_cholmod.py +0 -0
  19. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/sksparse/test_data/illc1033.mtx.gz +0 -0
  20. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/sksparse/test_data/illc1033_rhs1.mtx.gz +0 -0
  21. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/sksparse/test_data/illc1850.mtx.gz +0 -0
  22. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/sksparse/test_data/illc1850_rhs1.mtx.gz +0 -0
  23. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/sksparse/test_data/well1033.mtx.gz +0 -0
  24. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/sksparse/test_data/well1033_rhs1.mtx.gz +0 -0
  25. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/sksparse/test_data/well1850.mtx.gz +0 -0
  26. {scikit-sparse-0.4.7 → scikit-sparse-0.4.11}/sksparse/test_data/well1850_rhs1.mtx.gz +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: scikit-sparse
3
- Version: 0.4.7
3
+ Version: 0.4.11
4
4
  Summary: Scikit sparse matrix package
5
5
  Home-page: https://github.com/scikit-sparse/scikit-sparse
6
6
  Maintainer: Justin Ellis
@@ -20,7 +20,8 @@ Classifier: Programming Language :: Python :: 3.7
20
20
  Classifier: Programming Language :: Python :: 3.8
21
21
  Classifier: Programming Language :: Python :: 3.9
22
22
  Classifier: Programming Language :: Python :: 3.10
23
- Requires-Python: >=3.6, <3.11
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Requires-Python: >=3.6, <3.12
24
25
  License-File: LICENSE.txt
25
26
 
26
27
  Sparse matrix tools.
@@ -24,11 +24,12 @@ exclude = '''
24
24
  requires = [
25
25
  "setuptools>=40.8.0",
26
26
  "wheel",
27
- "Cython>=0.22",
27
+ "Cython>=0.22,<3.0.0",
28
28
  'numpy==1.13.3; python_version=="3.6"',
29
29
  'numpy==1.14.5; python_version=="3.7"',
30
30
  'numpy==1.17.3; python_version=="3.8"',
31
31
  'numpy==1.19.3; python_version=="3.9"',
32
32
  'numpy==1.23.1; python_version=="3.10"',
33
+ 'numpy==1.23.5; python_version=="3.11"',
33
34
  ]
34
35
  build-backend = "setuptools.build_meta"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: scikit-sparse
3
- Version: 0.4.7
3
+ Version: 0.4.11
4
4
  Summary: Scikit sparse matrix package
5
5
  Home-page: https://github.com/scikit-sparse/scikit-sparse
6
6
  Maintainer: Justin Ellis
@@ -20,7 +20,8 @@ Classifier: Programming Language :: Python :: 3.7
20
20
  Classifier: Programming Language :: Python :: 3.8
21
21
  Classifier: Programming Language :: Python :: 3.9
22
22
  Classifier: Programming Language :: Python :: 3.10
23
- Requires-Python: >=3.6, <3.11
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Requires-Python: >=3.6, <3.12
24
25
  License-File: LICENSE.txt
25
26
 
26
27
  Sparse matrix tools.
@@ -19,4 +19,5 @@ sksparse/test_data/illc1850_rhs1.mtx.gz
19
19
  sksparse/test_data/well1033.mtx.gz
20
20
  sksparse/test_data/well1033_rhs1.mtx.gz
21
21
  sksparse/test_data/well1850.mtx.gz
22
- sksparse/test_data/well1850_rhs1.mtx.gz
22
+ sksparse/test_data/well1850_rhs1.mtx.gz
23
+ tests/test_cholmod.py
@@ -55,13 +55,13 @@ if user_library_dir:
55
55
 
56
56
  setup(
57
57
  install_requires=["numpy>=1.13.3", "scipy>=0.19"],
58
- python_requires=">=3.6, <3.11",
58
+ python_requires=">=3.6, <3.12",
59
59
  packages=find_packages(),
60
60
  package_data={
61
61
  "": ["test_data/*.mtx.gz"],
62
62
  },
63
63
  name=DISTNAME,
64
- version="0.4.7", # remember to update __init__.py
64
+ version="0.4.11", # remember to update __init__.py
65
65
  maintainer=MAINTAINER,
66
66
  maintainer_email=MAINTAINER_EMAIL,
67
67
  description=DESCRIPTION,
@@ -83,6 +83,7 @@ setup(
83
83
  "Programming Language :: Python :: 3.8",
84
84
  "Programming Language :: Python :: 3.9",
85
85
  "Programming Language :: Python :: 3.10",
86
+ "Programming Language :: Python :: 3.11",
86
87
  ],
87
88
  # You may specify the directory where CHOLMOD is installed using the
88
89
  # library_dirs and include_dirs keywords in the lines below.
@@ -0,0 +1 @@
1
+ __version__ = "0.4.11"
@@ -0,0 +1,286 @@
1
+ # Test code for the scikits.sparse CHOLMOD wrapper.
2
+
3
+ # Copyright (C) 2008-2017 The scikit-sparse developers:
4
+ #
5
+ # 2008 David Cournapeau <cournape@gmail.com>
6
+ # 2009-2015 Nathaniel Smith <njs@pobox.com>
7
+ # 2010 Dag Sverre Seljebotn <dagss@student.matnat.uio.no>
8
+ # 2014 Leon Barrett <lbarrett@climate.com>
9
+ # 2015 Yuri <yuri@tsoft.com>
10
+ # 2016-2017 Antony Lee <anntzer.lee@gmail.com>
11
+ # 2016 Alex Grigorievskiy <alex.grigorievskiy@gmail.com>
12
+ # 2016-2017 Joscha Reimer <jor@informatik.uni-kiel.de>
13
+ # All rights reserved.
14
+ #
15
+ # Redistribution and use in source and binary forms, with or without
16
+ # modification, are permitted provided that the following conditions are
17
+ # met:
18
+ #
19
+ # - Redistributions of source code must retain the above copyright
20
+ # notice, this list of conditions and the following disclaimer.
21
+ # - Redistributions in binary form must reproduce the above
22
+ # copyright notice, this list of conditions and the following
23
+ # disclaimer in the documentation and/or other materials
24
+ # provided with the distribution.
25
+ #
26
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
27
+ # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
28
+ # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
29
+ # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
31
+ # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32
+ # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
33
+ # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
35
+ # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36
+ # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
37
+ # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38
+ # SUCH DAMAGE.
39
+
40
+ from functools import partial
41
+ import os.path
42
+
43
+ from pytest import raises as assert_raises
44
+ import numpy as np
45
+ from numpy.testing import assert_allclose, assert_array_equal
46
+ from scipy import sparse
47
+ from sksparse.cholmod import (
48
+ cholesky,
49
+ cholesky_AAt,
50
+ analyze,
51
+ analyze_AAt,
52
+ CholmodError,
53
+ CholmodNotPositiveDefiniteError,
54
+ _modes,
55
+ _ordering_methods,
56
+ )
57
+
58
+ modes = tuple(_modes.keys())
59
+ ordering_methods = tuple(_ordering_methods.keys())
60
+
61
+ # Match defaults of np.allclose, which were used before (and are needed).
62
+ assert_allclose = partial(assert_allclose, rtol=1e-5, atol=1e-8)
63
+
64
+
65
+ def test_cholesky_smoke_test():
66
+ f = cholesky(sparse.eye(10, 10))
67
+ d = np.arange(20).reshape(10, 2)
68
+ print("dense")
69
+ assert_allclose(f(d), d)
70
+ print("sparse")
71
+ s_csc = sparse.csc_matrix(np.eye(10)[:, :2])
72
+ assert sparse.issparse(f(s_csc))
73
+ assert_allclose(f(s_csc).todense(), s_csc.todense())
74
+ print("csr")
75
+ s_csr = s_csc.tocsr()
76
+ assert sparse.issparse(f(s_csr))
77
+ assert_allclose(f(s_csr).todense(), s_csr.todense())
78
+ print("extract")
79
+ assert np.all(f.P() == np.arange(10))
80
+
81
+
82
+ def test_writeability():
83
+ t = cholesky(sparse.eye(10, 10))(np.arange(10))
84
+ assert t.flags["WRITEABLE"]
85
+
86
+
87
+ def real_matrix():
88
+ return sparse.csc_matrix([[10, 0, 3, 0], [0, 5, 0, -2], [3, 0, 5, 0], [0, -2, 0, 2]])
89
+
90
+
91
+ def complex_matrix():
92
+ return sparse.csc_matrix([[10, 0, 3 - 1j, 0], [0, 5, 0, -2], [3 + 1j, 0, 5, 0], [0, -2, 0, 2]])
93
+
94
+
95
+ def factor_of(factor, matrix):
96
+ return np.allclose(
97
+ (factor.L() * factor.L().H).todense(), matrix.todense()[factor.P()[:, np.newaxis], factor.P()[np.newaxis, :]]
98
+ )
99
+
100
+
101
+ def convert_matrix_indices_to_long_indices(matrix):
102
+ matrix.indices = np.asarray(matrix.indices, dtype=np.int64)
103
+ matrix.indptr = np.asarray(matrix.indptr, dtype=np.int64)
104
+ return matrix
105
+
106
+
107
+ def test_complex():
108
+ c = complex_matrix()
109
+ fc = cholesky(c)
110
+ r = real_matrix()
111
+ fr = cholesky(r)
112
+
113
+ assert factor_of(fc, c)
114
+
115
+ assert_allclose(fc(np.arange(4))[:, None], c.todense().I * np.arange(4)[:, None])
116
+ assert_allclose(fc(np.arange(4) * 1j)[:, None], c.todense().I * (np.arange(4) * 1j)[:, None])
117
+ assert_allclose(fr(np.arange(4))[:, None], r.todense().I * np.arange(4)[:, None])
118
+ # If we did a real factorization, we can't do solves on complex arrays:
119
+ assert_raises(CholmodError, fr, np.arange(4) * 1j)
120
+
121
+
122
+ def test_beta():
123
+ for matrix in [real_matrix(), complex_matrix()]:
124
+ for beta in [0, 1, 3.4]:
125
+ matrix_plus_beta = matrix + beta * sparse.eye(*matrix.shape)
126
+ for use_long in [False, True]:
127
+ if use_long:
128
+ matrix_plus_beta = convert_matrix_indices_to_long_indices(matrix_plus_beta)
129
+ for ordering_method in ordering_methods:
130
+ for mode in modes:
131
+ f = cholesky(matrix, beta=beta, mode=mode, ordering_method=ordering_method)
132
+ L = f.L()
133
+ assert factor_of(f, matrix_plus_beta)
134
+
135
+
136
+ def test_update_downdate():
137
+ m = real_matrix()
138
+ f = cholesky(m)
139
+ L = f.L()[f.P(), :]
140
+ assert factor_of(f, m)
141
+ f.update_inplace(L)
142
+ assert factor_of(f, 2 * m)
143
+ f.update_inplace(L)
144
+ assert factor_of(f, 3 * m)
145
+ f.update_inplace(L, subtract=True)
146
+ assert factor_of(f, 2 * m)
147
+ f.update_inplace(L, subtract=True)
148
+ assert factor_of(f, m)
149
+
150
+
151
+ def test_solve_edge_cases():
152
+ m = real_matrix()
153
+ f = cholesky(m)
154
+ # sparse matrices give a sparse back:
155
+ assert sparse.issparse(f(sparse.eye(*m.shape).tocsc()))
156
+ # dense matrices give a dense back:
157
+ assert not sparse.issparse(f(np.eye(*m.shape)))
158
+ # 1d dense matrices are accepted and a 1d vector is returned (this matches
159
+ # the behavior of np.dot):
160
+ assert f(np.arange(m.shape[0])).shape == (m.shape[0],)
161
+ # 2d dense matrices are also accepted:
162
+ assert f(np.arange(m.shape[0])[:, np.newaxis]).shape == (m.shape[0], 1)
163
+ # But not if the dimensions are wrong...:
164
+ assert_raises(CholmodError, f, np.arange(m.shape[0] + 1)[:, np.newaxis])
165
+ assert_raises(CholmodError, f, np.arange(m.shape[0])[np.newaxis, :])
166
+ assert_raises(CholmodError, f, np.arange(m.shape[0])[:, np.newaxis, np.newaxis])
167
+ # And ditto for the sparse version:
168
+ assert_raises(CholmodError, f, sparse.eye(m.shape[0] + 1, m.shape[1]).tocsc())
169
+
170
+
171
+ def mm_matrix(name):
172
+ from scipy.io import mmread
173
+
174
+ # Supposedly, it is better to use resource_stream and pass the resulting
175
+ # open file object to mmread()... but for some reason this fails?
176
+ from pkg_resources import resource_filename
177
+
178
+ filename = resource_filename(__name__, "test_data/%s.mtx.gz" % name)
179
+ matrix = mmread(filename)
180
+ if sparse.issparse(matrix):
181
+ matrix = matrix.tocsc()
182
+ return matrix
183
+
184
+
185
+ def test_cholesky_matrix_market():
186
+ for problem in ("well1033", "illc1033", "well1850", "illc1850"):
187
+ X = mm_matrix(problem)
188
+ y = mm_matrix(problem + "_rhs1")
189
+ answer = np.linalg.lstsq(X.todense(), y)[0]
190
+ XtX = (X.T * X).tocsc()
191
+ Xty = X.T * y
192
+ for mode in modes:
193
+ assert_allclose(cholesky(XtX, mode=mode)(Xty), answer)
194
+ assert_allclose(cholesky_AAt(X.T, mode=mode)(Xty), answer)
195
+ assert_allclose(cholesky(XtX, mode=mode).solve_A(Xty), answer)
196
+ assert_allclose(cholesky_AAt(X.T, mode=mode).solve_A(Xty), answer)
197
+
198
+ f1 = analyze(XtX, mode=mode)
199
+ f2 = f1.cholesky(XtX)
200
+ assert_allclose(f2(Xty), answer)
201
+ assert_raises(CholmodError, f1, Xty)
202
+ assert_raises(CholmodError, f1.solve_A, Xty)
203
+ assert_raises(CholmodError, f1.solve_LDLt, Xty)
204
+ assert_raises(CholmodError, f1.solve_LD, Xty)
205
+ assert_raises(CholmodError, f1.solve_DLt, Xty)
206
+ assert_raises(CholmodError, f1.solve_L, Xty)
207
+ assert_raises(CholmodError, f1.solve_D, Xty)
208
+ assert_raises(CholmodError, f1.apply_P, Xty)
209
+ assert_raises(CholmodError, f1.apply_Pt, Xty)
210
+ f1.P()
211
+ assert_raises(CholmodError, f1.L)
212
+ assert_raises(CholmodError, f1.LD)
213
+ assert_raises(CholmodError, f1.L_D)
214
+ assert_raises(CholmodError, f1.L_D)
215
+ f1.cholesky_inplace(XtX)
216
+ assert_allclose(f1(Xty), answer)
217
+
218
+ f3 = analyze_AAt(X.T, mode=mode)
219
+ f4 = f3.cholesky(XtX)
220
+ assert_allclose(f4(Xty), answer)
221
+ assert_raises(CholmodError, f3, Xty)
222
+ f3.cholesky_AAt_inplace(X.T)
223
+ assert_allclose(f3(Xty), answer)
224
+
225
+ print(problem, mode)
226
+ for f in (f1, f2, f3, f4):
227
+ pXtX = XtX.todense()[f.P()[:, np.newaxis], f.P()[np.newaxis, :]]
228
+ assert_allclose(np.prod(f.D()), np.linalg.det(XtX.todense()))
229
+ assert_allclose((f.L() * f.L().T).todense(), pXtX)
230
+ L, D = f.L_D()
231
+ assert_allclose((L * D * L.T).todense(), pXtX)
232
+
233
+ b = np.arange(XtX.shape[0])[:, np.newaxis]
234
+ assert_allclose(f.solve_A(b), np.dot(XtX.todense().I, b))
235
+ assert_allclose(f(b), np.dot(XtX.todense().I, b))
236
+ assert_allclose(f.solve_LDLt(b), np.dot((L * D * L.T).todense().I, b))
237
+ assert_allclose(f.solve_LD(b), np.dot((L * D).todense().I, b))
238
+ assert_allclose(f.solve_DLt(b), np.dot((D * L.T).todense().I, b))
239
+ assert_allclose(f.solve_L(b), np.dot(L.todense().I, b))
240
+ assert_allclose(f.solve_Lt(b), np.dot(L.T.todense().I, b))
241
+ assert_allclose(f.solve_D(b), np.dot(D.todense().I, b))
242
+
243
+ assert_allclose(f.apply_P(b), b[f.P(), :])
244
+ assert_allclose(f.apply_P(b), b[f.P(), :])
245
+ # Pt is the inverse of P, and argsort inverts permutation
246
+ # vectors:
247
+ assert_allclose(f.apply_Pt(b), b[np.argsort(f.P()), :])
248
+ assert_allclose(f.apply_Pt(b), b[np.argsort(f.P()), :])
249
+
250
+
251
+ def test_convenience():
252
+ A_dense_seed = np.array([[10, 0, 3, 0], [0, 5, 0, -2], [3, 0, 5, 0], [0, -2, 0, 2]])
253
+ for dtype in (float, complex):
254
+ A_dense = np.array(A_dense_seed, dtype=dtype)
255
+ A_sp = sparse.csc_matrix(A_dense)
256
+ for use_long in [False, True]:
257
+ if use_long:
258
+ A_sp = convert_matrix_indices_to_long_indices(A_sp)
259
+ for ordering_method in ordering_methods:
260
+ for mode in modes:
261
+ print("----")
262
+ print(dtype)
263
+ print(A_sp.indices.dtype)
264
+ print(use_long)
265
+ print(ordering_method)
266
+ print(mode)
267
+ print("----")
268
+ f = cholesky(A_sp, mode=mode, ordering_method=ordering_method)
269
+ print(f.D())
270
+ assert_allclose(f.det(), np.linalg.det(A_dense))
271
+ assert_allclose(f.logdet(), np.log(np.linalg.det(A_dense)))
272
+ assert_allclose(f.slogdet(), [1, np.log(np.linalg.det(A_dense))])
273
+ assert_allclose((f.inv() * A_sp).todense(), np.eye(4))
274
+
275
+
276
+ def test_CholmodNotPositiveDefiniteError():
277
+ A = -sparse.eye(4).tocsc()
278
+ f = cholesky(A)
279
+ assert_raises(CholmodNotPositiveDefiniteError, f.L)
280
+
281
+
282
+ def test_natural_ordering_method():
283
+ A = real_matrix()
284
+ f = cholesky(A, ordering_method="natural")
285
+ p = f.P()
286
+ assert_array_equal(p, np.arange(len(p)))
@@ -1 +0,0 @@
1
- __version__ = "0.4.7"
File without changes
File without changes