Averages/Simple moving average: Difference between revisions
Content added Content deleted
(New task and Python solution.) |
(→Tcl: Added implementation) |
||
Line 58: | Line 58: | ||
Next number = 2 , SMA = 3.8 |
Next number = 2 , SMA = 3.8 |
||
Next number = 1 , SMA = 3 </pre> |
Next number = 1 , SMA = 3 </pre> |
||
=={{header|Tcl}}== |
|||
{{works with|Tcl|8.6}} |
|||
<lang tcl>oo::class create SimpleMovingAverage { |
|||
variable vals idx |
|||
constructor {{period 3}} { |
|||
set idx end-[expr {$period-1}] |
|||
set vals {} |
|||
} |
|||
method val x { |
|||
set vals [lrange [list {*}$vals $x] $idx end] |
|||
expr {[tcl::mathop::+ {*}$vals]/double([llength $vals])} |
|||
} |
|||
}</lang> |
|||
Demonstration: |
|||
<lang tcl>SimpleMovingAverage create averager3 |
|||
SimpleMovingAverage create averager5 5 |
|||
foreach n {1 2 3 4 5 5 4 3 2 1} { |
|||
puts "Next number = $n, SMA_3 = [averager3 val $n], SMA_5 = [averager5 val $n]" |
|||
}</lang> |
|||
Output: |
|||
<pre>Next number = 1, SMA_3 = 1.0, SMA_5 = 1.0 |
|||
Next number = 2, SMA_3 = 1.5, SMA_5 = 1.5 |
|||
Next number = 3, SMA_3 = 2.0, SMA_5 = 2.0 |
|||
Next number = 4, SMA_3 = 3.0, SMA_5 = 2.5 |
|||
Next number = 5, SMA_3 = 4.0, SMA_5 = 3.0 |
|||
Next number = 5, SMA_3 = 4.666666666666667, SMA_5 = 3.8 |
|||
Next number = 4, SMA_3 = 4.666666666666667, SMA_5 = 4.2 |
|||
Next number = 3, SMA_3 = 4.0, SMA_5 = 4.2 |
|||
Next number = 2, SMA_3 = 3.0, SMA_5 = 3.8 |
|||
Next number = 1, SMA_3 = 2.0, SMA_5 = 3.0</pre> |
Revision as of 22:05, 17 June 2009
Averages/Simple moving average
You are encouraged to solve this task according to the task description, using any language you may know.
You are encouraged to solve this task according to the task description, using any language you may know.
Computing the simple moving average of a series of numbers.
Create a stateful function/class/instance that takes a number as argument and returns a simple moving average of its arguments so far.
Python
<lang python>def simplemovingaverage(period):
assert period == int(period) and period > 0, "Period must be an integer >0" summ = n = 0.0 values = [0.0] * period # old value queue
def sma(x): nonlocal summ, n, values n += 1 values.insert(0, x) summ += x - values.pop() n = n if n <= period else period return summ / n
return sma
if __name__ == '__main__':
for period in [3, 5]: print ("\nSIMPLE MOVING AVERAGE: PERIOD =", period) sma = simplemovingaverage(period) for i in range(1,6): print (" Next number = %-2g, SMA = %g " % (i, sma(i))) for i in range(5, 0, -1): print (" Next number = %-2g, SMA = %g " % (i, sma(i)))</lang>
Sample output
SIMPLE MOVING AVERAGE: PERIOD = 3 Next number = 1 , SMA = 1 Next number = 2 , SMA = 1.5 Next number = 3 , SMA = 2 Next number = 4 , SMA = 3 Next number = 5 , SMA = 4 Next number = 5 , SMA = 4.66667 Next number = 4 , SMA = 4.66667 Next number = 3 , SMA = 4 Next number = 2 , SMA = 3 Next number = 1 , SMA = 2 SIMPLE MOVING AVERAGE: PERIOD = 5 Next number = 1 , SMA = 1 Next number = 2 , SMA = 1.5 Next number = 3 , SMA = 2 Next number = 4 , SMA = 2.5 Next number = 5 , SMA = 3 Next number = 5 , SMA = 3.8 Next number = 4 , SMA = 4.2 Next number = 3 , SMA = 4.2 Next number = 2 , SMA = 3.8 Next number = 1 , SMA = 3
Tcl
<lang tcl>oo::class create SimpleMovingAverage {
variable vals idx constructor Template:Period 3 { set idx end-[expr {$period-1}] set vals {} } method val x { set vals [lrange [list {*}$vals $x] $idx end] expr {[tcl::mathop::+ {*}$vals]/double([llength $vals])} }
}</lang> Demonstration: <lang tcl>SimpleMovingAverage create averager3 SimpleMovingAverage create averager5 5 foreach n {1 2 3 4 5 5 4 3 2 1} {
puts "Next number = $n, SMA_3 = [averager3 val $n], SMA_5 = [averager5 val $n]"
}</lang> Output:
Next number = 1, SMA_3 = 1.0, SMA_5 = 1.0 Next number = 2, SMA_3 = 1.5, SMA_5 = 1.5 Next number = 3, SMA_3 = 2.0, SMA_5 = 2.0 Next number = 4, SMA_3 = 3.0, SMA_5 = 2.5 Next number = 5, SMA_3 = 4.0, SMA_5 = 3.0 Next number = 5, SMA_3 = 4.666666666666667, SMA_5 = 3.8 Next number = 4, SMA_3 = 4.666666666666667, SMA_5 = 4.2 Next number = 3, SMA_3 = 4.0, SMA_5 = 4.2 Next number = 2, SMA_3 = 3.0, SMA_5 = 3.8 Next number = 1, SMA_3 = 2.0, SMA_5 = 3.0