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