1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.hipparchus.analysis.polynomials;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.Field;
21 import org.hipparchus.analysis.CalculusFieldUnivariateFunction;
22 import org.hipparchus.exception.LocalizedCoreFormats;
23 import org.hipparchus.exception.MathIllegalArgumentException;
24 import org.hipparchus.exception.NullArgumentException;
25 import org.hipparchus.util.FastMath;
26 import org.hipparchus.util.MathArrays;
27 import org.hipparchus.util.MathUtils;
28
29
30
31
32
33
34
35
36
37
38 public class FieldPolynomialFunction<T extends CalculusFieldElement<T>> implements CalculusFieldUnivariateFunction<T> {
39
40
41
42
43
44
45 private final T[] coefficients;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 public FieldPolynomialFunction(final T[] c)
62 throws MathIllegalArgumentException, NullArgumentException {
63 super();
64 MathUtils.checkNotNull(c);
65 int n = c.length;
66 if (n == 0) {
67 throw new MathIllegalArgumentException(LocalizedCoreFormats.EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY);
68 }
69 while ((n > 1) && (c[n - 1].isZero())) {
70 --n;
71 }
72 this.coefficients = MathArrays.buildArray(c[0].getField(), n);
73 System.arraycopy(c, 0, this.coefficients, 0, n);
74 }
75
76
77
78
79
80
81
82
83
84
85
86
87
88 public T value(double x) {
89 return evaluate(coefficients, getField().getZero().add(x));
90 }
91
92
93
94
95
96
97
98
99
100
101
102
103
104 @Override
105 public T value(T x) {
106 return evaluate(coefficients, x);
107 }
108
109
110
111
112 public Field<T> getField() {
113 return coefficients[0].getField();
114 }
115
116
117
118
119
120
121 public int degree() {
122 return coefficients.length - 1;
123 }
124
125
126
127
128
129
130
131
132
133 public T[] getCoefficients() {
134 return coefficients.clone();
135 }
136
137
138
139
140
141
142
143
144
145
146
147
148 protected static <T extends CalculusFieldElement<T>> T evaluate(T[] coefficients, T argument)
149 throws MathIllegalArgumentException, NullArgumentException {
150 MathUtils.checkNotNull(coefficients);
151 int n = coefficients.length;
152 if (n == 0) {
153 throw new MathIllegalArgumentException(LocalizedCoreFormats.EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY);
154 }
155 T result = coefficients[n - 1];
156 for (int j = n - 2; j >= 0; j--) {
157 result = argument.multiply(result).add(coefficients[j]);
158 }
159 return result;
160 }
161
162
163
164
165
166
167
168 public FieldPolynomialFunction<T> add(final FieldPolynomialFunction<T> p) {
169
170 final int lowLength = FastMath.min(coefficients.length, p.coefficients.length);
171 final int highLength = FastMath.max(coefficients.length, p.coefficients.length);
172
173
174 T[] newCoefficients = MathArrays.buildArray(getField(), highLength);
175 for (int i = 0; i < lowLength; ++i) {
176 newCoefficients[i] = coefficients[i].add(p.coefficients[i]);
177 }
178 System.arraycopy((coefficients.length < p.coefficients.length) ?
179 p.coefficients : coefficients,
180 lowLength,
181 newCoefficients, lowLength,
182 highLength - lowLength);
183
184 return new FieldPolynomialFunction<>(newCoefficients);
185 }
186
187
188
189
190
191
192
193 public FieldPolynomialFunction<T> subtract(final FieldPolynomialFunction<T> p) {
194
195 int lowLength = FastMath.min(coefficients.length, p.coefficients.length);
196 int highLength = FastMath.max(coefficients.length, p.coefficients.length);
197
198
199 T[] newCoefficients = MathArrays.buildArray(getField(), highLength);
200 for (int i = 0; i < lowLength; ++i) {
201 newCoefficients[i] = coefficients[i].subtract(p.coefficients[i]);
202 }
203 if (coefficients.length < p.coefficients.length) {
204 for (int i = lowLength; i < highLength; ++i) {
205 newCoefficients[i] = p.coefficients[i].negate();
206 }
207 } else {
208 System.arraycopy(coefficients, lowLength, newCoefficients, lowLength,
209 highLength - lowLength);
210 }
211
212 return new FieldPolynomialFunction<>(newCoefficients);
213 }
214
215
216
217
218
219
220 public FieldPolynomialFunction<T> negate() {
221 final T[] newCoefficients = MathArrays.buildArray(getField(), coefficients.length);
222 for (int i = 0; i < coefficients.length; ++i) {
223 newCoefficients[i] = coefficients[i].negate();
224 }
225 return new FieldPolynomialFunction<>(newCoefficients);
226 }
227
228
229
230
231
232
233
234 public FieldPolynomialFunction<T> multiply(final FieldPolynomialFunction<T> p) {
235 final Field<T> field = getField();
236 final T[] newCoefficients = MathArrays.buildArray(field, coefficients.length + p.coefficients.length - 1);
237
238 for (int i = 0; i < newCoefficients.length; ++i) {
239 newCoefficients[i] = field.getZero();
240 for (int j = FastMath.max(0, i + 1 - p.coefficients.length);
241 j < FastMath.min(coefficients.length, i + 1);
242 ++j) {
243 newCoefficients[i] = newCoefficients[i].add(coefficients[j].multiply(p.coefficients[i-j]));
244 }
245 }
246
247 return new FieldPolynomialFunction<>(newCoefficients);
248 }
249
250
251
252
253
254
255
256
257
258
259 protected static <T extends CalculusFieldElement<T>> T[] differentiate(T[] coefficients)
260 throws MathIllegalArgumentException, NullArgumentException {
261 MathUtils.checkNotNull(coefficients);
262 int n = coefficients.length;
263 if (n == 0) {
264 throw new MathIllegalArgumentException(LocalizedCoreFormats.EMPTY_POLYNOMIALS_COEFFICIENTS_ARRAY);
265 }
266 final Field<T> field = coefficients[0].getField();
267 final T[] result = MathArrays.buildArray(field, FastMath.max(1, n - 1));
268 if (n == 1) {
269 result[0] = field.getZero();
270 } else {
271 for (int i = n - 1; i > 0; i--) {
272 result[i - 1] = coefficients[i].multiply(i);
273 }
274 }
275 return result;
276 }
277
278
279
280
281
282
283 public FieldPolynomialFunction<T> antiDerivative() {
284 final Field<T> field = getField();
285 final int d = degree();
286 final T[] anti = MathArrays.buildArray(field, d + 2);
287 anti[0] = field.getZero();
288 for (int i = 1; i <= d + 1; i++) {
289 anti[i] = coefficients[i - 1].multiply(1.0 / i);
290 }
291 return new FieldPolynomialFunction<>(anti);
292 }
293
294
295
296
297
298
299
300
301
302
303
304
305 public T integrate(final double lower, final double upper) {
306 final T zero = getField().getZero();
307 return integrate(zero.add(lower), zero.add(upper));
308 }
309
310
311
312
313
314
315
316
317
318
319
320
321 public T integrate(final T lower, final T upper) {
322 if (Double.isInfinite(lower.getReal()) || Double.isInfinite(upper.getReal())) {
323 throw new MathIllegalArgumentException(LocalizedCoreFormats.INFINITE_BOUND);
324 }
325 if (lower.getReal() > upper.getReal()) {
326 throw new MathIllegalArgumentException(LocalizedCoreFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND);
327 }
328 final FieldPolynomialFunction<T> anti = antiDerivative();
329 return anti.value(upper).subtract(anti.value(lower));
330 }
331
332
333
334
335
336
337 public FieldPolynomialFunction<T> polynomialDerivative() {
338 return new FieldPolynomialFunction<>(differentiate(coefficients));
339 }
340
341 }