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 }