Reputation: 414
I want to calculate a moving average over a time window:
//object init
MovingAverageTimeBased movTime = new MovingAverageTimeBased(8000f);
//this gets called every Frame (around 180 FPS -- but varies of course)
movingAvg = movTime.next(value, System.currentTimeMillis());
And this is the class:
public class MovingAverageTimeBased {
float windowsize;
Queue<Float> queue;
Queue<Float> timestampQueue;
float sum;
float lastItemDeleted;
public MovingAverageTimeBased(float windowsize) {
this.windowsize = windowsize;
this.queue = new LinkedList<Float>();
this.timestampQueue = new LinkedList<Float>();
this.sum = 0;
}
public double next(float n, float timestamp) {
if(queue.size() > 1 && timestampQueue.size() > 1) {
System.out.println("Timestamp diff- " + (timestamp - (float) timestampQueue.peek()));
while (timestamp - (float) timestampQueue.peek() > windowsize) {
System.out.println("Unqueue item");
sum = sum - (float) queue.poll();
timestampQueue.poll();
}
}
queue.offer(n);
timestampQueue.offer(timestamp);
sum = sum + n;
return (float) sum / queue.size();
}
}
My error is that, that entries never seem to get deleted as the difference of the timestamps are always 0?
What could be the mistake?
Upvotes: 0
Views: 1604
Reputation: 59174
The big problem is that you used a Queue<Float>
for your time stamps.
System.currentTimeMillis()
is currently 1544100776456
rounded to the nearest float, this is 1.5441007E12
As you can see, we lost some digits. You need to wait about a minute before the float value will change.
You should use Long or Double in that queue.
Then you have to check queue size > 0 for every iteration of the while loop, not just the first one.
Upvotes: 2
Reputation: 1454
Your code is ok, but you are storing timestamp as float(float is not big enough for timestamp) store timestamps as long
public class MovingAverageTimeBased {
long windowsize;
Queue<Float> queue;
Queue<Long> timestampQueue;
float sum;
float lastItemDeleted;
public MovingAverageTimeBased(long windowsize) {
this.windowsize = windowsize;
this.queue = new LinkedList<Float>();
this.timestampQueue = new LinkedList<Long>();
this.sum = 0;
}
public double next(float n, long timestamp) {
if(queue.size() > 1 && timestampQueue.size() > 1) {
System.out.println("Timestamp diff- " + (timestamp - timestampQueue.peek()));
while(timestamp - timestampQueue.peek() > windowsize) {
System.out.println("Unqueue item");
sum = sum - queue.poll();
timestampQueue.poll();
}
}
queue.offer(n);
timestampQueue.offer(timestamp);
sum = sum + n;
return (float) sum / queue.size();
}
}
Upvotes: 1