Hi
I assume that I must be doing something wrong and despite checking the doc, I cannot see what. Any help would be greatly appreciated.
I have a TimeSeries using FixedMilliseconds as it represents precise "run" times of some processes. I can generate a nice chart plotted correctly with the X axis being datetime but when I try to add a MovingAverage, it seems to DUPLICATE the original TimeSeries, 2 categories appear on the chart but they are indistinguishable.
I enclose the code I am using:
TimeSeriesCollection series = new TimeSeriesCollection();
TimeSeries ts = new TimeSeries(name,"bla","bli",FixedMillisecond.class);
for (Iterator it = data.iterator(); it.hasNext(); )
{
BusResultStats stat =(BusResultStats)it.next();
ts.add(new FixedMillisecond(stat.getDate()), stat.getElapsedSeconds());
}
// moving average, assuming 5 "run" moving average
series.addSeries(MovingAverage.createMovingAverage(ts,"5-run Moving Average",5,5));
// create the chart
JFreeChart chart = ChartFactory.createTimeSeriesChart("title", "dates", "seconds", series, true, true, false);
What am I doing wrong?
I can email the chart if that helps...
many thanks
Benoit.
MovingAverage for TimeSeries with fixedMilliSeconds
Re: MovingAverage for TimeSeries with fixedMilliSeconds
Hi
I have had a look at the MovingAverage and I really wonder if it works as I think it "should" for TimeSeries with FixedMilliseconds.
Is the running average calculated on a REGULAR interval, say "5" being for every 5 milliseconds rather than for the last 5 points, whenever that was. If I have a dataset:
1Jan2003 12:15 = 2
2Jan2003 14:25 = 4
5Jan2003 13:17 = 4
8Jan2003 11:30 = 2
15Jan2003 16:27 = 2
I expect an average with period="5" to be (2+4+4+2+2)/5 = 2.8
as there are 5 points but each are defined FixedMilliseconds on the chart...
Am I right? Is there another method that calculates moving average for what I'm trying to achieve?
Many thanks
Benoit
I have had a look at the MovingAverage and I really wonder if it works as I think it "should" for TimeSeries with FixedMilliseconds.
Is the running average calculated on a REGULAR interval, say "5" being for every 5 milliseconds rather than for the last 5 points, whenever that was. If I have a dataset:
1Jan2003 12:15 = 2
2Jan2003 14:25 = 4
5Jan2003 13:17 = 4
8Jan2003 11:30 = 2
15Jan2003 16:27 = 2
I expect an average with period="5" to be (2+4+4+2+2)/5 = 2.8
as there are 5 points but each are defined FixedMilliseconds on the chart...
Am I right? Is there another method that calculates moving average for what I'm trying to achieve?
Many thanks
Benoit
Re: MovingAverage for TimeSeries with fixedMilliSeconds
Hi Benoit,
The existing code calculates the average of the values in the last n periods - in your case, the last 5 milliseconds.
Some new code would need to be written to average the last 5 observations, regardless of how old they are.
Regards,
Dave Gilbert
The existing code calculates the average of the values in the last n periods - in your case, the last 5 milliseconds.
Some new code would need to be written to average the last 5 observations, regardless of how old they are.
Regards,
Dave Gilbert
Re: MovingAverage for TimeSeries with fixedMilliSeconds
Hi Dave,
Thank you for your reply. I had a look at the MovingAverage code and deducted that I was missusing it.
I have written the code you mentioned and was about to submit it to the project. Here is it, feel free to add it to the MovingAverage class:
/**
* Creates a new {@link TimeSeries} containing moving average values for the given series,
* calculated by number of points and not number of periods.
* <p>
* If the series is empty (contains zero items), the result is an empty series.
*
* @param source the source series.
* @param name the name of the new series.
* @param pointCount the number of POINTS used in the average calculation. (not periods!)
*
* @return The moving average series.
* @author Benoit Xhenseval (www.ObjectLab.co.uk)
*/
public static TimeSeries createPointMovingAverage(TimeSeries source,
String name,
int pointCount) {
// check arguments
if (source == null) {
throw new IllegalArgumentException("MovingAverage.createMovingAverage(...) : "
+ "null source.");
}
if (pointCount < 2) {
throw new IllegalArgumentException("MovingAverage.createMovingAverage(...) : "
+ "periodCount must be greater than or equal to 2.");
}
TimeSeries result = new TimeSeries(name, source.getTimePeriodClass());
double rollingSumForPeriod =0.0;
for (int i = 0; i<source.getItemCount() ;i++) {
// get the current data item...
TimeSeriesDataPair current = source.getDataPair(i);
RegularTimePeriod period = current.getPeriod();
rollingSumForPeriod += current.getValue().doubleValue();
if (i>pointCount -1)
{
// remove the point i-periodCount out of the rolling sum.
TimeSeriesDataPair startOfMovingAvg = source.getDataPair(i-pointCount);
rollingSumForPeriod -=startOfMovingAvg.getValue().doubleValue();
result.add(period, rollingSumForPeriod / pointCount);
}
else if (i==pointCount -1)
{
result.add(period, rollingSumForPeriod / pointCount);
}
}
return result;
}
Let me know if it is ok.
Best regards
Benoit.
Thank you for your reply. I had a look at the MovingAverage code and deducted that I was missusing it.
I have written the code you mentioned and was about to submit it to the project. Here is it, feel free to add it to the MovingAverage class:
/**
* Creates a new {@link TimeSeries} containing moving average values for the given series,
* calculated by number of points and not number of periods.
* <p>
* If the series is empty (contains zero items), the result is an empty series.
*
* @param source the source series.
* @param name the name of the new series.
* @param pointCount the number of POINTS used in the average calculation. (not periods!)
*
* @return The moving average series.
* @author Benoit Xhenseval (www.ObjectLab.co.uk)
*/
public static TimeSeries createPointMovingAverage(TimeSeries source,
String name,
int pointCount) {
// check arguments
if (source == null) {
throw new IllegalArgumentException("MovingAverage.createMovingAverage(...) : "
+ "null source.");
}
if (pointCount < 2) {
throw new IllegalArgumentException("MovingAverage.createMovingAverage(...) : "
+ "periodCount must be greater than or equal to 2.");
}
TimeSeries result = new TimeSeries(name, source.getTimePeriodClass());
double rollingSumForPeriod =0.0;
for (int i = 0; i<source.getItemCount() ;i++) {
// get the current data item...
TimeSeriesDataPair current = source.getDataPair(i);
RegularTimePeriod period = current.getPeriod();
rollingSumForPeriod += current.getValue().doubleValue();
if (i>pointCount -1)
{
// remove the point i-periodCount out of the rolling sum.
TimeSeriesDataPair startOfMovingAvg = source.getDataPair(i-pointCount);
rollingSumForPeriod -=startOfMovingAvg.getValue().doubleValue();
result.add(period, rollingSumForPeriod / pointCount);
}
else if (i==pointCount -1)
{
result.add(period, rollingSumForPeriod / pointCount);
}
}
return result;
}
Let me know if it is ok.
Best regards
Benoit.