1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math4.legacy.analysis.integration.gauss;
18
19 import org.apache.commons.math4.core.jdkmath.JdkMath;
20 import org.apache.commons.math4.legacy.core.Pair;
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 public class HermiteRuleFactory extends BaseRuleFactory<Double> {
51
52 private static final double SQRT_PI = 1.77245385090551602729;
53
54 private static final double H0 = 7.5112554446494248286e-1;
55
56 private static final double H1 = 1.0622519320271969145;
57
58
59 @Override
60 protected Pair<Double[], Double[]> computeRule(int numberOfPoints) {
61 if (numberOfPoints == 1) {
62
63 return new Pair<>(new Double[] { 0d },
64 new Double[] { SQRT_PI });
65 }
66
67
68
69
70 final int lastNumPoints = numberOfPoints - 1;
71 final Double[] previousPoints = getRuleInternal(lastNumPoints).getFirst();
72
73
74 final Double[] points = new Double[numberOfPoints];
75 final Double[] weights = new Double[numberOfPoints];
76
77 final double sqrtTwoTimesLastNumPoints = JdkMath.sqrt(2.0 * lastNumPoints);
78 final double sqrtTwoTimesNumPoints = JdkMath.sqrt(2.0 * numberOfPoints);
79
80
81 final int iMax = numberOfPoints / 2;
82 for (int i = 0; i < iMax; i++) {
83
84 double a = (i == 0) ? -sqrtTwoTimesLastNumPoints : previousPoints[i - 1].doubleValue();
85
86 double b = (iMax == 1) ? -0.5 : previousPoints[i].doubleValue();
87
88
89 double hma = H0;
90
91 double ha = H1 * a;
92
93 double hmb = H0;
94
95 double hb = H1 * b;
96 for (int j = 1; j < numberOfPoints; j++) {
97
98 final double jp1 = j + 1.0;
99 final double s = JdkMath.sqrt(2 / jp1);
100 final double sm = JdkMath.sqrt(j / jp1);
101 final double hpa = s * a * ha - sm * hma;
102 final double hpb = s * b * hb - sm * hmb;
103 hma = ha;
104 ha = hpa;
105 hmb = hb;
106 hb = hpb;
107 }
108
109
110
111 double c = 0.5 * (a + b);
112
113 double hmc = H0;
114
115 double hc = H1 * c;
116 boolean done = false;
117 while (!done) {
118 done = b - a <= Math.ulp(c);
119 hmc = H0;
120 hc = H1 * c;
121 for (int j = 1; j < numberOfPoints; j++) {
122
123 final double jp1 = j + 1.0;
124 final double s = JdkMath.sqrt(2 / jp1);
125 final double sm = JdkMath.sqrt(j / jp1);
126 final double hpc = s * c * hc - sm * hmc;
127 hmc = hc;
128 hc = hpc;
129 }
130
131 if (!done) {
132 if (ha * hc < 0) {
133 b = c;
134 hmb = hmc;
135 hb = hc;
136 } else {
137 a = c;
138 hma = hmc;
139 ha = hc;
140 }
141 c = 0.5 * (a + b);
142 }
143 }
144 final double d = sqrtTwoTimesNumPoints * hmc;
145 final double w = 2 / (d * d);
146
147 points[i] = c;
148 weights[i] = w;
149
150 final int idx = lastNumPoints - i;
151 points[idx] = -c;
152 weights[idx] = w;
153 }
154
155
156
157
158
159 if ((numberOfPoints & 1) != 0) {
160 double hm = H0;
161 for (int j = 1; j < numberOfPoints; j += 2) {
162 final double jp1 = j + 1.0;
163 hm = -JdkMath.sqrt(j / jp1) * hm;
164 }
165 final double d = sqrtTwoTimesNumPoints * hm;
166 final double w = 2 / (d * d);
167
168 points[iMax] = 0d;
169 weights[iMax] = w;
170 }
171
172 return new Pair<>(points, weights);
173 }
174 }