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

Reply via email to