diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 71a62a7..451eeb9 100755 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,8 +10,28 @@ jobs: test: strategy: matrix: - python-version: ['3.9', '3.10', '3.11', '3.12'] # Specify the Python versions you want to test against - os: [ubuntu-latest, windows-latest] + # ubuntu-latest now resolves to a newer Ubuntu release than + # actions/setup-python has prebuilt Python 3.9/3.10 for (Python itself + # dropped support for the kernel/libc these need) - pin an older + # Ubuntu LTS for those so "Set up Python" doesn't fail outright. See + # https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json + include: + - python-version: '3.9' + os: ubuntu-24.04 + - python-version: '3.9' + os: windows-latest + - python-version: '3.10' + os: ubuntu-24.04 + - python-version: '3.10' + os: windows-latest + - python-version: '3.11' + os: ubuntu-latest + - python-version: '3.11' + os: windows-latest + - python-version: '3.12' + os: ubuntu-latest + - python-version: '3.12' + os: windows-latest name: Python ${{ matrix.python-version }} - ${{ matrix.os }} runs-on: ${{ matrix.os }} steps: diff --git a/README.md b/README.md index 70c317f..d03070b 100644 --- a/README.md +++ b/README.md @@ -25,3 +25,4 @@ Requirements - pyNFFT3 0.2.2 or greater - NumPy 2.0.0 or greater - SciPy 1.16.0 or greater + diff --git a/pyproject.toml b/pyproject.toml index 2596536..8cb3c21 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,8 +16,8 @@ readme = "README.md" requires-python = ">=3.9" dependencies = [ "pyNFFT3>=0.2.2", - "numpy>=2.0.0", - "scipy>=1.16.0", + "numpy>=1.26.4", + "scipy>=1.11.4", ] [project.urls] diff --git a/src/pyGroupedTransforms/CWWTtools.py b/src/pyGroupedTransforms/CWWTtools.py index ffbebe7..9b88a39 100644 --- a/src/pyGroupedTransforms/CWWTtools.py +++ b/src/pyGroupedTransforms/CWWTtools.py @@ -119,7 +119,7 @@ def indextoN(j, k): # indextoN(j::Array{Int}, k::Array{Int})::Array{Int} s = k.shape[1] if d != d2: - ValueError("j and k have to have same length, k has to be column vector.") + raise ValueError("j and k have to have same length, k has to be column vector.") out = np.zeros(s) diff --git a/src/pyGroupedTransforms/DeferredLinearOperator.py b/src/pyGroupedTransforms/DeferredLinearOperator.py index 3d46c82..fe651d4 100644 --- a/src/pyGroupedTransforms/DeferredLinearOperator.py +++ b/src/pyGroupedTransforms/DeferredLinearOperator.py @@ -7,8 +7,8 @@ def __init__( self, dtype="complex", shape=None, - mfunc=lambda x: "not yet initialized", - rmfunc=lambda x: "not yet initialized", + mfunc=None, + rmfunc=None, ): self.sh = False @@ -19,8 +19,6 @@ def __init__( self._matvec_func = mfunc self._rmatvec_func = rmfunc - self._matvec = lambda x: self._matvec_func(x) - self._rmatvec = lambda x: self._rmatvec_func(x) super().__init__(dtype=dtype, shape=shape) def set(self, dtype=None, shape=None, mfunc=None, rmfunc=None): @@ -38,16 +36,15 @@ def set(self, dtype=None, shape=None, mfunc=None, rmfunc=None): self._rmatvec_func = rmfunc def _matvec(self, x): - if self._matvec_func(0) == "not implemented yet" or self.sh == False: + if self._matvec_func is None or self.sh == False: raise NotImplementedError("LinearOperator is not yet initialized.") - print(self.LO @ x) - return self @ x + return self._matvec_func(x) def _rmatvec(self, x): - if self._matvec_func(0) == "not implemented yet" or self.sh == False: + if self._matvec_func is None or self.sh == False: raise NotImplementedError("LinearOperator is not yet initialized.") - if self._rmatvec_func(0) == "not implemented yet": + if self._rmatvec_func is None: raise NotImplementedError("rmatvec is not yet implemented") - return self.H @ x + return self._rmatvec_func(x) diff --git a/src/pyGroupedTransforms/GroupedTransform.py b/src/pyGroupedTransforms/GroupedTransform.py index 4f4117b..c083a84 100644 --- a/src/pyGroupedTransforms/GroupedTransform.py +++ b/src/pyGroupedTransforms/GroupedTransform.py @@ -53,11 +53,11 @@ def get_setting( if systems[system] == NFMTtools: if len(basis_vect) == 0: - ValueError( + raise ValueError( "please call get_setting with basis_vect for a NFMT transform." ) if len(basis_vect) < d: - ValueError("basis_vect must have an entry for every dimension.") + raise ValueError("basis_vect must have an entry for every dimension.") return [ Setting( u=U[idx], @@ -93,11 +93,11 @@ def get_setting( if systems[system] == NFMTtools: if len(basis_vect) == 0: - ValueError( + raise ValueError( "please call get_setting with basis_vect for a NFMT transform." ) if len(basis_vect) < max(max(u) for u in U): - ValueError("basis_vect must have an entry for every dimension.") + raise ValueError("basis_vect must have an entry for every dimension.") return [ Setting( u=u, @@ -132,11 +132,11 @@ def get_setting( if systems[system] == NFMTtools: if len(basis_vect) == 0: - ValueError( + raise ValueError( "please call get_setting with basis_vect for a NFMT transform." ) if len(basis_vect) < max(max(u) for u in U): - ValueError("basis_vect must have an entry for every dimension.") + raise ValueError("basis_vect must have an entry for every dimension.") return [ Setting( u=U[idx], @@ -197,11 +197,11 @@ def __init__( if system == "mixed": if len(basis_vect) == 0: - ValueError( + raise ValueError( "please call GroupedTransform with basis_vect for a NFMT transform." ) if len(basis_vect) != X.shape[1]: - ValueError("basis_vect must have an entry for every dimension.") + raise ValueError("basis_vect must have an entry for every dimension.") if system in {"exp", "chui1", "chui2", "chui3", "chui4"}: if np.min(X) < -0.5 or np.max(X) >= 0.5: @@ -433,7 +433,7 @@ def get_matrix(self): u1 = (0,) else: u1 = s1.u - F_direct = s1.mode.get_matrix(s.bdanwidths, self.X[:, u1].T, bases=s.bases) + F_direct = s1.mode.get_matrix(s1.bandwidths, self.X[:, u1].T, bases=s1.bases) for idx, s in enumerate(self.settings): if idx == 0: continue diff --git a/src/pyGroupedTransforms/GroupedTransforms.py b/src/pyGroupedTransforms/GroupedTransforms.py index 9818a45..bee060d 100644 --- a/src/pyGroupedTransforms/GroupedTransforms.py +++ b/src/pyGroupedTransforms/GroupedTransforms.py @@ -47,7 +47,7 @@ def get_IndexSet(settings, d): elif s.mode == NFMTtools: index_set_u = s.mode.nfmt_index_set_without_zeros(s.bandwidths, s.bases) else: - ValueError(f"Unknown mode: {s.mode}") + raise ValueError(f"Unknown mode: {s.mode}") if len(s.u) == 1: index_set[s.u[0], idx : idx + nf_u] = index_set_u diff --git a/src/pyGroupedTransforms/NFMTtools.py b/src/pyGroupedTransforms/NFMTtools.py index ea56cfb..ec4bb33 100644 --- a/src/pyGroupedTransforms/NFMTtools.py +++ b/src/pyGroupedTransforms/NFMTtools.py @@ -1 +1,6 @@ -RuntimeError("NFMTtools is not implemented yet!") +def __getattr__(name): + # NFMTtools is imported unconditionally at package import time (see + # GroupedCoefficients.py), so raising here directly would break importing + # pyGroupedTransforms entirely. Raise lazily instead, only once someone + # actually tries to use the (currently unimplemented) NFMT/"mixed" system. + raise RuntimeError("NFMTtools is not implemented yet!")