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