Простые коэффициенты ДПФ = › Амплитуда / Частоты = › График

Я пытаюсь использовать DFT и FFT в Python с помощью numpy и pyplot.

Мой образец вектора

x = np.array([1,2,4,3]

Коэффициенты ДПФ для этого вектора равны

K = [10+0j, -3+1j, 0+0j, -3-1j]

поэтому в основном у нас есть 10, -3+i, 0 и -3-1i в качестве коэффициентов ДПФ.

Теперь моя проблема состоит в том, чтобы получить комбинацию sin и cos, соответствующую всем 4 пунктам.

Предположим, у нас есть частота дискретизации 1 Гц.

Это мой код:

from matplotlib import pyplot as plt
import numpy as np

x = np.array([1,2,4,3])

fft = np.fft.fft(x)

space = np.linspace(0,4,50)
values = np.array([1,2,3,4])

cos0 = fft[0].real * np.cos(0 * space)

cos1 = fft[1].real * np.cos(1/4 * np.pi * space)
sin1 = fft[1].imag * np.sin(1/4 * np.pi * space)

res = cos0 + cos1 + sin1

plt.scatter(values, x, label="original")
plt.plot(space, cos0, label="cos0")
plt.plot(space, cos1, label="cos1")
plt.plot(space, sin1, label="sin1")
plt.plot(space, res, label="combined")

plt.legend()

В результате я получаю сюжет:

img
(источник: heeser- it.de)

Почему конечная кривая не попадает ни в одну точку?

Я был бы признателен за вашу помощь. Спасибо!

ИЗМЕНИТЬ:

N = 1000
dataPoints = np.linspace(0, np.pi, N)
function = np.sin(dataPoints)
fft = np.fft.fft(function)

F = np.zeros((N,))
for i in range(0, N):
    F[i] = (2 * np.pi * i) / N
F_sin = np.zeros((N,N))
F_cos = np.zeros((N,N))

res = 0
for i in range(0, N):
    F_sin[i] = fft[i].imag / 500 * np.sin(dataPoints * F[i])
    F_cos[i] = fft[i].real / 500* np.cos(dataPoints * F[i])
    res = res + F_sin[i] + F_cos[i] 
plt.plot(dataPoints, function)
plt.plot(dataPoints, res)

мой сюжет выглядит так:

img
(источник: heeser- it.de)

где я терплю неудачу?


person YHc44    schedule 12.08.2018    source источник
comment
Я считаю, что ваш вопрос больше связан с математикой, чем с программированием.   -  person Mixone    schedule 12.08.2018
comment
Я разместил свой код Python в своем исходном сообщении. Может идея?   -  person YHc44    schedule 12.08.2018
comment
Извините, у меня мало опыта в области математики: / Я думаю, было бы лучше, если бы вы ответили на вопрос об обмене математическими стеками.   -  person Mixone    schedule 12.08.2018
comment
Возможный дубликат Как мне получить частоты каждого значения в БПФ?   -  person Spektre    schedule 12.08.2018
comment
Нет, я знаю, как получить частоты. Но когда я хочу построить это, я не получаю хорошего результата   -  person YHc44    schedule 12.08.2018
comment
Я не вижу никакой фазы в вашем sin,cos... (как и atan2(im,re)) для каждой частоты Найквиста...   -  person Spektre    schedule 12.08.2018
comment
поэтому, когда f = 1/2 * sample_f, мне нужно добавить фазу?   -  person YHc44    schedule 12.08.2018
comment
@ YHc44 то, что вы получили, это амплитуда и фаза для каждой синусоидальной волны Найквиста ... поэтому вам нужно суммировать все волны вместе + смещение постоянного тока (первый коэффициент) ... каждая синусоидальная волна имеет форму amplitude*sin(2*PI*t*f + phase0), где t - время, f соответствует Частота Найквиста и phase0=atan2(im,re) и amplitude=sqrt(re*re + im*im)...   -  person Spektre    schedule 12.08.2018
comment
Извините за мои вопросы.. но я не понимаю этого на 100%.. Мои частоты на 8 выборках с частотой дискретизации 1 Гц: [0,125, 0,25, 0,375, 0,5, 0,625, 0,75, 0,875, 1].. верно? Какие частоты относятся к частотам Найквиста? или мне нужно взять эти значения как f в вашей формуле?   -  person YHc44    schedule 12.08.2018
comment
@ YHc44 все они ... используйте 0.125 для второго вывода DFT, 0.25 для третьего и т. д. ... Вы должны добавить 7 синусоид + смещение постоянного тока вместе, чтобы получить свой график ... кстати, добавьте @nick к вашему комментарию, чтобы пользователь nick сайт уведомляет   -  person Spektre    schedule 12.08.2018


Ответы (2)


Ваш тестовый вектор x немного похож на пилообразный, потому что он растет линейно, а затем начинает уменьшаться, но с что несколько точек данных трудно сказать, что это за сигнал. Он имеет бесконечный ряд БПФ, а это означает, что в нем много компонентов более высокой гармонической частоты. Таким образом, чтобы описать его с помощью коэффициентов DTF и приблизиться к исходным точкам, вам придется использовать

  1. более высокая частота дискретизации, чтобы получить информацию о более высоких частотах (вы должны узнать о теореме Найквиста< /а>)
  2. больше точек данных (выборок), чтобы вы могли извлечь более точную информацию о частотах в вашем сигнале) Это означает, что вам нужно иметь больше элементов в массиве «x».

