读者在阅读这篇博客之前,建议先阅读和掌握我之前写的另一篇博客循环卷积和线性卷积(矩阵视角)。
考虑一个时不变的宽带信号模型:
y
[
m
]
=
∑
l
=
0
L
−
1
h
l
x
[
m
−
l
]
+
w
[
m
]
(1)
y[m] = \sum_{l=0}^{L-1} h_l x[m - l] + w[m] \tag{1}
y[m]=l=0∑L−1hlx[m−l]+w[m](1)
如果不考虑噪声 w w w的话,式(1)可以看作是信道向量 h = [ h 0 , ⋯ , h L − 1 ] ∈ C L × 1 \boldsymbol h=[h_0,\cdots,h_{L-1}] \in \mathbb C^{L \times 1} h=[h0,⋯,hL−1]∈CL×1与信号向量 x = [ x 0 , ⋯ , x N − 1 ] ∈ C N × 1 \boldsymbol x=[x_0,\cdots,x_{N-1}] \in \mathbb C^{N \times 1} x=[x0,⋯,xN−1]∈CN×1的线性卷积。我们知道正弦函数是线性时不变系统的特征函数,注意这只在无穷维空间中成立,而实际中遇到的问题维度是有限的,所以不可避免地引入了符号间干扰(ISI)。
为了解决宽带通信系统中出现的ISI问题,学者引入了循环前缀(Prefix)的概念,下面我们将具体解释。
首先,如果不考虑循环前缀,我们把式(1)中的卷积部分写为矩阵形式,即
h
T
∗
x
T
=
h
T
[
x
0
x
1
⋯
x
N
−
1
0
⋯
0
0
x
0
x
1
⋯
x
N
−
1
⋯
0
0
0
⋱
⋯
⋱
⋯
0
0
0
0
x
0
x
1
⋯
x
N
−
1
]
∈
C
1
×
(
N
+
L
−
1
)
(2)
\begin{aligned} & \boldsymbol h^T * \boldsymbol x^T \\ &= \boldsymbol h^T \left[ \begin{matrix} x_0& x_1& \cdots& \begin{matrix} x_{N-1}& 0& \cdots& \ \ \ 0\\ \end{matrix}\\ 0& x_0& x_1& \begin{matrix} \cdots& x_{N-1}& \cdots& 0\\ \end{matrix}\\ 0& 0& \ddots& \begin{matrix} \ \ \cdots& \,\, \ddots& \cdots& 0\\ \end{matrix}\\ 0& 0& 0& \begin{matrix} x_0& x_1& \cdots& x_{N-1}\\ \end{matrix}\\ \end{matrix} \right] \in \mathbb C^{1 \times (N+L-1)} \end{aligned} \tag{2}
hT∗xT=hT⎣⎢⎢⎡x0000x1x000⋯x1⋱0xN−10⋯ 0⋯xN−1⋯0 ⋯⋱⋯0x0x1⋯xN−1⎦⎥⎥⎤∈C1×(N+L−1)(2)
考虑循环前缀,循环前缀的长度与
L
L
L(信道tap的数量,若延时拓展为
T
d
T_d
Td,信号带宽为
W
W
W,则
L
=
T
d
/
W
L=T_d/W
L=Td/W)相关,具体大小为
L
−
1
L-1
L−1,定义加入循环前缀后的信号向量为
x
′
=
[
x
N
−
L
+
1
,
x
N
−
L
+
2
,
⋯
,
x
N
−
1
,
x
0
,
x
1
,
⋯
x
N
−
1
]
T
=
[
x
N
−
L
+
1
,
x
N
−
L
+
2
,
⋯
,
x
N
−
1
⏟
Added prefix in the head with length
L
−
1
,
x
]
T
∈
C
N
+
L
−
1
(3)
\begin{aligned} \boldsymbol x^{\prime} &= [x_{N-L+1}, x_{N-L+2}, \cdots, x_{N-1}, x_0, x_1, \cdots x_{N-1}]^T \\ &= [\underset{{\text{ Added prefix in the head with length } L-1 }} {\underbrace{ x_{N-L+1}, x_{N-L+2}, \cdots, x_{N-1}}}, \boldsymbol x]^T \in \mathbb C^{N+L-1} \end{aligned} \tag{3}
x′=[xN−L+1,xN−L+2,⋯,xN−1,x0,x1,⋯xN−1]T=[ Added prefix in the head with length L−1
xN−L+1,xN−L+2,⋯,xN−1,x]T∈CN+L−1(3)
加入循环前缀后,把
x
′
\boldsymbol x^{\prime}
x′代入到式(1)中的
x
\boldsymbol x
x,我们可以写出类似(2)的矩阵表达式:
h
T
∗
x
′
T
=
h
T
[
x
N
−
L
+
1
⋯
x
N
−
1
x
0
x
1
⋯
x
N
−
1
0
⋯
0
0
x
N
−
L
+
1
⋯
x
N
−
1
x
0
x
1
⋯
⋱
⋱
0
⋮
⋱
⋱
⋱
x
N
−
1
⋱
x
1
⋯
⋱
⋮
0
⋯
0
x
N
−
L
+
1
⋯
x
N
−
1
x
0
x
1
⋯
x
N
−
1
]
(4)
\begin{aligned} & \boldsymbol h^T * \boldsymbol x^{\prime \ T} \\ & = \boldsymbol h^T \left[ \begin{matrix}{} x_{N-L+1}& \cdots& x_{N-1}& x_0& x_1& \cdots& x_{N-1}& 0& \cdots& 0\\ 0& x_{N-L+1}& \cdots& x_{N-1}& x_0& x_1& \cdots& \ddots& \ddots& 0\\ \vdots& \ddots& \ddots& \ddots& x_{N-1}& \ddots& x_1& \cdots& \ddots& \vdots\\ 0& \cdots& 0& x_{N-L+1}& \cdots& x_{N-1}& x_0& x_1& \cdots& x_{N-1}\\ \end{matrix} \right] \end{aligned} \tag{4}
hT∗x′ T=hT⎣⎢⎢⎢⎡xN−L+10⋮0⋯xN−L+1⋱⋯xN−1⋯⋱0x0xN−1⋱xN−L+1x1x0xN−1⋯⋯x1⋱xN−1xN−1⋯x1x00⋱⋯x1⋯⋱⋱⋯00⋮xN−1⎦⎥⎥⎥⎤(4)
我们将上式出现的矩阵做区分,如下图所示,可以发现中间部分是一个循环矩阵(Circulant Matrix),对应着循环卷积,因此我们得出结论:循环前缀可以将线性卷积转化为循环卷积。

