001/*
002 * $Id: ComplexAlgebraicRing.java 3987 2012-07-14 11:58:20Z kredel $
003 */
004
005package edu.jas.root;
006
007
008import java.io.Reader;
009import java.util.ArrayList;
010import java.util.List;
011import java.util.Random;
012
013import edu.jas.arith.Rational;
014import edu.jas.arith.BigRational;
015import edu.jas.arith.BigDecimal;
016import edu.jas.poly.AlgebraicNumber;
017import edu.jas.poly.AlgebraicNumberRing;
018import edu.jas.poly.Complex;
019import edu.jas.poly.ComplexRing;
020import edu.jas.poly.GenPolynomial;
021import edu.jas.structure.GcdRingElem;
022import edu.jas.structure.Power;
023import 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
033public class ComplexAlgebraicRing<C extends GcdRingElem<C> & Rational>
034/*extends AlgebraicNumberRing<C>*/
035implements 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 static 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}