1 16 17 package org.apache.commons.math.random; 18 19 import java.io.Serializable ; 20 import java.io.BufferedReader ; 21 import java.io.FileReader ; 22 import java.io.File ; 23 import java.io.IOException ; 24 import java.io.InputStreamReader ; 25 import java.net.URL ; 26 import java.util.ArrayList ; 27 import java.util.List ; 28 29 import org.apache.commons.math.stat.descriptive.SummaryStatistics; 30 import org.apache.commons.math.stat.descriptive.StatisticalSummary; 31 32 59 public class EmpiricalDistributionImpl implements Serializable , EmpiricalDistribution { 60 61 62 static final long serialVersionUID = -6773236347582113490L; 63 64 65 private ArrayList binStats = null; 66 67 68 SummaryStatistics sampleStats = null; 69 70 71 private int binCount = 1000; 72 73 74 private boolean loaded = false; 75 76 77 private double[] upperBounds = null; 78 79 80 private RandomData randomData = new RandomDataImpl(); 81 82 85 public EmpiricalDistributionImpl() { 86 binStats = new ArrayList (); 87 } 88 89 94 public EmpiricalDistributionImpl(int binCount) { 95 this.binCount = binCount; 96 binStats = new ArrayList (); 97 } 98 99 105 public void load(double[] in) { 106 DataAdapter da = new ArrayDataAdapter(in); 107 try { 108 da.computeStats(); 109 fillBinStats(in); 110 } catch (Exception e) { 111 throw new RuntimeException (e.getMessage()); 112 } 113 loaded = true; 114 115 } 116 117 123 public void load(URL url) throws IOException { 124 BufferedReader in = 125 new BufferedReader (new InputStreamReader (url.openStream())); 126 try { 127 DataAdapter da = new StreamDataAdapter(in); 128 try { 129 da.computeStats(); 130 } catch (Exception e) { 131 throw new IOException (e.getMessage()); 132 } 133 in = new BufferedReader (new InputStreamReader (url.openStream())); 134 fillBinStats(in); 135 loaded = true; 136 } finally { 137 if (in != null) { 138 try { 139 in.close(); 140 } catch (Exception ex) { 141 } 143 } 144 } 145 } 146 147 153 public void load(File file) throws IOException { 154 BufferedReader in = new BufferedReader (new FileReader (file)); 155 try { 156 DataAdapter da = new StreamDataAdapter(in); 157 try { 158 da.computeStats(); 159 } catch (Exception e) { 160 throw new IOException (e.getMessage()); 161 } 162 in = new BufferedReader (new FileReader (file)); 163 fillBinStats(in); 164 loaded = true; 165 } finally { 166 if (in != null) { 167 try { 168 in.close(); 169 } catch (Exception ex) { 170 } 172 } 173 } 174 } 175 176 180 private abstract class DataAdapter{ 181 188 public abstract void computeBinStats(double min, double delta) 189 throws Exception ; 190 195 public abstract void computeStats() throws Exception ; 196 } 197 202 private class DataAdapterFactory{ 203 209 public DataAdapter getAdapter(Object in) { 210 if (in instanceof BufferedReader ) { 211 BufferedReader inputStream = (BufferedReader ) in; 212 return new StreamDataAdapter(inputStream); 213 } else if (in instanceof double[]) { 214 double[] inputArray = (double[]) in; 215 return new ArrayDataAdapter(inputArray); 216 } else { 217 throw new IllegalArgumentException ( 218 "Input data comes from the" + " unsupported source"); 219 } 220 } 221 } 222 225 private class StreamDataAdapter extends DataAdapter{ 226 227 228 BufferedReader inputStream; 229 230 235 public StreamDataAdapter(BufferedReader in){ 236 super(); 237 inputStream = in; 238 } 239 246 public void computeBinStats(double min, double delta) 247 throws IOException { 248 String str = null; 249 double val = 0.0d; 250 while ((str = inputStream.readLine()) != null) { 251 val = Double.parseDouble(str); 252 SummaryStatistics stats = 253 (SummaryStatistics) binStats.get( 254 Math.max((int) Math.ceil((val - min) / delta) - 1, 0)); 255 stats.addValue(val); 256 } 257 258 inputStream.close(); 259 inputStream = null; 260 } 261 266 public void computeStats() throws IOException { 267 String str = null; 268 double val = 0.0; 269 sampleStats = SummaryStatistics.newInstance(); 270 while ((str = inputStream.readLine()) != null) { 271 val = new Double (str).doubleValue(); 272 sampleStats.addValue(val); 273 } 274 inputStream.close(); 275 inputStream = null; 276 } 277 } 278 279 282 private class ArrayDataAdapter extends DataAdapter{ 283 284 285 private double[] inputArray; 286 287 292 public ArrayDataAdapter(double[] in){ 293 super(); 294 inputArray = in; 295 } 296 301 public void computeStats() throws IOException { 302 sampleStats = SummaryStatistics.newInstance(); 303 for (int i = 0; i < inputArray.length; i++) { 304 sampleStats.addValue(inputArray[i]); 305 } 306 } 307 314 public void computeBinStats(double min, double delta) 315 throws IOException { 316 for (int i = 0; i < inputArray.length; i++) { 317 SummaryStatistics stats = 318 (SummaryStatistics) binStats.get( 319 Math.max((int) Math.ceil( 320 (inputArray[i] - min) / delta)- 1, 0)); 321 stats.addValue(inputArray[i]); 322 } 323 } 324 } 325 326 332 private void fillBinStats(Object in) throws IOException { 333 double min = sampleStats.getMin(); 335 double max = sampleStats.getMax(); 336 double delta = (max - min)/(new Double (binCount)).doubleValue(); 337 double[] binUpperBounds = new double[binCount]; 338 binUpperBounds[0] = min + delta; 339 for (int i = 1; i< binCount - 1; i++) { 340 binUpperBounds[i] = binUpperBounds[i-1] + delta; 341 } 342 binUpperBounds[binCount -1] = max; 343 344 if (!binStats.isEmpty()) { 346 binStats.clear(); 347 } 348 for (int i = 0; i < binCount; i++) { 349 SummaryStatistics stats = SummaryStatistics.newInstance(); 350 binStats.add(i,stats); 351 } 352 353 DataAdapterFactory aFactory = new DataAdapterFactory(); 355 DataAdapter da = aFactory.getAdapter(in); 356 try { 357 da.computeBinStats(min, delta); 358 } catch (Exception e) { 359 if(e instanceof RuntimeException ){ 360 throw new RuntimeException (e.getMessage()); 361 }else{ 362 throw new IOException (e.getMessage()); 363 } 364 } 365 366 upperBounds = new double[binCount]; 368 upperBounds[0] = 369 ((double)((SummaryStatistics)binStats.get(0)).getN())/ 370 (double)sampleStats.getN(); 371 for (int i = 1; i < binCount-1; i++) { 372 upperBounds[i] = upperBounds[i-1] + 373 ((double)((SummaryStatistics)binStats.get(i)).getN())/ 374 (double)sampleStats.getN(); 375 } 376 upperBounds[binCount-1] = 1.0d; 377 } 378 379 385 public double getNextValue() throws IllegalStateException { 386 387 if (!loaded) { 388 throw new IllegalStateException ("distribution not loaded"); 389 } 390 391 double x = Math.random(); 393 394 for (int i = 0; i < binCount; i++) { 396 if (x <= upperBounds[i]) { 397 SummaryStatistics stats = (SummaryStatistics)binStats.get(i); 398 if (stats.getN() > 0) { 399 if (stats.getStandardDeviation() > 0) { return randomData.nextGaussian 401 (stats.getMean(),stats.getStandardDeviation()); 402 } else { 403 return stats.getMean(); } 405 } 406 } 407 } 408 throw new RuntimeException ("No bin selected"); 409 } 410 411 419 public StatisticalSummary getSampleStats() { 420 return sampleStats; 421 } 422 423 428 public int getBinCount() { 429 return binCount; 430 } 431 432 439 public List getBinStats() { 440 return binStats; 441 } 442 443 450 public double[] getUpperBounds() { 451 return upperBounds; 452 } 453 454 459 public boolean isLoaded() { 460 return loaded; 461 } 462 } 463 | Popular Tags |