package org.djutils.stats.summarizers.event; import java.io.Serializable; import org.djutils.event.Event; import org.djutils.event.EventInterface; import org.djutils.event.EventListenerInterface; import org.djutils.event.EventProducer; import org.djutils.exceptions.Throw; import org.djutils.stats.summarizers.WeightedTally; import org.djutils.stats.summarizers.WeightedTallyInterface; /** * The EventBasedWeightedTally class defines a time-weighted tally that can be notified with weights and values using the * EventListenerInterface. It also produces events when values are tallied and when the tally is initialized. *
* Copyright (c) 2002-2021 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 Alexander Verbraeck
* @author Peter Knoppers
*/
public class EventBasedWeightedTally extends EventProducer implements EventListenerInterface, WeightedTallyInterface
{
/** */
private static final long serialVersionUID = 20200228L;
/** the wrapped WeightedTally. */
private final WeightedTally wrappedWeightedTally;
/**
* Construct a new WeightedTally with a description.
* @param description String; the description of this WeightedTally
*/
public EventBasedWeightedTally(final String description)
{
this.wrappedWeightedTally = new WeightedTally(description);
}
/** {@inheritDoc} */
@Override
public Serializable getSourceId()
{
return this;
}
/** {@inheritDoc} */
@Override
public final String getDescription()
{
return this.wrappedWeightedTally.getDescription();
}
/** {@inheritDoc} */
@Override
public final double getMax()
{
return this.wrappedWeightedTally.getMax();
}
/** {@inheritDoc} */
@Override
public final double getMin()
{
return this.wrappedWeightedTally.getMin();
}
/** {@inheritDoc} */
@Override
public final long getN()
{
return this.wrappedWeightedTally.getN();
}
/** {@inheritDoc} */
@Override
public final double getWeightedSampleMean()
{
return this.wrappedWeightedTally.getWeightedSampleMean();
}
/** {@inheritDoc} */
@Override
public final double getWeightedSampleStDev()
{
return this.wrappedWeightedTally.getWeightedSampleStDev();
}
/** {@inheritDoc} */
@Override
public final double getWeightedPopulationStDev()
{
return this.wrappedWeightedTally.getWeightedPopulationStDev();
}
/** {@inheritDoc} */
@Override
public final double getWeightedSampleVariance()
{
return this.wrappedWeightedTally.getWeightedSampleVariance();
}
/** {@inheritDoc} */
@Override
public final double getWeightedPopulationVariance()
{
return this.wrappedWeightedTally.getWeightedPopulationVariance();
}
/** {@inheritDoc} */
@Override
public final double getWeightedSum()
{
return this.wrappedWeightedTally.getWeightedSum();
}
/** {@inheritDoc} */
@Override
public void initialize()
{
this.wrappedWeightedTally.initialize();
fireEvent(new Event(StatisticsEvents.INITIALIZED_EVENT, this, null));
}
/** {@inheritDoc} */
@Override
public void notify(final EventInterface event)
{
Throw.when(!(event.getContent() instanceof Object[]), IllegalArgumentException.class,
"WeightedTally.notify: Content should be Object[] {weight, value}");
Object[] content = (Object[]) event.getContent();
Throw.when(content.length != 2, IllegalArgumentException.class,
"WeightedTally.notify: Content should be Object[] {weight, value}");
Throw.when(!(content[0] instanceof Number), IllegalArgumentException.class,
"WeightedTally.notify: Weight (Content[0]) should be a Number");
Throw.when(!(content[1] instanceof Number), IllegalArgumentException.class,
"WeightedTally.notify: Value (Content[1]) should be a Number");
double weight = ((Number) content[0]).doubleValue();
double value = ((Number) content[1]).doubleValue();
ingest(weight, value);
}
/**
* Process one observed weighted value.
* @param weight double; the weight of the value to process
* @param value double; the value to process
* @return double; the value
*/
public double ingest(final double weight, final double value)
{
this.wrappedWeightedTally.ingest(weight, value);
if (hasListeners())
{
fireEvent(new Event(StatisticsEvents.WEIGHTED_OBSERVATION_ADDED_EVENT, this, new Object[] {weight, value}));
fireEvents();
}
return value;
}
/**
* Method that can be overridden to fire own events or additional events when ingesting an observation.
*/
protected void fireEvents()
{
fireEvent(new Event(StatisticsEvents.N_EVENT, this, getN()));
fireEvent(new Event(StatisticsEvents.MIN_EVENT, this, getMin()));
fireEvent(new Event(StatisticsEvents.MAX_EVENT, this, getMax()));
fireEvent(new Event(StatisticsEvents.WEIGHTED_POPULATION_MEAN_EVENT, this, getWeightedPopulationMean()));
fireEvent(new Event(StatisticsEvents.WEIGHTED_POPULATION_VARIANCE_EVENT, this, getWeightedPopulationVariance()));
fireEvent(new Event(StatisticsEvents.WEIGHTED_POPULATION_STDEV_EVENT, this, getWeightedPopulationStDev()));
fireEvent(new Event(StatisticsEvents.WEIGHTED_SUM_EVENT, this, getWeightedSum()));
fireEvent(new Event(StatisticsEvents.WEIGHTED_SAMPLE_MEAN_EVENT, this, getWeightedSampleMean()));
fireEvent(new Event(StatisticsEvents.WEIGHTED_SAMPLE_VARIANCE_EVENT, this, getWeightedSampleVariance()));
fireEvent(new Event(StatisticsEvents.WEIGHTED_SAMPLE_STDEV_EVENT, this, getWeightedSampleStDev()));
}
/** {@inheritDoc} */
@Override
@SuppressWarnings("checkstyle:designforextension")
public String toString()
{
return this.wrappedWeightedTally.toString();
}
}