1 package org.djutils.stats.summarizers.event;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertNotNull;
5 import static org.junit.Assert.assertTrue;
6 import static org.junit.Assert.fail;
7
8 import org.djutils.event.Event;
9 import org.djutils.event.EventInterface;
10 import org.djutils.event.EventListenerInterface;
11 import org.djutils.event.EventType;
12 import org.djutils.metadata.MetaData;
13 import org.djutils.metadata.ObjectDescriptor;
14 import org.junit.Test;
15
16
17
18
19
20
21
22
23
24
25
26
27 public class EventBasedWeightedTallyTest
28 {
29
30 private static final EventType VALUE_EVENT = new EventType("VALUE_EVENT",
31 new MetaData("WeightAndValue", "Double[] with Double weight and Double value ",
32 new ObjectDescriptor[] { new ObjectDescriptor("Weight", "Double weight", Double.class),
33 new ObjectDescriptor("Valuie", "Double value", Double.class) }));
34
35
36 @Test
37 public void testEventBasedWeightedTally()
38 {
39 String description = "THIS EVENT BASED WEIGHTED TALLY IS TESTED";
40 EventBasedWeightedTally wt = new EventBasedWeightedTally(description);
41
42
43 assertEquals(description, wt.getDescription());
44 assertTrue(wt.toString().contains(description));
45
46
47 assertTrue(Double.isNaN(wt.getMin()));
48 assertTrue(Double.isNaN(wt.getMax()));
49 assertTrue(Double.isNaN(wt.getWeightedSampleMean()));
50 assertTrue(Double.isNaN(wt.getWeightedSampleVariance()));
51 assertTrue(Double.isNaN(wt.getWeightedSampleStDev()));
52 assertEquals(0.0, wt.getWeightedSum(), 0.0);
53 assertEquals(0L, wt.getN());
54
55 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0.1, 1.1 }));
56 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0.1, 1.2 }));
57 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0.1, 1.3 }));
58 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0.1, 1.4 }));
59 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0.1, 1.5 }));
60 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0.1, 1.6 }));
61 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0.1, 1.7 }));
62 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0.1, 1.8 }));
63 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0.1, 1.9 }));
64 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0.1, 2.0 }));
65 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0.1, 1.0 }));
66
67
68 assertEquals(2.0, wt.getMax(), 1.0E-6);
69 assertEquals(1.0, wt.getMin(), 1.0E-6);
70 assertEquals(11, wt.getN());
71 assertEquals(1.5 * 0.1 * 11, wt.getWeightedSum(), 1.0E-6);
72 assertEquals(1.5, wt.getWeightedSampleMean(), 1.0E-6);
73 assertEquals(0.316228, wt.getWeightedPopulationStDev(), 1.0E-6);
74 assertEquals(0.100000, wt.getWeightedPopulationVariance(), 1.0E-6);
75 assertEquals(0.331662, wt.getWeightedSampleStDev(), 1.0E-6);
76 assertEquals(0.110000, wt.getWeightedSampleVariance(), 1.0E-6);
77
78
79 double variance = 0;
80 for (int i = 0; i < 11; i++)
81 {
82 variance += Math.pow(1.5 - (1.0 + i / 10.0), 2);
83 }
84 variance = variance / 10.0;
85 double stDev = Math.sqrt(variance);
86
87 assertEquals(variance, wt.getWeightedSampleVariance(), 1.0E-6);
88 assertEquals(stDev, wt.getWeightedSampleStDev(), 1.0E-6);
89
90 try
91 {
92 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { -0.1, 123.456 }));
93 fail("negative weight should have thrown an exception");
94 }
95 catch (IllegalArgumentException iae)
96 {
97
98 }
99 try
100 {
101 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", "123"));
102 fail("non Object[] content should have thrown an exception");
103 }
104 catch (IndexOutOfBoundsException iobe)
105 {
106
107 }
108 try
109 {
110 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0.1 }));
111 fail("Object[] with one argument should have thrown an exception");
112 }
113 catch (IndexOutOfBoundsException iae)
114 {
115
116 }
117 try
118 {
119 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0.1, 0.2, 0.3 }));
120 fail("Object[] with thre arguments should have thrown an exception");
121 }
122 catch (IndexOutOfBoundsException iae)
123 {
124
125 }
126 try
127 {
128 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { "bla", 0.2 }));
129 fail("EventBasedWeightedTally should fail on weight !instanceOf Double");
130 }
131 catch (Exception exception)
132 {
133 assertNotNull(exception);
134 }
135 try
136 {
137 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0.3, "bla" }));
138 fail("EventBasedWeightedTally should fail on value !instanceOf Double");
139 }
140 catch (Exception exception)
141 {
142 assertNotNull(exception);
143 }
144
145 }
146
147
148 @Test
149 public void testEventBasedWeightedTallySimple()
150 {
151
152 EventBasedWeightedTally wt = new EventBasedWeightedTally("simple EventBasedWeightedTally statistic");
153 wt.initialize();
154 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 13.0, 86.0 }));
155 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 23.0, 26.0 }));
156 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 4.0, 0.0 }));
157
158 assertEquals(1716.0, wt.getWeightedSum(), 0.001);
159 assertEquals(42.9, wt.getWeightedSampleMean(), 0.001);
160
161
162 wt = new EventBasedWeightedTally("simple EventBasedWeightedTally statistic");
163 wt.initialize();
164 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 13.0, 86.0 }));
165 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 23.0, 26.0 }));
166 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 14.0, 0.0 }));
167
168 assertEquals(1716.0, wt.getWeightedSum(), 0.001);
169 assertEquals(34.32, wt.getWeightedSampleMean(), 0.001);
170
171
172 wt = new EventBasedWeightedTally("simple EventBasedWeightedTally statistic");
173 wt.initialize();
174 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 13.0, 86.0 }));
175 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0.0, 86.0 }));
176 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 23.0, 26.0 }));
177 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 4.0, 0.0 }));
178 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0.0, 0.0 }));
179
180 assertEquals(1716.0, wt.getWeightedSum(), 0.001);
181 assertEquals(42.9, wt.getWeightedSampleMean(), 0.001);
182
183
184 wt = new EventBasedWeightedTally("NIST");
185 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 1d, 2d }));
186 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 1d, 3d }));
187 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0d, 5d }));
188 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0d, 7d }));
189 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 4d, 11d }));
190 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 1d, 13d }));
191 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 2d, 17d }));
192 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 1d, 19d }));
193 wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] { 0d, 23d }));
194
195 assertEquals((2 + 3 + 4 * 11 + 13 + 2 * 17 + 19) / 10.0, wt.getWeightedSampleMean(), 0.001);
196 assertEquals(5.82, wt.getWeightedSampleStDev(), 0.01);
197 }
198
199
200
201
202 @Test
203 public void testWeightedTallyEventProduction()
204 {
205 EventBasedWeightedTally weightedTally = new EventBasedWeightedTally("testTally");
206 assertEquals(weightedTally, weightedTally.getSourceId());
207 WeightedObservationEventListener woel = new WeightedObservationEventListener();
208 weightedTally.addListener(woel, StatisticsEvents.WEIGHTED_OBSERVATION_ADDED_EVENT);
209 assertEquals(0, woel.getObservationEvents());
210
211 EventType[] types = new EventType[] { StatisticsEvents.N_EVENT, StatisticsEvents.MIN_EVENT, StatisticsEvents.MAX_EVENT,
212 StatisticsEvents.WEIGHTED_POPULATION_MEAN_EVENT, StatisticsEvents.WEIGHTED_POPULATION_VARIANCE_EVENT,
213 StatisticsEvents.WEIGHTED_POPULATION_STDEV_EVENT, StatisticsEvents.WEIGHTED_SUM_EVENT,
214 StatisticsEvents.WEIGHTED_SAMPLE_MEAN_EVENT, StatisticsEvents.WEIGHTED_SAMPLE_VARIANCE_EVENT,
215 StatisticsEvents.WEIGHTED_SAMPLE_STDEV_EVENT };
216 LoggingEventListener[] listeners = new LoggingEventListener[types.length];
217 for (int i = 0; i < types.length; i++)
218 {
219 listeners[i] = new LoggingEventListener();
220 weightedTally.addListener(listeners[i], types[i]);
221 }
222
223 for (int i = 1; i <= 10; i++)
224 {
225 weightedTally.register(1.0 * i, 10.0 * i);
226 }
227
228 assertEquals(10, woel.getObservationEvents());
229
230
231 Object[] expectedValues = new Object[] { 10L, 10.0, 100.0, 70.0, 600.0, 24.4949, 3850.0, 70.0, 666.6667, 25.81989 };
232 for (int i = 0; i < types.length; i++)
233 {
234 assertEquals("Number of events for listener " + types[i], 10, listeners[i].getNumberOfEvents());
235 assertEquals("Event sourceId for listener " + types[i], weightedTally, listeners[i].getLastEvent().getSourceId());
236 assertEquals("Event type for listener " + types[i], types[i], listeners[i].getLastEvent().getType());
237 if (expectedValues[i] instanceof Long)
238 {
239 assertEquals("Final value for listener " + types[i], expectedValues[i],
240 listeners[i].getLastEvent().getContent());
241 }
242 else
243 {
244 double e = ((Double) expectedValues[i]).doubleValue();
245 double c = ((Double) listeners[i].getLastEvent().getContent()).doubleValue();
246 assertEquals("Final value for listener " + types[i], e, c, 0.001);
247 }
248 }
249 }
250
251
252 class WeightedObservationEventListener implements EventListenerInterface
253 {
254
255 private static final long serialVersionUID = 1L;
256
257
258 private int observationEvents = 0;
259
260 @Override
261 public void notify(final EventInterface event)
262 {
263 assertTrue(event.getType().equals(StatisticsEvents.WEIGHTED_OBSERVATION_ADDED_EVENT));
264 assertTrue("Content of the event has a wrong type, not Object[]: " + event.getContent().getClass(),
265 event.getContent() instanceof Object[]);
266 Object[] c = (Object[]) event.getContent();
267 assertTrue("Content[0] of the event has a wrong type, not double: " + c[0].getClass(), c[0] instanceof Double);
268 assertTrue("Content[1] of the event has a wrong type, not double: " + c[1].getClass(), c[1] instanceof Double);
269 assertTrue("SourceId of the event has a wrong type, not EventBasedWeightedTally: " + event.getSourceId().getClass(),
270 event.getSourceId() instanceof EventBasedWeightedTally);
271 this.observationEvents++;
272 }
273
274
275
276
277 public int getObservationEvents()
278 {
279 return this.observationEvents;
280 }
281 }
282
283 }