Search code examples
javanumerical-methods

Incremental scaling function


If you know that 'input1' is strictly between 0 and 1 or generally, 'min' and 'max' (where min and max are known to be between, but not strictly, 0 and 1), how would you get 'input1'to increment or decrement by a numerical jump given by 'input2' with assurance that the new value is strictly between min and max and will never reach min or max?


Solution

  • You need a distribution function, preferably an invertible one (the inverse is called quantile function). In other words, you need a monotone strictly increasing, continuous function f with lim[x->-oo] f(x) = 0 and lim[x->oo] f(x) = 1.

    If you have such a distribution function f and its inverse f⁻¹, then your adjusting function gets something like this:

    g (x, Δ) = f( f⁻¹(x) + Δ )
    

    This is for values between 0 and 1, for other intervals [a, b] we need to scale it, using a scaling function s:

    s(x) = (b-a)·x + a,     s⁻¹(y) = (y-a)/(b-a)
    

    Then the adjustment function gets

    h(x, Δ) = s(g(s⁻¹(x), Δ) = s( f( f⁻¹(s⁻¹(x)) + Δ )).
    

    One easily Java-calculable such distribution function would be

    f(x) = 1 - 0.5 * exp(-x)   for 0 ≤ x
    f(x) =     0.5 * exp( x)   for x ≤ 0
    

    with the quantile function

    f⁻¹(y) = - log(2 - 2y)  for   y ≤ 0.5
    f⁻¹(y) =   log(2 y)     for 0.5 ≤ y
    

    Building from this your adjustment function is just putting these together.

    Of course, this works only to the limits of your number precision – you can't get arbitrary close to 1.