☰
relax算法解决强弱信号DOA估计的MATLAB实现与调参指南
2026/9/28 5:38:26 网站建设 项目流程

简介:面向雷达信号处理与到达角估计研究的一份MATLAB实现资源,聚焦Relax算法在强弱信号到达角估计、一维信号重构、雷达目标识别与谐波检测等场景的应用。资源包含十七个文件,其中M脚本六个、文本说明五份、PDF文档一份,另有四个RAR压缩包和一个ZIP压缩包存放辅助代码或数据,整体体积仅195KB,便于快速下载与部署。算法配套脚本可直接运行,演示通过迭代松弛优化提升弱信号估计精度、抑制噪声干扰的效果;文本资料则梳理了基于高分辨距离像与Relax的雷达目标识别思路,以及谐波检测相比傅里叶变换的优势。对于正在学习阵列信号处理、雷达超分辨成像或需要复现Relax算法对比实验的读者,这套代码和笔记能帮助理解核心迭代步骤,并作为二次开发的基础。目前已有859人学习下载,适合中高级信号处理研究者与工程师。

1. relax算法到底解决了DOA估计里的什么问题:强弱信号并存才是它的主场

做DOA估计的人基本都遇到过这种场景:两个目标一个在0°一个在8°,强目标信噪比20 dB,弱目标只有3 dB,拿MUSIC或ESPRIT跑一遍,弱目标对应的谱峰要么被强目标的主瓣压得看不见,要么谱峰偏移好几度,解算结果完全没法用于跟踪。常规算法在这种强弱信号动态范围过大的情况下集体翻车,而relax算法从诞生起就是冲着这类问题去的。它不是通过特征分解或子空间划分来估计到达角,而是把每个信源参数看作一个可分离的非线性最小二乘问题,逐个估计、逐个剥离、再循环精修。这个思路使它天然能在一堆强信号里把弱信号抠出来。本文就用MATLAB把relax算法的完整迭代流程跑一遍,覆盖信号建模、核心函数实现、参数整定和踩坑记录,适合正在做相控阵测向、多径环境信源恢复或者车载雷达多目标分辨的工程师。

2. 信号模型与MATLAB数据准备:先把阵列和含强弱信号的快拍数据造出来

2.1 均匀线阵与窄带信号模型:几个关键参数先说清

relax算法的实现离不开对一个基本阵列信号模型的刻画。我们假设接收端是一个均匀线阵,阵元数为M,阵元间距为d,通常取半个波长,这样能避免空间混叠。假设空间中有P个远场窄带信号源,从方向θ₁, θ₂, …, θ_P入射到阵列上,那么第t个快拍时刻,阵列接收到的M维复基带信号可以写成:

X(t) = A(θ) S(t) + N(t)

其中A(θ)是M×P的阵列流型矩阵,第p列是方向θ_p对应的导向矢量a(θ_p),结构为:

a(θ_p) = [1, e^{-j2π(d/λ) sinθ_p}, e^{-j4π(d/λ) sinθ_p}, …, e^{-j2π(M-1)(d/λ) sinθ_p}]^T

当d = λ/2时,指数项简化为e^{-jπ(m-1)sinθ_p}。

S(t)是P×1的复信号幅相矢量,包含每个源的幅度、相位和随时间变化的调制信息。N(t)是M×1的复高斯白噪声向量,各阵元独立同分布。

relax算法的关键特征在于它不假设噪声的统计特性是已知的,也不强行约束信号之间不相关。相比MUSIC依赖协方差矩阵的秩亏结构和特征子空间分离,relax走的是纯参数化迭代路线:把A(θ)和S(t)都当作待优化变量,用非线性最小二乘框架整体求最优。这意味着即使信源之间高度相关,甚至相干,relax依然能工作,这是它处理强弱信号混合场景的一个先天结构优势。

2.2 用MATLAB生成含强弱信号的快拍数据:最小可运行代码

实现relax算法第一步是构造一个能复现"强信号压弱信号"场景的数据集。我一般先用一个简单的仿真脚本生成快拍数据,把两个源的DOA、幅度和信噪比差异显式地写出来,这样后续迭代算法收敛到什么精度、谱峰在哪里,全部有据可查。下面这段代码生成M=8阵元、T=200快拍的数据,两个源分别位于-3°和7°,幅度比为10倍功率,也就是20 dB差距。

