0

私は実際の信号をリサンプリングしていますが、そのfftを自由rfftに使用できるので、を使用したいと思いますirfft(signal, new_length)。しかし、私はそれを機能させることができないようです。

これは、複雑なfftを使用して長さ4の信号をリサンプリングする実用的なコードスニペットです。

from numpy.fft import fft,ifft
p=array([1.,2.2,4.,1.])
pk=fft(p)
pnew=ifft(pk,8)*(8./4.)

ここで、係数(8./4.)は元の長さから新しい長さに再スケーリングされます。あなたはそれをチェックすることができますpnew[::2]==p

ここで、実際のフーリエ変換で同じ戦略を適用しようとすると、元のポイントで間違った結果が得られます。

from numpy.fft import rfft,irfft
p=array([1.,2.2,4.,1.])
pk=rfft(p)
pnew=irfft(pk,8)*(8./4.)

そして私は持っていpnew[::2]=[ 1.45, 1.75, 4.45, 0.55]!=pます。

誰かが何が起こっているのかについての手がかりを持っていますか?scipyのルーチンを使用してみましたが、同じ結果になりました。ドキュメント自体で、これを行う方法について簡単に説明しています。ページの下部にあるここを参照してください。

4

1 に答える 1

1

あなたが好きなドキュメントには次のように書かれています:

In other words, irfft(rfft(a), len(a)) == a to within numerical accuracy.

あなたがそうするなら、これは当てはまりませんirfft(pk, 8)!問題は、パディングに加えて、奇妙なサンプルとフーリエ変換の対称性によるものです。len(p)が奇数の場合はまったく問題ないことに注意してください。

理解を深めるために、次のことを考慮してください。

>>> p = np.array([1.,2.2,4.,1.])
>>> np.fft.fft(p)
array([ 8.2+0.j , -3.0-1.2j,  1.8+0.j , -3.0+1.2j])
>>> np.fft.fftfreq(len(p))
array([ 0.  ,  0.25, -0.5 , -0.25]) # 0.5 only occurs once negative
>>> np.fft.rfft(p)
array([ 8.2+0.j , -3.0-1.2j,  1.8+0.j ])
>>> np.fft.rfftfreq(len(p)) # (not available in numpy 1.6.)
array([ 0.  ,  0.25,  0.5 ]) # 0.5 occurs, here positive, it does not matter

# also consider the odd length FFT
>>> np.fft.fftfreq(len(p)+1)
array([ 0. ,  0.2,  0.4, -0.4, -0.2]) # 0.4 is in there twice.

# And consider that this gives the result you expect:
>>> symmetric_p = np.fft.rfft(p)
>>> symmetric_p[-1] /= 2
>>> np.fft.irfft(symmetric_p, 8)[::2]*(8./4.)
array([ 1. ,  2.2,  4. ,  1. ])

つまり、よく見ると。入力サンプルが偶数の場合、計算された FFT 周波数は対称ではなく、代わりに余分な負の周波数があります (常に位相シフトがないため、実際には正の周波数である可能性があります)。

別の周波数にパディングしているため (本当の理由はありませんか?)、RFFT は突然、この周波数に対して余分な「余裕」を持ちます。したがって、FFT の観点から見ると、通常は 1 回だけ発生する負の周波数を正の周波数として追加します (これは基本的に 2 倍になることを意味します)。半分以上を見ると、symmetric_pこの頻度はパディングで期待される結果をもたらします (パディングなしでは期待される結果は得られません)。

于 2012-12-10T14:03:35.477 に答える