I would like to map a value from one range to another. However, I would like to control the "curve"/"skewing of the mapping.
For example, I would like to map a range of values to the range [0.5, 2.0], such that a mid-point value in the source range maps to 1.0 in the destination range.
To continue with this example, for the following:
Src range [100.0, 1000.0]
Dst range [0.5, 2.0]
Desired output examples:
100.0 => 0.5
550.0 => 1.0
1000.0 => 2.0
(If I were to use a regular linear mapping — http://rosettacode.org/wiki/Map_range — then the midpoint value 550.0 maps to 1.25)
Thank you.
Allan
Best Answer
A quick-and-dirty approach to controlling the monotone image of an interval so that the midpoint goes to a predetermined location is with a piecewise linear function.
Let the original values be the reference interval $[0,1]$, and suppose the new range should be $[a,b]$. Since the function is to be onto and order preserving (monotone increasing), we will need:
$$ f(0) = a, f(1) = b$$
To give ourselves an extra degree of freedom we will specify $f(0.5) = m \in (a,b)$. The piecewise linear function then consists of two segments of definition:
$$ f(x) = \begin{cases} a + 2(m-a)x & \text{if } x \in [0,0.5] \\ b - 2(b-m)(1-x) & \text{if } x \in [0.5, 1] \end{cases} $$
To guarantee continuity of the mapping it is enough to verify that both segments agree at the the point of overlap, $f(0.5) = m$.
For some applications it might be desirable to have a smoother mapping (this one is not differentiable at $x=0.5$) or to specify other properties (concavity/convexity/point of inflexion). So this answer might be merely a stepping off point to explore more sophisticated mappings.