Averages/Simple moving average: Difference between revisions
Content added Content deleted
imported>Arakov |
|||
Line 2,309: | Line 2,309: | ||
[1, 1, 1.5, 2, 2.5, 3, 3.3333333333333335, 3.5714285714285716, 3.75, 3.888888888888889, 4] |
[1, 1, 1.5, 2, 2.5, 3, 3.3333333333333335, 3.5714285714285716, 3.75, 3.888888888888889, 4] |
||
[1, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5] |
[1, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5] |
||
</pre> |
|||
=={{header|jq}}== |
|||
'''Works with jq, the C implementation of jq''' |
|||
'''Works with gojq, the Go implementation of jq''' |
|||
'''Works with jaq, the Rust implementation of jq''' |
|||
jq functions are stateless, so in this entry, sma($x) is defined |
|||
as a parameterized jq filter that takes as input the relevant state as a JSON object. |
|||
This should initially include a key named "period" specifying the period, |
|||
which may be infinite, i.e. the jq value `infinite` corresponding to positive infinity. |
|||
For example the initial call to sma/1 might look like: |
|||
<pre> |
|||
{period: infinite} | sma(100) |
|||
</pre> |
|||
Two examples are given, one with a finite and the other with an infinite period. |
|||
Both compute the average of the 11 numbers 0, 1, ... 10, by calling sma(0) and then sma(1), and so on. |
|||
<syntaxhighlight lang="jq"> |
|||
# The input should be a JSON object with a key named "period". |
|||
# The output is a JSON object with a key named "average" giving the SMA. |
|||
def sma($x): |
|||
def average: |
|||
.n as $n |
|||
| if $n == null or $n == 0 then . + {n: 1, average: $x} |
|||
else .average |= (. * $n + $x) / ($n + 1) |
|||
| .n += 1 |
|||
end; |
|||
if . == null or (.period and .period < 1) |
|||
then "The initial call to sma/1 must specify the period properly" | error |
|||
elif .n and .n < 0 then "Invalid value of .n" | error |
|||
elif (.period | isinfinite) then average |
|||
elif .n == null or .n == 0 then . + {n: 1, average: $x, array: [$x]} |
|||
else .n as $n |
|||
| if $n < .period |
|||
then .array += [$x] |
|||
| .n += 1 |
|||
else .array |= .[1:] + [$x] |
|||
end |
|||
| .average = (.array | (add/length)) |
|||
end; |
|||
# Call sma($x) for the 11 numbers 0, 1, ... 10. |
|||
def example($period): |
|||
reduce range(0;11) as $x({period: $period}; sma($x)) |
|||
| .average ; |
|||
example(11), example(infinite) |
|||
</syntaxhighlight> |
|||
{{output}} |
|||
<pre> |
|||
5 |
|||
5 |
|||
</pre> |
</pre> |
||