質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
MATLAB

MATLABはMathWorksで開発された数値計算や数値の視覚化のための高水準の対話型プログラミング環境です。

Q&A

1回答

1515閲覧

FFTコードを用いない高速フーリエ変換(MATLAB)

moo2

総合スコア0

MATLAB

MATLABはMathWorksで開発された数値計算や数値の視覚化のための高水準の対話型プログラミング環境です。

0グッド

0クリップ

投稿2020/11/10 11:06

編集2020/11/10 11:23

前提・実現したいこと

FFTコードを用いない高速フーリエ変換を試みております.
作成したコードが正しいか確認したいのですが周囲に聞ける方がいません.

発生している問題・エラーメッセージ

要求された 262144x262144 (512.0GB) 配列は、最大配列サイズの設定を超えています。この制限より大きい配列を作成すると、処理に時間がかかり、MATLAB が反応しなくなることがあります。詳細については、配列サイズの制限または設定パネルを参照してください。

該当のソースコード

Fs = 5000; ``` > % サンプリング周波数は5000Hz

N = 2^18;

i = (0 : N-1);

C = zeros(N,1);

for k = 0 : 1: N-1
ex = exp(complex(0,-(2*pi/N)ki))';

  

C(k+1,1) = 1/N * sum(cur1.*ex);
end

>% 離散フーリエ変換を実行, cur1は測定で得られた電流値                            ### 試したこと 直接法を用いた計算(k*i行列)をしたところメモリ不足で計算できなかったため for-endを使ったコード作成を試みました. ### 補足情報(FW/ツールのバージョンなど) MATLAB2018aを使用しています.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2020/11/10 11:10

このままではコードが読めないので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
moo2

2020/11/10 11:23

ご指摘ありがとうございます。 編集いたしました。
guest

回答1

0

最初にこの回答の注意点ですが,私はMatlabを持っていないので
FreeMatというMatlabモドキのアプリで確認しています。
したがって,本家のMatlabでは違うかもしれません。

まずは,関数にして少ないデータ数でfftと結果を比較すればいいと思います。
質問者のコードを忠実に関数にすると,次のような感じでしょうか?
なお,引数xのサイズは (N, 1)と仮定します。

matlab

1function C = mydft(x) 2 N = size(x)(1); 3 i = 0:(N-1); 4 C = zeros(N, 1); 5 for k = 0:1:(N-1) 6 C(k+1, 1) = 1/N * exp(complex(0, -(2 * pi / N) * k * i)) * x; 7 end 8end

これを適当なデータに入れてみます。

--> test_in = [1,2,3,4,5]' test_in = 1 2 3 4 5 --> fft(test_in) ans = 15.0000 + 0.0000i -2.5000 + 3.4410i -2.5000 + 0.8123i -2.5000 - 0.8123i -2.5000 - 3.4410i --> mydft(test_in) ans = 3.0000 + 0.0000i -0.5000 + 0.6882i -0.5000 + 0.1625i -0.5000 - 0.1625i -0.5000 - 0.6882i -->

忠実にfftを再現するなら,1/Nはいらなそうです。
また,ついでにサイズを(1, N), (N, 1)の両対応にします。

matlab

1function C = mydft(x) 2 sz = size(x); 3 if sz(2) == 1 4 N = sz(1); 5 i = 0:(N-1); 6 C = zeros(N, 1); 7 for k = 0:1:(N-1) 8 C(k+1, 1) = exp(complex(0, -(2 * pi / N) * k * i)) * x; 9 end 10 elseif sz(1) == 1 11 N = sz(2); 12 i = (0:(N-1))'; 13 C = zeros(1, N); 14 for k = 0:1:(N-1) 15 C(1, k+1) = x * exp(complex(0, -(2 * pi / N) * k * i)); 16 end 17 else 18 C = [] 19 end 20end
--> mydft(x_in) ans = 15.0000 + 0.0000i -2.5000 + 3.4410i -2.5000 + 0.8123i -2.5000 - 0.8123i -2.5000 - 3.4410i --> fft(x_in') - mydft(x_in') ans = 1.0e-15 * 0 0.8882 - 0.4441i 0.0000 + 1.2212i -0.8882 + 1.4433i -3.5527 + 1.7764i -->

誤差が1.0e-14程度なので,まぁ精度としては十分でしょうか?
表示等で規格化するには,mydft(x) / Nmydft(x) * 2 / Nmydft(x) * sqrt(2) / N等の後処理が必要です。

投稿2023/10/19 12:17

ujimushi_sradjp

総合スコア2152

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問