diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 8f32d024..165aeab6 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.9.3","generation_timestamp":"2023-09-23T02:19:18","documenter_version":"1.0.1"}} \ No newline at end of file +{"documenter":{"julia_version":"1.9.3","generation_timestamp":"2023-09-24T02:23:12","documenter_version":"1.0.1"}} \ No newline at end of file diff --git a/dev/examples/index.html b/dev/examples/index.html index 95fc30b0..51ac6575 100644 --- a/dev/examples/index.html +++ b/dev/examples/index.html @@ -74,4 +74,4 @@ output = [std(window_value(update_state!(state, _wrap(v)))) for v in values] plot(values; alpha=0.4, label="Input") -plot!(output; label="std (window=100)")

+plot!(output; label="std (window=100)")

diff --git a/dev/index.html b/dev/index.html index f688a848..eba9901d 100644 --- a/dev/index.html +++ b/dev/index.html @@ -7,4 +7,4 @@ a + b + c, a + b + c - a + d, a + b + c - a + d - b + e -]

This can be problematic due to overflow / underflow for most numerical types, and accumulated rounding errors in floating point types (for an extreme example, suppose a is Inf). The simple approach also does not generalise to operators like the set union, since there is no inverse.

+]

This can be problematic due to overflow / underflow for most numerical types, and accumulated rounding errors in floating point types (for an extreme example, suppose a is Inf). The simple approach also does not generalise to operators like the set union, since there is no inverse.

diff --git a/dev/mean-plot-2.svg b/dev/mean-plot-2.svg index d7375a6c..a6d59221 100644 --- a/dev/mean-plot-2.svg +++ b/dev/mean-plot-2.svg @@ -1,52 +1,54 @@ - + - + - + - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/mean-plot.svg b/dev/mean-plot.svg index 854cd45e..6cd9df97 100644 --- a/dev/mean-plot.svg +++ b/dev/mean-plot.svg @@ -1,52 +1,54 @@ - + - + - + - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/reference/base/index.html b/dev/reference/base/index.html index 77027538..e2a8c9f4 100644 --- a/dev/reference/base/index.html +++ b/dev/reference/base/index.html @@ -3,4 +3,4 @@ WindowedAssociativeOp{T,Op,Op!}() WindowedAssociativeOp{T,Op}()

State associated with a windowed aggregation of a binary associative operator.

If Op! is not specified, it will default to Op. However, for non-bitstypes, it can be beneficial to provide this method to reduce memory allocations.

V will default to a Vector{T}. For windows of a fixed and known length, a circular buffer will be more efficient — see FixedWindowAssociativeOp.

Method

Wherever summation is discussed, we can consider any alternative binary, associative, operator. For example: +, *, max, min, &&, union

NB. It is interesting to observe that commutativity is not required by this algorithm.

Conceptually the window is maintained in two buffers:

    [---- A ---)[----- B ------)
         <                      >    <-- current window finishes at the end of B, and
-                                        starts somewhere in A.

A is stored as a sequence of cumulative sums, such that as the "<" advances we merely pick out the correct element:

    x_i,   x_i-1 + x_i,  x_i-2 + x_i-1 + x_i

B is stored as both:

  • The sequence of values seen: x_i+1, x_i+2, x_i+3, ...
  • The total of that sequence: x_i+1 + x_i+2 + x_i+3 + ...

When the "<" advances from A to B, we discard A, and the subset of B remaining after < becomes the new A. In becoming A, we transform its representation into that of the cumulative sums. We create a new, empty, B.

O(1) amortized runtime complexity, and O(L) space complexity, where L is the typical window length.

Type parameters

  • T: The type of the values in the window.
  • Op: Any binary, associative, function.
  • Op!: Op!(x, y) will perform x + y, storing the result in x.
  • V: The subtype of AbstractVector{T} used for internal state.

Fields (for internal use only)

  • previous_cumsum::Vector{T}: Corresponds to array A above.
  • ri_previous_cumsum::Int: A reverse index into previous_cumsum, once it contains values. It should be subtracted from end in order to obtain the appropriate index.
  • values::Vector{T}: Corresponds to array B above.
  • sum::T: The sum of the elements in values.
