import java.io.*;
import java.math.*;
import uk.ac.ed.ph.advcompsim.part3.histogram.Histogram;
/**
* ---------------------------------------------------------------
* Excersize 3.1.3
* ---------------------------------------------------------------
* I would expect the histogram to be fairly flat, because over a large number of N I would expect the probability of getting a value in the region
* 0-0.1 to be the same as that of getting a number in the region 0.4-0.5 for example.
*/
public class exc313 {
/**
* Takes a number n and prints that many random numbers.
*/
public static void main (String args[]) {
int n = 200; // number of random numbers to be generated
int nb = 10; // number of bins to use.
float[] data = new float[n]; // The data array
float lb = 0; // The lower boundary
float ub = 1; // The upper boundary
for(int i=0;i < n;i++) {
data[i] = (float)(Math.random()); // print the randomly generated number to screen
}
//Histogram.DataHistogram(nb, lb, ub, data, true);
}
}
THEN THE OTHER BITS
001 package uk.ac.ed.ph.advcompsim.part3.histogram;
002
003 import uk.ac.ed.ph.advcompsim.part3.display.GUI;
004 import java.awt.geom.Rectangle2D;
005 import uk.ac.ed.ph.advcompsim.part3.display.Board;
006 import uk.ac.ed.ph.advcompsim.part3.closure.Closure;
007 import java.awt.*;
008 import java.awt.Dimension;
009 import java.util.*;
010
011 /**
012 * This abstract base class provides basic methods and fields for the manipulation of
013 * histograms. It must be subclassed by a Histogram class, which defines methods
014 * for binning a data sample or a given function.
015 *
016 *
017 * @author M. L. Ciccolini
018 * @author Tony Kennedy
019 * @version 1.2
020 * @see Histogram Histogram
021 * @see Closure Closure
022 */
023
024 public abstract class Histogram implements Closure {
025
026 /** Is the area normalized to one? */
027 protected boolean normalized;
028
029 /** Number of bins */
030 protected int numBins;
031
032 /** Width of the bins */
033 protected float binWidth;
034
035 /**
036 * Cumulative area of the histogram in each bin, i.e., the area under the
037 * histogram up to and including that bin
038 */
039 protected float[] area;
040
041 /** Total area under the (unnormalized) histogram */
042 protected float totalArea;
043
044 /**Lower limit of the values included in the histogram */
045 protected float lowerBound;
046
047 /** Upper limit of the values included in the histogram */
048 protected float upperBound;
049
050 /** GUI in which to show graphs */
051 private static GUI window = null;
052
053 /**
054 * Partially initialize an object belonging to a class derived from
055 * {@link Histogram}:
bin
092 * @throws IllegalArgumentException if bin is out of range
093 */
094 public float binArea(int bin) throws IllegalArgumentException {
095 if (bin < 0 || bin >= numBins)
096 throw new IllegalArgumentException("Bin " + bin + " out of range");
097 if (bin == 0) return area[0];
098 return area[bin] - area[bin-1];
099 }
100
101 /**
102 * Height of the specified histogram bin.
103 *
104 * @param bin Bin whose height is desired
105 * @return Height of bin
106 * @throws IllegalArgumentException if bin is out of range
107 */
108 public float height(int bin) throws IllegalArgumentException {
109 return binArea(bin) / binWidth;
110 }
111
112 /**
113 * Bin containing coordinate x.
114 *
115 *
116 * @param x coordinate value
117 * @return bin containing x
118 * @throws IllegalArgumentException if x is not between
119 * {@link Histogram#upperBound lowerBound} and {@link Histogram#upperBound upperBound}
120 */
121 public int binValue(float x) {
122 int bin = (int) ((x - lowerBound) / binWidth);
123 if (bin < 0 || bin > numBins)
124 throw new IllegalArgumentException("Value " + x + "out of range");
125 return bin;
126 }
127
128 /**
129 * Find the bin containing the cumulative area x within it.
130 * This implementation just steps through the bins until it finds that the
131 * cumulative area (in the {@link Histogram#area area} array) exceeds
132 * x, so it takes O(numBins) time.
133 *
134 * {@question Can you find and implement an algorithm that takes
135 * O(ln(numBins)) time instead?}
136 *
137 * @param x Cumulative area to to left of bin.
138 * @return bin such that area[bin-1] <= x < area[bin].
139 * @throws IllegalArgumentException if the x does not correspond
140 * to any bin.
141 */
142 public int lookupBin(float x) throws IllegalArgumentException {
143 if (x < 0.0f || x > area[numBins - 1])
144 throw new IllegalArgumentException("Area " + x + " not underhistogram");
145 for (int bin = 0; bin < numBins; bin++) {
146 if (x < area[bin]) return bin;
147 }
148 throw new Error("This cannot happen");
149 }
150
151 /**
152 * Maximum height of the histogram.
153 *
154 * @return Maximum height
155 */
156 public float maxHeight() {
157 float max = 0.0f;
158 for (int i = 0; i < numBins; i++) {
159 float ht = height(i);
160 if (ht > max) max = ht;
161 }
162 return max;
163 }
164
165 /**
166 * Number of bins in histogram.
167 *
168 * @return Number of bins
169 */
170 public int getNumBins() { return numBins; }
171
172 /**
173 * Upper bound of values in histogram.
174 *
175 * @return Upper bound.
176 */
177 public float getUpperBound() { return upperBound; }
178
179 /**
180 * Lower bound of values in histogram
181 *
182 * @return Lower bound.
183 */
184 public float getLowerBound() { return lowerBound; }
185
186 /**
187 * Bounding {@link Rectangle} for this Histogram.
188 *
189 * @return Bounding {@link Rectangle} for this Histogram.
190 */
191 public Rectangle2D.Float getBounds() {
192 return new Rectangle2D.Float(lowerBound, 0.0f, upperBound - lowerBound, maxHeight());
193 }
194
195 /**
196 * Evaluate the histogram as a function.
197 *
198 * @param x coordinate
199 * @return Height of bin containing x
200 */
201 public float function(float x) {
202 if (x < lowerBound || x > upperBound) return 0.0f;
203 return height(binValue(x));
204 }
205
206 public String toString() {
207 return "AbsHistogram(lowerBound = " + lowerBound
208 + ", upperBound = " + upperBound
209 + ", numBins = " + numBins
210 + (normalized ? "" : " not") + "normalized)";
211 }
212
213 /**
214 * Prints the contents of the histogram to System.out as three
215 * columns: the first is the bin number, the second the location of the midpoint
216 * of the bin, and the third the height of the bin.
217 */
218 public void printHistogram() {
219 System.out.printf("\nBin #\tPosition\tHeight\n");
220 for (int bin = 0; bin < numBins; bin++) {
221 float middle = lowerBound + binWidth * (0.5f + (float) bin);
222 System.out.printf("%-6d\t%-10.2g\t%-10.2f\n", bin, middle, height(bin));
223 }
224 System.out.printf("\ntotalArea = %-10.2f\n", totalArea);
225 }
226
227 /**
228 * Display board in the GUI window, which is created if necessary.
229 *
230 * @param graph Board to be displayed.
231 * @see Board
232 * @see GUI
233 */
234 private static void show(Board graph) {
235 if (window == null) window = new GUI(graph);
236 else window.show(graph);
237 }
238
239 /**
240 * Display a collection of {@link Histogram}s and {@link Closure}s 241 * superimposed on a single graph with specified bounds on the graph's data 242 * coordinate system.
243 * 244 *Multiple calls to {@link Board#draw draw} will produce multiple graphs which 245 * can be paged through in the {@link GUI} window.
246 * 247 *If you want to display an {@link Histogram} as a function rather than as 248 * a histogram, by making use of the fact that it implments the {@link Closure} 249 * interface and thus provide the {@link Histogram#function function} method, then you will 250 * need create a wrapper object that implements {@link Closure} but not {@link 251 * Histogram}. This is because if an object both implements the {@link Closure} 252 * interface and extends {@link Histogram} then it will be plotted as 253 * a histogram rather than as a function.
254 * 255 *For convenient this method allows a collection of {@link Closure}s as well as 256 * and vararg list of them.
257 * 258 * @param title Title for the graph. 259 * @param bounds Bounds on the graph in data coordinates. 260 * @param thingCollection {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s 261 * and {@link Closure}s to superimpose on the graph. 262 * @param things {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s 263 * and {@link Closure}s to superimpose on the graph. 264 * @see Board 265 * @see Closure 266 */ 267 public static void draw(String title, Rectangle2D.Float bounds, IterableDisplay a collection of {@link Histogram}s and {@link Closure}s 287 * superimposed on a single graph with a scale chosen to fit all of them.
288 * 289 *Multiple calls to {@link Board#draw draw} will produce multiple graphs which 290 * can be paged through in the {@link GUI} window.
291 * 292 *If you want to display an {@link Histogram} as a function rather than as 293 * a histogram, by making use of the fact that it implments the {@link Closure} 294 * interface and thus provide the {@link Histogram#function function} method, then you will 295 * need create a wrapper object that implements {@link Closure} but not {@link 296 * Histogram}. This is because if an object both implements the {@link Closure} 297 * interface and extends {@link Histogram} then it will be plotted as 298 * a histogram rather than as a function.
299 * 300 *For convenient this method allows a collection of {@link Closure}s as well as 301 * and vararg list of them.
302 * 303 * @param title Title for the graph. 304 * @param thingCollection {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s 305 * and {@link Closure}s to superimpose on the graph. 306 * @param things {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s 307 * and {@link Closure}s to superimpose on the graph. 308 * @see Board 309 * @see Closure 310 */ 311 public static void draw(String title, IterableDisplay a collection of {@link Histogram}s and {@link Closure}s 317 * superimposed on a single graph with specified bounds on the graph's data 318 * coordinate system.
319 * 320 *Multiple calls to {@link Board#draw draw} will produce multiple graphs which 321 * can be paged through in the {@link GUI} window.
322 * 323 *If you want to display an {@link Histogram} as a function rather than as 324 * a histogram, by making use of the fact that it implments the {@link Closure} 325 * interface and thus provide the {@link Histogram#function function} method, then you will 326 * need create a wrapper object that implements {@link Closure} but not {@link 327 * Histogram}. This is because if an object both implements the {@link Closure} 328 * interface and extends {@link Histogram} then it will be plotted as 329 * a histogram rather than as a function.
330 * 331 *For convenient this method allows a collection of {@link Closure}s as well as 332 * and vararg list of them.
333 * 334 * @param bounds Bounds on the graph in data coordinates. 335 * @param thingCollection {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s 336 * and {@link Closure}s to superimpose on the graph. 337 * @param things {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s 338 * and {@link Closure}s to superimpose on the graph. 339 * @see Board 340 * @see Closure 341 */ 342 public static void draw(Rectangle2D.Float bounds, IterableDisplay a collection of {@link Histogram}s and {@link Closure}s 348 * superimposed on a single graph with a scale chosen to fit all of them.
349 * 350 *Multiple calls to {@link Board#draw draw} will produce multiple graphs which 351 * can be paged through in the {@link GUI} window.
352 * 353 *If you want to display an {@link Histogram} as a function rather than as 354 * a histogram, by making use of the fact that it implments the {@link Closure} 355 * interface and thus provide the {@link Histogram#function function} method, then you will 356 * need create a wrapper object that implements {@link Closure} but not {@link 357 * Histogram}. This is because if an object both implements the {@link Closure} 358 * interface and extends {@link Histogram} then it will be plotted as 359 * a histogram rather than as a function.
360 * 361 *For convenient this method allows a collection of {@link Closure}s as well as 362 * and vararg list of them.
363 * 364 * @param thingCollection {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s 365 * and {@link Closure}s to superimpose on the graph. 366 * @param things {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s 367 * and {@link Closure}s to superimpose on the graph. 368 * @see Board 369 * @see Closure 370 */ 371 public static void draw(IterableDisplay a collection of {@link Histogram}s and {@link Closure}s 377 * superimposed on a single graph with specified bounds on the graph's data 378 * coordinate system.
379 * 380 *Multiple calls to {@link Board#draw draw} will produce multiple graphs which 381 * can be paged through in the {@link GUI} window.
382 * 383 *If you want to display an {@link Histogram} as a function rather than as 384 * a histogram, by making use of the fact that it implments the {@link Closure} 385 * interface and thus provide the {@link Histogram#function function} method, then you will 386 * need create a wrapper object that implements {@link Closure} but not {@link 387 * Histogram}. This is because if an object both implements the {@link Closure} 388 * interface and extends {@link Histogram} then it will be plotted as 389 * a histogram rather than as a function.
390 * 391 * @param title Title for the graph. 392 * @param bounds Bounds on the graph in data coordinates. 393 * @param things {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s 394 * and {@link Closure}s to superimpose on the graph. 395 * @see Board 396 * @see Closure 397 */ 398 public static void draw(String title, Rectangle2D.Float bounds, Closure ... things) { 399 draw(title, bounds, null, things); 400 } 401 402 /** 403 *Display a collection of {@link Histogram}s and {@link Closure}s 404 * superimposed on a single graph with a scale chosen to fit all of them.
405 * 406 *Multiple calls to {@link Board#draw draw} will produce multiple graphs which 407 * can be paged through in the {@link GUI} window.
408 * 409 *If you want to display an {@link Histogram} as a function rather than as 410 * a histogram, by making use of the fact that it implments the {@link Closure} 411 * interface and thus provide the {@link Histogram#function function} method, then you will 412 * need create a wrapper object that implements {@link Closure} but not {@link 413 * Histogram}. This is because if an object both implements the {@link Closure} 414 * interface and extends {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram 415 * Histogram} then it will be plotted as a histogram rather than as a function.
416 * 417 * @param title Title for the graph. 418 * @param things {@link Histogram}s and {@link Closure}s to superimpose on the 419 * graph. 420 * @see Board 421 * @see Closure 422 */ 423 public static void draw(String title, Closure ... things) { draw(title, null, null, things); } 424 425 /** 426 *Display a collection of {@link Histogram}s and {@link Closure}s 427 * superimposed on a single graph with a scale chosen to fit all of them.
428 * 429 *Multiple calls to {@link Board#draw draw} will produce multiple graphs which 430 * can be paged through in the {@link GUI} window.
431 * 432 *If you want to display an {@link Histogram} as a function rather than as 433 * a histogram, by making use of the fact that it implments the {@link Closure} 434 * interface and thus provide the {@link Histogram#function function} method, then you will 435 * need create a wrapper object that implements {@link Closure} but not {@link 436 * Histogram}. This is because if an object both implements the {@link Closure} 437 * interface and extends {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram 438 * Histogram} then it will be plotted as a histogram rather than as a function.
439 * 440 * @param things {@link Histogram}s and {@link Closure}s to superimpose on the 441 * graph. 442 * @see Board 443 * @see Closure 444 */ 445 public static void draw(Closure ... things) { draw(null, null, null, things); } 446 447 /** 448 *Display a collection of {@link Histogram}s and {@link Closure}s 449 * superimposed on a single graph with specified bounds on the graph's data 450 * coordinate system.
451 * 452 *Multiple calls to {@link Board#draw draw} will produce multiple graphs which 453 * can be paged through in the {@link GUI} window.
454 * 455 *If you want to display an {@link Histogram} as a function rather than as 456 * a histogram, by making use of the fact that it implments the {@link Closure} 457 * interface and thus provide the {@link Histogram#function function} method, then you will 458 * need create a wrapper object that implements {@link Closure} but not {@link 459 * Histogram}. This is because if an object both implements the {@link Closure} 460 * interface and extends {@link Histogram} then it will be plotted as 461 * a histogram rather than as a function.
462 * 463 * @param title Title for the graph. 464 * @param bounds Bounds on the graph in data coordinates. 465 * @param thingCollection {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s 466 * and {@link Closure}s to superimpose on the graph. 467 * @see Board 468 * @see Closure 469 */ 470 public static void draw(String title, Rectangle2D.Float bounds, IterableDisplay a collection of {@link Histogram}s and {@link Closure}s 476 * superimposed on a single graph with specified bounds on the graph's data 477 * coordinate system.
478 * 479 *Multiple calls to {@link Board#draw draw} will produce multiple graphs which 480 * can be paged through in the {@link GUI} window.
481 * 482 *If you want to display an {@link Histogram} as a function rather than as 483 * a histogram, by making use of the fact that it implments the {@link Closure} 484 * interface and thus provide the {@link Histogram#function function} method, then you will 485 * need create a wrapper object that implements {@link Closure} but not {@link 486 * Histogram}. This is because if an object both implements the {@link Closure} 487 * interface and extends {@link Histogram} then it will be plotted as 488 * a histogram rather than as a function.
489 * 490 * @param bounds Bounds on the graph in data coordinates. 491 * @param thingCollection {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s 492 * and {@link Closure}s to superimpose on the graph. 493 * @see Board 494 * @see Closure 495 */ 496 public static void draw(Rectangle2D.Float bounds, IterableDisplay a collection of {@link Histogram}s and {@link Closure}s 502 * superimposed on a single graph with a scale chosen to fit all of them.
503 * 504 *Multiple calls to {@link Board#draw draw} will produce multiple graphs which 505 * can be paged through in the {@link GUI} window.
506 * 507 *If you want to display an {@link Histogram} as a function rather than as 508 * a histogram, by making use of the fact that it implments the {@link Closure} 509 * interface and thus provide the {@link Histogram#function function} method, then you will 510 * need create a wrapper object that implements {@link Closure} but not {@link 511 * Histogram}. This is because if an object both implements the {@link Closure} 512 * interface and extends {@link Histogram} then it will be plotted as 513 * a histogram rather than as a function.
514 * 515 * @param title Title for the graph. 516 * @param thingCollection {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s 517 * and {@link Closure}s to superimpose on the graph. 518 * @see Board 519 * @see Closure 520 */ 521 public static void draw(String title, IterableDisplay a collection of {@link Histogram}s and {@link Closure}s 527 * superimposed on a single graph with a scale chosen to fit all of them.
528 * 529 *Multiple calls to {@link Board#draw draw} will produce multiple graphs which 530 * can be paged through in the {@link GUI} window.
531 * 532 *If you want to display an {@link Histogram} as a function rather than as 533 * a histogram, by making use of the fact that it implments the {@link Closure} 534 * interface and thus provide the {@link Histogram#function function} method, then you will 535 * need create a wrapper object that implements {@link Closure} but not {@link 536 * Histogram}. This is because if an object both implements the {@link Closure} 537 * interface and extends {@link Histogram} then it will be plotted as 538 * a histogram rather than as a function.
539 * 540 * @param thingCollection {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s 541 * and {@link Closure}s to superimpose on the graph. 542 * @see Board 543 * @see Closure 544 */ 545 public static void draw(Iterabledata and initialize {@link Histogram#area area} array.
36 * The {@link Histogram#totalArea totalArea} field is set to the number of
37 * samples falling within the histogram bounds. The {@link Histogram#area area}
38 * array is normalized to have total area one if {@link Histogram#normalized
39 * normalized} is set.
40 *
41 *
42 * @param data Sample data
43 */
44 private void binData(float[] data) {
45 int count = 0;
46 int [] hits = new int[numBins];
47 for (int bin = 0; bin < numBins; bin++) hits[bin] = 0;
48 for (float sample : data) {
49 if (sample >= lowerBound && sample <= upperBound) {
50 hits[binValue(sample)]++;
51 count++;
52 }
53 }
54 totalArea = 0.0f;
55 for (int bin = 0; bin < numBins; bin++) {
56 totalArea += (float) hits[bin];
57 area[bin] = totalArea;
58 if (normalized) area[bin] /= count;
59 }
60 }
61 }