【通信系统】MIMO阵列信号来向DOA估计实现~含FOCUSS、OMP、贝叶斯学习(SBL)等稀疏重构法和常规、子空间法、空间平滑滤波法

MIMO阵列目标信号来向估计原理与实现~基于常规法、子空间变换法和稀疏恢复法

  • 写在最前
  • 前言
    • 空间谱估计的历史发展
  • 仿真原理
    • 离散时间阵列信号模型
    • 波束形成矩阵(完备字典)
    • 回波生成
    • 空间平滑滤波
    • 传统方法
      • CBF~常规波束成型
      • Capon~最小方差无失真响应法
      • ML~最大似然估计法
    • 子空间方法
      • MUSIC~多重信号分类法
      • ESPRIT~旋转不变子空间法
        • 最小二乘准则
        • 总体最小二乘准则
    • 稀疏恢复方法
      • FOCUSS~欠定系统聚焦法
      • OMP~正交匹配追踪法
      • 伪逆法
      • EM-SBL~最大期望-稀疏贝叶斯学习法
      • CVX~凸优化法
  • 仿真实现
    • 代码下载
    • 可修改的参数
    • 仿真结果
      • 常规情况
      • 低信噪比情况
      • 相干信源情况
      • 少快拍情况
    • 仿真小结
  • 后语
  • 附录代码
    • DOA_CBF.m
    • DOA_Capon.m
    • DOA_MUSIC
    • DOA_ESPRIT.m
    • DOA_ML.m
    • DOA_FOCUSS.m
    • DOA_OMP.m
    • DOA_PINV.m
    • DOA_EM_SBL.m
    • DOA_CVX.m
    • space_smooth.m

写在最前

本文章的代码已开源,基于凸优化法(CVX)实现DOA时,依赖CVX工具箱,如果你的MATLAB没有安装,请前往这里下载,解压后在MATLAB命令行,cd到解压目录并执行其中的“cvx_setup.m”文件进行安装。如果不做CVX部分的仿真,可忽略这一步。

前言

波达方向估计(Direction Of Arrival, DOA)也称为测向、空间谱估计,为利用电磁波来获取目标或信源对天线阵列的角度信息,主要应用于雷达、通信、电子侦察与对抗等领域。
本文利用MIMO天线阵列实现DOA相关算法的总结,主要仿真实现了常规波束形成(CBF)、Capon和最大似然估计(ML)三种常规方法,多重信号分类法(MUSIC)、LS-ESPRIT和TLS-ESPRIT三种子空间方法,欠定系统聚焦法(FOCUSS)、正交匹配追踪法(OMP)、凸优化法(CVX)、伪逆法(PINV)和期望最大化-稀疏贝叶斯学习法(EM-SBL)等稀疏恢复方法。对比了上述方法在常规、低信噪比、低快拍以及信源相干情况下的性能,并研究了空间平滑算法在处理相干信源问题上的表现。

空间谱估计的历史发展

常规波束形成
Capon自适应波束形成
信号子空间分类方法
最大似然估计法
压缩感知或稀疏恢复法
深度学习法

本文不涉及深度学习法。

仿真原理

离散时间阵列信号模型

天线阵元示意图如下图所示,在仿真中,默认最左边的阵元为相位中心,仿真的前提为信源发射的信号为窄带信号且为远场信号,阵元为全向天线其阵元之间没有互耦和误差。

天线阵列信号接收示意图

为了方便数字化处理,仿真采用了离散时间阵列信号模型:
[ x 1 ( n ) x 2 ( n ) ⋮ x M ( n ) ] = [ 1 1 ⋯ 1 e − j 2 π d s i n θ 1 / λ e − j 2 π d s i n θ 2 / λ ⋯ e − j 2 π d s i n θ p / λ ⋮ ⋮ ⋱ ⋮ e − j 2 π ( M − 1 ) d s i n θ 1 / λ e − j 2 π ( M − 1 ) d s i n θ 2 / λ ⋯ e − j 2 π ( M − 1 ) d s i n θ p / λ ] [ s 1 ( n ) s 2 ( n ) ⋮ s p ( n ) ] + [ n 1 ( n ) n 2 ( n ) ⋮ n M ( n ) ]     x = A ( θ ) s + n \begin{bmatrix} x_1(n) \\ x_2(n) \\ \vdots \\ x_M(n) \end{bmatrix} = \begin{bmatrix} &1 &1 & \cdots &1 \\ & e^{-j2\pi d \mathrm {sin}\theta _1/\lambda } & e^{-j2\pi d \mathrm {sin}\theta _2/\lambda } & \cdots & e^{-j2\pi d \mathrm {sin}\theta _p/\lambda } \\ & \vdots & \vdots & \ddots & \vdots \\ & e^{-j2\pi (M-1)d \mathrm {sin}\theta _1/\lambda } & e^{-j2\pi (M-1)d \mathrm {sin}\theta _2/\lambda } & \cdots & e^{-j2\pi (M-1)d \mathrm {sin}\theta _p/\lambda } \end{bmatrix} \begin{bmatrix} s_1(n) \\ s_2(n) \\ \vdots \\ s_p(n) \end{bmatrix} + \begin{bmatrix} n_1(n) \\ n_2(n) \\ \vdots \\ n_M(n) \end{bmatrix} \, \\ \, \\ \mathbf{x}=\mathbf{A}(\theta) \mathbf{s}+\mathbf{n} x1(n)x2(n)xM(n) = 1ej2πdsinθ1/λej2π(M1)dsinθ1/λ1ej2πdsinθ2/λej2π(M1)dsinθ2/λ1ej2πdsinθp/λej2π(M1)dsinθp/λ s1(n)s2(n)sp(n) + n1(n)n2(n)nM(n) x=A(θ)s+n
其中, x ∈ C M × N \mathbf{x}\in \mathbb{C}^{M \times N} xCM×N为天线阵列接收到的信号; A ∈ C M × P \mathbf{A}\in \mathbb{C}^{M \times P} ACM×P为空域导向矢量; s ∈ C p × N \mathbf{s} \in \mathbb{C}^{p \times N} sCp×N为目标发出的信号; n ∈ C M × N \mathbf{n} \in \mathbb{C}^{M \times N} nCM×N为噪声; d d d为阵元间隔; λ \lambda λ为载频信号的波长; N N N为快拍数; M M M为阵元数量; P P P为目标数量。

波束形成矩阵(完备字典)

