La evaluación diferida es una estrategia de evaluación que retarda la evaluación de una expresión hasta que su valor sea necesario. Cuando se combina con la memoización, la estrategia de evaluación diferida evita las evaluaciones repetidas y puede reducir el tiempo de ejecución de determinadas funciones por un factor significativo.
La biblioteca de series temporales utiliza la evaluación diferida para procesar datos. Teóricamente, un gráfico de ejecución se construye a partir de los datos de las series temporales cuya evaluación sólo se activa cuando se materializa su salida. Presuponiendo que un objeto se mueve en un espacio de una dimensión, cuya ubicación se captura mediante x (t). Puede determinar la aceleración y frenado de harsh (h(t)
) de este objeto utilizando su serie temporal de velocidad (v(t)
) y aceleración (a(t)
) del modo siguiente:
# 1d location timeseries
x(t) = input location timeseries
# velocity - first derivative of x(t)
v(t) = x(t) - x(t-1)
# acceleration - second derivative of x(t)
a(t) = v(t) - v(t-1)
# harsh acceleration/braking using thresholds on acceleration
h(t) = +1 if a(t) > threshold_acceleration
= -1 if a(t) < threshold_deceleration
= 0 otherwise
Da como resultado un simple gráfico de ejecución con el formato:
x(t) --> v(t) --> a(t) --> h(t)
Las evaluaciones no se activan hasta que se realiza una acción como, por ejemplo, compute h(5...10)
, es decir, compute h(5), ..., h(10)
. La biblioteca captura dependencias temporales acotadas entre series temporales. En este ejemplo, h(5...10)
requiere a(5...10)
, que a su vez requiere v(4...10)
, que luego requiere x(3...10)
. Solo se evalúan las partes relevantes de a(t)
, v(t)
y x(t)
.
h(5...10) <-- a(5...10) <-- v(4...10) <-- x(3...10)
Además, las evaluaciones se memoizan y, por lo tanto, se pueden reutilizar en acciones posteriores en h
. Por ejemplo, cuando una solicitud de h(7...12)
sigue una solicitud de h(5...10)
, podría aprovechar los valores memoizados h(7...10)
; además, h(11...12)
se evaluaría utilizando a(11...12), v(10...12)
y x(9...12)
, que a su vez aprovecharían v(10)
y x(9...10)
memoizados del cálculo anterior.
En un ejemplo más general, puede definir una serie temporal de velocidad ajustada de la siguiente manera:
# 1d location timeseries
x(t) = input location timeseries
# velocity - first derivative of x(t)
v(t) = x(t) - x(t-1)
# smoothened velocity
# alpha is the smoothing factor
# n is a smoothing history
v_smooth(t) = (v(t)*1.0 + v(t-1)*alpha + ... + v(t-n)*alpha^n) / (1 + alpha + ... + alpha^n)
# acceleration - second derivative of x(t)
a(t) = v_smooth(t) - v_smooth(t-1)
En este ejemplo, h(l...u)
tiene la siguiente dependencia temporal. La evaluación de h(l...u)
se adhiere estrictamente a esta dependencia temporal con memoización.
h(l...u) <-- a(l...u) <-- v_smooth(l-1...u) <-- v(l-n-1...u) <-- x(l-n-2...u)
Un ejemplo
El ejemplo siguiente muestra un fragmento de código python que implementa una aceleración de harsh en una serie temporal simple de la memoria. La biblioteca incluye varias transformaciones integradas. En este ejemplo, la transformación de diferencia se aplica dos veces a las series temporales de ubicación para calcular la serie temporal de aceleración. Se aplica una operación de correlación a la serie temporal de aceleración utilizando una función lambda de harsh, definida después del código de ejemplo, que correlaciona la aceleración con +1
(aceleración harsh), -1
(frenado harsh) y 0
(otros casos). La operación de filtro solo selecciona las instancias en las que se observa una aceleración harsh o un frenado harsh. Antes de llamar a get_values
, se crea un gráfico de ejecución, pero no se realizan cálculos. Cuando se llama a get_values(5, 10)
, la evaluación se realiza con la memoización en la dependencia temporal más acotada posible del gráfico de ejecución.
import tspy
from tspy.builders.functions import transformers
x = tspy.time_series([1.0, 2.0, 4.0, 7.0, 11.0, 16.0, 22.0, 29.0, 28.0, 30.0, 29.0, 30.0, 30.0])
v = x.transform(transformers.difference())
a = v.transform(transformers.difference())
h = a.map(harsh).filter(lambda h: h != 0)
print(h[5, 10])
El harsh lambda se define de la siguiente manera:
def harsh(a):
threshold_acceleration = 2.0
threshold_braking = -2.0
if (a > threshold_acceleration):
return +1
elif (a < threshold_braking):
return -1
else:
return 0
Más información
Para utilizar el SDK tspy
de Python, consulte la Documentación del SDK tspy
de Python.
Tema principal: Análisis de series temporales