/* * JASA Java Auction Simulator API * Copyright (C) 2013 Steve Phelps * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at e;your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. */ package net.sourceforge.jabm.learning; import java.io.Serializable; import net.sourceforge.jabm.report.DataWriter; import net.sourceforge.jabm.util.Prototypeable; import cern.jet.random.AbstractContinousDistribution; import cern.jet.random.Uniform; import cern.jet.random.engine.RandomEngine; /** * An implementation of the Widrow-Hoff learning algorithm for 1-dimensional * training sets. * * @author Steve Phelps * @version $Revision: 306 $ */ public class WidrowHoffLearner extends AbstractLearner implements MimicryLearner, Prototypeable, Serializable { /** * The learning rate. */ protected double learningRate; /** * The current output level. */ protected double currentOutput; /** * The current amount of adjustment to the output. */ protected double delta; protected AbstractContinousDistribution randomParamDistribution; public static final double DEFAULT_LEARNING_RATE = 0.1; public WidrowHoffLearner(double learningRate, AbstractContinousDistribution randomParamDistribution) { this.randomParamDistribution = randomParamDistribution; this.learningRate = learningRate; initialise(); } public WidrowHoffLearner(AbstractContinousDistribution randomParamDistribution) { this(DEFAULT_LEARNING_RATE, randomParamDistribution); } public WidrowHoffLearner() { this(null); } public WidrowHoffLearner(double learningRate, RandomEngine prng) { this(learningRate, new Uniform(0.1, 0.4, prng)); } // // public WidrowHoffLearner(RandomEngine prng) { // this(DEFAULT_LEARNING_RATE, prng); // } // public void setup(ParameterDatabase parameters, Parameter base) { // super.setup(parameters, base); // learningRate = parameters.getDoubleWithDefault(base.push(P_LEARNINGRATE), // new Parameter(P_DEF_BASE).push(P_LEARNINGRATE), DEFAULT_LEARNING_RATE); // } public void initialise() { delta = 0; currentOutput = 0; } public Object protoClone() { WidrowHoffLearner clone = new WidrowHoffLearner(learningRate, this.randomParamDistribution); return clone; } public double act() { return currentOutput; } public void train(double target) { currentOutput += delta(target); } public double delta(double target) { delta = learningRate * (target - currentOutput); return delta; } public void setOutputLevel(double currentOutput) { this.currentOutput = currentOutput; } public void dumpState(DataWriter out) { // TODO } public double getLearningDelta() { return delta; } public void reset() { initialise(); } public void setLearningRate(double learningRate) { this.learningRate = learningRate; } public double getLearningRate() { return learningRate; } public void randomInitialise() { learningRate = randomParamDistribution.nextDouble(); } public double getCurrentOutput() { return currentOutput; } public double getDelta() { return delta; } public AbstractContinousDistribution getRandomParamDistribution() { return randomParamDistribution; } public void setRandomParamDistribution( AbstractContinousDistribution randomParamDistribution) { this.randomParamDistribution = randomParamDistribution; } public String toString() { return "(" + getClass().getSimpleName() + " learningRate:" + learningRate + ")"; } }