Engee 文档
Notebook

MATLABEngee 在频谱和时频分析任务中的比较

比较 MATLABEngee 在频谱分析和时频分析领域的功能,让我们来看看它们在正反傅立叶变换和时频分析这两项任务中的能力和方法。

让我们设置一个随机输入信号。

In [ ]:
Pkg.add(["DSP"])
   Resolving package versions...
   Installed MPItrampoline_jll ── v5.5.2+0
   Installed IntervalArithmetic ─ v0.22.23
   Installed Documenter ───────── v1.8.1
  No Changes to `~/.project/Project.toml`
  No Changes to `~/.project/Manifest.toml`
In [ ]:
x_in = randn(300)
plot(x_in)
Out[0]:

傅立叶频谱变换(FFT 和 IFFT)

恩格**使用 FFTW 软件包中的函数:

  1. fft:直接快速傅立叶变换。
  2. ifft:反傅立叶变换。
In [ ]:
using FFTW

# Прямое преобразование Фурье
X = fft(x_in)

# Обратное преобразование Фурье
x_e = ifft(X)
Out[0]:
300-element Vector{ComplexF64}:
   0.17371489951964067 - 1.0954200509634878e-16im
    2.2377132029330844 + 2.2408317281964536e-16im
   -1.4829786507042373 + 2.2273568055204485e-16im
   -0.2348809459284378 - 4.320879722422531e-17im
  -0.31906921401547966 - 3.6273233115378e-17im
  -0.34465018150965426 + 1.56247404219809e-17im
   -1.2607176668657911 + 3.8205740429821057e-17im
   -1.3833370605598396 - 1.0954483820890101e-16im
    0.1073530872080035 + 4.054066051089606e-18im
   -1.1869125065267447 + 1.204268348309886e-16im
  -0.08869450663083418 - 9.907440153835353e-17im
    0.5356860088040623 - 9.578303805633852e-17im
 -0.027712149720118998 - 7.601346822348835e-17im
                       ⋮
    -1.099956486756265 - 2.4424426718144734e-16im
    1.9684779743047827 - 2.3821720609620034e-16im
   -0.9838794916231319 - 6.468831717252368e-17im
   -0.5483474914245768 + 9.609569947930888e-17im
   -0.4423484330625661 - 1.2054068815356207e-16im
   0.12882694892579774 - 7.323649583095336e-17im
    0.3790454548946689 + 1.2509628585190657e-16im
   -0.8125388544875829 + 1.946643454251107e-16im
    -0.603401253638474 + 1.6844285716281442e-17im
    0.9546133370515606 + 1.1027054714660098e-17im
   -1.0973310353263745 + 1.3942493435956269e-16im
    -1.198221964035762 - 1.6134900674300149e-16im

MATLAB 具有快速傅里叶变换的内置函数:

  1. fft:正向快速傅里叶变换。
  2. ifft:反快速傅立叶变换。
In [ ]:
using MATLAB

# Прямое преобразование Фурье
mat"""X = fft($(x_in));"""

# Обратное преобразование Фурье
x_m=mat"""ifft(X);"""
Out[0]:
300-element Vector{Float64}:
  0.17371489951964084
  2.2377132029330844
 -1.4829786507042373
 -0.2348809459284376
 -0.3190692140154795
 -0.3446501815096541
 -1.260717666865791
 -1.3833370605598394
  0.1073530872080034
 -1.186912506526744
 -0.08869450663083417
  0.5356860088040618
 -0.027712149720119327
  ⋮
 -1.0999564867562652
  1.9684779743047829
 -0.9838794916231323
 -0.5483474914245771
 -0.44234843306256627
  0.12882694892579727
  0.37904545489466895
 -0.812538854487583
 -0.6034012536384741
  0.9546133370515602
 -1.0973310353263745
 -1.1982219640357619

让我们比较一下结果并计算误差。

In [ ]:
plot(x_in)
plot!(real(x_e))
plot!(x_m)
Out[0]:
In [ ]:
error_e = abs.(x_in-real(x_e))
error_m = abs.(x_in-x_m)
println("Средняя ошибка Engee: $(sum(error_e)/length(error_e))")
println("Средняя ошибка MATLAB: $(sum(error_m)/length(error_m))")
Средняя ошибка Engee: 1.9054347220418914e-16
Средняя ошибка MATLAB: 2.179376470956562e-16

在这两种环境下,正向傅里叶变换的结果都是复数,而反向变换返回的是原始信号,由于数值舍入,误差很小。 由此可见,代码的语法和逻辑是完全相同的。

时频傅里叶变换

Engee 中没有此类变换的标准函数,必须手动实现。

In [ ]:
using DSP
# Функция для генерации чирп-сигнала
function chirp(t::AbstractVector{T}, f0::T, t1::T, k::T) where T<:Real
    return cos.(2π * (f0 .* t .+ 0.5 * k .* t.^2))
end

# Окно Хэмминга
function hamming(N::Int)
    n = 0:N-1
    return 0.54 .- 0.46 .* cos.(2π * n / (N - 1))
end

x = chirp(0:0.001:1, 0.0, 1.0, 100.0)  # Чирп-сигнал
l=500 # Размер окна
window=vcat(hamming(l),zeros(length(x)-l))

P = DSP.periodogram(x; fs=1000, window=window, nfft=length(x))

# Визуализация спектра
plot(freq(P), 20*log10.(power(P)), xlabel="Frequency (Hz)", ylabel="Power Spectrum (dB)", title="Power Spectrum", linewidth=2)
Out[0]:

MATLAB 有一个 pspectrum 函数,可以对信号进行时频分析。 pspectrum 会自动选择适当的分析方法。 它支持各种可视化(频谱图、功率密度)。

In [ ]:
using Images
mat"""cd("$(@__DIR__)")"""
mat"""
% Частотно-временной анализ
x = chirp(0:0.001:1, 0, 1, 100);
pspectrum(x, 1000); % Частотно-временной спектр
saveas(gcf, 'frequency_time_spectrum.jpg'); % Сохраняет текущую фигуру как JPG
"""
load( "$(@__DIR__)/frequency_time_spectrum.jpg" )
Out[0]:
No description has been provided for this image

从图中可以看出,Engee 反映了信号行为的主要趋势。要进行更详细的绘图,还需要对周期图函数进行更详细的窗口计算。

我们还可以比较一下 MATLAB 和 Engee 中生成的输入数据的正确性。

In [ ]:
plot(mat"chirp(0:0.001:1, 0, 1, 100)"[:])
plot!(chirp(0:0.001:1, 0.0, 1.0, 100.0))
title!("Sum_error: $(sum(mat"chirp(0:0.001:1, 0, 1, 100)"[:]-chirp(0:0.001:1, 0.0, 1.0, 100.0)))")
Out[0]:

我们可以看到,输入信号完全相同。

输出

MATLAB 内置了执行这些操作的函数。在 Engee 中,您可以使用第三方库(如 DSP 或 FFTW)进行更复杂的信号操作。同样重要的是,Engee 在如何实现转换方面提供了更大的灵活性。为了简化 Engee 实现中的这些操作,请使用本演示中介绍的开箱即用方法。

比较两种环境功能的另一个方面是,MATLAB 针对矩阵和信号进行了优化。不过,如果在编写代码时考虑到这一环境的特殊性,Engee 的计算速度通常会更快,这将显著提高大型系统中算法的执行和测试速度。