3. 均匀直线阵导向矢量与阵列流形校验
导向矢量的数学定义与校验思路
均匀直线阵(ULA)的导向矢量描述的是:当一束远场窄带平面波以方位角 θ 入射时,各阵元相对于参考阵元所接收到的复相位差。设阵元数为 N、阵元间距为 d、波长为 λ,以第 0 号阵元为相位参考,则导向矢量可写为
a(θ, f) = [1, e^{-j2πfd·sinθ/c}, e^{-j4πfd·sinθ/c}, ..., e^{-j2π(N-1)fd·sinθ/c}]^T
其中 c 为声速,f 为信号频率,空间相位步进量 μ = 2πfd·sinθ/c。把多个来向的导向矢量按列排成矩阵,就得到阵列流形矩阵 A = [a(θ₁), a(θ₂), …, a(θ_K)]。校验的核心就是检查这个矩阵是否满足三条可独立验证的性质:
- 共轭对称性:a(θ) 与 a(−θ) 互为共轭,即 a(−θ) = conj(a(θ)),因为 sin(−θ) = −sinθ 只改变相位符号。
- 范数恒定性:每个导向矢量的 2-范数应恒为 √N,与来向、频率无关,这是相位项模值为 1 的直接结果。
- 相位斜率线性:相邻阵元相位差恒为 −μ,对相位序列做线性拟合,斜率应等于 −μ,残差接近 0。
下面给出一个自洽的生成与校验函数,直接可运行(仅依赖 NumPy)。
import numpy as np
def ula_steering(N, d, f, theta_deg, c=1500.0):
"""生成 ULA 导向矢量,theta 为与阵列法线的夹角(度)"""
theta = np.deg2rad(theta_deg)
n = np.arange(N)
mu = 2 * np.pi * f * d * np.sin(theta) / c
return np.exp(-1j * mu * n)
def ula_manifold(N, d, f, thetas_deg, c=1500.0):
"""阵列流形矩阵,每列一个来向"""
return np.column_stack([ula_steering(N, d, f, t, c) for t in thetas_deg])
def check_manifold(N, d, f, thetas_deg, c=1500.0, tol=1e-9):
A = ula_manifold(N, d, f, thetas_deg, c)
report = {}
# 1) 范数
norms = np.linalg.norm(A, axis=0)
report['范数偏差'] = float(np.max(np.abs(norms - np.sqrt(N))))
# 2) 共轭对称:找 +θ 与 -θ 配对
th = np.asarray(thetas_deg, dtype=float)
idx_pos = np.where(th > 0)[0]
idx_neg = np.where(th < 0)[0]
sym_err = 0.0
for ip in idx_pos:
match = idx_neg[np.isclose(th[idx_neg], -th[ip])]
if match.size:
sym_err = max(sym_err, float(np.max(np.abs(A[:, ip] - np.conj(A[:, match[0]])))))
report['共轭对称偏差'] = sym_err
# 3) 相位斜率
slope_err = 0.0
for k, t in enumerate(th):
phase = np.unwrap(np.angle(A[:, k]))
n = np.arange(N)
p = np.polyfit(n, phase, 1)
mu = 2 * np.pi * f * d * np.sin(np.deg2rad(t)) / c
slope_err = max(slope_err, abs(p[0] + mu))
report['相位斜率偏差'] = float(slope_err)
report['通过'] = all(v < tol for k, v in report.items() if k != '通过')
return report
# 示例:N=8, d=λ/2 @ 3kHz, 声速1500 → λ=0.5m, d=0.25m
print(check_manifold(8, 0.25, 3000.0, [-60, -30, 0, 30, 60]))
示例参数下,三项偏差都应落在 1e-12 量级(浮点舍入),报告“通过”为 True。若把 d 误设为 0.5 m(即 λ),在 60° 处会出现相位混叠,相位斜率拟合残差会明显增大,这正是校验要拦截的错误。
校验函数的工程使用要点
把上面的 check_manifold 作为单元测试嵌入到算法流程之前,可以避免“导向矢量写错却继续做波束形成”的隐性错误。实际使用时注意三点:
- 配对来向要成对给出:共轭对称检查依赖 +θ 与 −θ 同时出现在来向列表中,否则该项会被跳过(偏差记为 0),造成假通过。建议固定传入
[-60,-30,0,30,60]这类对称集合。 - 相位斜率用 unwrap:当 μ 接近或超过 π 时,
np.angle会卷绕,必须先np.unwrap再拟合,否则斜率检查会误报。 - 容差按浮点精度设定:纯数学构造的导向矢量偏差应在 1e-12 量级,容差取 1e-9 足够宽松;若从实测数据估计导向矢量,则需改用统计容差。
把
ula_steering 与 check_manifold 保存为独立模块,后续 CBF、MVDR 等案例直接导入,即可保证所有算法共用同一份经过校验的导向矢量定义,避免各案例间相位约定不一致。