私はコメントを拡張して、元の例よりも理解しやすい方法で参照する例を作り直し、なぜfft
係数を元の方法で返すのかを説明したいと思います。
参考までに、例のfft部分は次のとおりです。
Nx = size(x,2);
k = 2*pi/(b-a)*[0:Nx/2-1 0 -Nx/2+1:-1];
dFdx = ifft(1i*k.*fft(f));
d2Fdx2 = ifft(-k.^2.*fft(f));
そのすぐ下に別のコードセクションを追加しました。
Nx = size(x,2);
k = 2*pi/(b-a)*(-Nx/2:Nx/2-1);
dFdxp = ifft(ifftshift(1i*k.*fftshift(fft(f))));
d2Fdx2p = ifft(ifftshift(-k.^2.*fftshift(fft(f))));
tic; toc
ラフなタイミングのために、両方のコードをで囲みました。より読みやすい形式では、2番目の方法は次のものを使用します。
ckf = fftshift(fft(f));
ckdf = 1i*k.*ckf;
df = ifft(ifftshift(ckdf));
最初の違いは、2番目の例の方がはるかに直感的であることk
です。これが2番目の例の主な利点です。kは、私たちが考える形になっているからです。2行目と3行目では、fftshift
への呼び出しの前後に追加する必要がありfft
、次にへの呼び出しのifftshift
内部に直接呼び出しますifft
。これらの追加の関数呼び出しは、コンピューターが係数を操作するために必要なものから、人間が通常それらを考える方法まで、係数を並べ替えます。
2番目の例の問題は、k
私たちにとってはより直感的ですが、これにより、fft
あまり有利でない形式で解いたり反転したりするための内部行列が残ることです。だから我々はへの呼び出しで順番を切り替えてどちらかfftswitch
とifftswitch
か、それはハードにコード化する必要があるfft
機能。これはユーザーからのエラーの可能性は低くなります(多くの人がそうであるように、ユーザーがfftの動作に不慣れであると想定します)が、実行時に料金を支払います。
前に述べたように、比較のために2つのブロックの周りにタイミングコールを追加し、複数のNに対して実行しました。タイミングの結果は次のとおりです。
N = 1000, Ex1 = 0.000222 s, Ex2 = 0.007072 s
N = 10000, Ex1 = 0.001576 s, Ex2 = 0.003506 s
N = 100000, Ex1 = 0.023857 s, Ex2 = 0.034051 s
N = 1000000, Ex1 = 0.213816 s, Ex2 = 0.406250 s
N = 10000000, Ex1 = 4.555143 s, Ex2 = 7.102348 s
ご覧のように、値を前後に切り替える動作は、特にNが低い場合(30倍遅い)、プロセスをかなり遅くします。これはほんの一例であり、メモリ速度、プロセッサコア/速度などによって、お使いのコンピュータに若干異なる傾向が見られる場合がありますが、これはポイントの例示です。fft
出力が混乱する理由は、計算時間の重要な部分を節約できるためです。