Advertisement
Guest User

Untitled

a guest
Oct 19th, 2018
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.98 KB | None | 0 0
  1. import java.util.Random;
  2. import java.util.concurrent.atomic.AtomicBoolean;
  3. import java.util.concurrent.atomic.LongAdder;
  4.  
  5.  
  6. /**
  7. * implement the Monte Carlo algorithm as described in class or see link below.
  8. * this class implements the {@link Runnable} interface
  9. *
  10. * @see <a
  11. * href=http://mathfaculty.fullerton.edu/mathews/n2003/montecarlopimod.html>Monte
  12. * Carlo Pi</a>
  13. * @author Shahriar (Shawn) Emami
  14. * @version September 31, 2018
  15. */
  16. public class PiMonteCarloSkeleton {
  17.  
  18. /**
  19. * width of the square.
  20. */
  21. private static final double WIDTH = 1;
  22.  
  23. /**
  24. * Radius of the circle which is always half of squares
  25. * {@link PiMonteCarloSkeleton#WIDTH}.
  26. */
  27. private static final double RADIUS = WIDTH / 2;
  28.  
  29. /**
  30. * Convenience variable to be used in
  31. * {@link PiMonteCarloSkeleton#containedInCircle()}.
  32. */
  33. private static final double RADIUS_SQUARE = RADIUS * RADIUS;
  34.  
  35. /**
  36. * random generator. by placing a seed in {@link Random#Random(long)} we can
  37. * repeat the same numbers which can be very helpful for debugging.
  38. */
  39. private final Random RAND;
  40.  
  41. /**
  42. * maximum number of points to be generated.
  43. */
  44. private static long threshold;
  45. AtomicBoolean alive = new AtomicBoolean();
  46. LongAdder one = new LongAdder(); // square
  47. LongAdder two = new LongAdder(); // circle
  48.  
  49. public PiMonteCarloSkeleton (){
  50. this.RAND = new Random();
  51. }
  52.  
  53. public void run() {
  54. while (one.longValue() < threshold && alive.get()) {
  55. double one1 = this.RAND.nextDouble();
  56. double two2 = this.RAND.nextDouble();
  57. one.increment();
  58. if (containedInCircle(one1, two2)) {
  59. two.increment();
  60. }
  61. }
  62. System.out.printf("S:" + one.longValue() + ", C:" + two.longValue() + ", C/S:" + getRatio() + ", PI:" + getPI()
  63. + ", Real PI:3.1415926536");
  64.  
  65. }
  66.  
  67. /**
  68. * <p>
  69. * create an {@link AtomicBoolean} as condition of keeping the thread alive,
  70. * named alive</br>
  71. * {@link AtomicBoolean} is thread safe, allowing multiple threads to change its
  72. * value without race condition.</br>
  73. * {@link AtomicBoolean} can be manipulated using {@link AtomicBoolean#get()},
  74. * {@link AtomicBoolean#set()} and other similar methods.</br>
  75. * </p>
  76. */
  77.  
  78. /**
  79. * <p>
  80. * create two {@link LongAdder} as counters to keep track of dots in each square
  81. * and circle.</br>
  82. * {@link LongAdder} is thread safe, allowing multiple threads to change its
  83. * value without race condition.</br>
  84. * {@link LongAdder} can be manipulated using {@link LongAdder#longValue()},
  85. * {@link LongAdder#increment()} and other similar methods.</br>
  86. * </p>
  87. */
  88.  
  89. /**
  90. * <p>
  91. * create a default constructor. you are to initialize
  92. * {@link PiMonteCarloSkeleton#RAND}.</br>
  93. * </p>
  94. */
  95.  
  96. /**
  97. * <p>
  98. * complete {@link Runnable#run()} which is inherited from
  99. * {@link Runnable}.</br>
  100. * generate {@link PiMonteCarloSkeleton#threshold} points in a loop as long as
  101. * {@link PiMonteCarloSkeleton#alive} is true</br>
  102. * generate each point using {@link PiMonteCarloSkeleton#RAND} and
  103. * {@link Random#nextDouble()}.</br>
  104. * for each point generated call {@link LongAdder#increment()} for square
  105. * counter and if this point is true for
  106. * {@link PiMonteCarloSkeleton#containedInCircle()}, call
  107. * {@link LongAdder#increment()} for circle counter as well.</br>
  108. * finally print your result in following format, you can use
  109. * System.out.printf():</br>
  110. *
  111. * <pre>
  112. * S:1000, C:781, C/S:0.7810000000, PI:3.1240000000, Real PI:3.1415926536
  113. * </pre>
  114. *
  115. * in order: points in square, points in circle,
  116. * {@link PiMonteCarloSkeleton#getRatio()},
  117. * {@link PiMonteCarloSkeleton#getPI()}, real pi ({@link Math#PI}).</br>
  118. * </p>
  119. */
  120.  
  121. /**
  122. * <p>
  123. * return the ratio of dots in circle over overall dots (dots in square).</br>
  124. * divide the value of 2 {@link LongAdder} class variables, circle over square.
  125. * </br>
  126. * remember to use {@link LongAdder#doubleValue()}, dividing suing long or int
  127. * will remove the decimal precision.</br>
  128. * </p>
  129. *
  130. * @return ratio of dots in circle over square
  131. */
  132. public double getRatio() {
  133. return two.doubleValue()/one.doubleValue();
  134. }
  135.  
  136. /**
  137. * <p>
  138. * using the {@link PiMonteCarloSkeleton#getRatio()} estimate the value of
  139. * pi.</br>
  140. * value of Pi is estimated using:
  141. *
  142. * <pre>
  143. * pi_estimate ~= Area of Circle/Area of Square = (pi*r^2)/(2*r)^2
  144. * => (pi*r^2)/(4*r^2) = pi/4 => pi ~= pi_estimate*4
  145. * </pre>
  146. *
  147. * using pi ~= pi_estimate*4 and by getting pi_estimate from </br>
  148. * {@link PiMonteCarloSkeleton#getRatio()} estimate the value of pi
  149. *
  150. * @return PI
  151. */
  152. public double getPI() {
  153. return getRatio()*4;
  154. }
  155.  
  156. /**
  157. * <p>
  158. * check to see if a point is with or on the circle.</br>
  159. * we know a circle with center of (j, k) and radius (r)is represented as:</br>
  160. *
  161. * <pre>
  162. * (x-j)^2 + (y-k)^2 = r^2
  163. * </pre>
  164. *
  165. * we want to shift our circle from center 0,0 to RADIUS,RADIUS so all of the
  166. * circle is in positive range.</br>
  167. * using the formula above as long as the left side is smaller and equal to
  168. * right side (x,y) is in the circle.</br>
  169. * </p>
  170. *
  171. * @param x
  172. * - x coordinate of the point
  173. * @param y
  174. * - y coordinate of the point
  175. * @return true of the point is in the circle
  176. */
  177. private boolean containedInCircle(double x, double y) {
  178. double radiusCalc;
  179. radiusCalc = Math.pow((x - RADIUS), 2) + Math.pow((y - RADIUS), 2);
  180. if(radiusCalc <= RADIUS_SQUARE) {
  181. return true;
  182. } else {
  183. return false;
  184. }
  185. }
  186.  
  187.  
  188. /**
  189. * <p>
  190. * this method will start the thread which will start the point generation.</br>
  191. * store the value of threshold in {@link PiMonteCarloSkeleton#threshold}.</br>
  192. * use {@link PiMonteCarloSkeleton#setSeed(long)} to set new seed.</br>
  193. * set {@link PiMonteCarloSkeleton#alive} to true to allow number generation
  194. * condition to pass.</br>
  195. * using {@link Thread} or {@link ExecutorService} class start the
  196. * {@link PiMonteCarloSkeleton} thread. </br>
  197. * {@link Thread} constructor takes a {@link Runnable} object and optional
  198. * thread name as second argument. </br>
  199. * upon calling {@link Thread#start()} on the Thread object the
  200. * {@link Runnable#run()} method is called internally. </br>
  201. * </p>
  202. *
  203. * @param threshold
  204. * - number of points to be generated
  205. * @param seed
  206. * - to be used in {@link PiMonteCarloSkeleton#RAND} using
  207. * {@link Random#setSeed()}
  208. */
  209. public void simulate(long threshold, long seed) {
  210. PiMonteCarloSkeleton pmcs = new PiMonteCarloSkeleton();
  211. this.setSeed(seed);
  212. this.alive.set(true);
  213. PiMonteCarloSkeleton.threshold = threshold;
  214. new Thread((Runnable) this).start();
  215. }
  216.  
  217. /**
  218. * <p>
  219. * chain to {@link PiMonteCarloSkeleton#simulate(long, long)} and use
  220. * {@link System#currentTimeMillis()} as seed for second argument of
  221. * {@link PiMonteCarloSkeleton#simulate(long, long)}.</br>
  222. * </p>
  223. *
  224. * @param threshold
  225. * - number of points to be generated
  226. */
  227. public void simulate(long threshold) {
  228. this.simulate(threshold, System.currentTimeMillis());
  229. }
  230.  
  231. /**
  232. * <p>
  233. * stop can be called to set {@link PiMonteCarloSkeleton#alive} to false.</br>
  234. * forcing number generation to stop.
  235. * </p>
  236. */
  237. public void stop() {
  238. this.alive.set(false);
  239. }
  240.  
  241. /**
  242. * <p>
  243. * set a new seed for {@link PiMonteCarloSkeleton#RAND} using
  244. * {@link Random#setSeed()}.</br>
  245. * </p>
  246. *
  247. * @param seed
  248. * - to be used in {@link PiMonteCarloSkeleton#RAND} using
  249. * {@link Random#setSeed()}
  250. */
  251. public void setSeed(long seed) {
  252. RAND.setSeed(seed);
  253. }
  254.  
  255. /**
  256. * <p>
  257. * in main instantiate {@link PiMonteCarloSkeleton} then call
  258. * {@link PiMonteCarloSkeleton#simulate(long)}
  259. * </p>
  260. *
  261. * @param args
  262. */
  263. public static void main(String[] args) {
  264. PiMonteCarloSkeleton pmc = new PiMonteCarloSkeleton();
  265. pmc.simulate(threshold);
  266. }
  267. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement