Class AppMath::Iv
In: interval.rb
Parent: Object

Class of real closed intervals. In most applications of intervals it is an advantage if single real values can be considered as intervals of length zero. This is possible only for closed intervals, and this is the rational for defining those in preference to open intervals. With the attributes @low and @upp, the values x which belong to interval are characterized by the formula

  @low <= x <= @upp .

Hence the interval is empty (void) iff @low > @upp.

Methods

&   *   +   axis_division   center   empty?   from_array   ind   inf   met_ind   new   put   size   sup   to_array   to_s   |  

Attributes

low  [R] 
upp  [R] 

Public Class methods

using max and min of an array for defining an interval. The values of the array components are then known to belong to to a closed interval. The smallest such interval is what his method returns.

[Source]

     # File interval.rb, line 81
 81:   def Iv.from_array(anArray)
 82:     n = anArray.size
 83:     case n
 84:     when 0
 85:       Iv.new
 86:     when 1 
 87:       a0 = anArray[0]
 88:       Iv.new(a0)
 89:     else
 90:       x0 = anArray[0]
 91:       x1 = x0
 92:       anArray.each{ |x|
 93:         if x < x0 
 94:           x0 = x
 95:         elsif x > x1
 96:           x1 = x
 97:         else
 98:         end
 99:       }
100:       Iv.new(x0,x1)
101:     end
102:   end

Allowed are 0, 1, 2 arguments, which all have to be convertible to R. For no argument the empty interval is created. For one argument, an second argument 0 is understood. For two arguments, these are the boundaries of the interval and the order on input does not matter:

  iv1 = Iv.new(2,3); iv2 = Iv.new(3,2)

are thus the same, non-empty, interval, which in mathematical notation would be

  [2,3]

Finally

  iv3 = Iv.new

is an empty interval.

[Source]

    # File interval.rb, line 44
44:   def initialize(*arg)
45:     n = arg.size
46:     case n
47:     when 0
48:       @low = R.c1
49:       @upp = R.c0 # notice: epmpty since @low > @upp

50:     when 1
51:       x = R.c arg[0] 
52:       zero = R.c0
53:       if x < zero
54:         @low = x
55:         @upp = zero
56:       else
57:         @upp = x
58:         @low = zero
59:       end
60:     when 2
61:       x = R.c arg[0]
62:       y = R.c arg[1]
63:       if x < y
64:         @low = x
65:         @upp = y
66:       else
67:         @low = y 
68:         @upp = x
69:       end
70:     else
71:         fail "Iv.new takes 0 or 1 or 2 arguments, but not " + n.to_s
72:     end # case n

73:   end

Public Instance methods

section, intersection meet or g.l.b (greatest lower bound) in lattice terminology

[Source]

     # File interval.rb, line 208
208:   def &(anIv)
209:     return Iv.new if empty? || anIv.empty?
210:     return Iv.new if @upp < anIv.low || @low > anIv.upp
211:     amin = Basics.sup(@low, anIv.low)
212:     amax = Basics.inf(@upp, anIv.upp)
213:     Iv.new(amin, amax)
214:   end

multiplying size by a, while preserving the center

[Source]

     # File interval.rb, line 202
202:   def *(a)
203:     Iv.new(center-(center-@low)*a,center+(@upp-center)*a)
204:   end

shifting by a

[Source]

     # File interval.rb, line 199
199:   def +(a); Iv.new(@low + a,@upp + a); end

The function creates a suitable axis sub-division for data ranging from @low to @upp. Let res be the return value of the function. Then res[0] is a proposal for the difference between adjacent axis tics and res[1] is an array of the values to which the proposed tics belong. Thus res[1].first <= @low and res[1].last >= @upp. All numbers are chosen such that they are simple when written down in normal scientific notation and the intention is to simulate the considerations that determine the axis subdivision of reasonable manually created diagrams. The argument of the function is a proposal for the number of tics to be used. Values from 5 to 10 are reasonable. To have a simple logic, we simply enforce that the interval between tics is a simple number. The initial and the final number of the axis division is chosen as an integer multiple of this inter-tic interval.

[Source]

     # File interval.rb, line 234
