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