ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/IntegrateGamma.java
Revision: 1.9
Committed: Thu Jan 15 18:34:19 2015 UTC (9 years, 3 months ago) by jsr166
Branch: MAIN
Changes since 1.8: +0 -2 lines
Log Message:
delete extraneous blank lines

File Contents

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