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