通信理论

日期2009-06-06 (最后修改), 2009-06-06 (创建)

这两个示例说明了简单的数字 BPSK 调制通信系统的仿真,其中每个符号只使用一个样本,并且信号只受 AWGN 噪声的影响。

在第一个示例中,我们循环遍历不同的信噪比值,信号长度是理论误差概率的函数。根据经验,我们希望为每个 SNR 值计算大约 100 个错误,这决定了信号(和噪声)向量(s)的长度。

在 [1]
#!/usr/bin/python
# BPSK digital modulation example
# by Ivo Maljevic

from numpy import *
from scipy.special import erfc
import matplotlib.pyplot as plt

SNR_MIN     = 0
SNR_MAX     = 9
Eb_No_dB    = arange(SNR_MIN,SNR_MAX+1)
SNR         = 10**(Eb_No_dB/10.0)  # linear SNR

Pe          = empty(shape(SNR))
BER         = empty(shape(SNR))

loop = 0
for snr in SNR:      # SNR loop
 Pe[loop] = 0.5*erfc(sqrt(snr))
 VEC_SIZE = ceil(100/Pe[loop])  # vector length is a function of Pe

 # signal vector, new vector for each SNR value
 s = 2*random.randint(0,high=2,size=VEC_SIZE)-1

 # linear power of the noise; average signal power = 1
 No = 1.0/snr

 # noise
 n = sqrt(No/2)*random.randn(VEC_SIZE)

 # signal + noise
 x = s + n

 # decode received signal + noise
 y = sign(x)

 # find erroneous symbols
 err = where(y != s)
 error_sum = float(len(err[0]))
 BER[loop] = error_sum/VEC_SIZE
 print 'Eb_No_dB=%4.2f, BER=%10.4e, Pe=%10.4e' % \
        (Eb_No_dB[loop], BER[loop], Pe[loop])
 loop += 1

#plt.semilogy(Eb_No_dB, Pe,'r',Eb_No_dB, BER,'s')
plt.semilogy(Eb_No_dB, Pe,'r',linewidth=2)
plt.semilogy(Eb_No_dB, BER,'-s')
plt.grid(True)
plt.legend(('analytical','simulation'))
plt.xlabel('Eb/No (dB)')
plt.ylabel('BER')
plt.show()
Eb_No_dB=0.00, BER=8.0975e-02, Pe=7.8650e-02
Eb_No_dB=1.00, BER=4.9522e-02, Pe=5.6282e-02
Eb_No_dB=2.00, BER=4.3870e-02, Pe=3.7506e-02
Eb_No_dB=3.00, BER=2.0819e-02, Pe=2.2878e-02
Eb_No_dB=4.00, BER=1.1750e-02, Pe=1.2501e-02
Eb_No_dB=5.00, BER=6.2515e-03, Pe=5.9539e-03
Eb_No_dB=6.00, BER=2.2450e-03, Pe=2.3883e-03
Eb_No_dB=7.00, BER=6.3359e-04, Pe=7.7267e-04
Eb_No_dB=8.00, BER=1.8709e-04, Pe=1.9091e-04
Eb_No_dB=9.00, BER=3.0265e-05, Pe=3.3627e-05

在第二个略微修改的示例中,通过将信号分成帧来解决信号长度增长的问题。也就是说,给定 SNR 的样本数量会快速增长,因此上述仿真对于大于 9 或 10 dB 的 Eb/No 值不切实际。

在 [2]
#!/usr/bin/python
# BPSK digital modulation: modified example
# by Ivo Maljevic

from scipy import *
from math import sqrt, ceil  # scalar calls are faster
from scipy.special import erfc
import matplotlib.pyplot as plt

rand   = random.rand
normal = random.normal

SNR_MIN   = 0
SNR_MAX   = 10
FrameSize = 10000
Eb_No_dB  = arange(SNR_MIN,SNR_MAX+1)
Eb_No_lin = 10**(Eb_No_dB/10.0)  # linear SNR

# Allocate memory
Pe        = empty(shape(Eb_No_lin))
BER       = empty(shape(Eb_No_lin))

# signal vector (for faster exec we can repeat the same frame)
s = 2*random.randint(0,high=2,size=FrameSize)-1

loop = 0
for snr in Eb_No_lin:
 No        = 1.0/snr
 Pe[loop]  = 0.5*erfc(sqrt(snr))
 nFrames   = ceil(100.0/FrameSize/Pe[loop])
 error_sum = 0
 scale = sqrt(No/2)

 for frame in arange(nFrames):
   # noise
   n = normal(scale=scale, size=FrameSize)

   # received signal + noise
   x = s + n

   # detection (information is encoded in signal phase)
   y = sign(x)

   # error counting
   err = where (y != s)
   error_sum += len(err[0])

   # end of frame loop
   ##################################################

 BER[loop] = error_sum/(FrameSize*nFrames)  # SNR loop level
 print 'Eb_No_dB=%2d, BER=%10.4e, Pe[loop]=%10.4e' % \
        (Eb_No_dB[loop], BER[loop], Pe[loop])
 loop += 1

plt.semilogy(Eb_No_dB, Pe,'r',linewidth=2)
plt.semilogy(Eb_No_dB, BER,'-s')
plt.grid(True)
plt.legend(('analytical','simulation'))
plt.xlabel('Eb/No (dB)')
plt.ylabel('BER')
plt.show()
Eb_No_dB= 0, BER=7.6900e-02, Pe[loop]=7.8650e-02
Eb_No_dB= 1, BER=5.5800e-02, Pe[loop]=5.6282e-02
Eb_No_dB= 2, BER=3.7600e-02, Pe[loop]=3.7506e-02
Eb_No_dB= 3, BER=2.2600e-02, Pe[loop]=2.2878e-02
Eb_No_dB= 4, BER=1.2300e-02, Pe[loop]=1.2501e-02
Eb_No_dB= 5, BER=6.6500e-03, Pe[loop]=5.9539e-03
Eb_No_dB= 6, BER=2.3000e-03, Pe[loop]=2.3883e-03
Eb_No_dB= 7, BER=9.0000e-04, Pe[loop]=7.7267e-04
Eb_No_dB= 8, BER=2.0566e-04, Pe[loop]=1.9091e-04
Eb_No_dB= 9, BER=3.3893e-05, Pe[loop]=3.3627e-05
Eb_No_dB=10, BER=4.1425e-06, Pe[loop]=3.8721e-06

章节作者: IvoMaljevic, GaelVaroquaux

附件