该矩阵也称为DOA栅格矩阵,用于估算在每个角度上的功率,该矩阵的表达式为:
a ( θ 0 , θ 1 , … , θ k ) = [ 1 1 ⋯ 1 e j 2 π d s i n θ 0 / λ e j 2 π d s i n θ 1 / λ ⋯ e j 2 π d s i n θ k / λ e j 2 π ( 2 d ) s i n θ 0 / λ e j 2 π ( 2 d ) s i n θ 1 / λ ⋯ e j 2 π ( 2 d ) s i n θ k / λ ⋮ ⋮ ⋱ ⋮ e j 2 π ( M − 1 ) d s i n θ 0 / λ e j 2 π ( M − 1 ) d s i n θ 1 / λ ⋯ e j 2 π ( M − 1 ) d s i n θ k / λ ] a(\theta_0,\theta_1,\dots,\theta_k)=\begin{bmatrix} & 1 & 1 & \cdots & 1 \\ & e^{j2\pi d \mathrm{sin}\theta _0/\lambda} & e^{j2\pi d \mathrm{sin}\theta _1/\lambda} & \cdots & e^{j2\pi d \mathrm{sin}\theta _k/\lambda} \\ & e^{j2\pi (2d) \mathrm{sin}\theta _0/\lambda} & e^{j2\pi (2d) \mathrm{sin}\theta _1/\lambda} & \cdots & e^{j2\pi (2d) \mathrm{sin}\theta _k/\lambda} \\ & \vdots & \vdots & \ddots & \vdots \\ & e^{j2\pi (M-1)d \mathrm{sin}\theta _0/\lambda} & e^{j2\pi (M-1)d \mathrm{sin}\theta _1/\lambda} & \cdots & e^{j2\pi (M-1)d \mathrm{sin}\theta _k/\lambda} \\ \end{bmatrix} a(θ0,θ1,,θk)= 1ej2πdsinθ0/λej2π(2d)sinθ0/λej2π(M1)dsinθ0/λ1ej2πdsinθ1/λej2π(2d)sinθ1/λej2π(M1)dsinθ1/λ1ej2πdsinθk/λej2π(2d)sinθk/λej2π(M1)dsinθk/λ
其中, θ 0 , θ 1 , … , θ k \theta_0,\theta_1,\dots,\theta_k θ0,θ1,,θk为需要做功率估计的等间距的来向角度; a ∈ C M × ( k + 1 ) a\in \mathbb{C}^{M \times (k+1)} aCM×(k+1)为波束形成矩阵。

回波生成

为了保证信号的正交性,省去上变频步骤,本仿真使用随机数+带通滤波方法实现指定带宽与中心频率的信源生成。针对每个信源在 [ f 0 − b w , f 0 + b w ] [f_0-bw,f_0+bw] [f0bw,f0+bw]之间等间隔地划分k个频段,用高斯分布的随机数初始化矩阵 s s s后,对矩阵的每一行执行对应频段的带通滤波以获得频域正交的信号,是不是有种OFDM的感觉了。

空间平滑滤波

在实际使用中,由于存在多径传输等影响因素。阵列接收到的信源信号往往是相干而非完全独立的,为了解决相干源的DOA估计问题,需要使用空间平滑滤波破坏掉接收信号的相干性。该方法将等数量的相邻的实际阵列构成子阵列,并利用所有子阵列的自相关矩阵的平均数作为阵列接收信号的自相关矩阵估计,从而解决实际自相关矩阵的相干问题。当子阵大小L越大时,去相关能力越强,但等效阵列数会越小,从而降低空间分辨率。该方法可表示为:
R x x ^ = E { R i } \hat {R_{xx}}=E\{ R_i \} Rxx^=E{Ri}
其中 R i R_i Ri为第 i i i个子阵列的自相关矩阵。

传统方法

CBF~常规波束成型

该方法大约在二战期间被提出,其本质是傅里叶变换在空域的直接应用,其分辨率受限于瑞丽限。该方法可表示为:
J C B F ( θ ) = a H ( θ ) R x x a ( θ ) ∣ a H ( θ ) a ( θ ) ∣ 2 J_{CBF}(\theta)=\frac {a^H(\theta)R_{xx}a(\theta)}{|a^H(\theta)a(\theta)|^{2}} JCBF(θ)=aH(θ)a(θ)2aH(θ)Rxxa(θ)

Capon~最小方差无失真响应法

这是一种自适应方法,提出于60年代,它将维纳滤波的思想应用于空域处理,相比于CBF法,分辨率得到了一定的提高。Capon法可表示为:
J C a p o n ( θ ) = 1 a H ( θ ) R x x − 1 a ( θ ) J_{Capon}(\theta)=\frac{1}{a^H(\theta)R_{xx}^{-1}a(\theta)} JCapon(θ)=aH(θ)Rxx1a(θ)1

ML~最大似然估计法

最大似然估计在九十年代提出,实质为给定观测数据,评估模型参数。在DOA估计中,ML法可表示为:
J M L ( θ ) = t r a c ( a ( θ ) a H ( θ ) ( a H ( θ ) a ( θ ) ) − 1 ∗ R x x ) / M J_{ML}(\theta)=\mathrm {trac}(\frac{a(\theta)a^H(\theta)}{(a^H(\theta)a(\theta))^{-1}}*R_{xx})/M JML(θ)=trac((aH(θ)a(θ))1a(θ)aH(θ)Rxx)/M
在只有一个目标信源时,该方法等效于CBF法,在多个信源时,ML法为多目标优化问题,运算量较大。

子空间方法

MUSIC~多重信号分类法

时间回到上世纪八十年代,多重信号分类法在这个时候被提出。相比于CBF和Capon法仅使用接收数据的自相关矩阵直接处理,该方法考虑了信号和噪声的分布特性,通过对自相关矩阵做特征分解得到信号子空间和噪声子空间,利用两个子空间的正交特性进行DOA估计。
由于接收信号的自相关矩阵为赫米特(Hermite)矩阵,满足 R H = R R^H=R RH=R,根据相关引理, R R R酉相似于对角矩阵,可进行酉对角化分解,即存在 酉矩阵 U U U和对角阵 V V V,使 U H R U = V U^HRU=V UHRU=V,且V主对角线上的元素为 R R R的特征值。
MUSIC方法可表示为:
J M U S I C ( θ ) = a H ( θ ) a ( θ ) a H ( θ ) ( I − U s U s H ) a ( θ )   或   J M U S I C ( θ ) = a H ( θ ) a ( θ ) a H ( θ ) ( U n U n H ) a ( θ ) J_{MUSIC}(\theta)=\frac{a^H(\theta)a(\theta)}{a^H(\theta)(I-U_sU_s^H)a(\theta)}\, 或 \\ \, \\ J_{MUSIC}(\theta)=\frac{a^H(\theta)a(\theta)}{a^H(\theta)(U_nU_n^H)a(\theta)} JMUSIC(θ)=aH(θ)(IUsUsH)a(θ)aH(θ)a(θ)JMUSIC(θ)=aH(θ)(UnUnH)a(θ)aH(θ)a(θ)
其中, U s ∈ C M × k U_s\in \mathbb{C}^{M\times k} UsCM×k为信号子空间,为 U U U k k k个最大特征值所对应的特征列向量组成的矩阵; U n ∈ C M × ( M − k ) U_n\in \mathbb{C}^{M\times (M-k)} UnCM×(Mk)为噪声子空间; k k k表示信源个数。在应用中可根据信源数量选择信号子空间解法或噪声子空间解法。

