极化码(Polar Codes)的MATLAB实现
极化码理论基础
1. 核心原理
极化码是首类达到香农限 的编码方案,核心思想是信道极化:
- 通过递归变换将N个独立信道转换为N个极化信道
- 部分信道趋于完美(容量→1),部分信道趋于完全噪声(容量→0)
- 在完美信道传输信息比特,在噪声信道传输冻结比特
2. 数学表示
生成矩阵:
G_N = B_N × F^{⊗n}
其中:
F = [1 0; 1 1] (基本核)
B_N: 比特反转排列矩阵
F^{⊗n}: F的n次克罗内克积,n = log2(N)
MATLAB实现
1. 主程序框架(main.m)
matlab
%% 极化码的信道编码与构造 - MATLAB实现
% 作者:AI助手
% 功能:完整的极化码编码、解码、性能仿真
% 包括:构造、编码、SC/SCL解码、性能分析
clear; clc; close all;
warning off;
fprintf('=========================================\n');
fprintf(' 极化码仿真系统 v1.0\n');
fprintf('=========================================\n\n');
%% 参数设置
params.N = 512; % 码长(必须是2的幂)
params.K = 256; % 信息位长度
params.R = params.K / params.N; % 码率
params.n = log2(params.N); % 极化级数
params.EbN0_dB = 0:0.5:3; % 信噪比范围(dB)
params.num_frames = 1000; % 仿真帧数
params.max_errors = 100; % 最大错误数
params.decoder_type = 'SCL'; % 解码器类型: 'SC', 'SCL', 'BP'
params.list_size = 8; % SCL解码的列表大小
params.crc_length = 16; % CRC长度(用于SCL解码)
params.channel_type = 'AWGN'; % 信道类型: 'AWGN', 'BSC', 'BEC'
params.modulation = 'BPSK'; % 调制方式: 'BPSK', 'QPSK'
params.construction_method = 'GA'; % 构造方法: 'Bhattacharyya', 'GA', 'PW'
%% 极化码构造
fprintf('>> 步骤1: 极化码构造\n');
fprintf(' 码长: N = %d\n', params.N);
fprintf(' 信息位: K = %d\n', params.K);
fprintf(' 码率: R = %.3f\n', params.R);
fprintf(' 构造方法: %s\n', params.construction_method);
% 构造极化码
polar_code = construct_polar_code(params);
fprintf(' 构造完成!\n\n');
%% 编码器测试
fprintf('>> 步骤2: 编码器测试\n');
test_encoder(polar_code, params);
%% 解码器测试
fprintf('>> 步骤3: 解码器测试\n');
test_decoder(polar_code, params);
%% 性能仿真
fprintf('>> 步骤4: 性能仿真\n');
fprintf(' 解码器类型: %s\n', params.decoder_type);
if strcmp(params.decoder_type, 'SCL')
fprintf(' 列表大小: L = %d\n', params.list_size);
fprintf(' CRC长度: %d\n', params.crc_length);
end
fprintf(' 仿真帧数: %d\n', params.num_frames);
fprintf(' 最大错误数: %d\n', params.max_errors);
% 运行性能仿真
[BER, FER] = simulate_performance(polar_code, params);
%% 结果显示
fprintf('\n>> 步骤5: 结果显示\n');
plot_results(BER, FER, params);
fprintf('\n=========================================\n');
fprintf(' 仿真完成!\n');
fprintf('=========================================\n');
2. 极化码构造函数(construct_polar_code.m)
matlab
function polar_code = construct_polar_code(params)
% 构造极化码
% 输入:params - 参数结构体
% 输出:polar_code - 极化码结构体
N = params.N;
K = params.K;
n = params.n;
% 初始化极化码结构
polar_code = struct();
polar_code.N = N;
polar_code.K = K;
polar_code.n = n;
polar_code.R = K/N;
% 1. 计算极化信道的可靠性
fprintf(' 计算信道可靠性...\n');
switch params.construction_method
case 'Bhattacharyya'
% Bhattacharyya参数构造法(适用于BEC信道)
Z = calculate_bhattacharyya_params(N, params.channel_type);
case 'GA'
% 高斯近似构造法(适用于AWGN信道)
Z = calculate_gaussian_approximation(N, params.R, params.EbN0_dB(1));
case 'PW'
% 极化权重构造法
Z = calculate_polarization_weights(N);
otherwise
error('未知的构造方法: %s', params.construction_method);
end
% 2. 选择信息位(可靠性最高的K个位置)
[~, sorted_idx] = sort(Z, 'ascend'); % 按可靠性升序排列
info_pos = sorted_idx(1:K); % 选择最可靠的K个位置
frozen_pos = sorted_idx(K+1:end); % 剩余为冻结位
% 3. 生成矩阵构造
fprintf(' 生成极化码矩阵...\n');
G_N = generate_polar_matrix(N);
% 4. 生成CRC多项式(如果使用SCL解码)
if params.crc_length > 0
polar_code.crc_poly = generate_crc_poly(params.crc_length);
end
% 5. 保存构造结果
polar_code.info_pos = sort(info_pos); % 信息位位置
polar_code.frozen_pos = sort(frozen_pos); % 冻结位位置
polar_code.Z = Z; % 信道可靠性度量
polar_code.G_N = G_N; % 生成矩阵
polar_code.F = [1 0; 1 1]; % 基本核
% 6. 验证构造
validate_construction(polar_code);
fprintf(' 信息位位置: %s\n', mat2str(polar_code.info_pos(1:10)));
if length(polar_code.info_pos) > 10
fprintf(' ...\n');
end
end
function Z = calculate_bhattacharyya_params(N, channel_type)
% 计算Bhattacharyya参数(递归方法)
% 对于BEC信道,Z(W) = 2Z - Z^2
n = log2(N);
Z = zeros(N, 1);
Z(1) = 0.5; % 初始Bhattacharyya参数(对称容量I(W)=0.5)
for level = 1:n
Z_next = zeros(2^level, 1);
for i = 1:2^(level-1)
Z_prev = Z(i);
if strcmp(channel_type, 'BEC')
% BEC信道的递归公式
Z_next(2*i-1) = 2*Z_prev - Z_prev^2;
Z_next(2*i) = Z_prev^2;
else
% 通用递归公式
Z_next(2*i-1) = min(1, 2*Z_prev - Z_prev^2);
Z_next(2*i) = Z_prev^2;
end
end
Z = Z_next;
end
end
function Z = calculate_gaussian_approximation(N, R, EbN0_dB)
% 高斯近似构造法
n = log2(N);
sigma_ch = 1 / sqrt(2 * R * 10^(EbN0_dB/10)); % 信道噪声标准差
mu0 = 2 / sigma_ch^2; % 初始LLR均值
% 递归计算高斯均值
mu = zeros(N, 1);
mu(1) = mu0;
for level = 1:n
mu_next = zeros(2^level, 1);
for i = 1:2^(level-1)
mu_prev = mu(i);
% 高斯近似的递归公式
mu_next(2*i-1) = phi_inv(1 - (1 - phi(mu_prev))^2);
mu_next(2*i) = 2 * mu_prev;
end
mu = mu_next;
end
% 计算错误概率
Z = qfunc(sqrt(mu/2));
end
function Z = calculate_polarization_weights(N)
% 极化权重构造法(5G标准方法)
n = log2(N);
beta = 0.25; % 5G标准中使用的参数
% 计算每个位置的极化权重
weights = zeros(N, 1);
for i = 0:N-1
binary = dec2bin(i, n); % 转换为二进制
weight = 0;
for j = 1:n
if binary(j) == '1'
weight = weight + beta^(j-1);
end
end
weights(i+1) = weight;
end
% 使用权重作为可靠性度量
Z = 1 ./ (weights + 1e-10); % 权重越大越可靠
end
function G_N = generate_polar_matrix(N)
% 生成极化码生成矩阵 G_N = B_N * F^{⊗n}
n = log2(N);
% 基本核
F = [1 0; 1 1];
% 计算F的n次克罗内克积
F_n = 1;
for i = 1:n
F_n = kron(F_n, F);
end
% 比特反转排列矩阵
B_N = generate_bit_reversal_matrix(N);
% 生成矩阵
G_N = mod(B_N * F_n, 2);
end
function B = generate_bit_reversal_matrix(N)
% 生成比特反转排列矩阵
n = log2(N);
B = zeros(N, N);
for i = 0:N-1
% 计算比特反转
i_rev = 0;
for bit = 0:n-1
if bitand(i, 2^bit) ~= 0
i_rev = bitor(i_rev, 2^(n-1-bit));
end
end
B(i_rev+1, i+1) = 1;
end
end
function crc_poly = generate_crc_poly(crc_length)
% 生成CRC多项式
switch crc_length
case 8
crc_poly = [1 0 0 0 1 1 1 0 1]; % CRC-8
case 16
crc_poly = [1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1]; % CRC-16
case 24
crc_poly = [1 1 0 0 0 0 1 1 0 0 1 0 0 1 1 0 0 1 1 1 1 1 0 1 1]; % CRC-24
case 32
crc_poly = [1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 0 1 1 0 1 1 1]; % CRC-32
otherwise
error('不支持的CRC长度: %d', crc_length);
end
end
function validate_construction(polar_code)
% 验证极化码构造
N = polar_code.N;
K = polar_code.K;
% 验证信息位和冻结位
all_pos = 1:N;
union_pos = union(polar_code.info_pos, polar_code.frozen_pos);
if length(union_pos) ~= N
error('信息位和冻结位不完整!');
end
if length(intersect(polar_code.info_pos, polar_code.frozen_pos)) > 0
error('信息位和冻结位有重叠!');
end
% 验证生成矩阵
G = polar_code.G_N;
if size(G,1) ~= N || size(G,2) ~= N
error('生成矩阵维度错误!');
end
% 验证生成矩阵的秩
if rank(G) ~= N
error('生成矩阵不是满秩!');
end
fprintf(' 构造验证通过!\n');
end
3. 辅助函数(phi_functions.m)
matlab
function y = phi(x)
% phi函数:用于高斯近似
if x < 10
y = exp(-0.4527*x^0.86 + 0.0218);
else
y = sqrt(pi/x) * exp(-x/4) * (1 - 10/(7*x));
end
end
function y = phi_inv(z)
% phi函数的逆
if z > 0.9999
y = 0;
elseif z < 1e-6
y = 20;
else
% 通过迭代求解
y_low = 0;
y_high = 20;
for iter = 1:20
y_mid = (y_low + y_high) / 2;
if phi(y_mid) > z
y_high = y_mid;
else
y_low = y_mid;
end
end
y = y_mid;
end
end
4. 编码器实现(polar_encode.m)
matlab
function encoded_bits = polar_encode(info_bits, polar_code, params)
% 极化码编码
% 输入:info_bits - 信息比特向量
% polar_code - 极化码结构
% params - 参数
% 输出:encoded_bits - 编码后的比特
N = polar_code.N;
K = polar_code.K;
% 验证输入长度
if length(info_bits) ~= K
error('信息比特长度错误!期望 %d,实际 %d', K, length(info_bits));
end
% 1. 如果需要CRC,添加CRC校验
if isfield(params, 'crc_length') && params.crc_length > 0
info_bits_with_crc = add_crc(info_bits, polar_code.crc_poly);
K_crc = length(info_bits_with_crc);
else
info_bits_with_crc = info_bits;
K_crc = K;
end
% 2. 构建完整的信息向量(包含冻结比特)
u = zeros(N, 1);
u(polar_code.info_pos(1:K_crc)) = info_bits_with_crc; % 信息位
u(polar_code.frozen_pos) = 0; % 冻结位设为0
% 3. 编码:x = u * G_N mod 2
encoded_bits = mod(u' * polar_code.G_N, 2)';
% 4. 速率匹配(如果需要)
if isfield(params, 'rate_matching') && params.rate_matching
encoded_bits = rate_matching(encoded_bits, params);
end
fprintf('编码完成: %d 信息比特 -> %d 编码比特\n', K, length(encoded_bits));
end
function data_with_crc = add_crc(data, crc_poly)
% 添加CRC校验
m = length(crc_poly) - 1; % CRC阶数
data_padded = [data, zeros(1, m)];
% 多项式除法
for i = 1:length(data)
if data_padded(i) == 1
data_padded(i:i+m) = mod(data_padded(i:i+m) + crc_poly, 2);
end
end
data_with_crc = [data, data_padded(length(data)+1:end)];
end
function matched_bits = rate_matching(encoded_bits, params)
% 速率匹配(缩短、打孔、重复)
E = params.E; % 输出长度
if E == length(encoded_bits)
matched_bits = encoded_bits;
elseif E < length(encoded_bits)
% 缩短或打孔
matched_bits = encoded_bits(1:E);
else
% 重复
n_repeats = ceil(E / length(encoded_bits));
repeated = repmat(encoded_bits, n_repeats, 1);
matched_bits = repeated(1:E);
end
end
5. SC解码器实现(sc_decode.m)
matlab
function [decoded_bits, info_bits] = sc_decode(llr, polar_code, params)
% SC(连续消除)解码
% 输入:llr - 对数似然比向量
% polar_code - 极化码结构
% params - 参数
% 输出:decoded_bits - 解码后的所有比特
% info_bits - 解码后的信息比特
N = polar_code.N;
K = polar_code.K;
n = polar_code.n;
% 初始化
L = zeros(N, n+1); % LLR数组
B = zeros(N, n+1); % 比特估计数组
decoded_bits = zeros(N, 1);
% 设置初始LLR
L(:, n+1) = llr;
% 递归解码
for i = 1:N
[decoded_bits(i), L, B] = decode_bit(i-1, 0, n, L, B, polar_code);
end
% 提取信息比特
info_bits = decoded_bits(polar_code.info_pos(1:K));
% 如果有CRC,验证CRC
if isfield(params, 'crc_length') && params.crc_length > 0
K_crc = K + params.crc_length;
info_bits_with_crc = decoded_bits(polar_code.info_pos(1:K_crc));
% 检查CRC
if check_crc(info_bits_with_crc, polar_code.crc_poly)
fprintf('CRC校验通过\n');
info_bits = info_bits_with_crc(1:K);
else
fprintf('CRC校验失败\n');
info_bits = NaN(K, 1);
end
end
end
function [bit_decision, L, B] = decode_bit(phi, lambda, layer, L, B, polar_code)
% 递归解码单个比特
if layer == 0
% 叶子节点
llr = L(phi+1, lambda+1);
if ismember(phi+1, polar_code.frozen_pos)
% 冻结比特,强制为0
bit_decision = 0;
else
% 信息比特,硬判决
bit_decision = (llr < 0);
end
B(phi+1, lambda+1) = bit_decision;
return;
end
% 计算psi
psi = floor(phi/2);
if mod(phi, 2) == 0
% 左子节点
[u_left, L, B] = decode_bit(2*psi, lambda+1, layer-1, L, B, polar_code);
[u_right, L, B] = decode_bit(2*psi+1, lambda+1, layer-1, L, B, polar_code);
% 计算当前节点的LLR
llr_left = L(2*psi+1, lambda+1);
llr_right = L(2*psi+2, lambda+1);
L(psi+1, lambda+1) = f_function(llr_left, llr_right);
% 递归调用右子节点
[bit_decision, L, B] = decode_bit(psi, lambda, layer-1, L, B, polar_code);
else
% 右子节点
bit_decision = B(psi+1, lambda+1);
end
B(phi+1, lambda+1) = bit_decision;
end
function result = f_function(a, b)
% f函数:L1 ⊞ L2
% 使用最小和近似以提高数值稳定性
sign_a = sign(a);
sign_b = sign(b);
if sign_a == 0 || sign_b == 0
result = 0;
else
result = sign_a * sign_b * min(abs(a), abs(b));
end
% 精确计算(注释掉,因为数值不稳定)
% result = 2 * atanh(tanh(a/2) * tanh(b/2));
end
function result = g_function(a, b, u)
% g函数:L1 ⊞ (1-2u)L2
if u == 0
result = a + b;
else
result = b - a;
end
end
参考代码 极化码的信道编码与构造在matlab 上的实现 www.youwenfan.com/contentcst/45806.html
6. SCL解码器实现(scl_decode.m)
matlab
function [decoded_bits, info_bits] = scl_decode(llr, polar_code, params)
% SCL(连续消除列表)解码
% 输入:llr - 对数似然比向量
% polar_code - 极化码结构
% params - 参数
% 输出:decoded_bits - 解码后的所有比特
% info_bits - 解码后的信息比特
L = params.list_size; % 列表大小
N = polar_code.N;
K = polar_code.K;
n = polar_code.n;
% 初始化路径度量
PM = zeros(L, 1); % 路径度量
PM(:) = Inf; % 初始化为无穷大
PM(1) = 0; % 第一个路径度量为0
% 路径存储
paths = cell(L, 1);
for l = 1:L
paths{l} = struct();
paths{l}.llr = zeros(N, n+1);
paths{l}.bits = zeros(N, n+1);
paths{l}.decisions = zeros(N, 1);
paths{l}.active = (l == 1); % 只有第一个路径初始激活
end
% 主解码循环
for i = 1:N
% 激活路径列表
active_paths = find([paths{:}.active]);
for l_idx = 1:length(active_paths)
l = active_paths(l_idx);
path = paths{l};
% 计算当前比特的LLR
[llr_current, path] = calculate_llr(i-1, 0, n, path, polar_code);
if ismember(i, polar_code.frozen_pos)
% 冻结比特,只有一种选择
bit_decision = 0;
[path, PM(l)] = update_path_metric(path, PM(l), llr_current, bit_decision, i);
else
% 信息比特,需要扩展两条路径
% 复制当前路径
if sum([paths{:}.active]) < L
% 找到空闲路径
free_paths = find(~[paths{:}.active]);
if ~isempty(free_paths)
l2 = free_paths(1);
paths{l2} = path;
paths{l2}.active = true;
% 更新两条路径
[paths{l}, PM(l)] = update_path_metric(paths{l}, PM(l), llr_current, 0, i);
[paths{l2}, PM(l2)] = update_path_metric(paths{l2}, PM(l), llr_current, 1, i);
end
else
% 列表已满,需要剪枝
% 暂时扩展所有路径
temp_paths = cell(L*2, 1);
temp_PM = zeros(L*2, 1);
for ll = 1:L
if paths{ll}.active
% 扩展两条路径
temp_paths{2*ll-1} = paths{ll};
temp_paths{2*ll} = paths{ll};
temp_PM(2*ll-1) = update_path_metric(temp_paths{2*ll-1}, PM(ll), llr_current, 0, i);
temp_PM(2*ll) = update_path_metric(temp_paths{2*ll}, PM(ll), llr_current, 1, i);
end
end
% 选择最好的L条路径
[~, sorted_idx] = sort(temp_PM);
best_idx = sorted_idx(1:min(L, sum(~isinf(temp_PM))));
% 更新路径
for ll = 1:L
if ll <= length(best_idx)
paths{ll} = temp_paths{best_idx(ll)};
PM(ll) = temp_PM(best_idx(ll));
paths{ll}.active = true;
else
paths{ll}.active = false;
PM(ll) = Inf;
end
end
end
end
paths{l} = path;
end
end
% 选择最佳路径
active_paths = find([paths{:}.active]);
if isempty(active_paths)
error('没有有效路径!');
end
[~, best_idx] = min(PM(active_paths));
best_path = paths{active_paths(best_idx)};
decoded_bits = best_path.decisions;
% 提取信息比特
K_total = length(polar_code.info_pos);
info_bits_with_crc = decoded_bits(polar_code.info_pos(1:K_total));
% 如果有CRC,验证CRC
if isfield(params, 'crc_length') && params.crc_length > 0
K_crc = K + params.crc_length;
% 在列表中选择通过CRC的路径
for l = active_paths
candidate_bits = paths{l}.decisions(polar_code.info_pos(1:K_crc));
if check_crc(candidate_bits, polar_code.crc_poly)
decoded_bits = paths{l}.decisions;
info_bits_with_crc = candidate_bits;
break;
end
end
end
info_bits = info_bits_with_crc(1:K);
end
function [llr, path] = calculate_llr(phi, lambda, layer, path, polar_code)
% 计算指定位置的LLR
if layer == 0
llr = path.llr(phi+1, lambda+1);
return;
end
psi = floor(phi/2);
if mod(phi, 2) == 0
% 左子节点
[llr_left, path] = calculate_llr(2*psi, lambda+1, layer-1, path, polar_code);
[llr_right, path] = calculate_llr(2*psi+1, lambda+1, layer-1, path, polar_code);
llr = f_function(llr_left, llr_right);
else
% 右子节点
bit_est = path.bits(psi+1, lambda+1);
[llr_left, path] = calculate_llr(2*psi, lambda+1, layer-1, path, polar_code);
[llr_right, path] = calculate_llr(2*psi+1, lambda+1, layer-1, path, polar_code);
llr = g_function(llr_left, llr_right, bit_est);
end
path.llr(phi+1, lambda+1) = llr;
end
function [path, new_PM] = update_path_metric(path, old_PM, llr, decision, idx)
% 更新路径度量
% 计算比特的对数似然
if decision == 0
log_prob = -log(1 + exp(-llr));
else
log_prob = -log(1 + exp(llr));
end
% 更新路径度量
new_PM = old_PM - log_prob;
% 更新路径
path.decisions(idx) = decision;
path.bits(idx, 1) = decision;
end
7. 性能仿真(simulate_performance.m)
matlab
function [BER, FER] = simulate_performance(polar_code, params)
% 性能仿真
N = polar_code.N;
K = polar_code.K;
num_EbN0 = length(params.EbN0_dB);
% 初始化结果
BER = zeros(num_EbN0, 1);
FER = zeros(num_EbN0, 1);
% 进度条
h = waitbar(0, '开始性能仿真...');
for snr_idx = 1:num_EbN0
EbN0_dB = params.EbN0_dB(snr_idx);
fprintf(' Eb/N0 = %.1f dB\n', EbN0_dB);
% 初始化统计
bit_errors = 0;
frame_errors = 0;
total_bits = 0;
total_frames = 0;
% 计算信噪比参数
EbN0 = 10^(EbN0_dB/10);
sigma = 1 / sqrt(2 * polar_code.R * EbN0); % 噪声标准差
while total_frames < params.num_frames && frame_errors < params.max_errors
% 生成随机信息比特
info_bits = randi([0, 1], K, 1);
% 编码
encoded_bits = polar_encode(info_bits, polar_code, params);
% BPSK调制:0->+1, 1->-1
modulated = 1 - 2 * encoded_bits;
% AWGN信道
noise = sigma * randn(size(modulated));
received = modulated + noise;
% 计算LLR
llr = 2 * received / (sigma^2);
% 解码
switch params.decoder_type
case 'SC'
[decoded_bits, decoded_info] = sc_decode(llr, polar_code, params);
case 'SCL'
[decoded_bits, decoded_info] = scl_decode(llr, polar_code, params);
case 'BP'
[decoded_bits, decoded_info] = bp_decode(llr, polar_code, params);
otherwise
error('未知的解码器类型: %s', params.decoder_type);
end
% 统计错误
if ~any(isnan(decoded_info))
bit_err = sum(decoded_info ~= info_bits);
frame_err = (bit_err > 0);
bit_errors = bit_errors + bit_err;
frame_errors = frame_errors + frame_err;
else
% CRC校验失败
frame_err = 1;
bit_err = K; % 假设所有比特都错误
frame_errors = frame_errors + 1;
bit_errors = bit_errors + bit_err;
end
total_bits = total_bits + K;
total_frames = total_frames + 1;
% 更新进度
if mod(total_frames, 100) == 0
waitbar(total_frames/params.num_frames, h, ...
sprintf('Eb/N0=%.1f dB: 仿真 %d/%d 帧', EbN0_dB, total_frames, params.num_frames));
end
end
% 计算BER和FER
BER(snr_idx) = bit_errors / total_bits;
FER(snr_idx) = frame_errors / total_frames;
fprintf(' BER: %.2e, FER: %.2e\n', BER(snr_idx), FER(snr_idx));
% 更新进度条
waitbar(snr_idx/num_EbN0, h, sprintf('进度: %d/%d', snr_idx, num_EbN0));
end
close(h);
end
8. 测试函数(test_encoder.m, test_decoder.m)
matlab
function test_encoder(polar_code, params)
% 测试编码器
K = polar_code.K;
N = polar_code.N;
fprintf(' 测试编码器...\n');
% 生成测试数据
test_info = randi([0, 1], K, 1);
% 编码
encoded = polar_encode(test_info, polar_code, params);
% 验证编码长度
if length(encoded) ~= N
error('编码长度错误!期望 %d,实际 %d', N, length(encoded));
end
% 验证冻结比特
u = mod(polar_code.G_N \ encoded, 2);
frozen_bits = u(polar_code.frozen_pos);
if any(frozen_bits ~= 0)
error('冻结比特不为0!');
end
fprintf(' 编码器测试通过!\n');
end
function test_decoder(polar_code, params)
% 测试解码器
K = polar_code.K;
N = polar_code.N;
fprintf(' 测试解码器...\n');
% 生成测试数据
test_info = randi([0, 1], K, 1);
% 编码
encoded = polar_encode(test_info, polar_code, params);
% 无噪声测试
modulated = 1 - 2 * encoded;
llr = 2 * modulated; % 无噪声时sigma=1
% 解码
switch params.decoder_type
case 'SC'
[~, decoded_info] = sc_decode(llr, polar_code, params);
case 'SCL'
[~, decoded_info] = scl_decode(llr, polar_code, params);
end
% 验证解码结果
if ~any(isnan(decoded_info))
if all(decoded_info == test_info)
fprintf(' 解码器无噪声测试通过!\n');
else
error('解码器无噪声测试失败!');
end
else
fprintf(' CRC校验失败(无噪声)\n');
end
% 低噪声测试
sigma = 0.1; % 低噪声
noise = sigma * randn(size(modulated));
received = modulated + noise;
llr_noisy = 2 * received / (sigma^2);
switch params.decoder_type
case 'SC'
[~, decoded_info_noisy] = sc_decode(llr_noisy, polar_code, params);
case 'SCL'
[~, decoded_info_noisy] = scl_decode(llr_noisy, polar_code, params);
end
if ~any(isnan(decoded_info_noisy))
bit_err = sum(decoded_info_noisy ~= test_info);
fprintf(' 低噪声测试:比特错误数 = %d\n', bit_err);
end
end
9. 结果可视化(plot_results.m)
matlab
function plot_results(BER, FER, params)
% 绘制性能曲线
figure('Position', [100, 100, 1200, 500]);
% BER曲线
subplot(1, 2, 1);
semilogy(params.EbN0_dB, BER, 'b-o', 'LineWidth', 2, 'MarkerSize', 8);
hold on;
% 理论界限(BPSK AWGN)
theory_BER = qfunc(sqrt(2 * 10.^(params.EbN0_dB/10)));
semilogy(params.EbN0_dB, theory_BER, 'r--', 'LineWidth', 2);
grid on;
xlabel('Eb/N0 (dB)');
ylabel('误比特率 (BER)');
title(sprintf('极化码性能 (N=%d, K=%d, R=%.2f)', params.N, params.K, params.R));
legend(sprintf('%s解码', params.decoder_type), 'BPSK理论界限', 'Location', 'southwest');
% 添加标注
text(0.5, 0.5, sprintf('列表大小 L=%d', params.list_size), ...
'Units', 'normalized', 'FontSize', 10);
% FER曲线
subplot(1, 2, 2);
semilogy(params.EbN0_dB, FER, 'r-s', 'LineWidth', 2, 'MarkerSize', 8);
grid on;
xlabel('Eb/N0 (dB)');
ylabel('误帧率 (FER)');
title('误帧率性能');
legend(sprintf('%s解码', params.decoder_type), 'Location', 'southwest');
% 保存图像
timestamp = datestr(now, 'yyyy-mm-dd_HH-MM-SS');
filename = sprintf('polar_code_results_%s.png', timestamp);
saveas(gcf, filename);
fprintf('结果已保存为: %s\n', filename);
% 显示详细结果
fprintf('\n性能总结:\n');
fprintf('Eb/N0(dB) BER FER\n');
fprintf('-----------------------------------\n');
for i = 1:length(params.EbN0_dB)
fprintf(' %.1f %.2e %.2e\n', ...
params.EbN0_dB(i), BER(i), FER(i));
end
end
10. 额外的解码器实现(bp_decode.m)
matlab
function [decoded_bits, info_bits] = bp_decode(llr, polar_code, params)
% BP(置信传播)解码
% 输入:llr - 对数似然比
% polar_code - 极化码结构
% params - 参数
% 输出:解码结果
N = polar_code.N;
n = polar_code.n;
max_iter = params.max_iter_bp;
% 初始化消息
R = zeros(N, n+1); % 右向消息
L = zeros(N, n+1); % 左向消息
% 设置信道LLR
R(:, n+1) = llr;
% 设置先验信息
for i = 1:N
if ismember(i, polar_code.frozen_pos)
L(i, 1) = 100; % 冻结比特,强制为0
else
L(i, 1) = 0; % 信息比特,无先验
end
end
% BP迭代
for iter = 1:max_iter
% 右向传递
for layer = n:-1:1
for idx = 1:2^(layer-1)
i = 2*idx-1;
j = 2*idx;
% 更新消息
R(i, layer) = f_function(R(i, layer+1), ...
R(j, layer+1) + L(j, layer));
R(j, layer) = f_function(R(i, layer+1), ...
L(i, layer)) + R(i, layer+1);
end
end
% 左向传递
for layer = 1:n
for idx = 1:2^(layer-1)
i = 2*idx-1;
j = 2*idx;
% 更新消息
L(i, layer+1) = f_function(L(i, layer), ...
R(j, layer+1) + L(j, layer));
L(j, layer+1) = f_function(L(i, layer), ...
R(i, layer+1)) + L(j, layer);
end
end
end
% 硬判决
decoded_bits = zeros(N, 1);
for i = 1:N
total_llr = L(i, 1) + R(i, 1);
decoded_bits(i) = (total_llr < 0);
end
% 提取信息比特
info_bits = decoded_bits(polar_code.info_pos(1:polar_code.K));
end
极化码构造方法比较
| 构造方法 | 适用信道 | 计算复杂度 | 准确性 | 应用场景 |
|---|---|---|---|---|
| Bhattacharyya | BEC | 低 | 精确 | 理论分析 |
| 高斯近似(GA) | AWGN | 中 | 高 | 5G通信 |
| 极化权重(PW) | 通用 | 低 | 中 | 5G标准 |
| 密度进化(DE) | 通用 | 高 | 最高 | 理论研究 |
应用场景
- 5G通信:控制信道编码
- 存储系统:NAND Flash错误纠正
- 深空通信:高可靠性传输
- 物联网:短包通信
- 量子计算:量子纠错码的基础
参数调优建议
| 参数 | 推荐值 | 说明 |
|---|---|---|
| 码长N | 256-8192 | 越长性能越好,但复杂度增加 |
| 列表大小L | 8-32 | SCL解码,L越大性能越好 |
| CRC长度 | 16-24 | 提高SCL解码的早期终止能力 |
| 最大迭代次数 | 10-50 | BP解码,迭代越多性能越好 |