%% 实验3.1 汉明码编译码系统 - 修正版
clear all; close all; clc;
%% 参数设置
m = 3; % 汉明码参数m=3 (7,4)
n = 7; % 码长
k = 4; % 信息位长度
% 标准(7,4)汉明码的生成矩阵
G = [1 0 0 0 1 1 0; % 系统形式的生成矩阵
0 1 0 0 1 0 1;
0 0 1 0 0 1 1;
0 0 0 1 1 1 1];
% 校验矩阵
H = [1 1 0 1 1 0 0; % 标准形式校验矩阵
1 0 1 1 0 1 0;
0 1 1 1 0 0 1];
% 仿真参数
SNR_dB = 0:2:10; % 信噪比范围(dB)
num_bits = 1e6; % 仿真比特数(增加以获得更准确结果)
p_errors = logspace(-3, -1, 5); % BSC错误概率范围
%% 主程序演示
fprintf('标准(7,4)汉明码性能测试:\n');
% 测试用例
test_msg = [1 0 1 0];
codeword = mod(test_msg * G, 2);
fprintf('\n测试编码:\n信息位: %s\n编码后: %s\n', num2str(test_msg), num2str(codeword));
% 引入错误
error_pos = 3;
rx_codeword = codeword;
rx_codeword(error_pos) = ~rx_codeword(error_pos);
fprintf('引入错误在位置%d: %s\n', error_pos, num2str(rx_codeword));
% 解码测试
syndrome = mod(rx_codeword * H', 2);
error_loc = bi2de(syndrome, 'left-msb') + 1;
if error_loc > 0 && error_loc <= n
rx_codeword(error_loc) = ~rx_codeword(error_loc);
end
decoded_msg = rx_codeword(1:k);
fprintf('解码结果: %s\n纠正位置: %d\n', num2str(decoded_msg), error_loc);
%% BSC信道仿真
ber_bsc = zeros(size(p_errors));
ber_uncoded_bsc = zeros(size(p_errors));
for i = 1:length(p_errors)
p = p_errors(i);
num_errors = 0;
num_errors_uncoded = 0;
num_blocks = ceil(num_bits / k);
for j = 1:num_blocks
msg = randi([0 1], 1, k);
codeword = mod(msg * G, 2);
% 信道传输(编码情况)
errors = rand(1, n) < p;
rx_codeword = xor(codeword, errors);
% 解码
syndrome = mod(rx_codeword * H', 2);
error_loc = bi2de(syndrome, 'left-msb') + 1;
if error_loc > 0 && error_loc <= n
rx_codeword(error_loc) = ~rx_codeword(error_loc);
end
decoded_msg = rx_codeword(1:k);
% 统计错误(编码情况)
num_errors = num_errors + sum(xor(msg, decoded_msg));
% 未编码情况(相同数量的信息比特通过BSC)
uncoded_rx = xor(msg, rand(1, k) < p);
num_errors_uncoded = num_errors_uncoded + sum(xor(msg, uncoded_rx));
end
ber_bsc(i) = num_errors / (num_blocks * k);
ber_uncoded_bsc(i) = num_errors_uncoded / (num_blocks * k);
fprintf('BSC p=%.3f: 编码BER=%.2e, 未编码BER=%.2e\n',...
p, ber_bsc(i), ber_uncoded_bsc(i));
end
%% AWGN信道仿真
ber_awgn = zeros(size(SNR_dB));
ber_uncoded_awgn = zeros(size(SNR_dB));
for i = 1:length(SNR_dB)
snr = SNR_dB(i);
snr_linear = 10^(snr/10); % 转换为线性值
num_errors = 0;
num_errors_uncoded = 0;
num_blocks = ceil(num_bits / k);
% 计算编码和未编码的Eb/N0
EbN0_coded = snr_linear * k/n; % 编码后每个信息比特的能量
EbN0_uncoded = snr_linear; % 未编码时每个比特的能量
for j = 1:num_blocks
msg = randi([0 1], 1, k);
codeword = mod(msg * G, 2);
% BPSK调制+AWGN(编码情况)
tx_signal = 2 * codeword - 1;
noise_power = 1/(2*EbN0_coded);
noise = sqrt(noise_power) * randn(1, n);
rx_signal = tx_signal + noise;
rx_codeword = rx_signal > 0;
% 解码
syndrome = mod(rx_codeword * H', 2);
error_loc = bi2de(syndrome, 'left-msb') + 1;
if error_loc > 0 && error_loc <= n
rx_codeword(error_loc) = ~rx_codeword(error_loc);
end
decoded_msg = rx_codeword(1:k);
% 统计错误(编码情况)
num_errors = num_errors + sum(xor(msg, decoded_msg));
% 未编码情况(相同数量的信息比特)
tx_uncoded = 2 * msg - 1;
noise_power_uncoded = 1/(2*EbN0_uncoded);
noise_uncoded = sqrt(noise_power_uncoded) * randn(1, k);
rx_uncoded = tx_uncoded + noise_uncoded;
rx_msg = rx_uncoded > 0;
% 统计错误(未编码情况)
num_errors_uncoded = num_errors_uncoded + sum(xor(msg, rx_msg));
end
ber_awgn(i) = num_errors / (num_blocks * k);
ber_uncoded_awgn(i) = num_errors_uncoded / (num_blocks * k);
fprintf('SNR=%.1fdB: 编码BER=%.2e, 未编码BER=%.2e\n',...
SNR_dB(i), ber_awgn(i), ber_uncoded_awgn(i));
end
%% 结果可视化
figure;
subplot(1,2,1);
semilogy(p_errors, ber_bsc, 'b-o', 'LineWidth', 1.5); hold on;
semilogy(p_errors, ber_uncoded_bsc, 'r--s', 'LineWidth', 1.5);
xlabel('BSC错误概率'); ylabel('BER'); title('BSC信道性能');
legend('(7,4)汉明码','未编码', 'Location', 'southwest');
grid on; axis tight;
subplot(1,2,2);
semilogy(SNR_dB, ber_awgn, 'b-o', 'LineWidth', 1.5); hold on;
semilogy(SNR_dB, ber_uncoded_awgn, 'r--s', 'LineWidth', 1.5);
xlabel('SNR (dB)'); ylabel('BER'); title('AWGN信道性能');
legend('(7,4)汉明码','未编码', 'Location', 'southwest');
grid on; axis tight;
sgtitle('(7,4)汉明码与未编码系统性能比较');
%% 编码函数
function codeword = hamming_encode(msg, G)
codeword = mod(msg * G, 2);
end
%% 解码函数
function [decoded_msg, error_loc] = hamming_decode(rx_codeword, H, k)
syndrome = mod(rx_codeword * H', 2);
error_loc = bi2de(syndrome, 'left-msb') + 1;
if error_loc > 0 && error_loc <= length(rx_codeword)
rx_codeword(error_loc) = ~rx_codeword(error_loc);
end
decoded_msg = rx_codeword(1:k);
end这个代码为什么编码后误码率反而变高了,修改后给我完整代码