diff options
Diffstat (limited to '')
-rw-r--r-- | stdlib/source/library/lux/world/net/http/response.lux | 7 | ||||
-rw-r--r-- | stdlib/source/library/lux/world/time/series.lux | 189 | ||||
-rw-r--r-- | stdlib/source/library/lux/world/time/series/average.lux | 129 |
3 files changed, 230 insertions, 95 deletions
diff --git a/stdlib/source/library/lux/world/net/http/response.lux b/stdlib/source/library/lux/world/net/http/response.lux index 1c8cef67c..93bd80ac8 100644 --- a/stdlib/source/library/lux/world/net/http/response.lux +++ b/stdlib/source/library/lux/world/net/http/response.lux @@ -13,9 +13,10 @@ [encoding ["[0]" utf8]]] [format - ["[0]" html] - ["[0]" css (.only CSS)] - ["[0]" json (.only JSON) (.use "[1]#[0]" codec)]]]]] + ["[0]" json (.only JSON) (.use "[1]#[0]" codec)]]] + [web + ["[0]" html] + ["[0]" css (.only CSS)]]]] ["[0]" // (.only Body Message) ["[0]" status (.only Status)] ["[0]" header] diff --git a/stdlib/source/library/lux/world/time/series.lux b/stdlib/source/library/lux/world/time/series.lux index c529f6636..debbe884a 100644 --- a/stdlib/source/library/lux/world/time/series.lux +++ b/stdlib/source/library/lux/world/time/series.lux @@ -4,121 +4,126 @@ [abstract [equivalence (.only Equivalence)] [functor (.only Functor)] - [mix (.only Mix)]] + [mix (.only Mix)] + [monad (.only do)]] [control ["[0]" try (.only Try)] ["[0]" exception (.only Exception)]] [data + ["[0]" product] [text ["%" \\format]] [collection - ["[0]" array (.only Array) (.use "[1]#[0]" functor mix) - ["/" \\unsafe]]]] + ["/" sequence (.use "[1]#[0]" functor mix)]]] + [math + [number + ["n" nat]]] [meta - [type - ["[0]" nominal]]]]] + [type (.only sharing)]]]] [// + ["[0]" duration (.only Duration) (.use "[1]#[0]" equivalence)] ["[0]" instant (.only Instant) (.use "[1]#[0]" order)]]) -(type .public (Event of) +(type .public (Series of) (Record - [#when Instant - #what of])) + [#start Instant + #interval Duration + #data (/.Sequence of)])) -(def (event_equivalence super) +(def .public (equivalence super) (All (_ of) (-> (Equivalence of) - (Equivalence (Event of)))) + (Equivalence (Series of)))) + (all product.equivalence + instant.equivalence + duration.equivalence + (/.equivalence super) + )) + +(def .public functor + (Functor Series) (implementation - (def (= reference example) - (and (instant#= (the #when reference) (the #when example)) - (of super = (the #what reference) (the #what example)))))) + (def (each $) + (|>> (revised #data (/#each $)))))) -(nominal.def .public (Series of) - (Array (Event of)) +(def .public mix + (Mix Series) + (implementation + (def (mix $ init) + (|>> (the #data) + (/#mix $ init))))) - (def .public (equivalence super) - (All (_ of) - (-> (Equivalence of) - (Equivalence (Series of)))) - (implementation - (def (= reference example) - (of (array.equivalence (event_equivalence super)) = - (nominal.representation reference) - (nominal.representation example))))) +(def .public size + (All (_ of) + (-> (Series of) + Nat)) + (|>> (the #data) + /.size)) - (def .public functor - (Functor Series) - (implementation - (def (each $) - (|>> nominal.representation - (array#each (revised #what $)) - nominal.abstraction)))) +(def .public start + (All (_ of) + (-> (Series of) + Instant)) + (the #start)) - (def .public mix - (Mix Series) - (implementation - (def (mix $ init) - (|>> nominal.representation - (array#mix (function (_ next it) - ($ (the #what next) it)) - init))))) +(def .public (end it) + (All (_ of) + (-> (Series of) + Instant)) + (instant.after (duration.up (-- (/.size (the #data it))) + (the #interval it)) + (the #start it))) - (exception.def .public (disordered [before after]) - (Exception [Instant Instant]) - (exception.report - (list ["(Expected) before" (%.instant before)] - ["(Expected) after" (%.instant after)]))) +(def .public (at event it) + (All (_ of) + (-> Nat (Series of) + Instant)) + (instant.after (duration.up event (the #interval it)) + (the #start it))) - (exception.def .public (duplicated it) - (Exception Instant) - (exception.report - (list ["Time-stamp" (%.instant it)]))) +(exception.def .public empty) - (def .public (series it) - (All (_ of) - (-> (List (Event of)) - (Try (Series of)))) - (when it - {.#Item head tail} - (loop (again [previous head - it tail]) - (when it - {.#Item current next} - (if (instant#< (the #when current) (the #when previous)) - (again current next) - (if (instant#= (the #when current) (the #when previous)) - (exception.except ..duplicated [(the #when current)]) - (exception.except ..disordered [(the #when previous) (the #when current)]))) - - {.#End} - {try.#Success (nominal.abstraction - (array.of_list it))})) - - {.#End} - {try.#Success (nominal.abstraction - (array.empty 0))})) +(with_template [<index> <name>] + [(def .public (<name> it) + (All (_ of) + (-> (Series of) + (Try of))) + (let [data (the #data it)] + (when (/.size data) + 0 (exception.except ..empty []) + @ (/.item <index> data))))] - (def .public size - (All (_ of) - (-> (Series of) - Nat)) - (|>> nominal.representation - /.size)) + [(|> 0) earliest] + [(-- @) latest] + ) - (exception.def .public empty) - - (with_template [<name> <index>] - [(def .public (<name> it) - (All (_ of) - (-> (Series of) - (Try (Event of)))) - (let [it (nominal.representation it)] - (when (array.size it) - 0 (exception.except ..empty []) - @ {try.#Success (/.item <index> it)})))] +(exception.def .public (window_goes_out_of_bounds [offset size max_size]) + (Exception [Nat Nat Nat]) + (exception.report + (list ["From" (%.nat offset)] + ["To" (%.nat (n.+ offset size))] + ["Maximum" (%.nat max_size)]))) - [earliest 0] - [latest (-- @)] - ) - ) +(def .public (window offset size it) + (All (_ of) + (-> Nat Nat (Series of) + (Try (Series of)))) + (if (n.< (n.+ offset size) + (..size it)) + (exception.except ..window_goes_out_of_bounds [offset size (..size it)]) + (let [input (the #data it)] + (loop (again [item 0 + output (sharing [of] + (is (/.Sequence of) + input) + (is (/.Sequence of) + /.empty))]) + (if (n.< size item) + (do try.monad + [it (/.item (n.+ offset item) input)] + (again (++ item) (/.suffix it output))) + {try.#Success (let [interval (the #interval it)] + [#start (instant.after (duration.up offset interval) + (the #start it)) + #interval interval + #data output])}))))) diff --git a/stdlib/source/library/lux/world/time/series/average.lux b/stdlib/source/library/lux/world/time/series/average.lux new file mode 100644 index 000000000..553cfee7f --- /dev/null +++ b/stdlib/source/library/lux/world/time/series/average.lux @@ -0,0 +1,129 @@ +(.require + [library + [lux (.except) + [abstract + [monad (.only do)]] + [control + ["[0]" try (.only Try)] + ["[0]" exception (.only Exception)]] + [data + ["[0]" product] + [text + ["%" \\format]] + [collection + ["[0]" sequence (.only Sequence) (.use "[1]#[0]" mix functor)]]] + [math + [number + ["n" nat] + ["f" frac]]] + [meta + [type (.only sharing)]]]] + ["[0]" // (.only Series) (.use "[1]#[0]" mix)]) + +... https://en.wikipedia.org/wiki/Moving_average#Cumulative_average +(def .public cumulative + (-> (Series Frac) + (Series Frac)) + (revised //.#data + (|>> (sequence#mix (function (_ event [[previous_summation previous_period] output]) + (let [summation (f.+ previous_summation event) + average (f./ previous_period summation)] + [[summation (f.+ +1.0 previous_period)] + (sequence.suffix average output)])) + [[+0.0 +1.0] (is (Sequence Frac) + sequence.empty)]) + product.right))) + +(exception.def .public (window_size_is_too_large [maximum actual]) + (Exception [Nat Nat]) + (exception.report + (list ["Maximum" (%.nat maximum)] + ["Actual" (%.nat actual)]))) + +(def .public (windows size it) + (All (_ of) + (-> Nat (Series of) + (Try (Series (Series of))))) + (let [maximum (//.size it)] + (if (n.< size maximum) + (exception.except ..window_size_is_too_large [maximum size]) + (let [limit (n.- size maximum)] + (loop (again [offset 0 + output (sharing [of] + (is (Series of) + it) + (is (Sequence (Series of)) + sequence.empty))]) + (if (n.< limit offset) + (do try.monad + [current (//.window offset size it)] + (again (++ offset) + (sequence.suffix current output))) + {try.#Success (has //.#data output it)})))))) + +(type .public (Average of) + (-> (Series of) + of)) + +... https://en.wikipedia.org/wiki/Moving_average +(def .public (moving average additional it) + (All (_ of) + (-> (Average of) Nat (Series of) + (Try (Series of)))) + (do try.monad + [.let [size (++ additional)] + it (windows size it)] + (in (|> it + (revised //.#data (sequence#each average)) + (has //.#start (//.at size it)))))) + +... https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average +... https://en.wikipedia.org/wiki/Exponential_smoothing +(type .public Factor + (-> Nat + Frac)) + +(def .public (simple_factor additional) + Factor + (f./ (n.frac (n.+ 2 additional)) + +2.0)) + +(def .public (exponential factor) + (-> Factor + (Average Frac)) + (function (_ it) + (let [factor (factor (//.size it)) + ~factor (f.- factor +1.0)] + (//#mix (is (-> Frac Frac + Frac) + (function (_ event previous) + (f.+ (f.* ~factor previous) + (f.* factor event)))) + +0.0 + it)))) + +... https://en.wikipedia.org/wiki/Moving_average#Simple_moving_average +(def .public (simple it) + (Average Frac) + (|> (the //.#data it) + (sequence#mix f.+ +0.0) + (f./ (n.frac (//.size it))))) + +... https://en.wikipedia.org/wiki/Triangular_number +(def (summation_up_to maximum) + (-> Nat + Nat) + (|> maximum + (n.* (++ maximum)) + (n./ 2))) + +... https://en.wikipedia.org/wiki/Moving_average#Weighted_moving_average +(def .public (weighted it) + (Average Frac) + (|> it + (//#mix (function (_ sample [weight summation]) + [(f.+ +1.0 weight) + (|> sample (f.* weight) (f.+ summation))]) + [+1.0 +0.0]) + product.right + (f./ (n.frac (summation_up_to (-- (//.size it))))))) |