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