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