September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -1,44 +0,0 @@
|
|||
I = (P) ->
|
||||
# The cryptic name "I" follows the problem description;
|
||||
# it returns a function that computes a moving average
|
||||
# of successive values over the period P, using closure
|
||||
# variables to maintain state.
|
||||
cq = circular_queue(P)
|
||||
num_elems = 0
|
||||
sum = 0
|
||||
|
||||
SMA = (n) ->
|
||||
sum += n
|
||||
if num_elems < P
|
||||
cq.add(n)
|
||||
num_elems += 1
|
||||
sum / num_elems
|
||||
else
|
||||
old = cq.replace(n)
|
||||
sum -= old
|
||||
sum / P
|
||||
|
||||
circular_queue = (n) ->
|
||||
# queue that only ever stores up to n values;
|
||||
# Caller shouldn't call replace until n values
|
||||
# have been added.
|
||||
i = 0
|
||||
arr = []
|
||||
|
||||
add: (elem) ->
|
||||
arr.push elem
|
||||
replace: (elem) ->
|
||||
# return value whose age is "n"
|
||||
old_val = arr[i]
|
||||
arr[i] = elem
|
||||
i = (i + 1) % n
|
||||
old_val
|
||||
|
||||
# The output of the code below should convince you that
|
||||
# calling I multiple times returns functions with independent
|
||||
# state.
|
||||
sma3 = I(3)
|
||||
sma7 = I(7)
|
||||
sma11 = I(11)
|
||||
for i in [1..10]
|
||||
console.log i, sma3(i), sma7(i), sma11(i)
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
> coffee moving_average.coffee
|
||||
1 1 1 1
|
||||
2 1.5 1.5 1.5
|
||||
3 2 2 2
|
||||
4 3 2.5 2.5
|
||||
5 4 3 3
|
||||
6 5 3.5 3.5
|
||||
7 6 4 4
|
||||
8 7 5 4.5
|
||||
9 8 6 5
|
||||
10 9 7 5.5
|
||||
|
|
@ -1,55 +1,56 @@
|
|||
#define system.
|
||||
#define system'routines.
|
||||
#define system'collections.
|
||||
#define extensions.
|
||||
import system'routines.
|
||||
import system'collections.
|
||||
import extensions.
|
||||
|
||||
#class SMA
|
||||
class SMA
|
||||
{
|
||||
#field thePeriod.
|
||||
#field theList.
|
||||
object thePeriod.
|
||||
object theList.
|
||||
|
||||
#constructor new : aPeriod
|
||||
constructor new : aPeriod
|
||||
[
|
||||
thePeriod := aPeriod.
|
||||
theList := List new.
|
||||
]
|
||||
|
||||
#method append : aNumber
|
||||
append : aNumber
|
||||
[
|
||||
theList += aNumber.
|
||||
theList append:aNumber.
|
||||
|
||||
#var aCount := theList length.
|
||||
^ aCount =>
|
||||
0 ? [ 0.0r ]
|
||||
var aCount := theList length.
|
||||
aCount =>
|
||||
0 [ ^0.0r ];
|
||||
! [
|
||||
(aCount > thePeriod)?
|
||||
if (aCount > thePeriod)
|
||||
[
|
||||
theList remove &index:0.
|
||||
theList remove at:0.
|
||||
|
||||
aCount := thePeriod.
|
||||
aCount := thePeriod
|
||||
].
|
||||
|
||||
#var aSum := theList summarize:(Real new &int:0).
|
||||
var aSum := theList summarize(Real new int:0).
|
||||
|
||||
^ aSum / aCount.
|
||||
].
|
||||
^ aSum / aCount
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
#symbol program =
|
||||
program =
|
||||
[
|
||||
#var SMA3 := SMA new:3.
|
||||
#var SMA5 := SMA new:5.
|
||||
var SMA3 := SMA new:3.
|
||||
var SMA5 := SMA new:5.
|
||||
|
||||
1 to:5 &doEach: (:i)
|
||||
1 to:5 do(:i)
|
||||
[
|
||||
console write:"sma3 + " :i :" = ": (SMA3 += i) &paddingRight:30 &with:#32.
|
||||
console writeLine:"sma5 + " :i :" = ": (SMA5 += i).
|
||||
console printPaddingRight(30, "sma3 + ", i, " = ", SMA3 append:i).
|
||||
console printLine("sma5 + ", i, " = ", SMA5 append:i)
|
||||
].
|
||||
|
||||
5 to:1 &doEach: (:i)
|
||||
5 to:1 do(:i)
|
||||
[
|
||||
console write:"sma3 + " :i :" = ": (SMA3 += i) &paddingRight:30 &with:#32.
|
||||
console writeLine:"sma5 + " :i :" = ": (SMA5 += i).
|
||||
console printPaddingRight(30, "sma3 + ", i, " = ", SMA3 append:i).
|
||||
console printLine("sma5 + ", i, " = ", SMA5 append:i)
|
||||
].
|
||||
|
||||
console readChar.
|
||||
].
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
public class MovingAverage {
|
||||
private final Queue<Double> window = new LinkedList<Double>();
|
||||
private final int period;
|
||||
|
|
@ -19,13 +20,13 @@ public class MovingAverage {
|
|||
}
|
||||
|
||||
public double getAvg() {
|
||||
if (window.isEmpty()) return 0; // technically the average is undefined
|
||||
if (window.isEmpty()) return 0.0; // technically the average is undefined
|
||||
return sum / window.size();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
double[] testData = {1,2,3,4,5,5,4,3,2,1};
|
||||
int[] windowSizes = {3,5};
|
||||
double[] testData = {1, 2, 3, 4, 5, 5, 4, 3, 2, 1};
|
||||
int[] windowSizes = {3, 5};
|
||||
for (int windSize : windowSizes) {
|
||||
MovingAverage ma = new MovingAverage(windSize);
|
||||
for (double x : testData) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
// version 1.0.6
|
||||
|
||||
fun initMovingAverage(p: Int): (Double) -> Double {
|
||||
if (p < 1) throw IllegalArgumentException("Period must be a positive integer")
|
||||
val list = mutableListOf<Double>()
|
||||
return {
|
||||
list.add(it)
|
||||
if (list.size > p) list.removeAt(0)
|
||||
list.average()
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val sma4 = initMovingAverage(4)
|
||||
val sma5 = initMovingAverage(5)
|
||||
val numbers = listOf(1.0, 2.0, 3.0, 4.0, 5.0, 5.0, 4.0, 3.0, 2.0, 1.0)
|
||||
println("num\tsma4\tsma5\n")
|
||||
for (number in numbers) println("${number}\t${sma4(number)}\t${sma5(number)}")
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface MovingAverage : NSObject {
|
||||
unsigned int period;
|
||||
NSMutableArray *window;
|
||||
double sum;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation MovingAverage
|
||||
|
||||
// init with default period
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if(self) {
|
||||
period = 10;
|
||||
window = [[NSMutableArray alloc] init];
|
||||
sum = 0.0;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
// init with specified period
|
||||
- (id)initWithPeriod:(unsigned int)thePeriod {
|
||||
self = [super init];
|
||||
if(self) {
|
||||
period = thePeriod;
|
||||
window = [[NSMutableArray alloc] init];
|
||||
sum = 0.0;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
// clear
|
||||
- (void)dealloc {
|
||||
[window release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
// add a new number to the window
|
||||
- (void)add:(double)val {
|
||||
sum += val;
|
||||
[window addObject:[NSNumber numberWithDouble:val]];
|
||||
if([window count] > period) {
|
||||
NSNumber *n = [window objectAtIndex:0];
|
||||
sum -= [n doubleValue];
|
||||
[window removeObjectAtIndex:0];
|
||||
}
|
||||
}
|
||||
|
||||
// get the average value
|
||||
- (double)avg {
|
||||
if([window count] == 0) {
|
||||
return 0; // technically the average is undefined
|
||||
}
|
||||
return sum / [window count];
|
||||
}
|
||||
|
||||
// set the period, resizes current window
|
||||
- (void)setPeriod:(unsigned int)thePeriod {
|
||||
// make smaller?
|
||||
if(thePeriod < [window count]) {
|
||||
for(int i = 0; i < thePeriod; ++i) {
|
||||
NSNumber *n = [window objectAtIndex:0];
|
||||
sum -= [n doubleValue];
|
||||
[window removeObjectAtIndex:0];
|
||||
}
|
||||
}
|
||||
period = thePeriod;
|
||||
}
|
||||
|
||||
// get the period (window size)
|
||||
- (unsigned int)period {
|
||||
return period;
|
||||
}
|
||||
|
||||
// clear the window and current sum
|
||||
- (void)clear {
|
||||
[window removeAllObjects];
|
||||
sum = 0;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
double testData[10] = {1,2,3,4,5,5,4,3,2,1};
|
||||
int periods[2] = {3,5};
|
||||
for(int i = 0; i < 2; ++i) {
|
||||
MovingAverage *ma = [[MovingAverage alloc] initWithPeriod:periods[i]];
|
||||
for(int j = 0; j < 10; ++j) {
|
||||
[ma add:testData[j]];
|
||||
NSLog(@"Next number = %f, SMA = %f", testData[j], [ma avg]);
|
||||
}
|
||||
[ma release];
|
||||
NSLog(@"\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
testdata = .array~of(1, 2, 3, 4, 5, 5, 4, 3, 2, 1)
|
||||
|
||||
-- run with different period sizes
|
||||
loop period over .array~of(3, 5)
|
||||
say "Period size =" period
|
||||
say
|
||||
movingaverage = .movingaverage~new(period)
|
||||
loop number over testdata
|
||||
average = movingaverage~addnumber(number)
|
||||
say " Next number =" number", moving average =" average
|
||||
end
|
||||
say
|
||||
end
|
||||
|
||||
::class movingaverage
|
||||
::method init
|
||||
expose period queue sum
|
||||
use strict arg period
|
||||
sum = 0
|
||||
-- the circular queue makes this easy
|
||||
queue = .circularqueue~new(period)
|
||||
|
||||
-- add a number to the average set
|
||||
::method addNumber
|
||||
expose queue sum
|
||||
use strict arg number
|
||||
sum += number
|
||||
-- add this to the queue
|
||||
old = queue~queue(number)
|
||||
-- if we pushed an element off the end of the queue,
|
||||
-- subtract this from our sum
|
||||
if old \= .nil then sum -= old
|
||||
-- and return the current item
|
||||
return sum / queue~items
|
||||
|
||||
-- extra method to retrieve current average
|
||||
::method average
|
||||
expose queue sum
|
||||
-- undefined really, but just return 0
|
||||
if queue~isempty then return 0
|
||||
-- return current queue
|
||||
return sum / queue~items
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
data 1,2,3,4,5,5,4,3,2,1
|
||||
dim sd(10) ' series data
|
||||
global sd ' make it global so we all see it
|
||||
for i = 1 to 10:read sd(i): next i
|
||||
|
||||
x = sma(3) ' simple moving average for 3 periods
|
||||
x = sma(5) ' simple moving average for 5 periods
|
||||
|
||||
function sma(p) ' the simple moving average function
|
||||
print "----- SMA:";p;" -----"
|
||||
for i = 1 to 10
|
||||
sumSd = 0
|
||||
for j = max((i - p) + 1,1) to i
|
||||
sumSd = sumSd + sd(j) ' sum series data for the period
|
||||
next j
|
||||
if p > i then p1 = i else p1 = p
|
||||
print sd(i);" sma:";p;" ";sumSd / p1
|
||||
next i
|
||||
end function
|
||||
|
|
@ -13,10 +13,10 @@ func simple_moving_average(period) {
|
|||
}
|
||||
}
|
||||
|
||||
var ma3 = simple_moving_average(3);
|
||||
var ma5 = simple_moving_average(5);
|
||||
var ma3 = simple_moving_average(3)
|
||||
var ma5 = simple_moving_average(5)
|
||||
|
||||
[1 ..^ 6, 6 ^.. 1].map{@|_} -> each {|num|
|
||||
printf("Next number = %d, SMA_3 = %.3f, SMA_5 = %.1f\n",
|
||||
for num (1..5, flip(1..5)) {
|
||||
printf("Next number = %d, SMA_3 = %.3f, SMA_5 = %.1f\n",
|
||||
num, ma3.call(num), ma5.call(num))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class sma_generator(period, list=[], sum=0) {
|
|||
var ma3 = sma_generator(3)
|
||||
var ma5 = sma_generator(5)
|
||||
|
||||
for num in [@|(1..5), @|(1..5 -> flip)] {
|
||||
printf("Next number = %d, SMA_3 = %.3f, SMA_5 = %.1f\n",
|
||||
for num (1..5, flip(1..5)) {
|
||||
printf("Next number = %d, SMA_3 = %.3f, SMA_5 = %.1f\n",
|
||||
num, ma3.SMA(num), ma5.SMA(num))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
fcn SMA(P){
|
||||
fcn(n,ns,P){
|
||||
sz:=ns.append(n.toFloat()).len();
|
||||
if(P>sz) return(0.0);
|
||||
if(P<sz) ns.del(0);
|
||||
ns.sum(0.0)/P;
|
||||
}.fp1(List.createLong(P+1),P) // pre-allocate a list of length P+1
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
T(1,2,3,4,5,5,4,3,2,1).apply(SMA(3)).println();
|
||||
T(1,2,3,4,5,5,4,3,2,1).apply(SMA(5)).println();
|
||||
Loading…
Add table
Add a link
Reference in a new issue