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<C>.
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<C>.
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<C>.
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<C>.
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<C>.
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<C>.
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<C>.
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 ≤ A, B ≤ (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 ≤ A, B ≤ (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 }