46 template <
typename T_,
typename TI_>
51 template <
typename T_,
typename TI_>
56 inline static bool cmp (T a, T b) {
61 inline static T neutral () {
62 return -std::numeric_limits<T>::max();
67 template <
typename T_,
typename TI_>
72 inline static bool cmp (T a, T b) {
75 inline static T neutral () {
76 return std::numeric_limits<T>::max();
88 template <
class C>
inline
89 void heap_pop (
size_t k,
typename C::T * bh_val,
typename C::TI * bh_ids)
93 typename C::T val = bh_val[k];
100 if (i2 == k + 1 || C::cmp(bh_val[i1], bh_val[i2])) {
101 if (C::cmp(val, bh_val[i1]))
103 bh_val[i] = bh_val[i1];
104 bh_ids[i] = bh_ids[i1];
108 if (C::cmp(val, bh_val[i2]))
110 bh_val[i] = bh_val[i2];
111 bh_ids[i] = bh_ids[i2];
115 bh_val[i] = bh_val[k];
116 bh_ids[i] = bh_ids[k];
124 template <
class C>
inline
126 typename C::T * bh_val,
typename C::TI * bh_ids,
127 typename C::T val,
typename C::TI ids)
131 size_t i = k, i_father;
134 if (!C::cmp (val, bh_val[i_father]))
136 bh_val[i] = bh_val[i_father];
137 bh_ids[i] = bh_ids[i_father];
148 template <
typename T>
inline
149 void minheap_pop (
size_t k, T * bh_val,
long * bh_ids)
151 heap_pop<CMin<T, long> > (k, bh_val, bh_ids);
155 template <
typename T>
inline
156 void minheap_push (
size_t k, T * bh_val,
long * bh_ids, T val,
long ids)
158 heap_push<CMin<T, long> > (k, bh_val, bh_ids, val, ids);
162 template <
typename T>
inline
163 void maxheap_pop (
size_t k, T * bh_val,
long * bh_ids)
165 heap_pop<CMax<T, long> > (k, bh_val, bh_ids);
169 template <
typename T>
inline
170 void maxheap_push (
size_t k, T * bh_val,
long * bh_ids, T val,
long ids)
172 heap_push<CMax<T, long> > (k, bh_val, bh_ids, val, ids);
184 template <
class C>
inline
187 typename C::T * bh_val,
188 typename C::TI * bh_ids,
189 const typename C::T * x =
nullptr,
190 const typename C::TI * ids =
nullptr,
193 if (k0 > 0) assert (x);
196 for (
size_t i = 0; i < k0; i++)
197 heap_push<C> (i+1, bh_val, bh_ids, x[i], ids[i]);
199 for (
size_t i = 0; i < k0; i++)
200 heap_push<C> (i+1, bh_val, bh_ids, x[i], i);
203 for (
size_t i = k0; i < k; i++) {
204 bh_val[i] = C::neutral();
210 template <
typename T>
inline
211 void minheap_heapify (
212 size_t k, T * bh_val,
214 const T * x =
nullptr,
215 const long * ids =
nullptr,
218 heap_heapify< CMin<T, long> > (k, bh_val, bh_ids, x, ids, k0);
222 template <
typename T>
inline
223 void maxheap_heapify (
227 const T * x =
nullptr,
228 const long * ids =
nullptr,
231 heap_heapify< CMax<T, long> > (k, bh_val, bh_ids, x, ids, k0);
242 template <
class C>
inline
243 void heap_addn (
size_t k,
244 typename C::T * bh_val,
typename C::TI * bh_ids,
245 const typename C::T * x,
246 const typename C::TI * ids,
251 for (i = 0; i < n; i++) {
252 if (C::cmp (bh_val[0], x[i])) {
253 heap_pop<C> (k, bh_val, bh_ids);
254 heap_push<C> (k, bh_val, bh_ids, x[i], ids[i]);
258 for (i = 0; i < n; i++) {
259 if (C::cmp (bh_val[0], x[i])) {
260 heap_pop<C> (k, bh_val, bh_ids);
261 heap_push<C> (k, bh_val, bh_ids, x[i], i);
269 template <
typename T>
inline
270 void minheap_addn (
size_t k, T * bh_val,
long * bh_ids,
271 const T * x,
const long * ids,
size_t n)
273 heap_addn<CMin<T, long> > (k, bh_val, bh_ids, x, ids, n);
276 template <
typename T>
inline
277 void maxheap_addn (
size_t k, T * bh_val,
long * bh_ids,
278 const T * x,
const long * ids,
size_t n)
280 heap_addn<CMax<T, long> > (k, bh_val, bh_ids, x, ids, n);
295 template <
typename C>
inline
296 size_t heap_reorder (
size_t k,
typename C::T * bh_val,
typename C::TI * bh_ids)
300 for (i = 0, ii = 0; i < k; i++) {
302 typename C::T val = bh_val[0];
303 typename C::TI
id = bh_ids[0];
306 heap_pop<C> (k-i, bh_val, bh_ids);
307 bh_val[k-ii-1] = val;
314 memmove (bh_val, bh_val+k-ii, ii *
sizeof(*bh_val));
315 memmove (bh_ids, bh_ids+k-ii, ii *
sizeof(*bh_ids));
317 for (; ii < k; ii++) {
318 bh_val[ii] = C::neutral();
324 template <
typename T>
inline
325 size_t minheap_reorder (
size_t k, T * bh_val,
long * bh_ids)
327 return heap_reorder< CMin<T, long> > (k, bh_val, bh_ids);
330 template <
typename T>
inline
331 size_t maxheap_reorder (
size_t k, T * bh_val,
long * bh_ids)
333 return heap_reorder< CMax<T, long> > (k, bh_val, bh_ids);
348 template <
typename C>
350 typedef typename C::TI TI;
351 typedef typename C::T T;
362 TI *
get_ids (
size_t key) {
return ids + key *
k; }
375 void addn (
size_t nj,
const T *vin, TI j0 = 0,
376 size_t i0 = 0,
long ni = -1);
384 size_t nj,
const T *vin,
const TI *id_in =
nullptr,
385 long id_stride = 0,
size_t i0 = 0,
long ni = -1);
401 typedef HeapArray<CMin<float, long> > float_minheap_array_t;
402 typedef HeapArray<CMin<int, long> > int_minheap_array_t;
404 typedef HeapArray<CMax<float, long> > float_maxheap_array_t;
405 typedef HeapArray<CMax<int, long> > int_maxheap_array_t;
441 void indirect_heap_pop (
443 const typename C::T * bh_val,
444 typename C::TI * bh_ids)
447 typename C::T val = bh_val[bh_ids[k]];
454 typename C::TI id1 = bh_ids[i1], id2 = bh_ids[i2];
455 if (i2 == k + 1 || C::cmp(bh_val[id1], bh_val[id2])) {
456 if (C::cmp(val, bh_val[id1]))
461 if (C::cmp(val, bh_val[id2]))
467 bh_ids[i] = bh_ids[k];
474 void indirect_heap_push (
size_t k,
475 const typename C::T * bh_val,
typename C::TI * bh_ids,
479 typename C::T val = bh_val[id];
482 size_t i_father = i >> 1;
483 if (!C::cmp (val, bh_val[bh_ids[i_father]]))
485 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)