Struct median::heap::Filter[][src]

pub struct Filter<T> { /* fields omitted */ }

An implementation of a median filter with linear complexity.

While the common naïve implementation of a median filter has a worst-case complexity of O(n^2) (due to having to sort the sliding window) the use of a combination of linked list and ring buffer allows for a worst-case complexity of O(n).

Implementations

impl<T> Filter<T> where
    T: Clone + PartialOrd
[src]

pub fn new(size: usize) -> Self[src]

Creates a new median filter with a given window size.

pub fn len(&self) -> usize[src]

Returns the window size of the filter.

pub fn is_empty(&self) -> usize[src]

Returns true if the filter has a length of 0.

pub fn median(&self) -> T[src]

Returns the filter buffer’s current median value, panicking if empty.

pub fn min(&self) -> T[src]

Returns the filter buffer’s current min value, panicking if empty.

pub fn max(&self) -> T[src]

Returns the filter buffer’s current max value, panicking if empty.

pub fn consume(&mut self, value: T) -> T[src]

Applies a median filter to the consumed value.

Implementation

The algorithm makes use of a ring buffer of the same size as its filter window. Inserting values into the ring buffer appends them to a linked list that is embedded inside said ring buffer (using relative integer jump offsets as links).

Example

Given a sequence of values [3, 2, 4, 6, 5, 1] and a buffer of size 5, the buffer would be filled like this:

new(5)  consume(3)  consume(2)  consume(4)  consume(6)  consume(5)  consume(1)
▶︎[ ]      ▷[3]       ┌→[3]       ┌→[3]─┐     ┌→[3]─┐    ▶︎┌→[3]─┐      ▷[1]─┐
 [ ]      ▶︎[ ]      ▷└─[2]      ▷└─[2] │    ▷└─[2] │    ▷└─[2] │    ▶︎┌─[2]←┘
 [ ]       [ ]        ▶︎[ ]         [4]←┘     ┌─[4]←┘     ┌─[4]←┘     └→[4]─┐
 [ ]       [ ]         [ ]        ▶︎[ ]       └→[6]       │ [6]←┐     ┌→[6] │
 [ ]       [ ]         [ ]         [ ]        ▶︎[ ]       └→[5]─┘     └─[5]←┘

Algorithm

  1. Remove node at current cursor (▶︎) from linked list, if it exists. (by re-wiring its predecessor to its successor).
  2. Initialize current and median index to first node of linked list ().
  3. Walk through linked list, searching for insertion point.
  4. Shift median index on every other hop (thus ending up in the list’s median).
  5. Insert value into ring buffer and linked list respectively.
  6. Update index to linked list’s first node, if necessary.
  7. Update ring buffer’s cursor.
  8. Return median value.

(Based on Phil Ekstrom, Embedded Systems Programming, November 2000.)

Trait Implementations

impl<T: Clone> Clone for Filter<T>[src]

impl<T: Debug> Debug for Filter<T>[src]

Auto Trait Implementations

impl<T> RefUnwindSafe for Filter<T> where
    T: RefUnwindSafe

impl<T> Send for Filter<T> where
    T: Send

impl<T> Sync for Filter<T> where
    T: Sync

impl<T> Unpin for Filter<T> where
    T: Unpin

impl<T> UnwindSafe for Filter<T> where
    T: UnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> Same<T> for T

type Output = T

Should always be Self

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.