【通信系统】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)等稀疏恢复方法。对比了上述方法在常规、低信噪比、低快拍以及信源相干情况下的性能,并研究了空间平滑算法在处理相干信源问题上的表现。
空间谱估计的历史发展
本文不涉及深度学习法。
仿真原理
离散时间阵列信号模型
天线阵元示意图如下图所示,在仿真中,默认最左边的阵元为相位中心,仿真的前提为信源发射的信号为窄带信号且为远场信号,阵元为全向天线其阵元之间没有互耦和误差。
为了方便数字化处理,仿真采用了离散时间阵列信号模型:
[ 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) = 1e−j2πdsinθ1/λ⋮e−j2π(M−1)dsinθ1/λ1e−j2πdsinθ2/λ⋮e−j2π(M−1)dsinθ2/λ⋯⋯⋱⋯1e−j2πdsinθp/λ⋮e−j2π(M−1)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} x∈CM×N为天线阵列接收到的信号; A ∈ C M × P \mathbf{A}\in \mathbb{C}^{M \times P} A∈CM×P为空域导向矢量; s ∈ C p × N \mathbf{s} \in \mathbb{C}^{p \times N} s∈Cp×N为目标发出的信号; n ∈ C M × N \mathbf{n} \in \mathbb{C}^{M \times N} n∈CM×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π(M−1)dsinθ0/λ1ej2πdsinθ1/λej2π(2d)sinθ1/λ⋮ej2π(M−1)dsinθ1/λ⋯⋯⋯⋱⋯1ej2πdsinθk/λej2π(2d)sinθk/λ⋮ej2π(M−1)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)} a∈CM×(k+1)为波束形成矩阵。
回波生成
为了保证信号的正交性,省去上变频步骤,本仿真使用随机数+带通滤波方法实现指定带宽与中心频率的信源生成。针对每个信源在 [ f 0 − b w , f 0 + b w ] [f_0-bw,f_0+bw] [f0−bw,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(θ)Rxx−1a(θ)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(θ)(I−UsUsH)a(θ)aH(θ)a(θ)或JMUSIC(θ)=aH(θ)(UnUnH)a(θ)aH(θ)a(θ)
其中, U s ∈ C M × k U_s\in \mathbb{C}^{M\times k} Us∈CM×k为信号子空间,为 U U U中 k k k个最大特征值所对应的特征列向量组成的矩阵; U n ∈ C M × ( M − k ) U_n\in \mathbb{C}^{M\times (M-k)} Un∈CM×(M−k)为噪声子空间; 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ϕ2⋯ejϕp)
只要得到两个子阵列的旋转不变关系 Φ \Phi Φ,就能得到信号的到达角,完成DOA估计。
仿真时,令 x 1 x_1 x1和 x 2 x_2 x2分别为接收到的信号 x \mathbf{x} x的前 M − 1 M-1 M−1行和后 M − 1 M-1 M−1行所构成的两个子矩阵,令回波子阵列合并为 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{xexp∗xexpH},对 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πd−angle(Vesp)∗λ)
其中, V e s p ∈ C P × 1 V_{esp}\in \mathbb{C}^{P \times 1} Vesp∈CP×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}] VTLS−esp=[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)} VTLS−ESP∈C(P∗2)×(P∗2),将 V T L S − E S P V_{TLS-ESP} VTLS−ESP等分为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=−E12∗inv(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 smin∥s∥0s.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=WWHaH∗inv(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} ∥sk∥∥sk+1−sk∣2<λerr)时,结束迭代。
OMP~正交匹配追踪法
该方法的迭代步骤如:
- 初始化,令标签集 Ω m a s k \Omega_{mask} Ωmask为空集并初始化残差向量 r 0 = y r_0=y r0=y。
- 辨识,求取传感器矩阵 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>|} jk∈argmax∣<rk,ϕj>∣,往 Ω m a s k \Omega_{mask} Ωmask中添加该原子的索引。
- 估计,最小化问题 m i n x ∥ y − Φ Ω k x ∥ 2 2 min_x \| y-\Phi_{\Omega_k}x \|_2^2 minx∥y−ΦΩkx∥22的最小二乘解为 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。
- 更新残差, 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
- 重复步骤2~4直到满足迭代停止条件,退出条件包括迭代次数达到字典的栅格数,或者 a ( : , Ω m a s k ) ′ ∗ a ( : , Ω m a s k ) a(:,\Omega_{mask})'*a(:,\Omega_{mask}) a(:,Ωmask)′∗a(:,Ωmask)为奇异矩阵。
- 输出结果,
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=yH∗pinv(a)H
该方法因为运算量较大且产生的不是稀疏解,在实际工程中很少使用,在仿真中仅用于效果对比。
EM-SBL~最大期望-稀疏贝叶斯学习法
SBL算法是稀疏信号重构的重要算法,涉及高斯分布、最大似然估计、贝叶斯公式等数学理论,由于推导过程比较复杂,主要是我懒得敲了,后续如果读者有强烈需要我再更新一下吧^_^,这里直接介绍推导结果。该方法迭代的步骤为:
- 初始化,令 Γ 0 = 0.1 ∗ I \Gamma_0=0.1*I Γ0=0.1∗I。
- 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为接收信号的自相关矩阵。
- 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(θ)
- 重复步骤2和3,直到达到最大迭代次数或 ∥ Γ k + 1 − Γ k ∥ 1 < 误差限 \|\Gamma_{k+1}-\Gamma_{k}\|_1<误差限 ∥Γk+1−Γk∥1<误差限
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} argmins∥s∥p,s.t.∥y−as∥2<λ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
可修改的参数
- 载波频率 f 0 f_0 f0:信源发射信号的中心频率。
- 系统全局采样率 f g f_g fg:由于仿真是数字系统,该采样率为仿真所使用的全局采样率。
- 信号带宽 B W BW BW:信源发射信号的总带宽,当存在多个信源时,如果使用非相干生成模式,会根据总带宽为每个信源划分不重合的等长信号频段;否则所有信源使用整个带宽的频段。
- 目标来向角度 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一起修改。
- 阵元数量 M M M:MIMO阵列阵元数量。
- 快拍数 L L L:每个阵元的采样点个数。
- 信噪比snr:信源发出的信号被收到时的信噪比。
- 扫描角度 s c a n a n g l e scan_{angle} scanangle:控制波束形成矩阵的角度,也称为完备字典或DOA栅格,可以改变间隔以提高空域采样率,注意空域分辨率不因空域采样率的改变而改变。
- 是否使用空间平滑滤波is_space_smooth:逻辑变量,置为ture时使能空间平滑滤波以解决信源的相干性问题。
- 是否产生相干的信源is_coherent:逻辑变量,置为true时将产生频域重叠的相干信源。
仿真结果
常规情况
在信源不相干,信噪比达到20dB,阵元数和快拍数分别为32和128的情况下,DOA结果如下图所示,可见CBF法主瓣最宽、旁瓣最高,其次为EM-SBL方法。CBF、EM-SBL、Capon、MUSIC的主瓣宽度依次减少。在稀疏恢复类型的算法中,FOCUSS算法效果最佳,OMP算法产生了过多的假峰,PINV法和ML法则出现了与传统方法相当的主瓣宽度。CVX方法则没有得到正确的来向角估计。两种准则下的ESPRIT算法均估计出了正确的来向角。
尽管CVX算法的结果不太理想,但仍可以发现在p1范数约束下将产生较为稀疏的解,随着范数的增加,稀疏恢复结果变得越来越不稀疏。
低信噪比情况
修改信噪比为0dB,仿真结果如下图所示,可见此时常规方法和MUSIC法仍然可以正常工作;ESPRIT算法估计的DOA角度出现偏差;稀疏恢复部分,FOCUSS方法仍然表现出良好的性能,OMP法的假峰消失,CVX方法的零陷刚好落在真实来波方向上。
修改信噪比为-10dB,仿真结果如下图所示,此时大部分算法都只能找到其中的一个来向角。
相干信源情况
信源发射信号相干且不使用平滑滤波时,仿真结果如下图所示,可见子空间类型算法和Capon法只能发现一个来向的角度,但稀疏恢复算法和CBF
信源发射信号相干且使用平滑滤波时,设置等效阵元数量为14,仿真结果如下图所示,此时Capon法、MUSIC法变得正常,可以分辨两个来向的信号,但ESPRIT仍然无法使用。但由于等效阵元数的降低,DOA结果的主瓣变换,降低了空域分辨率,这与理论是符合的。
少快拍情况
基于正常情况设置快拍数为32个(刚好等于阵元数)时,仿真结果如下图所示,可见此时算法仍然可以正常工作。
观察更极限的情况,设置快拍数为2,仿真结果如下图所示,可见此时CBF法仍然可以正常工作,Capon法出现了相当多的假峰,ESPRIT算法已无法正常工作。稀疏恢复类型的算法在此种情况下表现出了极佳的性能,FOCUSS算法可以准确地估计出来向角,CVX法可以正常工作但有一定误差,OMP算法在真实来向附近产生了多个假峰。
仿真小结
- CBF算法是万精油,可以用在低信噪比、低快拍和信源相干情况下,低时间复杂度,少空间占用使得它时至今天仍然是DOA的主流算法之一,在你不知道使用什么算法时,不妨先试试CBF吧。
- 稀疏恢复算法是概率类型的算法,每次执行都可能产生不一样的结果,这种算法优点在于可以获得很高的分辨率(超分辨率识别),并且可以在低快拍和信源相干情况下使用,是当前除了机器学习算法外的研究主流,稀疏算法唯一的缺点在于它的鲁棒性欠佳,且只能在高信噪比下使用,高信噪比也对应了空域“稀疏”。
后语
心里话:终于写完了!!!这篇长文从代码重构,到撰写与敲公式前前后后画了差不多一个星期,文中的所有公式、符号和矩阵等都是用 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_lenfoo = 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_lenfoo = 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_lenfoo = 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_lenscan = 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:1000W = 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_errbreak;ends0 = 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_tolerbreak;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-stepSigma_x = pinv(sigma * (scan_a'*scan_a) + pinv(Gamma));Mu_x = Sigma_x / sigma * scan_a' * R_sig;% M-stepGamma_new = Gamma;for i = 1:scan_lenmu_xn = Mu_x(i,:); Gamma_new(i,i) = mu_xn*mu_xn'/shot_len + Sigma_x(i,i);endif sum(abs(diag(Gamma_new - Gamma))) < err_lim || times_cnt > times_limbreak;endGamma = 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 tosum(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
相关文章:

【通信系统】MIMO阵列信号来向DOA估计实现~含FOCUSS、OMP、贝叶斯学习(SBL)等稀疏重构法和常规、子空间法、空间平滑滤波法
MIMO阵列目标信号来向估计原理与实现~基于常规法、子空间变换法和稀疏恢复法 写在最前前言空间谱估计的历史发展 仿真原理离散时间阵列信号模型波束形成矩阵(完备字典)回波生成空间平滑滤波传统方法CBF~常规波束成型Capon~最小方差无失真响应法ML~最大似然估计法 子空间方法MUS…...

高级变量赋值和变量的间接引用
1.高级变量赋值 var${str-lucky} 变量配置方式 var${str:-lucky} 变量配置方式 var${strlucky} 变量配置方式 2.变量的间接引用 eval 命令 eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一次扫描无法实现其功能的变量,该命令对变…...

vue动态修改侧边菜单栏宽度
1.添加可修改宽度的dom元素 <div style"background: #f5f7fa;padding: 20px 10px;"><label>菜单宽度 </label><el-input v-model"sideWidth" placeholder"请输入宽度值" style"width: 100px"/> px<el-but…...

【C++入门到精通】C++的IO流(输入输出流) [ C++入门 ]
阅读导航 引言一、C语言的输入与输出二、流是什么三、CIO流1. C标准IO流(1)istream(2)ostream(3)iostream(4)cin 和 cout 2. C文件IO流(1)ifstream࿰…...
【Spark系列5】Dataframe下常用算子API
Apache Spark DataFrame API 提供了丰富的方法来处理分布式数据集。以下是一些常见的 DataFrame API 类别和方法,但这不是一个完整的列表,因为 API 非常广泛。这些方法可以分为几个主要类别: 转换操作(Transformations࿰…...

【大数据】Flink SQL 语法篇(二):WITH、SELECT WHERE、SELECT DISTINCT
Flink SQL 语法篇(二) 1.WITH 子句2.SELECT & WHERE 子句3.SELECT DISTINCT 子句 1.WITH 子句 应用场景(支持 Batch / Streaming):With 语句和离线 Hive SQL With 语句一样的,语法糖 1,使用…...
leetcode-链表专题
25.K个一组翻转链表 题目链接 25. K 个一组翻转链表 - 力扣(LeetCode) 解题思路 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class So…...

Vue打包Webpack源码及物理路径泄漏问题解决
修复前: 找到vue.config.js文件,在其中增加配置 module.exports {productionSourceMap: false,// webpack 配置configureWebpack: {devtool: false,}}其中打包的物理路径泄露我这边试了好多次,发现只有打包的时候NODE_ENVproduction 才能保…...

MySQL学习记录——일 MySQL 安装、配置
文章目录 1、卸载内置环境2、安装MySQL3、启动4、登录5、配置my.cnf 当前环境是1核2G云服务器,CentOS7.6。要在root用户下进行操作 1、卸载内置环境 云服务器中有可能会自带mysql还有mariadb这样的数据库服务,在安装我们mysql前,得先查找一下…...

获取真实 IP 地址(二):绕过 CDN(附链接)
一、DNS历史解析记录 DNS 历史解析记录指的是一个域名在过去的某个时间点上的DNS解析信息记录。这些记录包含了该域名过去使用的IP地址、MX记录(邮件服务器)、CNAME记录(别名记录)等 DNS 信息。DNS 历史记录对于网络管理员、安全研…...

正则表达式补充以及sed
正则表达式: 下划线算 在单词里面 解释一下过程: 在第二行hello world当中,hello中的h 与后面第一个h相匹配,所以hello中的ello可以和abcde匹配 在world中,w先匹配h匹配不上,则在看0,r&#…...
LLM智能体开发指南
除非你一直生活在岩石下,否则你一定听说过像 Auto-GPT 和 MetaGPT 这样的项目。 这些是社区为使 GPT-4 完全自治而做出的尝试。在其最原始的形式中,代理基本上是文本到任务。你输入一个任务描述,比如“给我做一个贪吃蛇游戏”,并使…...

基于springboot校园二手书交易管理系统源码和论文
在Internet高速发展的今天,我们生活的各个领域都涉及到计算机的应用,其中包括乐校园二手书交易管理系统的网络应用,在外国二手书交易管理系统已经是很普遍的方式,不过国内的管理系统可能还处于起步阶段。乐校园二手书交易管理系统…...

Oracle和Mysql数据库
数据库 Oracle 体系结构与基本概念体系结构基本概念表空间(users)和数据文件段、区、块Oracle数据库的基本元素 Oracle数据库启动和关闭Oracle数据库启动Oracle数据库关闭 Sqlplussqlplus 登录数据库管理系统使用sqlplus登录Oracle数据库远程登录解锁用户修改用户密码查看当前语…...
java学习笔记:java常见注解语句汇总、解析及应用
文章目录 一、什么是注解二、注解有什么作用三、常见的Java注解及其功能介绍和示例OverrideDeprecatedSuppressWarningsFunctionalInterfaceSafeVarargsSuppressWarnings 一、什么是注解 Java中所有以开头的语句被称为注解(Annotation)。 注解是一种元数…...

k8s Sidecar filebeat 收集容器中的trace日志和app日志
目录 一、背景 二、设计 三、具体实现 Filebeat配置 K8S SideCar yaml Logstash配置 一、背景 将容器中服务的trace日志和应用日志收集到KAFKA,需要注意的是 trace 日志和app 日志需要存放在同一个KAFKA两个不同的topic中。分别为APP_TOPIC和TRACE_TOPIC 二、…...

三维模型设计新纪元:3D开发工具HOOPS在机械加工行业的应用与优势
在当今快速发展的科技时代,机械加工行业正经历着巨大的变革,而HOOPS技术正是其中一项重要的创新。HOOPS技术不仅仅是一种用于处理和可视化计算机辅助设计(CAD)数据的工具,更是机械加工领域中提升效率、优化设计的利器。…...
Python爬虫子页面并写入text代码
这是工具类 class UrlManager():"""url管理器"""def __init__(self):self.new_urls set()self.old_urls set()def add_new_url(self,url):if url is None or len(url) 0:returnif url in self.new_urls or url in self.old_urls:returnself.…...
《PyTorch基础教程》01 搭建环境 基于Docker搭建ubuntu22+Python3.10+Pytorch2+cuda11+jupyter的开发环境
01 环境搭建 《PyTorch基础教程》01 搭建环境 基于Docker搭建ubuntu22+Python3.10+Pytorch2+cuda11+jupyter的开发环境 Docker部署PyTorch 拉取cnstark/pytorch镜像 拉取镜像: docker pull cnstark/pytorch:2.0.1-py3.10.11-cuda11.8.0-ubuntu22.04导出镜像: docker sa…...
MySQL进阶之触发器
触发器 触发器是与表有关的数据库对象,指在insert/update/delete之前(BEFORE)或之后(AFTER),触 发并执行触发器中定义的SQL语句集合。触发器的这种特性可以协助应用在数据库端确保数据的完整性 , 日志记录 , 数据校验等操作 。 使用别名OLD和NEW来引用…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

C++实现分布式网络通信框架RPC(2)——rpc发布端
有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...

软件工程 期末复习
瀑布模型:计划 螺旋模型:风险低 原型模型: 用户反馈 喷泉模型:代码复用 高内聚 低耦合:模块内部功能紧密 模块之间依赖程度小 高内聚:指的是一个模块内部的功能应该紧密相关。换句话说,一个模块应当只实现单一的功能…...
CentOS 7.9安装Nginx1.24.0时报 checking for LuaJIT 2.x ... not found
Nginx1.24编译时,报LuaJIT2.x错误, configuring additional modules adding module in /www/server/nginx/src/ngx_devel_kit ngx_devel_kit was configured adding module in /www/server/nginx/src/lua_nginx_module checking for LuaJIT 2.x ... not…...

篇章一 论坛系统——前置知识
目录 1.软件开发 1.1 软件的生命周期 1.2 面向对象 1.3 CS、BS架构 1.CS架构编辑 2.BS架构 1.4 软件需求 1.需求分类 2.需求获取 1.5 需求分析 1. 工作内容 1.6 面向对象分析 1.OOA的任务 2.统一建模语言UML 3. 用例模型 3.1 用例图的元素 3.2 建立用例模型 …...

LeetCode 2894.分类求和并作差
目录 题目: 题目描述: 题目链接: 思路: 思路一详解(遍历 判断): 思路二详解(数学规律/公式): 代码: Java思路一(遍历 判断&a…...

RabbitMQ work模型
Work 模型是 RabbitMQ 最基础的消息处理模式,核心思想是 多个消费者竞争消费同一个队列中的消息,适用于任务分发和负载均衡场景。同一个消息只会被一个消费者处理。 当一个消息队列绑定了多个消费者,每个消息消费的个数都是平摊的&a…...