开发者

How to map numbers in range <0;99> to range <-1.0;1.0>?

开发者 https://www.devze.com 2023-01-24 19:31 出处:网络
So I have a function which always returns a number from range <0;99> (i.e. 0, 1, ... 99 - integers).

So I have a function which always returns a number from range <0;99> (i.e. 0, 1, ... 99 - integers).

What would be the best way to correctly map those numbers to range <-1.0;1开发者_如何学编程.0>?

0 would be -1.0 of course and 99 would be 1.0. How to calculate the numbers between?


Use a linear mapping:

y = ((x / 99.0) * 2) - 1

How it works:

  • Divide by 99: This normalizes the range from [0, 99] to [0, 1].
  • Multiply by 2: This increases the range to [0, 2].
  • Subtract 1: This is a translation which gives [-1, 1].

You can of course combine the steps ((x / 99.0) * 2) into a single division if you wish. I just split it up for clarity.


Don't do scaling manually; it takes far too much squinting at the math to figure out what's really intended. Use a helper function.

def scale(val, src, dst):
    """
    Scale the given value from the scale of src to the scale of dst.
    """
    return ((val - src[0]) / (src[1]-src[0])) * (dst[1]-dst[0]) + dst[0]

print scale(0, (0.0, 99.0), (-1.0, +1.0))
print scale(1, (0.0, 99.0), (-1.0, +1.0))
print scale(99, (0.0, 99.0), (-1.0, +1.0))

I've found this to be one of the more useful functions to have in any language; you can tell what the scale() calls do at a glance.


To map a value x from this range:

[a..b]

To this range:

[a'..b']

You use this formula:

x' = (x / 99) * 2 - 1

The way such a mapping works is as follows:

x' = ((x - a) / (b - a)) * (b' - a') + a'

Step by step:

  1. You first calculate a ratio of how far into a..b the x value is:

    (x - a) / (b - a)
    

    This value will be between 0 and 1.

  2. Then you use this value to calculate how far into a'..b' the value should be:

    ratio * (b' - a') + a'
    

In your particular case:

x' = ((x - 0) / (99 - 0)) * (1.0 - (-1.0)) + (-1.0)

or in contracted form:

x' = (x / 99) * 2 - 1

Note: If you're doing this in a programming language where integer divided by another integer is integer division, you should promote the values to floating point to avoid having to deal with loss of precision:

x' = (x / 99.0) * 2.0 - 1.0


Use numpy, that would be most efficient

>>> from numpy import interp
>>> interp(50, [0,99], [-1,1])
0.010101010101010166


Use this for any range (can be negative, too).

[minFrom..maxFrom] -> [minTo..maxTo]

mappedValue = minTo + (maxTo - minTo) * ((value - minFrom) / (maxFrom - minFrom));


n = (n / 99) * 2 - 1;
0

精彩评论

暂无评论...
验证码 换一张
取 消