1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.hipparchus.analysis.integration.gauss;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.Field;
21 import org.hipparchus.exception.MathIllegalArgumentException;
22 import org.hipparchus.util.MathArrays;
23 import org.hipparchus.util.Pair;
24
25
26
27
28
29
30
31
32
33
34
35
36
37 public class FieldLegendreRuleFactory<T extends CalculusFieldElement<T>> extends FieldAbstractRuleFactory<T> {
38
39
40
41
42 public FieldLegendreRuleFactory(final Field<T> field) {
43 super(field);
44 }
45
46
47 @Override
48 public Pair<T[], T[]> computeRule(int numberOfPoints)
49 throws MathIllegalArgumentException {
50
51 final Field<T> field = getField();
52
53 if (numberOfPoints == 1) {
54
55 final T[] points = MathArrays.buildArray(field, numberOfPoints);
56 final T[] weights = MathArrays.buildArray(field, numberOfPoints);
57 points[0] = field.getZero();
58 weights[0] = field.getZero().newInstance(2);
59 return new Pair<>(points, weights);
60 }
61
62
63 final Legendre<T> p = new Legendre<>(numberOfPoints);
64 final T[] points = findRoots(numberOfPoints, p::ratio);
65 enforceSymmetry(points);
66
67
68 final T[] weights = MathArrays.buildArray(field, numberOfPoints);
69 for (int i = 0; i <= numberOfPoints / 2; i++) {
70 final T c = points[i];
71 final T[] pKpKm1 = p.pNpNm1(c);
72 final T d = pKpKm1[1].subtract(c.multiply(pKpKm1[0])).multiply(numberOfPoints);
73 weights[i] = c.square().subtract(1).multiply(-2).divide(d.multiply(d));
74
75
76 final int idx = numberOfPoints - i - 1;
77 weights[idx] = weights[i];
78
79 }
80
81 return new Pair<>(points, weights);
82
83 }
84
85
86
87
88 private static class Legendre<T extends CalculusFieldElement<T>> {
89
90
91 private int degree;
92
93
94
95
96 Legendre(int degree) {
97 this.degree = degree;
98 }
99
100
101
102
103
104 public T ratio(T x) {
105 T pm = x.getField().getOne();
106 T p = x;
107 T d = x.getField().getOne();
108 for (int n = 1; n < degree; n++) {
109
110
111 final T pp = p.multiply(x.multiply(2 * n + 1)).subtract(pm.multiply(n)).divide(n + 1);
112 d = p.multiply(n + 1).add(d.multiply(x));
113 pm = p;
114 p = pp;
115 }
116 return p.divide(d);
117 }
118
119
120
121
122
123 private T[] pNpNm1(final T x) {
124 T[] p = MathArrays.buildArray(x.getField(), 2);
125 p[0] = x;
126 p[1] = x.getField().getOne();
127 for (int n = 1; n < degree; n++) {
128
129 final T pp = p[0].multiply(x.multiply(2 * n + 1)).subtract(p[1].multiply(n)).divide(n + 1);
130 p[1] = p[0];
131 p[0] = pp;
132 }
133 return p;
134 }
135
136 }
137
138 }