ESPRIT~旋转不变子空间法

与MUSIC法在同一时期被提出的子空间方法还有旋转不变子空间法,区别于MUSIC使用酉对角化后信号和噪声子空间的正交性,ESPRIT利用信号子空间的旋转不变特性来求解DOA。
假设存在两个完全相同的子阵列,且子阵列的间距 Δ \Delta Δ已知,假设两个子阵列接收到数据分别为 x 1 x_1 x1 x 2 x_2 x2,则:
x 1 = A s + n 1   x 2 = A Φ s + n 2   Φ = d i a g ( e j ϕ 1   e j ϕ 2   ⋯   e j ϕ p ) x_1=As+n_1 \\ \, \\ x_2=A\Phi s+n_2 \\ \, \\ \Phi=\mathrm {diag}(e^{j\phi_1} \, e^{j\phi_2} \, \cdots \, e^{j\phi_p}) x1=As+n1x2=AΦs+n2Φ=diag(ejϕ1ejϕ2ejϕp)
只要得到两个子阵列的旋转不变关系 Φ \Phi Φ,就能得到信号的到达角,完成DOA估计。
仿真时,令 x 1 x_1 x1 x 2 x_2 x2分别为接收到的信号 x \mathbf{x} x的前 M − 1 M-1 M1行和后 M − 1 M-1 M1行所构成的两个子矩阵,令回波子阵列合并为 x e x p = [ x 1 ; x 2 ] x_{exp}=[x_1;x_2] xexp=[x1;x2],计算 x e x p x_{exp} xexp的自相关矩阵 R e s p = E { x e x p ∗ x e x p H } R_{esp}=E\{x_{exp}*x_{exp}^H\} Resp=E{xexpxexpH},对 R e s p R_{esp} Resp做酉对角化分解,得到酉矩阵 U e s p U_{esp} Uesp和特征值对角矩阵 V e x p V_{exp} Vexp。根据目标数量从 U e s p U_{esp} Uesp中提取信号子空间并进行拆分得到 U s U_s Us的前M-1行 U s 1 U_{s1} Us1和后M-1行 U s 2 U_{s2} Us2,接下来需要求解ESPRIT矩阵 Ξ \Xi Ξ,使:
U s 1 Ξ = U s 2 U_{s1}\Xi=U_{s2} Us1Ξ=Us2
求解出ESPRIT矩阵 Ξ \Xi Ξ后,通过求取该矩阵的特征值并求其复角度即可得到来向角的正弦值,即:
D O A e x p = a r c s i n ( − a n g l e ( V e s p ) ∗ λ 2 π d ) DOA_{exp}=\mathrm{arcsin}(\frac {-\mathrm {angle}(V_{esp})*\lambda}{2\pi d}) DOAexp=arcsin(2πdangle(Vesp)λ)
其中, V e s p ∈ C P × 1 V_{esp}\in \mathbb{C}^{P \times 1} VespCP×1是由 Ξ \Xi Ξ的特征值构成的向量。
求解ESPRIT矩阵 Ξ \Xi Ξ可以使用最小二乘准则或总体最小二乘准则。

最小二乘准则

不难证明,在最小二乘准则下,使用下式对ESPRIT矩阵 Ξ L S \Xi_{LS} ΞLS进行求解:
Ξ L S = p i n v ( U s 1 ) ∗ U s 2 \Xi_{LS}=\mathrm {pinv}(U_{s1})*U_{s2} ΞLS=pinv(Us1)Us2

总体最小二乘准则

在总体最小二乘准则下,令 V T L S − e s p = [ U s 1 , U s 2 ] V_{TLS-esp}=[U_{s1},U_{s2}] VTLSesp=[Us1,Us2]并对V做奇异值分解得到右奇异矩阵 V T L S − E S P ∈ C ( P ∗ 2 ) × ( P ∗ 2 ) V_{TLS-ESP}\in \mathbb{C}^{(P*2)\times (P*2)} VTLSESPC(P2)×(P2),将 V T L S − E S P V_{TLS-ESP} VTLSESP等分为4个方阵并取右上角方阵和右下角方阵分别记为 E 12 E_{12} E12 E 22 E_{22} E22,即可解出ESPRIT矩阵 Ξ T L S \Xi_{TLS} ΞTLS
Ξ T L S = − E 12 ∗ i n v ( E 22 ) \Xi_{TLS}=-E_{12} * \mathrm {inv}(E_{22}) ΞTLS=E12inv(E22)

稀疏恢复方法

终于写到我最感兴趣的部分了。
2004年,陶哲轩、Emmanuel Candes和David Donoho等人证明了“如果信号是稀疏的,那么它可以由远低于采样定理要求的采样点恢复信号”,紧接着提出了“压缩感知”概念。总得来讲,稀疏恢复的前提条件之一为信号的稀疏性,即信号在某个域(常用作信号处理的领域包括时域、频域、多普勒域和空域等)上是稀疏的,在该域上零点的数量远远大于非零点的数量;前提条件之二为观测矩阵和稀疏表示基之间的不相关。如果一个信号在某个变换域是稀疏的,那么可以用一个与变换基不相关观测矩阵将变换所得高维信号投影到一个低维空间上,然后通过求解一个优化问题可从这些少量投影中以高概率重构出信号。
压缩感知的步骤包括压缩采样和信号重构:
压缩采样:
y = Φ Ψ s = Θ s y=\Phi \Psi s=\Theta s y=ΦΨs=Θs
Φ \Phi Φ Ψ \Psi Ψ分别为观测矩阵和稀疏表示基,它们是不相关的; Θ \Theta Θ为传感矩阵
信号重构:
min ⁡ s ∥ s ∥ 0   s . t .   y = Θ s \min_{s}\| s \|_0 \, \mathrm{s.t.} \, y=\Theta s smins0s.t.y=Θs
其中 ∥ ⋅ ∥ 0 \| \cdot \|_0 0 p 0 p_0 p0范数,表示 x x x中非零元素的个数,在实际求解中,一般将该约束松弛为 p 1 p_1 p1 p 2 p_2 p2等范数。
对于方程: y = Θ s y=\Theta s y=Θs,已知 y y y Θ \Theta Θ求解未知数 x x x时,如果超定方程,问题实质为拟合问题;如果 Θ \Theta Θ为满秩的方阵,问题则为线性方程组求解;当 Θ \Theta Θ为欠定时,才是稀疏恢复问题。
在仿真中,对接收信号的自相关矩阵 R x x R_{xx} Rxx做酉对角化后,取酉矩阵中最大特征值对应的特征向量作为稀疏恢复的观测值矩阵y,将波束形成矩阵 a a a作为传感器矩阵,稀疏恢复得到的 s s s即为DOA估计结果,即求解方程:
y = a s y=as y=as

