Static Value-Flow Analysis
Loading...
Searching...
No Matches
fastcluster_R_dm.cpp.inc
Go to the documentation of this file.
1//
2// Excerpt from fastcluster_R.cpp
3//
4// Copyright: Daniel Müllner, 2011 <http://danifold.net>
5//
6
7struct pos_node {
8 t_index pos;
9 int node;
10};
11
12void order_nodes(const int N, const int * const merge, const t_index * const node_size, int * const order) {
13 /* Parameters:
14 N : number of data points
15 merge : (N-1)×2 array which specifies the node indices which are
16 merged in each step of the clustering procedure.
17 Negative entries -1...-N point to singleton nodes, while
18 positive entries 1...(N-1) point to nodes which are themselves
19 parents of other nodes.
20 node_size : array of node sizes - makes it easier
21 order : output array of size N
22
23 Runtime: Θ(N)
24 */
25 auto_array_ptr<pos_node> queue(N/2);
26
27 int parent;
28 int child;
29 t_index pos = 0;
30
31 queue[0].pos = 0;
32 queue[0].node = N-2;
33 t_index idx = 1;
34
35 do {
36 --idx;
37 pos = queue[idx].pos;
38 parent = queue[idx].node;
39
40 // First child
41 child = merge[parent];
42 if (child<0) { // singleton node, write this into the 'order' array.
43 order[pos] = -child;
44 ++pos;
45 }
46 else { /* compound node: put it on top of the queue and decompose it
47 in a later iteration. */
48 queue[idx].pos = pos;
49 queue[idx].node = child-1; // convert index-1 based to index-0 based
50 ++idx;
51 pos += node_size[child-1];
52 }
53 // Second child
54 child = merge[parent+N-1];
55 if (child<0) {
56 order[pos] = -child;
57 }
58 else {
59 queue[idx].pos = pos;
60 queue[idx].node = child-1;
61 ++idx;
62 }
63 } while (idx>0);
64}
65
66#define size_(r_) ( ((r_<N) ? 1 : node_size[r_-N]) )
67
68template <const bool sorted>
69void generate_R_dendrogram(int * const merge, double * const height, int * const order, cluster_result & Z2, const int N) {
70 // The array "nodes" is a union-find data structure for the cluster
71 // identites (only needed for unsorted cluster_result input).
72 union_find nodes(sorted ? 0 : N);
73 if (!sorted) {
74 std::stable_sort(Z2[0], Z2[N-1]);
75 }
76
77 t_index node1, node2;
78 auto_array_ptr<t_index> node_size(N-1);
79
80 for (t_index i=0; i<N-1; ++i) {
81 // Get two data points whose clusters are merged in step i.
82 // Find the cluster identifiers for these points.
83 if (sorted) {
84 node1 = Z2[i]->node1;
85 node2 = Z2[i]->node2;
86 }
87 else {
88 node1 = nodes.Find(Z2[i]->node1);
89 node2 = nodes.Find(Z2[i]->node2);
90 // Merge the nodes in the union-find data structure by making them
91 // children of a new node.
92 nodes.Union(node1, node2);
93 }
94 // Sort the nodes in the output array.
95 if (node1>node2) {
96 t_index tmp = node1;
97 node1 = node2;
98 node2 = tmp;
99 }
100 /* Conversion between labeling conventions.
101 Input: singleton nodes 0,...,N-1
102 compound nodes N,...,2N-2
103 Output: singleton nodes -1,...,-N
104 compound nodes 1,...,N
105 */
106 merge[i] = (node1<N) ? -static_cast<int>(node1)-1
107 : static_cast<int>(node1)-N+1;
108 merge[i+N-1] = (node2<N) ? -static_cast<int>(node2)-1
109 : static_cast<int>(node2)-N+1;
110 height[i] = Z2[i]->dist;
111 node_size[i] = size_(node1) + size_(node2);
112 }
113
114 order_nodes(N, merge, node_size, order);
115}
cJSON * child
Definition cJSON.cpp:2723
iter_range< typename GenericGraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)