Method: AppMath::Iv#axis_division

Defined in:
lib/interval.rb

#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