Hay dos formas de implementar esto que uso comúnmente. Siempre estoy trabajando con datos en tiempo real, por lo que esto supone una entrada continua. Aquí hay un pseudocódigo:
Usando un minmax entrenable:
define function peak:
// keeps the highest value it has received
define function trough:
// keeps the lowest value it has received
define function calibrate:
// toggles whether peak() and trough() are receiving values or not
define function scale:
// maps input range [trough.value() to peak.value()] to [0.0 to 1.0]
Esta función requiere que realices una fase de entrenamiento inicial (mediante el uso calibrate()
) o que vuelvas a entrenar a ciertos intervalos o de acuerdo con ciertas condiciones. Por ejemplo, imagine una función como esta:
define function outBounds (val, thresh):
if val > (thresh*peak.value()) || val < (trough.value() / thresh):
calibrate()
pico y valle normalmente no reciben valores, pero si outBounds()
recibe un valor que es más de 1.5 veces el pico actual o menor que el canal actual dividido por 1.5, entonces calibrate()
se llama lo que permite que la función se recalibre automáticamente.
Usando un mínimo histórico:
var arrayLength = 1000
var histArray[arrayLength]
define historyArray(f):
histArray.pushFront(f) //adds f to the beginning of the array
define max(array):
// finds maximum element in histArray[]
return max
define min(array):
// finds minimum element in histArray[]
return min
define function scale:
// maps input range [min(histArray) to max(histArray)] to [0.0 to 1.0]
main()
historyArray(histArray)
scale(min(histArray), max(histArray), histArray[0])
// histArray[0] is the current element