Rolling median in C - Turlach implementation

后端 未结 2 814
谎友^
谎友^ 2020-11-30 07:14

Does anyone know if there is a clean implementation of the Turlach rolling median algorithm in C? I\'m having trouble porting the R version to a clean C version. See here

相关标签:
2条回答
  • 2020-11-30 07:18

    I've implemented a rolling median calculator in C here (Gist). It uses a max-median-min heap structure: The median is at heap[0] (which is at the center of a K-item array). There is a minheap starting at heap[ 1], and a maxheap (using negative indexing) at heap[-1].
    It's not exactly the same as the Turlach implementation from the R source: This one supports values being inserted on-the-fly, while the R version acts on a whole buffer at once. But I believe the time complexity is the same. And it could easily be used to implement a whole buffer version (possibly with with the addition of some code to handle R's "endrules").

    Interface:

    //Customize for your data Item type
    typedef int Item;
    #define ItemLess(a,b)  ((a)<(b))
    #define ItemMean(a,b)  (((a)+(b))/2)
    
    typedef struct Mediator_t Mediator;
    
    //creates new Mediator: to calculate `nItems` running median. 
    //mallocs single block of memory, caller must free.
    Mediator* MediatorNew(int nItems);
    
    //returns median item (or average of 2 when item count is even)
    Item MediatorMedian(Mediator* m);
    
    //Inserts item, maintains median in O(lg nItems)
    void MediatorInsert(Mediator* m, Item v)
    {
       int isNew = (m->ct < m->N);
       int p = m->pos[m->idx];
       Item old = m->data[m->idx];
       m->data[m->idx] = v;
       m->idx = (m->idx+1) % m->N;
       m->ct += isNew;
       if (p > 0)         //new item is in minHeap
       {  if (!isNew && ItemLess(old, v)) { minSortDown(m, p*2);  }
          else if (minSortUp(m, p)) { maxSortDown(m,-1); }
       }
       else if (p < 0)   //new item is in maxheap
       {  if (!isNew && ItemLess(v, old)) { maxSortDown(m, p*2); }
          else if (maxSortUp(m, p)) { minSortDown(m, 1); }
       }
       else            //new item is at median
       {  if (maxCt(m)) { maxSortDown(m,-1); }
          if (minCt(m)) { minSortDown(m, 1); }
       }
    }
    
    0 讨论(0)
  • 2020-11-30 07:28

    OpenCV has a medianBlur function that seems to do what you want. I know it's a rolling median. I can't say if it's the "Turlach rolling median" specifically. It's pretty fast though and it supports multi-threading when available.

    0 讨论(0)
提交回复
热议问题