Также вы можете попытаться подобрать более простой сигнал. Как насчет того, чтобы попытаться установить синусоидальный сигнал для запуска? Сгенерируйте 1000 точек данных низкочастотного синуса (1 Гц или один цикл на 1000 выборок), а затем запустите на нем DTF, чтобы проверить, работает ли ваш код.

person nio    schedule 12.08.2018
comment
Что меня смущает, так это то, что когда я ввожу свои 4 образца на planetcalc.com/7543, он вычисляет кривую, которая подходит по всем пунктам. - person YHc44; 12.08.2018
comment
Я отредактировал свой код ниже и проверил его на наличие ошибки с частотой 1 Гц. Пожалуйста, проверьте. Не знаю, может у меня проблемы с пониманием? - person YHc44; 12.08.2018

Есть несколько ошибок:

  • xs, которые вы присвоили исходным значениям, отключены на единицу
  • Частота, которую вы назначили для fft[1], неверна.
  • Неправильно рассчитываются коэффициенты.

Этот работает:

from matplotlib import pyplot as plt
import numpy as np

x = np.array([1,2,4,3])

fft = np.fft.fft(x)

space = np.linspace(0,4,50)
values = np.array([0,1,2,3])

cos0 = fft[0].real * np.cos(0 * space)/4

cos1 = fft[1].real * np.cos(1/2 * np.pi * space)/2
sin1 = -fft[1].imag * np.sin(1/2 * np.pi * space)/2

res = cos0 + cos1 + sin1

plt.scatter(values, x, label="original")
plt.plot(space, cos0, label="cos0")
plt.plot(space, cos1, label="cos1")
plt.plot(space, sin1, label="sin1")
plt.plot(space, res, label="combined")

plt.legend()
plt.show()
person Matt Timmermans    schedule 12.08.2018
comment
Спасибо. Почему вы масштабируете cos0 с 1/4 и cos1/sin1 с 1/2? - person YHc44; 12.08.2018
comment
это действительно 4 для всего: -fft[1].imag/2 на самом деле (fft[3]-fft[1]).imag / 4. Коэффициенты на самом деле не для синусов и косинусов, они для сложных экспонент. fft[1] и fft[3] имеют составляющие синуса и косинуса для одной и той же частоты, которые складываются вместе. - person Matt Timmermans; 12.08.2018