AlexanderKamynin / dsp

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

digital signal processing

Описание практического задания:

Технологии и ограничения:

  • Языки программирования: Java, Python, C++;
  • Дополнительные библиотеки: Apache math3;

Постановка задачи:

  1. Реализовать программный модуль фильтрации входящего сигнала на основе скользящего окна;
  2. Найти временной ряд отклонений (дисперсий) и построить их функцию распределения;
  3. Построить автокорреляционную функцию временного ряда:
    • Реализовать при помощи стандартного способа (кольцевого смещения);
    • При помощи БПФ;

Зависимости

Проект реализован на языке Python с использованием следующих библиотек:

Инструкция по запуску

Перед запуском необходимо скачать проект. Это можно сделать с помощью команды git clone https://github.com/AlexanderKamynin/dsp.git.
Запуск можно выполнить из корневой папки проекта с использованием команды python3 main.py.
После запуска с использованием CLI выбирается тип генератора для сигнала, вводятся параметры, размер окна фильтрации (SMA) и выбирается метод построения автокорреляционной функции.
Полученные в ходе обработки сигнала результаты сохраняются в папке output. В output/images/ находятся построенные графики, в output/result текстовые файлы с числовыми данными.

Теоретические сведения

Для генерации используется гармонический сигнал, формула которого может быть описана следующим уравнением:
$$x(t) = A sin(wt + \phi_0)$$ где $A$ - амплитуда сигнала, $w$ - циклическая частота, $\phi_0$ - начальная фаза.


Фильтрация сигнала осуществляется с помощью метода скользящего окна (Simple Moving Average). Для вычисления нового, отфильтрованного сигнала, в пределах задаваемого окна усредняются значения и заносятся в новый ряд по следующей формуле:
$$x_{i}^{new} = \frac{1}{w} \sum\limits_{j=i-h}^{i+h}x_i$$ Здесь $w$ - размер окна, h - величина, равная половине окна ($h=\frac{w-1}{2}$). В случае, если размер окна - нечетное число, оно увеличивается до четного. Как можно заметить, величиной $h$ определяется размах окна влево и вправо от i-го элемента.
Несложно заметить, что при $i<=h$ и $i+h>n$ (n - длина последовательности $x_i$) в знаке суммы выходим в отрицательные индексы. Для того, чтобы этого избежать (и тем самым вычислить новую отфильтрованную последовательность размерности n), можно постепенно увеличивать размер окна по формуле: $w=2 \cdot i + 1$. Тогда формула примет следующий вид:
$$x_{i}^{new} = \frac{1}{2i+1} \sum\limits_{j=0}^{2i}x_i \quad \text{if } i <= h$$ $$x_{i}^{new} = \frac{1}{2(n-i-1)} \sum\limits_{j=2i-n+2}^{n}x_i \quad \text{if } i + h > n$$ $$x_{i}^{new} = \frac{1}{w} \sum\limits_{j=i-h}^{i+h}x_i \quad \text{else}$$


Между полученным отфильтрованным сигналом и исходным ищется отклонение (разность между истинным и полученным значением). Полученный ряд сортируется по возрастанию, ищется значения функции распределения по следующей формуле: $$F(x) = P(X < x)$$ где $P(X < x)$ - вероятность того, что некоторое значение сигнала оказалась меньше фиксированного $x$.
$P(X < x)$ в данном можно посчитать так: $P(X < x) = \frac{\text{count(}X < x\text{)}}{n}$, где $n$ - длина последовательности сигнала.


Вычисление автокорреляционной функции циклическим сдвигом (кольцевым смещением) выполняется по следующей формуле:
$$R(t) = \rho(x(t),x(t+k))$$ где $k$ - величина сдвига (так называемый лаг), а $\rho(x(t),x(t+k))$ - корреляция между сигналом в момент времени t, и сдвиннутым сигналом в момент времени t+k. Величина лага перебирается от 0 до, обычно, величины $\frac{n}{4}$, так как функция является симметричной и нет необходимости в вычислении ее для всей последовательности.


Формула для автокорреляционной функции с применением быстрого преобразования Фурье выглядит следующим образом: $$R(t) = \frac{Re(\text{IFFT}(|\text{FFT}(x)|^2))}{C}$$ где FFT - прямое БПФ, IFFT - обратное БПФ, Re - вещественная комплекснозначная часть, C - некоторая константа, появляющаяся в ходе вычисления БПФ.
Известно, что для самого первого элемента коэффициент корреляции равен 1 (исходя из определения автокорреляционной функции). Значит коэффициент C можно найти, как $\frac{1}{R_0}$.

Пример работы

Запуск проекта: изображение

Сгенерированный сигнал: изображение

Отфильтрованный сигнал с помощью метода скользящего окна (SMA): изображение

Функция распределения отклонений: изображение

Автокорреляционная функция: изображение

About


Languages

Language:Python 100.0%