Farrow结构的系数设计是其实现可变分数延迟或动态群时延调整的关键步骤。其核心思想是将每个滤波器抽头的系数表示为多项式函数(通常以参数 u u u 为变量),通过优化多项式系数实现不同延迟下的滤波特性。以下是Farrow系数设计的主要方法及步骤:
Farrow结构的一般形式为:
H ( z , μ ) = ∑ m = 0 M μ m ⋅ ( ∑ k = 0 N c k , m z − k ) H(z, \mu) = \sum_{m=0}^{M} \mu^m \cdot \left( \sum_{k=0}^{N} c_{k,m} z^{-k} \right) H(z,μ)=m=0∑Mμm⋅(k=0∑Nck,mz−k)
其中:
设计目标:在指定频带(如通带 ω ∈ [ 0 , α π ] \omega \in [0, \alpha\pi] ω∈[0,απ])和延迟范围( μ ∈ [ 0 , 1 ) \mu \in [0,1) μ∈[0,1))内,使滤波器的幅频响应和群时延满足要求(如平坦响应、最小误差)。
核心思想:最小化实际响应与理想响应的误差平方和。
步骤:
适用场景:低复杂度设计,适用于局部插值需求。
适用场景:需约束通带波纹、群时延波动等性能指标时。
fmincon
)求解系数。步骤1:参数定义
步骤2:离散化采样
步骤3:构建目标矩阵
步骤4:求解线性方程组
步骤5:验证与迭代
假设设计一个三次多项式Farrow结构( M = 3 M=3 M=3),滤波器长度为 N = 4 N=4 N=4,通带 ω ∈ [ 0 , 0.8 π ] \omega \in [0, 0.8\pi] ω∈[0,0.8π]。
系数矩阵形式:
C = [ c 0 , 0 c 0 , 1 c 0 , 2 c 0 , 3 c 1 , 0 c 1 , 1 c 1 , 2 c 1 , 3 c 2 , 0 c 2 , 1 c 2 , 2 c 2 , 3 c 3 , 0 c 3 , 1 c 3 , 2 c 3 , 3 ] C = \begin{bmatrix} c_{0,0} & c_{0,1} & c_{0,2} & c_{0,3} \\ c_{1,0} & c_{1,1} & c_{1,2} & c_{1,3} \\ c_{2,0} & c_{2,1} & c_{2,2} & c_{2,3} \\ c_{3,0} & c_{3,1} & c_{3,2} & c_{3,3} \\ \end{bmatrix} C= c0,0c1,0c2,0c3,0c0,1c1,1c2,1c3,1c0,2c1,2c2,2c3,2c0,3c1,3c2,3c3,3
典型系数值(仅供参考):
lsqnonlin
、firls
等函数进行最小二乘优化。numpy.linalg.lstsq
或cvxpy
库求解。以下是使用Python设计一个四阶多项式( M = 4 M=4 M=4)且滤波器长度为5( N = 5 N=5 N=5)的Farrow结构的完整代码示例,包含系数设计和性能验证:
# -*- coding: utf-8 -*-
"""
Created on Sat Mar 15 22:47:36 2025
@author: Neol
"""
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import freqz
plt.close('all')
# 设置全局字体为支持中文的字体
plt.rcParams['font.sans-serif'] = ['SimHei'] # 黑体
# 解决负号显示问题
plt.rcParams['axes.unicode_minus'] = False
# 设计参数
M = 4 # 多项式阶数 (mu^0, mu^1, ..., mu^4)
N = 5 # 滤波器长度(抽头数 k=0,1,2,3,4)
D = 2 # 整数延迟(通常设为N//2)
alpha = 0.4 # 通带范围 [0, alpha*pi]
K = 200 # 频率采样点数
L = 20 # mu采样点数
# 生成离散频率和mu值
omega = np.linspace(0, alpha * np.pi, K)
mu = np.linspace(0, 1, L, endpoint=False)
# 构建最小二乘问题的矩阵A和向量b
A_real = []
A_imag = []
b_real = []
b_imag = []
for mu_j in mu:
for omega_i in omega:
# 理想响应:H_d = e^{-j*omega*(D + mu_j)}
H_d = np.exp(-1j * omega_i * (D + mu_j))
# 构建当前行的基函数(实部和虚部分开)
row_real = []
row_imag = []
for k in range(N):
for m in range(M+1):
# 基项:mu^m * e^{-j*omega*k}
term = (mu_j**m) * np.exp(-1j * omega_i * k)
row_real.append(term.real)
row_imag.append(term.imag)
A_real.append(row_real)
A_imag.append(row_imag)
b_real.append(H_d.real)
b_imag.append(H_d.imag)
# 合并实部和虚部
A = np.vstack([A_real, A_imag])
b = np.hstack([b_real, b_imag])
# 求解最小二乘问题
c, residuals, rank, singular_values = np.linalg.lstsq(A, b, rcond=None)
# 将系数向量转换为系数矩阵 (N x M+1)
C = c.reshape((N, M+1))
print("Farrow系数矩阵C:")
print(np.round(C, 4))
# 验证设计:计算在mu=0.5时的频率响应
mu_test = 0.9
h = np.zeros(N, dtype=np.complex128)
for k in range(N):
for m in range(M+1):
h[k] += C[k, m] * (mu_test ** m)
# 计算频率响应
w, H = freqz(h, worN=1024)
H_ideal = np.exp(-1j * w * (D + mu_test))
# 绘制幅度和相位响应
plt.figure(figsize=(12, 8))
# 幅度响应
plt.subplot(2, 2, 1)
plt.plot(w, 20*np.log10(np.abs(H)), label='Designed')
plt.plot(w, 20*np.log10(np.abs(H_ideal)), '--', label='Ideal')
plt.title(f'Magnitude Response (mu={mu_test})')
plt.xlabel('Frequency [rad/sample]')
plt.ylabel('Magnitude [dB]')
plt.grid(True)
plt.legend()
# 相位响应
plt.subplot(2, 2, 2)
plt.plot(w, np.unwrap(np.angle(H)), label='Designed')
plt.plot(w, np.unwrap(np.angle(H_ideal)), '--', label='Ideal')
plt.title(f'Phase Response (mu={mu_test})')
plt.xlabel('Frequency [rad/sample]')
plt.ylabel('Phase [rad]')
plt.grid(True)
plt.legend()
# 群时延
group_delay = -np.diff(np.unwrap(np.angle(H))) / np.diff(w)
group_delay = np.hstack([group_delay, group_delay[-1]]) # 保持长度一致
plt.subplot(2, 2, 3)
plt.plot(w, group_delay, label='Designed')
plt.plot(w, (D + mu_test)*np.ones_like(w), '--', label='Ideal')
plt.title(f'Group Delay (mu={mu_test})')
plt.xlabel('Frequency [rad/sample]')
plt.ylabel('Samples')
plt.ylim(D + mu_test - 1, D + mu_test + 1)
plt.grid(True)
plt.legend()
# 系数矩阵可视化
plt.subplot(2, 2, 4)
plt.imshow(C, cmap='coolwarm', aspect='auto')
plt.colorbar(label='Coefficient Value')
plt.title('Farrow Coefficient Matrix')
plt.xlabel('Polynomial Order (m)')
plt.ylabel('Tap Index (k)')
plt.xticks(range(M+1), [f'm={m}' for m in range(M+1)])
plt.yticks(range(N), [f'k={k}' for k in range(N)])
plt.tight_layout()
plt.show()
参数定义:
M=4
:多项式最高阶数为 μ 4 \mu^4 μ4N=5
:滤波器抽头数(对应 k = 0 , 1 , 2 , 3 , 4 k=0,1,2,3,4 k=0,1,2,3,4)D=2
:整数延迟(通常设置为滤波器中间位置)alpha=0.8
:通带截止频率为 0.8 π 0.8\pi 0.8πK=200
和 L=20
:频率和 μ \mu μ 的采样点数最小二乘问题构建:
系数求解:
numpy.linalg.lstsq
求解最小二乘问题性能验证:
[[ 0.0417 -0.0833 0.0833 -0.0417 0.0083]
[-0.1667 0.5 -0.5 0.1667 -0.0167]
[ 0.25 -0.5 0. -0.5 0.25 ]
[-0.1667 0.1667 0.5 -0.5 0.0833]
[ 0.0417 0.0833 -0.0833 -0.0417 0.0083]]
np.linalg.lstsq
中设置rcond
参数)。cvxpy
)添加约束条件。Farrow结构的系数设计本质是多变量优化问题,需权衡计算复杂度、逼近精度和实时性要求。最小二乘法是通用方法,拉格朗日插值适合低阶设计,而凸优化适用于高精度约束场景。通过合理选择参数和优化目标,Farrow结构能高效实现动态群时延调整和分数延迟滤波。