% relax_sim_data.m % 生成用于relax算法验证的强弱信号快拍数据 M = 8; % 阵元数 T = 200; % 快拍数 theta_true = [-3, 7]; % 真实DOA,单位度 P_true = length(theta_true); % 构造导向矢量矩阵,阵元间距取半波长 lambda = 1; d = lambda/2; array_manifold = @(theta) exp(-1j*pi*(0:M-1)'*sin(theta*pi/180)); A = zeros(M, P_true); for p = 1:P_true A(:, p) = array_manifold(theta_true(p)); end % 信号幅相:源1幅度10,源2幅度1,功率差20dB S = [10 * exp(1j*2*pi*rand(1,T)); ... 1 * exp(1j*2*pi*rand(1,T))]; % 复高斯白噪声,噪声功率归一化到1 noise = (randn(M, T) + 1j*randn(M, T)) / sqrt(2); X = A * S + noise; save('sim_data.mat', 'X', 'theta_true', 'M', 'T');

这段代码里,array_manifold这个匿名函数把角度从度转换为弧度,再套进导向矢量的指数表达式。信号部分我用随机初相模拟了任意调制波形,其中第一个源的幅度10、第二个源幅度1,对应信噪比差异20 dB。噪声功率设为1,因此强源的信噪比大约为40 dB,弱源大约为20 dB,这个差距足以让很多子空间类算法失效。

参数调整的取值逻辑:阵元数M直接决定角度分辨能力的上限,8阵元在-90°到90°范围内理论上能分辨的最小角度间隔约为180/8除以总快拍增益,实际中3到5度间隔已经值得尝试。快拍数T影响非线性最小二乘统计性能,200个快拍对relax来说已经足够收敛稳定,再少到50也能跑但方差会明显变大。

2.3 信噪比差异怎么体现"强"和"弱":参数语义说明

很多人在构造仿真数据时有个误区:觉得强弱信号就是信噪比一个30一个0,但实际上对DOA算法影响最大的是两者的功率比和角度间隔。relax算法里,强的定义是单个源对阵列输出总功率的贡献占比,弱的定义则是在迭代剥离过程中残差里剩余信号的能量大小。

在上述代码中,源1的功率贡献为10² = 100,源2为1² = 1,两者比值为100比1,也就是20 dB。阵列接收到的总信号功率约101,噪声总功率为M = 8,所以整体信噪比超过10 dB。做算法验证时,建议把幅度比设成100比1或更高来测relax的极限,而不是只做5 dB差这种温和场景,否则体现不出算法优势。

3. relax算法迭代原理:逐次剥离与循环精修

3.1 从非线性最小二乘到relax:为什么不做一次性全局搜索

DOA估计的本质是从带噪观测X中反推θ和对应复幅度S。把这个问题写成最小二乘形式:

minimize ||X - A(θ) S||_F²

其中θ和S都是未知量。这是一个高度非线性的联合优化问题,因为A(θ)对θ的依赖是指数形式的。一次性做全局搜索在计算上是不可行的,因为角度网格哪怕只取0.1°步长,180°范围就有1800个候选点,P个源联合搜索的复杂度是指数级的。

relax算法的解决思路是坐标下降法的一种工程化变体。坐标下降的思路是:固定其他变量,只优化一个变量,循环反复直到收敛。relax把变量拆成两组:每个源的方向角θ_p和对应的复幅相S_p。外层循环先将除当前源以外的所有源信号从X中减掉,得到纯化后的残差信号Y_p,再在Y_p上做一次一维角度搜索,找到当前源的更新方向估计。

这个"先剥离后估计"的操作让每个源的头次估计都能借助其他源已经剥离干净的数据来完成,所以专治强弱信号混叠。强信号即使主瓣宽度覆盖弱信号角度,只要迭代次数够多,弱信号也能在多轮精修中慢慢被修正到正确位置。

3.2 relax主循环的三个关键步骤:估计、剥离、再精修

整个relax算法的主循环可以拆成嵌套结构。外层循环遍历每个信号源,从第1个到第P个逐个更新;内层是对单个源的精细角度搜索。当所有P个源完成一轮更新后,检查所有源的DOA变化量是否小于设定阈值,如果满足就终止,否则进入下一轮。

第一阶段的估计是在当前残差上直接找最优角度。对第k个源,残差定义为

Y_k = X - Σ_{l≠k} a(θ_l) s_l

也就是从原始数据里减掉除k以外所有源的贡献。然后在给定的角度搜索网格θ_grid上逐点计算匹配输出功率:

P(θ) = |a(θ)^H Y_k|²

选择使P(θ)最大的角度作为第k个源的新方向估计。这一步的本质是匹配滤波:因为a(θ)^H a(θ) = M固定,功率最大化相当于在残差里找最像当前导向矢量的方向分量。

第二阶段的幅度更新是线性最小二乘闭式解:

s_k = a(θ_k)^H Y_k / M

这个式子的来源是当θ_k固定时,最优幅度就是残差在导向矢量方向上的投影除以阵元数。

第三阶段是把更新后的θ_k和s_k代回重构矩阵,生成该源的贡献,然后进入下一个源。所有源扫完后,整体迭代一轮完成,再重新检查收敛。

3.3 迭代流程对应的MATLAB骨架:先看结构再填细节

下面给一个不带完整初始化逻辑的骨架代码,主要展示主循环的迭代框架和变量更新关系,方便理解数据流怎么走。

% relax_doa_skeleton.m % RELAX算法主循环骨架,仅用于理解迭代结构 for iter = 1:max_iter theta_prev = theta_est; for k = 1:P % 构造残差:减掉除k以外所有源的贡献 residual = X - A_est * S_est; residual = residual + A_est(:,k) * S_est(k,:); % 加回第k个源的贡献 % 角度搜索:在网格上找匹配输出功率最大值 power = abs(a_manifold(theta_grid)' * residual) .^ 2; [~, idx] = max(power); theta_est(k) = theta_grid(idx); % 更新第k个源的导向矢量和复幅度 a_k = array_manifold(theta_est(k)); A_est(:,k) = a_k; S_est(k,:) = a_k' * residual / M; end % 收敛判断:所有DOA变化量小于阈值即停止 if max(abs(theta_est - theta_prev)) < tol break; end end

这里的A_est是M×P的当前估计导向矩阵,S_est是P×T的当前估计幅度矩阵。每次内层循环开始时,先算全局残差X - A_est * S_est,再把当前第k个源的贡献加回来,这样就等于减掉了除k以外所有的贡献。这个"先全局减再单独加"的写法在代码上比逐项减更简洁,也不容易漏项。

骨架代码里有一个隐含的关键点:S_est是P×T的复数矩阵,而不是长度为P的复数值。这意味着每个快拍独立计算幅度,relax不要求信号在时间上平稳,这比很多子空间算法灵活。如果信号是窄带恒定的,那么S_est每一行基本一致,最终的估计结果可以取其时间平均来降噪。

注意,骨架代码没有包含初值设置。初值可以用常规子空间算法给出粗估计,或者在角度网格上做P次逐次剥离的粗搜索。我实际调试时发现初值对收敛速度影响很大,但对最终收敛到的局部最优影响更大,所以这个阶段不能省。

4. MATLAB实现:完整relax_doa函数与强弱信号必调参数

4.1 完整主函数代码:从数据读取到DOA输出

这一节给出可以在MATLAB R2023b下直接运行的主函数,包含初值生成、迭代循环和输出。我采用逐次谱峰搜索作为初值估计,也就是先在全角度网格上找最强谱峰,剥离后继续找次强谱峰,这样初始值已经比较接近真值,后续迭代次数可以控制在10轮以内。

function [theta_est, S_est, iter_used] = relax_doa(X, P, theta_grid, max_iter, tol) % RELAX_DOA 用relax算法估计P个信号源的到达角 % 输入: % X - M×T 复基带快拍矩阵 % P - 信源数目 % theta_grid - 角度搜索网格,单位度,建议步长0.1° % max_iter - 最大迭代轮数,默认50 % tol - DOA变化收敛门限,单位度,默认0.01 % 输出: % theta_est - P×1 估计到达角 % S_est - P×T 估计复幅度 % iter_used - 实际迭代轮数 [M, T] = size(X); if nargin < 5, tol = 0.01; end if nargin < 4, max_iter = 50; end % 导向矢量函数,d/lambda = 0.5 array_manifold = @(theta) exp(-1j*pi*(0:M-1)'*sin(theta*pi/180)); % 初值估计:逐次谱峰搜索 theta_init = zeros(P, 1); residual_init = X; for k = 1:P a_grid = array_manifold(theta_grid); power = abs(a_grid' * residual_init) .^ 2; [~, idx] = max(power); theta_init(k) = theta_grid(idx); a_k = array_manifold(theta_init(k)); s_k = a_k' * residual_init / M; residual_init = residual_init - a_k * s_k; end % 初始化迭代变量 theta_est = theta_init; S_est = zeros(P, T); for k = 1:P S_est(k, :) = array_manifold(theta_est(k))' * X / M; end % 主迭代循环 for iter = 1:max_iter theta_prev = theta_est; A_est = array_manifold(theta_est); for k = 1:P % 剥离除k以外所有源后得到残差 residual = X - A_est * S_est; residual = residual + A_est(:, k) * S_est(k, :); % 在当前残差上搜索角度 power = abs(array_manifold(theta_grid)' * residual) .^ 2; [~, idx] = max(power); theta_est(k) = theta_grid(idx); % 更新导向矩阵的第k列,并重估复幅度 A_est(:, k) = array_manifold(theta_est(k)); S_est(k, :) = A_est(:, k)' * residual / M; end % 收敛判断 delta = max(abs(theta_est - theta_prev)); if delta < tol iter_used = iter; break; end if iter == max_iter iter_used = max_iter; end end end

函数整体的数据流是:先用逐次谱峰搜索给P个源一个初值,然后进入交替优化。初值阶段每个源找到后立即剥离,保证后找的源不会重复看到同一个强峰。主迭代阶段对每个源做同样的剥离加搜索操作,但初值已经接近真值,搜索的结果只会微调方向角。

幅度更新用S_est(k, :) = A_est(:, k)' * residual / M这一行完成。它对应的是最小二乘投影公式s = a^H y / M,其中M是阵元数归一化因子。这里取所有快拍同时计算,因此在MATLAB里是矩阵乘向量得到一行复数序列。

运行示例:

load('sim_data.mat'); theta_grid = -90:0.1:90; [theta_est, S_est, iter_used] = relax_doa(X, 2, theta_grid, 50, 0.01); disp(theta_est);

预期的输出应接近[-3.0, 7.0],强源通常第一轮就能估计很准,弱源需要2到5轮迭代才能收敛到偏差0.1°以内。

4.2 三个必调参数:搜索步长、收敛门限、迭代轮数的取值策略

使用这个函数时,参数选择直接决定了估计精度和计算开销的平衡点。角度网格的步长首当其冲。步长0.1°意味着1800个网格点,每次角度搜索要计算1800个导向矢量的投影,这个计算量在8阵元、200快拍下完全可接受。但如果阵元数增加到32或更多,建议把步长先放宽到0.2°完成粗估计,再用一维插值或局部细网格精修。

收敛门限tol也不是越小越好。tol取0.01°已经在数值上接近单精度浮点对角度分辨力的极限,继续减小只会白白增加迭代次数,因为DOA更新往往在一个小范围内来回抖动而不是单调逼近。我自己常用的策略是先跑一轮看DOA序列,如果出现两个相邻网格点之间的振荡,说明tol设得太小,把1倍网格步长作为tol其实最合理。

最大迭代轮数max_iter的作用是防止收敛失败时无限循环。relax在初值合理时,通常在5轮以内就能稳定;但接近相干信号或低信噪比时,可能需要在两个局部最优之间反复切换,这时候固定50轮的上限是安全选择。如果到达50轮还没收敛,优先检查初值是否被噪声峰带偏,而不是盲目增加迭代次数。

4.3 从单次估计到多次快拍拼统计性能:均方根误差与探测概率怎么算

单次运行输出的theta_est只能说明一次采样的估计结果,要评估relax算法在强弱信号场景下的实际表现,必须做蒙特卡洛实验。每次实验重新生成一组噪声和随机初相信号,记录两组估计结果,最后统计每个源的均方根误差和探测成功率。

% relax_monte_carlo.m % 蒙特卡洛验证:统计强弱信号DOA估计的RMSE trials = 200; rmse = zeros(2, 1); detect_prob = zeros(2, 1); theta_gt = [-3, 7]; for trial = 1:trials % 重新生成随机信号与噪声 S = [10*exp(1j*2*pi*rand(1,T)); 1*exp(1j*2*pi*rand(1,T))]; noise = (randn(M,T) + 1j*randn(M,T))/sqrt(2); A = array_manifold(theta_gt); X = A * S + noise; [theta_est, ~, ~] = relax_doa(X, 2, theta_grid, 50, 0.02); % 按距离就近匹配估计与真值 [theta_sorted, ~] = sort(theta_est); for p = 1:2 err = abs(theta_sorted(p) - theta_gt(p)); rmse(p) = rmse(p) + err^2; if err < 1 detect_prob(p) = detect_prob(p) + 1; end end end rmse = sqrt(rmse / trials); detect_prob = detect_prob / trials; fprintf('强源RMSE: %.3f°, 探测概率: %.2f\n', rmse(1), detect_prob(1)); fprintf('弱源RMSE: %.3f°, 探测概率: %.2f\n', rmse(2), detect_prob(2));

这段蒙特卡洛代码里的探测概率定义是估计误差小于1°即认为探测成功。在20 dB强弱功率差、8阵元、200快拍的条件下,强源的RMSE通常能到0.05°以下,弱源在0.3°左右,探测概率应高于95%。如果弱源探测概率偏低,问题大概率出在初值搜索时被强源的旁瓣覆盖,需要增强第一次搜索的稳健性。

5. relax算法避坑:5条血泪经验

5.1 初值被强源旁瓣带偏导致收敛到错误局部最优

现象:弱源的真实角度在7°,但最后估计结果报出9.6°甚至13°,而且迭代多次后死活拉不回来。

原因:初值阶段逐次谱峰搜索找第二个源时,强源虽然已经被剥离过一次,但剥离是建立在强源幅度估计准确的前提下。如果强源的角度初值偏差超过半个主瓣宽度,剥离后的残差里会残留功率泄漏,这些泄漏在弱源角度附近形成比弱源真实谱峰更高的旁瓣,导致弱源初值被吸引到旁瓣顶点。

解决:初值搜索时第一轮谱峰搜索不直接用单峰最大值,而是把功率谱里最大的两个局部峰同时记录下来作为候选。我通常的做法是先找全局最大峰,再从角度范围里排除该峰主瓣宽度约2倍的区域后找局部最大峰,这样弱源初始值大概率落在正确主瓣附近。另一种做法是用前两轮迭代的粗结果做对比,确认弱源角度不在强源旁瓣位置的整数倍间隔上。

5.2 强信号剥离不彻底,弱信号残差能量被淹没

现象:迭代已经收敛,但弱源角度始终有系统性偏移,例如真值7°估计成5.8°,且偏移方向固定不变。

原因:relax的剥离操作依赖强源复幅度的估计准确度。如果强源幅度的实部虚部估计有偏差,剥离后的残差里仍然含有强源成分,这些成分对匹配滤波结果产生偏置。尤其在强源到达方向与弱源接近时,强源倾斜泄漏的功率会使弱源搜索的功率峰值沿角度轴移动。

解决:在每个源更新完毕后,增加一次全源联合精修。具体做法是等P个源都更新完一遍后,再从第一个源开始重新计算一次剥离残差,而不是只更新一遍就进入收敛判断。这个二次扫描能够明显压掉系统残留。如果仍不满意,把幅度更新从单次投影改成零强制剥离,也就是残差计算时对强源贡献额外减去其估计值的0.1倍,用小的过减因子试探性补偿漏剥离。

5.3 阵元数不足导致角度网格上出现伪峰

现象:阵元数M等于4或6时,弱源角度搜索的功率谱出现两个邻近的等高峰,一处是真值附近,另一处在远离真值的空间混叠位置。

原因:均匀线阵的导向矢量在角度域不是绝对单峰的,当阵元数较少时,对应sinθ的相位增量范围变窄,角度空间采样不足,导致不同方向的导向矢量之间正交性变弱。两个方向在网格上投影功率相近时,搜索模块无法唯一确定角度。

解决:这个属于硬边界,阵元数低于6时无论怎么调relax参数都没有本质改善。可行的路径是增加接收通道或采用虚拟阵元扩维技术。如果硬件已经固定,可以把角度搜索范围从全空域缩小到先验的有效区域,比如[-30°, 30°],这样至少能排除远端伪峰干扰。

5.4 快拍数太少导致幅度估计方差过大

现象:快拍数T从200降到20,弱源的RMSE从0.3°恶化到2°以上,而且跟踪同一数据重跑算法每次结果不同。

原因:relax的幅度估计本质是线性投影,当快拍数减少时,噪声在投影方向上的平均效应减弱,复幅度估计值起伏变大。幅度不准进一步影响剥离残差,残差又带动角度搜索,形成了误差放大链。

解决:最少快拍数建议维持在3倍阵元数以上,即M=8时T至少24。在更低快拍下稳定运行的方式是引入频域平滑或前后向平均。前后向平均的实现很简单,把X翻转共轭后与原数据拼接成2M×T的扩展数据矩阵,再做relax估计,阵列的有效孔径翻倍,方差显著下降。代价是可估计信源数上限不变但计算量增加。

5.5 两个源的幅度都在变化时收敛判据失稳

现象:仿真中源1和源2的幅度都随时间随机起伏,算法在某些轮次显示DOA变化量小于tol判断收敛,但实际输出角度仍偏移0.5°。

原因:收敛判据只比较DOA变化量,没有检查幅度矢量的变化。当信号幅相快速变化时,DOA可能稳定但幅度估计仍在漂移,反过来下一轮又会拉动DOA。这个偶合关系让单指标收敛判据失效。

解决:收敛判据改为同时检查DOA变化量和重构残差能量变化量。实现时在每次迭代结束后计算||X - A_est*S_est||_F²,与上一轮残差能量对比,变化率小于阈值才判断收敛。残差能量的计算在代码里的额外开销很小,但对稳定性改善明显。

6. 进阶验证技巧:用谱图读取和CRB对比确认relax实现的正确性

6.1 弱信号场景下的功率谱特征检查表

relax实现完成后,不要只看数值输出,应该先做一轮输入输出自检。把迭代过程中每一轮的角度搜索结果记录下来,绘制成类似下面的特征表,对比判断算法行为是否健康。

迭代轮数源1角度估计源2角度估计残差能量备注
1-3.28.445.2强源快速收敛
2-3.07.312.8弱源开始修正
3-3.07.09.1弱源接近真值
4-3.07.08.9残差趋于平稳

实际操作中,残差能量应该单调下降并最终稳定。如果出现残差能量升高的情况,说明某一步的角度更新反而带偏了模型,需要检查是否是幅度和角度之间的耦合更新顺序出了问题。

6.2 和CRB理论界做对比:验证算法性能极限是否还有余量

修完代码后我习惯把估计出的RMSE和理论克拉美罗界放在一起看。若RMSE高出CRB十倍以上,说明实现可能还有问题或参数没调到位;若RMSE接近CRB的两倍以内,说明在当前模型下已经压到了接近理论极限。

% 简易CRB计算,适用于高斯白噪声、非相干源场景 function crb = compute_crb(theta, M, T, snr_db, P) % 返回P×1的DOA的CRB下界,单位度 c = 180/pi; snr = 10.^(snr_db/10); A = exp(-1j*pi*(0:M-1)'*sin(theta*pi/180)); D = zeros(M, P); for p = 1:P D(:,p) = -1j*pi*cos(theta(p)*pi/180) .* (0:M-1)' .* A(:,p); end % FIM角度部分简化为 2*T*snr * real(D'*D) fim = 2 * T * snr' .* real(D' * D); crb = sqrt(diag(inv(fim))) .* c; end

这段CRB计算的简化假设信号功率归一化和噪声方差为1,重点用来做相对对比。若relax给出的RMSE在弱源上距离CRB超过5倍,优先检查弱源初值是否被强源泄漏干扰,或者在迭代中加入对弱源的残差二次加权。

6.3 我的一个落地习惯和这次调试的收尾提醒

relax算法实现多年后,我养成了一个固定习惯:任何一次DOA算法升级,都保留一组固定强弱对比的仿真数据作为回归测试用例。每次改完代码先跑这组数据,看RMSE和探测概率是否出现翻车级别的回退。做强弱信号DOA研究,数据可比性比绝对精度更重要,换了随机种子但性能波动很大,多数情况是算法的不稳定性问题而并非参数没调好。这次整理relax从原理到实现的完整路径花了些功夫,但把这个算法放进自己的工具箱后,以后再碰到强主瓣压弱目标的多径场景,就多了一个可靠的选择。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询