2026a

# dsp_FrequencyDomainAdaptiveFilter


使用频域 FIR 自适应滤波器计算输出,误差和系数

函数库: TyDSPSystem

# 描述

dsp_FrequencyDomainAdaptiveFilter 系统对象使用快速块最小均方 (LMS) 算法在频域中实现自适应有限脉冲响应 (FIR) 滤波器。 Length 和 BlockLength 属性指定算法使用的滤波器长度和块长度值。 FFTCoefficients 属性包含当前滤波器系数的离散傅立叶变换。 该对象提供具有分区和非分区模式的算法的约束和非约束版本。 有关详细信息,请参阅算法。

使用频域 FIR 自适应滤波器对信号进行滤波:

  1. 创建 dsp_FrequencyDomainAdaptiveFilter 对象并设置其属性。

  2. 使用 step 调用对象。

# 构造

fdaf = dsp_FrequencyDomainAdaptiveFilter()
fdaf = dsp_FrequencyDomainAdaptiveFilter(___; Name = Value)

# 说明

fdaf = dsp_FrequencyDomainAdaptiveFilter( ) 返回频域 FIR 自适应滤波器系统对象 fdaf。 此系统对象用于计算给定输入和所需信号的滤波输出和滤波误差。


fdaf = dsp_FrequencyDomainAdaptiveFilter(___; Name = Value) 返回一个频域 FIR 自适应滤波器对象,其中每个指定属性设置为指定值。 您可以将此语法与任何先前的输入参数组合一起使用。

示例: fdaf = dsp_FrequencyDomainAdaptiveFilter(; Length = 32, StepSize = 0.1) 对长度为 32 个抽头、步长为 0.1 的频域自适应滤波器建模。

# 语法

y, err = step(fdaf, x, d)

# 说明

y, err = step(fdaf, x, d) 使用 d 作为所需信号对输入信号 x 进行滤波,并在 y 中返回滤波后的输出,在 err 中返回滤波误差。系统对象估计最小化输出信号和所需信号之间的误差所需的滤波器权重。 这些滤波器权重的 FFT 可以通过调用对象算法后访问 FFTCoefficients 属性来获得。

# 示例

带 FIR 滤波器的 QPSK 自适应均衡

通过嘈杂的传输通道传输正交相移键控 (QPSK) 信号。 使用频域自适应滤波器将接收信号中的噪声降至最低。

QPSK 信号 s 通过噪声信道传输。 通道的分子和分母系数分别包含在向量 b 和 a 中。 在传输信道末端获得的接收信号 r 包含传输的 QPSK 信号和添加到信道的噪声 n。 自适应滤波器用于从接收到的噪声输入中提取 QPSK 信号。 所需信号 d 是 QPSK 信号的延迟版本。

using TyDSPSystem
using TyPlot
using TyMath

D = 16
b = exp(1im * pi / 4) * [-0.7, 1]
a = [1, -0.7]
ntr = 1024
rng = MT19937ar(1234)
s = sign.(randn(rng, ntr + D)) + 1im * sign.(randn(rng, ntr + D))
n = 0.1 * (randn(rng, ntr + D) + 1im * randn(rng, ntr + D))
r = filter1(b, a, s)[1] + n
x = r[1+D:ntr+D]
d = s[1:ntr]

创建一个 dsp_FrequencyDomainAdaptiveFilter 对象来模拟一个长度为 32 个抽头和步长为 0.1 的频域自适应滤波器。 自适应滤波器接受接收信号的延迟版本和所需信号作为输入。 将自适应滤波器的输出与所需信号进行比较。 两个信号之间的误差表示添加到传输通道的噪声。 自适应滤波器更新其系数,直到该误差变得最小。 要获得滤波器系数的离散傅里叶变换,请调用 fdaf 对象,并访问该对象的 FFTCoefficients 属性。

mu = 0.1
fdaf = dsp_FrequencyDomainAdaptiveFilter(Length = 32, StepSize = mu)
fdaf.Method = "Unconstrained FDAF"
fdaf.BlockLength = 16
y, e = step(fdaf, x, d)
fftCoeffs = fdaf.FFTCoefficients

绘制所需信号、输出信号和误差信号的同相和正交分量。

figure()
plot([1:ntr;], real.([d y' e']))
grid("on")
legend(["Desired", "Output", "Error"])
title("In-Phase Components")
xlabel("Time Index")
ylabel("signal value")
figure()
plot([1:ntr;], imag.([d y' e']))
grid("on")
legend(["Desired", "Output", "Error"])
title("Quadrature Components")
xlabel("Time Index")
ylabel("signal value")

创建接收信号和所需信号的散点图。

