Как добавить фазовый сдвиг к синусоиде в частотной области с помощью fft?

Я хочу сдвинуть синусоидальную волну в частотной области

Моя идея такая:

  1. Преобразование Фурье
  2. Добавить фазовый сдвиг числа пи в частотной области
  3. Обратное преобразование Фурье

В коде:

t=np.arange(0, 6 , 0.001)
values = A*np.sin(t)
ft_values= np.fft.fft(values)
ft_values_phase=ft_values+1j*np.pi
back_again= np.fft.ifft(ft_values_phase)
plt.subplot(211)
plt.plot(t,values)
plt.subplot(212)
plt.plot(t,back_again)

Я ожидал два изображения, в которых одна волна сдвинута на число пи, однако я получил такой результат

(без фазового сдвига):

введите описание изображения здесь

Спасибо за любую помощь!


person Kolibril    schedule 24.07.2019    source источник
comment
Вы масштабировали величину, не применяли фазовый сдвиг. Предлагаю вам еще раз взглянуть на уравнение фазового сдвига.   -  person Cris Luengo    schedule 24.07.2019


Ответы (2)


Вы не сделали сдвиг фазы.

Что вы сделали, так это добавили вектор из 6000, скажем P, с постоянным значением P (i) = j π к V, БПФ из v.

Напишем Ṽ = V + P.

Из-за линейности БПФ (и ОБПФ) то, что вы назвали back_again, является

ṽ = ОБПФ (Ṽ) = ОБПФ (V) + ОБПФ (P) = v + p

где, конечно, p = IFFT (P) - разница values-back_again - теперь давайте проверим, что такое p ...

In [51]: P = np.pi*1j*np.ones(6000) 
    ...: p = np.fft.ifft(P) 
    ...: plt.plot(p.real*10**16, label='real(p)*10**16') 
    ...: plt.plot(p.imag, label='imag(p)') 
    ...: plt.legend();

антитрансформация P

Как видите, вы изменили values, добавив реальный компонент , который по сути является числовым шумом при суммировании ОБПФ (следовательно, никаких изменений в графике, что дает вам реальный < / em> часть back_again) и один воображаемый пик, высота которого неудивительно равна π, для t = 0.

Преобразование константы - это скачок при ω = 0, антитрансформация константы (в частотной области) - это скачок при t = 0.

Как я сказал в удаленном комментарии, если вы не добавляете константу к каждому члену БПФ, а умножаете их на константу, вы также умножаете сигнал на одну и ту же константу (помните, что БПФ и ОБПФ линейны).

Чтобы делать то, что вы хотите, вы должны помнить, что сдвиг во временной области - это просто (круговая) свертка (периодического) сигнала со сдвинутым во времени всплеском, поэтому вам нужно умножить БПФ сигнала на БПФ. смещенного шипа.

Поскольку преобразование Фурье распределения Дирака δ (t-a) равно exp (-iωa), вам необходимо умножить каждый член БПФ сигнала на член, зависящий от частоты.


Пример

Некоторые предварительные мероприятия

In [61]: import matplotlib.pyplot as plt 
    ...: import numpy as np                                                                                           
In [62]: def multiple_formatter(x, pos, den=60, number=np.pi, latex=r'\pi'): 
             ... # search on SO for an implementation
In [63]: def plot(t, x): 
    ...:     fig, ax = plt.subplots() 
    ...:     ax.plot(t, x) 
    ...:     ax.xaxis.set_major_formatter(plt.FuncFormatter(multiple_formatter)) 
    ...:     ax.xaxis.set_major_locator(plt.MultipleLocator(np.pi / 2)) 
    ...:     ax.xaxis.set_minor_locator(plt.MultipleLocator(np.pi / 4)) 

Функция для вычисления дискретного FT распределения Дирака с центром в n за период N

In [64]: def shift(n, N): 
    ...:     s = np.zeros(N) 
    ...:     s[n] = 1.0 
    ...:     return np.fft.fft(s)                                                                                     

Построим сигнал и смещенный сигнал

In [65]: t = np.arange(4096)*np.pi/1024                                                                               
In [66]: v0 = np.sin(t)                                                                                               
In [67]: v1 = np.sin(t-np.pi/4)                                                                                       
In [68]: f, a = plot(t, v0)                                                                                           
In [69]: a.plot(t, v1, label='shifted by $\\pi/4$');                                                                   
In [70]: a.legend();

введите описание изображения здесь

Теперь вычислите БПФ правильного пика (обратите внимание, что π / 4 = (4π) / 16), БПФ сдвинутого сигнала, ОБПФ БПФ с.с. и, наконец, построим наши результаты

In [71]: S = shift(4096//16-1, 4096)                                                                                  
In [72]: VS = np.fft.fft(v0)*S                                                                                        
In [73]: vs = np.fft.ifft(VS)                                                                                         
In [74]: f, ay = plot(t, v0)                                                                                          
In [75]: ay.plot(t, vs.real, label='shifted in frequency domain');                                                    
In [76]: ay.legend();

введите описание изображения здесь

person gboffi    schedule 24.07.2019

Здорово, это помогло! Для тех, кто хочет сделать то же самое, вот он в одном файле Python:


import numpy as np
from matplotlib.pyplot import plot, legend
def shift(n, N): 
    s = np.zeros(N) 
    s[n] = 1.0 
    return np.fft.fft(s)  
t = np.linspace(0, 2*np.pi,1000) 
v0 = np.sin(t)                                                                                               
S = shift(1000//4, 1000)  # shift by pi/4
VS = np.fft.fft(v0)*S 
vs = np.fft.ifft(VS)
plot(t, v0 , label='original' )
plot(t,vs.real,label='shifted in frequency domain')
legend()

введите описание изображения здесь

person Kolibril    schedule 27.07.2019