001    /*
002     * $Id: Interval.java 3662 2011-06-11 13:41:28Z kredel $
003     */
004    
005    package edu.jas.root;
006    
007    
008    import edu.jas.arith.BigDecimal;
009    import edu.jas.arith.BigRational;
010    import edu.jas.arith.Rational;
011    import edu.jas.structure.RingElem;
012    import edu.jas.structure.RingFactory;
013    
014    
015    /**
016     * Interval. For example isolating interval for real roots.
017     * @param <C> coefficient type.
018     * @author Heinz Kredel
019     */
020    public class Interval<C extends RingElem<C> & Rational > {
021    
022    
023        /**
024         * left interval border.
025         */
026        public final C left;
027    
028    
029        /**
030         * right interval border.
031         */
032        public final C right;
033    
034    
035        /**
036         * Constructor.
037         * @param left interval border.
038         * @param right interval border.
039         */
040        public Interval(C left, C right) {
041            this.left = left;
042            this.right = right;
043        }
044    
045    
046        /**
047         * Constructor.
048         * @param mid left and right interval border.
049         */
050        public Interval(C mid) {
051            this(mid, mid);
052        }
053    
054    
055        /**
056         * String representation of Interval.
057         * @see java.lang.Object#toString()
058         */
059        @Override
060        public String toString() {
061            return "[" + left + ", " + right + "]";
062        }
063    
064    
065        /**
066         * Get a scripting compatible string representation.
067         * @return script compatible representation for this Interval.
068         */
069        public String toScript() {
070            // Python case
071            return "[ " + left.toScript() + ", " + right.toScript() + " ]";
072        }
073    
074    
075        /**
076         * Clone this.
077         * @see java.lang.Object#clone()
078         */
079        @Override
080        public Interval<C> clone() {
081            return new Interval<C>(left, right);
082        }
083    
084    
085        /**
086         * Comparison with any other object.
087         * @see java.lang.Object#equals(java.lang.Object)
088         */
089        @Override
090        @SuppressWarnings("unchecked")
091        public boolean equals(Object b) {
092            if (!(b instanceof Interval)) {
093                return false;
094            }
095            Interval<C> a = null;
096            try {
097                a = (Interval<C>) b;
098            } catch (ClassCastException e) {
099            }
100            return left.equals(a.left) && right.equals(a.right);
101        }
102    
103    
104        /**
105         * Hash code for this Interval.
106         * @see java.lang.Object#hashCode()
107         */
108        @Override
109        public int hashCode() {
110            return 37 * left.hashCode() + right.hashCode();
111        }
112    
113    
114        /**
115         * Test if an element is contained in this interval.
116         * @param c element to test.
117         * @return true, if left <= b <= right;
118         */
119        public boolean contains(C c) {
120            return left.compareTo(c) <= 0 && c.compareTo(right) <= 0;
121        }
122    
123    
124        /**
125         * Test if an interval is contained in this interval.
126         * @param vc interval to test.
127         * @return true, if left <= vc.left and vc.right <= right;
128         */
129        public boolean contains(Interval<C> vc) {
130            return contains(vc.left) && contains(vc.right);
131        }
132    
133    
134        /**
135         * Length.
136         * @return |left-right|;
137         */
138        public C length() {
139            C m = right.subtract(left);
140            return m.abs();
141        }
142    
143    
144        /**
145         * BigRational Length.
146         * @return |left-right|;
147         */
148        public BigRational rationalLength() {
149            return length().getRational();
150        }
151    
152    
153        /**
154         * BigDecimal representation of Interval.
155         */
156        public BigDecimal toDecimal() {
157            BigDecimal l = new BigDecimal(left.getRational());
158            BigDecimal r = new BigDecimal(right.getRational());
159            BigDecimal two = new BigDecimal(2);
160            BigDecimal v = l.sum(r).divide(two);
161            return v;
162        }
163    
164    
165        /**
166         * Rational middle point.
167         * @return (left-right)/2;
168         */
169        public BigRational rationalMiddle() {
170            BigRational m = left.getRational().sum(right.getRational());
171            BigRational t = new BigRational(1L,2L);
172            m = m.multiply(t);
173            return m;
174        }
175    
176    
177        /**
178         * Random point of interval.
179         * @return a random point contained in this interval.
180         */
181        public C randomPoint() {
182            C dr = right.subtract(left);
183            RingFactory<C> fac = (RingFactory<C>)dr.factory();
184            C r = fac.random(13);
185            r = r.abs();
186            if ( !r.isZERO() ) {
187                if ( r.compareTo( fac.getONE() ) > 0 ) {
188                    r = r.inverse();
189                }
190            }
191            // 0 <= r <= 1
192            dr = dr.multiply(r);
193            C rv = left.sum(dr);
194            //System.out.println("rv   = " + new BigDecimal(rv.getRational()) );
195            return rv;
196        }
197    
198    }