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