LTSPICE中FFT结束时的垃圾是什么?


8

为什么FFT在高频端出现垃圾?假设我要在LTSPICE中模拟此电路:

原理图

模拟此电路 –使用CircuitLab创建的原理图

LTSPICE正弦和模拟参数为:

SINE(0 1 1K 0 0 0 1000)
.tran 1 startup

然后,我要求LTSPICE给我没有窗口和1,000,000点的FFT: 快速傅立叶变换

最后的垃圾是什么?我希望在1KHz处只出现一个尖峰,而在3KHz处不会再出现一个尖峰,等等。这是否发生在所有FFT上?是什么控制着您从根本上获得的峰值?


您真的可以查明其他频率吗?它们是否恰好都是1 kHz的奇数倍?在这种情况下,某些东西会使您的“完美”正弦失真,看起来更“直角”,这可能只是ltspice在内部使用的数值精度。
MarcusMüller'18

1
我不会看到低于-100dB的声音,而是从三次谐波开始,似乎没有窗口是一个问题
Tony Stewart Sunnyskyguy EE75,2018年

1
可能与波形压缩有关。有关更多详细信息以及如何检查是否存在这种情况,请参见另一个问题。electronics.stackexchange.com/questions/338292/…–
mkeith,

我无法复制此数据,我的LTspice版本希望超过1e6个模拟点才能获得1e6点的FFT,即最大时间步长为1e-6。
大声的声音

您是否需要准峰值来匹配音频频谱以进行调制带宽?
Tony Stewart Sunnyskyguy EE75,2018年

Answers:


4

@ D.Brown的答案已经是一个很好的答案,所以我只添加一些小问题。LTspice的算法是自定义的,并且接受非二乘幂的点。这并不意味着分辨率并不重要。不过,1kHz超过1s意味着周期数是整数,因此无需进行加窗或二项式平滑来降低噪声(在FFT窗口中进行设置)。但是,@ mkeith提到了什么,也就是说,默认情况下,LTspice使用波形压缩(每个显示器300个点,IIRC),这意味着任何其他点都会减少,并且波形的分辨率会受到影响。解决方案是缩短时间步长,或者.option plotwinsize=0最后一个消除波形压缩。添加此选项但不施加时间步时,将发生以下情况:

默认

这大概是您所看到的(或多或少),那么有什么选择呢?您将在1s的时间内模拟1 kHz波形。电路可以说是一个简单的源和负载,并且源是谐波源,这对于矩阵求解器来说是一项轻松的任务,因此LTspice和所有SPICE引擎一样,如果感觉到导数是平滑的,则将加倍其时间步长,以不减慢仿真速度,并且它将一直加倍直到达到某个内部极限,此时它将飞越仿真。结果是一个粗糙的波形,甚至不能改善太多。plotwinsize

现在需要另一种解决方法,即强加的时间步长,以提高分辨率。这是1的时间步的结果:μ

10u

这是更好的,但你执行的是1万点的FFT,这需要,也许并不令人惊讶,100个的时间点,所以最大时间步长应设置为1秒。此外,该选项设置为> 7的值,根据书,它可以实现双精度:μnumdgt

超

噪声本底仍然有些波动,但是现在的水平小于-250dB。这接近于机器精度。将时间步设为1/1048576(2 ^ -20)不会改善结果(您可以自己检查)。

最后,这取决于您愿意接受多少本底噪声。@托尼·斯图尔特(Tony Stewart)的评论具有实际意义,低于100〜120dB意味着小于1〜10 V至1V,这是一个相当大的成就。μ


感谢您为这个答案而努力。顺便说一句,它向我强调了与Windows相比,LTspice在macOS上的性能截然不同。(我假设这是Windows版本)
噪声

@loudnoises是的,尽管在Wine下,但这并不重要。我已经在Yahoo LTspice Group的各处看到了几点,但是由于我不是Mac用户,所以我没有坚持。可能是设置的问题,隐藏在不同的引擎盖下,但实际上,我不确定。
有关的公民

