import java.io.*;import java.math.*;import uk.ac.ed.ph.advcompsim.part3.histogram.Histogram;/** * --------------------------------------------------------------- * Excersize 3.1.3 * ---------------------------------------------------------------<br /> * 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 BITS001 package uk.ac.ed.ph.advcompsim.part3.histogram;002003 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.*;010011 /**012 * This abstract base class provides basic methods and fields for the manipulation of013 * histograms. It must be subclassed by a <code>Histogram</code> class, which defines methods014 * for binning a data sample or a given function.015 *016 *017 * @author M. L. Ciccolini018 * @author Tony Kennedy019 * @version 1.2020 * @see Histogram Histogram021 * @see Closure Closure022 */023024 public abstract class Histogram implements Closure {025026 /** Is the area normalized to one? */027 protected boolean normalized;028 029 /** Number of bins */030 protected int numBins;031032 /** Width of the bins */033 protected float binWidth;034035 /**036 * Cumulative area of the histogram in each bin, i.e., the area under the037 * histogram up to and including that bin038 */039 protected float[] area;040041 /** 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 from055 * {@link Histogram}: <ul><li>Allocate memory for the {@link Histogram#area area}056 * array,</li> <li>Initialize {@link Histogram#upperBound upperBound},057 * {@link Histogram#lowerBound lowerBound},058 * {@link Histogram#numBins numBins}, {@link Histogram#binWidth binWidth},059 * and {@link Histogram#normalized normalized}060 * fields.</li></ol>. This constructor for the <em>abstract</em>061 * base class for histograms <em>does not</em> initialize the062 * values in the {@link Histogram#area area} array, as no such values are yet063 * available to it.064 *065 *066 * @param nBins Number of bins067 * @param ub Upper bound on values to be histogrammed068 * @param lb Lower bound on values to be histogrammed069 * @param normalize set if the area under the histogram is to be normalized070 * to unity.071 * @throws IllegalArgumentException If the lower bound is greater than the upper072 * bound, or if the number of bins is not positive.073 */074 protected Histogram(int nBins, float lb, float ub, boolean normalize) throws IllegalArgumentException {075 if (nBins <= 0)076 throw new IllegalArgumentException("Number of bins must be positive");077 numBins = nBins;078 upperBound = ub;079 lowerBound = lb;080 binWidth = (upperBound - lowerBound) / (float) numBins;081 if (binWidth <= 0.0f)082 throw new IllegalArgumentException("Bins must have positive width");083 area = new float[numBins];084 normalized = normalize;085 }086 087 /**088 * Area of the specified histogram bin.089 *090 * @param bin Bin whose area is desired091 * @return Area of <code>bin</code>092 * @throws IllegalArgumentException if <code>bin</code> is out of range093 */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 }100101 /**102 * Height of the specified histogram bin.103 *104 * @param bin Bin whose height is desired105 * @return Height of <code>bin</code>106 * @throws IllegalArgumentException if <code>bin</code> is out of range107 */108 public float height(int bin) throws IllegalArgumentException {109 return binArea(bin) / binWidth;110 }111112 /**113 * Bin containing coordinate <code>x</code>.114 *115 *116 * @param x coordinate value117 * @return bin containing <code>x</code>118 * @throws IllegalArgumentException if <code>x</code> is not between119 * {@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 }127128 /**129 * Find the bin containing the cumulative area <code>x</code> within it.130 * This implementation just steps through the bins until it finds that the131 * cumulative area (in the {@link Histogram#area area} array) exceeds132 * <code>x</code>, so it takes <code>O(numBins)</code> time.133 *134 * {@question Can you find and implement an algorithm that takes135 * <code>O(ln(numBins))</code> time instead?}136 *137 * @param x Cumulative area to to left of bin.138 * @return <code>bin</code> such that <code>area[bin-1] <= x < area[bin]</code>.139 * @throws IllegalArgumentException if the <code>x</code> does not correspond140 * 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 }150151 /**152 * Maximum height of the histogram.153 *154 * @return Maximum height155 */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 }164165 /**166 * Number of bins in histogram.167 *168 * @return Number of bins169 */170 public int getNumBins() { return numBins; }171172 /**173 * Upper bound of values in histogram.174 *175 * @return Upper bound.176 */177 public float getUpperBound() { return upperBound; }178179 /**180 * Lower bound of values in histogram181 *182 * @return Lower bound.183 */184 public float getLowerBound() { return lowerBound; }185186 /**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 }194195 /**196 * Evaluate the histogram as a function.197 *198 * @param x coordinate199 * @return Height of bin containing <code>x</code>200 */201 public float function(float x) {202 if (x < lowerBound || x > upperBound) return 0.0f;203 return height(binValue(x));204 }205206 public String toString() {207 return "AbsHistogram(lowerBound = " + lowerBound208 + ", upperBound = " + upperBound209 + ", numBins = " + numBins210 + (normalized ? "" : " not") + "normalized)";211 }212213 /**214 * Prints the contents of the histogram to <code>System.out</code> as three215 * columns: the first is the bin number, the second the location of the midpoint216 * 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 }226227 /**228 * Display board in the GUI window, which is created if necessary.229 *230 * @param graph Board to be displayed.231 * @see Board232 * @see GUI233 */234 private static void show(Board graph) {235 if (window == null) window = new GUI(graph);236 else window.show(graph);237 }238239 /**240 * <p>Display a collection of {@link Histogram}s and {@link Closure}s241 * superimposed on a single graph with specified bounds on the graph's data242 * coordinate system.</p>243 *244 * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which245 * can be paged through in the {@link GUI} window.</p>246 *247 * <p>If you want to display an {@link Histogram} as a function rather than as248 * 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 will250 * need create a wrapper object that implements {@link Closure} but not {@link251 * Histogram}. This is because if an object both implements the {@link Closure}252 * interface <em>and</em> extends {@link Histogram} then it will be plotted as253 * a histogram rather than as a function.</p>254 *255 * <p>For convenient this method allows a collection of {@link Closure}s as well as256 * and vararg list of them.</p>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}s261 * and {@link Closure}s to superimpose on the graph.262 * @param things {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s263 * and {@link Closure}s to superimpose on the graph.264 * @see Board265 * @see Closure266 */267 public static void draw(String title, Rectangle2D.Float bounds, Iterable<Closure> thingCollection, Closure ... things) {268 LinkedList<Histogram> ahs = new LinkedList<Histogram>();269 LinkedList<Closure> fns = new LinkedList<Closure>();270 if (thingCollection != null) {271 for (Closure f : thingCollection) {272 if (f instanceof Histogram) ahs.add((Histogram) f);273 else fns.add(f);274 }275 }276 if (things != null) {277 for (Closure f : things) {278 if (f instanceof Histogram) ahs.add((Histogram) f);279 else fns.add(f);280 }281 }282 show(new Board(ahs, fns, bounds, title));283 }284285 /**286 * <p>Display a collection of {@link Histogram}s and {@link Closure}s287 * superimposed on a single graph with a scale chosen to fit all of them.</p>288 *289 * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which290 * can be paged through in the {@link GUI} window.</p>291 *292 * <p>If you want to display an {@link Histogram} as a function rather than as293 * 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 will295 * need create a wrapper object that implements {@link Closure} but not {@link296 * Histogram}. This is because if an object both implements the {@link Closure}297 * interface <em>and</em> extends {@link Histogram} then it will be plotted as298 * a histogram rather than as a function.</p>299 *300 * <p>For convenient this method allows a collection of {@link Closure}s as well as301 * and vararg list of them.</p>302 *303 * @param title Title for the graph.304 * @param thingCollection {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s305 * and {@link Closure}s to superimpose on the graph.306 * @param things {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s307 * and {@link Closure}s to superimpose on the graph.308 * @see Board309 * @see Closure310 */311 public static void draw(String title, Iterable<Closure> thingCollection, Closure ... things) {312 draw(title, null, thingCollection, things);313 }314315 /**316 * <p>Display a collection of {@link Histogram}s and {@link Closure}s317 * superimposed on a single graph with specified bounds on the graph's data318 * coordinate system.</p>319 *320 * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which321 * can be paged through in the {@link GUI} window.</p>322 *323 * <p>If you want to display an {@link Histogram} as a function rather than as324 * 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 will326 * need create a wrapper object that implements {@link Closure} but not {@link327 * Histogram}. This is because if an object both implements the {@link Closure}328 * interface <em>and</em> extends {@link Histogram} then it will be plotted as329 * a histogram rather than as a function.</p>330 *331 * <p>For convenient this method allows a collection of {@link Closure}s as well as332 * and vararg list of them.</p>333 *334 * @param bounds Bounds on the graph in data coordinates.335 * @param thingCollection {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s336 * and {@link Closure}s to superimpose on the graph.337 * @param things {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s338 * and {@link Closure}s to superimpose on the graph.339 * @see Board340 * @see Closure341 */342 public static void draw(Rectangle2D.Float bounds, Iterable<Closure> thingCollection, Closure ... things) {343 draw(null, bounds, thingCollection, things);344 }345346 /**347 * <p>Display a collection of {@link Histogram}s and {@link Closure}s348 * superimposed on a single graph with a scale chosen to fit all of them.</p>349 *350 * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which351 * can be paged through in the {@link GUI} window.</p>352 *353 * <p>If you want to display an {@link Histogram} as a function rather than as354 * 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 will356 * need create a wrapper object that implements {@link Closure} but not {@link357 * Histogram}. This is because if an object both implements the {@link Closure}358 * interface <em>and</em> extends {@link Histogram} then it will be plotted as359 * a histogram rather than as a function.</p>360 *361 * <p>For convenient this method allows a collection of {@link Closure}s as well as362 * and vararg list of them.</p>363 *364 * @param thingCollection {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s365 * and {@link Closure}s to superimpose on the graph.366 * @param things {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s367 * and {@link Closure}s to superimpose on the graph.368 * @see Board369 * @see Closure370 */371 public static void draw(Iterable<Closure> thingCollection, Closure ... things) {372 draw(null, null, thingCollection, things);373 }374375 /**376 * <p>Display a collection of {@link Histogram}s and {@link Closure}s377 * superimposed on a single graph with specified bounds on the graph's data378 * coordinate system.</p>379 *380 * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which381 * can be paged through in the {@link GUI} window.</p>382 *383 * <p>If you want to display an {@link Histogram} as a function rather than as384 * 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 will386 * need create a wrapper object that implements {@link Closure} but not {@link387 * Histogram}. This is because if an object both implements the {@link Closure}388 * interface <em>and</em> extends {@link Histogram} then it will be plotted as389 * a histogram rather than as a function.</p>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}s394 * and {@link Closure}s to superimpose on the graph.395 * @see Board396 * @see Closure397 */398 public static void draw(String title, Rectangle2D.Float bounds, Closure ... things) {399 draw(title, bounds, null, things);400 }401402 /**403 * <p>Display a collection of {@link Histogram}s and {@link Closure}s404 * superimposed on a single graph with a scale chosen to fit all of them.</p>405 *406 * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which407 * can be paged through in the {@link GUI} window.</p>408 *409 * <p>If you want to display an {@link Histogram} as a function rather than as410 * 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 will412 * need create a wrapper object that implements {@link Closure} but not {@link413 * Histogram}. This is because if an object both implements the {@link Closure}414 * interface <em>and</em> extends {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram415 * Histogram} then it will be plotted as a histogram rather than as a function.</p>416 *417 * @param title Title for the graph.418 * @param things {@link Histogram}s and {@link Closure}s to superimpose on the419 * graph.420 * @see Board421 * @see Closure422 */423 public static void draw(String title, Closure ... things) { draw(title, null, null, things); }424425 /**426 * <p>Display a collection of {@link Histogram}s and {@link Closure}s427 * superimposed on a single graph with a scale chosen to fit all of them.</p>428 *429 * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which430 * can be paged through in the {@link GUI} window.</p>431 *432 * <p>If you want to display an {@link Histogram} as a function rather than as433 * 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 will435 * need create a wrapper object that implements {@link Closure} but not {@link436 * Histogram}. This is because if an object both implements the {@link Closure}437 * interface <em>and</em> extends {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram438 * Histogram} then it will be plotted as a histogram rather than as a function.</p>439 *440 * @param things {@link Histogram}s and {@link Closure}s to superimpose on the441 * graph.442 * @see Board443 * @see Closure444 */445 public static void draw(Closure ... things) { draw(null, null, null, things); }446447 /**448 * <p>Display a collection of {@link Histogram}s and {@link Closure}s449 * superimposed on a single graph with specified bounds on the graph's data450 * coordinate system.</p>451 *452 * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which453 * can be paged through in the {@link GUI} window.</p>454 *455 * <p>If you want to display an {@link Histogram} as a function rather than as456 * 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 will458 * need create a wrapper object that implements {@link Closure} but not {@link459 * Histogram}. This is because if an object both implements the {@link Closure}460 * interface <em>and</em> extends {@link Histogram} then it will be plotted as461 * a histogram rather than as a function.</p>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}s466 * and {@link Closure}s to superimpose on the graph.467 * @see Board468 * @see Closure469 */470 public static void draw(String title, Rectangle2D.Float bounds, Iterable<Closure> thingCollection) {471 draw(title, bounds, thingCollection, (Closure []) null); 472 }473474 /**475 * <p>Display a collection of {@link Histogram}s and {@link Closure}s476 * superimposed on a single graph with specified bounds on the graph's data477 * coordinate system.</p>478 *479 * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which480 * can be paged through in the {@link GUI} window.</p>481 *482 * <p>If you want to display an {@link Histogram} as a function rather than as483 * 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 will485 * need create a wrapper object that implements {@link Closure} but not {@link486 * Histogram}. This is because if an object both implements the {@link Closure}487 * interface <em>and</em> extends {@link Histogram} then it will be plotted as488 * a histogram rather than as a function.</p>489 *490 * @param bounds Bounds on the graph in data coordinates.491 * @param thingCollection {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s492 * and {@link Closure}s to superimpose on the graph.493 * @see Board494 * @see Closure495 */496 public static void draw(Rectangle2D.Float bounds, Iterable<Closure> thingCollection) {497 draw(null, bounds, thingCollection, (Closure []) null); 498 }499500 /**501 * <p>Display a collection of {@link Histogram}s and {@link Closure}s502 * superimposed on a single graph with a scale chosen to fit all of them.</p>503 *504 * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which505 * can be paged through in the {@link GUI} window.</p>506 *507 * <p>If you want to display an {@link Histogram} as a function rather than as508 * 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 will510 * need create a wrapper object that implements {@link Closure} but not {@link511 * Histogram}. This is because if an object both implements the {@link Closure}512 * interface <em>and</em> extends {@link Histogram} then it will be plotted as513 * a histogram rather than as a function.</p>514 *515 * @param title Title for the graph.516 * @param thingCollection {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s517 * and {@link Closure}s to superimpose on the graph.518 * @see Board519 * @see Closure520 */521 public static void draw(String title, Iterable<Closure> thingCollection) {522 draw(title, null, thingCollection, (Closure []) null); 523 }524525 /**526 * <p>Display a collection of {@link Histogram}s and {@link Closure}s527 * superimposed on a single graph with a scale chosen to fit all of them.</p>528 *529 * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which530 * can be paged through in the {@link GUI} window.</p>531 *532 * <p>If you want to display an {@link Histogram} as a function rather than as533 * 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 will535 * need create a wrapper object that implements {@link Closure} but not {@link536 * Histogram}. This is because if an object both implements the {@link Closure}537 * interface <em>and</em> extends {@link Histogram} then it will be plotted as538 * a histogram rather than as a function.</p>539 *540 * @param thingCollection {@link uk.ac.ed.ph.advcompsim.part3.histogram.Histogram Histogram}s541 * and {@link Closure}s to superimpose on the graph.542 * @see Board543 * @see Closure544 */545 public static void draw(Iterable<Closure> thingCollection) {546 draw(null, null, thingCollection, (Closure []) null); 547 }548549 /**550 * Display the histogram.551 * TODO Check that this works! 552 */553 public void draw() { draw(this); }554555 /**556 * Display the histogram.557 *558 * TODO Check that this works! 559 * @param title Title for the graph.560 */561 public void draw(String title) { draw(title, this); }562 }THEN DATAHISTOGRAM FILE01 package uk.ac.ed.ph.advcompsim.part3.histogram;0203 import uk.ac.ed.ph.advcompsim.part3.closure.Closure;0405 /**06 * This class implements histograms generated by binning sample data values.07 * It is a subclass of the abstract {@link Histogram} class.08 * 09 * @author M. L. Ciccolini10 * @author <a href="mailto:adk@ph.ed.ac.uk">Tony Kennedy</a>11 * @version 1.312 */1314 public class DataHistogram extends Histogram {1516 /**17 * This constructor calls the constructor of the superclass {@link Histogram} setting18 * the interval and the number of bins. It then bins the sample and constructs the histogram.19 * 20 * @param nb Number of bins21 * @param ub Upper bound22 * @param lb Lower bound23 * @param data Data samples to be binned24 * @param normalize Area to be normalized?25 * @throws IllegalArgumentException if the arguments are invalid26 */2728 public DataHistogram(int nb, float lb, float ub, float[] data, boolean normalize)29 throws IllegalArgumentException {30 super(nb, lb, ub, normalize);31 binData(data);32 }3334 /**35 * Bin <code>data</code> and initialize {@link Histogram#area area} array.36 * The {@link Histogram#totalArea totalArea} field is set to the number of37 * samples falling within the histogram bounds. The {@link Histogram#area area}38 * array is normalized to have total area one if {@link Histogram#normalized39 * normalized} is set.40 * 41 * 42 * @param data Sample data43 */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 }