52700.fb2
lazyHead a =
let (x:xs) = a
in
x
Посмотрим как используются ленивые образцы при построении потоков, или бесконечных списков. Мы
будем представлять функции одного аргумента потоками значений с одинаковым шагом. Так мы будем пред-
ставлять непрерывные функции дискретными сигналами. Считаем, что шаг дискретизации (или шаг между
соседними точками) нам известен.
f : R → R ⇒ fn = f ( nτ ) ,
n = 0 , 1 , 2 , ...
Где τ – шаг дискретизации, а n пробегает все натуральные числа. Определим функцию решения диффе-
ренциальных уравнений вида:
dx = f( t)
dt
x(0) = ˆ
x
Символ ˆ x означает начальное значение функции x. Перейдём к дискретным сигналам:
xn−xn− 1 = f
τ
n,
x 0 = ˆ
x
Где τ – шаг дискретизации, а x и f – это потоки чисел, индекс n пробегает от нуля до бесконечности
по всем точкам функции, превращённой в дискретный сигнал. Такой метод приближения дифференциаль-
ных уравнений называют методом Эйлера. Теперь мы можем выразить следующий элемент сигнала через
предыдущий.
xn = xn− 1 + τ fn, x 0 = ˆ
x
Закодируем это уравнение:
-- шаг дискретизации
dt :: Fractional a => a
dt = 1e-3
-- метод Эйлера
int :: Fractional a => a -> [a] -> [a]
int x0 (f:fs) = x0 : int (x0 + dt * f) fs
Смотрите в функции int мы принимаем начальное значение x0 и поток всех значений функции пра-
вой части уравнения, поток значений функции f( t). Мы помещаем начальное значение в первый элемент
результата, а остальные значения получаем рекурсивно.
Определим две вспомогательные функции:
time :: Fractional a => [a]
time = [0, dt .. ]
dist :: Fractional a => Int -> [a] -> [a] -> a
dist n a b = ( / fromIntegral n) $
foldl’ (+) 0 $ take n $ map abs $ zipWith (-) a b
Функция time пробегает все значения отсчётов шага дискретизации по времени. Это тождественная функ-
ция представленная в виде потока с шагом dt.
Функция проверки результата dist принимает два потока и по ним считает расстояние между ними. Эта
функция говорит, что расстояние между двумя потоками в n первых точках равно сумме модулей разности
между значениями потоков. Для того чтобы оценить среднее расхождение, мы делим в конце результат на