ネットワークアナライザなどのデータをpythonで逆フーリエ変換

pythonのライブラリscipyを使えばフーリエ変換を容易に行うことができます。

フーリエ変換を行って逆フーリエ変換を行うという記事はあったので, ここではまず最初に逆フーリエ変換を行うということを考えた記事を書いていきます。
実験でネットワークアナライザで出てきたデータを逆フーリエ変換したいということがあったのでこれを書いています(実際にはIgorproを使いましたがpythonでも同じようにできるという検証です)。

ネットワークアナライザを逆フーリエ変換する意味は出てきたデータを逆フーリエ変換して時間領域でデータを見ることでケーブルの障害位置などを特定できるのではないかと考えたからです。 時間領域でみてそれに電磁波の速度をかければ障害位置を特定することができるはず!

早速逆フーリエ変換を行う手順です。

ネットワークアナライザの出力するデータ

ネットワークアナライザの出力するデータは周波数, 振幅, 位相 の列からなります。 このままだと逆フーリエ変換できないので振幅Aと位相\phi複素数zにまとめます。

 z = Ae^{i\phi \pi/180}

このときにネットワークアナライザから出力される位相の単位がdegreeなのでrad(ラジアン)に直すことに注意してください。

compData = absData*np.exp(complex(0,1)*phaseData*np.pi/180.0)

フーリエ変換 by scipy

横軸になる時間のデータ

周波数領域から時間領域に移るので横軸になる時間のデータが必要になります。scipyでは逆に周波数を作る関数としてfftfreq()が用意されていますが、その逆は用意されていないので自分で作って置きます。

## 使い方はfftfreqと同じでiffttime(データの数,周波数の幅)
def iffttime(n,df=1.0):
    t= 2*np.arange(n)/(df*2.0*n)
    return t

この関数で作ったデータ(時間)を逆フーリエ変換をプロットするときに横軸として使います。

使うとき

## 周波数を時間に変える
it = iffttime(freq.size,freq[1]-freq[0])

ifft()

フーリエ変換を行う関数はifft()です。引数に入れたデータを逆フーリエ変換して戻り値として返します。

## 逆フーリエ変換
ifftData = ifft(compData)

サンプルデータを適当に用意して逆フーリエ変換しました

サンプルコード by Jupyter

サンプルデータを作るところからのコードの例

ここでは上の逆フーリエ変換をするためのサンプルデータを作るところから全部のコードをnotebookで公開しています。

FFT_IFFTsample/FFT_IFFTsample.ipynb at master · mashiroyuya/FFT_IFFTsample · GitHub

notebookの流れは

  • sin波を重ね合わせて時間領域のサンプルを作って
  • それをフーリエ変換して
  • 振幅と位相に分け, ファイルとして保存(これが逆フーリエ変換ためのサンプルデータ)
  • サンプルデータを上の流れで逆フーリエ変換
  • プロットして元のsin波の重ね合わせと同じかを確認。

これだとフーリエ変換と逆フーリエ変換を両方を練習できます。

まとめ と 注意点

  • pythonFFT or IFFTをするときはspicy.fftpack から関数をインポート
  • 振幅と位相が別々のデータを逆フーリエ変換するときは複素数Ae^{i\phi}にしてから逆フーリエ変換しよう。
  • 横軸の時間を作るには自分で関数iffttimeを作ろう。

注意点というか自分もどちらがいいのかよくわかってはいませんが、

時間領域のデータをフーリエ変換するとf=0(f:周波数)で対称なデータが周波数領域として出てきます。 つまり独立なデータの数は元のデータの数の半分になるわけです。 この複素数のデータをfが0以上の半分だけをとってフーリエ変換しても、元の時間領域のデータをだいたい再現できます。しかし、だいたいと言っているのはデータの数が半分になって再現されます。つまり精度が落ちます(?)。

なので今回のように周波数領域のデータを逆フーリエ変換するときは一旦f=0で対称になるようにデータを拡張してから逆フーリエ変換を行うといいかもしれません。 今回はpythonで作ったサンプルデータなのでもともとf=0で対称でしたのでその処理をしていませんでした。

ネットワークアナライザからの生データは対称になっていないのでf=0で対称にするように拡張することも必要なのかもしれません。