figure()
plot(real.(x[ntr-100:ntr]), imag.(x[ntr-100:ntr]), ".")
title("Received Signal Scatter Plot")
axis("square")
xlabel("Real[x]")
ylabel("Imag[x]")
grid("on")
axis([-3 3 -3 3])
figure()
plot(real.(d[ntr-100:ntr]), imag.(d[ntr-100:ntr]), ".")
title("Desired Signal Scatter Plot")
axis("square")
xlabel("Real[y]")
ylabel("Imag[y]")
grid("on")
axis([-3 3 -3 3])
figure()
plot(real.(y[ntr-100:ntr]), imag.(y[ntr-100:ntr]), ".")
title("Equalized Signal Scatter Plot")
axis("square")
xlabel("Real[y]")
ylabel("Imag[y]")
grid("on")
axis([-3 3 -3 3])

# 属性

除非另有说明,否则属性是不可调整的,这意味着您在调用对象后无法更改它们的值。 对象在调用时锁定,而释放函数将其解锁。

如果属性是可调的,您可以随时更改其值。

Method - 计算滤波器系数的方法
"Constrained FDAF"(默认) | "Unconstrained FDAF" | "Partitioned constrained FDAF" | "Partitioned unconstrained FDAF"

用于计算滤波器系数的方法,指定为:

  • "Constrained FDAF" –– 对滤波器抽头权重施加梯度约束。
  • "Unconstrained FDAF" –– 没有对滤波器抽头权重施加梯度约束。
  • "Partitioned constrained FDAF" –– 对滤波器的脉冲响应进行分区以减少延迟。
  • "Partitioned unconstrained FDAF" –– 对滤波器的脉冲响应进行分区以减少延迟。 没有对滤波器抽头权重施加梯度约束。

有关更多详细信息,请参阅算法。

Length - 滤波器系数向量的长度
32(默认)| 正整数值标量

FIR 滤波器系数向量的长度,指定为正整数值标量。

数据类型:Float | Int

BlockLength - 系数更新的块长度
32(默认)| 正整数值标量

系数更新的块长度,指定为正整数值标量。 自适应滤波器将输入数据和所需信号处理为长度由该属性设置的样本块。 有关滤波器如何处理此数据的详细信息,请参阅算法。 输入向量的长度必须能被 BlockLength 属性值整除。 BlockLength 属性的默认值设置为 Length 属性的值。

数据类型:Float | Int

StepSize - 适应步长
1(默认)| 范围内的实标量 (0,1]

自适应步长因子,指定为 (0,1] 范围内的实数标量。使用小步长可确保较小的稳态误差。但是,小步长会降低自适应滤波器的最终收敛速度。增加 步长提高了收敛速度,代价是增加了稳态均方误差。当步长值为 1 时,算法提供了收敛速度和稳态均方误差之间的最佳折衷。

是否可调: Yes

数据类型:Float | Int

LeakageFactor - 适应泄漏因子
1(默认)| [0,1] 范围内的标量

实现泄漏自适应滤波器时使用的泄漏因子,指定为 [0,1] 范围内的标量数值。 当该值小于 1 时,System 对象实现泄漏自适应算法。 当值为 1 时,对象在适配方法中不提供泄漏。

是否可调: Yes

数据类型:Float | Int

AveragingFactor - 信号功率的平均因子
0.9(默认)| 范围内的实标量 (0,1]

用于计算系数更新的指数窗化 FFT 输入信号功率的平均系数,指定为 (0,1] 范围内的实数标量。

数据类型:Float

Offset - 归一化项的偏移量
0(默认)| 非负实标量

系数更新中归一化项的偏移量,指定为非负实标量值。 如果任何 FFT 输入信号功率变得非常小,则此属性值用于避免除以零或除以非常小的数字。

数据类型: Float

InitialCoefficients - 滤波器的初始时域系数
0 (默认) | 标量 | 向量

自适应滤波器的初始时域系数,指定为一个标量或一个长度等于 Length 属性值的向量。自适应滤波器对象使用这些系数来计算初始频域滤波器系数。

数据类型: Float

InitialPower - 初始 FFT 输入信号功率
1(默认)| 正实数标量

所有 FFT 输入信号功率的初始公共值,指定为一个正实数标量。

LockCoefficients - 系数更新的锁定状态
false (默认) | true

系数更新的锁定状态,指定为:

  • false — 对象不断更新滤波器系数。
  • true — 滤波器系数不会更新,它们的值保持在当前值。

数据类型: bool

FFTCoefficients - 滤波器的当前 FFT 系数
[ ](默认)| 行向量

滤波器系数的当前离散傅立叶变换,以行向量形式返回。 对于 "Constrained FDAF" 和 "Unconstrained FDAF" 算法,该向量的长度等于 Length 值和 BlockLength 值的总和。 此属性初始化为 InitialCoefficients 属性的 FFT 值。 要获得滤波器系数的离散傅里叶变换,请调用对象并访问对象的 FFTCoefficients 属性。

数据类型: Float

复数支持: Yes

# 输入参数

x - 数据输入
列向量

由频域 FIR 自适应滤波器滤波的信号。 输入 x 和所需信号 d 必须具有相同的大小和数据类型。 输入向量的长度必须能被 BlockLength 属性值整除。

