All pastes #766032 Raw Edit

Untitled

public text v1 · immutable
·published 2007-11-08 15:46 UTC
rendered paste body
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 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 <code>Histogram</code> 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}: <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 the
062      * values in the {@link Histogram#area area} array, as no such values are yet
063      * available to it.
064      *
065      *
066      * @param nBins Number of bins
067      * @param ub Upper bound on values to be histogrammed
068      * @param lb Lower bound on values to be histogrammed
069      * @param normalize set if the area under the histogram is to be normalized
070      *   to unity.
071      * @throws IllegalArgumentException If the lower bound is greater than the upper
072      *   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 desired
091      * @return Area of <code>bin</code>
092      * @throws IllegalArgumentException if <code>bin</code> 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 <code>bin</code>
106      * @throws IllegalArgumentException if <code>bin</code> 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 <code>x</code>.
114      *
115      *
116      * @param x coordinate value
117      * @return bin containing <code>x</code>
118      * @throws IllegalArgumentException if <code>x</code> 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 <code>x</code> 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      * <code>x</code>, so it takes <code>O(numBins)</code> time.
133      *
134      * {@question Can you find and implement an algorithm that takes
135      * <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 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 <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     }
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 <code>System.out</code> 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      * <p>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.</p>
243      *
244      * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which
245      * 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 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 <em>and</em> extends {@link Histogram} then it will be plotted as
253      * a histogram rather than as a function.</p>
254      *
255      * <p>For convenient this method allows a collection of {@link Closure}s as well as
256      * 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}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, 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     }
284     
285     /**
286      * <p>Display 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.</p>
288      *
289      * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which
290      * 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 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 <em>and</em> extends {@link Histogram} then it will be plotted as
298      * a histogram rather than as a function.</p>
299      *
300      * <p>For convenient this method allows a collection of {@link Closure}s as well as
301      * 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}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, Iterable<Closure> thingCollection, Closure ... things) {
312         draw(title, null, thingCollection, things);
313     }
314     
315     /**
316      * <p>Display 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.</p>
319      *
320      * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which
321      * 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 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 <em>and</em> extends {@link Histogram} then it will be plotted as
329      * a histogram rather than as a function.</p>
330      *
331      * <p>For convenient this method allows a collection of {@link Closure}s as well as
332      * 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}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, Iterable<Closure> thingCollection, Closure ... things) {
343         draw(null, bounds, thingCollection, things);
344     }
345  
346     /**
347      * <p>Display 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.</p>
349      *
350      * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which
351      * 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 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 <em>and</em> extends {@link Histogram} then it will be plotted as
359      * a histogram rather than as a function.</p>
360      *
361      * <p>For convenient this method allows a collection of {@link Closure}s as well as
362      * and vararg list of them.</p>
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(Iterable<Closure> thingCollection, Closure ... things) {
372         draw(null, null, thingCollection, things);
373     }
374     
375     /**
376      * <p>Display 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.</p>
379      *
380      * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which
381      * 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 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 <em>and</em> extends {@link Histogram} then it will be plotted as
389      * 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}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      * <p>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.</p>
405      *
406      * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which
407      * 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 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 <em>and</em> 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.</p>
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      * <p>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.</p>
428      *
429      * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which
430      * 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 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 <em>and</em> 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.</p>
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      * <p>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.</p>
451      *
452      * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which
453      * 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 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 <em>and</em> extends {@link Histogram} then it will be plotted as
461      * 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}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, Iterable<Closure> thingCollection) {
471         draw(title, bounds, thingCollection, (Closure []) null); 
472     }
473     
474     /**
475      * <p>Display 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.</p>
478      *
479      * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which
480      * 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 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 <em>and</em> extends {@link Histogram} then it will be plotted as
488      * 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}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, Iterable<Closure> thingCollection) {
497         draw(null, bounds, thingCollection, (Closure []) null); 
498     }
499     
500     /**
501      * <p>Display 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.</p>
503      *
504      * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which
505      * 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 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 <em>and</em> extends {@link Histogram} then it will be plotted as
513      * 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}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, Iterable<Closure> thingCollection) {
522         draw(title, null, thingCollection, (Closure []) null); 
523     }
524     
525     /**
526      * <p>Display 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.</p>
528      *
529      * <p>Multiple calls to {@link Board#draw draw} will produce multiple graphs which
530      * 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 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 <em>and</em> extends {@link Histogram} then it will be plotted as
538      * a histogram rather than as a function.</p>
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(Iterable<Closure> thingCollection) {
546         draw(null, null, thingCollection, (Closure []) null); 
547     }
548     
549     /**
550      * Display the histogram.
551      * TODO Check that this works! 
552      */
553     public void draw() { draw(this); }
554     
555     /**
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 FILE

01 package uk.ac.ed.ph.advcompsim.part3.histogram;
02 
03 import uk.ac.ed.ph.advcompsim.part3.closure.Closure;
04 
05 /**
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. Ciccolini
10  * @author <a href="mailto:adk@ph.ed.ac.uk">Tony Kennedy</a>
11  * @version 1.3
12  */
13 
14 public class DataHistogram extends Histogram {
15     
16     /**
17      * This constructor calls the constructor of the superclass {@link Histogram} setting
18      * the interval and the number of bins. It then bins the sample and constructs the histogram.
19      * 
20      * @param nb Number of bins
21      * @param ub Upper bound
22      * @param lb Lower bound
23      * @param data Data samples to be binned
24      * @param normalize Area to  be normalized?
25      * @throws IllegalArgumentException if the arguments are invalid
26      */
27     
28     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     }
33     
34     /**
35      * Bin <code>data</code> 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 }