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 &le; v &le; (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 &le; v &le; (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    }