• ベストアンサー

フーリエ変換(DFT)

現在、音響関係興味をもち、いろいろと勉強してるのですが、 フーリエ変換(DFT)を用いて、100Hzのsin波を1KHzでサンプリングするとは どういう意味なんでしょうか?どなたか教えて頂けませんか?

質問者が選んだベストアンサー

  • ベストアンサー
  • wolv
  • ベストアンサー率37% (376/1001)
回答No.8

「回答No4.」の「回答に対する補足」に対する回答: 今適当に作ったので,積分範囲と積分の刻み幅は まちがっているかもしれませんが, だいたいこんな感じになります.(よね?) データは配列として用意してください. なお,見易さ優先で行頭に全角の空白を使っているので, このままコンパイルするとエラーが出るかもしれません. ------------------------------------------------------------ /* 入力:data[i], i=0..(n-1) 出力:ws[f], wc[f] */ dft(int n, float *data, float *ws, float *wc){   int f, t;   for(f=0;f<=n;f++){     ws[i] = wc[i] = 0     for(t=0;t<n;t++){       ws[i] += sin(2*PI*f*t) * data[t];       wc[i] += cos(2*PI*f*t) * data[t];     }   } }

makayuki
質問者

お礼

ありがとうございます。 wolvさんに教えて頂いたプログラムを参考に組んでみると 予想通りの結果になりました。

その他の回答 (7)

  • republiky
  • ベストアンサー率50% (7/14)
回答No.7

FFTのプログラムは少々面倒ですが、DFTのプログラム は非常に簡単です。わずか数行で出来てしまいますの で、難しいことはありません(定義式をそのまま計算 すればいいのです)。ぜひ、トライしてください。 Cでは複素数の変数型はありませんので、実部と虚部に 分けて計算する(つまり、実部の実数型変数、虚部の 実数型変数、二つの変数を定義してそれぞれ計算す る)ことに注意してください。つまり、 exp(jx) = cos(x) + j*sin(x) と分解して考えましょう。Σの計算はforループを使え ば良いのです。その結果、nobouさんの計算どおり、 デルタ関数のピークが出てきます。 スペクトルの結果を表示する際は、振幅と位相にわけ てグラフを表示すると見やすくなります。 目盛りの読み方も大事なので、ここで書きたいところ ですが、説明が長くなってしまいますので、割愛しま す。とりあえずプログラムを作ってみて、結果を考察 してみてはいかがでしょう?

makayuki
質問者

お礼

ありがとうございました。 プログラムを組んでみたら、案外、簡単に作ることができました。

  • nubou
  • ベストアンサー率22% (116/506)
回答No.6

・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ =(δ(f-f0)-δ(f+f0))・A/2/j ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ =Σ(-∞<k<∞)・ (δ(f-k・fs-f0)-δ(f-k・fs+f0))・fs・A/2/j

makayuki
質問者

お礼

詳しい計算ありがとうございます。 この計算をもとにDFTのプログラムを組んで見ます。

  • nubou
  • ベストアンサー率22% (116/506)
回答No.5

一応FTを計算しておきましょう g(t)のフーリエ変換をG(f)とすると G(f)≡∫(-∞<t<∞)dt・g(t)・exp(-j・2・π・f・t) です g(t)=A・sin(2・π・f0・t) であれば G(f)≡∫(-∞<t<∞)dt・g(t)・exp(-j・2・π・f・t) =∫(-∞<t<∞)dt・A・sin(2・π・f0・t)・exp(-j・2・π・f・t) =∫(-∞<t<∞)dt・ A・(exp(-j・2・π・(f-f0)・t)-exp(-j・2・π・(f+f0)・t))/2/j =(δ(f-f0)+δ(f+f0))・A/2/j 次に gs(t)=Σ(-∞<n<∞)・g(t)・δ(t-n/fs) としgs(t)のフーリエ変換をGs(f)とすると Gs(f)≡∫(-∞<t<∞)dt・gs(t)・exp(-j・2・π・f・t) =Σ(-∞<n<∞)・g(n/fs)・exp(-j・2・π・f・n/fs) =fs・Σ(-∞<k<∞)・G(f-k・fs) =Σ(-∞<k<∞)・ (δ(f-k・fs-f0)+δ(f-k・fs+f0))・fs・A/2/j です

  • republiky
  • ベストアンサー率50% (7/14)
