View Javadoc

1   package org.lcsim.recon.tracking.trfutil;
2   
3   import java.util.Random;
4   
5   /**
6    * A generator produces objects with random parameters.
7    *
8    * This class is abstract and contains the interface for
9    * the random number generator.  Each instance will maintain
10   * its own sequence of random numbers.
11   *
12   * We use the default Java random number generator.
13   *
14   * The calls to rand are encapsulated so that we can keep count of
15   * the number of calls to reproduce the state.
16   *
17   * @author Norman A. Graf
18   * @version 1.0
19   */
20  public class RandomGenerator
21  {
22      
23      // attributes
24      
25      // Random number generator.
26      private Random _rand;
27      
28      // Number of calls since seed was set.
29      private int _ncall;
30      
31      // The seed
32      private long _seed;
33      
34      // methods
35      
36      /**
37       * Set the state = seed and number of calls.
38       *
39       * @param   seed  Random number seed
40       * @param   ncall Number of calls to this generator
41       */
42      private void setState(long seed, int ncall)
43      {
44          setSeed(seed);
45          for ( int i=0; i<ncall; ++i ) flat(0.0,1.0);
46      }
47      
48      
49      /**
50       * Return a flat value in range (min.max).
51       *
52       * @param   min  The minimum of the range.
53       * @param   max  The maximum of the range.
54       * @return  A double value flat between <em>min</em> and <em >max </em>.
55       */
56      protected double flat(double min, double max)
57      {
58          ++_ncall;
59          return min + (max-min)*_rand.nextDouble();
60      }
61      
62      
63      /**
64       * Return a random number according to a Gaussian distribution
65       * with sigma = 1.0.
66       * We do it this way to ensure that we can reproduce the same sequence.
67       *
68       * @return A double value gaussian distributed with mean 0 and sigma 1.
69       */
70      protected double gauss()
71      {
72          double v1, v2, r;
73          do
74          {
75              v1 = flat( -1.0, 1.0 );
76              v2 = flat( -1.0, 1.0 );
77              r = v1*v1 + v2*v2;
78          } while ( r > 1.0 );
79          double fac = Math.sqrt( -2.0*Math.log(r)/r);
80          return v2*fac;
81      }
82      
83      /**
84       * Default constructor.
85       *
86       */
87      public RandomGenerator()
88      {
89          _rand = new Random();
90          setSeed(19970729);
91      }
92      
93      /**
94       * Constructor from seed.
95       *
96       * @param   seed long value seeding the random number generator.
97       */
98      public RandomGenerator(long seed)
99      {
100         _rand = new Random();
101         setSeed(seed);
102     }
103     
104     /**
105      * Copy constructor.
106      * The new generator is independent from the original and is in the
107      * same state.
108      * Set the original seed and skip through the same number of
109      * values to obtain the same state.
110      *
111      * @param   rgen The RandomGenerator to copy.
112      */
113     public RandomGenerator( RandomGenerator rgen)
114     {
115         _rand = new Random();
116         setState(rgen);
117     }
118     
119     /**
120      * Set the seed.
121      * Generator is positioned at the beginning of the sequence.
122      * This reinitializes the generator engine, positioning it at the
123      *  first value in the sequence.
124      *
125      * @param   seed  long value seeding the random number generator.
126      */
127     public void setSeed(long seed)
128     {
129         _ncall = 0;
130         _seed = seed;
131         _rand.setSeed(seed);
132     }
133     
134     
135     /**
136      * Get the seed.
137      *
138      * @return  long value which seeded this random number generator.
139      */
140     public long seed()
141     {
142         return _seed;
143     }
144     
145     /**
146      * Set the state (seed + ncall) to be the same as that of the argument.
147      *
148      * @param   rgen RandomGenerator used to set the state of this RandomGenerator.
149      */
150     public void setState(RandomGenerator rgen)
151     {
152         setState(rgen.seed(),rgen._ncall);
153     }
154     
155     
156     /**
157      * String representation of this RandomGenerator.
158      *
159      * @return String representation of this RandomGenerator.
160      */
161     public String toString()
162     {
163         String className = getClass().getName();
164         int lastDot = className.lastIndexOf('.');
165         if(lastDot!=-1)className = className.substring(lastDot+1);
166         
167         return className+"\nSeed: " + seed() + "\n # calls: " + _ncall;
168     }
169     
170 }