47 template <
typename T_,
typename TI_>
52 template <
typename T_,
typename TI_>
57 inline static bool cmp (T a, T b) {
62 inline static T neutral () {
63 return -std::numeric_limits<T>::max();
68 template <
typename T_,
typename TI_>
73 inline static bool cmp (T a, T b) {
76 inline static T neutral () {
77 return std::numeric_limits<T>::max();
89 template <
class C>
inline
90 void heap_pop (
size_t k,
typename C::T * bh_val,
typename C::TI * bh_ids)
94 typename C::T val = bh_val[k];
101 if (i2 == k + 1 || C::cmp(bh_val[i1], bh_val[i2])) {
102 if (C::cmp(val, bh_val[i1]))
104 bh_val[i] = bh_val[i1];
105 bh_ids[i] = bh_ids[i1];
109 if (C::cmp(val, bh_val[i2]))
111 bh_val[i] = bh_val[i2];
112 bh_ids[i] = bh_ids[i2];
116 bh_val[i] = bh_val[k];
117 bh_ids[i] = bh_ids[k];
125 template <
class C>
inline
127 typename C::T * bh_val,
typename C::TI * bh_ids,
128 typename C::T val,
typename C::TI ids)
132 size_t i = k, i_father;
135 if (!C::cmp (val, bh_val[i_father]))
137 bh_val[i] = bh_val[i_father];
138 bh_ids[i] = bh_ids[i_father];
149 template <
typename T>
inline
150 void minheap_pop (
size_t k, T * bh_val,
long * bh_ids)
152 heap_pop<CMin<T, long> > (k, bh_val, bh_ids);
156 template <
typename T>
inline
157 void minheap_push (
size_t k, T * bh_val,
long * bh_ids, T val,
long ids)
159 heap_push<CMin<T, long> > (k, bh_val, bh_ids, val, ids);
163 template <
typename T>
inline
164 void maxheap_pop (
size_t k, T * bh_val,
long * bh_ids)
166 heap_pop<CMax<T, long> > (k, bh_val, bh_ids);
170 template <
typename T>
inline
171 void maxheap_push (
size_t k, T * bh_val,
long * bh_ids, T val,
long ids)
173 heap_push<CMax<T, long> > (k, bh_val, bh_ids, val, ids);
185 template <
class C>
inline
188 typename C::T * bh_val,
189 typename C::TI * bh_ids,
190 const typename C::T * x =
nullptr,
191 const typename C::TI * ids =
nullptr,
194 if (k0 > 0) assert (x);
197 for (
size_t i = 0; i < k0; i++)
198 heap_push<C> (i+1, bh_val, bh_ids, x[i], ids[i]);
200 for (
size_t i = 0; i < k0; i++)
201 heap_push<C> (i+1, bh_val, bh_ids, x[i], i);
204 for (
size_t i = k0; i < k; i++) {
205 bh_val[i] = C::neutral();
211 template <
typename T>
inline
212 void minheap_heapify (
213 size_t k, T * bh_val,
215 const T * x =
nullptr,
216 const long * ids =
nullptr,
219 heap_heapify< CMin<T, long> > (k, bh_val, bh_ids, x, ids, k0);
223 template <
typename T>
inline
224 void maxheap_heapify (
228 const T * x =
nullptr,
229 const long * ids =
nullptr,
232 heap_heapify< CMax<T, long> > (k, bh_val, bh_ids, x, ids, k0);
243 template <
class C>
inline
244 void heap_addn (
size_t k,
245 typename C::T * bh_val,
typename C::TI * bh_ids,
246 const typename C::T * x,
247 const typename C::TI * ids,
252 for (i = 0; i < n; i++) {
253 if (C::cmp (bh_val[0], x[i])) {
254 heap_pop<C> (k, bh_val, bh_ids);
255 heap_push<C> (k, bh_val, bh_ids, x[i], ids[i]);
259 for (i = 0; i < n; i++) {
260 if (C::cmp (bh_val[0], x[i])) {
261 heap_pop<C> (k, bh_val, bh_ids);
262 heap_push<C> (k, bh_val, bh_ids, x[i], i);
270 template <
typename T>
inline
271 void minheap_addn (
size_t k, T * bh_val,
long * bh_ids,
272 const T * x,
const long * ids,
size_t n)
274 heap_addn<CMin<T, long> > (k, bh_val, bh_ids, x, ids, n);
277 template <
typename T>
inline
278 void maxheap_addn (
size_t k, T * bh_val,
long * bh_ids,
279 const T * x,
const long * ids,
size_t n)
281 heap_addn<CMax<T, long> > (k, bh_val, bh_ids, x, ids, n);
296 template <
typename C>
inline
297 size_t heap_reorder (
size_t k,
typename C::T * bh_val,
typename C::TI * bh_ids)
301 for (i = 0, ii = 0; i < k; i++) {
303 typename C::T val = bh_val[0];
304 typename C::TI
id = bh_ids[0];
307 heap_pop<C> (k-i, bh_val, bh_ids);
308 bh_val[k-ii-1] = val;
315 memmove (bh_val, bh_val+k-ii, ii *
sizeof(*bh_val));
316 memmove (bh_ids, bh_ids+k-ii, ii *
sizeof(*bh_ids));
318 for (; ii < k; ii++) {
319 bh_val[ii] = C::neutral();
325 template <
typename T>
inline
326 size_t minheap_reorder (
size_t k, T * bh_val,
long * bh_ids)
328 return heap_reorder< CMin<T, long> > (k, bh_val, bh_ids);
331 template <
typename T>
inline
332 size_t maxheap_reorder (
size_t k, T * bh_val,
long * bh_ids)
334 return heap_reorder< CMax<T, long> > (k, bh_val, bh_ids);
349 template <
typename C>
351 typedef typename C::TI TI;
352 typedef typename C::T T;
363 TI *
get_ids (
size_t key) {
return ids + key *
k; }
376 void addn (
size_t nj,
const T *vin, TI j0 = 0,
377 size_t i0 = 0,
long ni = -1);
385 size_t nj,
const T *vin,
const TI *id_in =
nullptr,
386 long id_stride = 0,
size_t i0 = 0,
long ni = -1);
402 typedef HeapArray<CMin<float, long> > float_minheap_array_t;
403 typedef HeapArray<CMin<int, long> > int_minheap_array_t;
405 typedef HeapArray<CMax<float, long> > float_maxheap_array_t;
406 typedef HeapArray<CMax<int, long> > int_maxheap_array_t;
442 void indirect_heap_pop (
444 const typename C::T * bh_val,
445 typename C::TI * bh_ids)
448 typename C::T val = bh_val[bh_ids[k]];
455 typename C::TI id1 = bh_ids[i1], id2 = bh_ids[i2];
456 if (i2 == k + 1 || C::cmp(bh_val[id1], bh_val[id2])) {
457 if (C::cmp(val, bh_val[id1]))
462 if (C::cmp(val, bh_val[id2]))
468 bh_ids[i] = bh_ids[k];
475 void indirect_heap_push (
size_t k,
476 const typename C::T * bh_val,
typename C::TI * bh_ids,
480 typename C::T val = bh_val[id];
483 size_t i_father = i >> 1;
484 if (!C::cmp (val, bh_val[bh_ids[i_father]]))
486 bh_ids[i] = bh_ids[i_father];
T * get_val(size_t key)
Return the list of values for a heap.
void heap_pop(size_t k, typename C::T *bh_val, typename C::TI *bh_ids)
size_t k
allocated size per heap
void reorder()
reorder all the heaps
void per_line_extrema(T *vals_out, TI *idx_out) const
TI * ids
identifiers (size nh * k)
void addn_with_ids(size_t nj, const T *vin, const TI *id_in=nullptr, long id_stride=0, size_t i0=0, long ni=-1)
void heapify()
prepare all the heaps before adding
TI * get_ids(size_t key)
Correspponding identifiers.
T * val
values (distances or similarities), size nh * k
void heap_push(size_t k, typename C::T *bh_val, typename C::TI *bh_ids, typename C::T val, typename C::TI ids)
void addn(size_t nj, const T *vin, TI j0=0, size_t i0=0, long ni=-1)