diff --git a/.github/workflows/requirements-middle.txt b/.github/workflows/requirements-middle.txt index 80ba09b..cd0b9f0 100644 --- a/.github/workflows/requirements-middle.txt +++ b/.github/workflows/requirements-middle.txt @@ -1,2 +1,2 @@ -numpy==1.23.5 -scipy==1.9.3 +numpy==2.0.1 +scipy==1.14.0 diff --git a/.github/workflows/requirements-newest.txt b/.github/workflows/requirements-newest.txt index cd0b9f0..479d856 100644 --- a/.github/workflows/requirements-newest.txt +++ b/.github/workflows/requirements-newest.txt @@ -1,2 +1,2 @@ -numpy==2.0.1 -scipy==1.14.0 +numpy==2.4.1 +scipy==1.17.0 diff --git a/.github/workflows/requirements-oldest.txt b/.github/workflows/requirements-oldest.txt index 6b9bd11..80ba09b 100644 --- a/.github/workflows/requirements-oldest.txt +++ b/.github/workflows/requirements-oldest.txt @@ -1,2 +1,2 @@ -numpy==1.20.3 -scipy==1.7.3 +numpy==1.23.5 +scipy==1.9.3 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a545e7b..6e33d50 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,20 +11,20 @@ jobs: name: Test with Python ${{ matrix.python-version }} and ${{ matrix.req-version }} requirements on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: - fail-fast: true + fail-fast: false matrix: - python-version: ["3.8", "3.10", "3.12"] + python-version: ["3.10", "3.12", "3.14"] req-version: ["oldest", "middle", "newest"] os: ["ubuntu-24.04"] exclude: - - python-version: "3.8" - req-version: "newest" - python-version: "3.10" - req-version: "oldest" + req-version: "newest" - python-version: "3.12" req-version: "oldest" - - python-version: "3.12" + - python-version: "3.14" req-version: "middle" + - python-version: "3.14" + req-version: "oldest" steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} diff --git a/lazyarray.py b/lazyarray.py index ec873c9..93ff00f 100644 --- a/lazyarray.py +++ b/lazyarray.py @@ -510,10 +510,10 @@ def evaluate(self, simplify=False, empty_val=0): x = x.reshape(self._shape) elif have_scipy and sparse.issparse(self.base_value): # For sparse matrices if empty_val != 0: - x = self.base_value.toarray((sparse.csc_matrix)) + x = self.base_value.toarray() x = np.where(x, x, np.nan) else: - x = self.base_value.toarray((sparse.csc_matrix)) + x = self.base_value.toarray() elif isinstance(self.base_value, Iterator): x = np.fromiter(self.base_value, dtype=self.dtype or float, count=self.size) if x.shape != self._shape: diff --git a/pyproject.toml b/pyproject.toml index f762888..abcdc7e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,10 @@ [project] name = "lazyarray" -version = "0.6.0" +version = "0.7.0.dev.0" description = "A Python package that provides a lazily-evaluated numerical array class, larray, based on and compatible with NumPy arrays." readme = "README.rst" -requires-python = ">=3.8" -license = {text = "Modified BSD"} +requires-python = ">=3.10" +license = "BSD-3-Clause" authors = [ {name = "Andrew P. Davison", email = "andrew.davison@cnrs.fr"} ] @@ -15,18 +15,17 @@ keywords = ["lazy evaluation, array"] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Science/Research", - "License :: OSI Approved :: BSD License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Topic :: Scientific/Engineering" ] dependencies = [ - "numpy>=1.20.3" + "numpy>=1.23.5" ] [project.optional-dependencies] -sparse = ["scipy>=1.7.3"] +sparse = ["scipy>=1.9.3"] dev = ["sphinx", "pytest", "pytest-cov", "flake8", "wheel"] [project.urls] diff --git a/test/test_lazy_arrays_from_Sparse_Matrices.py b/test/test_lazy_arrays_from_Sparse_Matrices.py deleted file mode 100644 index ae0e834..0000000 --- a/test/test_lazy_arrays_from_Sparse_Matrices.py +++ /dev/null @@ -1,211 +0,0 @@ -# Support creating lazy arrays from SciPy sparse matrices -# -# 1 program for the 7 sparse matrices classes : -# -# csc_matrix(arg1[, shape, dtype, copy]) Compressed Sparse Column matrix -# csr_matrix(arg1[, shape, dtype, copy]) Compressed Sparse Row matrix -# bsr_matrix(arg1[, shape, dtype, copy, blocksize]) Block Sparse Row matrix -# lil_matrix(arg1[, shape, dtype, copy]) Row-based linked list sparse matrix -# dok_matrix(arg1[, shape, dtype, copy]) Dictionary Of Keys based sparse matrix. -# coo_matrix(arg1[, shape, dtype, copy]) A sparse matrix in COOrdinate format. -# dia_matrix(arg1[, shape, dtype, copy]) Sparse matrix with DIAgonal storage -# - - -import numpy as np -from lazyarray import larray -from scipy import sparse -import random - - -################ -# Random numbers -################ -i = random.randint(-100, 100) -j = random.randint(-100, 100) -k = random.randint(-100, 100) -l = random.randint(-100, 100) -m = random.randint(-100, 100) -n = random.randint(-100, 100) -p = random.randint(-100, 100) -q = random.randint(-100, 100) -r = random.randint(-100, 100) - -################ -# An example -################ -#i = 1 -#j = 2 -#k = 0 -#l = 0 -#m = 0 -#n = 3 -#p = 1 -#q = 0 -#r = 4 - -#print "i =", i -#print "j =", j -#print "k =", k -#print "l =", l -#print "m =", m -#print "n =", n -#print "p =", p -#print "q =", q -#print "r =", r - - -############################################################## -# Definition of an array -############################################################## - -def test_function_array_general(): - A = np.array([[i, j, k], [l, m, n], [p, q, r]]) - #print "A =" - #print A - return A - - -############################################################## -# Definition of 7 sparse matrices -############################################################## - -def sparse_csc_matrices(): - csc = sparse.csc_matrix([[i, j, k], [l, m, n], [p, q, r]]) - #print "csc matrices =" - #print csc - return csc - -def sparse_csr_matrices(): - csr = sparse.csr_matrix([[i, j, k], [l, m, n], [p, q, r]]) - #print "csr matrices =" - #print csr - return csr - -def sparse_bsr_matrices(): - bsr = sparse.bsr_matrix([[i, j, k], [l, m, n], [p, q, r]]) - #print "bsr matrices =" - #print bsr - return bsr - -def sparse_lil_matrices(): - lil = sparse.lil_matrix([[i, j, k], [l, m, n], [p, q, r]]) - #print "lil matrices =" - #print lil - return lil - -def sparse_dok_matrices(): - dok = sparse.dok_matrix([[i, j, k], [l, m, n], [p, q, r]]) - #print "dok matrices =" - #print dok - return dok - -def sparse_coo_matrices(): - coo = sparse.coo_matrix([[i, j, k], [l, m, n], [p, q, r]]) - #print "coo matrices =" - #print coo - return coo - -def sparse_dia_matrices(): - dia = sparse.dia_matrix([[i, j, k], [l, m, n], [p, q, r]]) - #print "dia matrices =" - #print dia - return dia - - - -if __name__ == "__main__": - - -############################################################## -# Call test_function_array_general -# Create a sparse matrix from array -# There are 7 sparse matrices -############################################################## - - #print "Array general =" - test_function_array_general() - #print "Array =" - #print test_function_array_general() - -# print "----" - -# print "Sparse array csc general =" - sA_csc_general = sparse.csc_matrix(test_function_array_general()) - #print ("sparse csc matrices", sparse.csc_matrix(test_function_array_general())) - #print "sparse csc matrices =" - #print sA_csc_general -# print "----" -# print "Sparse array csr general =" - sA_csr = sparse.csr_matrix(test_function_array_general()) - #print ("sparse csr matrices", sparse.csr_matrix(test_function_array_general())) - #print "sparse csr matrices =" - #print sA_csr -# print "----" -# print "Sparse array bsr general =" - sA_bsr = sparse.bsr_matrix(test_function_array_general()) -# print ("sparse bsr matrices", sparse.bsr_matrix(test_function_array_general())) -# print "sparse bsr matrices =" -# print sA_bsr -# print "----" -# print "Sparse array lil general =" - sA_lil = sparse.lil_matrix(test_function_array_general()) -# print ("sparse lil matrices", sparse.lil_matrix(test_function_array_general())) -# print "sparse lil matrices =" -# print sA_lil -# print "----" -# print "Sparse array dok general =" - sA_dok = sparse.dok_matrix(test_function_array_general()) -# print ("sparse dok matrices", sparse.dok_matrix(test_function_array_general())) -# print "sparse dok matrices =" -# print sA_dok -# print "----" -# print "Sparse array coo general =" - sA_coo = sparse.coo_matrix(test_function_array_general()) -# print ("sparse coo matrices", sparse.coo_matrix(test_function_array_general())) -# print "sparse coo matrices =" -# print sA_coo -# print "----" -# print "Sparse array dia general =" - sA_dia = sparse.dia_matrix(test_function_array_general()) -# print ("sparse dia matrices", sparse.dia_matrix(test_function_array_general())) -# print "sparse dia matrices =" -# print sA_dia - - -#print "----------------------------------------------------------------------" - - - ############################################################## - # Call the sparse matrices - # Create a lazy array from sparse matrices - ############################################################## - - -Array_csc_matrices = sparse_csc_matrices().toarray() -#print "Array csc matrices =" -#print Array_csc_matrices - -Array_csr_matrices = sparse_csr_matrices().toarray() -#print "Array csr matrices =" -#print Array_csr_matrices - -Array_bsr_matrices = sparse_bsr_matrices().toarray() -#print "Array bsr matrices =" -#print Array_bsr_matrices - -Array_lil_matrices = sparse_lil_matrices().toarray() -#print "Array lil matrices =" -#print Array_lil_matrices - -Array_dok_matrices = sparse_dok_matrices().toarray() -#print "Array dok matrices =" -#print Array_dok_matrices - -Array_coo_matrices = sparse_coo_matrices().toarray() -#print "Array coo matrices =" -#print Array_coo_matrices - -Array_dia_matrices = sparse_dia_matrices().toarray() -#print "Array dia matrices =" -#print Array_dia_matrices \ No newline at end of file diff --git a/test/test_lazyarray.py b/test/test_lazyarray.py index c10f7f3..83e451d 100644 --- a/test/test_lazyarray.py +++ b/test/test_lazyarray.py @@ -121,8 +121,8 @@ def test_create_with_sparse_array(): data_dia = np.array([[1, 2, 3, 4]]).repeat(3, axis=0) # For dia_matrix offsets_dia = np.array([0, -1, 2]) # For dia_matrix dia = larray(dia_matrix((data_dia, offsets_dia), shape=(4, 4))) # For dia_matrix - dok = larray(dok_matrix(((row, col)), shape=(3, 3))) # For dok_matrix - lil = larray(lil_matrix(data, shape=(3, 3))) # For lil_matrix + dok = larray(dok_matrix((np.vstack((row, col))), shape=(2, 6))) # For dok_matrix + lil = larray(lil_matrix(data, shape=(1, 6))) # For lil_matrix assert bsr.shape == (3, 3) assert coo.shape == (3, 3) assert csc.shape == (3, 3) @@ -136,47 +136,63 @@ def test_evaluate_with_sparse_array(): assert_array_equal(coo.evaluate(), coo_matrix((data, (row, col))).toarray()) # For coo_matrix assert_array_equal(csc.evaluate(), csc_matrix((data, (row, col))).toarray()) # For csc_matrix assert_array_equal(csr.evaluate(), csr_matrix((data, (row, col))).toarray()) # For csr_matrix - assert_array_equal(dia.evaluate(), dia_matrix((data_dia, (row, col))).toarray()) # For dia_matrix - assert_array_equal(dok.evaluate(), dok_matrix((data, (row, col))).toarray()) # For dok_matrix - assert_array_equal(lil.evaluate(), lil_matrix((data, (row, col))).toarray()) # For lil_matrix + assert_array_equal(dia.evaluate(), dia_matrix((data_dia, offsets_dia), shape=(4, 4)).toarray()) # For dia_matrix + assert_array_equal(dok.evaluate(), dok_matrix((np.vstack((row, col))), shape=(2, 6)).toarray()) # For dok_matrix + assert_array_equal(lil.evaluate(), lil_matrix(data, shape=(1, 6)).toarray()) # For lil_matrix + test_evaluate_with_sparse_array() def test_multiple_operations_with_sparse_array(): # For bsr_matrix - bsr0 = bsr /100.0 + bsr0 = bsr / 100.0 bsr1 = 0.2 + bsr0 assert_array_almost_equal(bsr0.evaluate(), np.array([[0.01, 0., 0.04], [0., 0., 0.05], [0.02, 0.03, 0.06]])) - assert_array_almost_equal(bsr0.evaluate(), np.array([[0.21, 0.2, 0.24], [0.2, 0.2, 0.25], [0.22, 0.23, 0.26]])) + assert_array_almost_equal(bsr1.evaluate(), np.array([[0.21, 0.2, 0.24], [0.2, 0.2, 0.25], [0.22, 0.23, 0.26]])) # For coo_matrix - coo0 = coo /100.0 + coo0 = coo / 100.0 coo1 = 0.2 + coo0 assert_array_almost_equal(coo0.evaluate(), np.array([[0.01, 0., 0.04], [0., 0., 0.05], [0.02, 0.03, 0.06]])) - assert_array_almost_equal(coo0.evaluate(), np.array([[0.21, 0.2, 0.24], [0.2, 0.2, 0.25], [0.22, 0.23, 0.26]])) + assert_array_almost_equal(coo1.evaluate(), np.array([[0.21, 0.2, 0.24], [0.2, 0.2, 0.25], [0.22, 0.23, 0.26]])) # For csc_matrix - csc0 = csc /100.0 + csc0 = csc / 100.0 csc1 = 0.2 + csc0 assert_array_almost_equal(csc0.evaluate(), np.array([[0.01, 0., 0.04], [0., 0., 0.05], [0.02, 0.03, 0.06]])) - assert_array_almost_equal(csc0.evaluate(), np.array([[0.21, 0.2, 0.24], [0.2, 0.2, 0.25], [0.22, 0.23, 0.26]])) + assert_array_almost_equal(csc1.evaluate(), np.array([[0.21, 0.2, 0.24], [0.2, 0.2, 0.25], [0.22, 0.23, 0.26]])) # For csr_matrix - csr0 = csr /100.0 + csr0 = csr / 100.0 csr1 = 0.2 + csr0 assert_array_almost_equal(csc0.evaluate(), np.array([[0.01, 0., 0.04], [0., 0., 0.05], [0.02, 0.03, 0.06]])) - assert_array_almost_equal(csc0.evaluate(), np.array([[0.21, 0.2, 0.24], [0.2, 0.2, 0.25], [0.22, 0.23, 0.26]])) + assert_array_almost_equal(csc1.evaluate(), np.array([[0.21, 0.2, 0.24], [0.2, 0.2, 0.25], [0.22, 0.23, 0.26]])) # For dia_matrix - dia0 = dia /100.0 + dia0 = dia / 100.0 dia1 = 0.2 + dia0 - assert_array_almost_equal(dia0.evaluate(), np.array([[0.01, 0.02, 0.03, 0.04]])) - assert_array_almost_equal(dia1.evaluate(), np.array([[0.21, 0.22, 0.23, 0.24]])) - # For dok_matrix - dok0 = dok /100.0 + assert_array_almost_equal( + dia0.evaluate(), + np.array([ + [0.01, 0, 0.03, 0], + [0.01, 0.02, 0, 0.04], + [0, 0.02, 0.03, 0], + [0, 0, 0.03, 0.04] + ]) + ) + assert_array_almost_equal( + dia1.evaluate(), + np.array([ + [0.21, 0.2, 0.23, 0.2], + [0.21, 0.22, 0.2, 0.24], + [0.2, 0.22, 0.23, 0.2], + [0.2, 0.2, 0.23, 0.24] + ]) + ) # For dok_matrix + dok0 = dok / 100.0 dok1 = 0.2 + dok0 assert_array_almost_equal(dok0.evaluate(), np.array([[0., 0.02, 0.02, 0., 0.01, 0.02], [0., 0., 0.01, 0.02, 0.02, 0.02]])) assert_array_almost_equal(dok1.evaluate(), np.array([[0.2, 0.22, 0.22, 0.2, 0.21, 0.22], [0.2, 0.2, 0.21, 0.22, 0.22, 0.22]])) # For lil_matrix - lil0 = lil /100.0 + lil0 = lil / 100.0 lil1 = 0.2 + lil0 assert_array_almost_equal(lil0.evaluate(), np.array([[0.01, 0.02, 0.03, 0.04, 0.05, 0.06]])) assert_array_almost_equal(lil1.evaluate(), np.array([[0.21, 0.22, 0.23, 0.24, 0.25, 0.26]])) - + test_multiple_operations_with_sparse_array() def test_getitem_from_2D_sparse_array(): pytest.raises(IndexError, bsr.__getitem__, (3, 0)) @@ -186,41 +202,7 @@ def test_getitem_from_2D_sparse_array(): pytest.raises(IndexError, dia.__getitem__, (3, 0)) pytest.raises(IndexError, dok.__getitem__, (3, 0)) pytest.raises(IndexError, lil.__getitem__, (3, 0)) - - -# def test_columnwise_iteration_with_flat_array(): -# m = larray(5, shape=(4,3)) # 4 rows, 3 columns -# cols = [col for col in m.by_column()] -# assert cols == [5, 5, 5] -# -# def test_columnwise_iteration_with_structured_array(): -# input = np.arange(12).reshape((4,3)) -# m = larray(input, shape=(4,3)) # 4 rows, 3 columns -# cols = [col for col in m.by_column()] -# assert_array_equal(cols[0], input[:,0]) -# assert_array_equal(cols[2], input[:,2]) -# -# def test_columnwise_iteration_with_function(): -# input = lambda i,j: 2*i + j -# m = larray(input, shape=(4,3)) -# cols = [col for col in m.by_column()] -# assert_array_equal(cols[0], np.array([0, 2, 4, 6])) -# assert_array_equal(cols[1], np.array([1, 3, 5, 7])) -# assert_array_equal(cols[2], np.array([2, 4, 6, 8])) -# -# def test_columnwise_iteration_with_flat_array_and_mask(): -# m = larray(5, shape=(4,3)) # 4 rows, 3 columns -# mask = np.array([True, False, True]) -# cols = [col for col in m.by_column(mask=mask)] -# assert cols == [5, 5] -# -# def test_columnwise_iteration_with_structured_array_and_mask(): -# input = np.arange(12).reshape((4,3)) -# m = larray(input, shape=(4,3)) # 4 rows, 3 columns -# mask = np.array([False, True, True]) -# cols = [col for col in m.by_column(mask=mask)] -# assert_array_equal(cols[0], input[:,1]) -# assert_array_equal(cols[1], input[:,2]) + # test_getitem_from_2D_sparse_array() def test_size_related_properties():