CofeehousePy/deps/scikit-image/skimage/future/graph/_ncut_cy.pyx

79 lines
2.0 KiB
Cython

# cython: cdivision=True
# cython: boundscheck=False
# cython: nonecheck=False
# cython: wraparound=False
cimport numpy as cnp
import numpy as np
cnp.import_array()
def argmin2(cnp.double_t[:] array):
"""Return the index of the 2nd smallest value in an array.
Parameters
----------
array : array
The array to process.
Returns
-------
min_idx2 : int
The index of the second smallest value.
"""
cdef cnp.float64_t min1 = np.inf
cdef cnp.float64_t min2 = np.inf
cdef Py_ssize_t min_idx1 = 0
cdef Py_ssize_t min_idx2 = 0
cdef Py_ssize_t i = 0
cdef Py_ssize_t n = array.shape[0]
for i in range(n):
x = array[i]
if x < min1:
min2 = min1
min_idx2 = min_idx1
min1 = x
min_idx1 = i
elif x > min1 and x < min2:
min2 = x
min_idx2 = i
i += 1
return min_idx2
def cut_cost(cut, W):
"""Return the total weight of crossing edges in a bi-partition.
Parameters
----------
cut : array
A array of booleans. Elements set to `True` belong to one
set.
W : array
The weight matrix of the graph.
Returns
-------
cost : float
The total weight of crossing edges.
"""
cdef cnp.ndarray[cnp.uint8_t, cast = True] cut_mask = np.array(cut)
cdef Py_ssize_t num_rows, num_cols
cdef cnp.int32_t row, col
cdef cnp.int32_t[:] indices = W.indices
cdef cnp.int32_t[:] indptr = W.indptr
cdef cnp.double_t[:] data = W.data.astype(np.double)
cdef cnp.int32_t row_index
cdef cnp.double_t cost = 0
num_rows = W.shape[0]
num_cols = W.shape[1]
for col in range(num_cols):
for row_index in range(indptr[col], indptr[col + 1]):
row = indices[row_index]
if cut_mask[row] != cut_mask[col]:
cost += data[row_index]
return cost * 0.5