因此,在加入循环前缀后,我们可以等效出循环卷积,为了保持循环卷积维度的一致性,我们对
h
\boldsymbol h
h做扩展,令
h
′
=
[
h
0
,
⋯
,
h
L
−
1
,
0
,
⋯
,
0
]
∈
C
N
×
1
\boldsymbol h^{\prime} = [h_0, \cdots, h_{L-1}, 0, \cdots, 0] \in \mathbb C^{N \times 1}
h′=[h0,⋯,hL−1,0,⋯,0]∈CN×1
我们令
C
=
[
h
0
h
1
h
2
⋯
h
L
−
2
h
L
−
1
0
0
⋯
0
0
h
0
h
1
h
2
⋱
h
L
−
2
h
L
−
1
0
⋱
0
0
0
h
0
h
1
h
2
⋱
h
L
−
2
h
L
−
1
⋱
⋮
⋮
⋱
⋱
⋱
⋱
⋱
⋱
⋱
⋱
0
0
⋯
0
0
h
0
h
1
h
2
⋯
h
L
−
2
h
L
−
1
h
L
−
1
0
⋯
0
0
h
0
h
1
h
2
⋯
h
L
−
2
h
L
−
2
h
L
−
1
0
0
⋱
0
h
0
h
1
⋱
⋮
h
L
−
3
h
L
−
2
h
L
−
1
0
0
⋱
0
h
0
⋱
h
2
⋮
⋱
h
L
−
2
⋱
⋱
⋱
⋱
⋱
⋱
h
1
h
1
⋯
h
L
−
3
h
L
−
2
h
L
−
1
0
0
⋯
0
h
0
]
∈
C
N
×
N
\boldsymbol C = \left[ \begin{matrix}{} h_0& h_1& h_2& \cdots& h_{L-2}& h_{L-1}& 0& 0& \cdots& 0\\ 0& h_0& h_1& h_2& \ddots& h_{L-2}& h_{L-1}& 0& \ddots& 0\\ 0& 0& h_0& h_1& h_2& \ddots& h_{L-2}& h_{L-1}& \ddots& \vdots\\ \vdots& \ddots& \ddots& \ddots& \ddots& \ddots& \ddots& \ddots& \ddots& 0\\ 0& \cdots& 0& 0& h_0& h_1& h_2& \cdots& h_{L-2}& h_{L-1}\\ h_{L-1}& 0& \cdots& 0& 0& h_0& h_1& h_2& \cdots& h_{L-2}\\ h_{L-2}& h_{L-1}& 0& 0& \ddots& 0& h_0& h_1& \ddots& \vdots\\ h_{L-3}& h_{L-2}& h_{L-1}& 0& 0& \ddots& 0& h_0& \ddots& h_2\\ \vdots& \ddots& h_{L-2}& \ddots& \ddots& \ddots& \ddots& \ddots& \ddots& h_1\\ h_1& \cdots& h_{L-3}& h_{L-2}& h_{L-1}& 0& 0& \cdots& 0& h_0\\ \end{matrix} \right] \in \mathbb C^{N \times N}
C=⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡h000⋮0hL−1hL−2hL−3⋮h1h1h00⋱⋯0hL−1hL−2⋱⋯h2h1h0⋱0⋯0hL−1hL−2hL−3⋯h2h1⋱0000⋱hL−2hL−2⋱h2⋱h00⋱0⋱hL−1hL−1hL−2⋱⋱h1h00⋱⋱00hL−1hL−2⋱h2h1h00⋱000hL−1⋱⋯h2h1h0⋱⋯⋯⋱⋱⋱hL−2⋯⋱⋱⋱000⋮0hL−1hL−2⋮h2h1h0⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤∈CN×N
可以得到,
h
′
\boldsymbol h^{\prime}
h′与
x
\boldsymbol x
x的循环卷积
h
′
T
⊗
x
T
=
h
′
T
[
x
0
x
1
⋯
x
N
−
1
x
N
−
1
x
0
⋱
x
N
−
2
⋮
⋱
⋱
x
1
x
N
−
L
+
1
⋯
x
N
−
1
x
0
⋮
⋮
⋮
⋮
]
=
[
h
0
,
⋯
,
h
L
−
1
,
0
,
⋯
,
0
]
[
x
0
x
1
⋯
x
N
−
1
x
N
−
1
x
0
⋱
x
N
−
2
⋮
⋱
⋱
x
1
x
N
−
L
+
1
⋯
x
N
−
1
x
0
⋮
⋮
⋮
⋮
]
=
x
T
C
\begin{aligned} & \boldsymbol h^{\prime \ T} \otimes \boldsymbol x^T \\ &= \boldsymbol h^{\prime \ T} \left[ \begin{matrix}{} x_0& x_1& \cdots& x_{N-1}\\ x_{N-1}& x_0& \ddots& x_{N-2}\\ \vdots& \ddots& \ddots& x_1\\ x_{N-L+1}& \cdots& x_{N-1}& x_0\\ \vdots& \vdots& \vdots& \vdots\\ \end{matrix} \right] \\ & = [h_0, \cdots, h_{L-1}, 0, \cdots, 0] \left[ \begin{matrix}{} x_0& x_1& \cdots& x_{N-1}\\ x_{N-1}& x_0& \ddots& x_{N-2}\\ \vdots& \ddots& \ddots& x_1\\ x_{N-L+1}& \cdots& x_{N-1}& x_0\\ \vdots& \vdots& \vdots& \vdots\\ \end{matrix} \right] \\ & =\boldsymbol x^T \boldsymbol C \end{aligned}
h′ T⊗xT=h′ T⎣⎢⎢⎢⎢⎢⎢⎡x0xN−1⋮xN−L+1⋮x1x0⋱⋯⋮⋯⋱⋱xN−1⋮xN−1xN−2x1x0⋮⎦⎥⎥⎥⎥⎥⎥⎤=[h0,⋯,hL−1,0,⋯,0]⎣⎢⎢⎢⎢⎢⎢⎡x0xN−1⋮xN−L+1⋮x1x0⋱⋯⋮⋯⋱⋱xN−1⋮xN−1xN−2x1x0⋮⎦⎥⎥⎥⎥⎥⎥⎤=xTC
那么就有
h
′
T
⊗
x
T
=
x
T
C
\boldsymbol h^{\prime \ T} \otimes \boldsymbol x^T = \boldsymbol x^T \boldsymbol C
h′ T⊗xT=xTC
又因为矩阵
C
\boldsymbol C
C是循环阵,基于另一篇博客另一篇博客循环卷积和线性卷积(矩阵视角),我们可以对
C
\boldsymbol C
C做谱分解
C
=
F
Λ
F
−
1
\boldsymbol C = \boldsymbol F \boldsymbol \Lambda \boldsymbol F^{-1}
C=FΛF−1
其中
F
\boldsymbol F
F为DFT矩阵,
Λ
\boldsymbol \Lambda
Λ为对角阵(对角线元素一般为复数)。令接收信号为
y
∈
C
N
\boldsymbol y \in \mathbb C^{N}
y∈CN,那么
y
\boldsymbol y
y可以表示为
y
T
=
x
T
C
=
x
T
F
Λ
F
−
1
\boldsymbol y^T = \boldsymbol x^T \boldsymbol C = \boldsymbol x^T \boldsymbol F \boldsymbol \Lambda \boldsymbol F^{-1}
yT=xTC=xTFΛF−1
转化成列向量形式为,因为
F
T
=
F
\boldsymbol F^T = \boldsymbol F
FT=F,所以
y
=
F
−
1
Λ
F
x
⇒
r
=
F
y
=
Λ
F
F
−
1
d
=
Λ
d
\begin{aligned} &\boldsymbol y = \boldsymbol F^{-1} \boldsymbol \Lambda \boldsymbol F \boldsymbol x \\ & \Rightarrow \boldsymbol r = \boldsymbol F \boldsymbol y = \boldsymbol \Lambda^{} \boldsymbol F \boldsymbol F^{-1} d = \boldsymbol \Lambda^{} \boldsymbol d \end{aligned}
y=F−1ΛFx⇒r=Fy=ΛFF−1d=Λd
其中 r = F y \boldsymbol r = \boldsymbol F \boldsymbol y r=Fy表示将接收到的时域信号 y \boldsymbol y y转换到频域上, x = F − 1 d \boldsymbol x = \boldsymbol F^{-1} \boldsymbol d x=F−1d表示将发送的频域信号 d \boldsymbol d d转换到时域上。信号的变换过程如下图所示,频域上的数据 d \boldsymbol d d经过IDFT变换转换为时域信号 x \boldsymbol x x,再依据式(3)加入循环前缀,经过信道(线性时不变系统)得到接收信号 y ′ \boldsymbol y^{\prime} y′,随后在接收端移除前缀,将剩余的信号 y \boldsymbol y y经过DFT变换转换到频域信号 r \boldsymbol r r。

