Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Algorithm to map an interval to a smaller interval

I tried searching, but due to the nature of my question, I was unable to find something satisfactory.

My problem is the following: I am trying to map numbers ranging from 0 to 2000 (though ideally the upper limit would be adjustable) to the much smaller interval ranging from 10 to 100. The upper limits would map (2000->100) and the lower limits as well. Other than that, an entry that is bigger than another entry in the interval [0;2000] would ideally be bigger than that mapped entry in [0;100]

I'm thinking that this question is not language specific, but in case you are wondering, I'm working with Javascript today.

like image 854
Marceau Avatar asked Oct 17 '12 09:10

Marceau


3 Answers

To map
[A, B] --> [a, b]

use this formula
(val - A)*(b-a)/(B-A) + a

as correctly mentioned in the other answer it's linear mapping.

Basically

y = m*x + c

c = intersection at y-axis
m = slope determined by two known point (A, a), (B, b) = (b-a)/(B-A)
like image 114
Nishant Avatar answered Nov 20 '22 15:11

Nishant


I think that instead of giving you a formula of direct mapping, a better approach would be to explain the idea behind it:

Suppose we want to map an interval [0,1] to interval [1,3], which can be seen as the problem of finding f(x) = Ax + B such that giving any x from interval [0,1], will result in f(x) being/resulting in interval [1,3].

From this perspective, we already know some values:

  1. x = 0 & f(0) = 1 => f(0) = A*0 + B = 1 => B = 1
  2. x = 1 & f(1) = 3 => f(1) = A*1 + B = 3 <=> A + 1 = 3 => A=2

From (1) and (2), we may conclude that the function that maps interval [0,1] to [1,3] is f(x) = 2x + 1.

In you very case, you now should have all necessary knowledge to be able to map [0,2000] interval to [10,100].

like image 32
denis-grigor Avatar answered Nov 20 '22 15:11

denis-grigor


// Given a value from intervalA, returns a mapped value from intervalB.
function intervalicValueMap(intervalA, intervalB, valueIntervalA) {
    var valueIntervalB = (valueIntervalA - intervalA[0]) * (intervalB[1] - intervalB[0]) 
                            / (intervalA[1] - intervalA[0]) + intervalB[0];

    valueIntervalB = Math.round(valueIntervalB); // Ommit rounding if not needed.
    return valueIntervalB;
}

var intervalA = [100, 200];
var intervalB = [1, 10];
var valueIntervalA = 170;
var valueIntervalB = intervalicValueMap(intervalA, intervalB, valueIntervalA);

console.log(valueIntervalB); // Logs 7
like image 3
G.L. Avatar answered Nov 20 '22 15:11

G.L.