| 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 |