Class: AppMath::Iv
- Inherits:
-
Object
- Object
- AppMath::Iv
- Defined in:
- lib/interval.rb
Overview
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.
Instance Attribute Summary collapse
-
#low ⇒ Object
readonly
Returns the value of attribute low.
-
#upp ⇒ Object
readonly
Returns the value of attribute upp.
Class Method Summary collapse
-
.from_array(anArray) ⇒ Object
using max and min of an array for defining an interval.
Instance Method Summary collapse
-
#&(anIv) ⇒ Object
section, intersection meet or g.l.b (greatest lower bound) in lattice terminology.
-
#*(a) ⇒ Object
multiplying size by a, while preserving the center.
-
#+(a) ⇒ Object
shifting by a.
-
#axis_division(anPosInteger) ⇒ Object
The function creates a suitable axis sub-division for data ranging from @low to @upp.
-
#center ⇒ Object
Returns the midpoint of the interval.
-
#empty? ⇒ Boolean
Returns true iff the interval is empty.
-
#ind(x) ⇒ Object
Indicator function.
-
#inf ⇒ Object
Returns the lower boundary if self is not empty and nil else.
-
#initialize(*arg) ⇒ Iv
constructor
Allowed are 0, 1, 2 arguments, which all have to be convertible to R.
-
#met_ind(x) ⇒ Object
Metrical indicator function.
-
#put(p) ⇒ Object
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 .
-
#size ⇒ Object
Returns the length of the interval, 0 for the empty one.
-
#sup ⇒ Object
Returns the upper boundary if self is not empty and nil else.
-
#to_array(a) ⇒ Object
Returns an ordered equidistant array of n numbers, where the first one is @low and the last one is @upp.
- #to_s ⇒ Object
-
#|(anIv) ⇒ Object
minimum closed interval that contains the union join or l.u.b.
Constructor Details
#initialize(*arg) ⇒ Iv
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.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/interval.rb', line 60 def initialize(*arg) n = arg.size case n when 0 @low = R.c1 @upp = R.c0 # notice: epmpty since @low > @upp when 1 x = R.c arg[0] zero = R.c0 if x < zero @low = x @upp = zero else @upp = x @low = zero end when 2 x = R.c arg[0] y = R.c arg[1] if x < y @low = x @upp = y else @low = y @upp = x end else fail "Iv.new takes 0 or 1 or 2 arguments, but not " + n.to_s end # case n end |
Instance Attribute Details
#low ⇒ Object (readonly)
Returns the value of attribute low.
47 48 49 |
# File 'lib/interval.rb', line 47 def low @low end |
#upp ⇒ Object (readonly)
Returns the value of attribute upp.
47 48 49 |
# File 'lib/interval.rb', line 47 def upp @upp end |
Class Method Details
.from_array(anArray) ⇒ Object
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.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/interval.rb', line 97 def Iv.from_array(anArray) n = anArray.size case n when 0 Iv.new when 1 a0 = anArray[0] Iv.new(a0) else x0 = anArray[0] x1 = x0 anArray.each{ |x| if x < x0 x0 = x elsif x > x1 x1 = x else end } Iv.new(x0,x1) end end |
Instance Method Details
#&(anIv) ⇒ Object
section, intersection meet or g.l.b (greatest lower bound) in lattice terminology
224 225 226 227 228 229 230 |
# File 'lib/interval.rb', line 224 def &(anIv) return Iv.new if empty? || anIv.empty? return Iv.new if @upp < anIv.low || @low > anIv.upp amin = Basics.sup(@low, anIv.low) amax = Basics.inf(@upp, anIv.upp) Iv.new(amin, amax) end |
#*(a) ⇒ Object
multiplying size by a, while preserving the center
218 219 220 |
# File 'lib/interval.rb', line 218 def *(a) Iv.new(center-(center-@low)*a,center+(@upp-center)*a) end |
#+(a) ⇒ Object
shifting by a
215 |
# File 'lib/interval.rb', line 215 def +(a); Iv.new(@low + a,@upp + a); end |
#axis_division(anPosInteger) ⇒ Object
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 is a proposal for the difference between adjacent axis tics and res is an array of the values to which the proposed tics belong. Thus res.first <= @low and res.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.
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/interval.rb', line 250 def axis_division(anPosInteger) fail "can't divide an empty interval" if empty? a = @low b = @upp n = anPosInteger.abs n += 1 if n == 0 d = size/n d_ = Basics.cut(d) # this is the essential point fail "Zero division in function axis_division" if d_ == 0.0 d_inv=d_.inv; epsilon = R.c 1e-6 k_b=(b*d_inv - epsilon).ceil # without the epsilon correction it depends on roundoff # errors whether b_ becomes too large k_a=(a*d_inv + epsilon).floor # without the epsilon correction it depends on roundoff # errors whether a_ becomes too small b_=k_b * d_ b__ = (k_b - 0.5) * d_ a_=k_a * d_ res=Array.new while a_ < b__ res << a_ a_ += d_ end res << b_ # we know the last item exactly, and should # not spoil it by arithmetic errors [ d_ , res ] end |
#center ⇒ Object
Returns the midpoint of the interval.
169 170 171 172 |
# File 'lib/interval.rb', line 169 def center nil if empty? (@low + @upp) * R.i2 end |
#empty? ⇒ Boolean
Returns true iff the interval is empty
152 |
# File 'lib/interval.rb', line 152 def empty?; @low > @upp; end |
#ind(x) ⇒ Object
Indicator function. Returns true if the point x belongs to self and false else.
182 183 184 185 186 187 |
# File 'lib/interval.rb', line 182 def ind(x) return false if empty? return false if x > @upp return false if x < @low true end |
#inf ⇒ Object
Returns the lower boundary if self is not empty and nil else.
156 157 158 159 |
# File 'lib/interval.rb', line 156 def inf return nil if empty? @low end |
#met_ind(x) ⇒ Object
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).
193 194 195 196 197 198 |
# File 'lib/interval.rb', line 193 def met_ind(x) return nil if empty? y = R.c x dc = (y - center).abs dc - size * R.i2 end |
#put(p) ⇒ Object
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 .
202 203 204 |
# File 'lib/interval.rb', line 202 def put(p) inf + size * p end |
#size ⇒ Object
Returns the length of the interval, 0 for the empty one
175 176 177 178 |
# File 'lib/interval.rb', line 175 def size s = @upp - @low s >= R.c0 ? s : R.c0 end |
#sup ⇒ Object
Returns the upper boundary if self is not empty and nil else.
163 164 165 166 |
# File 'lib/interval.rb', line 163 def sup return nil if empty? @upp end |
#to_array(a) ⇒ Object
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.
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/interval.rb', line 126 def to_array(a) return nil if empty? if a.integer? # then we interpret the argument as an intended number # of lattice points n = a else # then we interprete the argument as an intended lattice spacing d = a.abs fail "can't build a lattice with spacing 0" if d.zero? n = (size/d).round + 1 end fail "number of lattice points must be larger than 1" if n < 2 res = Array.new res << @low if n > 2 na = n - 2 d = size / (n-1) x = @low for i in 1..na x += d res << x end end res << @upp end |
#to_s ⇒ Object
232 233 234 |
# File 'lib/interval.rb', line 232 def to_s "Iv (" + @low.to_s + "," + @upp.to_s + ")" end |
#|(anIv) ⇒ Object
minimum closed interval that contains the union join or l.u.b. (lowest upper bound) in lattice terminology
208 209 210 211 212 |
# File 'lib/interval.rb', line 208 def |(anIv) return anIv if empty? return self if anIv.empty? Iv.from_array [@low, @upp, anIv.low, anIv.upp] end |