zmaxheap.cpp
Go to the documentation of this file.
1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4 //
5 // Copyright (C) 2013-2016, The Regents of The University of Michigan.
6 //
7 // This software was developed in the APRIL Robotics Lab under the
8 // direction of Edwin Olson, ebolson@umich.edu. This software may be
9 // available under alternative licensing terms; contact the address above.
10 //
11 // The views and conclusions contained in the software and documentation are those
12 // of the authors and should not be interpreted as representing official policies,
13 // either expressed or implied, of the Regents of The University of Michigan.
14 
15 #include "precomp.hpp"
16 #include "zmaxheap.hpp"
17 
18 
19 // 0
20 // 1 2
21 // 3 4 5 6
22 // 7 8 9 10 11 12 13 14
23 //
24 // Children of node i: 2*i+1, 2*i+2
25 // Parent of node i: (i-1) / 2
26 //
27 // Heap property: a parent is greater than (or equal to) its children.
28 
29 #define MIN_CAPACITY 16
30 namespace cv {
31 namespace aruco {
32 struct zmaxheap
33 {
34  size_t el_sz;
35 
36  int size;
37  int alloc;
38 
39  float *values;
40  char *data;
41 
42  void (*swap)(zmaxheap_t *heap, int a, int b);
43 };
44 
45 static inline void _swap_default(zmaxheap_t *heap, int a, int b)
46 {
47  float t = heap->values[a];
48  heap->values[a] = heap->values[b];
49  heap->values[b] = t;
50 
51  cv::AutoBuffer<char> tmp(heap->el_sz);
52  /* NOTE: OpenCV v<3.3 does not have .data() member for AutoBuffer */
53  memcpy(tmp, &heap->data[a*heap->el_sz], heap->el_sz);
54  memcpy(&heap->data[a*heap->el_sz], &heap->data[b*heap->el_sz], heap->el_sz);
55  memcpy(&heap->data[b*heap->el_sz], tmp, heap->el_sz);
56 }
57 
58 static inline void _swap_pointer(zmaxheap_t *heap, int a, int b)
59 {
60  float t = heap->values[a];
61  heap->values[a] = heap->values[b];
62  heap->values[b] = t;
63 
64  void **pp = (void**) heap->data;
65  void *tmp = pp[a];
66  pp[a] = pp[b];
67  pp[b] = tmp;
68 }
69 
70 
72 {
73  zmaxheap_t *heap = (zmaxheap_t*)calloc(1, sizeof(zmaxheap_t));
74  heap->el_sz = el_sz;
75 
76  heap->swap = _swap_default;
77 
78  if (el_sz == sizeof(void*))
79  heap->swap = _swap_pointer;
80 
81  return heap;
82 }
83 
85 {
86  free(heap->values);
87  free(heap->data);
88  memset(heap, 0, sizeof(zmaxheap_t));
89  free(heap);
90 }
91 
92 static void _zmaxheap_ensure_capacity(zmaxheap_t *heap, int capacity)
93 {
94  if (heap->alloc >= capacity)
95  return;
96 
97  int newcap = heap->alloc;
98 
99  while (newcap < capacity) {
100  if (newcap < MIN_CAPACITY) {
101  newcap = MIN_CAPACITY;
102  continue;
103  }
104 
105  newcap *= 2;
106  }
107 
108  heap->values = (float*)realloc(heap->values, newcap * sizeof(float));
109  heap->data = (char*)realloc(heap->data, newcap * heap->el_sz);
110  heap->alloc = newcap;
111 }
112 
113 void zmaxheap_add(zmaxheap_t *heap, void *p, float v)
114 {
115  _zmaxheap_ensure_capacity(heap, heap->size + 1);
116 
117  int idx = heap->size;
118 
119  heap->values[idx] = v;
120  memcpy(&heap->data[idx*heap->el_sz], p, heap->el_sz);
121 
122  heap->size++;
123 
124  while (idx > 0) {
125 
126  int parent = (idx - 1) / 2;
127 
128  // we're done!
129  if (heap->values[parent] >= v)
130  break;
131 
132  // else, swap and recurse upwards.
133  heap->swap(heap, idx, parent);
134  idx = parent;
135  }
136 }
137 
138 // Removes the item in the heap at the given index. Returns 1 if the
139 // item existed. 0 Indicates an invalid idx (heap is smaller than
140 // idx). This is mostly intended to be used by zmaxheap_remove_max.
141 static int zmaxheap_remove_index(zmaxheap_t *heap, int idx, void *p, float *v)
142 {
143  if (idx >= heap->size)
144  return 0;
145 
146  // copy out the requested element from the heap.
147  if (v != NULL)
148  *v = heap->values[idx];
149  if (p != NULL)
150  memcpy(p, &heap->data[idx*heap->el_sz], heap->el_sz);
151 
152  heap->size--;
153 
154  // If this element is already the last one, then there's nothing
155  // for us to do.
156  if (idx == heap->size)
157  return 1;
158 
159  // copy last element to first element. (which probably upsets
160  // the heap property).
161  heap->values[idx] = heap->values[heap->size];
162  memcpy(&heap->data[idx*heap->el_sz], &heap->data[heap->el_sz * heap->size], heap->el_sz);
163 
164  // now fix the heap. Note, as we descend, we're "pushing down"
165  // the same node the entire time. Thus, while the index of the
166  // parent might change, the parent_score doesn't.
167  int parent = idx;
168  float parent_score = heap->values[idx];
169 
170  // descend, fixing the heap.
171  while (parent < heap->size) {
172 
173  int left = 2*parent + 1;
174  int right = left + 1;
175 
176 // assert(parent_score == heap->values[parent]);
177 
178  float left_score = (left < heap->size) ? heap->values[left] : -INFINITY;
179  float right_score = (right < heap->size) ? heap->values[right] : -INFINITY;
180 
181  // put the biggest of (parent, left, right) as the parent.
182 
183  // already okay?
184  if (parent_score >= left_score && parent_score >= right_score)
185  break;
186 
187  // if we got here, then one of the children is bigger than the parent.
188  if (left_score >= right_score) {
189  CV_Assert(left < heap->size);
190  heap->swap(heap, parent, left);
191  parent = left;
192  } else {
193  // right_score can't be less than left_score if right_score is -INFINITY.
194  CV_Assert(right < heap->size);
195  heap->swap(heap, parent, right);
196  parent = right;
197  }
198  }
199 
200  return 1;
201 }
202 
203 int zmaxheap_remove_max(zmaxheap_t *heap, void *p, float *v)
204 {
205  return zmaxheap_remove_index(heap, 0, p, v);
206 }
207 
208 }}
static void _zmaxheap_ensure_capacity(zmaxheap_t *heap, int capacity)
Definition: zmaxheap.cpp:92
static void _swap_pointer(zmaxheap_t *heap, int a, int b)
Definition: zmaxheap.cpp:58
zmaxheap_t * zmaxheap_create(size_t el_sz)
Definition: zmaxheap.cpp:71
Definition: charuco.hpp:47
static int zmaxheap_remove_index(zmaxheap_t *heap, int idx, void *p, float *v)
Definition: zmaxheap.cpp:141
geometry_msgs::TransformStamped t
void(* swap)(zmaxheap_t *heap, int a, int b)
Definition: zmaxheap.cpp:42
static void _swap_default(zmaxheap_t *heap, int a, int b)
Definition: zmaxheap.cpp:45
int zmaxheap_remove_max(zmaxheap_t *heap, void *p, float *v)
Definition: zmaxheap.cpp:203
void zmaxheap_add(zmaxheap_t *heap, void *p, float v)
Definition: zmaxheap.cpp:113
void zmaxheap_destroy(zmaxheap_t *heap)
Definition: zmaxheap.cpp:84
#define MIN_CAPACITY
Definition: zmaxheap.cpp:29


aruco_pose
Author(s): Oleg Kalachev
autogenerated on Mon Feb 28 2022 22:08:24