@@ -17,7 +17,8 @@ import bioimage_cpp as bic
1717
1818Graph functionality is under ` bic.graph ` , segmentation functionality is under
1919` bic.segmentation ` , ground-truth comparison functionality is under
20- ` bic.ground_truth ` , and small utility functions are under ` bic.utils ` .
20+ ` bic.ground_truth ` , small utility functions are under ` bic.utils ` , and
21+ reusable data structures (e.g. union-find) are under ` bic.util ` .
2122
2223## Blocking
2324
@@ -1094,6 +1095,65 @@ partition metrics and a semantic-label match fraction so the deviation is
10941095measurable. The bioimage-cpp partitions match an independent Python
10951096reference implementation of the algorithm.
10961097
1098+ ## Union-Find
1099+
1100+ Nifty exposes a disjoint-set / union-find structure as ` nifty.ufd.ufd ` .
1101+ ` bioimage-cpp ` provides the same primitive under ` bic.util ` .
1102+
1103+ Nifty:
1104+
1105+ ``` python
1106+ import nifty.ufd as nufd
1107+ import numpy as np
1108+
1109+ uf = nufd.ufd(5 )
1110+ uf.merge(0 , 1 )
1111+ uf.merge(np.array([[2 , 3 ], [3 , 4 ]], dtype = " uint64" ))
1112+ roots = uf.find(np.array([0 , 1 , 2 , 3 , 4 ], dtype = " uint64" ))
1113+ labels = uf.elementLabeling()
1114+ ```
1115+
1116+ bioimage-cpp:
1117+
1118+ ``` python
1119+ import bioimage_cpp as bic
1120+ import numpy as np
1121+
1122+ uf = bic.util.UnionFind(5 )
1123+ uf.merge(0 , 1 )
1124+ uf.merge(np.array([[2 , 3 ], [3 , 4 ]], dtype = np.uint64))
1125+ roots = uf.find(np.array([0 , 1 , 2 , 3 , 4 ], dtype = np.uint64))
1126+ labels = uf.element_labeling()
1127+ ```
1128+
1129+ Method mapping:
1130+
1131+ | nifty-style name | bioimage-cpp name |
1132+ | --- | --- |
1133+ | ` find(node) ` / ` find(array) ` | ` find(node) ` / ` find(array) ` |
1134+ | ` merge(u, v) ` / ` merge(array) ` | ` merge(u, v) ` / ` merge(array) ` |
1135+ | ` elementLabeling ` | ` element_labeling ` |
1136+ | ` numberOfElements ` | ` size ` (property) |
1137+
1138+ Notes:
1139+
1140+ - The constructor takes a single ` size ` argument; all elements start as
1141+ singletons.
1142+ - Scalar ` find ` /` merge ` accept Python integers and return Python integers.
1143+ - Bulk ` find(nodes) ` accepts a 1D ` uint64 ` array and returns a 1D ` uint64 `
1144+ array of roots of the same length.
1145+ - Bulk ` merge(edges) ` accepts an ` (N, 2) ` ` uint64 ` array of node-pair edges
1146+ and applies the merges in row order.
1147+ - ` element_labeling() ` returns a ` uint64 ` array of length ` size ` , each entry
1148+ the (path-compressed) root of that element. Use this when you want the
1149+ final labeling as one array rather than via repeated ` find ` calls.
1150+ - ` merge_to(stable, removed) ` is also available: it forces ` stable ` 's root
1151+ to survive the union regardless of rank.
1152+ - ` reset(n) ` reinitialises the structure to ` n ` singletons, reusing
1153+ capacity where possible.
1154+ - The GIL is released around bulk operations, so multiple threads can run
1155+ bulk merges on independent ` UnionFind ` instances in parallel.
1156+
10971157## Dictionary-Based Relabeling
10981158
10991159If you used a small helper to apply a dictionary to an integer label array, use
0 commit comments