FOCUSS~欠定系统聚焦法

在该方法中,首先确定 s 0 s_0 s0的迭代初始值为:
s 0 = a H i n v ( a a H ) y s_0=a^H\mathrm {inv}(aa^H)y s0=aHinv(aaH)y
迭代过程为:
W = d i a g ( s k 1 − λ s p e / 2 )   s k + 1 = W W H a H ∗ i n v ( a W W H a H + λ r e g I ) ∗ y W=\mathrm{diag}(s_k^{1-\lambda_{spe}/2}) \\ \, \\ s_{k+1}=WW^Ha^H*\mathrm{inv}(aWW^Ha^H+\lambda_{reg}I)*y W=diag(sk1λspe/2)sk+1=WWHaHinv(aWWHaH+λregI)y
其中, λ r e g \lambda_{reg} λreg为正则化因子,过大会趋于0解,过小结果发散; λ s p e \lambda_{spe} λspe为稀疏因子,效果等效于稀疏解的范数约束。
迭代次数超过最大给定次数,或误差小于误差限制 λ e r r \lambda_{err} λerr(即 ∥ s k + 1 − s k ∣ 2 ∥ s k ∥ < λ e r r \frac {\|s_{k+1}-s_k |_2}{\| s_k \|}<\lambda_{err} sksk+1sk2<λerr)时,结束迭代。

OMP~正交匹配追踪法

