# Fast inner loop for DBSCAN. # Author: Lars Buitinck # License: 3-clause BSD from libcpp.vector cimport vector from ..utils._typedefs cimport uint8_t, intp_t def dbscan_inner(const uint8_t[::1] is_core, object[:] neighborhoods, intp_t[::1] labels): cdef intp_t i, label_num = 0, v cdef intp_t[:] neighb cdef vector[intp_t] stack for i in range(labels.shape[0]): if labels[i] != -1 or not is_core[i]: continue # Depth-first search starting from i, ending at the non-core points. # This is very similar to the classic algorithm for computing connected # components, the difference being that we label non-core points as # part of a cluster (component), but don't expand their neighborhoods. while True: if labels[i] == -1: labels[i] = label_num if is_core[i]: neighb = neighborhoods[i] for i in range(neighb.shape[0]): v = neighb[i] if labels[v] == -1: stack.push_back(v) if stack.size() == 0: break i = stack.back() stack.pop_back() label_num += 1