注意到,上述中间过程都是在时域上操作,如果把时域操作看作是黑匣子,只考虑收发两端的频域信号,那么问题在频域上就可以大大简化,如下图所示
从频域上看,引入循环前缀后,因为矩阵
Λ
\boldsymbol \Lambda
Λ是对角阵,所以消除了符号间干扰(ISI),发送符号与接收符号之间可以一一对应,即
r
n
=
h
~
n
d
n
+
w
n
r_n = \tilde h_n d_n + w_n
rn=h~ndn+wn
其中 h ~ n \tilde h_n h~n为第 n n n个子载波上的信道系数,不同的子载波对应不同的信道系数,体现了宽带通信系统中出现的频率选择性衰落。对上式的一种解释是,OFDM把宽带通信拆分成了多个并行的窄带通信(并行的多个子信道),信号并行地在各个窄带上传输。
小结
OFDM引入循环前缀扩充了原本信号向量与信道向量(注意区分这里的信道向量强调采样后的多径,而不是多天线)进行线性卷积的维度,在更高维度下,我们发现部分卷积结果可以直接用循环卷积表征(由式4可以看出),因此我们认为:循环前缀的引入可以将线性卷积转化为循环卷积。转化为循环卷积后,我们可以借助循环矩阵来实现循环卷积,又因为循环矩阵的特征分解为
F
Λ
F
−
1
\boldsymbol F \boldsymbol \Lambda \boldsymbol F^{-1}
FΛF−1,其中
F
\boldsymbol F
F为DFT矩阵,根据下面的式子
y
=
F
−
1
Λ
F
x
⇒
r
=
F
y
=
Λ
F
F
−
1
d
=
Λ
d
\begin{aligned} &\boldsymbol y = \boldsymbol F^{-1} \boldsymbol \Lambda \boldsymbol F \boldsymbol x \\ & \Rightarrow \boldsymbol r = \boldsymbol F \boldsymbol y = \boldsymbol \Lambda^{} \boldsymbol F \boldsymbol F^{-1} d = \boldsymbol \Lambda^{} \boldsymbol d \end{aligned}
y=F−1ΛFx⇒r=Fy=ΛFF−1d=Λd
可以在频域上消除符号间干扰(ISI)。
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法
点向量坐标矩阵的几何意义介绍旋转矩阵的几何含义之前,先介绍一下点向量坐标矩阵的几何含义点:在一维空间下就是一个标量,如同一条直线上,以任意某一个位置为0点,以一定的尺度间隔为1,2,3...,相反方向为-1,-2,-3...;如此就形成了一维坐标系,这时候任何一个点都可以用一个数值表示,如点p1=5,即即从原点出发沿着x轴正方向移动5个尺度;点p2=-3,负方向移动3个尺度; 在一维坐标系上过原点做垂直于一维坐标系的直线,则形成了二维坐标系,此时描述一个点需要两个数值来表示点p3=(3,2),即从原点出发沿着x轴正方向移动3个尺度,在此基础上沿着y轴正方向移动两个尺度的位置就是点p3。
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
我是Ruby的新手,有些闭包逻辑让我感到困惑。考虑这段代码:array=[]foriin(1..5)array[5,5,5,5,5]这对我来说很有意义,因为i被绑定(bind)在循环之外,所以每次循环都会捕获相同的变量。使用每个block可以解决这个问题对我来说也很有意义:array=[](1..5).each{|i|array[1,2,3,4,5]...因为现在每次通过时都单独声明i。但现在我迷路了:为什么我不能通过引入一个中间变量来修复它?array=[]foriin1..5j=iarray[5,5,5,5,5]因为j每次循环都是新的,我认为每次循环都会捕获不同的变量。例如,这绝对
我目前正在尝试学习RubyonRails和测试框架RSpec。assigns在此RSpec测试中做什么?describe"GETindex"doit"assignsallmymodelas@mymodel"domymodel=Factory(:mymodel)get:indexassigns(:mymodels).shouldeq([mymodel])endend 最佳答案 assigns只是检查您在Controller中设置的实例变量的值。这里检查@mymodels。 关于ruby-o
如thisquestion,当在其自己的赋值中使用未定义的局部变量时,它的计算结果为nil。x=x#=>nil但是当局部变量的名称与现有的方法名称冲突时,就比较棘手了。为什么下面的最后一个示例返回nil?{}.instance_eval{a=keys}#=>[]{}.instance_eval{keys=self.keys}#=>[]{}.instance_eval{keys=keys}#=>nil 最佳答案 在Ruby中,因为可以在没有显式接收器和括号的情况下调用方法,所以在局部变量引用和无接收器无参数方法调用之间存在语法歧义:f