优秀的!现在,回头看一下LTSPICE帮助文件,我应该注意到:“ LTspice使用专有的FFT算法,该算法允许任意数量的数据点,即,不限于2的幂。当您希望进行模拟的FFT时数据,您可能要关闭波形压缩,指定最大时间步长,甚至可能使用双精度波形文件格式来减少数字本底噪声。”
watkipet '18

@一位关心的市民:当您说“这是一个1μs的时间步长的结果”时,您的意思是“这是一个10μs的时间步长的结果”吗?
watkipet '18

@loudnoises我正在使用本机macOS版本。但我确实看到了与@a相关公民相同的结果。
watkipet '18

15

这个答案有几个部分。我将基于FFT算法的特征得出这个答案。我对特定的LTSpice实现并不熟悉,但是您报告的行为恰恰是我所期望的。

最常见的FFT实现以2个数据点的整数幂运算。因此,大多数实现会将您的1,000,000个数据点填充到1,048,576个数据点,并对其进行FFT。请注意,此长度不是正弦波的整数。

还有其他的傅立叶变换方法可以对数据进行不同的分解。这些通常被称为离散傅立叶变换(DFT)方法,并且实现起来既慢又相当复杂。在实际应用中,我几乎从未遇到过它们。FFT是一种特定的DFT实现,它要求数据点的数量为2的整数次幂(或有时为4的整数次幂)。

因此,我假设LTSpice将您的数据填充到1,048,576个数据点,最后添加的48,576个数据值包含一个常量。

现在您可以看到问题了:1,048,576个样本的缓冲区具有1,000个正弦波,每个1,000个样本,后跟48,576个常量。这不能用频率为1kHz的正弦波之和表示。取而代之的是,FFT结果显示了重构信号所需的其他高频值。

若要确定这是否是问题,请创建一个包含1,048,576个样本的缓冲区,其中包含一个带有1,024个周期的正弦波。高频的幅度应大大降低。

现在,关于应用窗口的效果:

FFT算法从概念上“包装”了数据,因此输入数据的最后一点之后是输入数据的第一点。也就是说,FFT的计算就好像数据是无限的一样,循环重复,作为一个向量,其序列为:x [0],x [1],...,x [1048574],x [1048575],x [ 0],x [1],...

这种包装可以导致数据缓冲区中的最后一个点和第一个点之间的逐步过渡。此阶跃转换会产生FFT结果,而FFT结果来自高频。窗口的目的是消除此问题。窗口函数的两端都为零,因此,在您的情况下,w [0]和w [999999]都将为零。当数据乘以窗口时,这些值在开始和结束时都为零,因此在换行时没有步骤转换。

您应用的窗口函数会更改缓冲区的频率内容,您选择的函数会呈现出可接受的折衷。高斯是一个很好的起点。对于无法精确控制数据频率内容的任何实际应用,您将必须应用窗口函数来消除由于数据长度而引起的隐式步进过渡。

残留问题:

FFT中还有另一个潜在的高频频谱噪声源。随着FFT长度的增加,效果会增加,在某些情况下,可能会看到1,000,000个数据点。

FFT算法的内部循环使用复平面中一个圆周围的点:e ^(i * theta),在该算法中,“ theta”从0到2 * pi逐次更精细地迭代,直到FFT。也就是说,如果您在1,048,576个样本上计算FFT,则在外循环的迭代之一中,内循环将计算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)的技术可以消除此问题,但实现起来更复杂。我只需要创建一次这样的实现。


关于DFT与FFT,LTSPICE中的右键单击菜单将其称为“ FFT”,而配置对话框将其称为“ DFFT”。现在,在阅读帮助文件时,我看到@a有关市民提到LTSPICE接受非2的幂的点。
watkipet '18

0

可能的原因:-

当您在模拟器中绘制瞬态波时,它将在实际计算之间进行插值,以最大程度地减少正在进行的工作,并使更快的结果显示在屏幕上。

LTSpice中最大时间步长的默认设置可能是100 us,因此在这些点之间您可以得到插值结果,即它们并不完美,并且会导致失真(在FFT中被视为谐波)。

尝试将最大时间步设置为比当前时间步小得多,然后看看会发生什么。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.