1:
50:
51: package ;
52:
53: import ;
54: import ;
55: import ;
56:
57:
60: public class MovingAverage {
61:
62:
75: public static TimeSeriesCollection createMovingAverage(
76: TimeSeriesCollection source, String suffix, int periodCount,
77: int skip) {
78:
79:
80: if (source == null) {
81: throw new IllegalArgumentException(
82: "MovingAverage.createMovingAverage() : null source."
83: );
84: }
85:
86: if (periodCount < 1) {
87: throw new IllegalArgumentException(
88: "periodCount must be greater than or equal to 1."
89: );
90: }
91:
92: TimeSeriesCollection result = new TimeSeriesCollection();
93:
94: for (int i = 0; i < source.getSeriesCount(); i++) {
95: TimeSeries sourceSeries = source.getSeries(i);
96: TimeSeries maSeries = createMovingAverage(
97: sourceSeries, sourceSeries.getKey() + suffix, periodCount, skip
98: );
99: result.addSeries(maSeries);
100: }
101:
102: return result;
103:
104: }
105:
106:
119: public static TimeSeries createMovingAverage(TimeSeries source,
120: String name,
121: int periodCount,
122: int skip) {
123:
124:
125: if (source == null) {
126: throw new IllegalArgumentException("Null source.");
127: }
128:
129: if (periodCount < 1) {
130: throw new IllegalArgumentException(
131: "periodCount must be greater than or equal to 1."
132: );
133:
134: }
135:
136: TimeSeries result = new TimeSeries(name, source.getTimePeriodClass());
137:
138: if (source.getItemCount() > 0) {
139:
140:
141:
142:
143: long firstSerial
144: = source.getDataItem(0).getPeriod().getSerialIndex() + skip;
145:
146: for (int i = source.getItemCount() - 1; i >= 0; i--) {
147:
148:
149: TimeSeriesDataItem current = source.getDataItem(i);
150: RegularTimePeriod period = current.getPeriod();
151: long serial = period.getSerialIndex();
152:
153: if (serial >= firstSerial) {
154:
155: int n = 0;
156: double sum = 0.0;
157: long serialLimit = period.getSerialIndex() - periodCount;
158: int offset = 0;
159: boolean finished = false;
160:
161: while ((offset < periodCount) && (!finished)) {
162: if ((i - offset) >= 0) {
163: TimeSeriesDataItem item
164: = source.getDataItem(i - offset);
165: RegularTimePeriod p = item.getPeriod();
166: Number v = item.getValue();
167: long currentIndex = p.getSerialIndex();
168: if (currentIndex > serialLimit) {
169: if (v != null) {
170: sum = sum + v.doubleValue();
171: n = n + 1;
172: }
173: }
174: else {
175: finished = true;
176: }
177: }
178: offset = offset + 1;
179: }
180: if (n > 0) {
181: result.add(period, sum / n);
182: }
183: else {
184: result.add(period, null);
185: }
186: }
187:
188: }
189: }
190:
191: return result;
192:
193: }
194:
195:
210: public static TimeSeries createPointMovingAverage(TimeSeries source,
211: String name,
212: int pointCount) {
213:
214:
215: if (source == null) {
216: throw new IllegalArgumentException("Null 'source'.");
217: }
218:
219: if (pointCount < 2) {
220: throw new IllegalArgumentException(
221: "periodCount must be greater than or equal to 2."
222: );
223: }
224:
225: TimeSeries result = new TimeSeries(name, source.getTimePeriodClass());
226: double rollingSumForPeriod = 0.0;
227: for (int i = 0; i < source.getItemCount(); i++) {
228:
229: TimeSeriesDataItem current = source.getDataItem(i);
230: RegularTimePeriod period = current.getPeriod();
231: rollingSumForPeriod += current.getValue().doubleValue();
232:
233: if (i > pointCount - 1) {
234:
235: TimeSeriesDataItem startOfMovingAvg
236: = source.getDataItem(i - pointCount);
237: rollingSumForPeriod
238: -= startOfMovingAvg.getValue().doubleValue();
239: result.add(period, rollingSumForPeriod / pointCount);
240: }
241: else if (i == pointCount - 1) {
242: result.add(period, rollingSumForPeriod / pointCount);
243: }
244: }
245: return result;
246: }
247:
248:
260: public static XYDataset createMovingAverage(XYDataset source, String suffix,
261: long period, final long skip) {
262:
263: return createMovingAverage(
264: source, suffix, (double) period, (double) skip
265: );
266:
267: }
268:
269:
270:
282: public static XYDataset createMovingAverage(XYDataset source, String suffix,
283: double period, double skip) {
284:
285:
286: if (source == null) {
287: throw new IllegalArgumentException("Null source (XYDataset).");
288: }
289:
290: XYSeriesCollection result = new XYSeriesCollection();
291:
292: for (int i = 0; i < source.getSeriesCount(); i++) {
293: XYSeries s = createMovingAverage(
294: source, i, source.getSeriesKey(i) + suffix, period, skip
295: );
296: result.addSeries(s);
297: }
298:
299: return result;
300:
301: }
302:
303:
315: public static XYSeries createMovingAverage(XYDataset source,
316: int series, String name,
317: double period, double skip) {
318:
319:
320:
321: if (source == null) {
322: throw new IllegalArgumentException("Null source (XYDataset).");
323: }
324:
325: if (period < Double.MIN_VALUE) {
326: throw new IllegalArgumentException("period must be positive.");
327:
328: }
329:
330: if (skip < 0.0) {
331: throw new IllegalArgumentException("skip must be >= 0.0.");
332:
333: }
334:
335: XYSeries result = new XYSeries(name);
336:
337: if (source.getItemCount(series) > 0) {
338:
339:
340:
341: double first = source.getXValue(series, 0) + skip;
342:
343: for (int i = source.getItemCount(series) - 1; i >= 0; i--) {
344:
345:
346: double x = source.getXValue(series, i);
347:
348: if (x >= first) {
349:
350: int n = 0;
351: double sum = 0.0;
352: double limit = x - period;
353: int offset = 0;
354: boolean finished = false;
355:
356: while (!finished) {
357: if ((i - offset) >= 0) {
358: double xx = source.getXValue(series, i - offset);
359: Number yy = source.getY(series, i - offset);
360: if (xx > limit) {
361: if (yy != null) {
362: sum = sum + yy.doubleValue();
363: n = n + 1;
364: }
365: }
366: else {
367: finished = true;
368: }
369: }
370: else {
371: finished = true;
372: }
373: offset = offset + 1;
374: }
375: if (n > 0) {
376: result.add(x, sum / n);
377: }
378: else {
379: result.add(x, null);
380: }
381: }
382:
383: }
384: }
385:
386: return result;
387:
388: }
389:
390: }