48 template <
typename T_,
typename TI_>
53 template <
typename T_,
typename TI_>
58 inline static bool cmp (T a, T b) {
63 inline static T neutral () {
64 return -std::numeric_limits<T>::max();
69 template <
typename T_,
typename TI_>
74 inline static bool cmp (T a, T b) {
77 inline static T neutral () {
78 return std::numeric_limits<T>::max();
90 template <
class C>
inline
91 void heap_pop (
size_t k,
typename C::T * bh_val,
typename C::TI * bh_ids)
95 typename C::T val = bh_val[k];
102 if (i2 == k + 1 || C::cmp(bh_val[i1], bh_val[i2])) {
103 if (C::cmp(val, bh_val[i1]))
105 bh_val[i] = bh_val[i1];
106 bh_ids[i] = bh_ids[i1];
110 if (C::cmp(val, bh_val[i2]))
112 bh_val[i] = bh_val[i2];
113 bh_ids[i] = bh_ids[i2];
117 bh_val[i] = bh_val[k];
118 bh_ids[i] = bh_ids[k];
126 template <
class C>
inline
128 typename C::T * bh_val,
typename C::TI * bh_ids,
129 typename C::T val,
typename C::TI ids)
133 size_t i = k, i_father;
136 if (!C::cmp (val, bh_val[i_father]))
138 bh_val[i] = bh_val[i_father];
139 bh_ids[i] = bh_ids[i_father];
150 template <
typename T>
inline
151 void minheap_pop (
size_t k, T * bh_val,
long * bh_ids)
153 heap_pop<CMin<T, long> > (k, bh_val, bh_ids);
157 template <
typename T>
inline
158 void minheap_push (
size_t k, T * bh_val,
long * bh_ids, T val,
long ids)
160 heap_push<CMin<T, long> > (k, bh_val, bh_ids, val, ids);
164 template <
typename T>
inline
165 void maxheap_pop (
size_t k, T * bh_val,
long * bh_ids)
167 heap_pop<CMax<T, long> > (k, bh_val, bh_ids);
171 template <
typename T>
inline
172 void maxheap_push (
size_t k, T * bh_val,
long * bh_ids, T val,
long ids)
174 heap_push<CMax<T, long> > (k, bh_val, bh_ids, val, ids);
186 template <
class C>
inline
189 typename C::T * bh_val,
190 typename C::TI * bh_ids,
191 const typename C::T * x =
nullptr,
192 const typename C::TI * ids =
nullptr,
195 if (k0 > 0) assert (x);
198 for (
size_t i = 0; i < k0; i++)
199 heap_push<C> (i+1, bh_val, bh_ids, x[i], ids[i]);
201 for (
size_t i = 0; i < k0; i++)
202 heap_push<C> (i+1, bh_val, bh_ids, x[i], i);
205 for (
size_t i = k0; i < k; i++) {
206 bh_val[i] = C::neutral();
212 template <
typename T>
inline
213 void minheap_heapify (
214 size_t k, T * bh_val,
216 const T * x =
nullptr,
217 const long * ids =
nullptr,
220 heap_heapify< CMin<T, long> > (k, bh_val, bh_ids, x, ids, k0);
224 template <
typename T>
inline
225 void maxheap_heapify (
229 const T * x =
nullptr,
230 const long * ids =
nullptr,
233 heap_heapify< CMax<T, long> > (k, bh_val, bh_ids, x, ids, k0);
244 template <
class C>
inline
245 void heap_addn (
size_t k,
246 typename C::T * bh_val,
typename C::TI * bh_ids,
247 const typename C::T * x,
248 const typename C::TI * ids,
253 for (i = 0; i < n; i++) {
254 if (C::cmp (bh_val[0], x[i])) {
255 heap_pop<C> (k, bh_val, bh_ids);
256 heap_push<C> (k, bh_val, bh_ids, x[i], ids[i]);
260 for (i = 0; i < n; i++) {
261 if (C::cmp (bh_val[0], x[i])) {
262 heap_pop<C> (k, bh_val, bh_ids);
263 heap_push<C> (k, bh_val, bh_ids, x[i], i);
271 template <
typename T>
inline
272 void minheap_addn (
size_t k, T * bh_val,
long * bh_ids,
273 const T * x,
const long * ids,
size_t n)
275 heap_addn<CMin<T, long> > (k, bh_val, bh_ids, x, ids, n);
278 template <
typename T>
inline
279 void maxheap_addn (
size_t k, T * bh_val,
long * bh_ids,
280 const T * x,
const long * ids,
size_t n)
282 heap_addn<CMax<T, long> > (k, bh_val, bh_ids, x, ids, n);
297 template <
typename C>
inline
298 size_t heap_reorder (
size_t k,
typename C::T * bh_val,
typename C::TI * bh_ids)
302 for (i = 0, ii = 0; i < k; i++) {
304 typename C::T val = bh_val[0];
305 typename C::TI
id = bh_ids[0];
308 heap_pop<C> (k-i, bh_val, bh_ids);
309 bh_val[k-ii-1] = val;
316 memmove (bh_val, bh_val+k-ii, ii *
sizeof(*bh_val));
317 memmove (bh_ids, bh_ids+k-ii, ii *
sizeof(*bh_ids));
319 for (; ii < k; ii++) {
320 bh_val[ii] = C::neutral();
326 template <
typename T>
inline
327 size_t minheap_reorder (
size_t k, T * bh_val,
long * bh_ids)
329 return heap_reorder< CMin<T, long> > (k, bh_val, bh_ids);
332 template <
typename T>
inline
333 size_t maxheap_reorder (
size_t k, T * bh_val,
long * bh_ids)
335 return heap_reorder< CMax<T, long> > (k, bh_val, bh_ids);
350 template <
typename C>
352 typedef typename C::TI TI;
353 typedef typename C::T T;
364 TI *
get_ids (
size_t key) {
return ids + key *
k; }
377 void addn (
size_t nj,
const T *vin, TI j0 = 0,
378 size_t i0 = 0,
long ni = -1);
386 size_t nj,
const T *vin,
const TI *id_in =
nullptr,
387 long id_stride = 0,
size_t i0 = 0,
long ni = -1);
403 typedef HeapArray<CMin<float, long> > float_minheap_array_t;
404 typedef HeapArray<CMin<int, long> > int_minheap_array_t;
406 typedef HeapArray<CMax<float, long> > float_maxheap_array_t;
407 typedef HeapArray<CMax<int, long> > int_maxheap_array_t;
443 void indirect_heap_pop (
445 const typename C::T * bh_val,
446 typename C::TI * bh_ids)
449 typename C::T val = bh_val[bh_ids[k]];
456 typename C::TI id1 = bh_ids[i1], id2 = bh_ids[i2];
457 if (i2 == k + 1 || C::cmp(bh_val[id1], bh_val[id2])) {
458 if (C::cmp(val, bh_val[id1]))
463 if (C::cmp(val, bh_val[id2]))
469 bh_ids[i] = bh_ids[k];
476 void indirect_heap_push (
size_t k,
477 const typename C::T * bh_val,
typename C::TI * bh_ids,
481 typename C::T val = bh_val[id];
484 size_t i_father = i >> 1;
485 if (!C::cmp (val, bh_val[bh_ids[i_father]]))
487 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)