Package teamwork :: Package math :: Module Interval
[hide private]
[frames] | no frames]

Source Code for Module teamwork.math.Interval

  1  import string 
  2  from types import * 
  3  from xml.dom.minidom import * 
  4   
5 -class Interval:
6 """Interval representation""" 7 8 # Minimum value for intervals 9 FLOOR = -1.0 10 # Maximum value for intervals 11 CEILING = 1.0 12 # Minimum distance (used for testing equality) 13 QUANTUM = 0.0001 14
15 - def __init__(self,lo=FLOOR,hi=CEILING):
16 """Interval constructor...creates an interval [lo,hi]""" 17 self.lo = max(min(min(lo,hi),Interval.CEILING),Interval.FLOOR) 18 self.hi = max(min(max(lo,hi),Interval.CEILING),Interval.FLOOR)
19
20 - def mean(self):
21 """Returns the midpoint of this interval""" 22 return (self.lo+self.hi)/2.0
23
24 - def __add__(self,other):
25 """Enables I1+I2 and I1+x""" 26 if type(other) in [IntType,LongType,FloatType]: 27 return Interval(self.lo+float(other),self.hi+float(other)) 28 else: 29 try: 30 return Interval(self.lo+other.lo,self.hi+other.hi) 31 except AttributeError: 32 raise TypeError,'non-interval addend ('+`type(other)`+')'
33
34 - def __neg__(self):
35 """Enables -I1""" 36 return Interval(-self.hi,-self.lo)
37
38 - def __sub__(self,other):
39 """Enables I1-I2 and I1-x""" 40 return self + (-other)
41
42 - def __mul__(self,other):
43 """Enables I1*I2 and I1*x""" 44 if type(other) in [IntType,LongType,FloatType]: 45 return Interval(self.lo*float(other),self.hi*float(other)) 46 else: 47 try: 48 values = [] 49 values.append(self.lo*other.lo) 50 values.append(self.lo*other.hi) 51 values.append(self.hi*other.lo) 52 values.append(self.hi*other.hi) 53 return Interval(min(values),max(values)) 54 except AttributeError: 55 raise TypeError,'non-interval multiplicand ('+`type(other)`+')'
56
57 - def __div__(self,other):
58 """Enables I1/I2 and I1/x""" 59 if type(other) in [IntType,LongType,FloatType]: 60 return Interval(self.lo/float(other),self.hi/float(other)) 61 else: 62 try: 63 values = [] 64 values.append(self.lo/other.lo) 65 values.append(self.lo/other.hi) 66 values.append(self.hi/other.lo) 67 values.append(self.hi/other.hi) 68 return Interval(min(values),max(values)) 69 except AttributeError: 70 raise TypeError,'non-interval divisor ('+`type(other)`+')'
71
72 - def __lt__(self,other):
73 """Enables I1<I2 and I1<x""" 74 if type(other) in [IntType,LongType,FloatType]: 75 return self.hi <= float(other)-Interval.QUANTUM 76 else: 77 try: 78 return self.hi <= other.lo-Interval.QUANTUM 79 except AttributeError: 80 raise TypeError,'non-interval comparison ('+`type(other)`+')'
81
82 - def __gt__(self,other):
83 """Enables I1>I2 and I1>x""" 84 if type(other) in [IntType,LongType,FloatType]: 85 return self.lo >= float(other)+Interval.QUANTUM 86 else: 87 try: 88 return self.lo >= other.hi+Interval.QUANTUM 89 except AttributeError: 90 raise TypeError,'non-interval comparison ('+`type(other)`+')'
91
92 - def __eq__(self,other):
93 """Enables I1==I2 and I1==x""" 94 if type(other) in [IntType,LongType,FloatType]: 95 return abs(self.lo-float(other))<Interval.QUANTUM and \ 96 abs(self.hi-float(other))<Interval.QUANTUM 97 else: 98 try: 99 return abs(self.lo-other.lo)<Interval.QUANTUM and \ 100 abs(self.hi-other.hi)<Interval.QUANTUM 101 except AttributeError: 102 raise TypeError,'non-interval comparison ('+`type(other)`+')'
103
104 - def __ne__(self,other):
105 """Enables I1!=I2 and I1!=x""" 106 return not (self == other)
107
108 - def __le__(self,other):
109 """Enables I1<=I2 and I1<=x""" 110 return self < other or self == other
111
112 - def __ge__(self,other):
113 """Enables I1>=I2 and I1>=x""" 114 return self > other or self == other
115
116 - def __contains__(self,other):
117 """Enables I2 in I1 and x in I1""" 118 if type(other) in [IntType,LongType,FloatType]: 119 return float(other) >= self.lo and float(other) <= self.hi 120 else: 121 try: 122 return other.lo >= self.lo and other.hi <= self.hi 123 except AttributeError: 124 raise TypeError,'non-interval comparison ('+`type(other)`+')'
125
126 - def __abs__(self):
127 """Enables abs(I1)""" 128 if self.lo > 0.0: 129 return self 130 elif self.hi < 0.0: 131 return Interval(-self.hi,-self.lo) 132 else: 133 return Interval(0.0,max(-self.lo,self.hi))
134
135 - def __repr__(self):
136 return '[%6.4f,%6.4f]' % (self.lo,self.hi)
137
138 - def __getitem__(self,index):
139 """Allows indexing to get the bounds of this interval 140 141 I['lo'] or I[0] returns the low bound of I; I['hi'] or I[1] 142 returns its high bound""" 143 if index == 'lo' or index == 0: 144 return self.lo 145 elif index == 'hi' or index == 1: 146 return self.hi 147 else: 148 raise IndexError
149
150 - def __setitem__(self,index,value):
151 """Allows indexing to set the bounds of this interval 152 153 I['lo']= or I[0]= sets the low bound of I; I['hi']= or I[1]= 154 sets its high bound""" 155 if index == 'lo' or index == 0: 156 self.lo = floor(value) 157 elif index == 'hi' or index == 1: 158 self.hi = ceil(value) 159 else: 160 raise IndexError
161
162 - def __float__(self):
163 return self.mean()
164
165 - def __xml__(self):
166 doc = Document() 167 root = doc.createElement('interval') 168 doc.appendChild(root) 169 node = doc.createElement('lo') 170 node.appendChild(doc.createTextNode(`self.lo`)) 171 root.appendChild(node) 172 node = doc.createElement('hi') 173 node.appendChild(doc.createTextNode(`self.hi`)) 174 root.appendChild(node) 175 return doc
176
177 - def parse(self,node):
178 child = node.firstChild.firstChild 179 while child: 180 self[child.tagName] = float(child.firstChild.data) 181 child = child.nextSibling
182
183 - def isPoint(self):
184 """Returns true iff the interval is a point interval""" 185 return self.width() < self.QUANTUM
186
187 - def width(self):
188 """Returns the float width of this interval""" 189 return self.hi - self.lo
190
191 -def floor(value):
192 """Returns the maximum between the given value and the interval floor""" 193 return max(value,Interval.FLOOR)
194
195 -def ceil(value):
196 """Returns the minimum between the given value and the interval ceiling""" 197 return min(value,Interval.CEILING)
198
199 -def str2Interval(content):
200 values = string.split(content[1:-1],',') 201 if len(values) != 2: 202 raise TypeError,'Illegal string format for Interval: %s' % content 203 return Interval(float(values[0]),float(values[1]))
204 205 if __name__ == '__main__': 206 import os.path 207 208 209 x = Interval(0.1,0.4) 210 y = Interval(0.3,0.6) 211 print 0.7 in y 212 213 x[0] = 0.3 214 x['hi'] = 0.5 215 print x 216 i = str2Interval('[0.,1.]') 217 print i.lo 218 print i.hi 219 name = '/tmp/%s.xml' % (os.path.basename(__file__)) 220 file = open(name,'w') 221 file.write(i.__xml__().toxml()) 222 file.close() 223 224 i = Interval() 225 i.parse(parse(name)) 226 print i 227