001/*
002 * $Id: ComplexRing.java 3882 2012-02-05 17:53:12Z kredel $
003 */
004
005package edu.jas.poly;
006
007
008import java.io.Reader;
009import java.math.BigInteger;
010import java.util.ArrayList;
011import java.util.List;
012import java.util.Random;
013
014import org.apache.log4j.Logger;
015
016import edu.jas.kern.StringUtil;
017import edu.jas.structure.GcdRingElem;
018import edu.jas.structure.RingElem;
019import edu.jas.structure.RingFactory;
020
021
022/**
023 * Generic Complex ring factory implementing the RingFactory interface. Objects
024 * of this class are immutable.
025 * @param <C> base type.
026 * @author Heinz Kredel
027 */
028public class ComplexRing<C extends RingElem<C>> implements RingFactory<Complex<C>> {
029
030
031    private final static Random random = new Random();
032
033
034    @SuppressWarnings("unused")
035    private static final Logger logger = Logger.getLogger(ComplexRing.class);
036
037
038    /**
039     * Complex class elements factory data structure.
040     */
041    public final RingFactory<C> ring;
042
043
044    /**
045     * The constructor creates a ComplexRing object.
046     * @param ring factory for Complex real and imaginary parts.
047     */
048    public ComplexRing(RingFactory<C> ring) {
049        this.ring = ring;
050    }
051
052
053    /**
054     * Get a list of the generating elements.
055     * @return list of generators for the algebraic structure.
056     * @see edu.jas.structure.ElemFactory#generators()
057     */
058    public List<Complex<C>> generators() {
059        List<C> gens = ring.generators();
060        List<Complex<C>> g = new ArrayList<Complex<C>>(gens.size() + 1);
061        for (C x : gens) {
062            Complex<C> cx = new Complex<C>(this, x);
063            g.add(cx);
064        }
065        g.add(getIMAG());
066        return g;
067    }
068
069
070    /**
071     * Corresponding algebraic number ring.
072     * @return algebraic number ring.
073     * not jet possible.
074     */
075    public AlgebraicNumberRing<C> algebraicRing() {
076        GenPolynomialRing<C> pfac 
077           = new GenPolynomialRing<C>(ring, 1, new TermOrder(TermOrder.INVLEX), new String[] { "I" });
078        GenPolynomial<C> I = pfac.univariate(0, 2L).sum(pfac.getONE());
079        AlgebraicNumberRing<C> afac = new AlgebraicNumberRing<C>(I, ring.isField()); // must indicate field
080        return afac;
081    }
082
083
084    /**
085     * Is this structure finite or infinite.
086     * @return true if this structure is finite, else false.
087     * @see edu.jas.structure.ElemFactory#isFinite()
088     */
089    public boolean isFinite() {
090        return ring.isFinite();
091    }
092
093
094    /**
095     * Copy Complex element c.
096     * @param c Complex&lt;C&gt;.
097     * @return a copy of c.
098     */
099    public Complex<C> copy(Complex<C> c) {
100        return new Complex<C>(this, c.re, c.im);
101    }
102
103
104    /**
105     * Get the zero element.
106     * @return 0 as Complex&lt;C&gt;.
107     */
108    public Complex<C> getZERO() {
109        return new Complex<C>(this);
110    }
111
112
113    /**
114     * Get the one element.
115     * @return 1 as Complex&lt;C&gt;.
116     */
117    public Complex<C> getONE() {
118        return new Complex<C>(this, ring.getONE());
119    }
120
121
122    /**
123     * Get the i element.
124     * @return i as Complex&lt;C&gt;.
125     */
126    public Complex<C> getIMAG() {
127        return new Complex<C>(this, ring.getZERO(), ring.getONE());
128    }
129
130
131    /**
132     * Query if this ring is commutative.
133     * @return true.
134     */
135    public boolean isCommutative() {
136        return ring.isCommutative();
137    }
138
139
140    /**
141     * Query if this ring is associative.
142     * @return true.
143     */
144    public boolean isAssociative() {
145        return ring.isAssociative();
146    }
147
148
149    /**
150     * Query if this ring is a field.
151     * @return true.
152     */
153    public boolean isField() {
154        return ring.isField();
155    }
156
157
158    /**
159     * Characteristic of this ring.
160     * @return characteristic of this ring.
161     */
162    public java.math.BigInteger characteristic() {
163        return ring.characteristic();
164    }
165
166
167    /**
168     * Get a Complex element from a BigInteger.
169     * @param a BigInteger.
170     * @return a Complex&lt;C&gt;.
171     */
172    public Complex<C> fromInteger(BigInteger a) {
173        return new Complex<C>(this, ring.fromInteger(a));
174    }
175
176
177    /**
178     * Get a Complex element from a long.
179     * @param a long.
180     * @return a Complex&lt;C&gt;.
181     */
182    public Complex<C> fromInteger(long a) {
183        return new Complex<C>(this, ring.fromInteger(a));
184    }
185
186
187    /**
188     * Get the String representation.
189     */
190    @Override
191    public String toString() {
192        StringBuffer sb = new StringBuffer();
193        sb.append("Complex[");
194        if (ring instanceof RingElem) {
195            RingElem ri = (RingElem) ring;
196            sb.append(ri.toScriptFactory());
197        } else {
198            sb.append(ring.toString());
199        }
200        sb.append("]");
201        return sb.toString();
202    }
203
204
205    /**
206     * Get a scripting compatible string representation.
207     * @return script compatible representation for this Element.
208     * @see edu.jas.structure.Element#toScript()
209     */
210    //JAVA6only: @Override
211    public String toScript() {
212        // Python case
213        StringBuffer s = new StringBuffer();
214        s.append("CR(");
215        if (ring instanceof RingElem) {
216            RingElem ri = (RingElem) ring;
217            s.append(ri.toScriptFactory());
218        } else {
219            s.append(ring.toScript());
220        }
221        s.append(")");
222        return s.toString();
223    }
224
225
226    /**
227     * Comparison with any other object.
228     * @see java.lang.Object#equals(java.lang.Object)
229     */
230    @Override
231    @SuppressWarnings("unchecked")
232    public boolean equals(Object b) {
233        if (!(b instanceof ComplexRing)) {
234            return false;
235        }
236        ComplexRing<C> a = null;
237        try {
238            a = (ComplexRing<C>) b;
239        } catch (ClassCastException e) {
240        }
241        if (a == null) {
242            return false;
243        }
244        if (!ring.equals(a.ring)) {
245            return false;
246        }
247        return true;
248    }
249
250
251    /**
252     * Hash code for this ComplexRing&lt;C&gt;.
253     * @see java.lang.Object#hashCode()
254     */
255    @Override
256    public int hashCode() {
257        return ring.hashCode();
258    }
259
260
261    /**
262     * Complex number random. Random base numbers A and B are generated using
263     * random(n). Then R is the complex number with real part A and imaginary
264     * part B.
265     * @param n such that 0 &le; A, B &le; (2<sup>n</sup>-1).
266     * @return R.
267     */
268    public Complex<C> random(int n) {
269        return random(n, random);
270        //         C r = ring.random( n ).abs();
271        //         C i = ring.random( n ).abs();
272        //         return new Complex<C>(this, r, i ); 
273    }
274
275
276    /**
277     * Complex number random. Random base numbers A and B are generated using
278     * random(n). Then R is the complex number with real part A and imaginary
279     * part B.
280     * @param n such that 0 &le; A, B &le; (2<sup>n</sup>-1).
281     * @param rnd is a source for random bits.
282     * @return R.
283     */
284    public Complex<C> random(int n, Random rnd) {
285        C r = ring.random(n, rnd);
286        C i = ring.random(n, rnd);
287        return new Complex<C>(this, r, i);
288    }
289
290
291    /**
292     * Parse complex number from string.
293     * @param s String.
294     * @return Complex<C> from s.
295     */
296    public Complex<C> parse(String s) {
297        return new Complex<C>(this, s);
298    }
299
300
301    /**
302     * Parse complex number from Reader.
303     * @param r Reader.
304     * @return next Complex<C> from r.
305     */
306    public Complex<C> parse(Reader r) {
307        return parse(StringUtil.nextString(r));
308    }
309
310}