Дискретное преобразование Фурье - PullRequest
26 голосов
/ 28 сентября 2011

В настоящее время я пытаюсь написать алгоритм преобразования Фурье.Я начал с простого алгоритма DFT, как описано в математическом определении:

public class DFT {
    public static Complex[] Transform(Complex[] input) {
        int N = input.Length;

        Complex[] output = new Complex[N];

        double arg = -2.0 * Math.PI / (double)N;
        for (int n = 0; n < N; n++) {
            output[n] = new Complex();
            for (int k = 0; k < N; k++)
                output[n] += input[k] * Complex.Polar(1, arg * (double)n * (double)k);
        }
        return output;
    }
}

Поэтому я протестировал этот алгоритм с помощью следующего кода:

    private int samplingFrequency = 120;
    private int numberValues = 240;

    private void doCalc(object sender, EventArgs e) {
        Complex[] input = new Complex[numberValues];
        Complex[] output = new Complex[numberValues];

        double t = 0;
        double y = 0;
        for (int i = 0; i < numberValues; i++) {
            t = (double)i / (double)samplingFrequency;
            y = Math.Sin(2 * Math.PI * t);
            input[i] = new Complex(y, 0);
        }

        output = DFT.Transform(input);

        printFunc(input);
        printAbs(output);
    }

Преобразование работает нормально, но только еслиnumberValues ​​- это кратное значение частоты дискретизации (в данном случае: 120, 240, 360, ...).Вот мой результат для 240 значений:

http://s1.directupload.net/images/110928/n3m8hqg6.jpg

Преобразование просто работает нормально.

Если я пытаюсь вычислить 280 значений, я получаю этот результат:

http://s7.directupload.net/images/110928/qizoiqbt.jpg

Почему я получаю неверный результат, если я изменяю количество вычисленных значений?Я не уверен, что моя проблема - это проблема с моим кодом или неправильное понимание математического определения ДПФ.В любом случае, кто-нибудь может мне помочь с моей проблемой?Спасибо.

Ответы [ 2 ]

29 голосов
/ 28 сентября 2011

То, что вы испытываете, называется Спектральная утечка .

Это вызвано тем, что основная математика преобразования Фурье предполагает непрерывную функцию от -infinity до + бесконечности. Таким образом, диапазон образцов, которые вы предоставляете, фактически повторяется бесконечное количество раз. Если у вас нет полного числа циклов формы волны в окне, концы не будут выровнены, и вы получите разрыв, который проявляется в виде размазывания частоты по обе стороны.

Обычный способ справиться с этим называется Windowing . Тем не менее, это имеет недостаток, так как амплитуды немного смещены. Это процесс умножения всего окна выборок, которое вы собираетесь обработать, с помощью некоторой функции, которая стремится к 0 на обоих концах окна, вызывая выравнивание концов, но с некоторым амплитудным искажением, поскольку этот процесс снижает общую мощность сигнала.

Итак, подведем итог: в вашем коде нет ошибок, и результат соответствует ожидаемому. Артефакты могут быть уменьшены с помощью оконной функции, однако это повлияет на точность амплитуд. Вам нужно будет изучить и определить, какое решение лучше всего соответствует требованиям вашего проекта.

5 голосов
/ 28 сентября 2011

Вы НЕ получаете неправильный результат для непериодической синусоиды.И они не просто "артефакты".Ваш результат на самом деле является более полным результатом DFT, который вы не видите с периодической синусоидой.Эти другие ненулевые значения содержат полезную информацию, которую можно использовать, например, для интерполяции частоты одной синусоиды с непериодической апертурой.

ДПФ можно рассматривать как свертывание прямоугольного окнас вашей синусоидой.Это создает (что-то очень похожее) функцию Sinc, которая имеет бесконечную протяженность, НО просто оказывается равной нулю на каждой частоте бина DFT, отличной от ее центрального бина DFT, для любой синусоиды, центрированной точно на бине DFT.Это происходит только в том случае, если частота в апертуре БПФ является точно периодической, а не для какой-либо другой.Функция Sinc имеет множество «горбов», которые скрыты на вашем первом графике.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...