Windows

Windows are FIFO (First In First Out) structures with a fixed size. They are used to collect a number of numerical values, and provides handy methods to get statistics on this set of values.

There exist two types of windows in GreyCat, TimeWindows where the size is defined in time (thus the number of values can vary), and SlidingWindows where the number of elements is fixed.

Both are presented next.

TimeWindow

TimeWindows are convenient to collect values within a given period of time. Developers would simply create a TimeWindow and specify the maximum time separating the first and last value of the set. The TimeWindow will automatically discard old elements when the max duration between elements is reached.

In the following example, a TimeWindow is used to compute the average of a value by periods of 5 seconds:

use util;

fn main() {
  var tw = TimeWindow::new();
  
  // sets the size of the window, in time.
  tw.configure(5s);
  
  for (var t = 0; t < 51; t++) {
    // add the value to the time window.
    tw.add(time::new(t, DurationUnit::seconds), t as float);
    
    // every five seconds
    if (t != 0 && t % 5 == 0) {
      // displays structure of TimeWindow:
      var t_start = tw.firstTime();
      var t_start_s = t_start.to(DurationUnit::seconds);
      var t_end = tw.lastTime();
      var t_end_s = t_end.to(DurationUnit::seconds);
      print("window size: ${tw.size()}, range: [${t_start_s}, ${t_end_s}], ");

      // displays the average computed over all values from the last 5 seconds
      println("average: ${tw.avg()}");
    }
  }
}

Displays:

window size: 6, range: [0, 5], average: 2.5
window size: 6, range: [5, 10], average: 7.5
window size: 6, range: [10, 15], average: 12.5
...

TimeWindows can be iterated using for loops. In that case the for loop iterates with 2 parameters for each element contained in the TimeWindow the time and the value.

for (time, value in timeWindow) {
  // ...
}

The reference section at the end of the page lists the TimeWindow interface.

Sliding Window

SlidingWindows are convenient to collect several values. Developers would simply create a SlidingWindow and specify the maximum number of values in the window. The SlidingWindow will automatically discard the last element when the max size is reached.

In the following example, a SlidingWindow is used to compute the average over 5 values:

use util;

fn main() {
  var sw = SlidingWindow::new();
  
  // sets the size of the window, in number of elements.
  sw.configure(5);
  
  for (var i = 0; i < 51; i++) {
    // add the value to the SlidingWindow (as floats)
    sw.add(i as float);
    
    // every five values
    if (i != 0 && i % 5 == 0) {
      // displays the average computed the last 5 values
      println("average over ${sw.size()}: ${sw.avg()}");
    }
  }
}

Displays:

average over 5: 3.0
average over 5: 8.0
average over 5: 13.0
...

SlidingWindows can be iterated using for loops. In that case the for loop iterates with 2 parameters for each element contained in the SlidingWindow the index and the value.

for (index, value in slidingWindow) {
// ...
}

The next reference section lists the SlidingWindow interface.

Reference

native type TimeWindow {
  /// Creates a new TimeWindow.
  static native fn new(): TimeWindow;

  /// Configures the size of the window in time.
  native fn configure(value: duration);

  /// Adds a new value `value` to the window at time `t`.
  /// Following this addition, any value which exceeds the period of time configured from the most recent timepoint will be discarded from the window.
  native fn add(t: time, value: any?);

  /// Moves the time window in time, so the window contains the time `t` given in parameter, without needing to add a value.
  native fn update(t: time);

  /// Clears the window of all its values.
  native fn clear();

  /// Returns the number of values contained in the window.
  native fn size(): int;

  /// Returns the sum of the values contained in the window.
  native fn sum(): float;

  /// Returns the minimum of the values contained in the window.
  native fn min(): any;

  /// Returns the maximum of the values contained in the window.
  native fn max(): any;

  /// Returns the median of the values contained in the window.
  native fn median(): any;

  /// Returns the standard deviation of the values contained in the window.
  native fn std(): float;

  /// Returns the average of the values contained in the window.
  native fn avg(): float;

  /// Returns the time of the first element contained in the TimeWindow, or null if empty.
  native fn firstTime(): time?;

  /// Returns the time of the last element contained in the TimeWindow, or null if empty.
  native fn lastTime(): time?;
  native fn first(): any?;
  native fn last(): any?;
}
native type SlidingWindow {
  /// Creates a new SlidingWindow.
  static native fn new(): SlidingWindow;

  /// Configures the size of the window in number of elements `nbElem`.
  native fn configure(nbElem: int);

  /// Adds a new value value to the window. Following this addition, the last value in the window is discarded if the maximum size is reached.
  native fn add(value: any?);

  /// Clears the window of all its values.
  native fn clear();

  /// Returns the number of values contained in the window.
  native fn size(): int;

  /// Returns the sum of the values contained in the window.
  native fn sum(): float;

  /// Returns the minimum of the values contained in the window.
  native fn min(): any;

  /// Returns the maximum of the values contained in the window.
  native fn max(): any;

  /// Returns the median of the values contained in the window.
  native fn median(): any;

  /// Returns the standard deviation of the values contained in the window.
  native fn std(): float;

  /// Returns the average of the values contained in the window.
  native fn avg(): float;
}