1 50 51 package org.jfree.data.time; 52 53 import org.jfree.data.xy.XYDataset; 54 import org.jfree.data.xy.XYSeries; 55 import org.jfree.data.xy.XYSeriesCollection; 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 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 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 long firstSerial 144 = source.getDataItem(0).getPeriod().getSerialIndex() + skip; 145 146 for (int i = source.getItemCount() - 1; i >= 0; i--) { 147 148 TimeSeriesDataItem current = source.getDataItem(i); 150 RegularTimePeriod period = current.getPeriod(); 151 long serial = period.getSerialIndex(); 152 153 if (serial >= firstSerial) { 154 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 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 TimeSeriesDataItem current = source.getDataItem(i); 230 RegularTimePeriod period = current.getPeriod(); 231 rollingSumForPeriod += current.getValue().doubleValue(); 232 233 if (i > pointCount - 1) { 234 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 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 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 double first = source.getXValue(series, 0) + skip; 342 343 for (int i = source.getItemCount(series) - 1; i >= 0; i--) { 344 345 double x = source.getXValue(series, i); 347 348 if (x >= first) { 349 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 } 391 | Popular Tags |