diff --git a/.github/workflows/test_and_deploy.yml b/.github/workflows/test_and_deploy.yml index 9395dc3..7754c54 100644 --- a/.github/workflows/test_and_deploy.yml +++ b/.github/workflows/test_and_deploy.yml @@ -22,8 +22,8 @@ jobs: runs-on: ${{ matrix.platform }} strategy: matrix: - platform: [ubuntu-latest, macos-latest] # windows-latest - python-version: ["3.8", "3.9", "3.10", "3.11"] + platform: [ubuntu-latest, macos-latest] # , windows-latest] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v2 diff --git a/setup.py b/setup.py index 365e0e4..41adc6e 100644 --- a/setup.py +++ b/setup.py @@ -61,10 +61,10 @@ def setup_package(): use_scm_version={'write_to': 'src/pyift/_version.py'}, setup_requires=build_requires, install_requires=[ - 'numpy', + 'numpy>=2', 'scipy', ], - python_requires=">=3.8", + python_requires=">=3.9", package_dir={'': 'src'}, ext_modules=exts, classifiers=[ @@ -76,9 +76,11 @@ def setup_package(): 'Programming Language :: C', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Programming Language :: Python :: 3.13', 'Topic :: Scientific/Engineering', 'Topic :: Software Development :: Libraries :: Python Modules', ], diff --git a/src/libift/tags b/src/libift/tags deleted file mode 100644 index 592b21e..0000000 --- a/src/libift/tags +++ /dev/null @@ -1,39 +0,0 @@ -Adjacency adjacency.h /^} Adjacency;$/ -Coord core.h /^} Coord;$/ -Heap heap.h /^} Heap;$/ -QCircularQueue queue.h /^} QCircularQueue;$/ -QLinkedList queue.h /^} QLinkedList;$/ -QNode queue.h /^} QNode;$/ -Queue queue.h /^} Queue;$/ -Set set.h /^} Set;$/ -_createAdjacency adjacency.c /^Adjacency *_createAdjacency(int size)$/ -_dad heap.c /^inline int _dad(int i)$/ -_goDownHeapPosition heap.c /^void _goDownHeapPosition(Heap *heap, int pos)$/ -_goUpHeapPosition heap.c /^void _goUpHeapPosition(Heap *heap, int pos)$/ -_greater heap.c /^inline bool _greater(Heap *heap, int i, int j)$/ -_leftSon heap.c /^inline int _leftSon(int i)$/ -_lower heap.c /^inline bool _lower(Heap *heap, int i, int j)$/ -_rightSon heap.c /^inline int _rightSon(int i)$/ -_swap heap.c /^inline void _swap(Heap *heap, int i, int j)$/ -argSortFloat sort.c /^void argSortFloat(float *values, int *indices, int/ -circularAdjacency adjacency.c /^Adjacency *circularAdjacency(float radii)$/ -createHeap heap.c /^Heap *createHeap(int size, double *values)$/ -createQueue queue.c /^Queue *createQueue(int max_value, long n_elem, int/ -destroyAdjacency adjacency.c /^void destroyAdjacency(Adjacency **adj_address)$/ -destroyHeap heap.c /^void destroyHeap(Heap **heap_address)$/ -destroySet set.c /^void destroySet(Set **head_address)$/ -goDownHeap heap.c /^void goDownHeap(Heap *heap, int index)$/ -goUpHeap heap.c /^void goUpHeap(Heap *heap, int index)$/ -insertHeap heap.c /^bool insertHeap(Heap *heap, int index)$/ -leftSide adjacency.c /^Adjacency *leftSide(Adjacency *adj, double shift)$/ -lengthSet set.c /^int lengthSet(const Set *head)$/ -nodeColor heap.h /^} nodeColor;$/ -popHeap heap.c /^int popHeap(Heap *heap)$/ -pushSet set.c /^void pushSet(Set **head_address, int value)$/ -removalPolicy heap.h /^} removalPolicy;$/ -removeHeap heap.c /^bool removeHeap(Heap *heap, int index)$/ -resetHeap heap.c /^void resetHeap(Heap *heap)$/ -reverseSet set.c /^void reverseSet(Set **head_address)$/ -rightSide adjacency.c /^Adjacency *rightSide(Adjacency *adj, double shift)/ -sortOrder sort.h /^} sortOrder;$/ -sphericAdjacency adjacency.c /^Adjacency *sphericAdjacency(float radii)$/ diff --git a/src/pyift/shortestpath.py b/src/pyift/shortestpath.py index 3168a72..8962580 100644 --- a/src/pyift/shortestpath.py +++ b/src/pyift/shortestpath.py @@ -4,8 +4,12 @@ from typing import Optional, Tuple, Dict, Union -def seed_competition(seeds: np.ndarray, image: Optional[np.ndarray] = None, graph: Optional[sparse.csr_matrix] = None, - image_3d: bool = False) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: +def seed_competition( + seeds: np.ndarray, + image: Optional[np.ndarray] = None, + graph: Optional[Union[sparse.csr_matrix, sparse.csr_array]] = None, + image_3d: bool = False, +) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: """ Performs the shortest path classification from the `seeds` nodes using the image foresting transform algorithm [1]_. @@ -102,8 +106,8 @@ def seed_competition(seeds: np.ndarray, image: Optional[np.ndarray] = None, grap return _pyift.seed_competition_grid(image, seeds) # graph is provided - if not isinstance(graph, sparse.csr_matrix): - raise TypeError('`graph` must be a `csr_matrix`.') + if not isinstance(graph, (sparse.csr_matrix, sparse.csr_array)): + raise TypeError('`graph` must be a `csr_matrix` or `csr_array`.') if graph.shape[0] != graph.shape[1]: raise ValueError('`graph` must be a square adjacency matrix, current shape %r.' % graph.shape) diff --git a/src/pyift_c_ext/_livewire.h b/src/pyift_c_ext/_livewire.h index 73166c5..0e4ab71 100644 --- a/src/pyift_c_ext/_livewire.h +++ b/src/pyift_c_ext/_livewire.h @@ -12,6 +12,7 @@ extern "C" { #define NO_IMPORT_ARRAY #define PY_ARRAY_UNIQUE_SYMBOL PYIFT_ARRAY_API #include "numpy/arrayobject.h" +#include "numpy/npy_math.h" typedef enum { diff --git a/src/pyift_c_ext/_shortestpath.h b/src/pyift_c_ext/_shortestpath.h index e44cced..cc84eb7 100644 --- a/src/pyift_c_ext/_shortestpath.h +++ b/src/pyift_c_ext/_shortestpath.h @@ -13,6 +13,7 @@ extern "C" { #define NO_IMPORT_ARRAY #define PY_ARRAY_UNIQUE_SYMBOL PYIFT_ARRAY_API #include "numpy/arrayobject.h" +#include "numpy/npy_math.h" PyObject *_seedCompetitionGrid(PyArrayObject *image, PyArrayObject *seeds);