回答No.4

さらにかいつまんで。 ・「100Hzのsin波」とは、1秒間で100周期の正弦波。 ・「1kHzでサンプリング」とは、一秒あたり1000個の  点で波形を表す(近似する?)こと。 もともとの正弦波をx(t)=sin(2*PI*f*t)とします。 それをT=1/1000秒ごとに正弦波の値を拾っていきま す。当然ながら、Tの値が小さいほど(サンプリング 周波数が高いほど)正弦波を正しく表すことができ ます。 式で表すと、時刻がt=n*T (n=1,2,..,N-1)のときに xの値を拾っていきます。 したがって正弦波は、x(n*T)=sin(2*PI*f*n*T), n=0,1,2,3,...,N-1というN個の値で表されます。 たとえば、2秒間計測するのであればN=2000、10秒間 計測するのであればN=10000となります。逆にN=1024 として計測するのであれば、時間は1.024秒かかりま す。 このx(n*T)をDFTのアルゴリズムで計算すると(離散) スペクトルが得られます。 すでに回答がありましたが、x(t)のスペクトルを得る のは、通常いわれているフーリエ変換(フーリエ積分) です。これはあくまで理想的な変換式なので、コンピ ュータでは計算できません。そこで、DFTが誕生したわ けです。 蛇足ですが、DFTのアルゴリズムに工夫を加えて計算速 度を上げたものをFFT(高速フーリエ変換)といいま す。計算結果はどちらも同じです。 かいつまんで書くつもりが長くなってしまいました…

makayuki
質問者

補足

とても詳しい説明ありがとうございます。 勉強になりました。 このような計算(サンプリング周波数は1KHzとして、100Hzのsin波をフーリエ変換DFTする。 )をC言語で計算することは可能でしょうか? また、どんなプログラムを組むと、計算できるのでしょうか? いろいろと質問してしまって申し訳ないですが、よろしくお願いいたします。

  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.3

すでに、お答えは出ているようですが、かいつまんで。 質問に対する回答は、「離散フーリエ変換(DFT)を用いる際、100Hzのsin波を1KHzでサンプリングした」と言うことだと思います。 フーリエ変換は時間変化の波形を周波数分析する事ですが、アナログ的にやるのがフーリエ変換、ディジタル的にやるのが離散フーリエ変換です。 参考URLにもあるとおり、「分析したい波に含まれる最高周波数の2倍以上の周波数でサンプリングすれば、もとの波は完全に再現できる」(シャノンのサンプリング定理)ということを利用してディジタル的に行なっているのが離散フーリエ変換です。100Hzのsin波が純粋なものか歪波なのか判りませんが、400Hzまでの高調波が含まれていても再現可能であるといえます。(500Hzは限界で微妙)

参考URL:
http://ziong.cs.kobe-u.ac.jp/~inamoto/TA/spectrum/2001/Nov20/Nov20node1.html
  • nubou
  • ベストアンサー率22% (116/506)
回答No.2

DFTは離散フーリエ変換でありフーリエ変換ではない フーリエ変換はFTである 振幅A周波数f0の正弦波は g(t)=A・sin(2・π・f0・t) である これを周波数fsのサンプリング周波数でサンプリングした信号は gs(t)=Σ(-∞<n<∞)・g(t)・δ(t-n/fs+τ) である t=0をづらしてτは扱いやすいように0にすることが多い すなわち gs(t)=Σ(-∞<n<∞)・g(t)・δ(t-n/fs) 質問ではf0=100[Hz],fs=1[kHz]である なおデルタ関数に当惑されるかも知れないがこれは連続時間信号と離散時間信号を扱いやすいようにするために現れたものである 要するにサンプリングとは ・・・,f(-3/fs),f(-2/fs),f(-1/fs),f(0/fs),f(1/fs),f(2/fs),f(3/fs),・・・ 以外の関数値を捨てるということである

  • wolv
  • ベストアンサー率37% (376/1001)
