001/*
002 * $Id: ComplexRing.java 5872 2018-07-20 16:01:46Z 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.logging.log4j.Logger;
015import org.apache.logging.log4j.LogManager; 
016
017import edu.jas.kern.StringUtil;
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 = LogManager.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. not jet possible.
073     */
074    public AlgebraicNumberRing<C> algebraicRing() {
075        GenPolynomialRing<C> pfac = new GenPolynomialRing<C>(ring, 1, new TermOrder(TermOrder.INVLEX),
076                        new String[] { "I" });
077        GenPolynomial<C> I = pfac.univariate(0, 2L).sum(pfac.getONE());
078        AlgebraicNumberRing<C> afac = new AlgebraicNumberRing<C>(I, ring.isField()); // must indicate field
079        return afac;
080    }
081
082
083    /**
084     * Is this structure finite or infinite.
085     * @return true if this structure is finite, else false.
086     * @see edu.jas.structure.ElemFactory#isFinite()
087     */
088    public boolean isFinite() {
089        return ring.isFinite();
090    }
091
092
093    /**
094     * Copy Complex element c.
095     * @param c Complex&lt;C&gt;.
096     * @return a copy of c.
097     */
098    public Complex<C> copy(Complex<C> c) {
099        return new Complex<C>(this, c.re, c.im);
100    }
101
102
103    /**
104     * Get the zero element.
105     * @return 0 as Complex&lt;C&gt;.
106     */
107    public Complex<C> getZERO() {
108        return new Complex<C>(this);
109    }
110
111
112    /**
113     * Get the one element.
114     * @return 1 as Complex&lt;C&gt;.
115     */
116    public Complex<C> getONE() {
117        return new Complex<C>(this, ring.getONE());
118    }
119
120
121    /**
122     * Get the i element.
123     * @return i as Complex&lt;C&gt;.
124     */
125    public Complex<C> getIMAG() {
126        return new Complex<C>(this, ring.getZERO(), ring.getONE());
127    }
128
129
130    /**
131     * Query if this ring is commutative.
132     * @return true.
133     */
134    public boolean isCommutative() {
135        return ring.isCommutative();
136    }
137
138
139    /**
140     * Query if this ring is associative.
141     * @return true.
142     */
143    public boolean isAssociative() {
144        return ring.isAssociative();
145    }
146
147
148    /**
149     * Query if this ring is a field.
150     * @return true.
151     */
152    public boolean isField() {
153        return ring.isField();
154    }
155
156
157    /**
158     * Characteristic of this ring.
159     * @return characteristic of this ring.
160     */
161    public java.math.BigInteger characteristic() {
162        return ring.characteristic();
163    }
164
165
166    /**
167     * Get a Complex element from a BigInteger.
168     * @param a BigInteger.
169     * @return a Complex&lt;C&gt;.
170     */
171    public Complex<C> fromInteger(BigInteger a) {
172        return new Complex<C>(this, ring.fromInteger(a));
173    }
174
175
176    /**
177     * Get a Complex element from a long.
178     * @param a long.
179     * @return a Complex&lt;C&gt;.
180     */
181    public Complex<C> fromInteger(long a) {
182        return new Complex<C>(this, ring.fromInteger(a));
183    }
184
185
186    /**
187     * Get the String representation.
188     */
189    @Override
190    public String toString() {
191        StringBuffer sb = new StringBuffer();
192        sb.append("Complex[");
193        if (ring instanceof RingElem) {
194            RingElem ri = (RingElem) ring;
195            sb.append(ri.toScriptFactory());
196        } else {
197            sb.append(ring.toString());
198        }
199        sb.append("]");
200        return sb.toString();
201    }
202
203
204    /**
205     * Get a scripting compatible string representation.
206     * @return script compatible representation for this Element.
207     * @see edu.jas.structure.Element#toScript()
208     */
209    @Override
210    public String toScript() {
211        // Python case
212        StringBuffer s = new StringBuffer();
213        s.append("CR(");
214        if (ring instanceof RingElem) {
215            RingElem ri = (RingElem) ring;
216            s.append(ri.toScriptFactory());
217        } else {
218            s.append(ring.toScript());
219        }
220        s.append(")");
221        return s.toString();
222    }
223
224
225    /**
226     * Comparison with any other object.
227     * @see java.lang.Object#equals(java.lang.Object)
228     */
229    @Override
230    @SuppressWarnings("unchecked")
231    public boolean equals(Object b) {
232        if (b == null) {
233            return false;
234        }
235        if (!(b instanceof ComplexRing)) {
236            return false;
237        }
238        ComplexRing<C> a = (ComplexRing<C>) b;
239        if (!ring.equals(a.ring)) {
240            return false;
241        }
242        return true;
243    }
244
245
246    /**
247     * Hash code for this ComplexRing&lt;C&gt;.
248     * @see java.lang.Object#hashCode()
249     */
250    @Override
251    public int hashCode() {
252        return ring.hashCode();
253    }
254
255
256    /**
257     * Complex number random. Random base numbers A and B are generated using
258     * random(n). Then R is the complex number with real part A and imaginary
259     * part B.
260     * @param n such that 0 &le; A, B &le; (2<sup>n</sup>-1).
261     * @return R.
262     */
263    public Complex<C> random(int n) {
264        return random(n, random);
265        //         C r = ring.random( n ).abs();
266        //         C i = ring.random( n ).abs();
267        //         return new Complex<C>(this, r, i ); 
268    }
269
270
271    /**
272     * Complex number random. Random base numbers A and B are generated using
273     * random(n). Then R is the complex number with real part A and imaginary
274     * part B.
275     * @param n such that 0 &le; A, B &le; (2<sup>n</sup>-1).
276     * @param rnd is a source for random bits.
277     * @return R.
278     */
279    public Complex<C> random(int n, Random rnd) {
280        C r = ring.random(n, rnd);
281        C i = ring.random(n, rnd);
282        return new Complex<C>(this, r, i);
283    }
284
285
286    /**
287     * Parse complex number from string.
288     * @param s String.
289     * @return Complex<C> from s.
290     */
291    public Complex<C> parse(String s) {
292        return new Complex<C>(this, s);
293    }
294
295
296    /**
297     * Parse complex number from Reader.
298     * @param r Reader.
299     * @return next Complex<C> from r.
300     */
301    public Complex<C> parse(Reader r) {
302        return parse(StringUtil.nextString(r));
303    }
304
305}