KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > JSci > maths > polynomials > RealPolynomial


1 package JSci.maths.polynomials;
2
3 import JSci.GlobalSettings;
4 import JSci.maths.MathDouble;
5 import JSci.maths.analysis.RealFunction;
6 import JSci.maths.fields.*;
7 import JSci.maths.fields.Field;
8 import JSci.maths.groups.AbelianGroup;
9
10
11 /** A Polynomial as a <code>Ring.Member</code> over a <i>real</i> <code>Field</code>
12  * @author b.dietrich
13  * @author Mark Hale
14  */

15 public class RealPolynomial extends RealFunction implements Polynomial {
16     /** Coefficients in ascending degree order */
17     private double[] _coeff;
18
19     /** Creates a new instance of RealPolynomial */
20     public RealPolynomial( double[] coeff ) {
21         if ( coeff == null ) {
22             throw new NullPointerException JavaDoc("Coefficients cannot be null");
23         }
24         _coeff = normalise(coeff);
25     }
26         /**
27         * Normalises the coefficient array.
28         * Trims off any leading (high degree) zero terms.
29         */

30         private static double[] normalise(double[] c) {
31                 int i = c.length-1;
32                 while(i >= 0 && Math.abs(c[i]) <= GlobalSettings.ZERO_TOL)
33                         i--;
34                 if(i < 0) {
35                         return new double[] {0.0};
36                 } else if(i < c.length-1) {
37                         double[] arr = new double[i+1];
38                         System.arraycopy(c, 0, arr, 0, arr.length);
39                         return arr;
40                 } else {
41                         return c;
42                 }
43         }
44
45     /**
46      * Creates a new RealPolynomial object.
47      *
48      * @param f
49      */

50     public RealPolynomial( Field.Member[] f ) {
51         if ( f == null ) {
52             throw new NullPointerException JavaDoc("Coefficients cannot be null");
53         }
54         _coeff = normalise(toDoubleArray(f));
55     }
56
57         private static double[] toDoubleArray(Field.Member[] f) {
58                 double[] arr = new double[f.length];
59                 for(int i=0; i<arr.length; i++) {
60                         if(f[i] instanceof MathDouble)
61                                 arr[i] = ((MathDouble)f[i]).value();
62                         else
63                                 throw new IllegalArgumentException JavaDoc("Different fields. Argument was " + f[i].getClass());
64                 }
65                 return arr;
66         }
67
68     /** Get the coefficient of degree k, i.e. <I>a_k</I> if
69      * <I>P(x)</I> := sum_{k=0}^n <I>a_k x^k</I>
70      * @param k degree
71      * @return coefficient as described above
72      */

73     public Field.Member getCoefficient( int k ) {
74         return new MathDouble( getCoefficientAsDouble( k ) );
75     }
76
77     /** Get the coefficient of degree k, i.e. <I>a_k</I> if
78      * <I>P(x)</I> := sum_{k=0}^n <I>a_k x^k</I> as a real number
79      * @param k degree
80      * @return coefficient as described above
81      */

82     public double getCoefficientAsDouble( int k ) {
83         if ( k >= _coeff.length ) {
84             return 0.0;
85         } else {
86             return _coeff[k];
87         }
88     }
89
90     /** Get the coefficients as an array
91       * @return the coefficients as an array
92       */

93     public Field.Member[] getCoefficients() {
94         return RealPolynomialRing.toMathDouble( getCoefficientsAsDoubles() );
95     }
96
97     /** Get the coefficients as an array of doubles
98      * @return the coefficients as an array
99      */

100     public double[] getCoefficientsAsDoubles() {
101         return _coeff;
102     }
103
104         /**
105         * Evaluates this polynomial.
106         */

107         public double map(double x) {
108                 return PolynomialMath.evalPolynomial(this, x);
109         }
110
111     /** The degree
112      * @return the degree
113      */

114     public int degree() {
115         return _coeff.length-1;
116     }
117
118     public Object JavaDoc getSet() {
119         return RealPolynomialRing.getInstance();
120     }
121
122     /**
123      * Returns true if this polynomial is equal to zero.
124      * All coefficients are tested for |a_k| < GlobalSettings.ZERO_TOL.
125      * @return true if all coefficients < GlobalSettings.ZERO_TOL
126      */

127     public boolean isZero() {
128         for ( int k = 0; k < _coeff.length; k++ ) {
129             if ( Math.abs( _coeff[k] ) > GlobalSettings.ZERO_TOL) {
130                 return false;
131             }
132         }
133
134         return true;
135     }
136
137     /**
138      * Returns true if this polynomial is equal to one.
139      * It is tested, whether |a_0 - 1| <= GlobalSettings.ZERO_TOL and the remaining
140      * coefficients are |a_k| < GlobalSettings.ZERO_TOL.
141      * @return true if this is equal to one.
142      */

143     public boolean isOne() {
144         if(Math.abs( _coeff[0] - 1.0 ) > GlobalSettings.ZERO_TOL)
145                 return false;
146
147         for ( int k = 1; k < _coeff.length; k++ ) {
148             if ( Math.abs( _coeff[k] ) > GlobalSettings.ZERO_TOL ) {
149                 return false;
150             }
151         }
152
153         return true;
154     }
155
156     /** The group composition law. Returns a new polynom with grade = max( this.grade, g.grade)
157      * @param g a group member
158      *
159      */

160     public RealFunction add( RealFunction g ) {
161         if ( g instanceof RealPolynomial ) {
162             RealPolynomial p = (RealPolynomial) g;
163             int maxgrade = PolynomialMath.maxDegree( this, p );
164             double[] c = new double[maxgrade+1];
165             for ( int k = 0; k < c.length; k++ ) {
166                 c[k] = getCoefficientAsDouble( k ) + p.getCoefficientAsDouble( k );
167             }
168             return new RealPolynomial( c );
169         } else {
170                 return super.add(g);
171         }
172     }
173
174     /**
175      * Differentiate the real polynomial. Only useful iff the polynomial is built over
176      * a Banach space and an appropriate multiplication law is provided.
177      *
178      * @return a new polynomial with degree = max(this.degree-1 , 0)
179      */

180     public RealFunction differentiate() {
181         if ( degree() == 0 ) {
182             return (RealPolynomial) RealPolynomialRing.getInstance().zero();
183         } else {
184             double[] dn = new double[degree()];
185             for ( int k = 0; k < dn.length; k++ ) {
186                 dn[k] = getCoefficientAsDouble( k+1 ) * (k+1);
187             }
188
189             return new RealPolynomial( dn );
190         }
191     }
192
193     /** return a new real Polynomial with coefficients divided by <I>f</I>
194      * @param f divisor
195      * @return new Polynomial with coefficients /= <I>f</I>
196      */

197     public Polynomial scalarDivide( Field.Member f ) {
198         if ( f instanceof Number JavaDoc ) {
199             double a = ( (Number JavaDoc) f ).doubleValue();
200
201             return scalarDivide( a );
202         } else {
203             throw new IllegalArgumentException JavaDoc("Member class not recognised by this method.");
204         }
205     }
206
207     /** return a new real Polynomial with coefficients divided by <I>a</I>
208      * @param a divisor
209      * @return new Polynomial with coefficients /= <I>a</I>
210      */

211     public RealPolynomial scalarDivide( double a ) {
212         double[] c = new double[_coeff.length];
213         for ( int k = 0; k < c.length; k++ ) {
214             c[k] = _coeff[k] / a;
215         }
216
217         return new RealPolynomial( c );
218     }
219
220     /**
221      * Returns true if this polynomial is equal to another.
222      * @param o the other polynomial
223      *
224      * @return true if so
225      */

226     public boolean equals( Object JavaDoc o ) {
227         if ( o == this ) {
228             return true;
229         } else if ( o instanceof RealPolynomial ) {
230             RealPolynomial p = (RealPolynomial) o;
231
232             return ( (RealPolynomial) this.subtract( p ) ).isZero();
233         }
234
235         return false;
236     }
237
238     /**
239      * Some kind of hashcode... (Since I have an equals)
240      * @return a hashcode
241      */

242     public int hashCode() {
243         int res = 0;
244         for ( int k = 0; k < _coeff.length; k++ ) {
245             res += (int) ( _coeff[k] * 10.0 );
246         }
247
248         return res;
249     }
250
251     /**
252      * "inverse" operation for differentiate
253      * @return the integrated polynomial
254      */

255     public RealPolynomial integrate() {
256         double[] dn = new double[_coeff.length+1];
257         for ( int k = 1; k < dn.length; k++ ) {
258             dn[k] = getCoefficientAsDouble( k-1 ) / k;
259         }
260
261         return new RealPolynomial( dn );
262     }
263
264     /**
265      * Returns the multiplication of this polynomial by a scalar
266      * @param f
267      */

268     public Polynomial scalarMultiply( Field.Member f ) {
269         if ( f instanceof Number JavaDoc ) {
270             double a = ( (Number JavaDoc) f ).doubleValue();
271             return scalarMultiply( a );
272         } else {
273             throw new IllegalArgumentException JavaDoc("Member class not recognised by this method.");
274         }
275     }
276
277     /**
278      * Returns the multiplication of this polynomial by a scalar
279     * @param a factor
280     * @return new Polynomial with coefficients *= <I>a</I>
281     */

282     public RealPolynomial scalarMultiply( double a ) {
283         double[] c = new double[_coeff.length];
284         for ( int k = 0; k < c.length; k++ ) {
285             c[k] = _coeff[k] * a;
286         }
287
288         return new RealPolynomial( c );
289     }
290
291     /**
292      * The multiplication law. Multiplies this Polynomial with another
293      * @param r a polynomial
294      * @return a new Polynomial with grade = max( this.grade, r.grade) + min( this.grade, r.grade)
295      */

296     public RealFunction multiply( RealFunction r ) {
297         if ( r instanceof RealPolynomial ) {
298             RealPolynomial p = (RealPolynomial) r;
299             int maxgrade = PolynomialMath.maxDegree( this, p );
300             int mingrade = PolynomialMath.minDegree( this, p );
301             int destgrade = maxgrade + mingrade;
302             double[] n = new double[destgrade+1];
303             for ( int k = 0; k < _coeff.length; k++ ) {
304                 for ( int j = 0; j < p._coeff.length; j++ ) {
305                     n[k + j] += ( _coeff[k] * p._coeff[j] );
306                 }
307             }
308
309             return new RealPolynomial( n );
310         } else {
311             throw new IllegalArgumentException JavaDoc("Member class not recognised by this method.");
312         }
313     }
314
315     /** Returns the inverse member. (That is mult(-1))
316      * @return inverse
317      */

318     public AbelianGroup.Member negate() {
319         double[] c = new double[_coeff.length];
320         for ( int k = 0; k < c.length; k++ ) {
321             c[k] = -_coeff[k];
322         }
323
324         return new RealPolynomial( c );
325     }
326
327     /** The group composition law with inverse.
328      * @param g a group member
329      *
330      */

331     public RealFunction subtract( RealFunction g ) {
332         if ( g instanceof RealPolynomial ) {
333             RealPolynomial p = (RealPolynomial) g;
334             int maxgrade = PolynomialMath.maxDegree( this, p );
335             double[] c = new double[maxgrade+1];
336             for ( int k = 0; k < c.length; k++ ) {
337                 c[k] = getCoefficientAsDouble( k ) - p.getCoefficientAsDouble( k );
338             }
339             return new RealPolynomial( c );
340         } else {
341                 return super.subtract(g);
342         }
343     }
344
345     /**
346      * String representation <I>P(x) = a_k x^k +...</I>
347      * @return String
348      */

349     public String JavaDoc toString() {
350         StringBuffer JavaDoc sb = new StringBuffer JavaDoc( "P(x) = " );
351         if ( _coeff[degree()] < 0.0 ) {
352             sb.append( "-" );
353         } else {
354             sb.append( " " );
355         }
356         for ( int k = degree(); k > 0; k-- ) {
357             sb.append( Math.abs( _coeff[k] ) ).append( "x^" ).append( k )
358               .append( ( _coeff[k-1] >= 0.0 ) ? " + " : " - " );
359         }
360         sb.append( Math.abs(_coeff[0]) );
361
362         return sb.toString();
363     }
364 }
365
366
Popular Tags