回答No.1

「フーリエ変換(DFT)を用いて、100Hzのsin波を1KHzでサンプリングする」とは 「100Hzのsin波を1KHzでサンプリングして,フーリエ変換(DFT)する」 という意味だと思います.言い換えると, 「ある波(実は100Hzのsin波)をフーリエ変換(DFT)する. その際の,サンプリング周波数は1KHzとする.」 ですね. -------------------------------- たぶん,上のような回答を求めているのではないですね. フーリエ変換の意味は知っていますか? 100Hz,1KHzなどのあらわす意味は知っていますか? サンプリングの意味は知っていますか? DFTの意味は知っていますか? はじめの二つは調べればわかる,または,知っていると仮定すると……. -------------------------------- サンプリングの意味 この場合,「1KHz(1秒に1000回)入力値を測定して, DFTに用いる」という意味になります. DFTの意味 Dは離散(descrete)のDです. フーリエ変換自体は「連続関数を積分を用いて変換するもの」(やや自信なし) ですが,DFTでは「微小時間ごとの関数の値」という離散的な値を使って 和(Σ)によって変換します. サンプリングの例 周波数1/16 (波長16)の波 (を周波数1で 周波数1/2で… 周波数1/17で… サンプリング) -----*-----00 -----*-----00 -----*-----000 -----+*----01 -----+-*---02 -----+*----017 -----+-*---02 -----+--*--04 -----+-*---034 -----+--*--03 -----+-*---06 -----+--*--051 -----+--*--04 -----*-----08 -----+--*--058 -----+--*--05 ---*-+-----00 -----+--*--075 -----+-*---06 --*--+-----12 -----+-*---092 -----+*----07 ---*-+-----14 -----+*----099 -----*-----08 -----*-----16 -----*-----116 ----*+-----09 -----+-*---18 ----*+-----133 ---*-+-----10 -----+--*--20 ---*-+-----130 --*--+-----11 -----+-*---22 --*--+-----157 --*--+-----12 -----*-----24 --*--+-----174 --*--+-----13 ---*-+-----26 --*--+-----191 ---*-+-----14 --*--+-----28 ---*-+-----198 ----*+-----15 ---*-+-----30 ----*+-----215 -----*-----16 -----*-----32 -----*-----232 サンプリング周波数が大きければ大きいほど, 元の音のデータを多く使うので, 元のデータをよく表す変換後のデータが得られます. ただし,データ数が多いので,計算が大変になります. 逆に, サンプリングレートがもとの波の周波数よりもだいぶ小さい場合 (元の波の1/2波長よりも波長が長くなる場合)(図右), 元の波を再現することはできなくなります. (やや自信なし) 図右はじの例では,波長232(周波数1/232)の波に対応する 変換結果が得られてしまいます. この辺のことから感覚的にわからないでしょうか. -------------------------------- 系統だった勉強をしたり,誰かに教えてもらったわけではないので, 説明するのは下手なようです……. どこがわからないのかわからないと,説明が難しい.

makayuki
質問者

お礼

わからなかった事が大体理解することができました。 ありがとうございます。

makayuki
質問者

補足

そうです、100Hzのsin波をフーリエ変換(DFT)する. その際の,サンプリング周波数は1KHzとする. 言いたかったことは、まさにそういうことです。 説明が悪くてすみません。

