Static Value-Flow Analysis
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 
7 struct pos_node {
8  t_index pos;
9  int node;
10 };
11 
12 void 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 
68 template <const bool sorted>
69 void 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)
Definition: GraphTraits.h:111