只要帧长度是 BlockLength 的倍数,输入 x 就可以是可变大小的信号。 即使对象被锁定,您也可以更改列向量中的元素数量。 当您调用对象运行其算法时,系统对象会锁定。

数据类型:Float

复数支持: Yes

d - 预期信号
列向量

频域自适应滤波器调整其滤波器权重以使误差 err 最小化,并尽可能将输入信号 x 收敛到所需信号 d。

输入信号和所需信号必须具有相同的大小和数据类型。 所需信号向量的长度必须能被 BlockLength 属性值整除。

输入信号可以是可变大小的信号,只要帧长度是 BlockLength 的倍数。 即使对象被锁定,您也可以更改列向量中的元素数量。 当您调用对象运行其算法时,系统对象会锁定。

数据类型:Float

复数支持: Yes

# 输出参数

y - 过滤后的输出
列向量

过滤后的输出,以列向量形式返回。 对象调整其滤波器权重以收敛输入信号 x,以匹配所需信号 d。 滤波器输出收敛的信号。

数据类型:Float

复数支持: Yes

err - 输出和所需信号之间的差异
列向量

输出信号和所需信号之间的差异,以列向量形式返回。 自适应滤波器的目标是最小化这个误差。 对象调整其权重以向最佳滤波器权重收敛,从而产生与所需信号尽可能匹配的输出信号。 有关如何计算 err 的更多详细信息,请参阅 [2]。

数据类型:Float

复数支持: Yes

# 对象函数

要使用对象函数,请将系统对象指定为第一个输入参数。 例如,要释放名为 obj 的系统对象的系统资源,请使用以下语法:

所有系统对象共有
对象 描述
step 运行系统对象算法
release 释放资源并允许更改系统对象属性值和输入特征
reset 重置系统对象的内部状态

# 算法

频域自适应滤波包括三个步骤——滤波、误差估计和抽头权重自适应。 该算法使用重叠保存或重叠添加方法在频域中实现 FIR 滤波。 有关这两种方法的更多实现细节,请参阅 dsp_FrequencyDomainAdaptiveFilter 对象页面中的算法部分。 使用快速块 LMS 算法 (FBLMS) 实现误差估计和抽头权重自适应。

Fast Block LMS Algorithm - 快速块 LMS 算法

频域自适应滤波器使用快速块 LMS (FBLMS) 算法将输入数据和所需信号数据作为样本块进行处理。 这是使用 FBLMS 算法的频域自适应滤波器的框图。 此图中的频域 FIR 滤波器使用重叠保存方法。

在哪里:

  • N - 滤波器长度
  • L - 块长
  • μ - 步长参数
  • x(n) - 输入信号
  • X(k) - 频域中的变换输入信号
  • d(n) - 所需信号
  • e(n) - 所需信号和滤波器输出之间的误差
  • E(n) - 频域中的变换误差信号
  • W(k) - 频域中的抽头权重向量
  • 有关如何估计误差和调整抽头权重的更多详细信息,请参阅 [2]。
Constrained and Unconstrained FBLMS Algorithms - 有约束和无约束的 FBLMS 算法

上图是受约束的版本。 如果您删除算法的梯度约束部分,您将获得不受约束的 FBLMS 实现。 有关受约束和不受约束的变化的收敛行为的详细信息,请参见 [2]。

Partitioned FBLMS Algorithm - 分区 FBLMS 算法

滤波器的延迟大致等于 FIR 分子的长度。 如果滤波器的脉冲响应非常长,则延迟会变得非常大。 分区 FBLMS 算法通过对脉冲响应进行分区来减少延迟。 对于长脉冲响应,非分区频域 FIR 滤波比时域滤波更快,但代价是延迟增加。 为了减少延迟并使频域滤波更加有效,该算法将脉冲响应划分为多个短块,并对每个块执行重叠保存或重叠添加。 然后将不同块的结果组合起来以获得最终输出。 这种方法的延迟是块长度的数量级,而不是整个脉冲响应长度。 这种减少的延迟是以额外计算为代价的。 有关实现的更多详细信息,请参阅 [2]。

# 参考文献

[1] Shynk, J.J. "Frequency-Domain and Multirate Adaptive Filtering." IEEE Signal Processing Magazine. Vol. 9, Number 1, 1992, pp. 14–37.

[2] Farhang-Boroujeny, B., Adaptive Filters: Theory and Applications, Chichester, England, Wiley, 1998.

[3] Stockham, T. G., Jr. "High Speed Convolution and Correlation." Proceedings of the 1966 Spring Joint Computer Conference, AFIPS, Vol. 28, 1966, pp. 229–233.

# 另请参阅

dsp_AdaptiveLatticeFilter | dsp_AffineProjectionFilter | dsp_FastTransversalFilter | dsp_FilteredXLMSFilter | dsp_FIRFilter | dsp_LMSFilter | dsp_RLSFilter