ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/IntegrateGamma.java
Revision: 1.5
Committed: Tue Mar 15 19:47:05 2011 UTC (13 years, 1 month ago) by jsr166
Branch: MAIN
CVS Tags: release-1_7_0
Changes since 1.4: +1 -1 lines
Log Message:
Update Creative Commons license URL in legal notices

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 import java.util.concurrent.*;
8
9 /**
10 * Adapted from FJTask version.
11 * Sample program using Guassian Quadrature for numerical integration.
12 * Inspired by a
13 * <A href="http://www.cs.uga.edu/~dkl/filaments/dist.html"> Filaments</A>
14 * demo program.
15 *
16 */
17
18 public class IntegrateGamma {
19 /** for time conversion */
20 static final long NPS = (1000L * 1000 * 1000);
21 public static void main(String[] args) {
22 int procs = 0;
23 double start = 1.0;
24 double end = 96.0;
25 int exp = 5;
26 try {
27 if (args.length > 0)
28 procs = Integer.parseInt(args[0]);
29 if (args.length > 1)
30 start = new Double(args[1]).doubleValue();
31 if (args.length > 2)
32 end = new Double(args[2]).doubleValue();
33 if (args.length > 3)
34 exp = Integer.parseInt(args[3]);
35 }
36 catch (Exception e) {
37 System.out.println("Usage: java IntegrateGamma <threads> <lower bound> <upper bound> <exponent>\n (for example 2 1 48 5).");
38 return;
39 }
40
41 ForkJoinPool g = (procs == 0) ? new ForkJoinPool() :
42 new ForkJoinPool(procs);
43
44 System.out.println("Integrating from " + start + " to " + end + " exponent: " + exp + " parallelism " + g.getParallelism());
45
46 Function f = new SampleFunction(exp);
47 for (int i = 0; i < 10; ++i) {
48 Integrator integrator = new Integrator(f, 0.001, g);
49 long last = System.nanoTime();
50 double result = integrator.integral(start, end);
51 double elapsed = elapsedTime(last);
52 System.out.printf("time: %7.3f", elapsed);
53 System.out.println(" Answer = " + result);
54 }
55 System.out.println(g);
56 g.shutdown();
57 }
58
59 static double elapsedTime(long startTime) {
60 return (double)(System.nanoTime() - startTime) / NPS;
61 }
62
63 /*
64 This is all set up as if it were part of a more serious
65 framework, but is for now just a demo, with all
66 classes declared as static within Integrate
67 */
68
69 /** A function to be integrated */
70 static interface Function {
71 double compute(double x);
72 }
73
74 /**
75 * Sample from filaments demo.
76 * Computes (2*n-1)*(x^(2*n-1)) for all odd values.
77 */
78 static class SampleFunction implements Function {
79 final int n;
80 SampleFunction(int n) { this.n = n; }
81
82 public double compute(double x) {
83 double power = x;
84 double xsq = x * x;
85 double val = power;
86 double di = 1.0;
87 for (int i = n - 1; i > 0; --i) {
88 di += 2.0;
89 power *= xsq;
90 val += di * power;
91 }
92 return val;
93 }
94 }
95
96
97 static class Integrator {
98 final Function f; // The function to integrate
99 final double errorTolerance;
100 final ForkJoinPool g;
101
102 Integrator(Function f, double errorTolerance, ForkJoinPool g) {
103 this.f = f;
104 this.errorTolerance = errorTolerance;
105 this.g = g;
106 }
107
108 double integral(double lowerBound, double upperBound) {
109 double f_lower = f.compute(lowerBound);
110 double f_upper = f.compute(upperBound);
111 double initialArea = 0.5 * (upperBound-lowerBound) * (f_upper + f_lower);
112 Quad q = new Quad(lowerBound, upperBound,
113 f_lower, f_upper,
114 initialArea);
115 g.invoke(q);
116 return q.area;
117 }
118
119
120 /**
121 * FJTask to recursively perform the quadrature.
122 * Algorithm:
123 * Compute the area from lower bound to the center point of interval,
124 * and from the center point to the upper bound. If this
125 * differs from the value from lower to upper by more than
126 * the error tolerance, recurse on each half.
127 */
128 final class Quad extends RecursiveAction {
129 final double left; // lower bound
130 final double right; // upper bound
131 final double f_left; // value of the function evaluated at left
132 final double f_right; // value of the function evaluated at right
133
134 // Area initialized with original estimate from left to right.
135 // It is replaced with refined value.
136 volatile double area;
137
138 Quad(double left, double right,
139 double f_left, double f_right,
140 double area) {
141 this.left = left;
142 this.right = right;
143 this.f_left = f_left;
144 this.f_right = f_right;
145 this.area = area;
146 }
147
148 public void compute() {
149 double center = 0.5 * (left + right);
150 double f_center = f.compute(center);
151
152 double leftArea = 0.5 * (center - left) * (f_left + f_center);
153 double rightArea = 0.5 * (right - center) * (f_center + f_right);
154 double sum = leftArea + rightArea;
155
156 double diff = sum - area;
157 if (diff < 0) diff = -diff;
158
159 if (diff >= errorTolerance) {
160 Quad q1 = new Quad(left, center, f_left, f_center, leftArea);
161 q1.fork();
162 Quad q2 = new Quad(center, right, f_center, f_right, rightArea);
163 q2.compute();
164 q1.join();
165 sum = q1.area + q2.area;
166 }
167
168 area = sum;
169 }
170 }
171 }
172
173 }
174
175