Cuando quieres comparar distintos datos en distintos rangos es habitual el tener que normalizarlos entre 0 y 1, es decir, convertir una variable de un rango de valores [in_min, in_max] a otro que va de 0 a 1. Para ello podemos usar la función map.
map(x, in_min, in_max, 0.0, 1.0);
En esta otra entrada de blog hay más información sobre la función map y como optimizarla, vamos a usar esos trucos para crear funciones de normalización más optimas.
Lo primero es que como los valores sobre los que se «mapea» son siempre los mismos 0 y 1 podemos crear nuestra propia función a partir del código de la función map.
long map(long x, long in_min, long in_max, long out_min, long out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
Se reemplaza out_min por 0 y out_max por 1 y se simplifican los cálculos:
long map(long x, long in_min, long in_max, long out_min, long out_max) {
return (x - in_min) * (1 - 0) / (in_max - in_min) + 0;
}
Obteniendo:
long normalize(long x, long in_min, long in_max) {
return (x - in_min) / (in_max - in_min);
}
Vamos a crear también funciones para los float y los double:
float floatNormalize(float x, float in_min, float in_max) {
return (x - in_min) / (in_max - in_min);
}
double doubleNormalize(double x, double in_min, double in_max) {
return (x - in_min) / (in_max - in_min);
}
Genial, pero aun podemos hacer otra mejora, la función anterior es genérica, si vamos a aplicar la normalización siempre a valores en el mismo rango podemos crear una nueva función donde remplacemos in_min e in_max por los valores de este rango. Por ejemplo en un rango de 0 a 1023:
//in: 0..1023
//in_min = 0
//in_max = 1023
long customNormalize(long x){
return (x - 0) / (1023 - 0);
}
Simplificando:
long customNormalize(long x){
return x / 1023;
}
Hemos reducido el coste de la normalización a una solo división, en el peor de los casos (cuando el in_min no sea 0) será una resta y una división.