Home : Map : Chapter 7 : Java : Tech : Physics :
Histogram Distribution
JavaTech
Course Map
Chapter 7

Introduction
Event Overview
Event Processing
Button Events
  Demo 1
 Demo 2
Mouse Events
  Demo3

More Components
  Demo 4  Demo 5
  Demo 6  Demo 7

LayoutManagers-1
  Demo 8     Demo 9
  Demo 10  Demo 11
  Demo 12

LayoutManagers-2
  Demo 13  Demo 14
  Demo 15  Demo 16
  Demo 17

Inner Classes
Anonymous Class
Adapter Classes
  Demo 18  Demo 19
Frames & Menus
  Demo 20  Demo 21
Exercises

    Supplements
AWT Components
  Button
     Demo 1
  Canvas
     Demo 2
  AWT GUI Demo
     Demo 3
Swing Dialogs
JOptionPane Dialog
  Demo 1
JDialog
  Demo 2
UI Enhancement: P1
  Demo 1   Demo 2
  Demo 3

UI Enhancement: P2
  Demo 1
     About JavaTech
     Codes List
     Exercises
     Feedback
     References
     Resources
     Tips
     Topic Index
     Course Guide
     What's New

For the rejection method discussed in Chapter 7: Tech and in the section Custom Probability Distributions in this chapter, we need a function g(y) to which we can compare the "second throw" of the uniform random number generator, if we make an analogy to throwing dice. If the second throw is equal or below g(y), the program accepts the value y obtained in the "first throw".

A histogram distribution can be modified to act as such a probability distribution (called experimental distributions in Bisset) :

    pi = ni/N

for bin i with ni contents and total histogram entries N. Then the probability density goes as

    p(x) = pi/w = ni/wN

where w is the bin width and i = (x - xmin)/w for a histogram of values between xmin and xmax.

However, for f(x) we want to reject as few attempts as possible, so it's more efficient to normalize to the maximum bin value. That is,

    fi = ni/nmax

where nmax equals the number of entries in the largest bin. Our uniform random number generator will provide values in the range xmin < r1 < xmax. Selecting the bin closes we can compare the second throw to a simple constant comparison function c(x)=1. (A comparison function that more closely fits f(x) will reduce the rejection rate.) If r2 < fi then the value of the first throw xmin < r1 < xmax will be accepted.

In the beam case mentioned in the previous section, we used a simple function to give us the g(x) for the rejection method to simulate the distribution of tracks through a detector. What if the situation was made more complicated by, say, a beampipe flange that screened out a portion of the tracks. In this and other real world problems can result in distributions that can easily be approximated with simple functions.

In such situations, it might be easier to first use an experimentally obtained distribution, say from a test beam, and then use the resulting histogram for our rejection method when doing other simulation studies.

For example, when studying the behavior of one detector element, I might want to consider only those particle tracks that traversed sensitive areas of the detector element in front of it. I could generate such tracks by using the experimentally obtained distribution for the detector element in front of the one of interest.

The program below shows a similar display as in the previous example except that a histogram provides the distribution of track angles. For generating the random values we use a histogram of facsimile experimental data where some areas are empty (due perhaps to obstacles in the support structure of the detector or insensitive areas in the detector.)

As you add entries to the histogram, it will gradually come to follow more and more closely the experimental data distribution:


RanDistHistApplet.java - The first histogram holds a distribution that emulates what one might obtain from an experiment. The second histogram displays a distribution of random values that follows the pattern in the first histogram.

