I'll be gone all weekend and I won't have time to test and commit this until probably Tuesday morning. I'm still having trouble figuring out how to use Eclipse, so if someone in IRC will help me Monday night (PST) that would help. Of course, if you'd like to test it out yourself and then commit, feel free. Additional changes need to be made to StandardNodeEstimator so that we use SelfAdjustingDecayingRunningAverage instead of DecayingRunningAverage.
-Martin
Martin Stone Davis wrote:
Martin Stone Davis wrote:
Let DDRA = the decaying decaying running average Let decayingDecayFactor=decayFactor * MIN(DRA,1-DRA) Then compute the new decaying decaying running average as: DDRA := DDRA*(1-decayingDecayFactor) + [1 or 0]*decayingDecayFactor
Attached is my attempt to implement this idea. I called it SelfAdjustingDecayingRunningAverage, but feel free to rename it if you like.
I will now see if we run into a similar problem using ResponseTimeEstimator for pDNF (epDNFGivenNotSearchFailed).
-Martin
------------------------------------------------------------------------
package freenet.node.rt;
import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException;
import freenet.Core; import freenet.FieldSet; import freenet.support.Logger;
/**
* Like DecayingRunningAverage, but adjusts the decayFactor downward the closer the current value * is to 0 or 1. * Allows reports between 0 and 1, inclusive, but probably should only be used for binary values.
*/
public class SelfAdjustingDecayingRunningAverage implements RunningAverage {
double currentVal;
final double decayFactor;
public SelfAdjustingDecayingRunningAverage(
double startVal,
double decayFactor) {
if (Double.isInfinite(startVal) || Double.isNaN(startVal))
throw new IllegalArgumentException(
"Infinite or NaN startVal: " + startVal);
if (startVal <= 0 || startVal >= 1)
throw new IllegalArgumentException(
"Not strictly between 0 and 1: " + startVal);
this.decayFactor = decayFactor; this.currentVal = startVal; }
public SelfAdjustingDecayingRunningAverage( DataInputStream dis, double decayFactor) throws IOException { this.decayFactor = decayFactor; this.currentVal = dis.readDouble(); if (Double.isInfinite(currentVal) || Double.isNaN(currentVal) || currentVal <= 0 || currentVal >= 1) { throw new IOException( "Invalid value serializing in: " + currentVal); } if (currentVal <= 0 || currentVal >= 1) { Core.logger.log( this, "reset " + currentVal, new Exception("debug"), Logger.NORMAL); currentVal = Core.hopTime(1); } }
public final double currentValue() { return currentVal; }
public synchronized final void report(double d) {
if (d < 0 || d > 1)
Core.logger.log(
this,
"Implausible report: " + d,
new Exception("debug"),
Logger.ERROR);
double adjustedDecayFactor =
decayFactor * Math.min(currentVal, 1 - currentVal);
currentVal =
currentVal * (1 - adjustedDecayFactor) + d * adjustedDecayFactor;
// The current value must in the open interval (0,1). If it becomes 0 or 1, it will
// become irretrievably stuck. // Bring value back into the open interval (0,1) if roundoff occurred. if (currentVal==0) currentVal=Double.MIN_VALUE;
if (currentVal==1) currentVal=1-Double.MIN_VALUE;
}
public synchronized final void report(long d) { report((double) d); }
public static RunningAverageFactory factory() { return new SelfAdjustingDecayingRunningAverageFactory(); }
static class SelfAdjustingDecayingRunningAverageFactory implements RunningAverageFactory { double defaultFactor = 0.2; public RunningAverage create(double start) { return new SelfAdjustingDecayingRunningAverage(start, defaultFactor); }
public RunningAverage create(DataInputStream dis) throws IOException { return new SelfAdjustingDecayingRunningAverage(dis, defaultFactor); }
/* (non-Javadoc) * @see freenet.node.rt.RunningAverageFactory#create(freenet.FieldSet) */ public RunningAverage create(FieldSet set) throws EstimatorFormatException { if (set == null) throw new EstimatorFormatException("null set passed to RunningAverage"); String impl = set.get("Implementation"); if (impl == null) throw new EstimatorFormatException("no Implementation in RunningAverage"); if (!impl.equals("SelfAdjustingDecayingRunningAverage")) throw new EstimatorFormatException( "unknown implementation " + impl); String v = set.get("Version"); if (v == null || !v.equals("1")) throw new EstimatorFormatException("Invalid version " + v); String val = set.get("CurrentValue"); if (val == null) throw new EstimatorFormatException("no CurrentValue"); double d; try { return new SelfAdjustingDecayingRunningAverage( Double.parseDouble(val), defaultFactor); } catch (NumberFormatException x) { throw new EstimatorFormatException( "invalid CurrentValue " + val); } } }
// Only write the value, not the decay factor public int getDataLength() { return 8; }
public void writeTo(DataOutputStream out) throws IOException { double cv; synchronized (this) { cv = currentVal; } out.writeDouble(cv); }
/* (non-Javadoc) * @see freenet.node.rt.RunningAverage#toFieldSet() */ public FieldSet toFieldSet() { FieldSet fs = new FieldSet(); fs.put("Implementation", "SelfAdjustingDecayingRunningAverage"); fs.put("Version", "1"); fs.put("CurrentValue", Double.toString(currentVal)); return fs; } }
------------------------------------------------------------------------
_______________________________________________ Devl mailing list [EMAIL PROTECTED] http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/devl
_______________________________________________ Devl mailing list [EMAIL PROTECTED] http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/devl
