この回答にはいくつかの部分があります。この答えは、FFTアルゴリズムの特性に基づいています。私は特定のLTSpice実装に精通していませんが、あなたが報告する動作はまさに私が期待するものです。
最も一般的なFFT実装は、2の累乗のデータポイントで動作します。したがって、ほとんどの実装では、1,000,000データポイントを1,048,576データポイントにパディングし、その上でFFTを実行します。この長さは正弦波の整数ではないことに注意してください。
データを異なる方法で分解する代替のフーリエ変換メソッドがあります。これらは通常、離散フーリエ変換(DFT)メソッドの名前で呼ばれ、実装が遅く、実装がかなり複雑です。私は実際のアプリケーションでそれらに遭遇したことはほとんどありません。FFTは、データポイントの数が整数の2の累乗(または、整数の4の累乗)である必要がある特定のDFT実装です。
したがって、LTSpiceはデータを1,048,576データポイントにパディングし、最後に追加された48,576データ値は定数を含むと想定しています。
これで問題を確認できます。1,048,576サンプルのバッファーには1,000サンプルの正弦波があり、それぞれ1,000サンプルに続いて48,576の定数値が続きます。これは、周波数1kHzの正弦波の合計では表すことができません。代わりに、FFT結果は、信号を再構築するために必要な追加の高周波値を示します。
これが問題であるかどうかを判断するには、1,024サンプルの周期の正弦波を含む1,048,576サンプルのバッファーを作成します。高周波は大きさが大幅に減少するはずです。
ここで、ウィンドウを適用した効果について:
FFTアルゴリズムはデータを概念的に「ラップ」するため、入力データの最後のポイントの後に入力データの最初のポイントが続きます。つまり、FFTは、データが無限であるかのように計算され、x [0]、x [1]、...、x [1048574]、x [1048575]、x [ 0]、x [1]、...
この折り返しにより、データバッファーの最後のポイントと最初のポイントの間にステップ遷移が生じる可能性があります。このステップ遷移は、高周波からの大きな(偽の)寄与を持つFFT結果を生成します。ウィンドウの目的は、この問題を排除することです。窓関数は両端でゼロになるため、この場合、w [0]とw [999999]は両方ともゼロになります。データがウィンドウで乗算されると、値は最初と最後でゼロになるため、ラップでのステップ遷移はありません。
適用するウィンドウ関数は、バッファーの周波数コンテンツを変更し、許容できるトレードオフを示す関数を選択します。ガウシアンは良い出発点です。データの周波数コンテンツを正確に制御できない実際のアプリケーションでは、ウィンドウ関数を適用して、データ長による暗黙のステップ遷移を排除する必要があります。
残りの問題:
FFTには、別の高周波スペクトルノイズの発生源となる可能性があります。効果はFFTの長さとともに増加し、場合によっては1,000,000データポイントで確認できます。
FFTアルゴリズムの内部ループは、複素平面内の円の周りの点を使用します:e ^(i * theta)、アルゴリズムは 'theta'を0から2 * piまで連続的に細かいステップで反復し、 FFT。つまり、1,048,576サンプルのFFTを計算する場合、外側のループの反復の1つで、内側のループはe ^(i * theta)を計算します。ここで、theta = 2 * pi * n / N、Nは1,048,576です。 、nを0から1,048,575まで繰り返します。これは、e ^(i * 2 * pi / N)を連続的に乗算する明らかな方法で行われます。
Nが大きくなると、e ^(i * 2 * pi / N)が1に非常に近くなり、N倍されます。倍精度浮動小数点を使用すると、エラーは小さくなりますが、注意深く見れば、ノイズフロアの結果がわかると思います。単精度浮動小数点では、1,000,000データポイントでFFT計算自体が大きなノイズフロアを生成します。
この問題を排除するe ^(i * theta)を計算する別の手法がありますが、実装はより複雑です。私はそのような実装を一度だけ作成する必要がありました。