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