001    /*
002     * $Id: ComplexAlgebraicRing.java 3592 2011-04-02 18:49:49Z kredel $
003     */
004    
005    package edu.jas.root;
006    
007    
008    import java.io.Reader;
009    import java.util.ArrayList;
010    import java.util.List;
011    import java.util.Random;
012    
013    import edu.jas.arith.Rational;
014    import edu.jas.arith.BigRational;
015    import edu.jas.arith.BigDecimal;
016    import edu.jas.poly.AlgebraicNumber;
017    import edu.jas.poly.AlgebraicNumberRing;
018    import edu.jas.poly.Complex;
019    import edu.jas.poly.ComplexRing;
020    import edu.jas.poly.GenPolynomial;
021    import edu.jas.structure.GcdRingElem;
022    import edu.jas.structure.Power;
023    import edu.jas.structure.RingFactory;
024    
025    
026    /**
027     * Complex algebraic number factory class based on AlgebraicNumberRing with RingElem
028     * interface. Objects of this class are immutable with the exception of the
029     * isolating intervals.
030     * @author Heinz Kredel
031     */
032    
033    public class ComplexAlgebraicRing<C extends GcdRingElem<C> & Rational>
034    /*extends AlgebraicNumberRing<C>*/
035    implements RingFactory<ComplexAlgebraicNumber<C>> {
036    
037    
038        /**
039         * Representing AlgebraicNumberRing.
040         */
041        public final AlgebraicNumberRing<Complex<C>> algebraic;
042    
043    
044        /**
045         * Isolating rectangle for a complex root. <b>Note: </b> interval may shrink
046         * eventually.
047         */
048        /*package*/Rectangle<C> root;
049    
050    
051        /**
052         * Epsilon of the isolating rectangle for a complex root.
053         */
054        protected C eps;
055    
056    
057        /**
058         * Precision of the isolating rectangle for a complex root.
059         */
060        public final int PRECISION = 9; //BigDecimal.DEFAULT_PRECISION;
061    
062    
063        /**
064         * Complex root computation engine.
065         */
066        public final ComplexRootsSturm<C> engine;
067    
068    
069        /**
070         * The constructor creates a ComplexAlgebraicNumber factory object from a
071         * GenPolynomial objects module.
072         * @param m module GenPolynomial&lt;C&gt;.
073         * @param root isolating rectangle for a complex root.
074         */
075        public ComplexAlgebraicRing(GenPolynomial<Complex<C>> m, Rectangle<C> root) {
076            algebraic = new AlgebraicNumberRing<Complex<C>>(m);
077            this.root = root;
078            engine = new ComplexRootsSturm<C>(m.ring.coFac);
079            if (m.ring.characteristic().signum() > 0) {
080                throw new IllegalArgumentException("characteristic not zero");
081            }
082            C e = m.ring.coFac.fromInteger(10L).getRe();
083            e = e.inverse();
084            e = Power.positivePower(e, PRECISION);
085            eps = e;
086        }
087    
088    
089        /**
090         * The constructor creates a ComplexAlgebraicNumber factory object from a
091         * GenPolynomial objects module.
092         * @param m module GenPolynomial&lt;C&gt;.
093         * @param root isolating rectangle for a complex root.
094         * @param isField indicator if m is prime.
095         */
096        public ComplexAlgebraicRing(GenPolynomial<Complex<C>> m, Rectangle<C> root, boolean isField) {
097            algebraic = new AlgebraicNumberRing<Complex<C>>(m, isField);
098            this.root = root;
099            engine = new ComplexRootsSturm<C>(m.ring.coFac);
100            if (m.ring.characteristic().signum() > 0) {
101                throw new IllegalArgumentException("characteristic not zero");
102            }
103            C e = m.ring.coFac.fromInteger(10L).getRe();
104            e = e.inverse();
105            e = Power.positivePower(e, PRECISION);
106            eps = e;
107        }
108    
109    
110        /*
111         * Get the module part.
112         * @return modul. public GenPolynomial<C> getModul() { return
113         *         algebraic.modul; }
114         */
115    
116    
117        /**
118         * Set a refined rectangle for the complex root. <b>Note: </b> rectangle may
119         * shrink eventually.
120         * @param v rectangle.
121         */
122        public synchronized void setRoot(Rectangle<C> v) {
123            // assert v is contained in root
124            this.root = v;
125        }
126    
127    
128        /**
129         * Get rectangle for the complex root.
130         * @return v rectangle.
131         */
132        public synchronized Rectangle<C> getRoot() {
133            return this.root;
134        }
135    
136    
137        /**
138         * Get epsilon. 
139         * @return epsilon.
140         */
141        public synchronized C getEps() {
142            return this.eps;
143        }
144    
145    
146        /**
147         * Set a new epsilon. 
148         * @param e epsilon.
149         */
150        public synchronized void setEps(C e) {
151            this.eps = e;
152        }
153    
154    
155        /**
156         * Set a new epsilon. 
157         * @param e epsilon.
158         */
159        public synchronized void setEps(BigRational e) {
160            this.eps = algebraic.ring.coFac.parse(e.toString()).getRe();
161        }
162    
163    
164        /**
165         * Is this structure finite or infinite.
166         * @return true if this structure is finite, else false.
167         * @see edu.jas.structure.ElemFactory#isFinite()
168         */
169        public boolean isFinite() {
170            return algebraic.isFinite();
171        }
172    
173    
174        /**
175         * Copy ComplexAlgebraicNumber element c.
176         * @param c
177         * @return a copy of c.
178         */
179        public ComplexAlgebraicNumber<C> copy(ComplexAlgebraicNumber<C> c) {
180            return new ComplexAlgebraicNumber<C>(this, c.number);
181        }
182    
183    
184        /**
185         * Get the zero element.
186         * @return 0 as ComplexAlgebraicNumber.
187         */
188        public ComplexAlgebraicNumber<C> getZERO() {
189            return new ComplexAlgebraicNumber<C>(this, algebraic.getZERO());
190        }
191    
192    
193        /**
194         * Get the one element.
195         * @return 1 as ComplexAlgebraicNumber.
196         */
197        public ComplexAlgebraicNumber<C> getONE() {
198            return new ComplexAlgebraicNumber<C>(this, algebraic.getONE());
199        }
200    
201    
202        /**
203         * Get the i element.
204         * @return i as ComplexAlgebraicNumber.
205         */
206        public ComplexAlgebraicNumber<C> getIMAG() {
207            ComplexRing<C> cr = (ComplexRing<C>) algebraic.ring.coFac;
208            Complex<C> I = cr.getIMAG(); 
209            return new ComplexAlgebraicNumber<C>(this, algebraic.getZERO().sum(I));
210        }
211    
212    
213        /**
214         * Get the generating element.
215         * @return alpha as ComplexAlgebraicNumber.
216         */
217        public ComplexAlgebraicNumber<C> getGenerator() {
218            return new ComplexAlgebraicNumber<C>(this, algebraic.getGenerator());
219        }
220    
221    
222        /**
223         * Get a list of the generating elements.
224         * @return list of generators for the algebraic structure.
225         * @see edu.jas.structure.ElemFactory#generators()
226         */
227        public List<ComplexAlgebraicNumber<C>> generators() {
228            List<AlgebraicNumber<Complex<C>>> agens = algebraic.generators();
229            List<ComplexAlgebraicNumber<C>> gens = new ArrayList<ComplexAlgebraicNumber<C>>(agens.size());
230            for (AlgebraicNumber<Complex<C>> a : agens) {
231                gens.add(getZERO().sum(a.getVal()));
232            }
233            return gens;
234        }
235    
236    
237        /**
238         * Query if this ring is commutative.
239         * @return true if this ring is commutative, else false.
240         */
241        public boolean isCommutative() {
242            return algebraic.isCommutative();
243        }
244    
245    
246        /**
247         * Query if this ring is associative.
248         * @return true if this ring is associative, else false.
249         */
250        public boolean isAssociative() {
251            return algebraic.isAssociative();
252        }
253    
254    
255        /**
256         * Query if this ring is a field.
257         * @return true if algebraic is prime, else false.
258         */
259        public boolean isField() {
260            return algebraic.isField();
261        }
262    
263    
264        /**
265         * Characteristic of this ring.
266         * @return characteristic of this ring.
267         */
268        public java.math.BigInteger characteristic() {
269            return algebraic.characteristic();
270        }
271    
272    
273        /**
274         * Get a ComplexAlgebraicNumber element from a BigInteger value.
275         * @param a BigInteger.
276         * @return a ComplexAlgebraicNumber.
277         */
278        public ComplexAlgebraicNumber<C> fromInteger(java.math.BigInteger a) {
279            return new ComplexAlgebraicNumber<C>(this, algebraic.fromInteger(a));
280        }
281    
282    
283        /**
284         * Get a ComplexAlgebraicNumber element from a long value.
285         * @param a long.
286         * @return a ComplexAlgebraicNumber.
287         */
288        public ComplexAlgebraicNumber<C> fromInteger(long a) {
289            return new ComplexAlgebraicNumber<C>(this, algebraic.fromInteger(a));
290        }
291    
292    
293        /**
294         * Get the String representation as RingFactory.
295         * @see java.lang.Object#toString()
296         */
297        @Override
298        public String toString() {
299            return "ComplexAlgebraicRing[ " + algebraic.modul.toString() + " in " + root + " | isField="
300                    + algebraic.isField() + " :: " + algebraic.ring.toString() + " ]";
301        }
302    
303    
304        /**
305         * Get a scripting compatible string representation.
306         * @return script compatible representation for this ElemFactory.
307         * @see edu.jas.structure.ElemFactory#toScript()
308         */
309        //JAVA6only: @Override
310        public String toScript() {
311            // Python case
312            return "ComplexN( " + algebraic.modul.toScript() + ", " + root.toScript()
313            //+ ", " + algebraic.isField() 
314                    //+ ", " + algebraic.ring.toScript() 
315                    + " )";
316        }
317    
318    
319        /**
320         * Comparison with any other object.
321         * @see java.lang.Object#equals(java.lang.Object)
322         */
323        @Override
324        @SuppressWarnings("unchecked")
325        // not jet working
326        public boolean equals(Object b) {
327            if (!(b instanceof ComplexAlgebraicRing)) {
328                return false;
329            }
330            ComplexAlgebraicRing<C> a = null;
331            try {
332                a = (ComplexAlgebraicRing<C>) b;
333            } catch (ClassCastException e) {
334            }
335            if (a == null) {
336                return false;
337            }
338            return algebraic.equals(a.algebraic) && root.equals(a.root);
339        }
340    
341    
342        /**
343         * Hash code for this ComplexAlgebraicNumber.
344         * @see java.lang.Object#hashCode()
345         */
346        @Override
347        public int hashCode() {
348            return 37 * algebraic.hashCode() + root.hashCode();
349        }
350    
351    
352        /**
353         * ComplexAlgebraicNumber random.
354         * @param n such that 0 &le; v &le; (2<sup>n</sup>-1).
355         * @return a random integer mod modul.
356         */
357        public ComplexAlgebraicNumber<C> random(int n) {
358            return new ComplexAlgebraicNumber<C>(this, algebraic.random(n));
359        }
360    
361    
362        /**
363         * ComplexAlgebraicNumber random.
364         * @param n such that 0 &le; v &le; (2<sup>n</sup>-1).
365         * @param rnd is a source for random bits.
366         * @return a random integer mod modul.
367         */
368        public ComplexAlgebraicNumber<C> random(int n, Random rnd) {
369            return new ComplexAlgebraicNumber<C>(this, algebraic.random(n, rnd));
370        }
371    
372    
373        /**
374         * Parse ComplexAlgebraicNumber from String.
375         * @param s String.
376         * @return ComplexAlgebraicNumber from s.
377         */
378        public ComplexAlgebraicNumber<C> parse(String s) {
379            return new ComplexAlgebraicNumber<C>(this, algebraic.parse(s));
380        }
381    
382    
383        /**
384         * Parse ComplexAlgebraicNumber from Reader.
385         * @param r Reader.
386         * @return next ComplexAlgebraicNumber from r.
387         */
388        public ComplexAlgebraicNumber<C> parse(Reader r) {
389            return new ComplexAlgebraicNumber<C>(this, algebraic.parse(r));
390        }
391    
392    }