View Javadoc
1   package org.djutils.stats.summarizers.event;
2   
3   import java.io.Serializable;
4   
5   import org.djutils.event.Event;
6   import org.djutils.event.EventInterface;
7   import org.djutils.event.EventListenerInterface;
8   import org.djutils.event.EventProducer;
9   import org.djutils.exceptions.Throw;
10  import org.djutils.stats.summarizers.WeightedTally;
11  import org.djutils.stats.summarizers.WeightedTallyInterface;
12  
13  /**
14   * The EventBasedWeightedTally class defines a time-weighted tally that can be notified with weights and values using the
15   * EventListenerInterface. It also produces events when values are tallied and when the tally is initialized.
16   * <p>
17   * Copyright (c) 2002-2021 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
18   * for project information <a href="https://simulation.tudelft.nl/" target="_blank"> https://simulation.tudelft.nl</a>. The DSOL
19   * project is distributed under a three-clause BSD-style license, which can be found at
20   * <a href="https://simulation.tudelft.nl/dsol/3.0/license.html" target="_blank">
21   * https://simulation.tudelft.nl/dsol/3.0/license.html</a>. <br>
22   * @author <a href="https://www.tudelft.nl/averbraeck" target="_blank"> Alexander Verbraeck</a>
23   * @author <a href="https://www.tudelft.nl/staff/p.knoppers/">Peter Knoppers</a>
24   */
25  public class EventBasedWeightedTally extends EventProducer implements EventListenerInterface, WeightedTallyInterface
26  {
27      /** */
28      private static final long serialVersionUID = 20200228L;
29  
30      /** the wrapped WeightedTally. */
31      private final WeightedTally wrappedWeightedTally;
32  
33      /**
34       * Construct a new WeightedTally with a description.
35       * @param description String; the description of this WeightedTally
36       */
37      public EventBasedWeightedTally(final String description)
38      {
39          this.wrappedWeightedTally = new WeightedTally(description);
40      }
41  
42      /** {@inheritDoc} */
43      @Override
44      public Serializable getSourceId()
45      {
46          return this;
47      }
48  
49      /** {@inheritDoc} */
50      @Override
51      public final String getDescription()
52      {
53          return this.wrappedWeightedTally.getDescription();
54      }
55  
56      /** {@inheritDoc} */
57      @Override
58      public final double getMax()
59      {
60          return this.wrappedWeightedTally.getMax();
61      }
62  
63      /** {@inheritDoc} */
64      @Override
65      public final double getMin()
66      {
67          return this.wrappedWeightedTally.getMin();
68      }
69  
70      /** {@inheritDoc} */
71      @Override
72      public final long getN()
73      {
74          return this.wrappedWeightedTally.getN();
75      }
76  
77      /** {@inheritDoc} */
78      @Override
79      public final double getWeightedSampleMean()
80      {
81          return this.wrappedWeightedTally.getWeightedSampleMean();
82      }
83  
84      /** {@inheritDoc} */
85      @Override
86      public final double getWeightedSampleStDev()
87      {
88          return this.wrappedWeightedTally.getWeightedSampleStDev();
89      }
90  
91      /** {@inheritDoc} */
92      @Override
93      public final double getWeightedPopulationStDev()
94      {
95          return this.wrappedWeightedTally.getWeightedPopulationStDev();
96      }
97  
98      /** {@inheritDoc} */
99      @Override
100     public final double getWeightedSampleVariance()
101     {
102         return this.wrappedWeightedTally.getWeightedSampleVariance();
103     }
104 
105     /** {@inheritDoc} */
106     @Override
107     public final double getWeightedPopulationVariance()
108     {
109         return this.wrappedWeightedTally.getWeightedPopulationVariance();
110     }
111 
112     /** {@inheritDoc} */
113     @Override
114     public final double getWeightedSum()
115     {
116         return this.wrappedWeightedTally.getWeightedSum();
117     }
118 
119     /** {@inheritDoc} */
120     @Override
121     public void initialize()
122     {
123         this.wrappedWeightedTally.initialize();
124         fireEvent(new Event(StatisticsEvents.INITIALIZED_EVENT, this, null));
125     }
126 
127     /** {@inheritDoc} */
128     @Override
129     public void notify(final EventInterface event)
130     {
131         Throw.when(!(event.getContent() instanceof Object[]), IllegalArgumentException.class,
132                 "WeightedTally.notify: Content should be Object[] {weight, value}");
133         Object[] content = (Object[]) event.getContent();
134         Throw.when(content.length != 2, IllegalArgumentException.class,
135                 "WeightedTally.notify: Content should be Object[] {weight, value}");
136         Throw.when(!(content[0] instanceof Number), IllegalArgumentException.class,
137                 "WeightedTally.notify: Weight (Content[0]) should be a Number");
138         Throw.when(!(content[1] instanceof Number), IllegalArgumentException.class,
139                 "WeightedTally.notify: Value (Content[1]) should be a Number");
140         double weight = ((Number) content[0]).doubleValue();
141         double value = ((Number) content[1]).doubleValue();
142         ingest(weight, value);
143     }
144 
145     /**
146      * Process one observed weighted value.
147      * @param weight double; the weight of the value to process
148      * @param value double; the value to process
149      * @return double; the value
150      */
151     public double ingest(final double weight, final double value)
152     {
153         this.wrappedWeightedTally.ingest(weight, value);
154         if (hasListeners())
155         {
156             fireEvent(new Event(StatisticsEvents.WEIGHTED_OBSERVATION_ADDED_EVENT, this, new Object[] {weight, value}));
157             fireEvents();
158         }
159         return value;
160     }
161 
162     /**
163      * Method that can be overridden to fire own events or additional events when ingesting an observation.
164      */
165     protected void fireEvents()
166     {
167         fireEvent(new Event(StatisticsEvents.N_EVENT, this, getN()));
168         fireEvent(new Event(StatisticsEvents.MIN_EVENT, this, getMin()));
169         fireEvent(new Event(StatisticsEvents.MAX_EVENT, this, getMax()));
170         fireEvent(new Event(StatisticsEvents.WEIGHTED_POPULATION_MEAN_EVENT, this, getWeightedPopulationMean()));
171         fireEvent(new Event(StatisticsEvents.WEIGHTED_POPULATION_VARIANCE_EVENT, this, getWeightedPopulationVariance()));
172         fireEvent(new Event(StatisticsEvents.WEIGHTED_POPULATION_STDEV_EVENT, this, getWeightedPopulationStDev()));
173         fireEvent(new Event(StatisticsEvents.WEIGHTED_SUM_EVENT, this, getWeightedSum()));
174         fireEvent(new Event(StatisticsEvents.WEIGHTED_SAMPLE_MEAN_EVENT, this, getWeightedSampleMean()));
175         fireEvent(new Event(StatisticsEvents.WEIGHTED_SAMPLE_VARIANCE_EVENT, this, getWeightedSampleVariance()));
176         fireEvent(new Event(StatisticsEvents.WEIGHTED_SAMPLE_STDEV_EVENT, this, getWeightedSampleStDev()));
177     }
178 
179     /** {@inheritDoc} */
180     @Override
181     @SuppressWarnings("checkstyle:designforextension")
182     public String toString()
183     {
184         return this.wrappedWeightedTally.toString();
185     }
186 
187 }