2016-08-07 4 views
2

numpy의 고속 푸리에 변환 구현에 어려움을 겪고 있습니다. 내 신호는주기적인 성격이 아니기 때문에 이상적인 후보는 아니지만 FFT의 결과는 내가 기대했던 것과는 거리가 멀다. 그것은 동일한 신호이며, 단순히 어떤 요인에 의해 뻗어 있습니다.numpy의 빠른 푸리에 변환으로 인해 예상치 못한 결과가 발생합니다.

import numpy as np 
from matplotlib import pyplot as plt 

signal = array([[ 0.], [ 0.1667557 ], [ 0.31103874], [ 0.44339886], [ 0.50747922], 
    [ 0.47848347], [ 0.64544846], [ 0.67861755], [ 0.69268326], [ 0.71581176], 
    [ 0.726552 ], [ 0.75032795], [ 0.77133769], [ 0.77379966], [ 0.80519187], 
    [ 0.78756476], [ 0.84179849], [ 0.85406538], [ 0.82852684], [ 0.87172407], 
    [ 0.9055542 ], [ 0.90563205], [ 0.92073452], [ 0.91178145], [ 0.8795554 ], 
    [ 0.89155587], [ 0.87965686], [ 0.91819571], [ 0.95774404], [ 0.95432073], 
    [ 0.96326252], [ 0.99480947], [ 0.94754962], [ 0.9818627 ], [ 0.9804966 ], 
    [ 1.], [ 0.99919711], [ 0.97202208], [ 0.99065786], [ 0.90567128], 
    [ 0.94300558], [ 0.89839004], [ 0.87312245], [ 0.86288378], [ 0.87301008], 
    [ 0.78184963], [ 0.73774451], [ 0.7450479 ], [ 0.67291666], [ 0.63518575], 
    [ 0.57036157], [ 0.5709147 ], [ 0.63079811], [ 0.61821523], [ 0.49526048], 
    [ 0.4434457 ], [ 0.29746173], [ 0.13024641], [ 0.17631683], [ 0.08590552]]) 

sinus = np.sin(np.linspace(0, np.pi, 60)) 

plt.plot(signal) 
plt.plot(sinus) 

파란색 라인 내 신호, 녹색 선은 동입니다 : 내가 제대로 FFT 기능을 사용하는 것이, 설명해야하는 그 옆에 내 신호를 근사, 부비동 곡선을 꾸몄다.

raw.pdf

transformed_signal = abs(np.fft.fft(signal)[:30]/len(signal)) 
transformed_sinus = abs(np.fft.fft(sinus)[:30]/len(sinus)) 

plt.plot(transformed_signal) 
plt.plot(transformed_sinus) 

파란색 선이 transformed_signal입니다

는 녹색 선은 transformed_sinus입니다.

enter image description here

사람이 여기에 무슨 일인지를 설명 할 수 :

fft.pdf

transformed_signal이 동작은 위에서 설명한 보여줍니다 음모를 꾸미고?

UPDATE는

나는 참으로 FFT를 호출의 문제였다. 이것은 올바른 전화 및 올바른 결과입니다 :

transformed_signal = abs(np.fft.fft(signal,axis=0)[:30]/len(signal)) 

enter image description here

답변

3

Numpy의 fft은 기본적으로 행에 적용됩니다. signal 변수가 열 벡터이기 때문에 하나의 요소로 구성된 행에 fft이 적용되고 각 요소의 1 포인트 FFT가 반환됩니다.

transformed_signal = abs(np.fft.fft(signal,axis=0)[:30]/len(signal)) 
+0

또는 signal이 1D 벡터가되도록하려는 경우'np.array ([signal in x]에 대해 [x [0])와 같은 것으로 변환하십시오.)' – mtrw

1

내가 스텔 리오스에 의해 언급 된 중요한 일을 간과 [편집]! 그럼에도 불구하고 나는 내 대답을 남겨두고있다. 문제의 근본 원인을 발견하지는 못했지만, 여전히 사실이며 유용한 FFT를 고려해야한다.

당신이 비주기적인 신호를 tranforming한다고. 신호에는 FFT에 멋지게 나타나는 잔물결 (고조파)이 있습니다. 사인은 훨씬 낮은 주파수를 가지며 대부분 DC 성분으로 구성됩니다.

지금까지 그렇게 좋았습니다. 내가 이해하지 못하는 것은 여러분의 신호에도 DC 성분이 있다는 것인데, 이것은 전혀 나타나지 않습니다. 이것이 규모의 문제 일 수 있습니다.

코어는 부비동과 신호가 완전히 같아 보이지만 완전히 다른 고조파 성분을 가지고 있습니다.

가장 주목할만한 점은 모두 절반 부비동에 해당하는 빈도를 보유하고 있지 않습니다. 이것은 '반 동성체'가 전체 sinusses을 합산하여 만들어지지 않기 때문입니다. 다른 말로하면, 아래에있는 전체 정현파는 반수 이상에 해당하는 부비동의 스펙트럼 내용이 아닙니다.

오직 60 개의 샘플을 가지고있는 BTW는 샘플 빈도가 신호 주파수의 두 배 이상이어야합니다. 그렇지 않으면 앨리어싱이 발생합니다 (주파수를 잘못된 위치로 매핑). 즉, 신호가 샘플링 후 시각적으로 부드럽게 나타나야합니다 (당연히 불연속이거나 블록 또는 삼각형 파처럼 불연속 파생물이없는 경우). 그러나 당신의 경우에 날카로운 봉우리가 언더 샘플링의 인공물 인 것처럼 보입니다.

+0

나는 FFT 아주 새로운 해요 완전히 답을 이해하지 않는다, 당신은 즉, FFT는 signal의 컬럼을 통해 적용할지 지정 fft의 축 옵션을 사용합니다. 나는 신호가 FFT와 완전히 다르게 보이므로 완전히 다른 결과를 만들어 낼 것이라는 것을 이해한다. 그러나 나는 당신이 DC 구성 요소로 무엇을 의미하는지 확신하지 못합니다. 왜 그게 있어야한다고 생각하니? 그리고이 가능한 규모의 문제를 완화하기 위해 당신은 무엇을 제안하겠습니까? 앨리어싱을 설명하기 위해 더 긴 신호를 찾으려고 노력할 것입니다. – Paul

+0

@Paul Jacques는 [Nyquist-Shannon sampling theorem] (https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem)을 언급하고 있습니다. 샘플링 주파수는 캡처하려는 신호의 가장 높은 주파수 구성 요소의 주파수의 두 배가되어야합니다. –

+0

표시 : 감지하고자하는 가장 낮은 주파수에서 최소 20 개의 전체 기간을 사용하고 가장 높은 주파수의 전체 기간에 최소 2 개의 샘플을 사용하십시오. 그리고 신호의 불연속성과 파생물을 방지하기 위해 시작과 끝에서 신호를 점차적으로 감쇠하십시오 (따라서 파생물이 점프를하기 때문에 0으로 절단하면 작동하지 않습니다). –

관련 문제