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.legacy.core.Pair;
20
21
22
23
24
25
26
27
28
29
30
31 public class LegendreRuleFactory extends BaseRuleFactory<Double> {
32
33 @Override
34 protected Pair<Double[], Double[]> computeRule(int numberOfPoints) {
35 if (numberOfPoints == 1) {
36
37 return new Pair<>(new Double[] { 0d },
38 new Double[] { 2d });
39 }
40
41
42
43
44 final Double[] previousPoints = getRuleInternal(numberOfPoints - 1).getFirst();
45
46
47 final Double[] points = new Double[numberOfPoints];
48 final Double[] weights = new Double[numberOfPoints];
49
50
51 final int iMax = numberOfPoints / 2;
52 for (int i = 0; i < iMax; i++) {
53
54 double a = (i == 0) ? -1 : previousPoints[i - 1].doubleValue();
55
56 double b = (iMax == 1) ? 1 : previousPoints[i].doubleValue();
57
58 double pma = 1;
59
60 double pa = a;
61
62 double pmb = 1;
63
64 double pb = b;
65 for (int j = 1; j < numberOfPoints; j++) {
66 final int two_j_p_1 = 2 * j + 1;
67 final int j_p_1 = j + 1;
68
69 final double ppa = (two_j_p_1 * a * pa - j * pma) / j_p_1;
70
71 final double ppb = (two_j_p_1 * b * pb - j * pmb) / j_p_1;
72 pma = pa;
73 pa = ppa;
74 pmb = pb;
75 pb = ppb;
76 }
77
78
79 double c = 0.5 * (a + b);
80
81 double pmc = 1;
82
83 double pc = c;
84 boolean done = false;
85 while (!done) {
86 done = b - a <= Math.ulp(c);
87 pmc = 1;
88 pc = c;
89 for (int j = 1; j < numberOfPoints; j++) {
90
91 final double ppc = ((2 * j + 1) * c * pc - j * pmc) / (j + 1);
92 pmc = pc;
93 pc = ppc;
94 }
95
96 if (!done) {
97 if (pa * pc <= 0) {
98 b = c;
99 pmb = pmc;
100 pb = pc;
101 } else {
102 a = c;
103 pma = pmc;
104 pa = pc;
105 }
106 c = 0.5 * (a + b);
107 }
108 }
109 final double d = numberOfPoints * (pmc - c * pc);
110 final double w = 2 * (1 - c * c) / (d * d);
111
112 points[i] = c;
113 weights[i] = w;
114
115 final int idx = numberOfPoints - i - 1;
116 points[idx] = -c;
117 weights[idx] = w;
118 }
119
120
121
122
123 if ((numberOfPoints & 1) != 0) {
124 double pmc = 1;
125 for (int j = 1; j < numberOfPoints; j += 2) {
126 pmc = -j * pmc / (j + 1);
127 }
128 final double d = numberOfPoints * pmc;
129 final double w = 2 / (d * d);
130
131 points[iMax] = 0d;
132 weights[iMax] = w;
133 }
134
135 return new Pair<>(points, weights);
136 }
137 }