diff --git a/.github/workflows/ci_checks.yml b/.github/workflows/ci_checks.yml index c8094b42..4baaf268 100644 --- a/.github/workflows/ci_checks.yml +++ b/.github/workflows/ci_checks.yml @@ -26,7 +26,7 @@ jobs: python -m pip install --upgrade pip python -m pip install flake8 python -m pip install -r requirements_dev.txt - python setup.py develop + pip install -e . - name: Test with pytest run: | py.test --doctest-modules --cov-report=xml --cov=sknetwork diff --git a/.github/workflows/wheels_build.yml b/.github/workflows/wheels_build.yml index 486fb489..8230b784 100644 --- a/.github/workflows/wheels_build.yml +++ b/.github/workflows/wheels_build.yml @@ -23,6 +23,8 @@ jobs: CIBW_SKIP: cp*-musllinux* *-win32 CIBW_ARCHS_MACOS: x86_64 arm64 CIBW_BUILD_VERBOSITY: 3 + CIBW_MANYLINUX_AARCH64_IMAGE: manylinux_2_28 + CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28 CIBW_BEFORE_BUILD: "pip install -r requirements_dev.txt && pip install ." CIBW_BUILD: cp310-* cp311-* cp312-* cp313-* cp314-* diff --git a/sknetwork/clustering/leiden.py b/sknetwork/clustering/leiden.py index 36b918f0..8d8e8412 100644 --- a/sknetwork/clustering/leiden.py +++ b/sknetwork/clustering/leiden.py @@ -163,7 +163,7 @@ def _optimize_refine(self, labels, adjacency, out_weights, in_weights): labels_refined = np.arange(len(labels)).astype(np.int32) return optimize_refine_core(labels, labels_refined, indices, indptr, data, out_weights, in_weights, out_cluster_weights, in_cluster_weights, cluster_weights, self_loops, - self.resolution) + self.resolution, self.tol_optimization) @staticmethod def _aggregate_refine(labels, labels_refined, adjacency, out_weights, in_weights): diff --git a/sknetwork/clustering/leiden_core.pyx b/sknetwork/clustering/leiden_core.pyx index e8814569..03d87fe0 100644 --- a/sknetwork/clustering/leiden_core.pyx +++ b/sknetwork/clustering/leiden_core.pyx @@ -13,7 +13,8 @@ ctypedef fused int_or_long: @cython.wraparound(False) def optimize_refine_core(int_or_long[:] labels, int_or_long[:] labels_refined, int_or_long[:] indices, int_or_long[:] indptr, float[:] data, float[:] out_weights, float[:] in_weights, float[:] out_cluster_weights, - float[:] in_cluster_weights, float[:] cluster_weights, float[:] self_loops, float resolution): # pragma: no cover + float[:] in_cluster_weights, float[:] cluster_weights, float[:] self_loops, float resolution, + float tol_optimization): # pragma: no cover """Refine clusters while maximizing modularity. Parameters @@ -42,6 +43,8 @@ def optimize_refine_core(int_or_long[:] labels, int_or_long[:] labels_refined, i Weights of self loops. resolution : Resolution parameter (positive). + tol_optimization : + Minimum increase in modularity to enter a new optimization pass. Returns ------- @@ -102,7 +105,7 @@ def optimize_refine_core(int_or_long[:] labels, int_or_long[:] labels_refined, i delta_local -= resolution * out_weight * in_cluster_weights[label_target] delta_local -= resolution * in_weight * out_cluster_weights[label_target] delta_local -= delta - if delta_local > 0: + if delta_local > tol_optimization: label_target_set.insert(label_target) cluster_weights[label_target] = 0