package org.djutils.stats.summarizers; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.djutils.event.Event; import org.djutils.event.EventType; import org.junit.Test; /** * The EventBasedWeightedTallyTest tests the EventBasedWeightedTally. *
* Copyright (c) 2002-2020 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
* for project information https://simulation.tudelft.nl. The DSOL
* project is distributed under a three-clause BSD-style license, which can be found at
*
* https://simulation.tudelft.nl/dsol/3.0/license.html.
*
* @author Peter Jacobs
* @since 1.5
*/
public class EventBasedWeightedTallyTest
{
/** an event to fire. */
private static final EventType VALUE_EVENT = new EventType("VALUE_EVENT");
/** Test the EventBasedWeightedTally. */
@Test
public void testEventBasedWeightedTally()
{
String description = "THIS EVENT BASED WEIGHTED TALLY IS TESTED";
EventBasedWeightedTally wt = new EventBasedWeightedTally(description);
// check the description
assertEquals(description, wt.getDescription());
assertTrue(wt.toString().contains(description));
// now we check the initial values
assertTrue(Double.isNaN(wt.getMin()));
assertTrue(Double.isNaN(wt.getMax()));
assertTrue(Double.isNaN(wt.getWeightedSampleMean()));
assertTrue(Double.isNaN(wt.getWeightedSampleVariance()));
assertTrue(Double.isNaN(wt.getWeightedSampleStDev()));
assertEquals(0.0, wt.getWeightedSum(), 0.0);
assertEquals(0L, wt.getN());
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0.1, 1.1}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0.1, 1.2}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0.1, 1.3}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0.1, 1.4}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0.1, 1.5}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0.1, 1.6}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0.1, 1.7}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0.1, 1.8}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0.1, 1.9}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0.1, 2.0}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0.1, 1.0}));
// Now we check the EventBasedWeightedTally
assertEquals(2.0, wt.getMax(), 1.0E-6);
assertEquals(1.0, wt.getMin(), 1.0E-6);
assertEquals(11, wt.getN());
assertEquals(1.5 * 0.1 * 11, wt.getWeightedSum(), 1.0E-6);
assertEquals(1.5, wt.getWeightedSampleMean(), 1.0E-6);
assertEquals(0.316228, wt.getWeightedStDev(), 1.0E-6); // Computed with Excel sheet
assertEquals(0.100000, wt.getWeightedVariance(), 1.0E-6);
assertEquals(0.331662, wt.getWeightedSampleStDev(), 1.0E-6); // Computed with Excel sheet
assertEquals(0.110000, wt.getWeightedSampleVariance(), 1.0E-6);
// Let's compute the standard deviation
double variance = 0;
for (int i = 0; i < 11; i++)
{
variance += Math.pow(1.5 - (1.0 + i / 10.0), 2);
}
variance = variance / 10.0;
double stDev = Math.sqrt(variance);
assertEquals(variance, wt.getWeightedSampleVariance(), 1.0E-6);
assertEquals(stDev, wt.getWeightedSampleStDev(), 1.0E-6);
try
{
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {-0.1, 123.456}));
fail("negative weight should have thrown an exception");
}
catch (IllegalArgumentException iae)
{
// Ignore expected exception
}
try
{
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", "123"));
fail("non Object[] content should have thrown an exception");
}
catch (IllegalArgumentException iae)
{
// Ignore expected exception
}
try
{
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0.1}));
fail("Object[] with one argument should have thrown an exception");
}
catch (IllegalArgumentException iae)
{
// Ignore expected exception
}
try
{
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0.1, 0.2, 0.3}));
fail("Object[] with thre arguments should have thrown an exception");
}
catch (IllegalArgumentException iae)
{
// Ignore expected exception
}
try
{
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {"bla", 0.2}));
fail("EventBasedWeightedTally should fail on weight !instanceOf Double");
}
catch (Exception exception)
{
assertNotNull(exception);
}
try
{
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0.3, "bla"}));
fail("EventBasedWeightedTally should fail on value !instanceOf Double");
}
catch (Exception exception)
{
assertNotNull(exception);
}
}
/** Test the EventBasedWeightedTally on a simple example. */
@Test
public void testEventBasedWeightedTallySimple()
{
// From: https://sciencing.com/calculate-time-decimals-5962681.html
EventBasedWeightedTally wt = new EventBasedWeightedTally("simple EventBasedWeightedTally statistic");
wt.initialize();
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {13.0, 86.0}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {23.0, 26.0}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {4.0, 0.0}));
assertEquals(1716.0, wt.getWeightedSum(), 0.001);
assertEquals(42.9, wt.getWeightedSampleMean(), 0.001);
// When we shift the times, we should get the same answers
wt = new EventBasedWeightedTally("simple EventBasedWeightedTally statistic");
wt.initialize();
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {13.0, 86.0}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {23.0, 26.0}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {14.0, 0.0}));
assertEquals(1716.0, wt.getWeightedSum(), 0.001);
assertEquals(34.32, wt.getWeightedSampleMean(), 0.001);
// When we have observations with duration 0, we should get the same answers
wt = new EventBasedWeightedTally("simple EventBasedWeightedTally statistic");
wt.initialize();
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {13.0, 86.0}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0.0, 86.0}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {23.0, 26.0}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {4.0, 0.0}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0.0, 0.0}));
assertEquals(1716.0, wt.getWeightedSum(), 0.001);
assertEquals(42.9, wt.getWeightedSampleMean(), 0.001);
// Example from NIST: https://www.itl.nist.gov/div898/software/dataplot/refman2/ch2/weightsd.pdf
wt = new EventBasedWeightedTally("NIST");
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {1, 2}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {1, 3}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0, 5}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0, 7}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {4, 11}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {1, 13}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {2, 17}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {1, 19}));
wt.notify(new Event(VALUE_EVENT, "EventBasedWeightedTallyTest", new Object[] {0, 23}));
assertEquals((2 + 3 + 4 * 11 + 13 + 2 * 17 + 19) / 10.0, wt.getWeightedSampleMean(), 0.001);
assertEquals(5.82, wt.getWeightedSampleStDev(), 0.01);
}
}