関連するQ&A

  • フーリエ変換のスペクトルについて

    趣味で音の勉強をしている高校2年です。 離散化されたサンプル数Nの音データ(サンプリング周波数はkHz)をフーリエ変換(DFT)すると、N個のデータが取れると聞きました。 このN個のデータをスペクトルとして表示する場合、横軸はどのような値になるのですか? 0(Hz)~N(Hz)になるのでしょうか。

  • 離散フーリエ変換(DFT)について。

    離散フーリエ変換(DFT)について。 次の有限長N=4のディジタル信号の離散フーリエ変換(DFT)の周波数スペクトルを求めよ。[F[0],F[1],F[2],F[3]]=[-1,1,-1,2] について。 算出した所、 DFTは F[0]=1 F[1]=j F[2]=-5 F[3]=-jと算出できましたが正解でしょうか。 よろしくお願いいたします。

  • CUDAでの離散フーリエ変換(DFT)を教えてください。

    CUDAでの離散フーリエ変換(DFT)を教えてください。

  • フーリエ変換を用いた画像処理_DFT,FFT

    こんにちは,私は現在フーリエ変換を勉強しておりまして,2次元高速フーリエ変換のプログラムを作成してみました.確認のため,フーリエ変換後のデータを逆変換して,元データの再構成を試みたところ,データが上下左右反転していることがわかりました.とあるネット上の解説では,「DFTを行うと上下左右が反転することがある…」と見かけたのですが,その情報も少なく,こちらとしては納得のいく解釈にはつながりません.どなたかなぜ逆変換時のデータが上下左右反転してしまっているのかわかる方はいらっしゃいませんか.

  • フーリエ変換の振幅について教えてください。

    エクセルアドインを使って下記サイン波をフーリエ変換しました。 振幅3mm、周波数4Hz、サンプリング周波数256Hzの波形であり、 つまり、フーリエ変換したい波形は3×SIN(2×PI()×4)です。 アドインでフーリエ変換を行い、出てきた複素数の絶対値つまり√(実部^2+虚部^2)を計算すると3を示すと思っていたのですが、実際は周波数4Hzで384 という値になりました。 周波数分析して周波数4Hz時の振幅が3となるようにするには振幅はどう計算すればよいのでしょうか?またいろいろな振幅や周波数の混ざったランダム波でも各周波数での振幅を求めるにはどう計算したらよいのでしょうか?素人ですが教えてください。

  • サンプリングを高くするほどフーリエ変換値がずれる?

    ある周波数解析ソフトで「フーリエ変換」釦があるのですが、サンプリング周波数を高くするほど、フーリエ変換値がずれてしまいます。 (例)60Hzの正弦波のみの1s間の波形を「フーリエ変換」釦を押すと、 (1)サンプリング周期(10ms)→ 50.5Hz、 52.5Hz、 76.5Hz、の順でピーク点 (2)   〃    (1.0ms)→ 62.5Hz がピーク点。 (3)   〃    (0.1ms)→ 98.5Hz が 〃 (4)   〃   (0.001ms)→  0.0Hz が 〃 となり、周波数ピーク点が60Hzに合いません。このように大きくずれてしまうものでしょうか? なお、同ソフトで「フーリエ級数展開」釦では特定区間指定でき、60Hzの「1次」のみに表示されるのですが、「フーリエ変換」機能には、区間指定釦がありません。 詳しい説明書きはないのですが、通常そのような使い方となるものでしょうか?

  • 高速フーリエ変換の標本点数について教えてください

    最近フーリエ変換を勉強し始めた者です。 自分の理解が合っているのかとても不安なので、ぜひともお知恵を頂戴したくお願いいたします。 CDのようにサンプリング周波数が44100Hzの場合、フーリエ変換の際の標本点数(データ数)が4096だと、4096 / 44100 = 0.1秒弱分しかそのCDの曲をフーリエ変換できないという理解で合っているのでしょうか。 合っている場合、たとえば5分程度の曲をフーリエ変換するためには、 5min * 60s * 44100Hz = 13,230,000点の標本点数についてフーリエ変換しなければならないという理解で合っているでしょうか。 恐れ入りますが、よろしくお願いいたします。

  • Sin波をAD変換ボードを通してAD変換したときの波形図。

    Sin波をAD変換ボードを通してAD変換したときの波形図。 AD変換ボードの操作に慣れようと思って、周波数発信機を用いて60Hz、600Hz、6kHz、60kHz、600kHzのsin波を測定しているのですが、60Hz、6kHzのときは、きれいなsin波が測定できるのですが、それ以外の周波数の場合には、sin波が測定できません。一応サンプリング周波数を変えてやってみたのですが、それでもダメでした。60Hzと6kHzの測定はサンプリング周波数1000Hzで取ることができました。こんな現象が起きるのにはサンプリング周波数以外にも何か理由があるのでしょうか? なお、供給する電圧は、2~3V程度の信号を使用しています。 使用しているAD変換ボード:分解能16bit、最高サンプリング速度100kSPS、バイポーラ:±10V 添付図は、電圧は違いますが同じ回路を使用した場合の60Hzと600Hzの波形です。

  • 離散フーリエ変換

    フーリエ変換を計算機で扱う場合について聞きたいです。 ある関数(例えばsin(x))を離散フーリエ変換しようとして、まずxを0.1ずつ増やしながらsin(x)をサンプリングします。これを虚部を0として複素数にします。 この後、複素数のフーリエ変換を行い結果が得られます。 と、ここまでは正しいと思うのですが、 その後が分かりません。 文献などに載っているフーリエ変換後のグラフは、横軸が周波数νで、縦軸がf(ν)です。 このグラフと合うようにするには 横軸・縦軸には何をとればいいのでしょうか? 横軸が周波数って言うのは、この場合は1/0.1のことでしょうか? 教えて頂きたいです。お願いします。

  • ある時間関数を離散フーリエ変換して得られるフーリエスペクトルの振幅値に

    ある時間関数を離散フーリエ変換して得られるフーリエスペクトルの振幅値について教えて下さい。 今想定している離散フーリエ変換の式は一般的なもので Σ(k=0~N-1) f(k)exp(-2πkni/N) を考えています。 また、離散フーリエ変換して得られるスペクトルは √(Re^2+Im^2) で計算します。 離散フーリエ変換を適用する関数を、 振幅1の直流、及び振幅1で周波数5[Hz]の正弦波とします。 (この2つの信号は別々の信号で合成されていません。) サンプリング周波数を20[Hz]とした場合、サンプリングして得られるデータ列はそれぞれ、 直流: 「1, 1, 1, 1」 正弦波: 「0, 1, 0, -1」 となると想定されます。 (正弦波をサンプリングする場合は位相が関わってきますが、今回は気にしないで下さい。) このデータ列に対して上記の離散フーリエ変換を適用した場合、 得られるフーリエスペクトルの振幅値はそれぞれ、 直流: 「4」(直流のフーリエスペクトルの振幅値値) 正弦波: 「2」(5[Hz]のフーリエスペクトルの振幅値) となります。 (データ点数は上の通り4点) ここで質問なのですが、 離散フーリエ変換して得られるスペクトルの振幅値から元の関数の振幅値を求める場合、 フーリエスペクトルをサンプリングの総データ点数で割ることは数学的に納得できます。 しかしこの例の場合、フーリエスペクトルを総データ点数で割ると、 直流: 「4 -> 1」 正弦波: 「2 -> 0.5」 となってしまい、直流は正しいのですが、正弦波の元の振幅値を正確に求めることは出来ません。 この例の場合、フーリエスペクトルの振幅値から正弦波の振幅値を正しく求めるには、 「フーリエスペクトルの振幅値*2/データ点数」 としてやらなければいけません。 上記のことに関して、なぜこのようになるのかを(2をかける理由を)教えて頂けないでしょうか。 当方、数学についてはあまり詳しくないため、簡単に説明して頂けると幸いです。