234:   def axis_division(anPosInteger)
235:     fail "can't divide an empty interval" if empty?
236:     a = @low
237:     b = @upp
238:     n = anPosInteger.abs
239:     n += 1 if n == 0
240:     d = size/n
241:     d_ = Basics.cut(d) # this is the essential point

242:     fail "Zero division in function axis_division" if d_ == 0.0
243:     d_inv=d_.inv;
244:     epsilon = R.c 1e-6
245:     k_b=(b*d_inv - epsilon).ceil
246:       # without the epsilon correction it depends on roundoff 

247:       # errors whether b_ becomes too large

248:     k_a=(a*d_inv + epsilon).floor
249:       # without the epsilon correction it depends on roundoff 

250:       # errors whether a_ becomes too small

251:     b_=k_b * d_
252:     b__ = (k_b - 0.5) * d_
253:     a_=k_a * d_
254:     res=Array.new
255:     while a_ < b__
256:       res << a_
257:       a_ += d_
258:     end
259:     res << b_ # we know the last item exactly, and should

260:       # not spoil it by arithmetic errors

261:     [ d_ , res ]
262:   end

Returns the midpoint of the interval.

[Source]

     # File interval.rb, line 153
153:   def center
154:     nil if empty?
155:     (@low + @upp) * R.i2
156:   end

Returns true iff the interval is empty

[Source]

     # File interval.rb, line 136
136:   def empty?; @low > @upp; end

Indicator function. Returns true if the point x belongs to self and false else.

[Source]

     # File interval.rb, line 166
166:   def ind(x)
167:     return false if empty?
168:     return false if x > @upp
169:     return false if x < @low
170:     true
171:   end

Returns the lower boundary if self is not empty and nil else.

[Source]

     # File interval.rb, line 140
140:   def inf
141:     return nil if empty?
142:     @low
143:   end

Metrical indicator function. Returns the distance of x from the set self if x is outside of self. If it is inside, the return value is minus the distance to the complement of self (which is not an interval but a well-defined set).

[Source]

     # File interval.rb, line 177
177:   def met_ind(x)
178:     return nil if empty?
179:     y = R.c x
180:     dc = (y - center).abs
181:     dc - size * R.i2
182:   end

Returns a real number, which is self‘s lower end for p == 0.0, self‘s center for p == 0.5, and self‘s upper end for p == 1.0 .

[Source]

     # File interval.rb, line 186
186:   def put(p)
187:     inf + size * p
188:   end

Returns the length of the interval, 0 for the empty one

[Source]

     # File interval.rb, line 159
159:   def size
160:     s = @upp - @low
161:     s >= R.c0 ? s : R.c0
162:   end

Returns the upper boundary if self is not empty and nil else.

[Source]

     # File interval.rb, line 147
147:   def sup
148:     return nil if empty?
149:     @upp
150:   end

Returns an ordered equidistant array of n numbers, where the first one is @low and the last one is @upp. The positive integer n is made from the argument a in a way which depends on whether this argument is integer or not. In the first case it is taken as n and in the second case, the argment is taken as a proposal for the lattice spacing. The actual lattice spacing will be chosen as a fraction of size.

[Source]

     # File interval.rb, line 110
110:   def to_array(a)
111:     return nil if empty?
112:     if a.integer? # then we interpret the argument as an intended number

113:       # of lattice points

114:       n = a
115:     else # then we interprete the argument as an intended lattice spacing

116:       d = a.abs
117:       fail "can't build a lattice with spacing 0" if d.zero?
118:       n = (size/d).round + 1
119:     end
120:     fail "number of lattice points must be larger than 1" if n < 2
121:     res = Array.new
122:     res << @low
123:     if n > 2
124:       na = n - 2
125:       d = size / (n-1)
126:       x = @low
127:       for i in 1..na
128:         x += d
129:         res << x
130:       end
131:     end
132:     res << @upp
133:   end

[Source]

     # File interval.rb, line 216
216:   def to_s
217:     "Iv (" + @low.to_s + "," + @upp.to_s + ")"
218:   end

minimum closed interval that contains the union join or l.u.b. (lowest upper bound) in lattice terminology

[Source]

     # File interval.rb, line 192
192:   def |(anIv)
193:     return anIv if empty?
194:     return self if anIv.empty?
195:     Iv.from_array [@low, @upp, anIv.low, anIv.upp]
196:   end

[Validate]