+ Previous classes:
Chapter 6:Tech: Histogram.java, HistPanel.java
Chapter 6:Tech: PlotPanel.java, PlotFormat.java

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/**
  *  The first histogram holds a distribution that emulates what one
  *  might obtain from an experiment. The second histogram displays
  *  a distribution of random values that follows the pattern in
  *  the first histogram.
  *
  *  The applet uses two instances of HistPanel to display contents of
  *  two instances of Histogram.
  *
  *
  *  Includes "Go" button to add random values that follow the data
  *  histogram distribution. The number of values taken from
  *  entry in a JTextField. "Clear"  button clears the histogram.
  *  In standalone mode, the Exit button closes the program.
  *  
  *  This program will run as an applet inside
  *  an application frame.
**/
public class RanDistHistApplet extends JApplet
             implements ActionListener
{
  // Use the HistPanel JPanel subclass here
  HistPanel fOutputPanel;

  Histogram fHistogram;
  int fNumDataPoints = 1000;

  // Create the histogram distribution function.
  HistPanel fRanHistPanel;
  Histogram fRanHistogram;
  int fRanHistBins;
  double [] fRanDist;

  // Set the angular range for scattered tracks
  double fMinAngle;
  double fMaxAngle;
  double fAngleRange;

  // Random number generator
  java.util.Random fRan;

  // A text field for input strings
  JTextField textField = null;

  // Flag for whether the applet is in a browser
  // or running via the main () below.
  boolean fInBrowser = true;

  //Buttons
  JButton fGoButton;
  JButton fClearButton;
  JButton fExitButton;

  /**
    * Create a User Interface with histograms and buttons to
    * control the program. A textfield holds number of entries
    * to be generated for the histogram.
   **/
  public void init () {

    JPanel panel = new JPanel (new BorderLayout ());

    // Get the data and make the histogram to use for
    // generating the random distributions.
    getRanHist ();

    // Create a histogram with Gaussian distribution.
    makeHist ();

    // JPanel subclass here.
    fOutputPanel = new HistPanel (fHistogram);
    fRanHistPanel = new HistPanel (fRanHistogram);

    JPanel hists_panel = new JPanel (new GridLayout (1,2));
    hists_panel.add (fRanHistPanel);
    hists_panel.add (fOutputPanel);

    panel.add (hists_panel,"Center");

    // Use a textfield for an input parameter.
    textField =
      new JTextField (Integer.toString (fNumDataPoints), 10);

    // If return hit after entering text, the
    // actionPerformed will be invoked.
    textField.addActionListener (this);

    fGoButton = new JButton ("Go");
    fGoButton.addActionListener (this);

    fClearButton = new JButton ("Clear");
    fClearButton.addActionListener (this);

    fExitButton = new JButton ("Exit");
    fExitButton.addActionListener (this);

    JPanel control_panel = new JPanel ();

    control_panel.add (textField);
    control_panel.add (fGoButton);
    control_panel.add (fClearButton);
    control_panel.add (fExitButton);

    if (fInBrowser) fExitButton.setEnabled (false);

    panel.add (control_panel,"South");

    // Add text area with scrolling to the contentPane.
    add (panel);

  } // init

  public void actionPerformed (ActionEvent e){
    Object source = e.getSource ();
    if (source == fGoButton || source == textField) {
      String strNumDataPoints = textField.getText ();
      try {
        fNumDataPoints = Integer.parseInt (strNumDataPoints);
      }
      catch (NumberFormatException ex) {
        // Could open an error dialog here but just
        // display a message on the browser status line.
        showStatus ("Bad input value");
        return;
      }
      makeHist ();
      repaint ();
    }
    else if (source == fClearButton) {
        fHistogram.clear ();
        repaint ();
    } else if (!fInBrowser)
        System.exit (0);
  } // actionPerformed

  /**
    * Create a random distribution of angles to
    * simulate the tracks in a particle scattering
    * experiment entering a detector element.
   **/
  void makeHist () {

    // Create an instance of the Random class for
    // producing our random values.
    fRan = new java.util.Random ();

    // Create an instance of our basic histogram class.
    // Make it wide enough enough to include most of the
    // gaussian values.
    if (fHistogram == null)
        fHistogram = new Histogram ("Ran Dist from Data Histogram",
                                "Degrees",
                                50,fMinAngle,fMaxAngle);


    // Use the transformation method to generate a
    // radioactive decay distribution
    for (int i=0; i < fNumDataPoints; i++) {
      // Generate random vals 0.0 to 1.0
      double r1 = fRan.nextDouble ();
      double angle = fMinAngle +  (fMaxAngle-fMinAngle)*r1;
      if (acceptAngle (angle) ){
         fHistogram.add (angle);
      }
    }
  } // makeHist

  /**
    *  This method creates the histogram that will be used to provide
    *  a random value distribution that matches a data distribution.
    *  In this case, the histogram is made with a fake set of data.
    *  For an actual experiment, this routine would obtain the data
    *  from a file in which the a histogram filled with real was saved.
   **/
  void getRanHist (){

    // Simulated data for creating the desired distibution.
    int [] ranData =
      {  20, 26, 34, 5, 0, 57, 65, 70, 0,  3,
         85, 93, 101, 0, 0, 122, 130, 138, 1,  3,
        158, 166, 174, 180, 188};

    // Range of the histogram.
    fMinAngle = 25.0;
    fMaxAngle = 50.0;
    fAngleRange = 25.0;
    fRanHistBins = ranData.length;

    // Create a histogram to provide the ran number distribution.
    fRanHistogram = new Histogram ("Expt. Data Dist",
                                 "Degrees",
                                 25,fMinAngle,fMaxAngle);
    fRanHistogram.pack (ranData, 0, 0, fMinAngle, fMaxAngle);

    fRanDist = new double[ranData.length];
    int maxVal = fRanHistogram.getMax ();
    // Create that comparison function for generating the
    // random distribution.
    for (int i=0; i < fRanHistBins; i++){
        fRanDist[i] =  ( (double)ranData[i])/maxVal;
    }

  } // getRanHist

  /**
    * This rejection function uses a simple linear
    * function to determine the acceptance of the
    * angle.
   **/
  boolean acceptAngle (double angle){
    if ( angle < fMinAngle || angle >= fMaxAngle) return false;

    double val = angle - fMinAngle;

    // Casting to int will round off to lower
    // integer value.
    int bin =  (int) (fRanHistBins *  (val/fAngleRange) );

    double r2 = fRan.nextDouble ();
    if ( r2 <= fRanDist[bin]) return true;
    return false;
  } // acceptAngle

  public static void main (String[] args) {
    //
    int frame_width=450;
    int frame_height=300;

    // Create an applet and add it to a frame.
    RanDistHistApplet applet = new RanDistHistApplet ();
    applet.fInBrowser = false;
    applet.init ();

    // Following anonymous class used to close window & exit program
    JFrame f = new JFrame ("Demo");
    f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

    // Add applet to the frame
    f.getContentPane ().add ( applet);
    f.setSize (new Dimension (frame_width,frame_height));
    f.setVisible (true);
  } // main

} // RanDistHistApplet

 

References & Web Resources

Most recent update Oct. 22, 2005

           Tech
Histogram UI
  Demo 1
Probablity Distrib.
  Demo 2 Demo 3
RejectionMethod
Histogram Stats
  Demo 4
Exercises

           Physics
Sim & Randomness
Custom Prob. Dist.
   Demo 1
Histogram Dist.
   Demo 2
Monte Carlo
  Demo 3
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.