该方法的迭代步骤如:

  1. 初始化,令标签集 Ω m a s k \Omega_{mask} Ωmask为空集并初始化残差向量 r 0 = y r_0=y r0=y
  2. 辨识,求取传感器矩阵 a a a中与残差向量 r k r_k rk最强相关的原子,即 j k ∈ a r g   m a x ∣ < r k , ϕ j > ∣ j_k\in \mathrm{arg\, max|<r_k,\phi_j>|} jkargmax∣<rk,ϕj>,往 Ω m a s k \Omega_{mask} Ωmask中添加该原子的索引。
  3. 估计,最小化问题 m i n x ∥ y − Φ Ω k x ∥ 2 2 min_x \| y-\Phi_{\Omega_k}x \|_2^2 minxyΦΩkx22的最小二乘解为 x k = i n v ( Φ Ω k H Φ Ω k ) ∗ Φ Ω k H y x_k=\mathrm{inv}(\Phi_{\Omega_k}^H\Phi_{\Omega_k})*\Phi_{\Omega_k}^Hy xk=inv(ΦΩkHΦΩk)ΦΩkHy
  4. 更新残差, r k + 1 = [ I − Φ Ω k ( Φ Ω k T Φ Ω k ) − 1 Φ Ω k T ] y r_{k+1}=[I-\Phi_{\Omega_k}(\Phi_{\Omega_k}^T\Phi_{\Omega_k})^{-1}\Phi_{\Omega_k}^T]y rk+1=[IΦΩk(ΦΩkTΦΩk)1ΦΩkT]y
  5. 重复步骤2~4直到满足迭代停止条件,退出条件包括迭代次数达到字典的栅格数,或者 a ( : , Ω m a s k ) ′ ∗ a ( : , Ω m a s k ) a(:,\Omega_{mask})'*a(:,\Omega_{mask}) a(:,Ωmask)a(:,Ωmask)为奇异矩阵。
  6. 输出结果,
    x ( i ) = { x k ( i ) , i ∈ Ω m a s k 0 , 其它 x(i)=\left\{\begin{matrix} &x_k(i) &,& i \in \Omega_{mask} \\ &0 &, & 其它 \end{matrix}\right. x(i)={xk(i)0,,iΩmask其它

伪逆法

对于方程: y = a s y=as y=as,令解s为:
s = y H ∗ p i n v ( a ) H s=y^H*{\mathrm {pinv}(a)}^H s=yHpinv(a)H
该方法因为运算量较大且产生的不是稀疏解,在实际工程中很少使用,在仿真中仅用于效果对比。

EM-SBL~最大期望-稀疏贝叶斯学习法

SBL算法是稀疏信号重构的重要算法,涉及高斯分布、最大似然估计、贝叶斯公式等数学理论,由于推导过程比较复杂,主要是我懒得敲了,后续如果读者有强烈需要我再更新一下吧^_^,这里直接介绍推导结果。该方法迭代的步骤为:

  1. 初始化,令 Γ 0 = 0.1 ∗ I \Gamma_0=0.1*I Γ0=0.1I
  2. E-step,令 σ x = p i n v ( σ ( a H a + p i n v ( Γ k ) ) \sigma_x=\mathrm {pinv}(\sigma(a^Ha+\mathrm {pinv}(\Gamma_k)) σx=pinv(σ(aHa+pinv(Γk)),令 μ x = σ x σ − 1 a H R x x \mu_x=\sigma_x\sigma^{-1}a^HR_{xx} μx=σxσ1aHRxx,其中 σ \sigma σ表示阵列接收信号的估计噪声方差, R x x R_{xx} Rxx为接收信号的自相关矩阵。
  3. M-step,令 Γ k + 1 = μ x ( θ ) ∗ μ x ( θ ) H / N + σ x ( θ ) \Gamma_{k+1}=\mu_x(\theta)*\mu_x(\theta)^H/N+\sigma_x(\theta) Γk+1=μx(θ)μx(θ)H/N+σx(θ)
  4. 重复步骤2和3,直到达到最大迭代次数或 ∥ Γ k + 1 − Γ k ∥ 1 < 误差限 \|\Gamma_{k+1}-\Gamma_{k}\|_1<误差限 Γk+1Γk1<误差限

CVX~凸优化法

由于方程“ y = a s y=as y=as”的求解可以转化为凸优化问题:
a r g   m i n s ∥ s ∥ p   ,   s . t . ∥ y − a s ∥ 2 < λ l i m arg \, min_s \| s\|_p \, , \, \mathrm{s.t.} \|y-as\|_2<\lambda_{lim} argminssp,s.t.yas2<λlim
因此可以使用凸优化工具箱进行求解,并且还可以根据需要调整用于约束稀疏解 s s s的范数,当使用 p 1 p_1 p1范数时,上述优化将产生稀疏解,当范数 p p p增大时,相当于增加了松弛量,解密度会越来越大,从而变得越来越不稀疏。
λ l i m \lambda_{lim} λlim为收敛控制量,过小可能产生发散的结果,过大则可能产生非稀疏解。

仿真实现

代码下载

代码已上传到GitHub:https://github.com/highskyno1/MIMO_DOA

可修改的参数

  1. 载波频率 f 0 f_0 f0:信源发射信号的中心频率。
  2. 系统全局采样率 f g f_g fg:由于仿真是数字系统,该采样率为仿真所使用的全局采样率。
  3. 信号带宽 B W BW BW:信源发射信号的总带宽,当存在多个信源时,如果使用非相干生成模式,会根据总带宽为每个信源划分不重合的等长信号频段;否则所有信源使用整个带宽的频段。
  4. 目标来向角度 s r c a n g l e src_{angle} srcangle:目标真实的相对于阵元平面法线的入射角度,内部元素数量被计算为目标数。考虑到实际的MIMIO阵列的扫描角度一般只有120°,取值范围为[-60°,60°],如果要在这个范围外取值,请连同 s c a n a n g l e scan_{angle} scanangle一起修改。
  5. 阵元数量 M M M:MIMO阵列阵元数量。
  6. 快拍数 L L L:每个阵元的采样点个数。
  7. 信噪比snr:信源发出的信号被收到时的信噪比。
  8. 扫描角度 s c a n a n g l e scan_{angle} scanangle:控制波束形成矩阵的角度,也称为完备字典或DOA栅格,可以改变间隔以提高空域采样率,注意空域分辨率不因空域采样率的改变而改变。
  9. 是否使用空间平滑滤波is_space_smooth:逻辑变量,置为ture时使能空间平滑滤波以解决信源的相干性问题。
  10. 是否产生相干的信源is_coherent:逻辑变量,置为true时将产生频域重叠的相干信源。

仿真结果

常规情况

在信源不相干,信噪比达到20dB,阵元数和快拍数分别为32和128的情况下,DOA结果如下图所示,可见CBF法主瓣最宽、旁瓣最高,其次为EM-SBL方法。CBF、EM-SBL、Capon、MUSIC的主瓣宽度依次减少。在稀疏恢复类型的算法中,FOCUSS算法效果最佳,OMP算法产生了过多的假峰,PINV法和ML法则出现了与传统方法相当的主瓣宽度。CVX方法则没有得到正确的来向角估计。两种准则下的ESPRIT算法均估计出了正确的来向角。
尽管CVX算法的结果不太理想,但仍可以发现在p1范数约束下将产生较为稀疏的解,随着范数的增加,稀疏恢复结果变得越来越不稀疏。

常规情况下多种DOA评估算法的仿真结果

低信噪比情况

修改信噪比为0dB,仿真结果如下图所示,可见此时常规方法和MUSIC法仍然可以正常工作;ESPRIT算法估计的DOA角度出现偏差;稀疏恢复部分,FOCUSS方法仍然表现出良好的性能,OMP法的假峰消失,CVX方法的零陷刚好落在真实来波方向上。

低信噪比(0dB)情况下多种DOA评估算法的仿真结果

修改信噪比为-10dB,仿真结果如下图所示,此时大部分算法都只能找到其中的一个来向角。

低信噪比(-10dB)情况下多种DOA评估算法的仿真结果

相干信源情况

信源发射信号相干且使用平滑滤波时,仿真结果如下图所示,可见子空间类型算法和Capon法只能发现一个来向的角度,但稀疏恢复算法和CBF

信源发射信号相干且不使用平滑滤波时多种DOA评估算法的仿真结果

信源发射信号相干且使用平滑滤波时,设置等效阵元数量为14,仿真结果如下图所示,此时Capon法、MUSIC法变得正常,可以分辨两个来向的信号,但ESPRIT仍然无法使用。但由于等效阵元数的降低,DOA结果的主瓣变换,降低了空域分辨率,这与理论是符合的。

信源发射信号相干且使用平滑滤波时多种DOA评估算法的仿真结果

少快拍情况

基于正常情况设置快拍数为32个(刚好等于阵元数)时,仿真结果如下图所示,可见此时算法仍然可以正常工作。

少快拍(32个)情况下多种DOA评估算法的仿真结果

观察更极限的情况,设置快拍数为2,仿真结果如下图所示,可见此时CBF法仍然可以正常工作,Capon法出现了相当多的假峰,ESPRIT算法已无法正常工作。稀疏恢复类型的算法在此种情况下表现出了极佳的性能,FOCUSS算法可以准确地估计出来向角,CVX法可以正常工作但有一定误差,OMP算法在真实来向附近产生了多个假峰。

少快拍(2个)情况下多种DOA评估算法的仿真结果

仿真小结

  1. CBF算法是万精油,可以用在低信噪比、低快拍和信源相干情况下,低时间复杂度,少空间占用使得它时至今天仍然是DOA的主流算法之一,在你不知道使用什么算法时,不妨先试试CBF吧。
  2. 稀疏恢复算法是概率类型的算法,每次执行都可能产生不一样的结果,这种算法优点在于可以获得很高的分辨率(超分辨率识别),并且可以在低快拍和信源相干情况下使用,是当前除了机器学习算法外的研究主流,稀疏算法唯一的缺点在于它的鲁棒性欠佳,且只能在高信噪比下使用,高信噪比也对应了空域“稀疏”。

后语

心里话:终于写完了!!!这篇长文从代码重构,到撰写与敲公式前前后后画了差不多一个星期,文中的所有公式、符号和矩阵等都是用 L a t e x \mathcal{Latex} Latex手敲的,通过撰写这篇文章我的Latex技术又得到了精进。
这是三年后复出的第二弹,后面还有,敬请期待。
看到这里了,点个赞再走吧,让我知道有人把文章看完也是我写下去的动力!

附录代码

仅附录DOA主要部分的代码,完整代码的下载请前往GitHub。

DOA_CBF.m

function P_cbf = DOA_CBF(scan_a, R)
% DOA_CBF 基于常规波束形成法实现DOA估计
%   scan_a  需要估计的来波方向
%   R       快拍的协方差矩阵,L*L维,L为快拍数
%   P_cbf   各个scan_a栅格上的来波归一化强度

scan_len = size(scan_a,2);
P_cbf = zeros(1,scan_len);
for i = 1:scan_len
    foo = scan_a(:,i);
    P_cbf(i) = foo' * R * foo / (foo' * foo)^2;
end
P_cbf = abs(P_cbf);
P_cbf = P_cbf ./ max(P_cbf);
end

DOA_Capon.m

function P_capon = DOA_Capon(scan_a, R)
% DOA_Capon 基于Capon法实现DOA估计
%   scan_a  需要估计的来波方向
%   R       快拍的协方差矩阵,L*L维,L为快拍数
%   P_capon 各个scan_a栅格上的来波归一化强度

scan_len = size(scan_a,2);
P_capon = zeros(1,scan_len);
for i = 1:scan_len
    foo = scan_a(:,i);
    P_capon(i) = 1 / (foo' * pinv(R) * foo);
end
P_capon = abs(P_capon);
P_capon = P_capon ./ max(P_capon);
end

DOA_MUSIC

function P_music = DOA_MUSIC(U, target_len, scan_a)
% DOA_MUSIC 基于多重信号分类法实现DOA估计
%   U           对接收信号的自相关矩阵做酉对角化分解后的左酉矩阵
%   target_len  目标数量
%   rec_len     阵元数量
%   scan_a      DOA估计栅格

% 计算阵元数和栅格数
[rec_len,scan_len] = size(scan_a);
W = fliplr(U);
% 已知只有两个信源,用信号子空间法
U_s = W(:,1:target_len);
U_music = eye(rec_len) - U_s * U_s';
P_music = zeros(1,scan_len);
for i = 1:scan_len
    foo = scan_a(:,i);
    P_music(i) = 1 / (foo' * U_music * foo);
end
P_music = abs(P_music);
P_music = P_music ./ max(P_music);
end

DOA_ESPRIT.m

function [DOA_esp_ml, DOA_esp_tls] = DOA_ESPRIT(x_sig, target_len, lamda, d)
% DOA_ESPRIT 基于旋转不变子空间法实现DOA
%   x_sig       每个阵元接收到的信号矩阵,阵元数*快拍数
%   target_len  目标数量
%   lamda       载波波长
%   d           阵元间隔
%   DOA_esp_ml  基于最大似然估计准则得到的估计结果
%   DOA_esp_tls 基于最小二乘准则得到的估计结果

% 计算阵元数
rec_len = size(x_sig,1);
% 回波子阵列合并
x_esp = [x_sig(1:rec_len-1,:);x_sig(2:rec_len,:)];
% 计算协方差
R_esp = cov(x_esp');
% 特征分解
[~,~,W] = eig(R_esp);
% 获取信号子空间
W = fliplr(W);
U_s = W(:,1:target_len);
% 拆分
U_s1 = U_s(1:rec_len-1,:);
U_s2 = U_s(rec_len:end,:);

%% LS-ESPRIT法
mat_esp_ml = pinv(U_s1) * U_s2;
% 获取对角线元素并解算来向角
DOA_esp_ml = -angle(eig(mat_esp_ml));
DOA_esp_ml = asin(DOA_esp_ml .* lamda ./ 2 ./ pi ./ d);
DOA_esp_ml = rad2deg(DOA_esp_ml);

%% TLS-ESPRIT
V = [U_s1,U_s2];
[~,~,V] = svd(V);
% 提取E12和E22
E12 = V(1:target_len,target_len+1:end);
E22 = V(target_len+1:end,target_len+1:end);
mat_esp_tls = - E12 / E22;
% 获取对角线元素并解算来向角
DOA_esp_tls = -angle(eig(mat_esp_tls));
DOA_esp_tls = asin(DOA_esp_tls .* lamda ./ 2 ./ pi ./ d);
DOA_esp_tls = rad2deg(DOA_esp_tls);
end

DOA_ML.m

function P_ml = DOA_ML(scan_a, R_sig)
% DOA_ML 基于最大似然估计法得到DOA估计
%   scan_a  DOA估计栅格矩阵
%   R_sig   接收信号的自相关矩阵,阵元数*阵元数
%   P_ml    通过ML法得到的归一化估计结果

% 计算阵元数和栅格数
[rec_len,scan_len] = size(scan_a);
P_ml = zeros(1,scan_len);
for i = 1:scan_len
    scan = scan_a(:,i);
    Pa = scan / (scan'*scan) * scan';
    P_ml(i) = trace(Pa*R_sig) / rec_len;
end
P_ml = abs(P_ml);
P_ml = P_ml ./ max(P_ml);
end

DOA_FOCUSS.m

function P_focuss = DOA_FOCUSS(scan_a, u, lamda_spe, lamda_reg, lamda_err)
% DOA_FOCUSS 基于欠定系统局灶解法(Focal Under determinedSystem Solver)
% 实现稀疏恢复获得DOA估计结果
%   scan_a      DOA估计的栅格,在稀疏恢复理论中也称为"超完备字典"
%   u           对回波自相关矩阵做酉对角化后,最大特征值对应的酉向量
%   lamda_spe   稀疏因子,效果类似于结果的范数约束
%   lamda_reg   正则化因子,过大会趋于0解,过小结果发散
%   lamda_err   迭代结束误差
%   P_focuss    通过FOCUSS法得到的归一化来波方向功率估计

% 计算阵元数
rec_len = size(u,1);
% 确定s的初始值
Dg = scan_a;
s0 = Dg' / (Dg * Dg') * u;
for i = 1:1000
    W = diag(s0.^(1-lamda_spe/2));
    s = W * W' * Dg' / (Dg * (W * W') * Dg' + lamda_reg .* eye(rec_len)) * u;
    if norm(s - s0,2) / norm(s0,2) < lamda_err
        break;
    end
    s0 = s;
end
P_focuss = abs(s);
% 数据饱和钳制
P_focuss = P_focuss ./ max(P_focuss);
P_focuss(P_focuss < 1e-4) = 1e-4;
end

DOA_OMP.m

function P_omp = DOA_OMP(u, scan_a, omp_toler)
% 基于正交匹配追踪法实现来波的DOA估计
%   u           对回波自相关矩阵做酉对角化后,最大特征值对应的酉向量
%   scan_a      DOA估计的栅格,在稀疏恢复理论中也称为"超完备字典"
%   omp_toler   容许的最小误差,低于此误差时结束迭代
%   P_omp       基于OMP法得到的不同方向来波功率估计

% 计算阵元数量和栅格数量
[rec_len,scan_len] = size(scan_a);
% 初始化标签集合
omp_omiga_mask = zeros(1,scan_len,'logical');
% 初始化初始向量
omp_r = u;
for i = 1:scan_len
    % 求字典矩阵中与残差向量rk-1最强相关的原子
    foo = abs(omp_r' * scan_a);
    [~,idx] = max(foo);
    % 往omiga中添加该列索引
    omp_omiga_mask(idx) = true;
    % 依据索引从字典中选出需要的列向量
    omp_omiga_foo = scan_a(:,omp_omiga_mask);
    % 奇异判断
    rms = det(omp_omiga_foo' * omp_omiga_foo);
    % 退出条件
    if rms < omp_toler
        break;
    end
    % 最小化min(x) ||y-fa*x|| L2范数的平方最小
    omp_xk = (omp_omiga_foo' * omp_omiga_foo) \ omp_omiga_foo' * u;
    % 更新残差
    omp_r = (eye(rec_len) - omp_omiga_foo / (omp_omiga_foo.'*omp_omiga_foo) * omp_omiga_foo.') * u;
end
P_omp = zeros(1,scan_len);
% 提取结果
foo = find(omp_omiga_mask==true);
P_omp(foo(1:length(omp_xk))) = abs(omp_xk)';
% 归一化
P_omp = P_omp ./ max(P_omp);
P_omp(P_omp < 1e-4) = 1e-4;
end

DOA_PINV.m

function s_pinv = DOA_PINV(u, scan_a)
% DOA_PINV 基于伪逆法实现稀疏恢复,效果等同于最大似然估计法
%   u       对回波自相关矩阵做酉对角化后,最大特征值对应的酉向量
%   scan_a  DOA估计的栅格,在稀疏恢复理论中也称为"超完备字典"
%   s_pinv  基于PINV法得到的不同来波方向的归一化功率

s_pinv = u' * pinv(scan_a)';
s_pinv = abs(s_pinv);
s_pinv = s_pinv ./ max(s_pinv);
end

DOA_EM_SBL.m

function s_sbl = DOA_EM_SBL(sigma, scan_a, R_sig, shot_len, err_lim, times_lim)
% 基于期望最大化-稀疏贝叶斯学习方法实现DOA估计
%   sigma       估计的噪声方差
%   scan_a      DOA估计的栅格,在稀疏恢复理论中也称为"超完备字典"
%   R_sig       回波自相关矩阵
%   shot_len    快拍数
%   err_lim     迭代误差限,迭代退出的条件之一
%   times_lim   迭代次数限制,迭代退出的条件之二

% 计算DOA栅格数量
scan_len = size(scan_a,2);
times_cnt = 0;
Gamma = eye(scan_len)*0.1;  % 初始Gamma矩阵
while true 
    times_cnt = times_cnt + 1;
    % E-step
    Sigma_x = pinv(sigma * (scan_a'*scan_a) + pinv(Gamma));
    Mu_x = Sigma_x / sigma * scan_a' * R_sig;
    % M-step
    Gamma_new = Gamma;
    for i = 1:scan_len
        mu_xn = Mu_x(i,:); 
        Gamma_new(i,i) = mu_xn*mu_xn'/shot_len + Sigma_x(i,i);
    end
    if sum(abs(diag(Gamma_new - Gamma))) < err_lim || times_cnt > times_lim
        break;
    end
    Gamma = Gamma_new;
end
Gamma_new = abs(diag(Gamma_new));
s_sbl = Gamma_new ./ max(Gamma_new);
end

DOA_CVX.m

function s_cvx = DOA_CVX(u, scan_a, p_norm, tor_lim)
% DOA_CVX 尝试利用凸优化方法实现稀疏恢复,获得DOA估计
%   !!使用前必须先安装CVX凸优化工具箱,下载地址为:http://cvxr.com/cvx/download/
%   u       对回波自相关矩阵做酉对角化后,最大特征值对应的酉向量
%   scan_a  DOA估计的栅格,在稀疏恢复理论中也称为"超完备字典"
%   s_cvx   基于CVX法得到的不同方向来波功率估计
%   p_norm  约束结果的P范数
%   tor_lim 对稀疏恢复整体(u - scan_a * s_cvx)的容许限度
%           如果结果为+inf,说明发散了,请增大该值
% 注意在CVX工具箱的scope中
% 尽量调用工具箱自己的函数(定义在CVX解压目录/functions 文件夹下)
% 使用MATLAB定义的函数可能会有问题

% 计算DOA栅格数量
scan_len = size(scan_a,2);
%% CVX工具箱调用语法~开始
cvx_begin
variable s_cvx(scan_len,1)
minimize(  sum(pow_abs(s_cvx, p_norm)) );
subject to
    sum(pow_abs(u - scan_a * s_cvx,2)) <= tor_lim;
cvx_end
% CVX工具箱调用语法~结束
s_cvx = abs(s_cvx);
s_cvx = s_cvx ./ max(s_cvx);
end

space_smooth.m

function R_sig = space_smooth(rec_len, equ_l, x_sig)
% 基于空间平滑法解决相干信源问题
%   rec_len 真实阵元数量
%   equ_l   等效阵元数量
%   x_sig   回波矩阵,真实阵元数量*快拍数

% 计算平滑阵元数量
rec_len_equ = rec_len - equ_l + 1;
% 计算子阵的自相关
R_sig = zeros(equ_l,equ_l);
for i = 1:rec_len_equ
    % 第i个子阵
    foo = x_sig(i:equ_l+i-1,:);
    % 计算协方差
    R_sig = R_sig + (foo * foo')./rec_len;
end
R_sig = R_sig ./ rec_len_equ;
end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/359722.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS 鸿蒙驱动消息机制管理

驱动消息机制管理 使用场景 当用户态应用和内核态驱动需要交互时&#xff0c;可以使用HDF框架的消息机制来实现。 接口说明 消息机制的功能主要有以下两种&#xff1a; 用户态应用发送消息到驱动。 用户态应用接收驱动主动上报事件。 表1 消息机制接口 方法描述struct …

数据结构--堆排序(超详细!)

一、前言 堆排序与Top K问题是堆的两大应用&#xff0c;在我们日常也有很广泛的用处 我们已经上面已经说过了堆&#xff0c;这次来说堆的其中一个应用---堆排序。 二、堆排序 堆排序优势在哪里&#xff1f;有什么恐怖之处吗&#xff1f; 重点&#xff1a;拿一个举例&…

代理模式(静态代理、JDK 动态代理、CGLIB 动态代理)

代理模式(静态代理、JDK 动态代理、CGLIB 动态代理) 一、代理模式概述1. 生活中的代理案例2. 为什么要使用代理3. 代理模式在 Java 中的应用4. 概述5. 生活中代理图示二、代理的实现方式1. Java 中代理图示2. 静态代理2.1 案例2.2 实现案例2.3 静态代理存在的问题三、动态代理…

优化器刺客之limit 1--Order by col limit n 代价预估优化探索

一、现象 order by 排序加了limit后更慢了&#xff1f; test# explain analyze select userid from dba_users where username like %aaaaaaaaaaaaaaaaaa% order by userid ;QUERY PLAN --------------…

OpenMIPS用verilog实现

一、前期准备 1. 编辑、编译、仿真工具 用vscodeiveriloggtkwave组合实现verilog的编写、编译和波形查看&#xff0c;其配置过程见博主&#xff1a;Macbook M1使用vscodeiveriloggtkwave实现Verilog代码的编译与运行-CSDN博客​​​​​​​​ ​ ​​​​ 文章浏览阅读1.6k次…

深入理解TCP网络协议(2)

目录 1.TCP的状态转换 1.1 LISTEN状态和ETABLISHED状态 ​编辑2.TIME_WAIT 和 CLOSE_WAIT 2.滑动窗口 1.TCP的状态转换 我们通过上图可以看到TCP状态转换的详细过程.在实际开发的过程中,我们不需要了解的这么细致.为了方便大家的理解,我挑几个主要的状态来给大家聊一下 1.…

MySQL库表操作 作业

题目&#xff1a; 1. sql语句分为几类?2. 表的约束有哪些,分别是什么,设置的语法分别是什么?3. 做出班级表,学生表的E-R图,数据库模型图,以及核心的sql语句. 1. MySQL致力于支持全套ANSI/ISO SQL标准。在MySQL数据库中&#xff0c;SQL语句主要可以划分为以下几类: > DD…

CentOS gui 图形界面显示文字乱码

一、现象 CentOS&#xff08;CentOS 7.5&#xff09;控制台下显示中文乱码&#xff1a; 或者通过X11 Forwarding远程显示CentOS的图形化程序文字乱码&#xff1a; 二、解决方法 安装中文语言包&#xff1a; yum install kde-l10n-Chinese 注&#xff1a;网上有些文章会推荐安…

最小化安装BCLinux-for-Euler-21.10-dvd-x86_64-230731版

本文记录最小化安装BCLinux-for-Euler-21.10-dvd-x86_64-230731版。 一、镜像获取 1、下载镜像 移动云官方网站 最新镜像为2023-11-02 15:04:56更新的BCLinux-for-Euler-21.10-dvd-x86_64-230731版 直接下载地址&#xff1a;https://mirrors.cmecloud.cn/bclinux/oe21.10/I…

回归预测 | Matlab实现CPO-SVR冠豪猪优化支持向量机的数据多输入单输出回归预测

回归预测 | Matlab实现CPO-SVR冠豪猪优化支持向量机的数据多输入单输出回归预测 目录 回归预测 | Matlab实现CPO-SVR冠豪猪优化支持向量机的数据多输入单输出回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现CPO-SVR冠豪猪优化支持向量机的数据多输入…

excel中提取一串数字中的某几个数字

excel中提取一串数字中的某几个数字 提取一串数字中的某几个数字&#xff0c;使用公式函数截取数据 LEFT函数&#xff1a;用于截取单元格左边的字符&#xff0c;例如“LEFT(A1,5)”会返回A1单元格中的前5个字符。RIGHT函数&#xff1a;用于截取单元格右边的字符&#xff0c;例…

华为云codeArts使用操作流程

一、开启服务 什么是华为云CodeArts&#xff1f; 本实验将在华为云CodeArts平台上搭建一个凤凰商城开发项目&#xff0c;并完成需求管理、代码仓库、代码检查、编译构建、发布、部署、流水线等软件开发操作。 1)新建项目 进入华为云“控制台”&#xff0c;鼠标移动到页面左侧菜…

【鸿蒙】大模型对话应用(二):对话界面设计与实现

Demo介绍 本demo对接阿里云和百度的大模型API&#xff0c;实现一个简单的对话应用。 DecEco Studio版本&#xff1a;DevEco Studio 3.1.1 Release HarmonyOS SDK版本&#xff1a;API9 关键点&#xff1a;ArkTS、ArkUI、UIAbility、网络http请求、列表布局、层叠布局 对话页…

Mac下手动源码编译安装Swig

使用Homebrew安装 这个方式最简单&#xff0c;但是一般都是安装的最新版&#xff1a; brew install swig如果按照特定版本&#xff0c;需要看一个当前支持的列表&#xff1a; brew search swig brew install swig3源码编译安装 swig依赖pcre库&#xff0c;需要先安装pcre …

一文掌握SpringBoot注解之@Component 知识文集(8)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

Nginx 本地部署vue项目

1、 下载 Nginx 稳定版本 2、下载安装后&#xff0c;打开 nginx.conf配置文件 3、找到打包好的文件&#xff0c;并配置运行文件 文件的位置 root C:/server/build location /{root C:/server/build;index index.html index.htm;#解决刷新后nginx报404问题try_files $uri …

redis复习笔记05(小滴课堂)

案例实战之注册登录-图形验证码谷歌开源Kaptcha引入 验证码配置工具类。 验证码存储Redis逻辑编码实战 工具类用于获取本机ip和md5加密&#xff0c;直接使用就行&#xff0c;我们这里主要是学习redis不是学习这个。 获取验证码并存到redis中的接口&#xff1a; 运行测试&…

聚焦AI新动能,九州未来与燧弘华创签约!

1月24日&#xff0c;厦门市电子信息与人工智能产业高质量发展大会成功举办。来自电子信息产业、人工智能领域的企业家、专家等近300位嘉宾齐聚一堂&#xff0c;共谋智能基础&#xff0c;共话产业合作&#xff0c;共享发展商机。 会上&#xff0c;九州未来与燧弘华创签署算力租…

【Tomcat与网络4】Tomcat的连接器设计

目录 1 如何设计一个灵活可靠的连接器 2 主要组件介绍 在上一篇&#xff0c;我们介绍了Tomcat提供服务的整体结构&#xff0c;本文我们一起来看一下Tomcat的连接器的设计。 在前面我们提到Tomcat主要完成两个功能&#xff1a; 处理 Socket 连接&#xff0c;负责网络字节流与…

详解SpringCloud微服务技术栈:深入ElasticSearch(1)——数据聚合

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;详解SpringCloud微服务技术栈&#xff1a;ElasticSearch实战&#xff08;旅游类项目&#xff09; &#x1f4da;订阅专栏&#x…
最新文章