source
AssociativeWindowAggregation.window_sizeMethod
function window_size(state::WindowedAssociativeOp)::Int

Get the current size of the window in state.

Arguments:

  • state::WindowedAssociativeOp: The state to query.

Returns:

  • Int: The current size of the window.
source
AssociativeWindowAggregation.window_valueMethod
window_value(state::WindowedAssociativeOp{T})::T where T

Get the value currently represented by the state.

Behaviour is undefined if this is called when the window is empty.

Arguments:

  • state::WindowedAssociativeOp{T}: The state to query.

Returns:

  • T: The result of aggregating over the values in the window.
source
Base.popfirst!Method
popfirst!(state::WindowedAssociativeOp, n::Integer=1) -> state

Drop n values from the start of state.

source
Base.push!Method
push!(state::WindowedAssociativeOp{T}, value) -> state

Push value onto the end of state.

Arguments

  • state::WindowedAssociativeOp: The state to update (will be mutated).
  • value: The value to add to the end of the window - must be convertible to a T.
source
+ starts somewhere in A.

A is stored as a sequence of cumulative sums, such that as the "<" advances we merely pick out the correct element:

    x_i,   x_i-1 + x_i,  x_i-2 + x_i-1 + x_i

B is stored as both:

  • The sequence of values seen: x_i+1, x_i+2, x_i+3, ...
  • The total of that sequence: x_i+1 + x_i+2 + x_i+3 + ...

When the "<" advances from A to B, we discard A, and the subset of B remaining after < becomes the new A. In becoming A, we transform its representation into that of the cumulative sums. We create a new, empty, B.

O(1) amortized runtime complexity, and O(L) space complexity, where L is the typical window length.

Type parameters

  • T: The type of the values in the window.
  • Op: Any binary, associative, function.
  • Op!: Op!(x, y) will perform x + y, storing the result in x.
  • V: The subtype of AbstractVector{T} used for internal state.

Fields (for internal use only)

  • previous_cumsum::Vector{T}: Corresponds to array A above.
  • ri_previous_cumsum::Int: A reverse index into previous_cumsum, once it contains values. It should be subtracted from end in order to obtain the appropriate index.
  • values::Vector{T}: Corresponds to array B above.
  • sum::T: The sum of the elements in values.
source
AssociativeWindowAggregation.window_sizeMethod
function window_size(state::WindowedAssociativeOp)::Int

Get the current size of the window in state.

Arguments:

  • state::WindowedAssociativeOp: The state to query.

Returns:

  • Int: The current size of the window.
source
AssociativeWindowAggregation.window_valueMethod
window_value(state::WindowedAssociativeOp{T})::T where T

Get the value currently represented by the state.

Behaviour is undefined if this is called when the window is empty.

Arguments:

  • state::WindowedAssociativeOp{T}: The state to query.

Returns:

  • T: The result of aggregating over the values in the window.
source
Base.popfirst!Method
popfirst!(state::WindowedAssociativeOp, n::Integer=1) -> state

Drop n values from the start of state.

source
Base.push!Method
push!(state::WindowedAssociativeOp{T}, value) -> state

Push value onto the end of state.

Arguments

  • state::WindowedAssociativeOp: The state to update (will be mutated).
  • value: The value to add to the end of the window - must be convertible to a T.
source
diff --git a/dev/reference/fixed/index.html b/dev/reference/fixed/index.html index dca52c82..93060384 100644 --- a/dev/reference/fixed/index.html +++ b/dev/reference/fixed/index.html @@ -1,3 +1,3 @@ Fixed window · AssociativeWindowAggregation.jl

Fixed window

A state to represent a window with a fixed capacity. It will start off empty, can have values pushed into it, and can be tested to see if it is "full".

AssociativeWindowAggregation.FixedWindowAssociativeOpType
FixedWindowAssociativeOp{T,Op,Op!}(window)
-FixedWindowAssociativeOp{T,Op}(window)

State necessary for accumulation over a rolling window of fixed size.

Fields

  • window_state::WindowedAssociativeOp{T,Op}: The underlying general-window state.
  • remaining_window::Int: How much of the window remains to be filled. Initially this will be set to the window size, and will then reduce for every value added until it reaches zero.
