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