1 package org.opentrafficsim.road.gtu.lane.perception.categories; 2 3 import org.djunits.value.vdouble.scalar.Duration; 4 import org.djunits.value.vdouble.scalar.Time; 5 import org.opentrafficsim.core.dsol.OTSSimulatorInterface; 6 7 import nl.tudelft.simulation.jstats.distributions.DistNormal; 8 import nl.tudelft.simulation.jstats.streams.StreamInterface; 9 10 /** 11 * A numerical update scheme that represents a Wiener process if {@code dt << tau}. A Wiener process is a process that results 12 * in random values that follow a Normal distribution with parameters mu and sigma. However, there is a time progression with 13 * correlation {@code tau}, such that the process has a tendency to stay close to the previous value. The correlation time 14 * {@code tau} is a measure for this tendency. Given sufficient time (and {@code dt << tau}) the overall probability remains 15 * equal to the Normal distribution. 16 * <p> 17 * The Wiener process is typically used for measurement or perception errors in cases where the error of two consecutive time 18 * steps is unlikely to deviate much. 19 * <p> 20 * Treiber, M., A. Kesting, D. Helbing (2006) "Delays, Inaccuracies and Anticipation in Microscopic Traffic Models", Physica A – 21 * Statistical Mechanics and its Applications, Vol. 360, Issue 1, pp. 71-88. 22 * <p> 23 * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br> 24 * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>. 25 * <p> 26 * @version $Revision$, $LastChangedDate$, by $Author$, initial version 18 okt. 2018 <br> 27 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a> 28 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a> 29 * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a> 30 */ 31 public class WienerProcess extends DistNormal 32 { 33 34 /** */ 35 private static final long serialVersionUID = 20181018L; 36 37 /** Simulator. */ 38 private final OTSSimulatorInterface simulator; 39 40 /** Mean. */ 41 private final double muW; 42 43 /** Standard deviation. */ 44 private final double sigmaW; 45 46 /** Correlation time. */ 47 private final Duration tau; 48 49 /** Value of the standard Wiener process (mu = 0, sigma = 1). */ 50 private Double value; 51 52 /** Time the value was determined. */ 53 private Time prevTime; 54 55 /** 56 * @param stream StreamInterface; random number stream 57 * @param mu double; mean 58 * @param sigma double; standard deviation 59 * @param tau Duration; correlation time 60 * @param simulator OTSSimulatorInterface; simulator 61 */ 62 public WienerProcess(final StreamInterface stream, final double mu, final double sigma, final Duration tau, 63 final OTSSimulatorInterface simulator) 64 { 65 super(stream); 66 this.muW = mu; 67 this.sigmaW = sigma; 68 this.tau = tau; 69 this.simulator = simulator; 70 } 71 72 /** {@inheritDoc} */ 73 @Override 74 public double draw() 75 { 76 if (this.value == null) 77 { 78 this.value = super.draw(); 79 this.prevTime = this.simulator.getSimulatorTime(); 80 } 81 else if (this.simulator.getSimulatorTime().gt(this.prevTime)) 82 { 83 // calculate next value 84 Time now = this.simulator.getSimulatorTime(); 85 double dt = now.si - this.prevTime.si; 86 if (dt <= this.tau.si) 87 { 88 this.value = Math.exp(-dt / this.tau.si) * this.value + Math.sqrt((2 * dt) / this.tau.si) * super.draw(); 89 } 90 else 91 { 92 // too long ago, exp may result in extreme values, draw new independent value 93 this.value = super.draw(); 94 } 95 this.prevTime = now; 96 } 97 return this.muW + this.value * this.sigmaW; 98 } 99 100 }