The class below implements an exponentially time-decaying counter. The rate of the decay is defined by it's half-life, which is specified in seconds.
/**
* An exponentially time-decaying counter.
* @author Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland, www.source-code.biz
**/
public class DecayingCounter {
private double value;
private long time;
private final double tau;
/**
* Creates a new decaying counter with an initial value of 0.
* @param halfLife
* half-life in seconds.
**/
public DecayingCounter (double halfLife) {
this(halfLife, 0.0); }
/**
* Creates a new decaying counter.
* @param halfLife
* half-life in seconds.
* @param initialValue
* initial value of the counter.
**/
public DecayingCounter (double halfLife, double initialValue) {
tau = halfLife / Math.log(2.0);
set(initialValue); }
/**
* Sets the counter to a new value.
**/
public void set (double newValue) {
value = newValue;
time = System.nanoTime(); }
/**
* Returns the current counter value.
**/
public double get() {
update();
return value; }
/**
* Increments the counter by 1 and returns the new value.
**/
public double increment() {
update();
value += 1.0;
return value; }
private void update() {
long newTime = System.nanoTime();
long deltaTime = newTime - time;
if (deltaTime > 0)
value *= Math.exp(deltaTime * -1E-9 / tau);
time = newTime; }
} // end class DecayingCounter
// A simple test program for the DecayingCounter class.
public class TestDecayingCounter {
public static void main (String[] args) throws Exception {
DecayingCounter counter = new DecayingCounter(2.0, 8.0);
// Half-life 2 seconds, initial value 8.
int ctr2 = 12; // first increment after 6 seconds
while (true) {
System.out.println(counter.get());
Thread.sleep(500); // wait for half a second
if (ctr2-- <= 0) {
System.out.println ("--- increment ---");
counter.increment();
ctr2 = 6; }}} // next increment after 3 seconds
} // end class TestDeayingCounter
Author: Christian d'Heureuse (www.source-code.biz, www.inventec.ch/chdh)
License: Free
Index