Home : Course Map : Chapter 3 : Java : Tech :
Histogram Class
JavaTech
Course Map
Chapter 3

Introduction
Class Definition
Data Fields
Methods
Constructors
Instantiation
  
Demo 1
  Demo 2
Static Members
  Demo 3

Value&Reference
  Demo 4
Overloading
   Demo 5
Wrappers 
  Demo 6
Autobox/Unbox
   Demo 7
Arrays
  Demo 8
Exceptions
Exercises

    Supplements
MoreAboutObjects
Creating Types

Classes,Objs&JVM

Java OOP vs C++
Garbage Collection
     About JavaTech
     Codes List
     Exercises
     Feedback
     References
     Resources
     Tips
     Topic Index
     Course Guide
     What's New

A histogram provides the frequency distribution of values taken by a parameter of interest. These types of distributions are often needed in science and engineering studies.

For example, say that an experiment counts the number of cosmic rays passing through a detector every minute. We might expect, say, a distribution of "hits" per minute to have a mean around 10. We record the number of hits every minute over a period of a few hours and then make a histogram of the values.

We create a histogram with, say, 10 bins in which the first bin holds the number of times the hits measured between 0 and 4, the second bin for between 5 and 8, and so forth, up to the last bin which counts the number of times the hits were between 37 and 40. The resulting Poisson type distribution would peak below 10 and have a tail that falls to zero on the low side and a long tail on the high side.

The following BasicHist.java class provides some essential histogram features. The class attributes include instance variables for the number of bins, an integer array of bins, over and under flow counts, and the minimum and maximum values that the histogram spans. The constructor creates an instance of the class for a given set of bins and for a lower and upper parameter range.

The three methods provide for adding an entry to the histogram, clearing the histogram, and for obtaining the values in the bins (including the over and underflows.)

BasicHist.java
/** A simple histogram class to count the frequency of
  * values of a parameter of interest.
 **/

public class
BasicHist
{
  int [] bins;
  int numBins;
  int underflows;
  int overflows;

  double lo;
  double hi;
  double range;

  /** The constructor will create an array of a given
    * number of bins. The range of the histogram given
    * by the upper and lower limt values.
   **/
  public BasicHist (int numBins, double lo, double hi) {
    this.numBins = numBins;

    bins = new int[numBins];

    this.lo = lo;
    this.hi = hi;
    range = hi - lo;
  }

  /**
    * Add an entry to a bin.
    * Include if value is in the range
    * lo <= x < hi
   **/
  public void add(double x) {
    if
( x >= hi) overflows++;
    else if
( x < lo) underflows++;
    else {
      double val = x - lo;

      // Casting to int will round off to lower
      // integer value.

     int bin = (
int)(numBins * (val/range) );

      // Increment the corresponding bin.
      bins[bin]++;
    }
  }

  /** Clear the histogram bins. **/
  public void clear() {
    for
(int i=0; i < numBins; i++) {
        bins[i] = 0;
        overflows = 0;
        underflows= 0;
    }
  }

  /** Provide access to the bin values. **/
  public int getValue(
int bin) {
    if
(bin < 0)
        return underflows;
    else if
( bin >= numBins)
        return overflows;
    else
        return bins[bin];
  }
}

The applet below creates and instance of BasicHist and uses it to provide a histogram of the distribution of values generated by Gaussian random number generator. (We will discuss details about random number generation in Java in Chapter 4: Tech.)

BasicHistApplet1.java
(Output goes to browser's Java console.)
public class  BasicHistApplet1 extends java.applet.Applet
{
  public void init() {   
     // Create an instance of the Random class for
     // producing our random values.

     java.util.Random r = new java.util.Random();
     // Them method nextGaussian in the class Random produces
     // values centered at 0.0 and with a standard deviation
     // of 1.0.

     // Create an instance of our basic histogram class.
     // Make it wide enough enough to include most of the
     // gaussian values.

     BasicHist bh = new BasicHist (10,-2.0,2.0);

     // Fill the histogram
     for (int i=0; i < 100; i++) {
       double val = r.nextGaussian ();
       bh.add (val);
     }

     // Print out the frequency values in each bin.
     for(int i=0; i < 10; i++) {
       System.out.println("Bin " + i + " = "+ bh.getValue (i));
     }

     // Negative bin values gives the underflows
     System.out.println ("Underflows = "+ bh.getValue (-1));

     // Bin values above the range give the overflows.
     System.out.println ("Overflows = "+ bh.getValue (10));

   //------------------------------------------------
   // and this line.

  }
  ... standard code...
}

 

When we run the above applet, an output similar to the following will be produced:

Bin 0 = 3
Bin 1 = 8
Bin 2 = 12
Bin 3 = 14
Bin 4 = 15
Bin 5 = 17
Bin 6 = 9
Bin 7 = 9
Bin 8 = 7
Bin 9 = 3
Underflows = 1
Overflows = 2

 

We see that the distribution does in fact roughly follow the general shape of a guassian centered in the middle bins.

Object Oriented vs Procedural

The histogram example provides a nice illustration of the power and utility of object oriented program design.

If your program had 20 parameters to examine, you can simply create 20 instances of BasicHist, each with its own number of bins and range limits relevant to that parameter. If at some later point, we add new methods and instance variables to the BasicHist, you don't not need to modify the code in your program as long as the changes are internal and don't affect the argument lists in the methods that you invoke.

If you think about how to do histogramming in a purely procedural code manner, you will start to appreciate the elegance of the object oriented approach. In a procedural program, you would need to create arrays to hold the histogram values. Most likely you would use a 2-D array with the first index for the given histogram, and the second index corresponding to the bins.

Similarly, you could use arrays to hold the parameters of the histograms, such as the number of bins, the lower and upper ranges, and so forth. Functions to add entries to the histograms would require a lot of bookkeeping to determine which histogram was needed. With classes, we just create 20 instances of the BasicHist type and each instance knows which histogram it is and you don't have to worry about keeping track of the histogramming details in your code.

Furthermore, if you wanted to use the histogram code in another program, it would be messy to extract just that code from the program and move it into the new one. The encapsulation aspect inherent to the object approach makes reusability far easier that with procedural code.

 

References & Web Resources

Latest update: Oct. 19.2004

           Tech
OOP in Tech Apps
Complex Number
Histogram Class
  Demo
More Wrappers

           Physics
OOP in Physics
Particle Class
Root Finding
  Demo 1
Newton Methods
  Demo 2
Exercises

  Part I Part II Part III
Java Core 1  2  3  4  5  6  7  8  9  10  11  12 13 14 15 16 17
18 19 20
21
22 23 24
Supplements

1  2  3  4  5  6  7  8  9  10  11  12

Tech 1  2  3  4  5  6  7  8  9  10  11  12
Physics 1  2  3  4  5  6  7  8  9  10  11  12

Java is a trademark of Sun Microsystems, Inc.