BSC信道下重复码纠错性能仿真 P124302178 李云徽
摘要
本实验通过Python仿真实现了二进制对称信道(BSC)下重复码的纠错性能分析。重复码是一种简单的纠错编码方案,其基本思想是将每个信息比特重复nnn次发送,接收端通过大数判决来纠正错误。实验对比了不同重复次数(3次、5次、7次)的误码率性能,并与理论值进行了比较。结果表明,重复码在信道误码率较低时能够显著降低解码后的误码率,且重复次数越多,纠错能力越强,但编码效率越低。仿真结果与理论值高度吻合,验证了理论分析的正确性和仿真实现的准确性。
一、基本原理
1.1 二进制对称信道(BSC)
二进制对称信道是一种离散无记忆信道,其特点是:
- 输入符号:0 或 1
- 输出符号:0 或 1
- 错误概率:P(0∣1)=P(1∣0)=pP(0|1) = P(1|0) = pP(0∣1)=P(1∣0)=p,即每个比特独立地以概率ppp发生翻转
1.2 重复码编码原理
对于(n,1)(n,1)(n,1)重复码,每个信息比特被重复nnn次发送:
- 输入:d∈{0,1}d \in \{0, 1\}d∈{0,1}
- 编码输出:d,d,...,d⏟n次\underbrace{d, d, ..., d}_{n \text{次}}n次d,d,...,d
例如,对于3次重复码:
- 输入 0 → 编码输出 000
- 输入 1 → 编码输出 111
1.3 大数判决解码原理
接收端对每个码组进行大数判决:
- 统计码组中0和1的个数
- 如果1的个数多于0,则判决为1
- 如果0的个数多于1,则判决为0
对于奇数n=2t+1n = 2t + 1n=2t+1,重复码可以纠正最多ttt个错误。
1.4 理论误码率公式
(n,1)(n,1)(n,1)重复码的理论误码率为:
Pe=∑k=t+1n(nk)pk(1−p)n−k P_e = \sum_{k=t+1}^{n} \binom{n}{k} p^k (1-p)^{n-k}Pe=k=t+1∑n(kn)pk(1−p)n−k
其中t=⌊(n−1)/2⌋t = \lfloor (n-1)/2 \rfloort=⌊(n−1)/2⌋是最大可纠正错误数。
二、代码实现
2.1 整体结构
├── generate_binary_data()# 生成随机二进制数据├── repetition_encode()# 重复码编码├── bsc_channel()# BSC信道模型├── majority_decode()# 大数判决解码├── calculate_bit_error_rate()# 计算误码率├── simulate_bsc_repetition_code()# 仿真主函数├── theoretical_ber()# 理论误码率计算└── plot_ber_curves()# 绘制BER曲线2.2 核心函数详解
2.2.1 BSC信道模型
defbsc_channel(encoded_data,p_error):noise=np.random.rand(len(encoded_data))<p_error received=np.logical_xor(encoded_data,noise).astype(int)returnreceived该函数通过生成均匀分布的随机数来模拟信道噪声,当随机数小于错误概率ppp时,对应比特发生翻转。
2.2.2 大数判决解码
defmajority_decode(received_data,n_repeats):data_length=len(received_data)//n_repeats decoded=np.zeros(data_length,dtype=int)foriinrange(data_length):start=i*n_repeats end=start+n_repeats chunk=received_data[start:end]decoded[i]=1ifnp.sum(chunk)>n_repeats//2else0returndecoded该函数将接收数据按码组分割,对每个码组统计1的个数,通过比较1的个数是否超过半数来进行判决。
2.2.3 理论误码率计算
deftheoretical_ber(n_repeats,p_error):t=(n_repeats-1)//2ber=0forkinrange(t+1,n_repeats+1):ber+=math.comb(n_repeats,k)*(p_error**k)*((1-p_error)**(n_repeats-k))returnber该函数根据二项分布计算超过纠错能力的错误概率之和。
三、仿真结果
3.1 仿真参数
| 参数 | 值 |
|---|---|
| 重复次数 | 3, 5, 7 |
| 信道误码率范围 | 0.0001 ~ 1.0 |
| 数据长度 | 100000 bit |
| 信道误码率采样点数 | 20 |
3.2 仿真数据
| 信道误码率ppp | 3次重复码BER | 5次重复码BER | 7次重复码BER |
|---|---|---|---|
| 0.0001 | 0.0000e+00 | 0.0000e+00 | 0.0000e+00 |
| 0.0004 | 0.0000e+00 | 0.0000e+00 | 0.0000e+00 |
| 0.0018 | 1.0000e-05 | 0.0000e+00 | 0.0000e+00 |
| 0.0078 | 1.7000e-04 | 1.0000e-05 | 0.0000e+00 |
| 0.0336 | 3.3900e-03 | 4.3000e-04 | 5.0000e-05 |
| 0.1438 | 5.6130e-02 | 2.3510e-02 | 1.0500e-02 |
| 0.6158 | 6.7102e-01 | 7.0943e-01 | 7.3995e-01 |
3.3 BER曲线
四、结果分析
4.1 纠错性能对比
从仿真结果可以看出:
低误码率区域(p<0.1p < 0.1p<0.1):重复码表现出显著的纠错效果,误码率相比未编码情况降低了几个数量级。重复次数越多,纠错效果越好。
中等误码率区域(0.1<p<0.50.1 < p < 0.50.1<p<0.5):重复码仍然有效,但优势逐渐减小。此时7次重复码的优势最为明显。
高误码率区域(p>0.5p > 0.5p>0.5):当信道误码率超过0.5时,重复码的性能反而恶化,误码率超过0.5。这是因为此时噪声占主导,大数判决反而更容易出错。
4.2 仿真与理论对比
仿真结果与理论曲线几乎完全重合,验证了仿真实现的正确性。这表明:
- BSC信道模型的实现是准确的
- 大数判决解码算法是正确的
- 理论公式的推导是正确的
4.3 复杂度与性能权衡
| 重复次数 | 编码效率 | 最大纠错能力 | 适用场景 |
|---|---|---|---|
| 3 | 1/3 | 1 bit | 信道质量较好 |
| 5 | 1/5 | 2 bits | 信道质量一般 |
| 7 | 1/7 | 3 bits | 信道质量较差 |
重复码的缺点是编码效率较低,随着重复次数增加,传输效率线性下降。因此在实际应用中需要在纠错能力和传输效率之间进行权衡。
五、结论
本实验通过Python仿真实现了BSC信道下重复码的纠错性能分析,得出以下结论:
重复码是有效的纠错编码方案:在信道误码率较低时,能够显著降低解码后的误码率。
重复次数与纠错能力正相关:重复次数越多,纠错能力越强,但编码效率越低。
仿真结果与理论值高度吻合:验证了理论分析的正确性和仿真实现的准确性。
适用范围有限:重复码仅在信道误码率低于0.5时有效,且编码效率较低,实际应用中通常采用更高效的编码方案(如汉明码、卷积码等)。
六、源码
importnumpyasnpimportmatplotlib.pyplotaspltimportmathdefgenerate_binary_data(length):returnnp.random.randint(0,2,length)defrepetition_encode(data,n_repeats):encoded=np.repeat(data,n_repeats)returnencodeddefbsc_channel(encoded_data,p_error):noise=np.random.rand(len(encoded_data))<p_error received=np.logical_xor(encoded_data,noise).astype(int)returnreceiveddefmajority_decode(received_data,n_repeats):data_length=len(received_data)//n_repeats decoded=np.zeros(data_length,dtype=int)foriinrange(data_length):start=i*n_repeats end=start+n_repeats chunk=received_data[start:end]decoded[i]=1ifnp.sum(chunk)>n_repeats//2else0returndecodeddefcalculate_bit_error_rate(original,decoded):errors=np.sum(original!=decoded)returnerrors/len(original)defsimulate_bsc_repetition_code(n_repeats_list,p_error_list,data_length=100000):ber_results={}forn_repeatsinn_repeats_list:ber_values=[]forp_errorinp_error_list:data=generate_binary_data(data_length)encoded=repetition_encode(data,n_repeats)received=bsc_channel(encoded,p_error)decoded=majority_decode(received,n_repeats)ber=calculate_bit_error_rate(data,decoded)ber_values.append(ber)ber_results[n_repeats]=ber_valuesreturnber_resultsdeftheoretical_ber(n_repeats,p_error):t=(n_repeats-1)//2ber=0forkinrange(t+1,n_repeats+1):ber+=math.comb(n_repeats,k)*(p_error**k)*((1-p_error)**(n_repeats-k))returnberdefplot_ber_curves(p_error_list,ber_results,n_repeats_list):plt.rcParams['font.sans-serif']=['SimHei','Microsoft YaHei','DejaVu Sans']plt.rcParams['axes.unicode_minus']=Falseplt.figure(figsize=(10,6))colors=['blue','red','green','orange','purple']markers=['o','s','^','D','v']foridx,n_repeatsinenumerate(n_repeats_list):plt.semilogy(p_error_list,ber_results[n_repeats],color=colors[idx],marker=markers[idx],linestyle='-',linewidth=2,markersize=6,label=f'{n_repeats}次重复码(仿真)')theoretical_values=[theoretical_ber(n_repeats,p)forpinp_error_list]plt.semilogy(p_error_list,theoretical_values,color=colors[idx],linestyle='--',linewidth=1.5,label=f'{n_repeats}次重复码(理论)')plt.semilogy(p_error_list,p_error_list,'k--',linewidth=2,label='未编码(理论)')plt.xlabel('信道误码率 $p$',fontsize=12)plt.ylabel('解码后误码率 BER',fontsize=12)plt.title('BSC信道下重复码纠错性能仿真',fontsize=14,fontweight='bold')plt.grid(True,which='both',linestyle='--',alpha=0.7)plt.legend(fontsize=10,loc='upper left')plt.xlim([min(p_error_list),max(p_error_list)])plt.ylim([1e-10,1])plt.tight_layout()plt.savefig('ber_curves.png',dpi=300,bbox_inches='tight')plt.show()defmain():np.random.seed(42)n_repeats_list=[3,5,7]p_error_list=np.logspace(-4,0,20)print("="*60)print("BSC信道下重复码纠错性能仿真")print("="*60)print(f"\n仿真参数:")print(f" 重复次数:{n_repeats_list}")print(f" 信道误码率范围:{p_error_list[0]:.4f}~{p_error_list[-1]:.4f}")print(f" 数据长度:100000 bit")print(f"\n正在进行仿真...")ber_results=simulate_bsc_repetition_code(n_repeats_list,p_error_list)print(f"\n仿真结果:")print(f"{'信道误码率':<15}",end='')forninn_repeats_list:print(f"|{n}次重复码BER",end='')print()print("-"*60)fori,pinenumerate(p_error_list[::3]):print(f"{p:<15.4f}",end='')forninn_repeats_list:print(f"|{ber_results[n][i*3]:<15.4e}",end='')print()print(f"\n绘制BER曲线...")plot_ber_curves(p_error_list,ber_results,n_repeats_list)print(f"\n仿真完成!结果图已保存为 'ber_curves.png'")print("="*60)if__name__=="__main__":main()