1
2
3
4
5
6
7
8
9
10 package nl.tudelft.simulation.jstats.statistics;
11
12 import nl.tudelft.simulation.event.EventInterface;
13 import nl.tudelft.simulation.event.EventType;
14 import nl.tudelft.simulation.event.TimedEvent;
15 import nl.tudelft.simulation.logger.Logger;
16
17 /***
18 * The Persisten class defines a statistics event persistent. A Persistent is a
19 * time-averaged tally.
20 * <p>
21 * (c) copyright 2003-2004 <a href="http://www.simulation.tudelft.nl">Delft
22 * University of Technology </a>, the Netherlands. <br>
23 * See for project information <a
24 * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
25 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
26 * License (GPL) </a>, no warranty <br>
27 *
28 * @author <a href="http://www.simulation.tudelft.nl/people/jacobs.html">Peter
29 * Jacobs </a>
30 * @version 1.15, 2004-03-23
31 * @since 1.2
32 */
33 public class Persistent extends Tally
34 {
35 /*** VALUE_EVENT is fired whenever on a change in measurements */
36 public static final EventType VALUE_EVENT = new EventType("VALUE_EVENT");
37
38 /*** startTime defines the time of the first event */
39 private double startTime = Double.NaN;
40
41 /*** elapsedTime tracks the elapsed time */
42 private double elapsedTime = Double.NaN;
43
44 /*** deltaTime defines the time between 2 events */
45 private double deltaTime = Double.NaN;
46
47 /*** lastvalue tracks the last value */
48 private double lastValue = Double.NaN;
49
50 /***
51 * constructs a new Persistent with a description.
52 *
53 * @param description the description of this Persistent
54 */
55 public Persistent(final String description)
56 {
57 super(description);
58 }
59
60 /***
61 * @see nl.tudelft.simulation.jstats.statistics.Tally#getStdDev()
62 */
63 public double getStdDev()
64 {
65 synchronized (this.semaphore)
66 {
67 if (super.n > 1)
68 {
69 return Math.sqrt(super.varianceSum
70 / (this.elapsedTime - this.deltaTime));
71 }
72 return Double.NaN;
73 }
74 }
75
76 /***
77 * @see nl.tudelft.simulation.jstats.statistics.Tally#getSampleVariance()
78 */
79 public double getSampleVariance()
80 {
81 synchronized (this.semaphore)
82 {
83 if (super.n > 1)
84 {
85 return super.varianceSum / (this.elapsedTime - this.deltaTime);
86 }
87 return Double.NaN;
88 }
89 }
90
91 /***
92 * @see nl.tudelft.simulation.jstats.statistics.Tally#initialize()
93 */
94 public void initialize()
95 {
96 synchronized (this.semaphore)
97 {
98 super.initialize();
99 this.deltaTime = 0.0;
100 this.elapsedTime = 0.0;
101 this.lastValue = 0.0;
102 }
103 }
104
105 /***
106 * @see nl.tudelft.simulation.jstats.statistics.Tally
107 * #notify(nl.tudelft.simulation.event.EventInterface)
108 */
109 public void notify(final EventInterface event)
110 {
111 if (!(event instanceof TimedEvent)
112 || !(event.getContent() instanceof Number))
113 {
114 throw new IllegalArgumentException(
115 "event !=TimedEvent || event.source !=Double ("
116 + event.getContent().getClass().toString() + ")");
117 }
118 TimedEvent timedEvent = (TimedEvent) event;
119 double value = 0.0;
120 if (event.getContent() instanceof Number)
121 {
122 value = ((Number) event.getContent()).doubleValue();
123 } else
124 {
125 Logger.warning(this, "notify", event.getContent()
126 + "should be a number.");
127 }
128 synchronized (this.semaphore)
129 {
130 super.fireEvent(Persistent.VALUE_EVENT, this.lastValue, timedEvent
131 .getTimeStamp());
132 super.fireEvent(Persistent.VALUE_EVENT, value, timedEvent
133 .getTimeStamp());
134 super.setN(super.n + 1);
135
136 if (value < super.min)
137 {
138 super.setMin(value);
139 }
140 if (value > super.max)
141 {
142 super.setMax(value);
143 }
144 super.setSum(super.sum + value);
145
146
147
148 if (this.n == 1)
149 {
150 super.setSampleMean(value);
151 this.startTime = timedEvent.getTimeStamp();
152 } else
153 {
154 this.deltaTime = timedEvent.getTimeStamp()
155 - (this.elapsedTime + this.startTime);
156 if (this.deltaTime > 0.0)
157 {
158 double newAverage = ((super.sampleMean * (this.elapsedTime)) + (this.lastValue * this.deltaTime))
159 / (this.elapsedTime + this.deltaTime);
160 super.varianceSum += (this.lastValue - super.sampleMean)
161 * (this.lastValue - newAverage) * this.deltaTime;
162 super.setSampleMean(newAverage);
163 this.elapsedTime = this.elapsedTime + this.deltaTime;
164 }
165 }
166 if (this.n > 1)
167 {
168 super.fireEvent(Tally.STANDARD_DEVIATION_EVENT, this
169 .getStdDev());
170 this.fireEvent(Tally.SAMPLE_VARIANCE_EVENT, this
171 .getSampleVariance());
172 }
173 this.lastValue = value;
174 }
175 }
176 }