1 package org.djutils.stats.summarizers.event;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertFalse;
5 import static org.junit.Assert.assertNotNull;
6 import static org.junit.Assert.assertTrue;
7 import static org.junit.Assert.fail;
8
9 import java.util.Calendar;
10
11 import org.djutils.event.Event;
12 import org.djutils.event.EventInterface;
13 import org.djutils.event.EventListenerInterface;
14 import org.djutils.event.EventType;
15 import org.djutils.event.TimedEvent;
16 import org.djutils.event.TimedEventType;
17 import org.djutils.metadata.MetaData;
18 import org.junit.Test;
19
20
21
22
23
24
25
26
27
28
29
30
31 public class EventBasedTimestampWeightedTallyTest
32 {
33
34 private static final TimedEventType TIMED_VALUE_EVENT = new TimedEventType("VALUE_EVENT", MetaData.NO_META_DATA);
35
36
37 @Test
38 public void testEventBasedTimestampWeightedTally()
39 {
40 String description = "THIS TIMESTAMP WEIGHTED TALLY IS TESTED";
41 EventBasedTimestampWeightedTally wt = new EventBasedTimestampWeightedTally(description);
42
43
44 assertEquals(description, wt.getDescription());
45 assertTrue(wt.toString().contains(description));
46
47
48 assertTrue(wt.isActive());
49 assertTrue(Double.isNaN(wt.getMin()));
50 assertTrue(Double.isNaN(wt.getMax()));
51 assertTrue(Double.isNaN(wt.getWeightedSampleMean()));
52 assertTrue(Double.isNaN(wt.getWeightedPopulationMean()));
53 assertTrue(Double.isNaN(wt.getWeightedSampleVariance()));
54 assertTrue(Double.isNaN(wt.getWeightedSampleStDev()));
55 assertEquals(0.0, wt.getWeightedSum(), 0.0);
56 assertEquals(0L, wt.getN());
57
58
59 try
60 {
61 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", "ERROR", 0.0));
62 fail("tally should fail on events.value !instanceOf Double");
63 }
64 catch (Exception exception)
65 {
66 assertNotNull(exception);
67 }
68
69
70 try
71 {
72 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "ERROR", 1.0, Double.NaN));
73 fail("tally should fail on events.timestamp == NaN");
74 }
75 catch (Exception exception)
76 {
77 assertNotNull(exception);
78 }
79
80
81 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 1.0, 0.0));
82 assertTrue(Double.isNaN(wt.getMin()));
83 assertTrue(Double.isNaN(wt.getMax()));
84 assertTrue(Double.isNaN(wt.getWeightedSampleMean()));
85 assertTrue(Double.isNaN(wt.getWeightedPopulationMean()));
86 assertTrue(Double.isNaN(wt.getWeightedSampleVariance()));
87 assertTrue(Double.isNaN(wt.getWeightedSampleStDev()));
88 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 1.1, 0.1));
89 assertEquals(1.0, wt.getMin(), 0.000001);
90 assertEquals(1.0, wt.getMax(), 0.000001);
91 assertEquals(1.0, wt.getWeightedSampleMean(), 0.000001);
92 assertEquals(1.0, wt.getWeightedPopulationMean(), 0.000001);
93 assertTrue(Double.isNaN(wt.getWeightedSampleVariance()));
94 assertTrue(Double.isNaN(wt.getWeightedSampleStDev()));
95 assertEquals(0, wt.getWeightedPopulationVariance(), 0.000001);
96 assertEquals(0, wt.getWeightedPopulationStDev(), 0.0000001);
97 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 1.2, 0.2));
98 assertFalse(Double.isNaN(wt.getWeightedSampleVariance()));
99 assertFalse(Double.isNaN(wt.getWeightedSampleStDev()));
100 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 1.3, 0.3));
101 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 1.4, 0.4));
102 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 1.5, 0.5));
103 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 1.6, 0.6));
104 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 1.7, 0.7));
105 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 1.8, 0.8));
106 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 1.9, 0.9));
107 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 2.0, 1.0));
108
109 try
110 {
111 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 123.456, 0.8));
112 fail("timestamp out of order should have thrown an exception");
113 }
114 catch (IllegalArgumentException iae)
115 {
116
117 }
118
119 assertTrue(wt.isActive());
120 wt.endObservations(1.1);
121 assertFalse(wt.isActive());
122
123
124 assertEquals(2.0, wt.getMax(), 1.0E-6);
125 assertEquals(1.0, wt.getMin(), 1.0E-6);
126 assertEquals(11, wt.getN());
127 assertEquals(1.5 * 0.1 * 11, wt.getWeightedSum(), 1.0E-6);
128 assertEquals(1.5, wt.getWeightedSampleMean(), 1.0E-6);
129
130
131 double varianceAccumulator = 0;
132 for (int i = 0; i < 11; i++)
133 {
134 varianceAccumulator += Math.pow(1.5 - (1.0 + i / 10.0), 2);
135 }
136 double variance = varianceAccumulator / 10.0;
137 double stDev = Math.sqrt(variance);
138 assertEquals(variance, wt.getWeightedSampleVariance(), 1.0E-6);
139 assertEquals(stDev, wt.getWeightedSampleStDev(), 1.0E-6);
140
141 variance = varianceAccumulator / 11.0;
142 stDev = Math.sqrt(variance);
143 assertEquals(variance, wt.getWeightedPopulationVariance(), 1.0E-6);
144 assertEquals(stDev, wt.getWeightedPopulationStDev(), 1.0E-6);
145
146
147 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 10.0, 20.0));
148 assertFalse(wt.isActive());
149 assertEquals(2.0, wt.getMax(), 1.0E-6);
150 assertEquals(1.0, wt.getMin(), 1.0E-6);
151 assertEquals(11, wt.getN());
152 assertEquals(1.5 * 0.1 * 11, wt.getWeightedSum(), 1.0E-6);
153 assertEquals(1.5, wt.getWeightedSampleMean(), 1.0E-6);
154
155
156 try
157 {
158 wt.notify(new Event(new EventType("VALUE_EVENT", new MetaData("VALUE_EVENT", "non-timed event")),
159 "EventBasedTimestampWeightedTallyTest", 123.456));
160 fail("non time-based event should have thrown an exception");
161 }
162 catch (Exception e)
163 {
164
165 }
166 try
167 {
168 wt.notify(new TimedEvent<String>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 123.456, "abc"));
169 fail("non time-based evenevent with timestamp != Calendar or Number should have thrown an exception");
170 }
171 catch (Exception e)
172 {
173
174 }
175
176 }
177
178
179 @Test
180 public void testEventBasedTimestampWeightedTallySimple()
181 {
182
183 EventBasedTimestampWeightedTally wt =
184 new EventBasedTimestampWeightedTally("simple EventBasedTimestampWeightedTally statistic");
185 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 86.0, 0.0));
186 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 26.0, 13.0));
187 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 0.0, 36.0));
188 wt.endObservations(40.0);
189
190 assertEquals(1716.0, wt.getWeightedSum(), 0.001);
191 assertEquals(42.9, wt.getWeightedSampleMean(), 0.001);
192 assertEquals(3, wt.getN());
193
194
195 wt = new EventBasedTimestampWeightedTally("simple EventBasedTimestampWeightedTally statistic");
196 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 86.0, 10.0));
197 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 26.0, 23.0));
198 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 0.0, 46.0));
199 wt.endObservations(50.0);
200
201 assertEquals(1716.0, wt.getWeightedSum(), 0.001);
202 assertEquals(42.9, wt.getWeightedSampleMean(), 0.001);
203 assertEquals(3, wt.getN());
204
205
206 wt = new EventBasedTimestampWeightedTally("simple EventBasedTimestampWeightedTally statistic");
207 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 86.0, 0.0));
208 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 26.0, 13.0));
209 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 0.0, 13.0));
210 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 26.0, 13.0));
211 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 0.0, 36.0));
212 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 0.0, 36.0));
213 wt.endObservations(40.0);
214
215 assertEquals(1716.0, wt.getWeightedSum(), 0.001);
216 assertEquals(42.9, wt.getWeightedSampleMean(), 0.001);
217 assertEquals(3, wt.getN());
218
219
220 wt = new EventBasedTimestampWeightedTally("NIST");
221 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 2, 0.0));
222 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 3, 1.0));
223 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 5, 2.0));
224 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 7, 2.0));
225 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 11, 2.0));
226 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 13, 6.0));
227 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 17, 7.0));
228 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 19, 9.0));
229 wt.notify(new TimedEvent<Double>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", 23, 10.0));
230 wt.endObservations(10.0);
231
232 assertEquals((2 + 3 + 4 * 11 + 13 + 2 * 17 + 19) / 10.0, wt.getWeightedSampleMean(), 0.001);
233 assertEquals(5.82, wt.getWeightedSampleStDev(), 0.01);
234 }
235
236
237 @Test
238 public void testEBTimestampWeightedTallyCalendarNotify()
239 {
240 String description = "THIS TIMESTAMP WEIGHTED TALLY IS TESTED";
241 EventBasedTimestampWeightedTally wt = new EventBasedTimestampWeightedTally(description);
242
243 int index = 10;
244 for (int second = 30; second <= 40; second++)
245 {
246 Calendar calendar = new Calendar.Builder().setDate(2000, 2, 2).setTimeOfDay(4, 12, second, 10).build();
247 wt.notify(new TimedEvent<Calendar>(TIMED_VALUE_EVENT, "EventBasedTimestampWeightedTallyTest", index++, calendar));
248 }
249 assertTrue(wt.isActive());
250 wt.endObservations(new Calendar.Builder().setDate(2000, 2, 2).setTimeOfDay(4, 12, 41, 10).build());
251 assertFalse(wt.isActive());
252
253
254 assertEquals(20.0, wt.getMax(), 1.0E-6);
255 assertEquals(10.0, wt.getMin(), 1.0E-6);
256 assertEquals(11, wt.getN());
257 assertEquals(1.5 * 10000 * 11, wt.getWeightedSum(), 1.0E-2);
258 assertEquals(15.0, wt.getWeightedSampleMean(), 1.0E-6);
259
260
261 double variance = 0;
262 for (int i = 0; i < 11; i++)
263 {
264 variance += Math.pow(15.0 - (10 + i), 2);
265 }
266 variance = variance / 10.0;
267 double stDev = Math.sqrt(variance);
268
269 assertEquals(variance, wt.getWeightedSampleVariance(), 1.0E-6);
270 assertEquals(stDev, wt.getWeightedSampleStDev(), 1.0E-6);
271 }
272
273
274 @Test
275 public void testEBTimestampWeightedTallyCalendarregister()
276 {
277 String description = "THIS TIMESTAMP WEIGHTED TALLY IS TESTED";
278 EventBasedTimestampWeightedTally wt = new EventBasedTimestampWeightedTally(description);
279
280 int index = 10;
281 for (int second = 30; second <= 40; second++)
282 {
283 Calendar calendar = new Calendar.Builder().setDate(2000, 2, 2).setTimeOfDay(4, 12, second, 10).build();
284 wt.register(calendar, index++);
285 }
286 assertTrue(wt.isActive());
287 wt.endObservations(new Calendar.Builder().setDate(2000, 2, 2).setTimeOfDay(4, 12, 41, 10).build());
288 assertFalse(wt.isActive());
289
290
291 assertEquals(20.0, wt.getMax(), 1.0E-6);
292 assertEquals(10.0, wt.getMin(), 1.0E-6);
293 assertEquals(11, wt.getN());
294 assertEquals(1.5 * 10000 * 11, wt.getWeightedSum(), 1.0E-2);
295 assertEquals(15.0, wt.getWeightedSampleMean(), 1.0E-6);
296
297
298 double variance = 0;
299 for (int i = 0; i < 11; i++)
300 {
301 variance += Math.pow(15.0 - (10 + i), 2);
302 }
303 variance = variance / 10.0;
304 double stDev = Math.sqrt(variance);
305
306 assertEquals(variance, wt.getWeightedSampleVariance(), 1.0E-6);
307 assertEquals(stDev, wt.getWeightedSampleStDev(), 1.0E-6);
308 }
309
310
311
312
313 @Test
314 public void testWeightedTallyEventProduction()
315 {
316 EventBasedTimestampWeightedTally timestampedTally = new EventBasedTimestampWeightedTally("testTally");
317 assertEquals(timestampedTally, timestampedTally.getSourceId());
318 TimestampedObservationEventListener toel = new TimestampedObservationEventListener();
319 timestampedTally.addListener(toel, StatisticsEvents.TIMESTAMPED_OBSERVATION_ADDED_EVENT);
320 assertEquals(0, toel.getObservationEvents());
321
322 TimedEventType[] types = new TimedEventType[] {StatisticsEvents.TIMED_N_EVENT, StatisticsEvents.TIMED_MIN_EVENT,
323 StatisticsEvents.TIMED_MAX_EVENT, StatisticsEvents.TIMED_WEIGHTED_POPULATION_MEAN_EVENT,
324 StatisticsEvents.TIMED_WEIGHTED_POPULATION_VARIANCE_EVENT,
325 StatisticsEvents.TIMED_WEIGHTED_POPULATION_STDEV_EVENT, StatisticsEvents.TIMED_WEIGHTED_SUM_EVENT,
326 StatisticsEvents.TIMED_WEIGHTED_SAMPLE_MEAN_EVENT, StatisticsEvents.TIMED_WEIGHTED_SAMPLE_VARIANCE_EVENT,
327 StatisticsEvents.TIMED_WEIGHTED_SAMPLE_STDEV_EVENT};
328 LoggingEventListener[] listeners = new LoggingEventListener[types.length];
329 for (int i = 0; i < types.length; i++)
330 {
331 listeners[i] = new LoggingEventListener();
332 timestampedTally.addListener(listeners[i], types[i]);
333 }
334
335 double prevTime = 0.0;
336 for (int i = 1; i <= 10; i++)
337 {
338 timestampedTally.register(prevTime, 10.0 * i);
339 prevTime += i;
340 }
341 timestampedTally.endObservations(prevTime);
342
343
344 assertEquals(11, toel.getObservationEvents());
345
346
347 Object[] expectedValues = new Object[] {10L, 10.0, 100.0, 70.0, 600.0, 24.4949, 3850.0, 70.0, 666.6667, 25.81989};
348 for (int i = 0; i < types.length; i++)
349 {
350 assertEquals("Number of events for listener " + types[i], 11, listeners[i].getNumberOfEvents());
351 assertEquals("Event sourceId for listener " + types[i], timestampedTally,
352 listeners[i].getLastEvent().getSourceId());
353 assertEquals("Event type for listener " + types[i], types[i], listeners[i].getLastEvent().getType());
354 if (expectedValues[i] instanceof Long)
355 {
356 assertEquals("Final value for listener " + types[i], expectedValues[i],
357 listeners[i].getLastEvent().getContent());
358 }
359 else
360 {
361 double e = ((Double) expectedValues[i]).doubleValue();
362 double c = ((Double) listeners[i].getLastEvent().getContent()).doubleValue();
363 assertEquals("Final value for listener " + types[i], e, c, 0.001);
364 }
365 }
366 }
367
368
369 class TimestampedObservationEventListener implements EventListenerInterface
370 {
371
372 private static final long serialVersionUID = 1L;
373
374
375 private int observationEvents = 0;
376
377 @Override
378 public void notify(final EventInterface event)
379 {
380 assertTrue(event.getType().equals(StatisticsEvents.TIMESTAMPED_OBSERVATION_ADDED_EVENT));
381 assertTrue("Content of the event has a wrong type, not Object[]: " + event.getContent().getClass(),
382 event.getContent() instanceof Object[]);
383 Object[] c = (Object[]) event.getContent();
384 assertTrue("Content[0] of the event has a wrong type, not double: " + c[0].getClass(), c[0] instanceof Double);
385 assertTrue("Content[1] of the event has a wrong type, not double: " + c[1].getClass(), c[1] instanceof Double);
386 assertTrue("SourceId of the event has a wrong type, not EventBasedTimestampWeightedTally: "
387 + event.getSourceId().getClass(), event.getSourceId() instanceof EventBasedTimestampWeightedTally);
388 this.observationEvents++;
389 }
390
391
392
393
394 public int getObservationEvents()
395 {
396 return this.observationEvents;
397 }
398 }
399
400 }