質問: 不規則なデータのfft処理 データサンプリングが不規則なのですが、excelでmacroを使って中間値を補間してフーリエ変換fft処理する方法をお教え頂けないでしょうか? またできればexcelはfftできる最大が4096ですがmacro処理でそれ以上の数でできるようになりませんか?フリーソフトでも構いません。切り貼りは致します。 両方の質問共にでなくても、片側だけでも良いので、お手数おかけしますが、よろしくお願いいたします。
回答: マクロが組めるならば、無理にfftをせずに、dft(離散フーリエ変換)で良いのかと思います。 また、かなり誤解がある(一般にそうだろうと思いますが)ようなので、 少し難しくなりますが、頑張って読んでください。 fftと言う名前は有名ですが、dftと演算結果は同じです。 dftの演算量を減らして高速化したものがfftです。 dftは非常に簡単なループ処理で演算できます。 fftは結構面倒なので、一からプログラムすると大変です。 私はfftのサンプルを手に入れるのが面倒なので、 必要に迫られたときネットで検索してdftの数式を見つけて毎回プログラムしてます。 【これを知っておくと、c言語だろうが、javaだろうが、エクセルだろうが、何でも移植できる】 プログラムも総ライン数で10行くらいでしょうか。 デジタルデータの周波数変換に関してfftを頼る必要は全く無いですよ。 【dftで検索。σ式がすぐ出てきます。つまり数列の和ですね。表計算で簡単に出力できるでしょう】 fftは今から相当昔に開発された手法ですが、コンピュータが遅い時代に重宝しました。 しかし、当時のマイコンでもdftで充分なスピードでしたよ。 今のパソコンのスピードは、当時の1000倍くらいです。 定義をおさらいします。 (1)フーリエ変換 無限数列を前提に処理するもの。周波数変換。 (2)dft サンプリングされたデータを擬似的に周波数変換するもの。厳密に周波数変換ではない。 (3)fft dftと演算結果が同じになるように開発された高速演算アルゴリズム。 アルゴリズム名であり、変換としての用語ではない。直交変換としてはdftが正しい説明。 dftの演算結果を見ると、周期的に、実数と虚数の絶対値が同じものが現れたりする事に着眼。 最初のほうだけdftを行い、途中から虚実を入れ替えたり、符号を変えたりして、 残りの演算結果を生成してしまう手法。 fftが有難いとされていたのは、(3)の説明で分かると思いますが、浮動小数点演算よりも、 符号の入れ替えや、実数部と虚数部の入れ替えの方が早いとされていた時代の話です。 3dポリゴンのゲームなどは、浮動小数点を使った行列演算を物凄いスピードでやっております。 と言うことは、dftとfftの違いにこだわる必要もなくなってきたわけです。 その上で、dftは普通の人でもプログラムできます。正に初心者向け。 次にサンプリング周期が不規則とありますが、これはディジタル信号処理の感覚ではngです。 せめてサンプリングレートを落として、一定周期でサンプリングされていることを保障しましょう。 サンプリングしたタイミングがズレると、歪みの様なノイズが重畳されます。(変調がおきる) さらに、通常のfftの使い方は、周波数積でのフィルタリングです。 この用途の一つとしてデータ補完があります。 インターポレーションというテクニックです。 これにより粗いサンプリングをしたデータの中間値を補完する事ができます。 これは直線補完や二次補完よりも滑らかな補完になり、自然に見える効果があります。 アニメやイラスト画像には向いていませんので、スプラインとか色んな補完が使われます。 しかし、音声や自然画像(写真)の補完では周波数をつかった補完が効果的で重宝されます。 jpegやmpegなどで使われるdctもこれと似た考え方をしています。 つまり、一度圧縮でデータを削っておいて、補完によって復元するわけです。 そのため、 【fftする前に別のアルゴリズムで中間値を補完してしまったら、意味が無いです】 中間値を直線的に案分して補完したり、投影法により補完していたのは相当昔(40年以上前) の話であり、今はdftを使って補完するほう普通です。(特性が良い) また、 dftでは少ないサンプルデータでも大雑把に周波数のカーブを見せてくれるので便利なのです。 例1)サンプルデータは5個しかないが、周波数データは1024サンプル欲しい。 【1024の配列を用意し、先頭5個にサンプルデータを代入。残りに0を入れてdftをする】 これでokです。 例2)データサンプルを補完を使って増やしたい(インターポレーション) 元データ:a、b、c、d、 の4サンプルを例に、データを2倍に増やす方法を説明します。 手順1) a、0、b、0、c、0、d、0 と言う0(ゼロ)を間に挿入したデータを作る。 手順2)dftをかける 手順3)dftデータを見ると、周期的に同じデータ出てくるので2周期目を虚数部含めて 0(ゼロ)で消す a,b,a,b,b,a,b,a 見たいな感じに成るので、a,b,0,0,0,0,b,a に作り直す 手順4)idft(dftの逆変換)をする。これも式が違うだけでdftとほぼ同じ演算方法です。 手順5)idft結果を見て、元のデータと似たような変化を持つ数列になっていることを確認する。 例3)歯抜けデータを補完する 歯抜けになった部分を0として例2と同様の処理をする。 この場合サンプリングレートは半分になります。また完全な復元ではありません。 大雑把に復元できた気分になります。 以上ご参考になれば。