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:
You first calculate a ratio of how far into
a..b
thex
value is:(x - a) / (b - a)
This value will be between 0 and 1.
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;
精彩评论