source
AssociativeWindowAggregation.update_state!Method
update_state!(state::FixedWindowAssociativeOp, value) -> state

Add the specified value to the state. Drop a value from the window iff the window is full.

Returns

  • ::FixedWindowAssociativeOp: The instance state that was passed in.
source
+FixedWindowAssociativeOp{T,Op}(window)

State necessary for accumulation over a rolling window of fixed size.

Fields

  • window_state::WindowedAssociativeOp{T,Op}: The underlying general-window state.
  • remaining_window::Int: How much of the window remains to be filled. Initially this will be set to the window size, and will then reduce for every value added until it reaches zero.
source
AssociativeWindowAggregation.update_state!Method
update_state!(state::FixedWindowAssociativeOp, value) -> state

Add the specified value to the state. Drop a value from the window iff the window is full.

Returns

  • ::FixedWindowAssociativeOp: The instance state that was passed in.
source
diff --git a/dev/reference/time/index.html b/dev/reference/time/index.html index f755270e..0e8f5a11 100644 --- a/dev/reference/time/index.html +++ b/dev/reference/time/index.html @@ -1,3 +1,3 @@ Time window · AssociativeWindowAggregation.jl

Time window

A state to represent a window with fixed time capacity.

Every value pushed onto the state has an associated time, and time is taken to be strictly increasing. The window is taken to be fixed in terms of time duration rather than a fixed number of values.

AssociativeWindowAggregation.TimeWindowAssociativeOpType
TimeWindowAssociativeOp{Value,Op,Op!,Time}(window::TimeDiff)
-TimeWindowAssociativeOp{Value,Op,Time}(window::TimeDiff)

State necessary for accumulation over a rolling window of fixed size, in terms of time.

When presented with a new time t', we guarantee that all times t remaining in the window satisfy:

t > t' - w

That is, at time t' this window represents the open-closed time interval (t' - w, t']

We require that window be of a type that, when added to a Time, gives a Time.

Fields

  • window_state::WindowedAssociativeOp{Value}: The underlying general-window state.
  • window::TimeDiff: The window, as a difference between two times.
  • times::Deque{Time}: The same length as the values stored in window_state, and representing the times of those observations.
  • window_full::Bool: For internal use - will be set to true once a point has dropped out of the window.
source
AssociativeWindowAggregation.update_state!Method
update_state!(state::TimeWindowAssociativeOp, time, value) -> state

Add the specified value to the state with associated time, and drop any values that are no longer in the time window.

Arguments

  • state::TimeWindowAssociativeOp:
  • time: The time to which value corresponds.
  • value: The value to add to the window.

Returns

  • ::TimeWindowAssociativeOp: state, which has been mutated.
source
+TimeWindowAssociativeOp{Value,Op,Time}(window::TimeDiff)

State necessary for accumulation over a rolling window of fixed size, in terms of time.

When presented with a new time t', we guarantee that all times t remaining in the window satisfy:

t > t' - w

That is, at time t' this window represents the open-closed time interval (t' - w, t']

We require that window be of a type that, when added to a Time, gives a Time.

Fields

  • window_state::WindowedAssociativeOp{Value}: The underlying general-window state.
  • window::TimeDiff: The window, as a difference between two times.
  • times::Deque{Time}: The same length as the values stored in window_state, and representing the times of those observations.
  • window_full::Bool: For internal use - will be set to true once a point has dropped out of the window.
source
AssociativeWindowAggregation.update_state!Method
update_state!(state::TimeWindowAssociativeOp, time, value) -> state

Add the specified value to the state with associated time, and drop any values that are no longer in the time window.

Arguments

  • state::TimeWindowAssociativeOp:
  • time: The time to which value corresponds.
  • value: The value to add to the window.

Returns

  • ::TimeWindowAssociativeOp: state, which has been mutated.
source
diff --git a/dev/std-plot.svg b/dev/std-plot.svg index fdde9b3b..250a710a 100644 --- a/dev/std-plot.svg +++ b/dev/std-plot.svg @@ -1,48 +1,48 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + +