Są dwa sposoby realizacji tego, z których często korzystam. Zawsze pracuję z danymi w czasie rzeczywistym, więc zakłada to ciągłe wprowadzanie danych. Oto pseudo-kod:
Używając trenowalnego minmax:
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]
Ta funkcja wymaga, abyś albo przeprowadził wstępną fazę szkolenia (przy użyciu calibrate()
), albo abyś ponownie trenował w określonych odstępach czasu lub zgodnie z określonymi warunkami. Wyobraź sobie na przykład taką funkcję:
define function outBounds (val, thresh):
if val > (thresh*peak.value()) || val < (trough.value() / thresh):
calibrate()
wartości szczytowe i minimalne zwykle nie przyjmują wartości, ale jeśli outBounds()
otrzyma wartość, która jest ponad 1,5 razy większa niż aktualny pik lub mniejsza niż bieżąca wartość dolna podzielona przez 1,5, wówczas calibrate()
wywoływana jest funkcja, która pozwala na automatyczną ponowną kalibrację funkcji.
Używając historycznego minmax:
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