├── PolarCodeBPdecoder ├── BP_Decoder_LLR.m ├── Decoding_Index │ ├── get_llr_layer.m │ └── index_Matrix.m ├── GA │ ├── Capacity_Binary_AWGN.m │ ├── GA.m │ ├── accurate_phi.m │ ├── derivative_phi.m │ ├── get_PCi_vector.m │ ├── get_optimized_parameters.m │ ├── get_subchannel_capacity.m │ ├── main.m │ ├── phi.m │ └── phi_inverse.m ├── Simulation.m ├── bler.m ├── get_bit_layer.m ├── main.m └── polar_encoder.m ├── PolarConventionalCASCL ├── CASCL_decoder.m ├── GA │ ├── Capacity_Binary_AWGN.m │ ├── GA.m │ ├── accurate_phi.m │ ├── derivative_phi.m │ ├── get_PCi_vector.m │ ├── get_optimized_parameters.m │ ├── get_subchannel_capacity.m │ ├── main.m │ ├── phi.m │ └── phi_inverse.m ├── HowToConstructPolarCode │ ├── DegradingConstruction │ │ ├── Clambda.m │ │ ├── LR_sort.m │ │ ├── bit_channel_degrading_procedure.m │ │ ├── capacity.m │ │ ├── dClambdadx.m │ │ ├── degrading_merge.m │ │ ├── erasure_symbol_merge.m │ │ ├── get_AWGN_capacity.m │ │ ├── get_AWGN_transition_probability.m │ │ ├── get_BMS_capacity.m │ │ ├── get_Clambda_zero_points.m │ │ ├── get_W_down.m │ │ ├── get_W_up.m │ │ ├── get_y_interval.m │ │ ├── main.m │ │ └── transform_AWGN_to_DMC.m │ └── UpgradingConstruction │ │ ├── Clambda.m │ │ ├── LR_sort.m │ │ ├── bit_channel_upgrading_procedure.m │ │ ├── dClambdadx.m │ │ ├── delta_capacity_basic.m │ │ ├── delta_capacity_lemma11.m │ │ ├── delta_capacity_lemma9.m │ │ ├── erasure_symbol_merge.m │ │ ├── get_AWGN_capacity.m │ │ ├── get_AWGN_transition_probability.m │ │ ├── get_BMS_capacity.m │ │ ├── get_Clambda_zero_points.m │ │ ├── get_W_down.m │ │ ├── get_W_up.m │ │ ├── get_y_interval.m │ │ ├── main.m │ │ ├── upgrading_merge.m │ │ └── upgrading_transform_AWGN_to_DMC.m ├── NodeProcess │ ├── Advanced_SC_decoder.m │ ├── REP.m │ ├── SPC.m │ ├── get_node_structure.m │ ├── node_identifier.m │ ├── node_identifier_large_node.m │ ├── node_identifier_no_12345.m │ ├── node_identifier_no_45.m │ ├── typeI.m │ ├── typeII.m │ ├── typeIII.m │ ├── typeIV.m │ └── typeV.m ├── PolarizaedChannelsPartialOrder │ ├── beta_expansion_polar_code_construction.m │ └── partial_order_polarized_channels.m ├── SC_decoder.m ├── crc_generator_matrix.m ├── get_BEC_IWi.m ├── get_bit_layer.m ├── get_crc_objective.m ├── get_llr_layer.m ├── main.m ├── polar_encoder.m └── simulation.m ├── PolarFastSCL ├── BECconstruction │ └── get_BEC_IWi.m ├── FastSCL_decoder.m ├── GA │ ├── Analysis of Sum-Product Decoding of Low-Density.pdf │ ├── Capacity_Binary_AWGN.m │ ├── GA.m │ ├── accurate_phi.m │ ├── derivative_phi.m │ ├── get_PCi_vector.m │ ├── get_optimized_parameters.m │ ├── get_subchannel_capacity.m │ ├── main.m │ ├── phi.m │ └── phi_inverse.m ├── HowToConstructPolarCode │ ├── DegradingConstruction │ │ ├── Clambda.m │ │ ├── LR_sort.m │ │ ├── bit_channel_degrading_procedure.m │ │ ├── capacity.m │ │ ├── dClambdadx.m │ │ ├── degrading_merge.m │ │ ├── erasure_symbol_merge.m │ │ ├── get_AWGN_capacity.m │ │ ├── get_AWGN_transition_probability.m │ │ ├── get_BMS_capacity.m │ │ ├── get_Clambda_zero_points.m │ │ ├── get_W_down.m │ │ ├── get_W_up.m │ │ ├── get_y_interval.m │ │ ├── main.m │ │ └── transform_AWGN_to_DMC.m │ ├── How to Construct Polar Codes.pdf │ └── UpgradingConstruction │ │ ├── Clambda.m │ │ ├── LR_sort.m │ │ ├── bit_channel_upgrading_procedure.m │ │ ├── dClambdadx.m │ │ ├── delta_capacity_basic.m │ │ ├── delta_capacity_lemma11.m │ │ ├── delta_capacity_lemma9.m │ │ ├── erasure_symbol_merge.m │ │ ├── get_AWGN_capacity.m │ │ ├── get_AWGN_transition_probability.m │ │ ├── get_BMS_capacity.m │ │ ├── get_Clambda_zero_points.m │ │ ├── get_W_down.m │ │ ├── get_W_up.m │ │ ├── get_y_interval.m │ │ ├── main.m │ │ ├── upgrading_merge.m │ │ └── upgrading_transform_AWGN_to_DMC.m ├── MonteCarloCodeConstruction │ ├── Polar Coding for Bit-Interleaved Coded Modulation .pdf │ ├── get_bit_layer.m │ ├── get_llr_layer.m │ ├── main.m │ ├── mc_typeI_SC_decoder.m │ └── my_polar_encode.m ├── NodeDecoding │ ├── Fast List Decoders for Polar Codes.pdf │ ├── Rate1.m │ ├── Rep.m │ └── SPC.m ├── NodeProcess │ ├── Fast Successive-Cancellation Decoding of Polar Codes Identification and Decoding of New Nodes .pdf │ ├── FastSCdecoder.m │ ├── get_node_structure.m │ ├── get_psi_for_advanced_sc_decoder.m │ └── node_identifier.m ├── PolarizaedChannelsPartialOrder │ ├── EPW.m │ ├── HPW.m │ ├── PW.m │ ├── Polarization Weight Family Methods fo.pdf │ ├── Recursive Construction of Polar Codes.pdf │ └── partial_order_polarized_channels.m ├── SC_decoder.m ├── SystematicPolarEncoders │ ├── Flexible and Low-Complexity Encoding and Decoding of Systematic Polar Codes.pdf │ ├── SC_systematic_encoder.m │ ├── Systematic Polar Coding.pdf │ ├── arikan_recursive_systematic_polar_encoder.m │ ├── arikan_sc_systematic_polar_encoder.m │ └── sarkis_systematic_polar_encoder.m ├── bler.m ├── crc_generator_matrix.m ├── get_GN.m ├── get_bit_layer.m ├── get_crc_objective.m ├── get_llr_layer.m ├── main.m ├── polar_encoder.m └── simulation.m ├── README.md └── elements_of_polar_codes.pdf /PolarCodeBPdecoder/BP_Decoder_LLR.m: -------------------------------------------------------------------------------- 1 | function [info_esti, denoised_llr, error, iter_this_time] = BP_Decoder_LLR(info_bits, frozen_bits, llr, max_iter, M_right_up, M_right_down) 2 | N = length(frozen_bits); 3 | n = log2(N); 4 | R = zeros(N, n + 1); 5 | L = zeros(N, n + 1); 6 | internal_bits = zeros(N, n + 1); 7 | %Initialize R 8 | for i = 1:N 9 | if frozen_bits(i) == 1 10 | R(i, 1) = realmax; 11 | end 12 | end 13 | %Initialize L 14 | L(:, n + 1) = llr; 15 | %Iter 16 | for iter = 1 : max_iter 17 | %Left Prop 18 | for j = n : -1 : 1 %for each layer 19 | for i = 1 : N/2 %for each 2*2 module in each layer 20 | up_index = M_right_up(i, j); 21 | down_index = M_right_down(i, j); 22 | R_up_j = R(up_index, j); 23 | R_down_j = R(down_index, j); 24 | L_up_j_plus_1 = L(up_index, j + 1); 25 | L_down_j_plus_1 = L(down_index, j + 1); 26 | L(up_index, j) = 0.9375 * sign(R_down_j + L_down_j_plus_1) * sign(L_up_j_plus_1) * min(abs(R_down_j + L_down_j_plus_1), abs(L_up_j_plus_1)); 27 | L(down_index, j) = 0.9375 * sign(R_up_j) * sign(L_up_j_plus_1) * min(abs(R_up_j), abs(L_up_j_plus_1)) + L_down_j_plus_1; 28 | end 29 | end 30 | u_esti = (L(:, 1) + R(:, 1)) < 0; 31 | internal_bits(:, 1) = u_esti; 32 | %Right Prop 33 | for j = 1 : n 34 | for i = 1 : N/2 35 | up_index = M_right_up(i, j); 36 | down_index = M_right_down(i, j); 37 | R_up_j = R(up_index, j); 38 | R_down_j = R(down_index, j); 39 | L_up_j_plus_1 = L(up_index, j + 1); 40 | L_down_j_plus_1 = L(down_index, j + 1); 41 | R(up_index, j + 1) = 0.9375 * sign(R_down_j + L_down_j_plus_1) * sign(R_up_j) * min(abs(R_down_j + L_down_j_plus_1), abs(R_up_j)); 42 | R(down_index, j + 1) = 0.9375 * sign(R_up_j) * sign(L_up_j_plus_1) * min(abs(R_up_j), abs(L_up_j_plus_1)) + R_down_j; 43 | internal_bits(up_index, j + 1) = mod(internal_bits(up_index, j) + internal_bits(down_index, j), 2); 44 | internal_bits(down_index, j + 1) = internal_bits(down_index, j); 45 | end 46 | end 47 | x_esti = (L(:, n + 1) + R(:, n + 1)) < 0; 48 | x_enc = internal_bits(:, n + 1); 49 | if all(x_esti == x_enc) 50 | info_esti = u_esti(info_bits); 51 | denoised_llr = L(:, n + 1) + R(:, n + 1); 52 | error = 0; 53 | iter_this_time = iter; 54 | break; 55 | else 56 | if iter == max_iter 57 | info_esti = u_esti(info_bits); 58 | denoised_llr = L(:, n + 1) + R(:, n + 1); 59 | error = 1; 60 | iter_this_time = iter; 61 | end 62 | end 63 | end 64 | end -------------------------------------------------------------------------------- /PolarCodeBPdecoder/Decoding_Index/get_llr_layer.m: -------------------------------------------------------------------------------- 1 | function layer_vec = get_llr_layer(N) 2 | layer_vec = zeros(N , 1); 3 | for phi = 1 : N - 1 4 | psi = phi; 5 | layer = 0; 6 | while(mod(psi, 2) == 0) 7 | psi = floor(psi/2); 8 | layer = layer + 1; 9 | end 10 | layer_vec(phi + 1) = layer; 11 | end 12 | end -------------------------------------------------------------------------------- /PolarCodeBPdecoder/Decoding_Index/index_Matrix.m: -------------------------------------------------------------------------------- 1 | function [M_right_up, M_right_down] = index_Matrix(N) 2 | n = log2(N); 3 | M_right_up = zeros(N/2, n); 4 | M_right_down = zeros(N/2, n); 5 | for i = 1 : n 6 | for j = 1 : 2^(i - 1) 7 | M_right_up((j - 1) * N/2^i + 1 : j * N/2^i, i) = (1 : N/2^i)' + (j - 1) * N/2^(i - 1); 8 | end 9 | M_right_down(:, i) = M_right_up(:, i) + 2^(n - i); 10 | end 11 | M_right_up = M_right_up(:, end : -1 : 1); 12 | M_right_down = M_right_down(:, end : -1 : 1); 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /PolarCodeBPdecoder/GA/Capacity_Binary_AWGN.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarCodeBPdecoder/GA/Capacity_Binary_AWGN.m -------------------------------------------------------------------------------- /PolarCodeBPdecoder/GA/GA.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarCodeBPdecoder/GA/GA.m -------------------------------------------------------------------------------- /PolarCodeBPdecoder/GA/accurate_phi.m: -------------------------------------------------------------------------------- 1 | function z = accurate_phi(x) 2 | f = @(u, x) (exp(u) - 1)./(exp(u) + 1) .* exp(-(u - x).^2./4./x); 3 | z = integral(@(u) f(u, x), -100, 100); 4 | z = 1 - 1/sqrt(4 * pi * x) * z; 5 | end -------------------------------------------------------------------------------- /PolarCodeBPdecoder/GA/derivative_phi.m: -------------------------------------------------------------------------------- 1 | function dx = derivative_phi(x) 2 | if (x >= 0)&&(x <= 10) 3 | dx = -0.4527*0.86*x^(-0.14)*phi(x); 4 | else 5 | dx = exp(-x/4)*sqrt(pi/x)*(-1/2/x*(1 - 10/7/x) - 1/4*(1 - 10/7/x) + 10/7/x/x); 6 | end 7 | end -------------------------------------------------------------------------------- /PolarCodeBPdecoder/GA/get_PCi_vector.m: -------------------------------------------------------------------------------- 1 | function PCi = get_PCi_vector(ELNi) 2 | PCi = zeros(length(ELNi), 1); 3 | for i = 1:length(ELNi) 4 | PCi(i) = 0.5*erfc(0.5*sqrt(ELNi(i))); 5 | end 6 | end -------------------------------------------------------------------------------- /PolarCodeBPdecoder/GA/get_optimized_parameters.m: -------------------------------------------------------------------------------- 1 | xdata = 1:10; 2 | ydata = zeros(1, length(xdata)); 3 | for i = 1 : length(xdata) 4 | ydata(i) = accurate_phi(xdata(i)); 5 | end 6 | % p = lsqcurvefit(@(p, xdata) exp(p(1) .* xdata.^p(2) + p(3)), [2 7], xdata, ydata); 7 | fun = @(p) exp(p(1) .* xdata .^ p(2) + p(3)) - ydata; 8 | p0 = [1 0.5 1]; 9 | options = optimoptions('lsqnonlin', 'Display', 'iter'); 10 | p = lsqnonlin(fun, p0, [], [], options); 11 | pl = plot(xdata, [ydata; exp(p(1) .* xdata .^ p(2) + p(3))]); 12 | pl(1).Marker = 'd'; 13 | p1(2).Marker = '^'; -------------------------------------------------------------------------------- /PolarCodeBPdecoder/GA/get_subchannel_capacity.m: -------------------------------------------------------------------------------- 1 | function cap_vec = get_subchannel_capacity(u) 2 | cap_vec = zeros(1, length(u)); 3 | for i = 1:length(u) 4 | cap_vec(i) = Capacity_Binary_AWGN(u(i), sqrt(2*u(i))); 5 | end 6 | end -------------------------------------------------------------------------------- /PolarCodeBPdecoder/GA/main.m: -------------------------------------------------------------------------------- 1 | %rewrite Gauss Approximation for PolarCode construction 2 | %more accurate and easier to read and much quicker 3 | %GA for BPSK-AWGN BPSK = [1 -1] 4 | %such that y = bpsk + noise, llr = 2y/sigma^2 subjects to N(2/sigma^2, 4/sigma^2) when zero 5 | %code word is transmitted 6 | EbN0 = 1; 7 | R = 0.5; 8 | sigma = sqrt(1/2/R)*10^(-EbN0/20); 9 | n = 10; 10 | N = 2^n; 11 | tic 12 | u = GA(sigma, N);%u is the mean value vector for subchannels after the wohle polarization process 13 | toc 14 | % cap_vec = get_subchannel_capacity(u); 15 | % ber_vec = get_PCi_vector(u); 16 | % u 17 | % cap_vec 18 | % ber_vec 19 | -------------------------------------------------------------------------------- /PolarCodeBPdecoder/GA/phi.m: -------------------------------------------------------------------------------- 1 | function y = phi(x) 2 | if (x >= 0)&&(x <= 10) 3 | y = exp(-0.4527*x^0.859 + 0.0218); 4 | else 5 | y = sqrt(pi/x) * exp(-x/4) * (1 - 10/7/x); 6 | end -------------------------------------------------------------------------------- /PolarCodeBPdecoder/GA/phi_inverse.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarCodeBPdecoder/GA/phi_inverse.m -------------------------------------------------------------------------------- /PolarCodeBPdecoder/Simulation.m: -------------------------------------------------------------------------------- 1 | function [bler, ber] = Simulation(max_iter, max_err, max_runs, resolution, ebno_vec, N, K) 2 | R = K/N; 3 | n = log2(N); 4 | num_block_err_bp = zeros(length(ebno_vec), 1); 5 | num_bit_err_bp = zeros(length(ebno_vec), 1); 6 | num_runs = zeros(length(ebno_vec), 1); 7 | 8 | %Indices for enc/decoding 9 | [M_up, M_down] = index_Matrix(N); 10 | lambda_offset = 2.^(0 : n); 11 | llr_layer_vec = get_llr_layer(N); 12 | 13 | %code construction 14 | design_snr = 2.5; 15 | sigma_cc = 1/sqrt(2 * R) * 10^(-design_snr/20); 16 | [channels, ~] = GA(sigma_cc, N); 17 | [~, channel_ordered] = sort(channels, 'descend'); 18 | info_bits = sort(channel_ordered(1 : K), 'ascend'); 19 | frozen_bits = ones(N , 1); 20 | frozen_bits(info_bits) = 0; 21 | 22 | tic 23 | for i_run = 1 : max_runs 24 | if mod(i_run, ceil(max_runs/resolution)) == 1 25 | disp(['Sim iteration running = ', num2str(i_run)]); 26 | disp(['N = ' num2str(N) ' K = ' num2str(K) ' GA construction SNR = ' num2str(design_snr) 'dB' ' Max Iter Number = ' num2str(max_iter)]) 27 | disp('BP BLER') 28 | disp(num2str([ebno_vec' num_block_err_bp./num_runs])); 29 | disp(' ') 30 | end 31 | u = zeros(N, 1); 32 | info = rand(K, 1) < 0.5 ; 33 | u(info_bits) = info; 34 | x = polar_encoder(u, lambda_offset, llr_layer_vec); 35 | bpsk = 1 - 2 * x; 36 | noise = randn(N, 1); 37 | for i_ebno = 1 : length(ebno_vec) 38 | if num_block_err_bp(i_ebno) > max_err 39 | continue; 40 | end 41 | num_runs(i_ebno) = num_runs(i_ebno) + 1; 42 | sigma = 1 / sqrt(2 * R) * 10^(-ebno_vec(i_ebno)/20); 43 | y = bpsk + sigma * noise; 44 | llr = 2/sigma^2 * y; 45 | [info_esti_bp, ~, ~, ~] = BP_Decoder_LLR(info_bits, frozen_bits, llr, max_iter, M_up, M_down); 46 | if any(info_esti_bp ~= info) 47 | num_block_err_bp(i_ebno) = num_block_err_bp(i_ebno) + 1; 48 | num_bit_err_bp(i_ebno) = num_bit_err_bp(i_ebno) + sum(info ~= info_esti_bp); 49 | end 50 | 51 | end 52 | end 53 | toc 54 | bler = num_block_err_bp./num_runs; 55 | ber = num_bit_err_bp./num_runs/K; 56 | end 57 | -------------------------------------------------------------------------------- /PolarCodeBPdecoder/bler.m: -------------------------------------------------------------------------------- 1 | % Sim iteration running = 41001 2 | % N = 1024 K = 512 GA construction SNR = 2.5dB Max Iter Number = 50 3 | % BP BLER 4 | % 1 0.70139 5 | % 1.5 0.26234 6 | % 2 0.051426 7 | % 2.5 0.010047 8 | % 3 0.0020244 9 | % 3.5 0.00034146 10 | % 11 | % Sim iteration running = 93001 12 | % N = 2048 K = 1024 GA construction SNR = 2.5dB Max Iter Number = 50 13 | % BP BLER 14 | % 1 0.82114 15 | % 1.5 0.2012 16 | % 2 0.019847 17 | % 2.5 0.0020258 18 | % 3 0.00036559 19 | % 3.5 6.4516e-05 20 | % 21 | % Sim iteration running = 37001 22 | % N = 256 K = 128 GA construction SNR = 2.5dB Max Iter Number = 50 23 | % BP BLER 24 | % 1 0.5 25 | % 1.5 0.24877 26 | % 2 0.092491 27 | % 2.5 0.032166 28 | % 3 0.010046 29 | % 3.5 0.0023784 30 | % 31 | % Sim iteration running = 46001 32 | % N = 512 K = 256 GA construction SNR = 2.5dB Max Iter Number = 50 33 | % BP BLER 34 | % 1 0.55495 35 | % 1.5 0.26649 36 | % 2 0.084307 37 | % 2.5 0.018868 38 | % 3 0.004632 39 | % 3.5 0.00071739 40 | 41 | p256 = [ 0.5 42 | 0.24877 43 | 0.092491 44 | 0.032166 45 | 0.010046 46 | 0.0023784]; 47 | 48 | p512 = [ 0.55495 49 | 0.26649 50 | 0.084307 51 | 0.018868 52 | 0.004632 53 | 0.00071739]; 54 | 55 | p1024 = [ 0.70139 56 | 0.26234 57 | 0.051426 58 | 0.010047 59 | 0.0020244 60 | 0.00034146]; 61 | 62 | p2048 = [ 0.82114 63 | 0.2012 64 | 0.019847 65 | 0.0020258 66 | 0.00036559 67 | 6.4516e-05]; 68 | snr = 1 : 0.5 : 3.5; 69 | p = semilogy(snr, [p256 p512 p1024 p2048]); 70 | grid on 71 | p(1).Marker = 'o'; 72 | p(2).Marker = 'd'; 73 | p(3).Marker = 'p'; 74 | p(4).Marker = 'v'; 75 | 76 | p(1).Color = 'r'; 77 | p(2).Color = 'g'; 78 | p(3).Color = 'm'; 79 | 80 | for k = 1 : 4 81 | p(k).MarkerSize = 8; 82 | p(k).LineWidth = 1.1; 83 | end 84 | l = legend('N = 256',... 85 | 'N = 512',... 86 | 'N = 1024',... 87 | 'N = 2048'); 88 | 89 | l.Location = 'SouthWest'; 90 | 91 | xlabel('E_b/N_0 (dB)') 92 | ylabel('BLER') 93 | set(gca, 'fontname', 'times new roman', 'fontsize', 14) 94 | 95 | 96 | -------------------------------------------------------------------------------- /PolarCodeBPdecoder/get_bit_layer.m: -------------------------------------------------------------------------------- 1 | function layer_vec = get_bit_layer(N) 2 | layer_vec = zeros(N, 1); 3 | for phi = 0 : N - 1 4 | psi = floor(phi/2); 5 | layer = 0; 6 | while(mod(psi, 2) == 1) 7 | psi = floor(psi/2); 8 | layer = layer + 1; 9 | end 10 | layer_vec(phi + 1) = layer; 11 | end 12 | end -------------------------------------------------------------------------------- /PolarCodeBPdecoder/main.m: -------------------------------------------------------------------------------- 1 | clear; 2 | addpath('Decoding_Index/') 3 | addpath('GA/') 4 | n = 9; 5 | N = 2^n; 6 | K = 2^(n - 1); 7 | max_iter = 50; 8 | max_err = 100; 9 | max_runs = 1e8; 10 | resolution = 1e5; 11 | ebno_vec = 1 : 0.5 : 3.5; 12 | [bler, ber] = Simulation(max_iter, max_err, max_runs, resolution, ebno_vec, N, K); 13 | 14 | 15 | -------------------------------------------------------------------------------- /PolarCodeBPdecoder/polar_encoder.m: -------------------------------------------------------------------------------- 1 | function x = polar_encoder(u, lambda_offset, llr_layer_vec) 2 | %encoding: x = u * Fn. 3 | N = length(u); 4 | m = log2(N); 5 | C = zeros(N - 1, 1); 6 | x = zeros(N, 1); 7 | for phi = 0 : N - 1 8 | switch phi 9 | case 0 10 | index_1 = lambda_offset(m); 11 | for beta = 1 : index_1 12 | C(beta + index_1 - 1) = u(beta) + u(beta + index_1); 13 | end 14 | for i_layer = m - 2 : -1 : 0 15 | index_1 = lambda_offset(i_layer + 1); 16 | index_2 = lambda_offset(i_layer + 2); 17 | for beta = index_1 : index_2 - 1 18 | C(beta) = C(beta + index_1) + C(beta + index_2); 19 | end 20 | end 21 | case N/2 22 | index_1 = lambda_offset(m); 23 | for beta = 1 : index_1 24 | C(beta + index_1 - 1) = u(beta + index_1); 25 | end 26 | for i_layer = m - 2 : -1 : 0 27 | index_1 = lambda_offset(i_layer + 1); 28 | index_2 = lambda_offset(i_layer + 2); 29 | for beta = index_1 : index_2 - 1 30 | C(beta) = C(beta + index_1) + C(beta + index_2); 31 | end 32 | end 33 | otherwise 34 | layer = llr_layer_vec(phi + 1); 35 | index_1 = lambda_offset(layer + 1); 36 | index_2 = lambda_offset(layer + 2); 37 | for beta = index_1 : index_2 - 1 38 | C(beta) = C(beta + index_2); 39 | end 40 | for i_layer = layer - 1: -1 : 0 41 | index_1 = lambda_offset(i_layer + 1); 42 | index_2 = lambda_offset(i_layer + 2); 43 | for beta = index_1 : index_2 - 1 44 | C(beta) = C(beta + index_1) + C(beta + index_2); 45 | end 46 | end 47 | end 48 | x(phi + 1) = C(1); 49 | end 50 | x = mod(x, 2); 51 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/CASCL_decoder.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarConventionalCASCL/CASCL_decoder.m -------------------------------------------------------------------------------- /PolarConventionalCASCL/GA/Capacity_Binary_AWGN.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarConventionalCASCL/GA/Capacity_Binary_AWGN.m -------------------------------------------------------------------------------- /PolarConventionalCASCL/GA/GA.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarConventionalCASCL/GA/GA.m -------------------------------------------------------------------------------- /PolarConventionalCASCL/GA/accurate_phi.m: -------------------------------------------------------------------------------- 1 | function z = accurate_phi(x) 2 | f = @(u, x) (exp(u) - 1)./(exp(u) + 1) .* exp(-(u - x).^2./4./x); 3 | z = integral(@(u) f(u, x), -100, 100); 4 | z = 1 - 1/sqrt(4 * pi * x) * z; 5 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/GA/derivative_phi.m: -------------------------------------------------------------------------------- 1 | function dx = derivative_phi(x) 2 | if (x >= 0)&&(x <= 10) 3 | dx = -0.4527*0.86*x^(-0.14)*phi(x); 4 | else 5 | dx = exp(-x/4)*sqrt(pi/x)*(-1/2/x*(1 - 10/7/x) - 1/4*(1 - 10/7/x) + 10/7/x/x); 6 | end 7 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/GA/get_PCi_vector.m: -------------------------------------------------------------------------------- 1 | function PCi = get_PCi_vector(ELNi) 2 | PCi = zeros(length(ELNi), 1); 3 | for i = 1:length(ELNi) 4 | PCi(i) = 0.5*erfc(0.5*sqrt(ELNi(i))); 5 | end 6 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/GA/get_optimized_parameters.m: -------------------------------------------------------------------------------- 1 | xdata = 1:10; 2 | ydata = zeros(1, length(xdata)); 3 | for i = 1 : length(xdata) 4 | ydata(i) = accurate_phi(xdata(i)); 5 | end 6 | % p = lsqcurvefit(@(p, xdata) exp(p(1) .* xdata.^p(2) + p(3)), [2 7], xdata, ydata); 7 | fun = @(p) exp(p(1) .* xdata .^ p(2) + p(3)) - ydata; 8 | p0 = [1 0.5 1]; 9 | options = optimoptions('lsqnonlin', 'Display', 'iter'); 10 | p = lsqnonlin(fun, p0, [], [], options); 11 | pl = plot(xdata, [ydata; exp(p(1) .* xdata .^ p(2) + p(3))]); 12 | pl(1).Marker = 'd'; 13 | p1(2).Marker = '^'; -------------------------------------------------------------------------------- /PolarConventionalCASCL/GA/get_subchannel_capacity.m: -------------------------------------------------------------------------------- 1 | function cap_vec = get_subchannel_capacity(u) 2 | cap_vec = zeros(1, length(u)); 3 | for i = 1:length(u) 4 | cap_vec(i) = Capacity_Binary_AWGN(u(i), sqrt(2*u(i))); 5 | end 6 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/GA/main.m: -------------------------------------------------------------------------------- 1 | %rewrite Gauss Approximation for PolarCode construction 2 | %more accurate and easier to read and much quicker 3 | %GA for BPSK-AWGN BPSK = [1 -1] 4 | %such that y = bpsk + noise, llr = 2y/sigma^2 subjects to N(2/sigma^2, 4/sigma^2) when zero 5 | %code word is transmitted 6 | EbN0 = 1; 7 | R = 0.5; 8 | sigma = sqrt(1/2/R)*10^(-EbN0/20); 9 | n = 10; 10 | N = 2^n; 11 | tic 12 | u = GA(sigma, N);%u is the mean value vector for subchannels after the wohle polarization process 13 | toc 14 | % cap_vec = get_subchannel_capacity(u); 15 | % ber_vec = get_PCi_vector(u); 16 | % u 17 | % cap_vec 18 | % ber_vec 19 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/GA/phi.m: -------------------------------------------------------------------------------- 1 | function y = phi(x) 2 | if (x >= 0)&&(x <= 10) 3 | y = exp(-0.4527*x^0.859 + 0.0218); 4 | else 5 | y = sqrt(pi/x) * exp(-x/4) * (1 - 10/7/x); 6 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/GA/phi_inverse.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarConventionalCASCL/GA/phi_inverse.m -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/Clambda.m: -------------------------------------------------------------------------------- 1 | function z = Clambda(lambda) 2 | z = 1 - lambda./(1 + lambda).*log2(1 + 1./lambda) - 1./(1 + lambda).*log2(1 + lambda); 3 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/LR_sort.m: -------------------------------------------------------------------------------- 1 | function V = LR_sort(W) 2 | N = size(W, 2); 3 | LLR = zeros(1, N); 4 | for i = 1 : N 5 | if (W(1, i) ~= 0) && (W(2, i) ~= 0) 6 | LLR(i) = log(W(1, i)) - log(W(2, i)); 7 | else 8 | if (W(1, i) == 0) && (W(2, i) ~= 0) 9 | LLR(i) = -inf; 10 | else 11 | if (W(1, i) ~= 0) && (W(2, i) == 0) 12 | LLR(i) = inf; 13 | end 14 | end 15 | end 16 | end 17 | [~, ordered] = sort(LLR, 'descend'); 18 | V = W(:, ordered); 19 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/bit_channel_degrading_procedure.m: -------------------------------------------------------------------------------- 1 | function Pe = bit_channel_degrading_procedure(W, z, miu) 2 | N = length(z); 3 | if N == 1 4 | Pe = 0.5 * sum(min(W)); 5 | disp(['Bit index = ' num2str(z) ' Error rate = ' num2str(Pe)]) 6 | else 7 | W_up = get_W_up(W); 8 | W_up = LR_sort(W_up); 9 | W_up_after_erasure_symbol_merge = erasure_symbol_merge(W_up); 10 | W_up_after_merge = degrading_merge(W_up_after_erasure_symbol_merge, miu); 11 | Pe1 = bit_channel_degrading_procedure(W_up_after_merge, z(1 : N/2), miu); 12 | 13 | W_down = get_W_down(W); 14 | W_down = LR_sort(W_down); 15 | W_down_after_erasure_symbol_merge = erasure_symbol_merge(W_down); 16 | W_down_after_merge = degrading_merge(W_down_after_erasure_symbol_merge, miu); 17 | Pe2 = bit_channel_degrading_procedure(W_down_after_merge, z(N/2 + 1 : end), miu); 18 | 19 | Pe = [Pe1 Pe2]; 20 | end 21 | end 22 | 23 | % function Pe = bit_channel_degrading_procedure(W, z, miu) 24 | % N = length(z); 25 | % m = round(log2(N)); 26 | % Pe = zeros(N, 1); 27 | % for k = 0 : N - 1 28 | % char_bin_expansion = dec2bin(k, m); 29 | % W_tmp = W; 30 | % for i_level = 1 : m 31 | % if char_bin_expansion(i_level) == '0' 32 | % W_up = get_W_up(W_tmp); 33 | % W_up = LR_sort(W_up); 34 | % W_up_after_erasure_symbol_merge = erasure_symbol_merge(W_up); 35 | % W_tmp = degrading_merge(W_up_after_erasure_symbol_merge, miu); 36 | % else 37 | % W_down = get_W_down(W_tmp); 38 | % W_down = LR_sort(W_down); 39 | % W_down_after_erasure_symbol_merge = erasure_symbol_merge(W_down); 40 | % W_tmp = degrading_merge(W_down_after_erasure_symbol_merge, miu); 41 | % 42 | % end 43 | % end 44 | % Pe(k + 1) = 0.5 * sum(min(W_tmp)); 45 | % disp(['Bit index = ' num2str(k + 1) ' Error rate = ' num2str(Pe(k + 1))]) 46 | % end 47 | % end 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/capacity.m: -------------------------------------------------------------------------------- 1 | function z = capacity(x, y) 2 | 3 | if (x ~= 0) && (y ~= 0) 4 | z = -(x + y) * log2((x + y)/2) + x * log2(x) + y * log2(y); 5 | else 6 | if (x == 0) && (y ~= 0) 7 | z = y; 8 | else 9 | if (y == 0) && (x ~= 0) 10 | z = x; 11 | else 12 | z = 0; 13 | end 14 | end 15 | end 16 | 17 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/dClambdadx.m: -------------------------------------------------------------------------------- 1 | function z = dClambdadx(lambda) 2 | z = log2(lambda)./(1 + lambda).^2; 3 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/degrading_merge.m: -------------------------------------------------------------------------------- 1 | function W = degrading_merge(W, miu) 2 | N = size(W, 2);%N is not a constant if merge is needed 3 | if N <= miu 4 | return 5 | else 6 | % sum_before_merge = 0; 7 | % for i = 1 : N/2 8 | % sum_before_merge = sum_before_merge + norm(W(:, i) - W(end:-1:1, N - i + 1)); 9 | % end 10 | % sum_before_merge 11 | % if sum_before_merge > 0.01 12 | % sum(W(1,:)); 13 | % sum(W(2, :)) 14 | % end 15 | 16 | 17 | % if sum_before_merge ~= 0 18 | % sum_before_merge 19 | % W 20 | % sum(W(1, :)) 21 | % sum(W(2, :)) 22 | % LLR = log(W(1,:)) - log(W(2,:)) 23 | % [~, orderd] = sort(LLR, 'descend') 24 | % end 25 | while(N > miu) 26 | min_deltaI = realmax; 27 | min_index = 0; 28 | for i = 1 : N/2 - 1 29 | a1 = W(1, i); 30 | b1 = W(2, i); 31 | a2 = W(1,i + 1); 32 | b2 = W(2, i + 1); 33 | deltaI = capacity(a1, b1) + capacity(a2, b2) - capacity(a1 + a2, b1 + b2); 34 | 35 | if deltaI < min_deltaI %find minimum delta I 36 | min_deltaI = deltaI; 37 | min_index = i; 38 | end 39 | end 40 | 41 | % indicator = 0; 42 | % 43 | % for k = 1 : N/2 44 | % if sum(W(:, k)) < 1e-20 45 | % indicator = 1; 46 | % W(:, k) = []; 47 | % W(:, N - k) = []; 48 | % N = size(W, 2); 49 | % break; 50 | % end 51 | % end 52 | % 53 | % if indicator == 1 54 | % continue 55 | % end 56 | 57 | W(1, min_index) = W(1, min_index) + W(1, min_index + 1); 58 | W(2, min_index) = W(2, min_index) + W(2, min_index + 1); 59 | W(1, N - min_index + 1) = W(1, N - min_index + 1) + W(1, N - min_index); 60 | W(2, N - min_index + 1) = W(2, N - min_index + 1) + W(2, N - min_index); 61 | W(:, min_index + 1) = []; 62 | W(:, N - min_index - 1) = []; 63 | N = size(W, 2); 64 | end 65 | % sum_after_merge = 0; 66 | % for i = 1 : N/2 67 | % sum_after_merge = sum_after_merge + norm(W(:, i) - W(end:-1:1, N - i + 1)); 68 | % end 69 | % sum_after_merge 70 | end 71 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/erasure_symbol_merge.m: -------------------------------------------------------------------------------- 1 | function V = erasure_symbol_merge(W) 2 | cnt = 0; 3 | N = size(W, 2); 4 | for i = N/2 : -1 : 1 5 | if W(1, i) == W(2, i) 6 | cnt = cnt + 1; 7 | else 8 | break; 9 | end 10 | end 11 | W_erasure = W(:, N/2 - cnt + 1 : N/2 + cnt); 12 | erasure_probability = sum(W_erasure(1, :)); 13 | middle = erasure_probability/2 * ones(2, 2); 14 | W_left = W(:, 1 : N/2 - cnt); 15 | W_right = W(:, N/2 + cnt + 1 : end); 16 | V = [W_left middle W_right]; 17 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/get_AWGN_capacity.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/get_AWGN_capacity.m -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/get_AWGN_transition_probability.m: -------------------------------------------------------------------------------- 1 | function W = get_AWGN_transition_probability(sigma, v) 2 | alpha = get_Clambda_zero_points(v); 3 | y = get_y_interval(sigma, alpha); 4 | W = transform_AWGN_to_DMC(y, sigma, v); 5 | end 6 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/get_BMS_capacity.m: -------------------------------------------------------------------------------- 1 | function IW = get_BMS_capacity(W) 2 | %This function is employed here to verify the correctness of the program 3 | %that is being writen 4 | HYX = sum(W(1, :).*log2(W(1, :))); 5 | PY = (W(1, :) + W(2, :))/2; 6 | HY = sum(-PY.*log2(PY)); 7 | IW = HY + HYX; 8 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/get_Clambda_zero_points.m: -------------------------------------------------------------------------------- 1 | function alpha = get_Clambda_zero_points(v) 2 | alpha = zeros(v + 1, 1); 3 | alpha(1) = 1; 4 | alpha(v + 1) = realmax; 5 | %above two values are obtained by simple calculations and avoid numerical 6 | %problems 7 | %Newton descend method 8 | epsilon = 1e-6;%tolerance error 9 | for i = 2 : v 10 | beta = (i - 1)/v; 11 | x0 = 0; 12 | x1 = 1.5;%initial point, the zero point of d^2C(lambda)/x^2 13 | while(abs(x0 - x1) > epsilon) 14 | x0 = x1; 15 | x1 = x0 - (Clambda(x0) - beta)/dClambdadx(x0); 16 | end 17 | alpha(i) = x1; 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/get_W_down.m: -------------------------------------------------------------------------------- 1 | function W_down = get_W_down(W) 2 | N = size(W, 2); 3 | W_down = zeros(2, 2 * N^2); 4 | for u2 = 0 : 1 5 | for y1 = 1 : N 6 | for y2 = 1 : N 7 | for u1 = 0 : 1 8 | W_down(u2 + 1, 2 * N * (y1 - 1) + 2 * (y2 - 1) + u1 + 1) = 0.5 * W(mod(u1 + u2, 2) + 1, y1) * W(u2 + 1, y2); 9 | end 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/get_W_up.m: -------------------------------------------------------------------------------- 1 | function W_up = get_W_up(W) 2 | N = size(W, 2); 3 | W_up = zeros(2, N^2); 4 | for u1 = 0 : 1 5 | for y1 = 1 : N 6 | for y2 = 1 : N 7 | W_up(u1 + 1, N * (y1 - 1) + y2) = 0.5 * (W(u1 + 1, y1) * W(1, y2) + W(mod(u1 + 1, 2) + 1, y1) * W(2, y2)); 8 | end 9 | end 10 | end 11 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/get_y_interval.m: -------------------------------------------------------------------------------- 1 | function y = get_y_interval(sigma, alpha) 2 | y = zeros(size(alpha, 1) - 1, 2); 3 | for i = 1 : size(alpha, 1) - 1 4 | y(i, 1) = sigma^2/2*log(alpha(i)); 5 | y(i, 2) = sigma^2/2*log(alpha(i + 1)); 6 | end 7 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/main.m: -------------------------------------------------------------------------------- 1 | clear 2 | snr = 2.5; 3 | R = 1/2; 4 | sigma = 1/sqrt(2 * R) * 10^(-snr/20); 5 | n = 8; 6 | N = 2^n; 7 | miu = 32; 8 | v = miu/2; 9 | W = get_AWGN_transition_probability(sigma, v); 10 | C_AWGN = get_AWGN_capacity(1, sigma); 11 | IW = get_BMS_capacity(W); 12 | disp(['AWGN with sigma = ' num2str(sigma) '. AWGN Capacity = ' num2str(C_AWGN)]); 13 | disp(['Capacity of Degrading cahnnel with respect to above AWGN = ' num2str(IW)]); 14 | disp(['Capacity difference = ' num2str(abs(IW - C_AWGN))]); 15 | Pe = bit_channel_degrading_procedure(W, 1 : N, miu); 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/DegradingConstruction/transform_AWGN_to_DMC.m: -------------------------------------------------------------------------------- 1 | function W = transform_AWGN_to_DMC(y, sigma, v) 2 | W = zeros(2, 2 * v); 3 | for i = 1 : v 4 | y_min = y(i, 1); 5 | y_max = y(i, 2); 6 | p0 = normcdf(y_max, 1, sigma) - normcdf(y_min, 1, sigma); 7 | p1 = normcdf(y_max, -1, sigma) - normcdf(y_min, -1, sigma); 8 | W(1, 2*i - 1) = p0; 9 | W(2, 2*i - 1) = p1; 10 | W(1, 2*i) = p1; 11 | W(2, 2*i) = p0; 12 | end 13 | 14 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/Clambda.m: -------------------------------------------------------------------------------- 1 | function z = Clambda(lambda) 2 | z = 1 - lambda./(1 + lambda).*log2(1 + 1./lambda) - 1./(1 + lambda).*log2(1 + lambda); 3 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/LR_sort.m: -------------------------------------------------------------------------------- 1 | function V = LR_sort(W) 2 | N = size(W, 2); 3 | LLR = zeros(1, N); 4 | for i = 1 : N 5 | if (W(1, i) ~= 0) && (W(2, i) ~= 0) 6 | LLR(i) = log(W(1, i)) - log(W(2, i)); 7 | else 8 | if (W(1, i) == 0) && (W(2, i) ~= 0) 9 | LLR(i) = -inf; 10 | else 11 | if (W(1, i) ~= 0) && (W(2, i) == 0) 12 | LLR(i) = inf; 13 | end 14 | end 15 | end 16 | end 17 | [~, ordered] = sort(LLR, 'descend'); 18 | V = W(:, ordered); 19 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/bit_channel_upgrading_procedure.m: -------------------------------------------------------------------------------- 1 | function Pe = bit_channel_upgrading_procedure(W, z, miu) 2 | N = length(z); 3 | if N == 1 4 | Pe = 0.5 * sum(min(W)); 5 | disp(['Bit index = ' num2str(z) ' ML detection Bit Error rate = ' num2str(Pe)]) 6 | else 7 | W_up = get_W_up(W); 8 | W_up = LR_sort(W_up); 9 | W_up_after_erasure_symbol_merge = erasure_symbol_merge(W_up); 10 | W_up_after_merge = upgrading_merge(W_up_after_erasure_symbol_merge, miu); 11 | Pe1 = bit_channel_upgrading_procedure(W_up_after_merge, z(1 : N/2), miu); 12 | 13 | W_down= get_W_down(W); 14 | W_down = LR_sort(W_down); 15 | W_down_after_erasure_symbol_merge = erasure_symbol_merge(W_down); 16 | W_down_after_merge = upgrading_merge(W_down_after_erasure_symbol_merge, miu); 17 | Pe2 = bit_channel_upgrading_procedure(W_down_after_merge, z(N/2 + 1 : end), miu); 18 | 19 | Pe = [Pe1 Pe2]; 20 | end 21 | end 22 | 23 | % function Pe = bit_channel_upgrading_procedure(W, z, miu) 24 | % N = length(z); 25 | % m = round(log2(N)); 26 | % Pe = zeros(N, 1); 27 | % for k = N - 7 : N - 1 28 | % char_bin_expansion = dec2bin(k, m); 29 | % W_tmp = W; 30 | % for i_level = 1 : m 31 | % if char_bin_expansion(i_level) == '0' 32 | % W_up = get_W_up(W_tmp); 33 | % W_up = LR_sort(W_up); 34 | % W_up_after_erasure_symbol_merge = erasure_symbol_merge(W_up); 35 | % W_tmp = upgrading_merge(W_up_after_erasure_symbol_merge, miu); 36 | % else 37 | % W_down = get_W_down(W_tmp); 38 | % W_down = LR_sort(W_down); 39 | % W_down_after_erasure_symbol_merge = erasure_symbol_merge(W_down); 40 | % W_tmp = upgrading_merge(W_down_after_erasure_symbol_merge, miu); 41 | % end 42 | % end 43 | % Pe(k + 1) = 0.5 * sum(min(W_tmp)); 44 | % disp(['Bit index = ' num2str(k + 1) ' ML detection Bit Error rate = ' num2str(Pe(k + 1))]) 45 | % end 46 | % end 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/dClambdadx.m: -------------------------------------------------------------------------------- 1 | function z = dClambdadx(lambda) 2 | z = log2(lambda)./(1 + lambda).^2; 3 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/delta_capacity_basic.m: -------------------------------------------------------------------------------- 1 | function z = delta_capacity_basic(x, y) 2 | 3 | if (x ~= 0) && (y ~= 0) 4 | z = -(x + y) * log2((x + y)/2) + x * log2(x) + y * log2(y); 5 | else 6 | if (x == 0) && (y ~= 0) 7 | z = y; 8 | else 9 | if (y == 0) && (x ~= 0) 10 | z = x; 11 | else 12 | z = 0; 13 | end 14 | end 15 | end 16 | 17 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/delta_capacity_lemma11.m: -------------------------------------------------------------------------------- 1 | function z = delta_capacity_lemma11(a1, a2, a3, b1, b2, b3) 2 | I1 = -delta_capacity_basic(a1, b1); 3 | I2 = -delta_capacity_basic(a2, b2); 4 | I3 = -delta_capacity_basic(a3, b3); 5 | 6 | lambda1 = a1/b1; 7 | 8 | if a3/b3 < inf 9 | lambda3 = a3/b3; 10 | alpha1 = lambda1 * (lambda3 * b2 - a2) / (lambda3 - lambda1); 11 | beta1 = (lambda3 * b2 - a2) / (lambda3 - lambda1); 12 | alpha3 = lambda3 * (a2 - lambda1 * b2) / (lambda3 - lambda1); 13 | beta3 = (a2 - lambda1 * b2) / (lambda3 - lambda1); 14 | else 15 | alpha1 = lambda1 * b2; 16 | beta1 = b2; 17 | alpha3 = a2 - lambda1 * b2; 18 | beta3 = 0; 19 | end 20 | I4 = delta_capacity_basic(a3 + alpha3, b3 + beta3); 21 | I5 = delta_capacity_basic(a1 + alpha1, b1 + beta1); 22 | 23 | z = I1 + I2 + I3 + I4 + I5; 24 | 25 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/delta_capacity_lemma9.m: -------------------------------------------------------------------------------- 1 | function z = delta_capacity_lemma9(a1, a2, b1, b2) 2 | I1 = -delta_capacity_basic(a1, b1); 3 | I2 = -delta_capacity_basic(a2, b2); 4 | 5 | if a2/b2 < inf 6 | lambda2 = a2/b2; 7 | alpha2 = lambda2 * (a1 + b1)/(lambda2 + 1); 8 | beta2 = (a1 + b1)/(lambda2 + 1); 9 | else 10 | alpha2 = a1 + b1; 11 | beta2 = 0; 12 | end 13 | 14 | I3 = delta_capacity_basic(a2 + alpha2, b2 + beta2); 15 | 16 | z = I1 + I2 + I3; 17 | 18 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/erasure_symbol_merge.m: -------------------------------------------------------------------------------- 1 | function V = erasure_symbol_merge(W) 2 | cnt = 0; 3 | N = size(W, 2); 4 | for i = N/2 : -1 : 1 5 | if W(1, i) == W(2, i) 6 | cnt = cnt + 1; 7 | else 8 | break; 9 | end 10 | end 11 | 12 | W_erasure = W(:, N/2 - cnt + 1 : N/2 + cnt); 13 | erasure_probability = sum(W_erasure(1, :)); 14 | middle = erasure_probability/2 * ones(2, 2); 15 | W_left = W(:, 1 : N/2 - cnt); 16 | W_right = W(:, N/2 + cnt + 1 : end); 17 | V = [W_left middle W_right]; 18 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/get_AWGN_capacity.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/get_AWGN_capacity.m -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/get_AWGN_transition_probability.m: -------------------------------------------------------------------------------- 1 | function W = get_AWGN_transition_probability(sigma, v) 2 | alpha = get_Clambda_zero_points(v); 3 | y = get_y_interval(sigma, alpha); 4 | W = upgrading_transform_AWGN_to_DMC(y, alpha, sigma, v); 5 | end 6 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/get_BMS_capacity.m: -------------------------------------------------------------------------------- 1 | function IW = get_BMS_capacity(W) 2 | %This function is employed here to verify the correctness of the program 3 | %that is being writen 4 | N = size(W, 2); 5 | HYX = 0; 6 | for i = 1 : N 7 | if W(1, i) ~= 0 8 | one_term = W(1, i) * log2(W(1, i)); 9 | HYX = HYX + one_term; 10 | end 11 | end 12 | % HYX = sum(W(1, :).*log2(W(1, :))); 13 | PY = (W(1, :) + W(2, :))/2; 14 | HY = sum(-PY.*log2(PY)); 15 | IW = HY + HYX; 16 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/get_Clambda_zero_points.m: -------------------------------------------------------------------------------- 1 | function alpha = get_Clambda_zero_points(v) 2 | alpha = zeros(v + 1, 1); 3 | alpha(1) = 1; 4 | alpha(v + 1) = realmax; 5 | %above two values are obtained by simple calculations and avoid numerical 6 | %problems 7 | %Newton descend method 8 | epsilon = 1e-6;%tolerance error 9 | for i = 2 : v 10 | beta = (i - 1)/v; 11 | x0 = 0; 12 | x1 = 1.5;%initial point, the zero point of d^2C(lambda)/x^2 13 | while(abs(x0 - x1) > epsilon) 14 | x0 = x1; 15 | x1 = x0 - (Clambda(x0) - beta)/dClambdadx(x0); 16 | end 17 | alpha(i) = x1; 18 | end 19 | 20 | end 21 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/get_W_down.m: -------------------------------------------------------------------------------- 1 | function W_down = get_W_down(W) 2 | N = size(W, 2); 3 | W_down = zeros(2, 2 * N^2); 4 | for u2 = 0 : 1 5 | for y1 = 1 : N 6 | for y2 = 1 : N 7 | for u1 = 0 : 1 8 | % P = 0.5 * W(mod(u1 + u2, 2) + 1, y1) * W(u2 + 1, y2); 9 | % if P == 0 10 | % W_down(u2 + 1, 2 * N * (y1 - 1) + 2 * (y2 - 1) + u1 + 1) = realmin; 11 | % else 12 | % W_down(u2 + 1, 2 * N * (y1 - 1) + 2 * (y2 - 1) + u1 + 1) = P; 13 | % end 14 | W_down(u2 + 1, 2 * N * (y1 - 1) + 2 * (y2 - 1) + u1 + 1) = 0.5 * W(mod(u1 + u2, 2) + 1, y1) * W(u2 + 1, y2); 15 | end 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/get_W_up.m: -------------------------------------------------------------------------------- 1 | function W_up = get_W_up(W) 2 | N = size(W, 2); 3 | W_up = zeros(2, N^2); 4 | for u1 = 0 : 1 5 | for y1 = 1 : N 6 | for y2 = 1 : N 7 | % P = 0.5 * (W(u1 + 1, y1) * W(1, y2) + W(mod(u1 + 1, 2) + 1, y1) * W(2, y2)); 8 | % if P == 0 9 | % W_up(u1 + 1, N * (y1 - 1) + y2) = realmin; 10 | % else 11 | % W_up(u1 + 1, N * (y1 - 1) + y2) = P; 12 | % end 13 | W_up(u1 + 1, N * (y1 - 1) + y2) = 0.5 * (W(u1 + 1, y1) * W(1, y2) + W(mod(u1 + 1, 2) + 1, y1) * W(2, y2)); 14 | end 15 | end 16 | end 17 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/get_y_interval.m: -------------------------------------------------------------------------------- 1 | function y = get_y_interval(sigma, alpha) 2 | y = zeros(size(alpha, 1) - 1, 2); 3 | for i = 1 : size(alpha, 1) - 1 4 | y(i, 1) = sigma^2/2*log(alpha(i)); 5 | y(i, 2) = sigma^2/2*log(alpha(i + 1)); 6 | end 7 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/main.m: -------------------------------------------------------------------------------- 1 | clear 2 | snr = 2; 3 | R = 1/2; 4 | sigma = 1/sqrt(2 * R) * 10^(-snr/20); 5 | n = 11; 6 | N = 2^n; 7 | miu = 32; 8 | v = miu/2; 9 | W = get_AWGN_transition_probability(sigma, v); 10 | C_AWGN = get_AWGN_capacity(1, sigma); 11 | IW = get_BMS_capacity(W); 12 | disp(['AWGN with sigma = ' num2str(sigma) '. AWGN Capacity = ' num2str(C_AWGN)]); 13 | disp(['Capacity of Upgrading cahnnel with respect to above AWGN = ' num2str(IW)]); 14 | disp(['Capacity difference = ' num2str(IW - C_AWGN)]); 15 | Pe = bit_channel_upgrading_procedure(W, 1 : N, miu); 16 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/upgrading_merge.m: -------------------------------------------------------------------------------- 1 | function W = upgrading_merge(W, miu) 2 | N = size(W, 2);%N is not a constant if merge is needed 3 | if N <= miu 4 | return 5 | else 6 | % sum_before_merge = 0; 7 | % for i = 1 : N/2 8 | % sum_before_merge = sum_before_merge + norm(W(:, i) - W(end:-1:1, N - i + 1)); 9 | % end 10 | % sum_before_merge 11 | % 12 | % if sum_before_merge > 0.01 13 | % sum(W(1, :)) 14 | % sum(W(2, :)) 15 | % W 16 | % end 17 | % 18 | % if sum_before_merge ~= 0 19 | % sum_before_merge 20 | % W 21 | % sum(W(1, :)) 22 | % sum(W(2, :)) 23 | % LLR = log(W(1,:)) - log(W(2,:)) 24 | % [~, orderd] = sort(LLR, 'descend') 25 | % end 26 | 27 | epsilon = 1e-3; 28 | while(N > miu) 29 | 30 | W_first_half = W(:, 1 : N/2); 31 | LR = W_first_half(1, :)./W_first_half(2, :); 32 | numerical_warning = 0; 33 | 34 | for i = 1 : N/2 - 1 35 | ratio = LR(i)/LR(i + 1); 36 | if ratio < 1 + epsilon 37 | numerical_warning = 1; 38 | break; 39 | end 40 | end 41 | 42 | if numerical_warning == 1 43 | 44 | min_deltaI = realmax; 45 | min_index = 0; 46 | for i = 1 : N/2 - 1 47 | a2 = W(1, i); 48 | b2 = W(2, i); 49 | a1 = W(1,i + 1); 50 | b1 = W(2, i + 1); 51 | deltaI = delta_capacity_lemma9(a1, a2, b1, b2); 52 | if deltaI < min_deltaI %find minimum delta I 53 | min_deltaI = deltaI; 54 | min_index = i; 55 | end 56 | end 57 | 58 | if min_index == 0 59 | for k = 1 : N/2 60 | if sum(W(:, k)) < 1e-20 61 | min_index = k; 62 | W(:, min_index) = []; 63 | W(:, N - min_index) = []; 64 | N = size(W, 2); 65 | break; 66 | end 67 | end 68 | continue; 69 | end 70 | 71 | a2 = W(1, min_index); 72 | b2 = W(2, min_index); 73 | a1 = W(1, min_index + 1); 74 | b1 = W(2, min_index + 1); 75 | 76 | 77 | 78 | 79 | if a2/b2 < inf 80 | lambda2 = a2/b2; 81 | alpha2 = lambda2 * (a1 + b1)/(lambda2 + 1); 82 | beta2 = (a1 + b1)/(lambda2 + 1); 83 | else 84 | alpha2 = a1 + b1; 85 | beta2 = 0; 86 | end 87 | 88 | W(1, min_index) = a2 + alpha2; 89 | W(2, min_index) = b2 + beta2; 90 | W(1, N - min_index + 1) = b2 + beta2; 91 | W(2, N - min_index + 1) = a2 + alpha2; 92 | 93 | W(:, min_index + 1) = []; 94 | W(:, N - min_index - 1) = []; 95 | N = size(W, 2); 96 | 97 | else 98 | 99 | min_deltaI = realmax; 100 | min_index = 0; 101 | 102 | for i = 1 : N/2 - 2 103 | a3 = W(1, i); 104 | b3 = W(2, i); 105 | a2 = W(1,i + 1); 106 | b2 = W(2, i + 1); 107 | a1 = W(1,i + 2); 108 | b1 = W(2, i + 2); 109 | 110 | deltaI = delta_capacity_lemma11(a1, a2, a3, b1, b2, b3); 111 | 112 | if deltaI < min_deltaI %find minimum delta I 113 | min_deltaI = deltaI; 114 | min_index = i; 115 | end 116 | end 117 | 118 | if min_index == 0 119 | for k = 1 : N/2 120 | if sum(W(:, k)) < 1e-20 121 | min_index = k; 122 | W(:, min_index) = []; 123 | W(:, N - min_index) = []; 124 | N = size(W, 2); 125 | break; 126 | end 127 | end 128 | continue; 129 | end 130 | 131 | a3 = W(1, min_index); 132 | b3 = W(2, min_index); 133 | a2 = W(1, min_index + 1); 134 | b2 = W(2, min_index + 1); 135 | a1 = W(1, min_index + 2); 136 | b1 = W(2, min_index + 2); 137 | 138 | lambda1 = a1/b1; 139 | if a3/b3 < inf 140 | lambda3 = a3/b3; 141 | alpha1 = lambda1 * (lambda3 * b2 - a2) / (lambda3 - lambda1); 142 | beta1 = (lambda3 * b2 - a2) / (lambda3 - lambda1); 143 | alpha3 = lambda3 * (a2 - lambda1 * b2) / (lambda3 - lambda1); 144 | beta3 = (a2 - lambda1 * b2) / (lambda3 - lambda1); 145 | else 146 | alpha1 = lambda1 * b2; 147 | beta1 = b2; 148 | alpha3 = a2 - lambda1 * b2; 149 | beta3 = 0; 150 | end 151 | 152 | W(1, min_index) = a3 + alpha3; 153 | W(2, min_index) = b3 + beta3; 154 | 155 | W(1, min_index + 1) = a1 + alpha1; 156 | W(2, min_index + 1) = b1 + beta1; 157 | 158 | W(1, N - min_index + 1) = b3 + beta3; 159 | W(2, N - min_index + 1) = a3 + alpha3; 160 | 161 | W(1, N - min_index) = b1 + beta1; 162 | W(2, N - min_index) = a1 + alpha1; 163 | 164 | W(:, min_index + 2) = []; 165 | W(:, N - min_index - 2) = []; 166 | N = size(W, 2); 167 | 168 | % if N == miu 169 | % W 170 | % end 171 | end 172 | end 173 | 174 | 175 | 176 | % sum_after_merge = 0; 177 | % for i = 1 : N/2 178 | % sum_after_merge = sum_after_merge + norm(W(:, i) - W(end:-1:1, N - i + 1)); 179 | % end 180 | % sum_after_merge 181 | % W 182 | end 183 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/HowToConstructPolarCode/UpgradingConstruction/upgrading_transform_AWGN_to_DMC.m: -------------------------------------------------------------------------------- 1 | function W = upgrading_transform_AWGN_to_DMC(y, theta, sigma, v) 2 | W = zeros(2, 2 * v); 3 | for i = 1 : v 4 | if i < v 5 | y_min = y(i, 1); 6 | y_max = y(i, 2); 7 | p0 = normcdf(y_max, 1, sigma) - normcdf(y_min, 1, sigma); 8 | p1 = normcdf(y_max, -1, sigma) - normcdf(y_min, -1, sigma); 9 | pi_i = p0 + p1; 10 | z0 = (theta(i + 1) * pi_i)/(1 + theta(i + 1)); 11 | z1 = pi_i/(1 + theta(i + 1)); 12 | W(1, 2*i - 1) = z0; 13 | W(2, 2*i - 1) = z1; 14 | W(1, 2*i) = z1; 15 | W(2, 2*i) = z0; 16 | else 17 | y_min = y(i, 1); 18 | y_max = y(i, 2); 19 | p0 = normcdf(y_max, 1, sigma) - normcdf(y_min, 1, sigma); 20 | p1 = normcdf(y_max, -1, sigma) - normcdf(y_min, -1, sigma); 21 | pi_i = p0 + p1; 22 | W(1, 2*i - 1) = pi_i; 23 | W(2, 2*i - 1) = 0; 24 | W(1, 2*i) = 0; 25 | W(2, 2*i) = pi_i; 26 | end 27 | end 28 | 29 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/NodeProcess/Advanced_SC_decoder.m: -------------------------------------------------------------------------------- 1 | function x = Advanced_SC_decoder(llr, frozen_bits, node_type_matrix, lambda_offset_) 2 | %Theoretically, this decoder has much lower latency compared with 3 | %traditional SC decoder because 9 kinds of specific constituent nodes are 4 | %identified and decoded with alternative methods instead of successive 5 | %cancellation. However, due to complex logical that is employed to 6 | %distingguish above nodes, the decoding speed is even slightly lower than traditional SC in terms of MATLAB implementation. 7 | N = length(llr); 8 | m = log2(N); 9 | C = zeros(2 * N - 1, 2); 10 | P = zeros(2 * N - 1, 1); 11 | P(end - N + 1 : end) = llr; 12 | node_type_matrix_cnt = 1; 13 | phi = 0; 14 | while(phi < N) 15 | if (phi + 1) == node_type_matrix(node_type_matrix_cnt, 1) 16 | switch node_type_matrix(node_type_matrix_cnt, 3) 17 | case -1%RATE 0 18 | M = node_type_matrix(node_type_matrix_cnt, 2); 19 | reduced_layer = log2(M); %This reduced layer denotes where to stop. 20 | psi = phi;%This psi leads you to a known (higher level with already obtained LLRs) layer. 21 | psi_ = phi;%This psi_ is used for bits recursion 22 | for i = 1 : reduced_layer 23 | psi_ = floor(psi_/2); 24 | end 25 | layer = 0;%This layer denotes where to start. 26 | 27 | if phi ~= 0 28 | while(mod(psi, 2) == 0) 29 | psi = floor(psi/2); 30 | layer = layer + 1; 31 | end 32 | end 33 | 34 | if phi == 0 35 | for i_layer = m - 1 : -1 : reduced_layer%NOT FULL LAYER = 0 36 | index_1 = lambda_offset_(i_layer + 1); 37 | index_2 = lambda_offset_(i_layer + 2); 38 | for beta = 0 : index_1 - 1 39 | P(beta + index_1) = sign(P(2*beta + index_2)) * sign(P(2*beta + 1 + index_2)) * ... 40 | min(abs(P(2*beta + index_2)), abs(P(2*beta + 1 + index_2))); 41 | end 42 | end 43 | else 44 | for i_layer = layer: -1 : reduced_layer 45 | index_1 = lambda_offset_(i_layer + 1); 46 | index_2 = lambda_offset_(i_layer + 2); 47 | if i_layer == layer 48 | for beta = 0 : index_1 - 1 49 | P(beta + index_1) = (1 - 2*C(beta + index_1, 1)) * P(2 * beta + index_2) + P(2 * beta + 1 + index_2); 50 | end 51 | else 52 | for beta = 0 : index_1 - 1 53 | P(beta + index_1) = sign(P(2 * beta + index_2)) * sign(P(2 * beta + 1 + index_2)) * ... 54 | min(abs(P(2 * beta + index_2)), abs(P(2 * beta + 1 + index_2))); 55 | end 56 | end 57 | end 58 | end 59 | 60 | if mod(psi_, 2) == 0 61 | C(M : 2 * M - 1, 1) = zeros(M, 1); 62 | else 63 | C(M : 2 * M - 1, 2) = zeros(M, 1); 64 | while(mod(psi_, 2) == 1) 65 | psi_ = floor(psi_/2); 66 | index_1 = lambda_offset_(reduced_layer + 1); 67 | index_2 = lambda_offset_(reduced_layer + 2); 68 | for beta = 0 : index_1 - 1 69 | C(2 * beta + index_2, 1 + mod(psi_, 2)) = mod(C(beta + index_1, 1) + C(beta + index_1, 2), 2); 70 | C(2 * beta + 1 + index_2, 1 + mod(psi_, 2)) = C(beta + index_1, 2); 71 | end 72 | reduced_layer = reduced_layer + 1; 73 | end 74 | end 75 | phi = phi + M; 76 | 77 | % 78 | % M = node_type_matrix(node_type_matrix_cnt, 2); 79 | % reduced_layer = log2(M); 80 | % psi = phi; 81 | % for i = 1 : reduced_layer 82 | % psi = floor(psi/2); 83 | % end 84 | % P = recursive_calc_llr(m - reduced_layer, psi, P, C(: , 1), m, lambda_offset); 85 | % 86 | % if mod(psi, 2) == 0 87 | % C(M : 2 * M - 1, 1) = zeros(M, 1); 88 | % else 89 | % C(M : 2 * M - 1, 2) = zeros(M, 1); 90 | % [C(:, 1), C(:, 2)] = recursive_calc_bits(m - reduced_layer, psi, C(:, 1), C(:, 2), m, lambda_offset); 91 | % end 92 | % phi = phi + M; 93 | case 1%RATE 1 94 | M = node_type_matrix(node_type_matrix_cnt, 2); 95 | reduced_layer = log2(M); %This reduced layer denotes where to stop. 96 | psi = phi; 97 | psi_ = phi;%This psi_ is used for bits recursion 98 | for i = 1 : reduced_layer 99 | psi_ = floor(psi_/2); 100 | end 101 | layer = 0;%This layer denotes where to start. 102 | 103 | 104 | if phi ~= 0 105 | while(mod(psi, 2) == 0) 106 | psi = floor(psi/2); 107 | layer = layer + 1; 108 | end 109 | end 110 | 111 | if phi == 0 112 | for i_layer = m - 1 : -1 : reduced_layer%NOT FULL LAYER = 0 113 | index_1 = lambda_offset_(i_layer + 1); 114 | index_2 = lambda_offset_(i_layer + 2); 115 | for beta = 0 : index_1 - 1 116 | P(beta + index_1) = sign(P(2*beta + index_2)) * sign(P(2*beta + 1 + index_2)) * ... 117 | min(abs(P(2*beta + index_2)), abs(P(2*beta + 1 + index_2))); 118 | end 119 | end 120 | else 121 | for i_layer = layer: -1 : reduced_layer 122 | index_1 = lambda_offset_(i_layer + 1); 123 | index_2 = lambda_offset_(i_layer + 2); 124 | if i_layer == layer 125 | for beta = 0 : index_1 - 1 126 | P(beta + index_1) = (1 - 2*C(beta + index_1, 1)) * P(2 * beta + index_2) + P(2 * beta + 1 + index_2); 127 | end 128 | else 129 | for beta = 0 : index_1 - 1 130 | P(beta + index_1) = sign(P(2 * beta + index_2)) * sign(P(2 * beta + 1 + index_2)) * ... 131 | min(abs(P(2 * beta + index_2)), abs(P(2 * beta + 1 + index_2))); 132 | end 133 | end 134 | end 135 | end 136 | x_r1 = P(M : 2 * M - 1) < 0; 137 | if mod(psi_, 2) == 0 138 | C(M : 2 * M - 1, 1) = x_r1; 139 | else 140 | C(M : 2 * M - 1, 2) = x_r1; 141 | while(mod(psi_, 2) == 1) 142 | psi_ = floor(psi_/2); 143 | index_1 = lambda_offset_(reduced_layer + 1); 144 | index_2 = lambda_offset_(reduced_layer + 2); 145 | for beta = 0 : index_1 - 1 146 | C(2 * beta + index_2, 1 + mod(psi_, 2)) = mod(C(beta + index_1, 1) + C(beta + index_1, 2), 2); 147 | C(2 * beta + 1 + index_2, 1 + mod(psi_, 2)) = C(beta + index_1, 2); 148 | end 149 | reduced_layer = reduced_layer + 1; 150 | end 151 | end 152 | phi = phi + M; 153 | 154 | 155 | 156 | % M = node_type_matrix(node_type_matrix_cnt, 2); 157 | % reduced_layer = log2(M); 158 | % psi = phi; 159 | % for i = 1 : reduced_layer 160 | % psi = floor(psi/2); 161 | % end 162 | % P = recursive_calc_llr(m - reduced_layer, psi, P, C(: , 1), m, lambda_offset); 163 | % x_r1 = P(M : 2 * M - 1) < 0; 164 | % if mod(psi, 2) == 0 165 | % C(M : 2 * M - 1, 1) = x_r1; 166 | % else 167 | % C(M : 2 * M - 1, 2) = x_r1; 168 | % [C(:, 1), C(:, 2)] = recursive_calc_bits(m - reduced_layer, psi, C(:, 1), C(:, 2), m, lambda_offset); 169 | % end 170 | % phi = phi + M; 171 | case 2%REP 172 | M = node_type_matrix(node_type_matrix_cnt, 2); 173 | reduced_layer = log2(M); %This reduced layer denotes where to stop. 174 | psi = phi; 175 | psi_ = phi;%This psi_ is used for bits recursion 176 | for i = 1 : reduced_layer 177 | psi_ = floor(psi_/2); 178 | end 179 | layer = 0;%This layer denotes where to start. 180 | 181 | 182 | if phi ~= 0 183 | while(mod(psi, 2) == 0) 184 | psi = floor(psi/2); 185 | layer = layer + 1; 186 | end 187 | end 188 | 189 | if phi == 0 190 | for i_layer = m - 1 : -1 : reduced_layer%NOT FULL LAYER = 0 191 | index_1 = lambda_offset_(i_layer + 1); 192 | index_2 = lambda_offset_(i_layer + 2); 193 | for beta = 0 : index_1 - 1 194 | P(beta + index_1) = sign(P(2*beta + index_2)) * sign(P(2*beta + 1 + index_2)) * ... 195 | min(abs(P(2*beta + index_2)), abs(P(2*beta + 1 + index_2))); 196 | end 197 | end 198 | else 199 | for i_layer = layer: -1 : reduced_layer 200 | index_1 = lambda_offset_(i_layer + 1); 201 | index_2 = lambda_offset_(i_layer + 2); 202 | if i_layer == layer 203 | for beta = 0 : index_1 - 1 204 | P(beta + index_1) = (1 - 2*C(beta + index_1, 1)) * P(2 * beta + index_2) + P(2 * beta + 1 + index_2); 205 | end 206 | else 207 | for beta = 0 : index_1 - 1 208 | P(beta + index_1) = sign(P(2 * beta + index_2)) * sign(P(2 * beta + 1 + index_2)) * ... 209 | min(abs(P(2 * beta + index_2)), abs(P(2 * beta + 1 + index_2))); 210 | end 211 | end 212 | end 213 | end 214 | x_rep = (sum(P(M : 2 * M - 1)) < 0) * ones(M , 1); 215 | if mod(psi_, 2) == 0 216 | C(M : 2 * M - 1, 1) = x_rep; 217 | else 218 | C(M : 2 * M - 1, 2) = x_rep; 219 | while(mod(psi_, 2) == 1) 220 | psi_ = floor(psi_/2); 221 | index_1 = lambda_offset_(reduced_layer + 1); 222 | index_2 = lambda_offset_(reduced_layer + 2); 223 | for beta = 0 : index_1 - 1 224 | C(2 * beta + index_2, 1 + mod(psi_, 2)) = mod(C(beta + index_1, 1) + C(beta + index_1, 2), 2); 225 | C(2 * beta + 1 + index_2, 1 + mod(psi_, 2)) = C(beta + index_1, 2); 226 | end 227 | reduced_layer = reduced_layer + 1; 228 | end 229 | end 230 | phi = phi + M; 231 | 232 | % M = node_type_matrix(node_type_matrix_cnt, 2); 233 | % reduced_layer = log2(M); 234 | % psi = phi; 235 | % for i = 1 : reduced_layer 236 | % psi = floor(psi/2); 237 | % end 238 | % P = recursive_calc_llr(m - reduced_layer, psi, P, C(: , 1), m, lambda_offset); 239 | % x_rep = (sum(P(M : 2 * M - 1)) < 0) * ones(M , 1); 240 | % if mod(psi, 2) == 0 241 | % C(M : 2 * M - 1, 1) = x_rep; 242 | % else 243 | % C(M : 2 * M - 1, 2) = x_rep; 244 | % [C(:, 1), C(:, 2)] = recursive_calc_bits(m - reduced_layer, psi, C(:, 1), C(:, 2), m, lambda_offset); 245 | % end 246 | % phi = phi + M; 247 | case 3%spc 248 | M = node_type_matrix(node_type_matrix_cnt, 2); 249 | reduced_layer = log2(M); %This reduced layer denotes where to stop. 250 | psi = phi; 251 | psi_ = phi;%This psi_ is used for bits recursion 252 | for i = 1 : reduced_layer 253 | psi_ = floor(psi_/2); 254 | end 255 | layer = 0;%This layer denotes where to start. 256 | 257 | 258 | if phi ~= 0 259 | while(mod(psi, 2) == 0) 260 | psi = floor(psi/2); 261 | layer = layer + 1; 262 | end 263 | end 264 | 265 | if phi == 0 266 | for i_layer = m - 1 : -1 : reduced_layer%NOT FULL LAYER = 0 267 | index_1 = lambda_offset_(i_layer + 1); 268 | index_2 = lambda_offset_(i_layer + 2); 269 | for beta = 0 : index_1 - 1 270 | P(beta + index_1) = sign(P(2*beta + index_2)) * sign(P(2*beta + 1 + index_2)) * ... 271 | min(abs(P(2*beta + index_2)), abs(P(2*beta + 1 + index_2))); 272 | end 273 | end 274 | else 275 | for i_layer = layer: -1 : reduced_layer 276 | index_1 = lambda_offset_(i_layer + 1); 277 | index_2 = lambda_offset_(i_layer + 2); 278 | if i_layer == layer 279 | for beta = 0 : index_1 - 1 280 | P(beta + index_1) = (1 - 2*C(beta + index_1, 1)) * P(2 * beta + index_2) + P(2 * beta + 1 + index_2); 281 | end 282 | else 283 | for beta = 0 : index_1 - 1 284 | P(beta + index_1) = sign(P(2 * beta + index_2)) * sign(P(2 * beta + 1 + index_2)) * ... 285 | min(abs(P(2 * beta + index_2)), abs(P(2 * beta + 1 + index_2))); 286 | end 287 | end 288 | end 289 | end 290 | x_spc = SPC(P(M : 2 * M - 1)); 291 | if mod(psi_, 2) == 0 292 | C(M : 2 * M - 1, 1) = x_spc; 293 | else 294 | C(M : 2 * M - 1, 2) = x_spc; 295 | while(mod(psi_, 2) == 1) 296 | psi_ = floor(psi_/2); 297 | index_1 = lambda_offset_(reduced_layer + 1); 298 | index_2 = lambda_offset_(reduced_layer + 2); 299 | for beta = 0 : index_1 - 1 300 | C(2 * beta + index_2, 1 + mod(psi_, 2)) = mod(C(beta + index_1, 1) + C(beta + index_1, 2), 2); 301 | C(2 * beta + 1 + index_2, 1 + mod(psi_, 2)) = C(beta + index_1, 2); 302 | end 303 | reduced_layer = reduced_layer + 1; 304 | end 305 | end 306 | phi = phi + M; 307 | 308 | % M = node_type_matrix(node_type_matrix_cnt, 2); 309 | % reduced_layer = log2(M); 310 | % psi = phi; 311 | % for i = 1 : reduced_layer 312 | % psi = floor(psi/2); 313 | % end 314 | % P = recursive_calc_llr(m - reduced_layer, psi, P, C(: , 1), m, lambda_offset); 315 | % x_spc = SPC(P(M : 2 * M - 1)); 316 | % if mod(psi, 2) == 0 317 | % C(M : 2 * M - 1, 1) = x_spc; 318 | % else 319 | % C(M : 2 * M - 1, 2) = x_spc; 320 | % [C(:, 1), C(:, 2)] = recursive_calc_bits(m - reduced_layer, psi, C(:, 1), C(:, 2), m, lambda_offset); 321 | % end 322 | % phi = phi + M; 323 | case 4% I type 324 | M = node_type_matrix(node_type_matrix_cnt, 2); 325 | reduced_layer = log2(M); %This reduced layer denotes where to stop. 326 | psi = phi; 327 | psi_ = phi;%This psi_ is used for bits recursion 328 | for i = 1 : reduced_layer 329 | psi_ = floor(psi_/2); 330 | end 331 | layer = 0;%This layer denotes where to start. 332 | 333 | 334 | if phi ~= 0 335 | while(mod(psi, 2) == 0) 336 | psi = floor(psi/2); 337 | layer = layer + 1; 338 | end 339 | end 340 | 341 | if phi == 0 342 | for i_layer = m - 1 : -1 : reduced_layer%NOT FULL LAYER = 0 343 | index_1 = lambda_offset_(i_layer + 1); 344 | index_2 = lambda_offset_(i_layer + 2); 345 | for beta = 0 : index_1 - 1 346 | P(beta + index_1) = sign(P(2*beta + index_2)) * sign(P(2*beta + 1 + index_2)) * ... 347 | min(abs(P(2*beta + index_2)), abs(P(2*beta + 1 + index_2))); 348 | end 349 | end 350 | else 351 | for i_layer = layer: -1 : reduced_layer 352 | index_1 = lambda_offset_(i_layer + 1); 353 | index_2 = lambda_offset_(i_layer + 2); 354 | if i_layer == layer 355 | for beta = 0 : index_1 - 1 356 | P(beta + index_1) = (1 - 2*C(beta + index_1, 1)) * P(2 * beta + index_2) + P(2 * beta + 1 + index_2); 357 | end 358 | else 359 | for beta = 0 : index_1 - 1 360 | P(beta + index_1) = sign(P(2 * beta + index_2)) * sign(P(2 * beta + 1 + index_2)) * ... 361 | min(abs(P(2 * beta + index_2)), abs(P(2 * beta + 1 + index_2))); 362 | end 363 | end 364 | end 365 | end 366 | x_typeI = typeI(P(M : 2 * M - 1)); 367 | if mod(psi_, 2) == 0 368 | C(M : 2 * M - 1, 1) = x_typeI; 369 | else 370 | C(M : 2 * M - 1, 2) = x_typeI; 371 | while(mod(psi_, 2) == 1) 372 | psi_ = floor(psi_/2); 373 | index_1 = lambda_offset_(reduced_layer + 1); 374 | index_2 = lambda_offset_(reduced_layer + 2); 375 | for beta = 0 : index_1 - 1 376 | C(2 * beta + index_2, 1 + mod(psi_, 2)) = mod(C(beta + index_1, 1) + C(beta + index_1, 2), 2); 377 | C(2 * beta + 1 + index_2, 1 + mod(psi_, 2)) = C(beta + index_1, 2); 378 | end 379 | reduced_layer = reduced_layer + 1; 380 | end 381 | end 382 | phi = phi + M; 383 | 384 | 385 | % M = node_type_matrix(node_type_matrix_cnt, 2); 386 | % reduced_layer = log2(M); 387 | % psi = phi; 388 | % for i = 1 : reduced_layer 389 | % psi = floor(psi/2); 390 | % end 391 | % P = recursive_calc_llr(m - reduced_layer, psi, P, C(: , 1), m, lambda_offset); 392 | % x_typeI = typeI(P(M : 2 * M - 1)); 393 | % if mod(psi, 2) == 0 394 | % C(M : 2 * M - 1, 1) = x_typeI; 395 | % else 396 | % C(M : 2 * M - 1, 2) = x_typeI; 397 | % [C(:, 1), C(:, 2)] = recursive_calc_bits(m - reduced_layer, psi, C(:, 1), C(:, 2), m, lambda_offset); 398 | % end 399 | % phi = phi + M; 400 | case 5% II type 401 | 402 | M = node_type_matrix(node_type_matrix_cnt, 2); 403 | reduced_layer = log2(M); %This reduced layer denotes where to stop. 404 | psi = phi; 405 | psi_ = phi;%This psi_ is used for bits recursion 406 | for i = 1 : reduced_layer 407 | psi_ = floor(psi_/2); 408 | end 409 | layer = 0;%This layer denotes where to start. 410 | 411 | 412 | if phi ~= 0 413 | while(mod(psi, 2) == 0) 414 | psi = floor(psi/2); 415 | layer = layer + 1; 416 | end 417 | end 418 | 419 | if phi == 0 420 | for i_layer = m - 1 : -1 : reduced_layer%NOT FULL LAYER = 0 421 | index_1 = lambda_offset_(i_layer + 1); 422 | index_2 = lambda_offset_(i_layer + 2); 423 | for beta = 0 : index_1 - 1 424 | P(beta + index_1) = sign(P(2*beta + index_2)) * sign(P(2*beta + 1 + index_2)) * ... 425 | min(abs(P(2*beta + index_2)), abs(P(2*beta + 1 + index_2))); 426 | end 427 | end 428 | else 429 | for i_layer = layer: -1 : reduced_layer 430 | index_1 = lambda_offset_(i_layer + 1); 431 | index_2 = lambda_offset_(i_layer + 2); 432 | if i_layer == layer 433 | for beta = 0 : index_1 - 1 434 | P(beta + index_1) = (1 - 2*C(beta + index_1, 1)) * P(2 * beta + index_2) + P(2 * beta + 1 + index_2); 435 | end 436 | else 437 | for beta = 0 : index_1 - 1 438 | P(beta + index_1) = sign(P(2 * beta + index_2)) * sign(P(2 * beta + 1 + index_2)) * ... 439 | min(abs(P(2 * beta + index_2)), abs(P(2 * beta + 1 + index_2))); 440 | end 441 | end 442 | end 443 | end 444 | x_typeII = typeII(P(M : 2 * M - 1)); 445 | if mod(psi_, 2) == 0 446 | C(M : 2 * M - 1, 1) = x_typeII; 447 | else 448 | C(M : 2 * M - 1, 2) = x_typeII; 449 | while(mod(psi_, 2) == 1) 450 | psi_ = floor(psi_/2); 451 | index_1 = lambda_offset_(reduced_layer + 1); 452 | index_2 = lambda_offset_(reduced_layer + 2); 453 | for beta = 0 : index_1 - 1 454 | C(2 * beta + index_2, 1 + mod(psi_, 2)) = mod(C(beta + index_1, 1) + C(beta + index_1, 2), 2); 455 | C(2 * beta + 1 + index_2, 1 + mod(psi_, 2)) = C(beta + index_1, 2); 456 | end 457 | reduced_layer = reduced_layer + 1; 458 | end 459 | end 460 | phi = phi + M; 461 | 462 | % M = node_type_matrix(node_type_matrix_cnt, 2); 463 | % reduced_layer = log2(M); 464 | % psi = phi; 465 | % for i = 1 : reduced_layer 466 | % psi = floor(psi/2); 467 | % end 468 | % P = recursive_calc_llr(m - reduced_layer, psi, P, C(: , 1), m, lambda_offset); 469 | % x_typeII = typeII(P(M : 2 * M - 1)); 470 | % if mod(psi, 2) == 0 471 | % C(M : 2 * M - 1, 1) = x_typeII; 472 | % else 473 | % C(M : 2 * M - 1, 2) = x_typeII; 474 | % [C(:, 1), C(:, 2)] = recursive_calc_bits(m - reduced_layer, psi, C(:, 1), C(:, 2), m, lambda_offset); 475 | % end 476 | % phi = phi + M; 477 | case 6% III type 478 | M = node_type_matrix(node_type_matrix_cnt, 2); 479 | reduced_layer = log2(M); %This reduced layer denotes where to stop. 480 | psi = phi; 481 | psi_ = phi;%This psi_ is used for bits recursion 482 | for i = 1 : reduced_layer 483 | psi_ = floor(psi_/2); 484 | end 485 | layer = 0;%This layer denotes where to start. 486 | 487 | 488 | if phi ~= 0 489 | while(mod(psi, 2) == 0) 490 | psi = floor(psi/2); 491 | layer = layer + 1; 492 | end 493 | end 494 | 495 | if phi == 0 496 | for i_layer = m - 1 : -1 : reduced_layer%NOT FULL LAYER = 0 497 | index_1 = lambda_offset_(i_layer + 1); 498 | index_2 = lambda_offset_(i_layer + 2); 499 | for beta = 0 : index_1 - 1 500 | P(beta + index_1) = sign(P(2*beta + index_2)) * sign(P(2*beta + 1 + index_2)) * ... 501 | min(abs(P(2*beta + index_2)), abs(P(2*beta + 1 + index_2))); 502 | end 503 | end 504 | else 505 | for i_layer = layer: -1 : reduced_layer 506 | index_1 = lambda_offset_(i_layer + 1); 507 | index_2 = lambda_offset_(i_layer + 2); 508 | if i_layer == layer 509 | for beta = 0 : index_1 - 1 510 | P(beta + index_1) = (1 - 2*C(beta + index_1, 1)) * P(2 * beta + index_2) + P(2 * beta + 1 + index_2); 511 | end 512 | else 513 | for beta = 0 : index_1 - 1 514 | P(beta + index_1) = sign(P(2 * beta + index_2)) * sign(P(2 * beta + 1 + index_2)) * ... 515 | min(abs(P(2 * beta + index_2)), abs(P(2 * beta + 1 + index_2))); 516 | end 517 | end 518 | end 519 | end 520 | x_typeIII = typeIII(P(M : 2 * M - 1)); 521 | if mod(psi_, 2) == 0 522 | C(M : 2 * M - 1, 1) = x_typeIII; 523 | else 524 | C(M : 2 * M - 1, 2) = x_typeIII; 525 | while(mod(psi_, 2) == 1) 526 | psi_ = floor(psi_/2); 527 | index_1 = lambda_offset_(reduced_layer + 1); 528 | index_2 = lambda_offset_(reduced_layer + 2); 529 | for beta = 0 : index_1 - 1 530 | C(2 * beta + index_2, 1 + mod(psi_, 2)) = mod(C(beta + index_1, 1) + C(beta + index_1, 2), 2); 531 | C(2 * beta + 1 + index_2, 1 + mod(psi_, 2)) = C(beta + index_1, 2); 532 | end 533 | reduced_layer = reduced_layer + 1; 534 | end 535 | end 536 | phi = phi + M; 537 | 538 | % M = node_type_matrix(node_type_matrix_cnt, 2); 539 | % reduced_layer = log2(M); 540 | % psi = phi; 541 | % for i = 1 : reduced_layer 542 | % psi = floor(psi/2); 543 | % end 544 | % P = recursive_calc_llr(m - reduced_layer, psi, P, C(: , 1), m, lambda_offset); 545 | % x_typeIII = typeIII(P(M : 2 * M - 1)); 546 | % if mod(psi, 2) == 0 547 | % C(M : 2 * M - 1, 1) = x_typeIII; 548 | % else 549 | % C(M : 2 * M - 1, 2) = x_typeIII; 550 | % [C(:, 1), C(:, 2)] = recursive_calc_bits(m - reduced_layer, psi, C(:, 1), C(:, 2), m, lambda_offset); 551 | % end 552 | % phi = phi + M; 553 | case 7% IV type 554 | M = node_type_matrix(node_type_matrix_cnt, 2); 555 | reduced_layer = log2(M); %This reduced layer denotes where to stop. 556 | psi = phi; 557 | psi_ = phi;%This psi_ is used for bits recursion 558 | for i = 1 : reduced_layer 559 | psi_ = floor(psi_/2); 560 | end 561 | layer = 0;%This layer denotes where to start. 562 | 563 | 564 | if phi ~= 0 565 | while(mod(psi, 2) == 0) 566 | psi = floor(psi/2); 567 | layer = layer + 1; 568 | end 569 | end 570 | 571 | if phi == 0 572 | for i_layer = m - 1 : -1 : reduced_layer%NOT FULL LAYER = 0 573 | index_1 = lambda_offset_(i_layer + 1); 574 | index_2 = lambda_offset_(i_layer + 2); 575 | for beta = 0 : index_1 - 1 576 | P(beta + index_1) = sign(P(2*beta + index_2)) * sign(P(2*beta + 1 + index_2)) * ... 577 | min(abs(P(2*beta + index_2)), abs(P(2*beta + 1 + index_2))); 578 | end 579 | end 580 | else 581 | for i_layer = layer: -1 : reduced_layer 582 | index_1 = lambda_offset_(i_layer + 1); 583 | index_2 = lambda_offset_(i_layer + 2); 584 | if i_layer == layer 585 | for beta = 0 : index_1 - 1 586 | P(beta + index_1) = (1 - 2*C(beta + index_1, 1)) * P(2 * beta + index_2) + P(2 * beta + 1 + index_2); 587 | end 588 | else 589 | for beta = 0 : index_1 - 1 590 | P(beta + index_1) = sign(P(2 * beta + index_2)) * sign(P(2 * beta + 1 + index_2)) * ... 591 | min(abs(P(2 * beta + index_2)), abs(P(2 * beta + 1 + index_2))); 592 | end 593 | end 594 | end 595 | end 596 | x_typeIV = typeIV(P(M : 2 * M - 1)); 597 | if mod(psi_, 2) == 0 598 | C(M : 2 * M - 1, 1) = x_typeIV; 599 | else 600 | C(M : 2 * M - 1, 2) = x_typeIV; 601 | while(mod(psi_, 2) == 1) 602 | psi_ = floor(psi_/2); 603 | index_1 = lambda_offset_(reduced_layer + 1); 604 | index_2 = lambda_offset_(reduced_layer + 2); 605 | for beta = 0 : index_1 - 1 606 | C(2 * beta + index_2, 1 + mod(psi_, 2)) = mod(C(beta + index_1, 1) + C(beta + index_1, 2), 2); 607 | C(2 * beta + 1 + index_2, 1 + mod(psi_, 2)) = C(beta + index_1, 2); 608 | end 609 | reduced_layer = reduced_layer + 1; 610 | end 611 | end 612 | phi = phi + M; 613 | 614 | % M = node_type_matrix(node_type_matrix_cnt, 2); 615 | % reduced_layer = log2(M); 616 | % psi = phi; 617 | % for i = 1 : reduced_layer 618 | % psi = floor(psi/2); 619 | % end 620 | % P = recursive_calc_llr(m - reduced_layer, psi, P, C(: , 1), m, lambda_offset); 621 | % x_typeIV = typeIV(P(M : 2 * M - 1)); 622 | % if mod(psi, 2) == 0 623 | % C(M : 2 * M - 1, 1) = x_typeIV; 624 | % else 625 | % C(M : 2 * M - 1, 2) = x_typeIV; 626 | % [C(:, 1), C(:, 2)] = recursive_calc_bits(m - reduced_layer, psi, C(:, 1), C(:, 2), m, lambda_offset); 627 | % end 628 | % phi = phi + M; 629 | case 8% V type 630 | M = node_type_matrix(node_type_matrix_cnt, 2); 631 | reduced_layer = log2(M); %This reduced layer denotes where to stop. 632 | psi = phi; 633 | psi_ = phi;%This psi_ is used for bits recursion 634 | for i = 1 : reduced_layer 635 | psi_ = floor(psi_/2); 636 | end 637 | layer = 0;%This layer denotes where to start. 638 | 639 | 640 | if phi ~= 0 641 | while(mod(psi, 2) == 0) 642 | psi = floor(psi/2); 643 | layer = layer + 1; 644 | end 645 | end 646 | 647 | if phi == 0 648 | for i_layer = m - 1 : -1 : reduced_layer%NOT FULL LAYER = 0 649 | index_1 = lambda_offset_(i_layer + 1); 650 | index_2 = lambda_offset_(i_layer + 2); 651 | for beta = 0 : index_1 - 1 652 | P(beta + index_1) = sign(P(2*beta + index_2)) * sign(P(2*beta + 1 + index_2)) * ... 653 | min(abs(P(2*beta + index_2)), abs(P(2*beta + 1 + index_2))); 654 | end 655 | end 656 | else 657 | for i_layer = layer: -1 : reduced_layer 658 | index_1 = lambda_offset_(i_layer + 1); 659 | index_2 = lambda_offset_(i_layer + 2); 660 | if i_layer == layer 661 | for beta = 0 : index_1 - 1 662 | P(beta + index_1) = (1 - 2*C(beta + index_1, 1)) * P(2 * beta + index_2) + P(2 * beta + 1 + index_2); 663 | end 664 | else 665 | for beta = 0 : index_1 - 1 666 | P(beta + index_1) = sign(P(2 * beta + index_2)) * sign(P(2 * beta + 1 + index_2)) * ... 667 | min(abs(P(2 * beta + index_2)), abs(P(2 * beta + 1 + index_2))); 668 | end 669 | end 670 | end 671 | end 672 | x_typev = typeV(P(M : 2 * M - 1)); 673 | if mod(psi_, 2) == 0 674 | C(M : 2 * M - 1, 1) = x_typev; 675 | else 676 | C(M : 2 * M - 1, 2) = x_typev; 677 | while(mod(psi_, 2) == 1) 678 | psi_ = floor(psi_/2); 679 | index_1 = lambda_offset_(reduced_layer + 1); 680 | index_2 = lambda_offset_(reduced_layer + 2); 681 | for beta = 0 : index_1 - 1 682 | C(2 * beta + index_2, 1 + mod(psi_, 2)) = mod(C(beta + index_1, 1) + C(beta + index_1, 2), 2); 683 | C(2 * beta + 1 + index_2, 1 + mod(psi_, 2)) = C(beta + index_1, 2); 684 | end 685 | reduced_layer = reduced_layer + 1; 686 | end 687 | end 688 | phi = phi + M; 689 | % M = node_type_matrix(node_type_matrix_cnt, 2); 690 | % reduced_layer = log2(M); 691 | % psi = phi; 692 | % for i = 1 : reduced_layer 693 | % psi = floor(psi/2); 694 | % end 695 | % P = recursive_calc_llr(m - reduced_layer, psi, P, C(: , 1), m, lambda_offset); 696 | % x_typeV = typeV(P(M : 2 * M - 1)); 697 | % if mod(psi, 2) == 0 698 | % C(M : 2 * M - 1, 1) = x_typeV; 699 | % else 700 | % C(M : 2 * M - 1, 2) = x_typeV; 701 | % [C(:, 1), C(:, 2)] = recursive_calc_bits(m - reduced_layer, psi, C(:, 1), C(:, 2), m, lambda_offset); 702 | % end 703 | % phi = phi + M; 704 | end 705 | node_type_matrix_cnt = node_type_matrix_cnt + 1; 706 | if node_type_matrix_cnt == size(node_type_matrix, 1) 707 | node_type_matrix_cnt = 1; 708 | end 709 | else 710 | layer = 0; 711 | if phi == 0 712 | layer = m - 1; 713 | else 714 | psi = phi; 715 | while(mod(psi, 2) == 0) 716 | psi = floor(psi/2); 717 | layer = layer + 1; 718 | end 719 | end 720 | 721 | if phi == 0 722 | for i_layer = m - 1 : -1 : 0 723 | index_1 = lambda_offset_(i_layer + 1); 724 | index_2 = lambda_offset_(i_layer + 2); 725 | for beta = 0 : index_1 - 1 726 | P(beta + index_1) = sign(P(2*beta + index_2)) * sign(P(2*beta + 1 + index_2)) * ... 727 | min(abs(P(2*beta + index_2)), abs(P(2*beta + 1 + index_2))); 728 | end 729 | end 730 | else 731 | for i_layer = layer: -1 : 0 732 | index_1 = lambda_offset_(i_layer + 1); 733 | index_2 = lambda_offset_(i_layer + 2); 734 | if i_layer == layer 735 | for beta = 0 : index_1 - 1 736 | P(beta + index_1) = (1 - 2*C(beta + index_1, 1)) * P(2 * beta + index_2) + P(2 * beta + 1 + index_2); 737 | end 738 | else 739 | for beta = 0 : index_1 - 1 740 | P(beta + index_1) = sign(P(2 * beta + index_2)) * sign(P(2 * beta + 1 + index_2)) * ... 741 | min(abs(P(2 * beta + index_2)), abs(P(2 * beta + 1 + index_2))); 742 | end 743 | end 744 | end 745 | end 746 | 747 | if frozen_bits(phi + 1) == 1 748 | C(1, 1 + mod(phi, 2)) = 0; 749 | else 750 | C(1, 1 + mod(phi, 2)) = P(1) < 0; 751 | end 752 | 753 | if mod(phi, 2) == 1 754 | layer = 0; 755 | psi = phi; 756 | while(mod(psi, 2) == 1) 757 | psi = floor(psi/2); 758 | index_1 = lambda_offset_(layer + 1); 759 | index_2 = lambda_offset_(layer + 2); 760 | for beta = 0 : index_1 - 1 761 | C(2 * beta + index_2, 1 + mod(psi, 2)) = mod(C(beta + index_1, 1) + C(beta + index_1, 2), 2); 762 | C(2 * beta + 1 + index_2, 1 + mod(psi, 2)) = C(beta + index_1, 2); 763 | end 764 | layer = layer + 1; 765 | end 766 | end 767 | 768 | % P = recursive_calc_llr(m, phi, P, C(: , 1), m, lambda_offset); 769 | % if frozen_bits(phi + 1) == 1 770 | % C(1, mod(phi, 2) + 1) = 0; 771 | % else 772 | % C(1, mod(phi, 2) + 1) = P(1) < 0; 773 | % end 774 | % 775 | % if mod(phi, 2) == 1 776 | % [C(:, 1), C(:, 2)] = recursive_calc_bits(m, phi, C(:, 1), C(:, 2), m, lambda_offset); 777 | % end 778 | 779 | phi = phi + 1; 780 | end 781 | end 782 | x = C(end - N + 1 : end, 1); 783 | end 784 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/NodeProcess/REP.m: -------------------------------------------------------------------------------- 1 | function x = REP(alpha) 2 | x_tmp = sum(alpha) < 0; 3 | x = x_tmp * ones(length(alpha), 1); 4 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/NodeProcess/SPC.m: -------------------------------------------------------------------------------- 1 | function x = SPC(alpha)%Wagner Decoder 2 | x = alpha < 0; 3 | if mod(sum(x(2 : end)), 2) ~= x(1) 4 | alpha_plus = abs(alpha); 5 | x(alpha_plus == min(alpha_plus)) = mod(x(alpha_plus == min(alpha_plus)) + 1, 2); 6 | end 7 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/NodeProcess/get_node_structure.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarConventionalCASCL/NodeProcess/get_node_structure.m -------------------------------------------------------------------------------- /PolarConventionalCASCL/NodeProcess/node_identifier.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarConventionalCASCL/NodeProcess/node_identifier.m -------------------------------------------------------------------------------- /PolarConventionalCASCL/NodeProcess/node_identifier_large_node.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarConventionalCASCL/NodeProcess/node_identifier_large_node.m -------------------------------------------------------------------------------- /PolarConventionalCASCL/NodeProcess/node_identifier_no_12345.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarConventionalCASCL/NodeProcess/node_identifier_no_12345.m -------------------------------------------------------------------------------- /PolarConventionalCASCL/NodeProcess/node_identifier_no_45.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarConventionalCASCL/NodeProcess/node_identifier_no_45.m -------------------------------------------------------------------------------- /PolarConventionalCASCL/NodeProcess/typeI.m: -------------------------------------------------------------------------------- 1 | function x = typeI(alpha) 2 | N = length(alpha); 3 | x0 = sum(alpha(1 : end/2)) < 0; 4 | x1 = sum(alpha(end/2 + 1 : end)) < 0; 5 | x_tmp = [x0 * ones(1, N/2) x1 * ones(1, N/2)]; 6 | x = x_tmp'; 7 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/NodeProcess/typeII.m: -------------------------------------------------------------------------------- 1 | function x = typeII(alpha) 2 | N = length(alpha); 3 | x_tmp_4 = zeros(4, 1); 4 | 5 | sum_alpha_1 = sum(alpha(1 : end/4)); 6 | x_tmp_4(1) = sum_alpha_1 < 0; 7 | 8 | sum_alpha_2 = sum(alpha(end/4 + 1 : end/2)); 9 | x_tmp_4(2) = sum_alpha_2 < 0; 10 | 11 | sum_alpha_3 = sum(alpha(end/2 + 1 : end * 3/4)); 12 | x_tmp_4(3) = sum_alpha_3 < 0; 13 | 14 | sum_alpha_4 = sum(alpha(end * 3/4 + 1 : end)); 15 | x_tmp_4(4) = sum_alpha_4 < 0; 16 | 17 | if mod(sum(x_tmp_4(2 : 4)), 2) ~= x_tmp_4(1) 18 | abs_sum_alpha = [abs(sum_alpha_1) abs(sum_alpha_2) abs(sum_alpha_3) abs(sum_alpha_4)]; 19 | index_vec = (abs_sum_alpha == min(abs_sum_alpha)); 20 | x_tmp_4(index_vec) = mod(x_tmp_4(index_vec) + 1, 2); 21 | end 22 | x_tmp = [x_tmp_4(1) * ones(1, N/4) x_tmp_4(2) * ones(1, N/4) x_tmp_4(3) * ones(1, N/4) x_tmp_4(4) * ones(1, N/4)]; 23 | x = x_tmp'; 24 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/NodeProcess/typeIII.m: -------------------------------------------------------------------------------- 1 | function x = typeIII(alpha) 2 | alpha_first_half = alpha(1 : end/2); 3 | alpha_second_half = alpha(end/2 + 1 : end); 4 | x0 = alpha_first_half < 0; 5 | x1 = alpha_second_half < 0; 6 | if mod(sum(x0(2 : end)), 2) ~= x0(1) 7 | abs_alpha_first_half = abs(alpha_first_half); 8 | index_vec = abs_alpha_first_half == min(abs_alpha_first_half); 9 | x0(index_vec) = mod(x0(index_vec) + 1, 2); 10 | end 11 | if mod(sum(x1(2 : end)), 2) ~= x1(1) 12 | abs_alpha_second_half = abs(alpha_second_half); 13 | index_vec = abs_alpha_second_half == min(abs_alpha_second_half); 14 | x1(index_vec) = mod(x1(index_vec) + 1, 2); 15 | end 16 | x_tmp = [x0; x1]; 17 | x = x_tmp(:); 18 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/NodeProcess/typeIV.m: -------------------------------------------------------------------------------- 1 | function x = typeIV(alpha) 2 | %4 times of Bit-wise MAP 3 | alpha_1 = alpha(1 : end/4); 4 | % llr_1 = 2*atanh(prod(tanh(alpha_1/2))); 5 | llr_1 = prod(sign(alpha_1))*min(abs(alpha_1)); 6 | 7 | alpha_2 = alpha(end/4 + 1 : end/2); 8 | % llr_2 = 2*atanh(prod(tanh(alpha_2/2))); 9 | llr_2 = prod(sign(alpha_2))*min(abs(alpha_2)); 10 | 11 | alpha_3 = alpha(end/2 + 1 : end*3/4); 12 | % llr_3 = 2*atanh(prod(tanh(alpha_3/2))); 13 | llr_3 = prod(sign(alpha_3))*min(abs(alpha_3)); 14 | 15 | alpha_4 = alpha(end*3/4 + 1 : end); 16 | % llr_4 = 2*atanh(prod(tanh(alpha_4/2))); 17 | llr_4 = prod(sign(alpha_4))*min(abs(alpha_4)); 18 | 19 | 20 | %Even Parity check 21 | check_bit = (llr_1 + llr_2 + llr_3 + llr_4) < 0; 22 | %Wagner Decoder 23 | x1 = alpha_1 < 0; 24 | if mod(sum(x1), 2) ~= check_bit 25 | x1(abs(alpha_1) == min(abs(alpha_1))) = mod(x1(abs(alpha_1) == min(abs(alpha_1))) + 1, 2); 26 | end 27 | 28 | x2 = alpha_2 < 0; 29 | if mod(sum(x2), 2) ~= check_bit 30 | x2(abs(alpha_2) == min(abs(alpha_2))) = mod(x2(abs(alpha_2) == min(abs(alpha_2))) + 1, 2); 31 | end 32 | 33 | x3 = alpha_3 < 0; 34 | if mod(sum(x3), 2) ~= check_bit 35 | x3(abs(alpha_3) == min(abs(alpha_3))) = mod(x3(abs(alpha_3) == min(abs(alpha_3))) + 1, 2); 36 | end 37 | 38 | x4 = alpha_4 < 0; 39 | if mod(sum(x4), 2) ~= check_bit 40 | x4(abs(alpha_4) == min(abs(alpha_4))) = mod(x4(abs(alpha_4) == min(abs(alpha_4))) + 1, 2); 41 | end 42 | 43 | x_tmp = [x1; x2; x3; x4]; 44 | 45 | x = x_tmp(:); 46 | 47 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/NodeProcess/typeV.m: -------------------------------------------------------------------------------- 1 | function x = typeV(alpha) 2 | N = length(alpha)/8; 3 | sum_alpha = [sum(alpha(1 : end/8)) sum(alpha(end/8 + 1 : end/4)) sum(alpha(end/4 + 1 : end*3/8)) sum(alpha(end*3/8 + 1 : end/2))... 4 | sum(alpha(end/2 + 1 : end*5/8)) sum(alpha(end*5/8 + 1 : end*3/4)) sum(alpha(end*3/4 + 1 : end*7/8)) sum(alpha(end*7/8 + 1 : end))]; 5 | 6 | % z = 2*(atanh(tanh(sum_alpha(1)/2)*tanh(sum_alpha(2)/2)) + atanh(tanh(sum_alpha(3)/2)*tanh(sum_alpha(4)/2)) + ... 7 | % atanh(tanh(sum_alpha(5)/2)*tanh(sum_alpha(6)/2)) + atanh(tanh(sum_alpha(7)/2)*tanh(sum_alpha(8)/2))) < 0; 8 | z = sign(sum_alpha(1))*sign(sum_alpha(2))*min(abs(sum_alpha(1)), abs(sum_alpha(2))) + ... 9 | sign(sum_alpha(3))*sign(sum_alpha(4))*min(abs(sum_alpha(3)), abs(sum_alpha(4))) +... 10 | sign(sum_alpha(5))*sign(sum_alpha(6))*min(abs(sum_alpha(5)), abs(sum_alpha(6))) +... 11 | sign(sum_alpha(7))*sign(sum_alpha(8))*min(abs(sum_alpha(7)), abs(sum_alpha(8))); 12 | z = z < 0; 13 | x = zeros(8, 1); 14 | 15 | x(2) = (1 - 2*z)*sum_alpha(1) + sum_alpha(2) < 0; 16 | x(4) = (1 - 2*z)*sum_alpha(3) + sum_alpha(4) < 0; 17 | x(6) = (1 - 2*z)*sum_alpha(5) + sum_alpha(6) < 0; 18 | x(8) = (1 - 2*z)*sum_alpha(7) + sum_alpha(8) < 0; 19 | 20 | if x(2) ~= mod(x(4) + x(6) + x(8), 2) 21 | abs_alpha_tmp = [abs((1 - 2*z)*sum_alpha(1) + sum_alpha(2)) abs((1 - 2*z)*sum_alpha(3) + sum_alpha(4)) ... 22 | abs((1 - 2*z)*sum_alpha(5) + sum_alpha(6)) abs((1 - 2*z)*sum_alpha(7) + sum_alpha(8))]; 23 | index = find(abs_alpha_tmp == min(abs_alpha_tmp)); 24 | switch index 25 | case 1 26 | x(2) = mod(x(2) + 1, 2); 27 | case 2 28 | x(4) = mod(x(4) + 1, 2); 29 | case 3 30 | x(6) = mod(x(6) + 1, 2); 31 | case 4 32 | x(8) = mod(x(8) + 1, 2); 33 | end 34 | end 35 | x(1) = mod(x(2) + z, 2); 36 | x(3) = mod(x(4) + z, 2); 37 | x(5) = mod(x(6) + z, 2); 38 | x(7) = mod(x(8) + z, 2); 39 | x = [x(1) * ones(N, 1); x(2) * ones(N, 1); x(3) * ones(N, 1); x(4) * ones(N, 1); x(5) * ones(N, 1); x(6) * ones(N, 1); x(7) * ones(N, 1); x(8) * ones(N, 1)]; 40 | end 41 | 42 | % function x = typeV(alpha) 43 | % N = length(alpha)/8; 44 | % sum_alpha = [sum(alpha(1 : end/8)) sum(alpha(end/8 + 1 : end/4)) sum(alpha(end/4 + 1 : end*3/8)) sum(alpha(end*3/8 + 1 : end/2))... 45 | % sum(alpha(end/2 + 1 : end*5/8)) sum(alpha(end*5/8 + 1 : end*3/4)) sum(alpha(end*3/4 + 1 : end*7/8)) sum(alpha(end*7/8 + 1 : end))]; 46 | % 47 | % % z = 2*(atanh(tanh(sum_alpha(1)/2)*tanh(sum_alpha(2)/2)) + atanh(tanh(sum_alpha(3)/2)*tanh(sum_alpha(4)/2)) + ... 48 | % % atanh(tanh(sum_alpha(5)/2)*tanh(sum_alpha(6)/2)) + atanh(tanh(sum_alpha(7)/2)*tanh(sum_alpha(8)/2))) < 0; 49 | % z = sign(sum_alpha(1))*sign(sum_alpha(2))*min(abs(sum_alpha(1)), abs(sum_alpha(2))) + ... 50 | % sign(sum_alpha(3))*sign(sum_alpha(4))*min(abs(sum_alpha(3)), abs(sum_alpha(4))) +... 51 | % sign(sum_alpha(5))*sign(sum_alpha(6))*min(abs(sum_alpha(5)), abs(sum_alpha(6))) +... 52 | % sign(sum_alpha(7))*sign(sum_alpha(8))*min(abs(sum_alpha(7)), abs(sum_alpha(8))); 53 | % z = z < 0; 54 | % x = zeros(8, 1); 55 | % 56 | % x(2) = sum_alpha(2) < 0; 57 | % x(4) = sum_alpha(4) < 0; 58 | % x(6) = sum_alpha(6) < 0; 59 | % x(8) = sum_alpha(8) < 0; 60 | % 61 | % if x(2) ~= mod(x(4) + x(6) + x(8), 2) 62 | % abs_alpha_tmp = abs([sum_alpha(2) sum_alpha(4) sum_alpha(6) sum_alpha(8)]); 63 | % index = find(abs_alpha_tmp == min(abs_alpha_tmp)); 64 | % switch index 65 | % case 1 66 | % x(2) = mod(x(2) + 1, 2); 67 | % case 2 68 | % x(4) = mod(x(4) + 1, 2); 69 | % case 3 70 | % x(6) = mod(x(6) + 1, 2); 71 | % case 4 72 | % x(8) = mod(x(8) + 1, 2); 73 | % end 74 | % end 75 | % x(1) = mod(x(2) + z, 2); 76 | % x(3) = mod(x(4) + z, 2); 77 | % x(5) = mod(x(6) + z, 2); 78 | % x(7) = mod(x(8) + z, 2); 79 | % x = [x(1) * ones(N, 1); x(2) * ones(N, 1); x(3) * ones(N, 1); x(4) * ones(N, 1); x(5) * ones(N, 1); x(6) * ones(N, 1); x(7) * ones(N, 1); x(8) * ones(N, 1)]; 80 | % end 81 | 82 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/PolarizaedChannelsPartialOrder/beta_expansion_polar_code_construction.m: -------------------------------------------------------------------------------- 1 | function channels = beta_expansion_polar_code_construction(N, beta) 2 | m = log2(N); 3 | channels = zeros(N, 1); 4 | for i = 0 : N - 1 5 | bin_seq = dec2bin(i, m); 6 | sum = 0; 7 | for j = 1 : m 8 | if bin_seq(j) == '1' 9 | sum = sum + beta^(m - j); 10 | end 11 | end 12 | channels(i + 1) = sum; 13 | end 14 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/PolarizaedChannelsPartialOrder/partial_order_polarized_channels.m: -------------------------------------------------------------------------------- 1 | function UPO = partial_order_polarized_channels(N) 2 | %N is code length, power of 2. UPO = Univeral partial order 3 | m = log2(N); 4 | max_connection = 32; 5 | UPO = zeros(N, max_connection); 6 | UPO(1, 1) = 1; 7 | % Partial order construction 8 | for layer = 2 : m 9 | N_tmp = 2^layer; 10 | UPO_tmp = UPO(1 : N_tmp/2, :); 11 | for i = 1 : N_tmp/2 12 | for j = 1 : max_connection 13 | if UPO_tmp(i, j) == 0 14 | break; 15 | else 16 | UPO_tmp(i, j) = UPO_tmp(i, j) + N_tmp/2; 17 | end 18 | end 19 | end 20 | UPO(N_tmp/2 + 1 : N_tmp, :) = UPO_tmp; 21 | for i = N_tmp/4 + 1 : N_tmp/2 22 | for j = 1 : max_connection 23 | if UPO(i, j) == 0 24 | UPO(i, j) = (i - 1) + N_tmp/4; 25 | break; 26 | end 27 | end 28 | end 29 | end 30 | %Delete redundant all zero columns 31 | while(all(UPO(:, end) == 0)) 32 | UPO(:, end) = []; 33 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/SC_decoder.m: -------------------------------------------------------------------------------- 1 | function polar_info_esti = SC_decoder(llr, K, frozen_bits, lambda_offset, llr_layer_vec, bit_layer_vec) 2 | N = length(llr);%llr refers to channel LLR. 3 | n = log2(N); 4 | P = zeros(N - 1, 1);%channel llr is not include in P. 5 | C = zeros(N - 1, 2);%C stores internal bit values 6 | polar_info_esti = zeros(K, 1); 7 | cnt_K = 1; 8 | for phi = 0 : N - 1 9 | switch phi 10 | case 0%for decoding u_1 11 | index_1 = lambda_offset(n); 12 | for beta = 0 : index_1 - 1%use llr vector 13 | P(beta + index_1) = sign(llr(beta + 1)) * sign(llr(beta + 1 + index_1)) * min(abs(llr(beta + 1)), abs(llr(beta + 1 + index_1))); 14 | end 15 | for i_layer = n - 2 : -1 : 0%use P vector 16 | index_1 = lambda_offset(i_layer + 1); 17 | index_2 = lambda_offset(i_layer + 2); 18 | for beta = index_1 : index_2 - 1 19 | P(beta) = sign(P(beta + index_1)) * sign(P(beta + index_2)) * min(abs(P(beta + index_1)), abs(P(beta + index_2))); 20 | end 21 | end 22 | case N/2%for deocding u_{N/2 + 1} 23 | index_1 = lambda_offset(n); 24 | for beta = 0 : index_1 - 1%use llr vector. g function. 25 | P(beta + index_1) = (1 - 2 * C(beta + index_1, 1)) * llr(beta + 1) + llr(beta + 1 + index_1); 26 | end 27 | for i_layer = n - 2 : -1 : 0%use P vector. f function 28 | index_1 = lambda_offset(i_layer + 1); 29 | index_2 = lambda_offset(i_layer + 2); 30 | for beta = index_1 : index_2 - 1 31 | P(beta) = sign(P(beta + index_1)) * sign(P(beta + index_2)) * min(abs(P(beta + index_1)), abs(P(beta + index_2))); 32 | end 33 | end 34 | otherwise 35 | llr_layer = llr_layer_vec(phi + 1); 36 | index_1 = lambda_offset(llr_layer + 1); 37 | index_2 = lambda_offset(llr_layer + 2); 38 | for beta = index_1 : index_2 - 1%g function is first implemented. 39 | P(beta) = (1 - 2 * C(beta, 1)) * P(beta + index_1) + P(beta + index_2); 40 | end 41 | for i_layer = llr_layer - 1 : -1 : 0%then f function is implemented. 42 | index_1 = lambda_offset(i_layer + 1); 43 | index_2 = lambda_offset(i_layer + 2); 44 | for beta = index_1 : index_2 - 1 45 | P(beta) = sign(P(beta + index_1)) * sign(P(beta + index_2)) * min(abs(P(beta + index_1)), abs(P(beta + index_2))); 46 | end 47 | end 48 | end 49 | phi_mod_2 = mod(phi, 2); 50 | if frozen_bits(phi + 1) == 1%frozen bit 51 | C(1, 1 + phi_mod_2) = 0; 52 | else%information bit 53 | C(1, 1 + phi_mod_2) = P(1) < 0;%store internal bit values 54 | polar_info_esti(cnt_K) = P(1) < 0; 55 | cnt_K = cnt_K + 1; 56 | end 57 | if phi_mod_2 == 1 && phi ~= N - 1 58 | bit_layer = bit_layer_vec(phi + 1); 59 | for i_layer = 0 : bit_layer - 1%give values to the 2nd column of C 60 | index_1 = lambda_offset(i_layer + 1); 61 | index_2 = lambda_offset(i_layer + 2); 62 | for beta = index_1 : index_2 - 1 63 | C(beta + index_1, 2) = mod(C(beta, 1) + C(beta, 2), 2); 64 | C(beta + index_2, 2) = C(beta, 2); 65 | end 66 | end 67 | index_1 = lambda_offset(bit_layer + 1); 68 | index_2 = lambda_offset(bit_layer + 2); 69 | for beta = index_1 : index_2 - 1%give values to the 1st column of C 70 | C(beta + index_1, 1) = mod(C(beta, 1) + C(beta, 2), 2); 71 | C(beta + index_2, 1) = C(beta, 2); 72 | end 73 | end 74 | end 75 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/crc_generator_matrix.m: -------------------------------------------------------------------------------- 1 | function [G, H] = crc_generator_matrix(g, K) 2 | % [1 1 1 0 1 0 1 0 1] can be used for test 3 | r = length(g) - 1; 4 | N = K + r; 5 | zero_fill = zeros(1, K - 1); 6 | G = zeros(K, N); 7 | G(end, :) = [zero_fill g]; 8 | for i = K - 1 : -1 : 1 9 | G(i, :) = [G(i + 1, 2 : end), G(i + 1, 1)]; 10 | end 11 | for i = K - 1 : -1 : 1 12 | for j = N - r : -1 : i + 1 13 | if G(i, j) == 1 14 | G(i, :) = mod(G(i, :) + G(j, :), 2); 15 | end 16 | end 17 | end 18 | H = zeros(r, N); 19 | H(:, 1 : K) = G(:, K + 1 : end)'; 20 | H(:, K + 1 : end) = eye(r); -------------------------------------------------------------------------------- /PolarConventionalCASCL/get_BEC_IWi.m: -------------------------------------------------------------------------------- 1 | function IWi = get_BEC_IWi(N, C) 2 | IWi = zeros(1, N); 3 | IWi(1) = C; 4 | I_ = zeros(1, N); 5 | m = 1; 6 | while(m <= N/2) 7 | for k = 1 : m 8 | I_(k) = IWi(k) * IWi(k); 9 | I_(k + m) = 2 * IWi(k) - IWi(k) * IWi(k); 10 | end 11 | IWi = I_; 12 | m = m * 2; 13 | end 14 | IWi = bitrevorder(IWi); 15 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/get_bit_layer.m: -------------------------------------------------------------------------------- 1 | function layer_vec = get_bit_layer(N) 2 | layer_vec = zeros(N, 1); 3 | for phi = 0 : N - 1 4 | psi = floor(phi/2); 5 | layer = 0; 6 | while(mod(psi, 2) == 1) 7 | psi = floor(psi/2); 8 | layer = layer + 1; 9 | end 10 | layer_vec(phi + 1) = layer; 11 | end 12 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/get_crc_objective.m: -------------------------------------------------------------------------------- 1 | function [gen, det, g] = get_crc_objective(crc_length) 2 | switch crc_length 3 | case 4 4 | gen = crc.generator('Polynomial',[1 0 0 1 1],'InitialState',zeros(1, 4),'FinalXOR',zeros(1, 4)); 5 | det = crc.detector('Polynomial',[1 0 0 1 1],'InitialState',zeros(1, 4),'FinalXOR',zeros(1, 4)); 6 | g = [1 0 0 1 1]; 7 | case 6 8 | gen = crc.generator('Polynomial',[1 0 0 0 0 1 1],'InitialState',zeros(1, 6),'FinalXOR',zeros(1, 6)); 9 | det = crc.detector('Polynomial',[1 0 0 0 0 1 1],'InitialState',zeros(1, 6),'FinalXOR',zeros(1, 6)); 10 | g = [1 0 0 0 0 1 1]; 11 | case 8 12 | gen = crc.generator('Polynomial','0xA6','InitialState','0x00','FinalXOR','0x00'); 13 | det = crc.detector('Polynomial','0xA6','InitialState','0x00','FinalXOR','0x00'); 14 | % g = [1 0 1 0 0 1 1 0 1]; 15 | g = [1 1 1 1 1 1 0 0 1]; 16 | case 10 17 | gen = crc.generator('Polynomial',[1 1 0 0 1 0 0 1 1 1 1],'InitialState',zeros(1, 10),'FinalXOR',zeros(1, 10)); 18 | det = crc.detector('Polynomial',[1 1 0 0 1 0 0 1 1 1 1],'InitialState',zeros(1, 10),'FinalXOR',zeros(1, 10)); 19 | g = [1 1 0 0 1 0 0 1 1 1 1]; 20 | case 12 21 | gen = crc.generator('Polynomial',[1 1 0 0 0 0 0 0 0 1 1 0 1],'InitialState',zeros(1, 12),'FinalXOR',zeros(1, 12)); 22 | det = crc.detector('Polynomial',[1 1 0 0 0 0 0 0 0 1 1 0 1],'InitialState',zeros(1, 12),'FinalXOR',zeros(1, 12)); 23 | g = [1 1 0 0 0 0 0 0 0 1 1 0 1]; 24 | case 16 25 | gen = crc.generator('Polynomial',[1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1],'InitialState',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0],'FinalXOR',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]); 26 | det = crc.detector('Polynomial',[1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1],'InitialState',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0],'FinalXOR',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]); 27 | g = [1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1]; 28 | case 24 29 | gen = crc.generator('Polynomial',[1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1],'InitialState',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0],... 30 | 'FinalXOR',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]); 31 | det = crc.detector('Polynomial',[1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1],'InitialState',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0],... 32 | 'FinalXOR',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]); 33 | g = [1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1]; 34 | otherwise 35 | disp('Unsupported CRC length. Program terminates') 36 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/get_llr_layer.m: -------------------------------------------------------------------------------- 1 | function layer_vec = get_llr_layer(N) 2 | layer_vec = zeros(N , 1); 3 | for phi = 1 : N - 1 4 | psi = phi; 5 | layer = 0; 6 | while(mod(psi, 2) == 0) 7 | psi = floor(psi/2); 8 | layer = layer + 1; 9 | end 10 | layer_vec(phi + 1) = layer; 11 | end 12 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/main.m: -------------------------------------------------------------------------------- 1 | %High speed MATLAB codes 2 | 3 | %This program use SCL with small list size as a "filter", i.e., under the 4 | %same noise realization, If CRC-SCL with smaller L is correct, then CRC-SCL 5 | %with larger L must be correct. You may not believe in this conjecture, but you can have 6 | %a try, This is true with high probability (almost 1) 7 | 8 | %This program has another accelerator. If in lower snr, CRC-SCL is correct, then at higher snr, 9 | %the same CRC-SCL must be correct. You may not believe in this conjecture, but you can have 10 | %a try, This is true with high probability (almost 1). 11 | 12 | %I know above methods sound dangerous, but it is safe under following 4 13 | %conditions 14 | 15 | %1. The same code word 16 | %2. The same AWGN noise realization with distribution N(0, 1) 17 | %3. CRC must be used (Only SCL is not permitted) 18 | %4. The same code construction in all SNR range. 19 | 20 | %This program satisfies above 4 conditions. You can verify the bler performance by comparisons with existing results. 21 | 22 | %Since MATLAB is not good at recursive function (too many parameters to be passed) 23 | %I cancel the well-known recursiveCalcP() and recursiveCalcB() proposed by 24 | %I. Tal 25 | %Instead, 'For' function is used. You may argue that we can use objective 26 | %oriented (OO) style. However, OO in matlab is also slow. 27 | 28 | %Besides, the algorithms of following papers are provided. 29 | 30 | %How to Construct Polar Codes 31 | %Fast Successive-Cancellation Decoding of Polar Codes: Identification and Decoding of New Nodes 32 | %beta-expansion: A Theoretical Framework for Fast and Recursive Construction of Polar Codes 33 | 34 | %Above three algorithms are made by myself so the correctness is not guaranteed. 35 | 36 | 37 | 38 | 39 | clear 40 | addpath('GA/') 41 | % addpath('HowToConstructPolarCode/') 42 | addpath('NodeProcess/') 43 | % addpath('BECconstruction/') 44 | % addpath('PolarizaedChannelsPartialOrder/') 45 | %adding above folders will take round 2 seconds 46 | 47 | design_epsilon = 0.32; 48 | crc_length = 16; 49 | [gen, det, g] = get_crc_objective(crc_length); 50 | n = 10; 51 | N = 2^n; 52 | K = N/2 + crc_length; 53 | ebno_vec = [2 2.5]; %row vec, you can write it like [1 1.5 2 2.5 3] 54 | list_vec = [1 16]; %row vec, you can write it like [1 4 16 32 ...]. The first element is always 1 for acceleration purpose. The ramaining elements are power of two. 55 | max_runs = 1e7; 56 | max_err = 100; 57 | resolution = 1e4;%the results are shown per max_runs/resolution. 58 | [bler, ber] = simulation(N, K, design_epsilon, max_runs, max_err, resolution, ebno_vec, list_vec, gen, det, g, crc_length); 59 | 60 | -------------------------------------------------------------------------------- /PolarConventionalCASCL/polar_encoder.m: -------------------------------------------------------------------------------- 1 | function x = polar_encoder(u, lambda_offset, llr_layer_vec) 2 | %encoding: x = u * Fn. 3 | N = length(u); 4 | m = log2(N); 5 | C = zeros(N - 1, 1); 6 | x = zeros(N, 1); 7 | for phi = 0 : N - 1 8 | switch phi 9 | case 0 10 | index_1 = lambda_offset(m); 11 | for beta = 1 : index_1 12 | C(beta + index_1 - 1) = u(beta) + u(beta + index_1); 13 | end 14 | for i_layer = m - 2 : -1 : 0 15 | index_1 = lambda_offset(i_layer + 1); 16 | index_2 = lambda_offset(i_layer + 2); 17 | for beta = index_1 : index_2 - 1 18 | C(beta) = C(beta + index_1) + C(beta + index_2); 19 | end 20 | end 21 | case N/2 22 | index_1 = lambda_offset(m); 23 | for beta = 1 : index_1 24 | C(beta + index_1 - 1) = u(beta + index_1); 25 | end 26 | for i_layer = m - 2 : -1 : 0 27 | index_1 = lambda_offset(i_layer + 1); 28 | index_2 = lambda_offset(i_layer + 2); 29 | for beta = index_1 : index_2 - 1 30 | C(beta) = C(beta + index_1) + C(beta + index_2); 31 | end 32 | end 33 | otherwise 34 | layer = llr_layer_vec(phi + 1); 35 | index_1 = lambda_offset(layer + 1); 36 | index_2 = lambda_offset(layer + 2); 37 | for beta = index_1 : index_2 - 1 38 | C(beta) = C(beta + index_2); 39 | end 40 | for i_layer = layer - 1: -1 : 0 41 | index_1 = lambda_offset(i_layer + 1); 42 | index_2 = lambda_offset(i_layer + 2); 43 | for beta = index_1 : index_2 - 1 44 | C(beta) = C(beta + index_1) + C(beta + index_2); 45 | end 46 | end 47 | end 48 | x(phi + 1) = C(1); 49 | end 50 | x = mod(x, 2); 51 | end -------------------------------------------------------------------------------- /PolarConventionalCASCL/simulation.m: -------------------------------------------------------------------------------- 1 | function [bler, ber] = simulation(N, K, design_epsilon, max_runs, max_err, resolution, ebno_vec, list_size_vec, gen, det, g, crc_length) 2 | %effective rate of concatenated codes 3 | R = (K - crc_length)/N; 4 | 5 | %codes parameters to avoid redundant calcularions 6 | lambda_offset = 2.^(0 : log2(N)); 7 | llr_layer_vec = get_llr_layer(N); 8 | bit_layer_vec = get_bit_layer(N); 9 | 10 | 11 | %Self-made CRC check 12 | [G_crc, H_crc] = crc_generator_matrix(g, K - crc_length); 13 | crc_parity_check = G_crc(:, K - crc_length + 1 : end)'; 14 | 15 | %Bhattacharyya Code (BEC) Construction 16 | % channels = get_BEC_IWi(N, 1 - design_epsilon); 17 | % [~, channel_ordered] = sort(channels, 'descend'); 18 | % info_bits = sort(channel_ordered(1 : K), 'ascend'); 19 | % frozen_bits = ones(N , 1); 20 | % frozen_bits(info_bits) = 0; 21 | % info_bits_logical = logical(mod(frozen_bits + 1, 2)); 22 | % search_index = get_search_index(info_bits, K, log2(N)) 23 | 24 | %Gaussian approximation Code Construction 25 | design_snr = 2.5; 26 | sigma_cc = 1/sqrt(2 * R) * 10^(-design_snr/20); 27 | [channels, ~] = GA(sigma_cc, N); 28 | [~, channel_ordered] = sort(channels, 'descend'); 29 | info_bits = sort(channel_ordered(1 : K), 'ascend'); 30 | frozen_bits = ones(N , 1); 31 | frozen_bits(info_bits) = 0; 32 | info_bits_logical = logical(mod(frozen_bits + 1, 2)); 33 | 34 | %beta expansion 35 | % beta = sqrt(sqrt(2)); 36 | % channels = beta_expansion_polar_code_construction(N, beta); 37 | % [~, channel_ordered] = sort(channels, 'descend'); 38 | % info_bits = sort(channel_ordered(1 : K)); 39 | % frozen_bits = ones(N , 1); 40 | % frozen_bits(info_bits) = 0; 41 | 42 | %Special nodes 43 | node_type_matrix = get_node_structure(frozen_bits); 44 | 45 | 46 | %Results Stored 47 | bler = zeros(length(ebno_vec), length(list_size_vec)); 48 | num_runs = zeros(length(ebno_vec), length(list_size_vec)); 49 | ber = 0; 50 | %Loop starts 51 | tic 52 | % profile on 53 | for i_run = 1 : max_runs 54 | if mod(i_run, max_runs/resolution) == 1 55 | disp(' '); 56 | disp(['Sim iteration running = ' num2str(i_run)]); 57 | disp(['N = ' num2str(N) ' K = ' num2str(K)]); 58 | disp(['List size = ' num2str(list_size_vec)]); 59 | disp('The first column is the Eb/N0'); 60 | disp('The second column is the BLER of SC.'); 61 | disp('The remaining columns are the BLERs of CA-SCL you desired'); 62 | disp(num2str([ebno_vec' bler./num_runs])); 63 | disp(' ') 64 | end 65 | %To avoid redundancy 66 | info = rand(K - crc_length, 1) > 0.5; 67 | info_with_crc = [info; mod(crc_parity_check * info, 2)]; 68 | u = zeros(N, 1); 69 | u(info_bits_logical) = info_with_crc; 70 | x = polar_encoder(u, lambda_offset, llr_layer_vec); 71 | bpsk = 1 - 2 * x; 72 | noise = randn(N, 1); 73 | prev_decoded = zeros(length(ebno_vec), length(list_size_vec)); 74 | for i_ebno = 1 : length(ebno_vec) 75 | sigma = 1/sqrt(2 * R) * 10^(-ebno_vec(i_ebno)/20); 76 | y = bpsk + sigma * noise; 77 | llr = 2/sigma^2*y; 78 | for i_list = 1 : length(list_size_vec) 79 | if i_list ~= 1 80 | if bler(i_ebno, i_list) == max_err 81 | continue; 82 | end 83 | else 84 | if all(bler(i_ebno, 2 : end) == max_err) 85 | continue 86 | end 87 | end 88 | num_runs(i_ebno, i_list) = num_runs(i_ebno, i_list) + 1; 89 | run_sim = 1; 90 | for i_ebno2 = 1 : i_ebno 91 | for i_list2 = 1 : i_list 92 | if prev_decoded(i_ebno2, i_list2) 93 | run_sim = 0; 94 | end 95 | end 96 | end 97 | if run_sim == 0 98 | continue; 99 | end 100 | if list_size_vec(i_list) == 1 101 | polar_info_esti = SC_decoder(llr, K, frozen_bits, lambda_offset, llr_layer_vec, bit_layer_vec); 102 | else 103 | polar_info_esti = CASCL_decoder(llr, list_size_vec(i_list), K, frozen_bits, H_crc, lambda_offset, llr_layer_vec, bit_layer_vec); 104 | end 105 | 106 | if any(polar_info_esti ~= info_with_crc) 107 | bler(i_ebno, i_list) = bler(i_ebno, i_list) + 1; 108 | else 109 | prev_decoded(i_ebno, i_list) = 1; 110 | end 111 | 112 | end 113 | end 114 | end 115 | % profile viewer 116 | toc 117 | end 118 | 119 | -------------------------------------------------------------------------------- /PolarFastSCL/BECconstruction/get_BEC_IWi.m: -------------------------------------------------------------------------------- 1 | function IWi = get_BEC_IWi(N, design_epsilon) 2 | IWi = zeros(N,1); 3 | IWi(1) = 1 - design_epsilon; 4 | I_tmp = zeros(N,1); 5 | m = 1; 6 | while(m <= N/2) 7 | for k = 1 : m 8 | I_tmp(k) = IWi(k) * IWi(k); 9 | I_tmp(k+m) = 2 * IWi(k) - IWi(k) * IWi(k); 10 | end 11 | IWi = I_tmp; 12 | m = m * 2; 13 | end 14 | IWi = bitrevorder(IWi); 15 | end -------------------------------------------------------------------------------- /PolarFastSCL/FastSCL_decoder.m: -------------------------------------------------------------------------------- 1 | function polar_info_esti = FastSCL_decoder(llr, L, info_bits, lambda_offset, llr_layer_vec, bit_layer_vec, psi_vec, node_type_matrix, H_crc) 2 | %2018.1.7.14:16 Yu Y. R. 3 | %LLR-based SCL deocoder 4 | %Systematic polar code used 5 | %4 nodes are identified and decoded, i.e., rate0, rate1, rep, spc, 6 | %No BLER loss, while using fast algorithms. 7 | %const 8 | N = length(llr); 9 | m = log2(N); 10 | %memory declared 11 | P = zeros(N - 1, L); %llr is public-used, so N - 1 is enough. 12 | C = zeros(2 * N - 1, 2 * L); 13 | PM = zeros(L, 1); 14 | activepath = zeros(L, 1); 15 | lazy_copy = zeros(m, L); 16 | %initialize the 1st SC decoder 17 | activepath(1) = 1; 18 | lazy_copy(:, 1) = 1; 19 | %decoding starts 20 | %default: in the case of path clone in REP and leaf node, 21 | %origianl always corresponds to bit 0s, while the new path bit 1s. 22 | for i_node = 1 : size(node_type_matrix, 1) 23 | current_index = node_type_matrix(i_node, 1); 24 | llr_layer = llr_layer_vec(current_index); 25 | M = node_type_matrix(i_node, 2);%number of leaf nodes in this constituent node 26 | reduced_layer = log2(M); %For LLR recursion, this reduced layer denotes where to stop; For Bit recursion, this denotes where to start. 27 | psi = psi_vec(i_node);%This psi is used for bits recursion 28 | psi_mod_2 = mod(psi, 2);%To decide whether the bit recuision should continue. 1 : continue; 0 : stop. 29 | for l_index = 1 : L 30 | if activepath(l_index) == 0 31 | continue; 32 | end 33 | switch current_index 34 | case 1 35 | index_1 = lambda_offset(m); 36 | for beta = 0 : index_1 - 1 37 | P(beta + index_1, l_index) = sign(llr(beta + 1)) * sign(llr(beta + index_1 + 1)) * min(abs(llr(beta + 1)), abs(llr(beta + index_1 + 1))); 38 | end 39 | for i_layer = m - 2 : -1 : reduced_layer 40 | index_1 = lambda_offset(i_layer + 1); 41 | index_2 = lambda_offset(i_layer + 2); 42 | for beta = index_1 : index_2 - 1 43 | P(beta, l_index) = sign(P(beta + index_1, l_index)) * sign(P(beta + index_2, l_index)) * ... 44 | min(abs(P(beta + index_1, l_index)), abs(P(beta + index_2, l_index))); 45 | end 46 | end 47 | case N/2 + 1 48 | index_1 = lambda_offset(m); 49 | for beta = 0 : index_1 - 1 50 | x_tmp = C(beta + index_1, 2 * l_index - 1); 51 | P(beta + index_1, l_index) = (1 - 2 * x_tmp) * llr(beta + 1) + llr(beta + index_1 + 1); 52 | end 53 | for i_layer = m - 2 : -1 : reduced_layer 54 | index_1 = lambda_offset(i_layer + 1); 55 | index_2 = lambda_offset(i_layer + 2); 56 | for beta = index_1 : index_2 - 1 57 | P(beta, l_index) = sign(P(beta + index_1, l_index)) * sign(P(beta + index_2, l_index)) * ... 58 | min(abs(P(beta + index_1, l_index)), abs(P(beta + index_2, l_index))); 59 | end 60 | end 61 | otherwise 62 | index_1 = lambda_offset(llr_layer + 1); 63 | index_2 = lambda_offset(llr_layer + 2); 64 | for beta = index_1 : index_2 - 1 65 | %lazy copy 66 | P(beta, l_index) = (1 - 2 * C(beta, 2 * l_index - 1)) * P(beta + index_1, lazy_copy(llr_layer + 2, l_index)) + P(beta + index_2, lazy_copy(llr_layer + 2, l_index)); 67 | end 68 | for i_layer = llr_layer - 1 : -1 : reduced_layer 69 | index_1 = lambda_offset(i_layer + 1); 70 | index_2 = lambda_offset(i_layer + 2); 71 | for beta = index_1 : index_2 - 1 72 | P(beta, l_index) = sign(P(beta + index_1, l_index)) * sign(P(beta + index_2, l_index)) * ... 73 | min(abs(P(beta + index_1, l_index)), abs(P(beta + index_2, l_index))); 74 | end 75 | end 76 | end 77 | end%LLR calculations. You may fold thiis code block. 78 | index_vec = M : 2 * M - 1; 79 | switch node_type_matrix(i_node, 3) 80 | case -1%****RATE 0***** 81 | x = zeros(M, 1); 82 | for l_index = 1 : L 83 | if activepath(l_index) == 0 84 | continue; 85 | end 86 | C(index_vec, psi_mod_2 + 2 * l_index - 1) = x; 87 | PM(l_index) = PM(l_index) + sum(log(1 + exp(-P(index_vec, l_index)))); 88 | %Do not forget updating path metric in rate 0 nodes 89 | %No copy in Rate 0 node 90 | end 91 | case 1%*****RATE 1***** 92 | %input LLR: P(index_vec, :) 93 | [PM, activepath, selected_subcodeword, lazy_copy] = Rate1(M, P(index_vec, :), activepath, PM, L, lazy_copy); 94 | %output: estimated sub polar codeword: 'selected_subcodeword'. 95 | for l_index = 1 : L 96 | if activepath(l_index) == 0 97 | continue 98 | end 99 | C(index_vec, 2 * l_index - 1 + psi_mod_2) = selected_subcodeword(:, l_index); 100 | end 101 | case 2%*****REP***** 102 | [PM, activepath, lazy_copy, selected_subcodeword] = Rep(PM, P(index_vec, :), activepath, L, M, lazy_copy); 103 | for l_index = 1 : L 104 | if activepath(l_index) == 0 105 | continue 106 | end 107 | C(index_vec, 2 * l_index - 1 + psi_mod_2) = selected_subcodeword(:, l_index); 108 | end 109 | case 3%*******SPC******* 110 | [PM, activepath, selected_subcodeword, lazy_copy] = SPC(index_vec, P(index_vec, :), activepath, PM, L, lazy_copy); 111 | for l_index = 1 : L 112 | if activepath(l_index) == 0 113 | continue 114 | end 115 | C(index_vec, 2 * l_index - 1 + psi_mod_2) = selected_subcodeword(:, l_index); 116 | end 117 | end 118 | %Internal Bits Update for each active path 119 | bit_layer = bit_layer_vec(current_index + M - 1); 120 | for l_index = 1 : L 121 | if activepath(l_index) == 0 122 | continue; 123 | end 124 | if psi_mod_2 == 1%right child of its mother 125 | for i_layer = reduced_layer : bit_layer - 1 126 | index_1 = lambda_offset(i_layer + 1); 127 | index_2 = lambda_offset(i_layer + 2); 128 | for beta = index_1 : index_2 - 1 129 | C(beta + index_1, 2 * l_index) = mod(C(beta, 2 * lazy_copy(i_layer + 1, l_index) - 1) + C(beta, 2 * l_index), 2); 130 | C(beta + index_2, 2 * l_index) = C(beta, 2 * l_index); 131 | end 132 | end 133 | index_1 = lambda_offset(bit_layer + 1); 134 | index_2 = lambda_offset(bit_layer + 2); 135 | for beta = index_1 : index_2 - 1 136 | C(beta + index_1, 2 * l_index - 1) = mod(C(beta, 2 * lazy_copy(bit_layer + 1, l_index) - 1) + C(beta, 2 * l_index), 2); 137 | C(beta + index_2, 2 * l_index - 1) = C(beta, 2 * l_index); 138 | end 139 | end 140 | end 141 | %lazy copy 142 | if i_node < size(node_type_matrix, 1) 143 | for i_layer = 1 : llr_layer_vec(current_index + M) + 1 144 | for l_index = 1 : L 145 | lazy_copy(i_layer, l_index) = l_index; 146 | end 147 | end 148 | end 149 | end 150 | %select the best path 151 | [~, path_ordered] = sort(PM); 152 | for l_index = 1 : L 153 | path_num = path_ordered(l_index); 154 | x = C(end - N + 1 : end, 2 * path_num - 1); 155 | info_with_crc = x(info_bits); 156 | err = sum(mod(H_crc * info_with_crc, 2)); 157 | if err == 0 158 | polar_info_esti = info_with_crc; 159 | break; 160 | else 161 | if l_index == L 162 | x = C(end - N + 1 : end, 2 * path_ordered(1) - 1); 163 | polar_info_esti = x(info_bits); 164 | end 165 | end 166 | end 167 | end -------------------------------------------------------------------------------- /PolarFastSCL/GA/Analysis of Sum-Product Decoding of Low-Density.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarFastSCL/GA/Analysis of Sum-Product Decoding of Low-Density.pdf -------------------------------------------------------------------------------- /PolarFastSCL/GA/Capacity_Binary_AWGN.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarFastSCL/GA/Capacity_Binary_AWGN.m -------------------------------------------------------------------------------- /PolarFastSCL/GA/GA.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarFastSCL/GA/GA.m -------------------------------------------------------------------------------- /PolarFastSCL/GA/accurate_phi.m: -------------------------------------------------------------------------------- 1 | function z = accurate_phi(x) 2 | f = @(u, x) (exp(u) - 1)./(exp(u) + 1) .* exp(-(u - x).^2./4./x); 3 | z = integral(@(u) f(u, x), -100, 100); 4 | z = 1 - 1/sqrt(4 * pi * x) * z; 5 | end -------------------------------------------------------------------------------- /PolarFastSCL/GA/derivative_phi.m: -------------------------------------------------------------------------------- 1 | function dx = derivative_phi(x) 2 | if (x >= 0)&&(x <= 10) 3 | dx = -0.4527*0.86*x^(-0.14)*phi(x); 4 | else 5 | dx = exp(-x/4)*sqrt(pi/x)*(-1/2/x*(1 - 10/7/x) - 1/4*(1 - 10/7/x) + 10/7/x/x); 6 | end 7 | end -------------------------------------------------------------------------------- /PolarFastSCL/GA/get_PCi_vector.m: -------------------------------------------------------------------------------- 1 | function PCi = get_PCi_vector(ELNi) 2 | PCi = zeros(length(ELNi), 1); 3 | for i = 1:length(ELNi) 4 | PCi(i) = 0.5*erfc(0.5*sqrt(ELNi(i))); 5 | end 6 | end -------------------------------------------------------------------------------- /PolarFastSCL/GA/get_optimized_parameters.m: -------------------------------------------------------------------------------- 1 | xdata = 1:10; 2 | ydata = zeros(1, length(xdata)); 3 | for i = 1 : length(xdata) 4 | ydata(i) = accurate_phi(xdata(i)); 5 | end 6 | % p = lsqcurvefit(@(p, xdata) exp(p(1) .* xdata.^p(2) + p(3)), [2 7], xdata, ydata); 7 | fun = @(p) exp(p(1) .* xdata .^ p(2) + p(3)) - ydata; 8 | p0 = [1 0.5 1]; 9 | options = optimoptions('lsqnonlin', 'Display', 'iter'); 10 | p = lsqnonlin(fun, p0, [], [], options); 11 | pl = plot(xdata, [ydata; exp(p(1) .* xdata .^ p(2) + p(3))]); 12 | pl(1).Marker = 'd'; 13 | p1(2).Marker = '^'; -------------------------------------------------------------------------------- /PolarFastSCL/GA/get_subchannel_capacity.m: -------------------------------------------------------------------------------- 1 | function cap_vec = get_subchannel_capacity(u) 2 | cap_vec = zeros(1, length(u)); 3 | for i = 1:length(u) 4 | cap_vec(i) = Capacity_Binary_AWGN(u(i), sqrt(2*u(i))); 5 | end 6 | end -------------------------------------------------------------------------------- /PolarFastSCL/GA/main.m: -------------------------------------------------------------------------------- 1 | %rewrite Gauss Approximation for PolarCode construction 2 | %more accurate and easier to read and much quicker 3 | %GA for BPSK-AWGN BPSK = [1 -1] 4 | %such that y = bpsk + noise, llr = 2y/sigma^2 subjects to N(2/sigma^2, 4/sigma^2) when zero 5 | %code word is transmitted 6 | EbN0 = 1; 7 | R = 0.5; 8 | sigma = sqrt(1/2/R)*10^(-EbN0/20); 9 | n = 10; 10 | N = 2^n; 11 | tic 12 | u = GA(sigma, N);%u is the mean value vector for subchannels after the wohle polarization process 13 | toc 14 | % cap_vec = get_subchannel_capacity(u); 15 | % ber_vec = get_PCi_vector(u); 16 | % u 17 | % cap_vec 18 | % ber_vec 19 | -------------------------------------------------------------------------------- /PolarFastSCL/GA/phi.m: -------------------------------------------------------------------------------- 1 | function y = phi(x) 2 | if (x >= 0)&&(x <= 10) 3 | y = exp(-0.4527*x^0.859 + 0.0218); 4 | else 5 | y = sqrt(pi/x) * exp(-x/4) * (1 - 10/7/x); 6 | end -------------------------------------------------------------------------------- /PolarFastSCL/GA/phi_inverse.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarFastSCL/GA/phi_inverse.m -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/Clambda.m: -------------------------------------------------------------------------------- 1 | function z = Clambda(lambda) 2 | z = 1 - lambda./(1 + lambda).*log2(1 + 1./lambda) - 1./(1 + lambda).*log2(1 + lambda); 3 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/LR_sort.m: -------------------------------------------------------------------------------- 1 | function V = LR_sort(W) 2 | N = size(W, 2); 3 | LLR = zeros(1, N); 4 | for i = 1 : N 5 | if (W(1, i) ~= 0) && (W(2, i) ~= 0) 6 | LLR(i) = log(W(1, i)) - log(W(2, i)); 7 | else 8 | if (W(1, i) == 0) && (W(2, i) ~= 0) 9 | LLR(i) = -inf; 10 | else 11 | if (W(1, i) ~= 0) && (W(2, i) == 0) 12 | LLR(i) = inf; 13 | end 14 | end 15 | end 16 | end 17 | [~, ordered] = sort(LLR, 'descend'); 18 | V = W(:, ordered); 19 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/bit_channel_degrading_procedure.m: -------------------------------------------------------------------------------- 1 | function Pe = bit_channel_degrading_procedure(W, z, miu) 2 | N = length(z); 3 | if N == 1 4 | Pe = 0.5 * sum(min(W)); 5 | disp(['Bit index = ' num2str(z) ' Error rate = ' num2str(Pe)]) 6 | else 7 | W_up = get_W_up(W); 8 | W_up = LR_sort(W_up); 9 | W_up_after_erasure_symbol_merge = erasure_symbol_merge(W_up); 10 | W_up_after_merge = degrading_merge(W_up_after_erasure_symbol_merge, miu); 11 | Pe1 = bit_channel_degrading_procedure(W_up_after_merge, z(1 : N/2), miu); 12 | 13 | W_down = get_W_down(W); 14 | W_down = LR_sort(W_down); 15 | W_down_after_erasure_symbol_merge = erasure_symbol_merge(W_down); 16 | W_down_after_merge = degrading_merge(W_down_after_erasure_symbol_merge, miu); 17 | Pe2 = bit_channel_degrading_procedure(W_down_after_merge, z(N/2 + 1 : end), miu); 18 | 19 | Pe = [Pe1 Pe2]; 20 | end 21 | end 22 | 23 | % function Pe = bit_channel_degrading_procedure(W, z, miu) 24 | % N = length(z); 25 | % m = round(log2(N)); 26 | % Pe = zeros(N, 1); 27 | % for k = 0 : N - 1 28 | % char_bin_expansion = dec2bin(k, m); 29 | % W_tmp = W; 30 | % for i_level = 1 : m 31 | % if char_bin_expansion(i_level) == '0' 32 | % W_up = get_W_up(W_tmp); 33 | % W_up = LR_sort(W_up); 34 | % W_up_after_erasure_symbol_merge = erasure_symbol_merge(W_up); 35 | % W_tmp = degrading_merge(W_up_after_erasure_symbol_merge, miu); 36 | % else 37 | % W_down = get_W_down(W_tmp); 38 | % W_down = LR_sort(W_down); 39 | % W_down_after_erasure_symbol_merge = erasure_symbol_merge(W_down); 40 | % W_tmp = degrading_merge(W_down_after_erasure_symbol_merge, miu); 41 | % 42 | % end 43 | % end 44 | % Pe(k + 1) = 0.5 * sum(min(W_tmp)); 45 | % disp(['Bit index = ' num2str(k + 1) ' Error rate = ' num2str(Pe(k + 1))]) 46 | % end 47 | % end 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/capacity.m: -------------------------------------------------------------------------------- 1 | function z = capacity(x, y) 2 | 3 | if (x ~= 0) && (y ~= 0) 4 | z = -(x + y) * log2((x + y)/2) + x * log2(x) + y * log2(y); 5 | else 6 | if (x == 0) && (y ~= 0) 7 | z = y; 8 | else 9 | if (y == 0) && (x ~= 0) 10 | z = x; 11 | else 12 | z = 0; 13 | end 14 | end 15 | end 16 | 17 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/dClambdadx.m: -------------------------------------------------------------------------------- 1 | function z = dClambdadx(lambda) 2 | z = log2(lambda)./(1 + lambda).^2; 3 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/degrading_merge.m: -------------------------------------------------------------------------------- 1 | function W = degrading_merge(W, miu) 2 | N = size(W, 2);%N is not a constant if merge is needed 3 | if N <= miu 4 | return 5 | else 6 | % sum_before_merge = 0; 7 | % for i = 1 : N/2 8 | % sum_before_merge = sum_before_merge + norm(W(:, i) - W(end:-1:1, N - i + 1)); 9 | % end 10 | % sum_before_merge 11 | % if sum_before_merge > 0.01 12 | % sum(W(1,:)); 13 | % sum(W(2, :)) 14 | % end 15 | 16 | 17 | % if sum_before_merge ~= 0 18 | % sum_before_merge 19 | % W 20 | % sum(W(1, :)) 21 | % sum(W(2, :)) 22 | % LLR = log(W(1,:)) - log(W(2,:)) 23 | % [~, orderd] = sort(LLR, 'descend') 24 | % end 25 | while(N > miu) 26 | min_deltaI = realmax; 27 | min_index = 0; 28 | for i = 1 : N/2 - 1 29 | a1 = W(1, i); 30 | b1 = W(2, i); 31 | a2 = W(1,i + 1); 32 | b2 = W(2, i + 1); 33 | deltaI = capacity(a1, b1) + capacity(a2, b2) - capacity(a1 + a2, b1 + b2); 34 | 35 | if deltaI < min_deltaI %find minimum delta I 36 | min_deltaI = deltaI; 37 | min_index = i; 38 | end 39 | end 40 | 41 | % indicator = 0; 42 | % 43 | % for k = 1 : N/2 44 | % if sum(W(:, k)) < 1e-20 45 | % indicator = 1; 46 | % W(:, k) = []; 47 | % W(:, N - k) = []; 48 | % N = size(W, 2); 49 | % break; 50 | % end 51 | % end 52 | % 53 | % if indicator == 1 54 | % continue 55 | % end 56 | 57 | W(1, min_index) = W(1, min_index) + W(1, min_index + 1); 58 | W(2, min_index) = W(2, min_index) + W(2, min_index + 1); 59 | W(1, N - min_index + 1) = W(1, N - min_index + 1) + W(1, N - min_index); 60 | W(2, N - min_index + 1) = W(2, N - min_index + 1) + W(2, N - min_index); 61 | W(:, min_index + 1) = []; 62 | W(:, N - min_index - 1) = []; 63 | N = size(W, 2); 64 | end 65 | % sum_after_merge = 0; 66 | % for i = 1 : N/2 67 | % sum_after_merge = sum_after_merge + norm(W(:, i) - W(end:-1:1, N - i + 1)); 68 | % end 69 | % sum_after_merge 70 | end 71 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/erasure_symbol_merge.m: -------------------------------------------------------------------------------- 1 | function V = erasure_symbol_merge(W) 2 | cnt = 0; 3 | N = size(W, 2); 4 | for i = N/2 : -1 : 1 5 | if W(1, i) == W(2, i) 6 | cnt = cnt + 1; 7 | else 8 | break; 9 | end 10 | end 11 | W_erasure = W(:, N/2 - cnt + 1 : N/2 + cnt); 12 | erasure_probability = sum(W_erasure(1, :)); 13 | middle = erasure_probability/2 * ones(2, 2); 14 | W_left = W(:, 1 : N/2 - cnt); 15 | W_right = W(:, N/2 + cnt + 1 : end); 16 | V = [W_left middle W_right]; 17 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/get_AWGN_capacity.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/get_AWGN_capacity.m -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/get_AWGN_transition_probability.m: -------------------------------------------------------------------------------- 1 | function W = get_AWGN_transition_probability(sigma, v) 2 | alpha = get_Clambda_zero_points(v); 3 | y = get_y_interval(sigma, alpha); 4 | W = transform_AWGN_to_DMC(y, sigma, v); 5 | end 6 | -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/get_BMS_capacity.m: -------------------------------------------------------------------------------- 1 | function IW = get_BMS_capacity(W) 2 | %This function is employed here to verify the correctness of the program 3 | %that is being writen 4 | HYX = sum(W(1, :).*log2(W(1, :))); 5 | PY = (W(1, :) + W(2, :))/2; 6 | HY = sum(-PY.*log2(PY)); 7 | IW = HY + HYX; 8 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/get_Clambda_zero_points.m: -------------------------------------------------------------------------------- 1 | function alpha = get_Clambda_zero_points(v) 2 | alpha = zeros(v + 1, 1); 3 | alpha(1) = 1; 4 | alpha(v + 1) = realmax; 5 | %above two values are obtained by simple calculations and avoid numerical 6 | %problems 7 | %Newton descend method 8 | epsilon = 1e-6;%tolerance error 9 | for i = 2 : v 10 | beta = (i - 1)/v; 11 | x0 = 0; 12 | x1 = 1.5;%initial point, the zero point of d^2C(lambda)/x^2 13 | while(abs(x0 - x1) > epsilon) 14 | x0 = x1; 15 | x1 = x0 - (Clambda(x0) - beta)/dClambdadx(x0); 16 | end 17 | alpha(i) = x1; 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/get_W_down.m: -------------------------------------------------------------------------------- 1 | function W_down = get_W_down(W) 2 | N = size(W, 2); 3 | W_down = zeros(2, 2 * N^2); 4 | for u2 = 0 : 1 5 | for y1 = 1 : N 6 | for y2 = 1 : N 7 | for u1 = 0 : 1 8 | W_down(u2 + 1, 2 * N * (y1 - 1) + 2 * (y2 - 1) + u1 + 1) = 0.5 * W(mod(u1 + u2, 2) + 1, y1) * W(u2 + 1, y2); 9 | end 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/get_W_up.m: -------------------------------------------------------------------------------- 1 | function W_up = get_W_up(W) 2 | N = size(W, 2); 3 | W_up = zeros(2, N^2); 4 | for u1 = 0 : 1 5 | for y1 = 1 : N 6 | for y2 = 1 : N 7 | W_up(u1 + 1, N * (y1 - 1) + y2) = 0.5 * (W(u1 + 1, y1) * W(1, y2) + W(mod(u1 + 1, 2) + 1, y1) * W(2, y2)); 8 | end 9 | end 10 | end 11 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/get_y_interval.m: -------------------------------------------------------------------------------- 1 | function y = get_y_interval(sigma, alpha) 2 | y = zeros(size(alpha, 1) - 1, 2); 3 | for i = 1 : size(alpha, 1) - 1 4 | y(i, 1) = sigma^2/2*log(alpha(i)); 5 | y(i, 2) = sigma^2/2*log(alpha(i + 1)); 6 | end 7 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/main.m: -------------------------------------------------------------------------------- 1 | clear 2 | snr = 2.5; 3 | R = 1/2; 4 | sigma = 1/sqrt(2 * R) * 10^(-snr/20); 5 | n = 8; 6 | N = 2^n; 7 | miu = 32; 8 | v = miu/2; 9 | W = get_AWGN_transition_probability(sigma, v); 10 | C_AWGN = get_AWGN_capacity(1, sigma); 11 | IW = get_BMS_capacity(W); 12 | disp(['AWGN with sigma = ' num2str(sigma) '. AWGN Capacity = ' num2str(C_AWGN)]); 13 | disp(['Capacity of Degrading cahnnel with respect to above AWGN = ' num2str(IW)]); 14 | disp(['Capacity difference = ' num2str(abs(IW - C_AWGN))]); 15 | Pe = bit_channel_degrading_procedure(W, 1 : N, miu); 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/DegradingConstruction/transform_AWGN_to_DMC.m: -------------------------------------------------------------------------------- 1 | function W = transform_AWGN_to_DMC(y, sigma, v) 2 | W = zeros(2, 2 * v); 3 | for i = 1 : v 4 | y_min = y(i, 1); 5 | y_max = y(i, 2); 6 | p0 = normcdf(y_max, 1, sigma) - normcdf(y_min, 1, sigma); 7 | p1 = normcdf(y_max, -1, sigma) - normcdf(y_min, -1, sigma); 8 | W(1, 2*i - 1) = p0; 9 | W(2, 2*i - 1) = p1; 10 | W(1, 2*i) = p1; 11 | W(2, 2*i) = p0; 12 | end 13 | 14 | -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/How to Construct Polar Codes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarFastSCL/HowToConstructPolarCode/How to Construct Polar Codes.pdf -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/Clambda.m: -------------------------------------------------------------------------------- 1 | function z = Clambda(lambda) 2 | z = 1 - lambda./(1 + lambda).*log2(1 + 1./lambda) - 1./(1 + lambda).*log2(1 + lambda); 3 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/LR_sort.m: -------------------------------------------------------------------------------- 1 | function V = LR_sort(W) 2 | N = size(W, 2); 3 | LLR = zeros(1, N); 4 | for i = 1 : N 5 | if (W(1, i) ~= 0) && (W(2, i) ~= 0) 6 | LLR(i) = log(W(1, i)) - log(W(2, i)); 7 | else 8 | if (W(1, i) == 0) && (W(2, i) ~= 0) 9 | LLR(i) = -inf; 10 | else 11 | if (W(1, i) ~= 0) && (W(2, i) == 0) 12 | LLR(i) = inf; 13 | end 14 | end 15 | end 16 | end 17 | [~, ordered] = sort(LLR, 'descend'); 18 | V = W(:, ordered); 19 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/bit_channel_upgrading_procedure.m: -------------------------------------------------------------------------------- 1 | function Pe = bit_channel_upgrading_procedure(W, z, miu) 2 | N = length(z); 3 | if N == 1 4 | Pe = 0.5 * sum(min(W)); 5 | disp(['Bit index = ' num2str(z) ' ML detection Bit Error rate = ' num2str(Pe)]) 6 | else 7 | W_up = get_W_up(W); 8 | W_up = LR_sort(W_up); 9 | W_up_after_erasure_symbol_merge = erasure_symbol_merge(W_up); 10 | W_up_after_merge = upgrading_merge(W_up_after_erasure_symbol_merge, miu); 11 | Pe1 = bit_channel_upgrading_procedure(W_up_after_merge, z(1 : N/2), miu); 12 | 13 | W_down= get_W_down(W); 14 | W_down = LR_sort(W_down); 15 | W_down_after_erasure_symbol_merge = erasure_symbol_merge(W_down); 16 | W_down_after_merge = upgrading_merge(W_down_after_erasure_symbol_merge, miu); 17 | Pe2 = bit_channel_upgrading_procedure(W_down_after_merge, z(N/2 + 1 : end), miu); 18 | 19 | Pe = [Pe1 Pe2]; 20 | end 21 | end 22 | 23 | % function Pe = bit_channel_upgrading_procedure(W, z, miu) 24 | % N = length(z); 25 | % m = round(log2(N)); 26 | % Pe = zeros(N, 1); 27 | % for k = N - 7 : N - 1 28 | % char_bin_expansion = dec2bin(k, m); 29 | % W_tmp = W; 30 | % for i_level = 1 : m 31 | % if char_bin_expansion(i_level) == '0' 32 | % W_up = get_W_up(W_tmp); 33 | % W_up = LR_sort(W_up); 34 | % W_up_after_erasure_symbol_merge = erasure_symbol_merge(W_up); 35 | % W_tmp = upgrading_merge(W_up_after_erasure_symbol_merge, miu); 36 | % else 37 | % W_down = get_W_down(W_tmp); 38 | % W_down = LR_sort(W_down); 39 | % W_down_after_erasure_symbol_merge = erasure_symbol_merge(W_down); 40 | % W_tmp = upgrading_merge(W_down_after_erasure_symbol_merge, miu); 41 | % end 42 | % end 43 | % Pe(k + 1) = 0.5 * sum(min(W_tmp)); 44 | % disp(['Bit index = ' num2str(k + 1) ' ML detection Bit Error rate = ' num2str(Pe(k + 1))]) 45 | % end 46 | % end 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/dClambdadx.m: -------------------------------------------------------------------------------- 1 | function z = dClambdadx(lambda) 2 | z = log2(lambda)./(1 + lambda).^2; 3 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/delta_capacity_basic.m: -------------------------------------------------------------------------------- 1 | function z = delta_capacity_basic(x, y) 2 | 3 | if (x ~= 0) && (y ~= 0) 4 | z = -(x + y) * log2((x + y)/2) + x * log2(x) + y * log2(y); 5 | else 6 | if (x == 0) && (y ~= 0) 7 | z = y; 8 | else 9 | if (y == 0) && (x ~= 0) 10 | z = x; 11 | else 12 | z = 0; 13 | end 14 | end 15 | end 16 | 17 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/delta_capacity_lemma11.m: -------------------------------------------------------------------------------- 1 | function z = delta_capacity_lemma11(a1, a2, a3, b1, b2, b3) 2 | I1 = -delta_capacity_basic(a1, b1); 3 | I2 = -delta_capacity_basic(a2, b2); 4 | I3 = -delta_capacity_basic(a3, b3); 5 | 6 | lambda1 = a1/b1; 7 | 8 | if a3/b3 < inf 9 | lambda3 = a3/b3; 10 | alpha1 = lambda1 * (lambda3 * b2 - a2) / (lambda3 - lambda1); 11 | beta1 = (lambda3 * b2 - a2) / (lambda3 - lambda1); 12 | alpha3 = lambda3 * (a2 - lambda1 * b2) / (lambda3 - lambda1); 13 | beta3 = (a2 - lambda1 * b2) / (lambda3 - lambda1); 14 | else 15 | alpha1 = lambda1 * b2; 16 | beta1 = b2; 17 | alpha3 = a2 - lambda1 * b2; 18 | beta3 = 0; 19 | end 20 | I4 = delta_capacity_basic(a3 + alpha3, b3 + beta3); 21 | I5 = delta_capacity_basic(a1 + alpha1, b1 + beta1); 22 | 23 | z = I1 + I2 + I3 + I4 + I5; 24 | 25 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/delta_capacity_lemma9.m: -------------------------------------------------------------------------------- 1 | function z = delta_capacity_lemma9(a1, a2, b1, b2) 2 | I1 = -delta_capacity_basic(a1, b1); 3 | I2 = -delta_capacity_basic(a2, b2); 4 | 5 | if a2/b2 < inf 6 | lambda2 = a2/b2; 7 | alpha2 = lambda2 * (a1 + b1)/(lambda2 + 1); 8 | beta2 = (a1 + b1)/(lambda2 + 1); 9 | else 10 | alpha2 = a1 + b1; 11 | beta2 = 0; 12 | end 13 | 14 | I3 = delta_capacity_basic(a2 + alpha2, b2 + beta2); 15 | 16 | z = I1 + I2 + I3; 17 | 18 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/erasure_symbol_merge.m: -------------------------------------------------------------------------------- 1 | function V = erasure_symbol_merge(W) 2 | cnt = 0; 3 | N = size(W, 2); 4 | for i = N/2 : -1 : 1 5 | if W(1, i) == W(2, i) 6 | cnt = cnt + 1; 7 | else 8 | break; 9 | end 10 | end 11 | 12 | W_erasure = W(:, N/2 - cnt + 1 : N/2 + cnt); 13 | erasure_probability = sum(W_erasure(1, :)); 14 | middle = erasure_probability/2 * ones(2, 2); 15 | W_left = W(:, 1 : N/2 - cnt); 16 | W_right = W(:, N/2 + cnt + 1 : end); 17 | V = [W_left middle W_right]; 18 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/get_AWGN_capacity.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/get_AWGN_capacity.m -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/get_AWGN_transition_probability.m: -------------------------------------------------------------------------------- 1 | function W = get_AWGN_transition_probability(sigma, v) 2 | alpha = get_Clambda_zero_points(v); 3 | y = get_y_interval(sigma, alpha); 4 | W = upgrading_transform_AWGN_to_DMC(y, alpha, sigma, v); 5 | end 6 | -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/get_BMS_capacity.m: -------------------------------------------------------------------------------- 1 | function IW = get_BMS_capacity(W) 2 | %This function is employed here to verify the correctness of the program 3 | %that is being writen 4 | N = size(W, 2); 5 | HYX = 0; 6 | for i = 1 : N 7 | if W(1, i) ~= 0 8 | one_term = W(1, i) * log2(W(1, i)); 9 | HYX = HYX + one_term; 10 | end 11 | end 12 | % HYX = sum(W(1, :).*log2(W(1, :))); 13 | PY = (W(1, :) + W(2, :))/2; 14 | HY = sum(-PY.*log2(PY)); 15 | IW = HY + HYX; 16 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/get_Clambda_zero_points.m: -------------------------------------------------------------------------------- 1 | function alpha = get_Clambda_zero_points(v) 2 | alpha = zeros(v + 1, 1); 3 | alpha(1) = 1; 4 | alpha(v + 1) = realmax; 5 | %above two values are obtained by simple calculations and avoid numerical 6 | %problems 7 | %Newton descend method 8 | epsilon = 1e-6;%tolerance error 9 | for i = 2 : v 10 | beta = (i - 1)/v; 11 | x0 = 0; 12 | x1 = 1.5;%initial point, the zero point of d^2C(lambda)/x^2 13 | while(abs(x0 - x1) > epsilon) 14 | x0 = x1; 15 | x1 = x0 - (Clambda(x0) - beta)/dClambdadx(x0); 16 | end 17 | alpha(i) = x1; 18 | end 19 | 20 | end 21 | -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/get_W_down.m: -------------------------------------------------------------------------------- 1 | function W_down = get_W_down(W) 2 | N = size(W, 2); 3 | W_down = zeros(2, 2 * N^2); 4 | for u2 = 0 : 1 5 | for y1 = 1 : N 6 | for y2 = 1 : N 7 | for u1 = 0 : 1 8 | % P = 0.5 * W(mod(u1 + u2, 2) + 1, y1) * W(u2 + 1, y2); 9 | % if P == 0 10 | % W_down(u2 + 1, 2 * N * (y1 - 1) + 2 * (y2 - 1) + u1 + 1) = realmin; 11 | % else 12 | % W_down(u2 + 1, 2 * N * (y1 - 1) + 2 * (y2 - 1) + u1 + 1) = P; 13 | % end 14 | W_down(u2 + 1, 2 * N * (y1 - 1) + 2 * (y2 - 1) + u1 + 1) = 0.5 * W(mod(u1 + u2, 2) + 1, y1) * W(u2 + 1, y2); 15 | end 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/get_W_up.m: -------------------------------------------------------------------------------- 1 | function W_up = get_W_up(W) 2 | N = size(W, 2); 3 | W_up = zeros(2, N^2); 4 | for u1 = 0 : 1 5 | for y1 = 1 : N 6 | for y2 = 1 : N 7 | % P = 0.5 * (W(u1 + 1, y1) * W(1, y2) + W(mod(u1 + 1, 2) + 1, y1) * W(2, y2)); 8 | % if P == 0 9 | % W_up(u1 + 1, N * (y1 - 1) + y2) = realmin; 10 | % else 11 | % W_up(u1 + 1, N * (y1 - 1) + y2) = P; 12 | % end 13 | W_up(u1 + 1, N * (y1 - 1) + y2) = 0.5 * (W(u1 + 1, y1) * W(1, y2) + W(mod(u1 + 1, 2) + 1, y1) * W(2, y2)); 14 | end 15 | end 16 | end 17 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/get_y_interval.m: -------------------------------------------------------------------------------- 1 | function y = get_y_interval(sigma, alpha) 2 | y = zeros(size(alpha, 1) - 1, 2); 3 | for i = 1 : size(alpha, 1) - 1 4 | y(i, 1) = sigma^2/2*log(alpha(i)); 5 | y(i, 2) = sigma^2/2*log(alpha(i + 1)); 6 | end 7 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/main.m: -------------------------------------------------------------------------------- 1 | clear 2 | snr = 2; 3 | R = 1/2; 4 | sigma = 1/sqrt(2 * R) * 10^(-snr/20); 5 | n = 11; 6 | N = 2^n; 7 | miu = 32; 8 | v = miu/2; 9 | W = get_AWGN_transition_probability(sigma, v); 10 | C_AWGN = get_AWGN_capacity(1, sigma); 11 | IW = get_BMS_capacity(W); 12 | disp(['AWGN with sigma = ' num2str(sigma) '. AWGN Capacity = ' num2str(C_AWGN)]); 13 | disp(['Capacity of Upgrading cahnnel with respect to above AWGN = ' num2str(IW)]); 14 | disp(['Capacity difference = ' num2str(IW - C_AWGN)]); 15 | Pe = bit_channel_upgrading_procedure(W, 1 : N, miu); 16 | -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/upgrading_merge.m: -------------------------------------------------------------------------------- 1 | function W = upgrading_merge(W, miu) 2 | N = size(W, 2);%N is not a constant if merge is needed 3 | if N <= miu 4 | return 5 | else 6 | % sum_before_merge = 0; 7 | % for i = 1 : N/2 8 | % sum_before_merge = sum_before_merge + norm(W(:, i) - W(end:-1:1, N - i + 1)); 9 | % end 10 | % sum_before_merge 11 | % 12 | % if sum_before_merge > 0.01 13 | % sum(W(1, :)) 14 | % sum(W(2, :)) 15 | % W 16 | % end 17 | % 18 | % if sum_before_merge ~= 0 19 | % sum_before_merge 20 | % W 21 | % sum(W(1, :)) 22 | % sum(W(2, :)) 23 | % LLR = log(W(1,:)) - log(W(2,:)) 24 | % [~, orderd] = sort(LLR, 'descend') 25 | % end 26 | 27 | epsilon = 1e-3; 28 | while(N > miu) 29 | 30 | W_first_half = W(:, 1 : N/2); 31 | LR = W_first_half(1, :)./W_first_half(2, :); 32 | numerical_warning = 0; 33 | 34 | for i = 1 : N/2 - 1 35 | ratio = LR(i)/LR(i + 1); 36 | if ratio < 1 + epsilon 37 | numerical_warning = 1; 38 | break; 39 | end 40 | end 41 | 42 | if numerical_warning == 1 43 | 44 | min_deltaI = realmax; 45 | min_index = 0; 46 | for i = 1 : N/2 - 1 47 | a2 = W(1, i); 48 | b2 = W(2, i); 49 | a1 = W(1,i + 1); 50 | b1 = W(2, i + 1); 51 | deltaI = delta_capacity_lemma9(a1, a2, b1, b2); 52 | if deltaI < min_deltaI %find minimum delta I 53 | min_deltaI = deltaI; 54 | min_index = i; 55 | end 56 | end 57 | 58 | if min_index == 0 59 | for k = 1 : N/2 60 | if sum(W(:, k)) < 1e-20 61 | min_index = k; 62 | W(:, min_index) = []; 63 | W(:, N - min_index) = []; 64 | N = size(W, 2); 65 | break; 66 | end 67 | end 68 | continue; 69 | end 70 | 71 | a2 = W(1, min_index); 72 | b2 = W(2, min_index); 73 | a1 = W(1, min_index + 1); 74 | b1 = W(2, min_index + 1); 75 | 76 | 77 | 78 | 79 | if a2/b2 < inf 80 | lambda2 = a2/b2; 81 | alpha2 = lambda2 * (a1 + b1)/(lambda2 + 1); 82 | beta2 = (a1 + b1)/(lambda2 + 1); 83 | else 84 | alpha2 = a1 + b1; 85 | beta2 = 0; 86 | end 87 | 88 | W(1, min_index) = a2 + alpha2; 89 | W(2, min_index) = b2 + beta2; 90 | W(1, N - min_index + 1) = b2 + beta2; 91 | W(2, N - min_index + 1) = a2 + alpha2; 92 | 93 | W(:, min_index + 1) = []; 94 | W(:, N - min_index - 1) = []; 95 | N = size(W, 2); 96 | 97 | else 98 | 99 | min_deltaI = realmax; 100 | min_index = 0; 101 | 102 | for i = 1 : N/2 - 2 103 | a3 = W(1, i); 104 | b3 = W(2, i); 105 | a2 = W(1,i + 1); 106 | b2 = W(2, i + 1); 107 | a1 = W(1,i + 2); 108 | b1 = W(2, i + 2); 109 | 110 | deltaI = delta_capacity_lemma11(a1, a2, a3, b1, b2, b3); 111 | 112 | if deltaI < min_deltaI %find minimum delta I 113 | min_deltaI = deltaI; 114 | min_index = i; 115 | end 116 | end 117 | 118 | if min_index == 0 119 | for k = 1 : N/2 120 | if sum(W(:, k)) < 1e-20 121 | min_index = k; 122 | W(:, min_index) = []; 123 | W(:, N - min_index) = []; 124 | N = size(W, 2); 125 | break; 126 | end 127 | end 128 | continue; 129 | end 130 | 131 | a3 = W(1, min_index); 132 | b3 = W(2, min_index); 133 | a2 = W(1, min_index + 1); 134 | b2 = W(2, min_index + 1); 135 | a1 = W(1, min_index + 2); 136 | b1 = W(2, min_index + 2); 137 | 138 | lambda1 = a1/b1; 139 | if a3/b3 < inf 140 | lambda3 = a3/b3; 141 | alpha1 = lambda1 * (lambda3 * b2 - a2) / (lambda3 - lambda1); 142 | beta1 = (lambda3 * b2 - a2) / (lambda3 - lambda1); 143 | alpha3 = lambda3 * (a2 - lambda1 * b2) / (lambda3 - lambda1); 144 | beta3 = (a2 - lambda1 * b2) / (lambda3 - lambda1); 145 | else 146 | alpha1 = lambda1 * b2; 147 | beta1 = b2; 148 | alpha3 = a2 - lambda1 * b2; 149 | beta3 = 0; 150 | end 151 | 152 | W(1, min_index) = a3 + alpha3; 153 | W(2, min_index) = b3 + beta3; 154 | 155 | W(1, min_index + 1) = a1 + alpha1; 156 | W(2, min_index + 1) = b1 + beta1; 157 | 158 | W(1, N - min_index + 1) = b3 + beta3; 159 | W(2, N - min_index + 1) = a3 + alpha3; 160 | 161 | W(1, N - min_index) = b1 + beta1; 162 | W(2, N - min_index) = a1 + alpha1; 163 | 164 | W(:, min_index + 2) = []; 165 | W(:, N - min_index - 2) = []; 166 | N = size(W, 2); 167 | 168 | % if N == miu 169 | % W 170 | % end 171 | end 172 | end 173 | 174 | 175 | 176 | % sum_after_merge = 0; 177 | % for i = 1 : N/2 178 | % sum_after_merge = sum_after_merge + norm(W(:, i) - W(end:-1:1, N - i + 1)); 179 | % end 180 | % sum_after_merge 181 | % W 182 | end 183 | end -------------------------------------------------------------------------------- /PolarFastSCL/HowToConstructPolarCode/UpgradingConstruction/upgrading_transform_AWGN_to_DMC.m: -------------------------------------------------------------------------------- 1 | function W = upgrading_transform_AWGN_to_DMC(y, theta, sigma, v) 2 | W = zeros(2, 2 * v); 3 | for i = 1 : v 4 | if i < v 5 | y_min = y(i, 1); 6 | y_max = y(i, 2); 7 | p0 = normcdf(y_max, 1, sigma) - normcdf(y_min, 1, sigma); 8 | p1 = normcdf(y_max, -1, sigma) - normcdf(y_min, -1, sigma); 9 | pi_i = p0 + p1; 10 | z0 = (theta(i + 1) * pi_i)/(1 + theta(i + 1)); 11 | z1 = pi_i/(1 + theta(i + 1)); 12 | W(1, 2*i - 1) = z0; 13 | W(2, 2*i - 1) = z1; 14 | W(1, 2*i) = z1; 15 | W(2, 2*i) = z0; 16 | else 17 | y_min = y(i, 1); 18 | y_max = y(i, 2); 19 | p0 = normcdf(y_max, 1, sigma) - normcdf(y_min, 1, sigma); 20 | p1 = normcdf(y_max, -1, sigma) - normcdf(y_min, -1, sigma); 21 | pi_i = p0 + p1; 22 | W(1, 2*i - 1) = pi_i; 23 | W(2, 2*i - 1) = 0; 24 | W(1, 2*i) = 0; 25 | W(2, 2*i) = pi_i; 26 | end 27 | end 28 | 29 | -------------------------------------------------------------------------------- /PolarFastSCL/MonteCarloCodeConstruction/Polar Coding for Bit-Interleaved Coded Modulation .pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarFastSCL/MonteCarloCodeConstruction/Polar Coding for Bit-Interleaved Coded Modulation .pdf -------------------------------------------------------------------------------- /PolarFastSCL/MonteCarloCodeConstruction/get_bit_layer.m: -------------------------------------------------------------------------------- 1 | function layer_vec = get_bit_layer(N) 2 | layer_vec = zeros(N, 1); 3 | for phi = 0 : N - 1 4 | psi = floor(phi/2); 5 | layer = 0; 6 | while(mod(psi, 2) == 1) 7 | psi = floor(psi/2); 8 | layer = layer + 1; 9 | end 10 | layer_vec(phi + 1) = layer; 11 | end 12 | end -------------------------------------------------------------------------------- /PolarFastSCL/MonteCarloCodeConstruction/get_llr_layer.m: -------------------------------------------------------------------------------- 1 | function layer_vec = get_llr_layer(N) 2 | layer_vec = zeros(N , 1); 3 | for phi = 1 : N - 1 4 | psi = phi; 5 | layer = 0; 6 | while(mod(psi, 2) == 0) 7 | psi = floor(psi/2); 8 | layer = layer + 1; 9 | end 10 | layer_vec(phi + 1) = layer; 11 | end 12 | end -------------------------------------------------------------------------------- /PolarFastSCL/MonteCarloCodeConstruction/main.m: -------------------------------------------------------------------------------- 1 | n = 10; 2 | N = 2^n; 3 | K = 2^(n - 1); 4 | R = K/N; 5 | design_snr = 2.5;%dB 6 | %You;d better to learn more about the relationship between RM code and 7 | %polar code. Then you can construct good polar code. 8 | sigma = 1/sqrt(2 * R) * 10^(-design_snr/20); 9 | max_runs = 1e5; 10 | llr_layer_vec = get_llr_layer(N); 11 | bit_layer_vec = get_bit_layer(N); 12 | lambda_offset = 2.^(0 : n); 13 | ber = zeros(N, 1); 14 | for i_run = 1 : max_runs 15 | if mod(i_run, max_runs/100) == 1 16 | disp(['Type I monte carlo code construction running = ' num2str(i_run/max_runs*100) '%']); 17 | end 18 | dummy_info = rand(N, 1) > 0.5; 19 | noise = randn(N, 1); 20 | x = my_polar_encode(dummy_info, lambda_offset, llr_layer_vec); 21 | bpsk = 1 - 2 * x; 22 | y = bpsk + sigma * noise; 23 | llr = 2 * y / sigma^2; 24 | ber_tmp = mc_typeI_SC_decoder(llr, lambda_offset, llr_layer_vec, bit_layer_vec, dummy_info); 25 | ber = ber + ber_tmp; 26 | end 27 | [~, channel_ordered] = sort(ber); 28 | info_bits = sort(channel_ordered(1 : K)); 29 | disp('Type I MC CC done.') 30 | disp('Variable "info_bits" is what you want') 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /PolarFastSCL/MonteCarloCodeConstruction/mc_typeI_SC_decoder.m: -------------------------------------------------------------------------------- 1 | function ber = mc_typeI_SC_decoder(llr, lambda_offset, llr_layer_vec, bit_layer_vec, dummy_info)%x is code word, not sorcue seq. 2 | N = length(llr); 3 | m = log2(N); 4 | P = zeros(N - 1, 1);%llr is not include in P. 5 | C = zeros(N - 1, 2); %I do not calculate the estimate of (x1, x2, ... , xN). It is not very necessary. 6 | ber = zeros(N, 1); 7 | for phi = 0 : N - 1 8 | switch phi 9 | case 0 10 | for i_layer = m - 1 : -1 : 0 11 | index_1 = lambda_offset(i_layer + 1); 12 | if i_layer == (m - 1) 13 | for beta = 0 : index_1 - 1 14 | sign_1 = sign(llr(2 * beta + 1)); 15 | sign_2 = sign(llr(2 * beta + 2)); 16 | a = abs(llr(2 * beta + 1)); 17 | b = abs(llr(2 * beta + 2)); 18 | P(beta + index_1) = sign_1 * sign_2 * min(a, b); 19 | end 20 | else 21 | for beta = index_1 : 2 * index_1 - 1 22 | sign_1 = sign(P(2 * beta)); 23 | sign_2 = sign(P(2 * beta + 1)); 24 | a = abs(P(2 * beta)); 25 | b = abs(P(2 * beta + 1)); 26 | P(beta) = sign_1 * sign_2 * min(a, b); 27 | end 28 | end 29 | end 30 | case N/2 31 | for i_layer = m - 1 : -1 : 0 32 | index_1 = lambda_offset(i_layer + 1); 33 | if i_layer == (m - 1) 34 | for beta = 0 : index_1 - 1 35 | a = llr(2 * beta + 1); 36 | b = llr(2 * beta + 2); 37 | P(beta + index_1) = (1 - 2 * C(beta + index_1, 1)) * a + b; 38 | end 39 | else 40 | for beta = index_1 : 2 * index_1 - 1 41 | sign_1 = sign(P(2 * beta)); 42 | sign_2 = sign(P(2 * beta + 1)); 43 | a = abs(P(2 * beta)); 44 | b = abs(P(2 * beta + 1)); 45 | P(beta) = sign_1 * sign_2 * min(a, b); 46 | end 47 | end 48 | end 49 | otherwise 50 | layer = llr_layer_vec(phi + 1); 51 | for i_layer = layer: -1 : 0 52 | index_1 = lambda_offset(i_layer + 1); 53 | switch i_layer 54 | case layer 55 | for beta = index_1 : 2 * index_1 - 1 56 | P(beta) = (1 - 2 * C(beta, 1)) * P(2 * beta) + P(2 * beta + 1); 57 | end 58 | otherwise 59 | for beta = index_1 : 2 * index_1 - 1 60 | sign_1 = sign(P(2 * beta)); 61 | sign_2 = sign(P(2 * beta + 1)); 62 | a = abs(P(2 * beta)); 63 | b = abs(P(2 * beta + 1)); 64 | P(beta) = sign_1 * sign_2 * min(a, b); 65 | end 66 | end 67 | end 68 | end 69 | 70 | phi_mod_2 = mod(phi, 2); 71 | 72 | C(1, 1 + phi_mod_2) = dummy_info(phi + 1); 73 | 74 | if ((P(1) < 0) && (dummy_info(phi + 1) == 0)) || ((P(1) >= 0) && (dummy_info(phi + 1) == 1)) 75 | ber(phi + 1) = 1; 76 | end 77 | 78 | 79 | if (phi_mod_2) == 1 && (phi ~= (N - 1)) 80 | layer = bit_layer_vec(phi + 1); 81 | for i_layer = 0 : layer 82 | index_1 = lambda_offset(i_layer + 1); 83 | if i_layer == layer 84 | for beta = index_1 : 2 * index_1 - 1 85 | C(2 * beta, 1) = mod(C(beta, 1) + C(beta, 2), 2); 86 | C(2 * beta + 1, 1) = C(beta, 2); 87 | end 88 | else 89 | for beta = index_1 : 2 * index_1 - 1 90 | C(2 * beta, 2) = mod(C(beta, 1) + C(beta, 2), 2); 91 | C(2 * beta + 1, 2) = C(beta, 2); 92 | end 93 | end 94 | end 95 | end 96 | 97 | end 98 | end -------------------------------------------------------------------------------- /PolarFastSCL/MonteCarloCodeConstruction/my_polar_encode.m: -------------------------------------------------------------------------------- 1 | function x = my_polar_encode(u, lambda_offset, layer_vec) 2 | N = length(u); 3 | m = log2(N); 4 | C = zeros(2 * N - 1, 1); 5 | C(end - N + 1 : end) = u; 6 | x = zeros(N, 1); 7 | for phi = 0 : N - 1 8 | switch phi 9 | case 0 10 | for i_layer = m - 1 : -1 : 0 11 | index_1 = lambda_offset(i_layer + 1); 12 | for beta = index_1 : 2 * index_1 - 1 13 | C(beta) = C(2 * beta) + C(2 * beta + 1); 14 | end 15 | end 16 | otherwise 17 | layer = layer_vec(phi + 1); 18 | for i_layer = layer: -1 : 0 19 | index_1 = lambda_offset(i_layer + 1); 20 | switch i_layer 21 | case layer 22 | for beta = index_1 : 2 * index_1 - 1 23 | C(beta) = C(2 * beta + 1); 24 | end 25 | otherwise 26 | for beta = index_1 : 2 * index_1 - 1 27 | C(beta) = C(2 * beta) + C(2 * beta + 1); 28 | end 29 | end 30 | end 31 | end 32 | x(phi + 1) = C(1); 33 | end 34 | x = mod(x, 2); 35 | end -------------------------------------------------------------------------------- /PolarFastSCL/NodeDecoding/Fast List Decoders for Polar Codes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarFastSCL/NodeDecoding/Fast List Decoders for Polar Codes.pdf -------------------------------------------------------------------------------- /PolarFastSCL/NodeDecoding/Rate1.m: -------------------------------------------------------------------------------- 1 | function [PM, activepath, candidate_codeword, lazy_copy] = Rate1(M, LLR_array, activepath, PM, L, lazy_copy) 2 | candidate_codeword = zeros(M, L); 3 | llr_ordered = zeros(M, L); 4 | sub_lazy_copy = 1 : L;%lazy_copy used in this function. 5 | for l_index = 1 : L 6 | if activepath(l_index) == 0 7 | continue; 8 | end 9 | %sort length-Nv LLR in its absolute value. 10 | [~, llr_ordered(:, l_index)] = sort(abs(LLR_array(:, l_index))); 11 | candidate_codeword(:, l_index) = LLR_array(:, l_index) < 0;%ML codeword loaded 12 | end 13 | for i_split = 1 : min(M, L - 1)%number of splits in codeword sense 14 | PM_rate_1 = realmax * ones(2, L); 15 | compare_rate_1 = zeros(2, L); 16 | for l_index = 1 : L 17 | if activepath(l_index) == 0 18 | continue; 19 | end 20 | PM_rate_1(1, l_index) = PM(l_index); 21 | %the first row remains the same. 22 | PM_rate_1(2, l_index) = PM(l_index) + abs(LLR_array(llr_ordered(i_split, sub_lazy_copy(l_index)), sub_lazy_copy(l_index))); 23 | %the 2nd row is penalized. 24 | end 25 | num_surviving_path = min(L, 2 * sum(activepath)); 26 | PM_sorted = sort(PM_rate_1(:)); 27 | PM_cv = PM_sorted(num_surviving_path); 28 | cnt = 0; 29 | for j = 1 : L 30 | for i = 1 : size(PM_rate_1, 1) %****CAUTION!!!***** 31 | if cnt == num_surviving_path 32 | break; 33 | end 34 | if PM_rate_1(i, j) <= PM_cv 35 | compare_rate_1(i, j) = 1; 36 | cnt = cnt + 1; 37 | end 38 | end 39 | end 40 | kill_index = zeros(L, 1); 41 | kill_cnt = 0; 42 | for l_index = 1 : L 43 | if sum(compare_rate_1(:, l_index)) == 0 44 | activepath(l_index) = 0; 45 | kill_cnt = kill_cnt + 1;%push stack 46 | kill_index(kill_cnt) = l_index; 47 | end 48 | end 49 | for l_index = 1 : L 50 | if activepath(l_index) == 0 51 | continue 52 | end 53 | if sum(compare_rate_1(:, l_index)) == 2 54 | new_index = kill_index(kill_cnt); 55 | kill_cnt = kill_cnt - 1; 56 | activepath(new_index) = 1; 57 | sub_lazy_copy(new_index) = sub_lazy_copy(l_index); 58 | codeword_tmp = candidate_codeword(:, l_index); 59 | codeword_tmp(llr_ordered(i_split, sub_lazy_copy(l_index))) = mod(codeword_tmp(llr_ordered(i_split, sub_lazy_copy(l_index))) + 1, 2); 60 | candidate_codeword(:, new_index) = codeword_tmp; 61 | PM(new_index) = PM(l_index) + abs(LLR_array(llr_ordered(i_split, sub_lazy_copy(l_index)), sub_lazy_copy(l_index)));%PM updated 62 | end 63 | end 64 | end 65 | for l_index = 1 : L 66 | if activepath(l_index) == 0 67 | continue 68 | end 69 | lazy_copy(:, l_index) = lazy_copy(:, sub_lazy_copy(l_index)); 70 | end 71 | end -------------------------------------------------------------------------------- /PolarFastSCL/NodeDecoding/Rep.m: -------------------------------------------------------------------------------- 1 | function [PM, activepath, lazy_copy, candidate_codeword] = Rep(PM, LLR_array, activepath, L, M, lazy_copy) 2 | num_surviving_path = min(L, 2 * sum(activepath)); 3 | PM_pair = realmax * ones(2, L); 4 | %In rep node, one exsiting path generates two candidates 5 | candidate_codeword = zeros(M, L); 6 | for l_index = 1 : L 7 | if activepath(l_index) == 0 8 | continue; 9 | end 10 | Delta0 = 0; 11 | Delta1 = 0; 12 | for i_llr = 1 : M 13 | if LLR_array(i_llr, l_index) < 0 14 | Delta0 = Delta0 - LLR_array(i_llr, l_index); 15 | else 16 | Delta1 = Delta1 + LLR_array(i_llr, l_index); 17 | end 18 | end 19 | PM_pair(1, l_index) = PM(l_index) + Delta0; 20 | PM_pair(2, l_index) = PM(l_index) + Delta1; 21 | end 22 | PM_sort = sort(PM_pair(:)); 23 | PM_cv = PM_sort(num_surviving_path); 24 | compare = zeros(2, L); 25 | cnt = 0; 26 | for j = 1 : L 27 | for i = 1 : 2 28 | if cnt == num_surviving_path 29 | break; 30 | end 31 | if PM_pair(i, j) <= PM_cv 32 | compare(i, j) = 1; 33 | cnt = cnt + 1; 34 | end 35 | end 36 | end 37 | kill_index = zeros(L, 1); 38 | kill_cnt = 0; 39 | for i = 1 : L 40 | if (compare(1, i) == 0)&&(compare(2, i) == 0) 41 | %indicates that this path should be killed 42 | activepath(i) = 0; 43 | kill_cnt = kill_cnt + 1;%push stack 44 | kill_index(kill_cnt) = i; 45 | end 46 | end 47 | 48 | for l_index = 1 : L 49 | if sum(compare(:, l_index)) == 0 50 | continue; 51 | end 52 | path_state = compare(1, l_index) * 2 + compare(2, l_index); 53 | switch path_state 54 | case 1 55 | candidate_codeword(:, l_index) = 1; 56 | PM(l_index) = PM_pair(2, l_index); 57 | case 2 58 | PM(l_index) = PM_pair(1, l_index);%initilized values are 0s, so no update here. 59 | case 3 60 | new_index = kill_index(kill_cnt); 61 | kill_cnt = kill_cnt - 1; 62 | activepath(new_index) = 1; 63 | lazy_copy(:, new_index) = lazy_copy(:, l_index); 64 | candidate_codeword(:, new_index) = 1; 65 | PM(l_index) = PM_pair(1, l_index); 66 | PM(new_index) = PM_pair(2, l_index); 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /PolarFastSCL/NodeDecoding/SPC.m: -------------------------------------------------------------------------------- 1 | function [PM, activepath, candidate_codeword, lazy_copy] = SPC(index_vec, LLR_array, activepath, PM, L, lazy_copy) 2 | M = length(index_vec); 3 | candidate_codeword = zeros(M, L); 4 | llr_ordered = zeros(M, L); 5 | parity_check_track = zeros(L, 1); %caution, default value must be 0s. 6 | sub_lazy_copy = 1 : L;%Lazy copy used in this function 7 | for l_index = 1 : L 8 | if activepath(l_index) == 0 9 | continue; 10 | end 11 | abs_LLR = abs(LLR_array(:, l_index)); 12 | [~, llr_ordered(:, l_index)] = sort(abs_LLR);%Ascending sorting 13 | candidate_codeword(:, l_index) = LLR_array(:, l_index) < 0;%quasi-ML codeword 14 | if mod(sum(candidate_codeword(:, l_index)), 2) == 1 %Do not satisfy parity check 15 | candidate_codeword(llr_ordered(1, l_index), l_index) = mod(candidate_codeword(llr_ordered(1, l_index), l_index) + 1, 2); 16 | %Least reliable Bit flip 17 | parity_check_track(l_index) = 1;%initialize parity check 18 | PM(l_index) = PM(l_index) + abs_LLR(llr_ordered(1, l_index)); 19 | %PM changes accordingly. 20 | end 21 | end 22 | for t = 2 : min(M, L) 23 | PM_spc = realmax * ones(2, L); 24 | compare_spc = zeros(2, L); 25 | for l_index = 1 : L 26 | if activepath(l_index) == 0 27 | continue; 28 | end 29 | LLR = LLR_array(:, sub_lazy_copy(l_index)); 30 | PM_spc(1, l_index) = PM(l_index); %remain the same as original path 31 | PM_spc(2, l_index) = PM(l_index) + abs(LLR(llr_ordered(t, sub_lazy_copy(l_index)))) + (1 - 2 * parity_check_track(l_index)) * abs(LLR(llr_ordered(1, sub_lazy_copy(l_index)))); 32 | end 33 | num_surviving_path = min(L, 2 * sum(activepath)); 34 | PM_sorted = sort(PM_spc(:)); 35 | PM_cv = PM_sorted(num_surviving_path); 36 | cnt = 0; 37 | for j = 1 : L 38 | for i = 1 : size(PM_spc, 1) %****CAUTION!!!***** 39 | if cnt == num_surviving_path 40 | break; 41 | end 42 | if PM_spc(i, j) <= PM_cv 43 | compare_spc(i, j) = 1; 44 | cnt = cnt + 1; 45 | end 46 | end 47 | end 48 | kill_index = zeros(L, 1); 49 | kill_cnt = 0; 50 | for i = 1 : L 51 | if all(compare_spc(:, i) == 0) 52 | activepath(i) = 0; 53 | kill_cnt = kill_cnt + 1;%push stack 54 | kill_index(kill_cnt) = i; 55 | end 56 | end 57 | for l_index = 1 : L 58 | if activepath(l_index) == 0 59 | continue 60 | end 61 | path_state = sum(compare_spc(:, l_index)); 62 | switch path_state 63 | case 2 64 | new_index = kill_index(kill_cnt); 65 | kill_cnt = kill_cnt - 1; 66 | activepath(new_index) = 1; 67 | sub_lazy_copy(new_index) = sub_lazy_copy(l_index); 68 | %generate a new sub-codeword 69 | codeword_tmp = candidate_codeword(:, l_index); 70 | codeword_tmp(llr_ordered(t, sub_lazy_copy(l_index))) = mod(codeword_tmp(llr_ordered(t, sub_lazy_copy(l_index))) + 1, 2);%t-th index (after llr sorting) 71 | codeword_tmp(llr_ordered(1, sub_lazy_copy((l_index)))) = mod(codeword_tmp(llr_ordered(1, sub_lazy_copy(l_index))) + 1, 2);%1-st index always 72 | candidate_codeword(:, new_index) = codeword_tmp; 73 | parity_check_track(new_index) = mod(parity_check_track(l_index) + 1, 2); 74 | %When you split path, the parity check sign should be fliped accordingly. 75 | PM(new_index) = PM_spc(2, l_index);%PM updated 76 | end 77 | end 78 | end 79 | for l_index = 1 : L 80 | if activepath(l_index) == 0 81 | continue 82 | end 83 | lazy_copy(:, l_index) = lazy_copy(:, sub_lazy_copy(l_index)); 84 | end 85 | end -------------------------------------------------------------------------------- /PolarFastSCL/NodeProcess/Fast Successive-Cancellation Decoding of Polar Codes Identification and Decoding of New Nodes .pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarFastSCL/NodeProcess/Fast Successive-Cancellation Decoding of Polar Codes Identification and Decoding of New Nodes .pdf -------------------------------------------------------------------------------- /PolarFastSCL/NodeProcess/FastSCdecoder.m: -------------------------------------------------------------------------------- 1 | function polar_info_esti = FastSCdecoder(llr, info_bits, node_type_structure, lambda_offset, llr_layer_vec, psi_vec, bit_layer_vec) 2 | N = length(llr); 3 | n = log2(N); 4 | C = zeros(2 * N - 1, 2);%Bit vector 5 | P = zeros(2 * N - 1, 1);%LLR vector 6 | P(end - N + 1 : end) = llr;%LLR initialization 7 | for i_node = 1 : size(node_type_structure, 1) 8 | M = node_type_structure(i_node, 2);%size of subcode 9 | reduced_layer = log2(M); 10 | %reduced_layer denotes where to stop LLR calculation 11 | %reduced_layer also denotes where to start Internal Bits calculation. 12 | llr_layer = llr_layer_vec(node_type_structure(i_node, 1)); 13 | %llr_layer denotes where to start LLR calculation 14 | bit_layer = bit_layer_vec(node_type_structure(i_node, 1) + M - 1); 15 | %bit_layer denotes where to stop Internal Bits calculation. 16 | psi = psi_vec(i_node);%This psi is used for bits recursion 17 | psi_mod_2 = mod(psi, 2); 18 | if i_node == 1%first LLR calculation only uses f function. 19 | for i_layer = n - 1 : -1 : reduced_layer 20 | index_1 = lambda_offset(i_layer + 1); 21 | index_2 = lambda_offset(i_layer + 2); 22 | for beta = index_1 : index_2 - 1 23 | P(beta) = sign(P(beta + index_1)) * sign(P(beta + index_2)) * min(abs(P(beta + index_1)), abs(P(beta + index_2))); 24 | end 25 | end 26 | else 27 | index_1 = lambda_offset(llr_layer + 1); 28 | index_2 = lambda_offset(llr_layer + 2); 29 | for beta = index_1 : index_2 - 1 30 | P(beta) = (1 - 2 * C(beta, 1)) * P(beta + index_1) + P(beta + index_2); 31 | end 32 | for i_layer = llr_layer - 1 : -1 : reduced_layer 33 | index_1 = lambda_offset(i_layer + 1); 34 | index_2 = lambda_offset(i_layer + 2); 35 | for beta = index_1 : index_2 - 1 36 | P(beta) = sign(P(beta + index_1)) * sign(P(beta + index_2)) * min(abs(P(beta + index_1)), abs(P(beta + index_2))); 37 | end 38 | end 39 | end 40 | switch node_type_structure(i_node, 3) 41 | case -1%RATE 0 42 | for j = M : 2 * M - 1 43 | C(j, psi_mod_2 + 1) = 0; 44 | end 45 | case 1%RATE 1 46 | for j = M : 2 * M - 1 47 | C(j, psi_mod_2 + 1) = P(j) < 0; 48 | end 49 | case 2%REP 50 | sum_llr = 0; 51 | for j = M : 2 * M - 1 52 | sum_llr = sum_llr + P(j); 53 | end 54 | rep_bit = sum_llr < 0; 55 | for j = M : 2 * M - 1 56 | C(j, psi_mod_2 + 1) = rep_bit; 57 | end 58 | case 3%spc 59 | llr_sub_polar_code = zeros(M, 1); 60 | for j = M : 2 * M - 1 61 | llr_sub_polar_code(j - M + 1) = P(j); 62 | end 63 | x = llr_sub_polar_code < 0; 64 | if mod(sum(x), 2) ~= 0%if SPC constraint is ont satisfied 65 | alpha_plus = abs(llr_sub_polar_code); 66 | [~, min_index] = min(alpha_plus); 67 | x(min_index) = mod(x(min_index) + 1, 2); 68 | end 69 | for j = M : 2 * M - 1 70 | C(j, psi_mod_2 + 1) = x(j - M + 1); 71 | end 72 | end 73 | if psi_mod_2 == 1%bit recursion 74 | for i_layer = reduced_layer : bit_layer - 1 75 | index_1 = lambda_offset(i_layer + 1); 76 | index_2 = lambda_offset(i_layer + 2); 77 | for beta = index_1 : index_2 - 1 78 | C(beta + index_1, 2) = mod(C(beta, 1) + C(beta, 2), 2); 79 | C(beta + index_2, 2) = C(beta, 2); 80 | end 81 | end 82 | index_1 = lambda_offset(bit_layer + 1); 83 | index_2 = lambda_offset(bit_layer + 2); 84 | for beta = index_1 : index_2 - 1 85 | C(beta + index_1, 1) = mod(C(beta, 1) + C(beta, 2), 2); 86 | C(beta + index_2, 1) = C(beta, 2); 87 | end 88 | end 89 | end 90 | x = C(end - N + 1 : end, 1); 91 | polar_info_esti = x(info_bits); 92 | end -------------------------------------------------------------------------------- /PolarFastSCL/NodeProcess/get_node_structure.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarFastSCL/NodeProcess/get_node_structure.m -------------------------------------------------------------------------------- /PolarFastSCL/NodeProcess/get_psi_for_advanced_sc_decoder.m: -------------------------------------------------------------------------------- 1 | function psi_vec = get_psi_for_advanced_sc_decoder(node_type_matrix) 2 | psi_vec = zeros(size(node_type_matrix, 1), 1); 3 | for i = 1 : length(psi_vec) 4 | psi = node_type_matrix(i, 1); 5 | M = node_type_matrix(i, 2); 6 | reduced_layer = log2(M); 7 | for j = 1 : reduced_layer 8 | psi = floor(psi/2); 9 | end 10 | psi_vec(i) = psi; 11 | end 12 | end -------------------------------------------------------------------------------- /PolarFastSCL/NodeProcess/node_identifier.m: -------------------------------------------------------------------------------- 1 | function node_identifier(f, z) 2 | N = length(f); 3 | global code_structure cnt_structure 4 | if all(f(1 : end - 1) == 1) && (f(end) == 0)%REP 5 | code_structure(cnt_structure, 1) = z(1); 6 | code_structure(cnt_structure, 2) = N; 7 | code_structure(cnt_structure, 3) = 2; 8 | cnt_structure = cnt_structure + 1; 9 | else 10 | if (f(1) == 1) && all(f(2 : end) == 0)%SPC 11 | code_structure(cnt_structure, 1) = z(1); 12 | code_structure(cnt_structure, 2) = N; 13 | code_structure(cnt_structure, 3) = 3; 14 | cnt_structure = cnt_structure + 1; 15 | else 16 | if all(f == 0)%R1 17 | code_structure(cnt_structure, 1) = z(1); 18 | code_structure(cnt_structure, 2) = N; 19 | code_structure(cnt_structure, 3) = 1; 20 | cnt_structure = cnt_structure + 1; 21 | else 22 | if all(f == 1)%R0 23 | code_structure(cnt_structure, 1) = z(1); 24 | code_structure(cnt_structure, 2) = N; 25 | code_structure(cnt_structure, 3) = -1; 26 | cnt_structure = cnt_structure + 1; 27 | else 28 | node_identifier(f(1:N/2), z(1:N/2)); 29 | node_identifier(f(N/2+1:end), z(N/2+1:end)); 30 | end 31 | end 32 | end 33 | end 34 | end -------------------------------------------------------------------------------- /PolarFastSCL/PolarizaedChannelsPartialOrder/EPW.m: -------------------------------------------------------------------------------- 1 | function channels = EPW(N, beta) 2 | m = log2(N); 3 | channels = zeros(N, 1); 4 | for i = 0 : N - 1 5 | bin_seq_str = dec2bin(i, m); 6 | bin_seq = zeros(m, 1); 7 | for j = 1 : m 8 | if bin_seq_str(j) == '1' 9 | bin_seq(j) = 1; 10 | end 11 | end 12 | bin_seq = bin_seq(m : -1 : 1); 13 | sum = 0; 14 | for j = 1 : m 15 | if m >= 9 16 | sum = sum + bin_seq(j) * (beta^(j - 1) + 0.221 * 0.9889^(j - 1) - bin_seq(9) * 0.0371 * 0.5759^(j - 1) - bin_seq(8) * 0.047 * 0.4433^(j - 1)); 17 | else 18 | if m == 8 19 | sum = sum + bin_seq(j) * (beta^(j - 1) + 0.221 * 0.9889^(j - 1) - bin_seq(8) * 0.047 * 0.4433^(j - 1)); 20 | else 21 | sum = sum + bin_seq(j) * (beta^(j - 1) + 0.221 * 0.9889^(j - 1)); 22 | end 23 | end 24 | end 25 | channels(i + 1) = sum; 26 | end 27 | end -------------------------------------------------------------------------------- /PolarFastSCL/PolarizaedChannelsPartialOrder/HPW.m: -------------------------------------------------------------------------------- 1 | function channels = HPW(N, beta) 2 | m = log2(N); 3 | channels = zeros(N, 1); 4 | for i = 0 : N - 1 5 | bin_seq = dec2bin(i, m); 6 | sum = 0; 7 | for j = 1 : m 8 | if bin_seq(j) == '1' 9 | sum = sum + (beta^(m - j) + 0.25 * beta ^ (0.25 * (m - j))); 10 | end 11 | end 12 | channels(i + 1) = sum; 13 | end 14 | end -------------------------------------------------------------------------------- /PolarFastSCL/PolarizaedChannelsPartialOrder/PW.m: -------------------------------------------------------------------------------- 1 | function channels = PW(N, beta) 2 | m = log2(N); 3 | channels = zeros(N, 1); 4 | for i = 0 : N - 1 5 | bin_seq = dec2bin(i, m); 6 | sum = 0; 7 | for j = 1 : m 8 | if bin_seq(j) == '1' 9 | sum = sum + beta^(m - j); 10 | end 11 | end 12 | channels(i + 1) = sum; 13 | end 14 | end -------------------------------------------------------------------------------- /PolarFastSCL/PolarizaedChannelsPartialOrder/Polarization Weight Family Methods fo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarFastSCL/PolarizaedChannelsPartialOrder/Polarization Weight Family Methods fo.pdf -------------------------------------------------------------------------------- /PolarFastSCL/PolarizaedChannelsPartialOrder/Recursive Construction of Polar Codes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarFastSCL/PolarizaedChannelsPartialOrder/Recursive Construction of Polar Codes.pdf -------------------------------------------------------------------------------- /PolarFastSCL/PolarizaedChannelsPartialOrder/partial_order_polarized_channels.m: -------------------------------------------------------------------------------- 1 | function UPO = partial_order_polarized_channels(N) 2 | %N is code length, power of 2. UPO = Univeral partial order 3 | m = log2(N); 4 | max_connection = 32; 5 | UPO = zeros(N, max_connection); 6 | UPO(1, 1) = 1; 7 | % Partial order construction 8 | for layer = 2 : m 9 | N_tmp = 2^layer; 10 | UPO_tmp = UPO(1 : N_tmp/2, :); 11 | for i = 1 : N_tmp/2 12 | for j = 1 : max_connection 13 | if UPO_tmp(i, j) == 0 14 | break; 15 | else 16 | UPO_tmp(i, j) = UPO_tmp(i, j) + N_tmp/2; 17 | end 18 | end 19 | end 20 | UPO(N_tmp/2 + 1 : N_tmp, :) = UPO_tmp; 21 | for i = N_tmp/4 + 1 : N_tmp/2 22 | for j = 1 : max_connection 23 | if UPO(i, j) == 0 24 | UPO(i, j) = (i - 1) + N_tmp/4; 25 | break; 26 | end 27 | end 28 | end 29 | end 30 | %Delete redundant all zero columns 31 | while(all(UPO(:, end) == 0)) 32 | UPO(:, end) = []; 33 | end -------------------------------------------------------------------------------- /PolarFastSCL/SC_decoder.m: -------------------------------------------------------------------------------- 1 | function u_hat = SC_decoder(llr, frozen_bits, lambda_offset, llr_layer_vec, bit_layer_vec, info_bits) 2 | N = length(llr);%llr refers to channel LLR. 3 | n = log2(N); 4 | P = zeros(N - 1, 1);%channel llr is not include in P. 5 | %P stores internal LLRs, P(1) is used for decision. 6 | C = zeros(2 * N - 1, 2);%C stores internal bit values 7 | for phi = 0 : N - 1 8 | switch phi 9 | case 0%for decoding u_1 10 | index_1 = lambda_offset(n); 11 | for beta = 0 : index_1 - 1%use llr vector 12 | P(beta + index_1) = sign(llr(beta + 1)) * sign(llr(beta + 1 + index_1)) * min(abs(llr(beta + 1)), abs(llr(beta + 1 + index_1))); 13 | end 14 | for i_layer = n - 2 : -1 : 0%use P vector 15 | index_1 = lambda_offset(i_layer + 1); 16 | index_2 = lambda_offset(i_layer + 2); 17 | for beta = index_1 : index_2 - 1 18 | P(beta) = sign(P(beta + index_1)) * sign(P(beta + index_2)) * min(abs(P(beta + index_1)), abs(P(beta + index_2))); 19 | end 20 | end 21 | case N/2%for deocding u_{N/2 + 1} 22 | index_1 = lambda_offset(n); 23 | for beta = 0 : index_1 - 1%use llr vector. g function. 24 | P(beta + index_1) = (1 - 2 * C(beta + index_1, 1)) * llr(beta + 1) + llr(beta + 1 + index_1); 25 | end 26 | for i_layer = n - 2 : -1 : 0%use P vector. f function 27 | index_1 = lambda_offset(i_layer + 1); 28 | index_2 = lambda_offset(i_layer + 2); 29 | for beta = index_1 : index_2 - 1 30 | P(beta) = sign(P(beta + index_1)) * sign(P(beta + index_2)) * min(abs(P(beta + index_1)), abs(P(beta + index_2))); 31 | end 32 | end 33 | otherwise 34 | llr_layer = llr_layer_vec(phi + 1); 35 | index_1 = lambda_offset(llr_layer + 1); 36 | index_2 = lambda_offset(llr_layer + 2); 37 | for beta = index_1 : index_2 - 1%g function is first implemented. 38 | P(beta) = (1 - 2 * C(beta, 1)) * P(beta + index_1) + P(beta + index_2); 39 | end 40 | for i_layer = llr_layer - 1 : -1 : 0%then f function is implemented. 41 | index_1 = lambda_offset(i_layer + 1); 42 | index_2 = lambda_offset(i_layer + 2); 43 | for beta = index_1 : index_2 - 1 44 | P(beta) = sign(P(beta + index_1)) * sign(P(beta + index_2)) * min(abs(P(beta + index_1)), abs(P(beta + index_2))); 45 | end 46 | end 47 | end 48 | phi_mod_2 = mod(phi, 2); 49 | if frozen_bits(phi + 1) == 1%frozen bit 50 | C(1, 1 + phi_mod_2) = 0; 51 | else%information bit 52 | C(1, 1 + phi_mod_2) = P(1) < 0;%store internal bit values 53 | end 54 | if phi_mod_2 == 1%whether to perform bit recursion ? 55 | bit_layer = bit_layer_vec(phi + 1); 56 | for i_layer = 0 : bit_layer - 1%give values to the 2nd column of C 57 | index_1 = lambda_offset(i_layer + 1); 58 | index_2 = lambda_offset(i_layer + 2); 59 | for beta = index_1 : index_2 - 1 60 | C(beta + index_1, 2) = mod(C(beta, 1) + C(beta, 2), 2); 61 | C(beta + index_2, 2) = C(beta, 2); 62 | end 63 | end 64 | index_1 = lambda_offset(bit_layer + 1); 65 | index_2 = lambda_offset(bit_layer + 2); 66 | for beta = index_1 : index_2 - 1%give values to the 1st column of C 67 | C(beta + index_1, 1) = mod(C(beta, 1) + C(beta, 2), 2); 68 | C(beta + index_2, 1) = C(beta, 2); 69 | end 70 | end 71 | end 72 | x_hat = C(end - N + 1 : end, 1); 73 | u_hat = x_hat(info_bits); 74 | end -------------------------------------------------------------------------------- /PolarFastSCL/SystematicPolarEncoders/Flexible and Low-Complexity Encoding and Decoding of Systematic Polar Codes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarFastSCL/SystematicPolarEncoders/Flexible and Low-Complexity Encoding and Decoding of Systematic Polar Codes.pdf -------------------------------------------------------------------------------- /PolarFastSCL/SystematicPolarEncoders/SC_systematic_encoder.m: -------------------------------------------------------------------------------- 1 | function x_hat = SC_systematic_encoder(llr, frozen_bits, lambda_offset, llr_layer_vec, bit_layer_vec) 2 | N = length(llr);%llr refers to channel LLR. 3 | n = log2(N); 4 | P = zeros(N - 1, 1);%channel llr is not include in P. 5 | %P stores internal LLRs, P(1) is used for decision. 6 | C = zeros(2 * N - 1, 2);%C stores internal bit values 7 | for phi = 0 : N - 1 8 | switch phi 9 | case 0%for decoding u_1 10 | index_1 = lambda_offset(n); 11 | for beta = 0 : index_1 - 1%use llr vector 12 | P(beta + index_1) = sign(llr(beta + 1)) * sign(llr(beta + 1 + index_1)) * min(abs(llr(beta + 1)), abs(llr(beta + 1 + index_1))); 13 | end 14 | for i_layer = n - 2 : -1 : 0%use P vector 15 | index_1 = lambda_offset(i_layer + 1); 16 | index_2 = lambda_offset(i_layer + 2); 17 | for beta = index_1 : index_2 - 1 18 | P(beta) = sign(P(beta + index_1)) * sign(P(beta + index_2)) * min(abs(P(beta + index_1)), abs(P(beta + index_2))); 19 | end 20 | end 21 | case N/2%for deocding u_{N/2 + 1} 22 | index_1 = lambda_offset(n); 23 | for beta = 0 : index_1 - 1%use llr vector. g function. 24 | P(beta + index_1) = (1 - 2 * C(beta + index_1, 1)) * llr(beta + 1) + llr(beta + 1 + index_1); 25 | end 26 | for i_layer = n - 2 : -1 : 0%use P vector. f function 27 | index_1 = lambda_offset(i_layer + 1); 28 | index_2 = lambda_offset(i_layer + 2); 29 | for beta = index_1 : index_2 - 1 30 | P(beta) = sign(P(beta + index_1)) * sign(P(beta + index_2)) * min(abs(P(beta + index_1)), abs(P(beta + index_2))); 31 | end 32 | end 33 | otherwise 34 | llr_layer = llr_layer_vec(phi + 1); 35 | index_1 = lambda_offset(llr_layer + 1); 36 | index_2 = lambda_offset(llr_layer + 2); 37 | for beta = index_1 : index_2 - 1%g function is first implemented. 38 | P(beta) = (1 - 2 * C(beta, 1)) * P(beta + index_1) + P(beta + index_2); 39 | end 40 | for i_layer = llr_layer - 1 : -1 : 0%then f function is implemented. 41 | index_1 = lambda_offset(i_layer + 1); 42 | index_2 = lambda_offset(i_layer + 2); 43 | for beta = index_1 : index_2 - 1 44 | P(beta) = sign(P(beta + index_1)) * sign(P(beta + index_2)) * min(abs(P(beta + index_1)), abs(P(beta + index_2))); 45 | end 46 | end 47 | end 48 | phi_mod_2 = mod(phi, 2); 49 | if frozen_bits(phi + 1) == 1%frozen bit 50 | C(1, 1 + phi_mod_2) = 0; 51 | else%information bit 52 | C(1, 1 + phi_mod_2) = P(1) < 0;%store internal bit values 53 | end 54 | if phi_mod_2 == 1%whether to perform bit recursion ? 55 | bit_layer = bit_layer_vec(phi + 1); 56 | for i_layer = 0 : bit_layer - 1%give values to the 2nd column of C 57 | index_1 = lambda_offset(i_layer + 1); 58 | index_2 = lambda_offset(i_layer + 2); 59 | for beta = index_1 : index_2 - 1 60 | C(beta + index_1, 2) = mod(C(beta, 1) + C(beta, 2), 2); 61 | C(beta + index_2, 2) = C(beta, 2); 62 | end 63 | end 64 | index_1 = lambda_offset(bit_layer + 1); 65 | index_2 = lambda_offset(bit_layer + 2); 66 | for beta = index_1 : index_2 - 1%give values to the 1st column of C 67 | C(beta + index_1, 1) = mod(C(beta, 1) + C(beta, 2), 2); 68 | C(beta + index_2, 1) = C(beta, 2); 69 | end 70 | end 71 | end 72 | x_hat = C(end - N + 1 : end, 1); 73 | end -------------------------------------------------------------------------------- /PolarFastSCL/SystematicPolarEncoders/Systematic Polar Coding.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/PolarFastSCL/SystematicPolarEncoders/Systematic Polar Coding.pdf -------------------------------------------------------------------------------- /PolarFastSCL/SystematicPolarEncoders/arikan_recursive_systematic_polar_encoder.m: -------------------------------------------------------------------------------- 1 | function x = arikan_recursive_systematic_polar_encoder(input_vec, info_bits) 2 | %info_bits is an N*1 vector. info_bits(i) = 1 means u_i is an 3 | %information bit, otherwise a frozen bit. 4 | 5 | %part 1: input_vec(info_bits) is information bit vec. 6 | 7 | %part 2: input_vec(frozen_bits) can be initilaized arbitrarily. The value 8 | %of input_vec(frozen_bits) does not affect encoding, even if 9 | %input_vec(frozen_bits) is NaN. 10 | 11 | %Arikan's recursive method 12 | %although this method is low-complexity, it is not that good for MATLAB 13 | %implementation. It is too slow. 14 | N = length(info_bits); 15 | sum_info_bits = sum(info_bits); 16 | switch sum_info_bits 17 | case N 18 | x = input_vec; 19 | case 0 20 | x = zeros(N, 1); 21 | otherwise 22 | index_1 = 1 : N/2; 23 | index_2 = N/2 + 1 : N; 24 | A1 = info_bits(index_1); 25 | A2 = info_bits(index_2); 26 | input_vec_1 = input_vec(index_1);%the first half 27 | input_vec_2 = input_vec(index_2);%the second half 28 | x2 = arikan_recursive_systematic_polar_encoder(input_vec_2, A2); 29 | input_vec_1 = mod(input_vec_1 + x2, 2); 30 | x1 = arikan_recursive_systematic_polar_encoder(input_vec_1, A1); 31 | x1 = mod(x1 + x2, 2); 32 | x = [x1; x2]; 33 | end 34 | end 35 | 36 | -------------------------------------------------------------------------------- /PolarFastSCL/SystematicPolarEncoders/arikan_sc_systematic_polar_encoder.m: -------------------------------------------------------------------------------- 1 | function x = arikan_sc_systematic_polar_encoder(u, frozen_bits, info_bits, lambda_offset, llr_layer_vec, bit_layer_vec) 2 | N = length(frozen_bits); 3 | y = zeros(N, 1); 4 | llr = 1 - 2 * u; 5 | y(info_bits) = llr; 6 | x = SC_systematic_encoder(y, frozen_bits, lambda_offset, llr_layer_vec, bit_layer_vec); 7 | end 8 | 9 | -------------------------------------------------------------------------------- /PolarFastSCL/SystematicPolarEncoders/sarkis_systematic_polar_encoder.m: -------------------------------------------------------------------------------- 1 | function x = sarkis_systematic_polar_encoder(u, info_bits, frozen_bits, N, lambda_offset, llr_layer_vec) 2 | x = zeros(N, 1); 3 | %First step encoding 4 | x(info_bits) = u; 5 | x = polar_encoder(x, lambda_offset, llr_layer_vec); 6 | %Second step encoding 7 | x(frozen_bits) = 0; 8 | x = polar_encoder(x, lambda_offset, llr_layer_vec); 9 | end 10 | 11 | -------------------------------------------------------------------------------- /PolarFastSCL/bler.m: -------------------------------------------------------------------------------- 1 | % Sim iteration running = 770001 2 | % N = 1024 K = 528 3 | % List size = 1 8 16 32 4 | % Current block error performance 5 | % 1 0.8221 0.33557 0.25189 0.18727 6 | % 1.25 0.67502 0.14903 0.087642 0.064226 7 | % 1.5 0.49319 0.053022 0.034471 0.020016 8 | % 1.75 0.28943 0.014271 0.0059905 0.0027032 9 | % 2 0.14774 0.0026683 0.0011349 0.00043618 10 | % 2.25 0.065164 0.00051471 0.00011558 3.8961e-05 11 | % 2.5 0.025055 5.4545e-05 1.4286e-05 3.8961e-06 12 | % Current bit error performance 13 | % 1 0.10798 0.036131 0.027216 0.020365 14 | % 1.25 0.074146 0.013814 0.0079874 0.0064846 15 | % 1.5 0.047494 0.0044145 0.002821 0.0017059 16 | % 1.75 0.023615 0.0010287 0.00043738 0.00017827 17 | % 2 0.010243 0.00014074 6.1261e-05 2.5427e-05 18 | % 2.25 0.0038202 2.363e-05 6.1934e-06 2.0095e-06 19 | % 2.5 0.0012243 2.3072e-06 5.5342e-07 2.2383e-07 20 | % 21 | % Sim iteration running = 232001 22 | % N = 1024 K = 528 23 | % List size = 1 2 4 24 | % Current block error performance 25 | % 1 0.85052 0.66225 0.51546 26 | % 1.25 0.70652 0.48309 0.27174 27 | % 1.5 0.49127 0.2584 0.11641 28 | % 1.75 0.28955 0.10881 0.040667 29 | % 2 0.14897 0.043029 0.007861 30 | % 2.25 0.064858 0.010949 0.0018702 31 | % 2.5 0.024953 0.0027085 0.0003319 32 | % Current bit error performance 33 | % 1 0.11547 0.073625 0.055276 34 | % 1.25 0.078562 0.044933 0.025692 35 | % 1.5 0.046555 0.022081 0.0092933 36 | % 1.75 0.024858 0.0078334 0.0028867 37 | % 2 0.010126 0.0025263 0.00040228 38 | % 2.25 0.0037166 0.00047758 7.5515e-05 39 | % 2.5 0.0011996 9.1206e-05 1.2743e-05 40 | snr = 1 : 0.25 : 2.5; 41 | fastcscl1 = [ 0.66225 0.51546 42 | 0.48309 0.27174 43 | 0.2584 0.11641 44 | 0.10881 0.040667 45 | 0.043029 0.007861 46 | 0.010949 0.0018702 47 | 0.0027085 0.0003319]; 48 | 49 | fastcscl2 = [ 0.33557 0.25189 0.18727 50 | 0.14903 0.087642 0.064226 51 | 0.053022 0.034471 0.020016 52 | 0.014271 0.0059905 0.0027032 53 | 0.0026683 0.0011349 0.00043618 54 | 0.00051471 0.00011558 3.8961e-05 55 | 5.4545e-05 1.4286e-05 3.8961e-06]; 56 | 57 | p = semilogy(snr, [fastcscl1 fastcscl2]); 58 | grid on 59 | p(1).Marker = 'o'; 60 | p(2).Marker = 'd'; 61 | p(3).Marker = 'p'; 62 | p(4).Marker = 'v'; 63 | p(5).Marker = 's'; 64 | 65 | p(1).Color = 'r'; 66 | p(2).Color = 'g'; 67 | p(3).Color = 'm'; 68 | 69 | for k = 1 : 5 70 | p(k).MarkerSize = 8; 71 | p(k).LineWidth = 1.1; 72 | end 73 | l = legend('L = 2',... 74 | 'L = 4',... 75 | 'L = 8',... 76 | 'L = 16',... 77 | 'L = 32'); 78 | 79 | l.Location = 'SouthWest'; 80 | 81 | xlabel('E_b/N_0 (dB)') 82 | ylabel('BLER') 83 | set(gca, 'fontname', 'times new roman', 'fontsize', 16) -------------------------------------------------------------------------------- /PolarFastSCL/crc_generator_matrix.m: -------------------------------------------------------------------------------- 1 | function [G_parity_check_part, H_crc] = crc_generator_matrix(g, K) 2 | %Advanced CRC parity-check generator, space efficient version. 3 | r = length(g) - 1; 4 | last_row = g(2 : end); 5 | G_parity_check_part = zeros(K, r); 6 | G_parity_check_part(K, :) = last_row; 7 | %get non-systematic form 8 | for i_r = r - 1 : -1 : max(r - K + 1, 1) 9 | G_parity_check_part(K + i_r - r, :) = [last_row(r - i_r + 1 : end), zeros(1, r - i_r)]; 10 | end 11 | %Gaussian elimination to get systematic form 12 | last_row_of_entire_Gcrc = [zeros(1, K - 1), g]; 13 | for j = K - 1 : -1 : 1 14 | num_shift = K - j; 15 | shifted_vec = [last_row_of_entire_Gcrc(1 + num_shift : end), zeros(1, num_shift)]; 16 | for p = j + 1 : K 17 | if shifted_vec(p) == 1 18 | G_parity_check_part(j, :) = mod(G_parity_check_part(j, :) + G_parity_check_part(p, :), 2); 19 | end 20 | end 21 | end 22 | %get H_crc 23 | H_crc = [G_parity_check_part' eye(r)]; 24 | end -------------------------------------------------------------------------------- /PolarFastSCL/get_GN.m: -------------------------------------------------------------------------------- 1 | function FN = get_GN(N) 2 | F = [1, 0 ; 1, 1]; 3 | FN = zeros(N, N); 4 | FN(1 : 2, 1 : 2) = F; 5 | for i = 2 : log2(N) 6 | FN(1 : 2^i, 1 : 2^i) = kron(FN(1 : 2^(i - 1), 1 : 2^(i - 1)), F); 7 | end -------------------------------------------------------------------------------- /PolarFastSCL/get_bit_layer.m: -------------------------------------------------------------------------------- 1 | function layer_vec = get_bit_layer(N) 2 | layer_vec = zeros(N, 1); 3 | for phi = 0 : N - 1 4 | psi = floor(phi/2); 5 | layer = 0; 6 | while(mod(psi, 2) == 1) 7 | psi = floor(psi/2); 8 | layer = layer + 1; 9 | end 10 | layer_vec(phi + 1) = layer; 11 | end 12 | end -------------------------------------------------------------------------------- /PolarFastSCL/get_crc_objective.m: -------------------------------------------------------------------------------- 1 | function [gen, det, g] = get_crc_objective(crc_length) 2 | switch crc_length 3 | case 4 4 | gen = crc.generator('Polynomial',[1 0 0 1 1],'InitialState',zeros(1, 4),'FinalXOR',zeros(1, 4)); 5 | det = crc.detector('Polynomial',[1 0 0 1 1],'InitialState',zeros(1, 4),'FinalXOR',zeros(1, 4)); 6 | g = [1 0 0 1 1]; 7 | case 6 8 | gen = crc.generator('Polynomial',[1 0 0 0 0 1 1],'InitialState',zeros(1, 6),'FinalXOR',zeros(1, 6)); 9 | det = crc.detector('Polynomial',[1 0 0 0 0 1 1],'InitialState',zeros(1, 6),'FinalXOR',zeros(1, 6)); 10 | g = [1 0 0 0 0 1 1]; 11 | 12 | case 8 13 | gen = crc.generator('Polynomial','0xA6','InitialState','0x00','FinalXOR','0x00'); 14 | det = crc.detector('Polynomial','0xA6','InitialState','0x00','FinalXOR','0x00'); 15 | g = [1 0 1 0 0 1 1 0 1]; 16 | % g = [1 1 0 0 1 1 0 1 1]; %WCDMA CRC 17 | % g = [1 1 1 1 1 1 0 0 1]; 18 | case 10 19 | gen = crc.generator('Polynomial',[1 1 0 0 1 0 0 1 1 1 1],'InitialState',zeros(1, 10),'FinalXOR',zeros(1, 10)); 20 | det = crc.detector('Polynomial',[1 1 0 0 1 0 0 1 1 1 1],'InitialState',zeros(1, 10),'FinalXOR',zeros(1, 10)); 21 | g = [1 1 0 0 1 0 0 1 1 1 1]; 22 | case 12 23 | gen = crc.generator('Polynomial',[1 1 0 0 0 0 0 0 0 1 1 0 1],'InitialState',zeros(1, 12),'FinalXOR',zeros(1, 12)); 24 | det = crc.detector('Polynomial',[1 1 0 0 0 0 0 0 0 1 1 0 1],'InitialState',zeros(1, 12),'FinalXOR',zeros(1, 12)); 25 | g = [1 1 0 0 0 0 0 0 0 1 1 0 1]; 26 | case 16 27 | gen = crc.generator('Polynomial',[1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1],'InitialState',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0],'FinalXOR',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]); 28 | det = crc.detector('Polynomial',[1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1],'InitialState',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0],'FinalXOR',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]); 29 | g = [1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1]; 30 | case 24 31 | gen = crc.generator('Polynomial',[1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1],'InitialState',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0],... 32 | 'FinalXOR',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]); 33 | det = crc.detector('Polynomial',[1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1],'InitialState',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0],... 34 | 'FinalXOR',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]); 35 | g = [1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1]; 36 | case 32 37 | g = [ 1 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 1 0 ... 38 | 0 0 1 1 1 0 1 1 0 1 1 0 1 1 1]; 39 | gen = crc.generator('Polynomial',g,'InitialState',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0],... 40 | 'FinalXOR',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]); 41 | det = crc.detector('Polynomial',g,'InitialState',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0],... 42 | 'FinalXOR',[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]); 43 | otherwise 44 | disp('Unsupported CRC length. Program terminates') 45 | end -------------------------------------------------------------------------------- /PolarFastSCL/get_llr_layer.m: -------------------------------------------------------------------------------- 1 | function layer_vec = get_llr_layer(N) 2 | layer_vec = zeros(N , 1); 3 | for phi = 1 : N - 1 4 | psi = phi; 5 | layer = 0; 6 | while(mod(psi, 2) == 0) 7 | psi = floor(psi/2); 8 | layer = layer + 1; 9 | end 10 | layer_vec(phi + 1) = layer; 11 | end 12 | end -------------------------------------------------------------------------------- /PolarFastSCL/main.m: -------------------------------------------------------------------------------- 1 | clear 2 | disp('adding files....') 3 | addpath('GA/') 4 | addpath('NodeProcess/') 5 | addpath('NodeDecoding/') 6 | addpath('SystematicPolarEncoders/') 7 | addpath('PolarizaedChannelsPartialOrder/') 8 | 9 | crc_length = 16; 10 | [~, ~, g] = get_crc_objective(crc_length); 11 | design_epsilon = 0.05; 12 | n = 10; 13 | N = 2^n; 14 | K = N*0.5 + crc_length; 15 | ebno_vec = 1 : 0.25 : 2.5; %row vec, you can write it like [1 1.5 2 2.5 3] 16 | list_vec = [1 2 4]; %row vec, you can write it like [1 4 16 32 ...]. The first element is always 1 for acceleration purpose. The ramaining elements are power of two. 17 | max_runs = 1e9; 18 | max_err = 100; 19 | resolution = 1e6;%the results are shown per max_runs/resolution. 20 | [bler, ber] = simulation(N, K, design_epsilon, max_runs, max_err, resolution, ebno_vec, list_vec, g, crc_length); 21 | 22 | -------------------------------------------------------------------------------- /PolarFastSCL/polar_encoder.m: -------------------------------------------------------------------------------- 1 | function x = polar_encoder(u, lambda_offset, llr_layer_vec) 2 | %encoding: x = u * Fn. 3 | N = length(u); 4 | m = log2(N); 5 | C = zeros(N - 1, 1); 6 | x = zeros(N, 1); 7 | for phi = 0 : N - 1 8 | switch phi 9 | case 0 10 | index_1 = lambda_offset(m); 11 | for beta = 1 : index_1 12 | C(beta + index_1 - 1) = u(beta) + u(beta + index_1); 13 | end 14 | for i_layer = m - 2 : -1 : 0 15 | index_1 = lambda_offset(i_layer + 1); 16 | index_2 = lambda_offset(i_layer + 2); 17 | for beta = index_1 : index_2 - 1 18 | C(beta) = C(beta + index_1) + C(beta + index_2); 19 | end 20 | end 21 | case N/2 22 | index_1 = lambda_offset(m); 23 | for beta = 1 : index_1 24 | C(beta + index_1 - 1) = u(beta + index_1); 25 | end 26 | for i_layer = m - 2 : -1 : 0 27 | index_1 = lambda_offset(i_layer + 1); 28 | index_2 = lambda_offset(i_layer + 2); 29 | for beta = index_1 : index_2 - 1 30 | C(beta) = C(beta + index_1) + C(beta + index_2); 31 | end 32 | end 33 | otherwise 34 | layer = llr_layer_vec(phi + 1); 35 | index_1 = lambda_offset(layer + 1); 36 | index_2 = lambda_offset(layer + 2); 37 | for beta = index_1 : index_2 - 1 38 | C(beta) = C(beta + index_2); 39 | end 40 | for i_layer = layer - 1: -1 : 0 41 | index_1 = lambda_offset(i_layer + 1); 42 | index_2 = lambda_offset(i_layer + 2); 43 | for beta = index_1 : index_2 - 1 44 | C(beta) = C(beta + index_1) + C(beta + index_2); 45 | end 46 | end 47 | end 48 | x(phi + 1) = C(1); 49 | end 50 | x = mod(x, 2); 51 | end -------------------------------------------------------------------------------- /PolarFastSCL/simulation.m: -------------------------------------------------------------------------------- 1 | function [bler, ber] = simulation(N, K, design_epsilon, max_runs, max_err, resolution, ebno_vec, list_size_vec, g, crc_length) 2 | R = (K - crc_length)/N; 3 | lambda_offset = 2.^(0 : log2(N)); 4 | llr_layer_vec = get_llr_layer(N); 5 | bit_layer_vec = get_bit_layer(N); 6 | [G_crc, H_crc] = crc_generator_matrix(g, K - crc_length); 7 | crc_parity_check = G_crc'; 8 | 9 | %beta expansion Code Construction, proposed by Huawei 10 | % beta = sqrt(sqrt(2)); 11 | % % channels = PW(N, beta); 12 | % % channels = HPW(N, beta); 13 | % channels = EPW(N, beta); 14 | % [~, channel_ordered] = sort(channels, 'descend'); 15 | % info_bits = sort(channel_ordered(1 : K)); 16 | % frozen_bits = ones(N , 1); 17 | % frozen_bits(info_bits) = 0; 18 | 19 | %Bhattacharyya Code (BEC) Construction 20 | % channels = get_BEC_IWi(N, design_epsilon); 21 | % [~, channel_ordered] = sort(channels, 'descend'); 22 | % info_bits = sort(channel_ordered(1 : K), 'ascend'); 23 | % frozen_bits = ones(N , 1); 24 | % frozen_bits(info_bits) = 0; 25 | % info_bits_logical = logical(mod(frozen_bits + 1, 2)); 26 | 27 | %Gaussian approximation Code Construction 28 | design_snr = 2.5; 29 | sigma_cc = 1/sqrt(2 * R) * 10^(-design_snr/20); 30 | [channels, ~] = GA(sigma_cc, N); 31 | [~, channel_ordered] = sort(channels, 'descend'); 32 | info_bits = sort(channel_ordered(1 : K), 'ascend'); 33 | frozen_bits = ones(N, 1); 34 | frozen_bits(info_bits) = 0; 35 | frozen_bits = logical(frozen_bits); 36 | 37 | %Following MATLAB code is used for matrix-multiplication based systematic polar encoding 38 | FN = get_GN(N); 39 | GAA = FN(info_bits, info_bits); 40 | GAAC = FN(info_bits, frozen_bits); 41 | Generate_xAC = mod(GAAC' * GAA', 2); 42 | systematic_encoding_algorithm = 1; 43 | 44 | %This value can be 1, 2, 3, and 4. 45 | %1 : 'Matrix_multiplication_systematic_encoder' 46 | %!!!!But when N is large,the Generator matrix will be large, too. The computer may not have such large storage. 47 | %2 : 'Sarkis_Two_step_systematic_encoder' 48 | %3 : 'Arikan_SC_style_systematic_encoder' 49 | %4 : 'Arikan_Recursive_systematic_encoder'. This one is slow. 50 | 51 | %Special constituent nodes 52 | node_type_matrix = get_node_structure(frozen_bits); 53 | psi_vec = get_psi_for_advanced_sc_decoder(node_type_matrix); 54 | 55 | %Results Stored 56 | bler = zeros(length(ebno_vec), length(list_size_vec)); 57 | num_runs = zeros(length(ebno_vec), length(list_size_vec)); 58 | ber = zeros(length(ebno_vec), length(list_size_vec)); 59 | %Loop starts 60 | tic 61 | for i_run = 1 : max_runs 62 | if mod(i_run, max_runs/resolution) == 1 63 | disp(' '); 64 | disp(['Sim iteration running = ' num2str(i_run)]); 65 | disp(['N = ' num2str(N) ' K = ' num2str(K)]); 66 | disp(['List size = ' num2str(list_size_vec)]); 67 | disp('Current block error performance'); 68 | disp(num2str([ebno_vec' bler./num_runs])); 69 | disp('Current bit error performance'); 70 | disp(num2str([ebno_vec' ber./num_runs/K])); 71 | disp(' ') 72 | end 73 | info = rand(K - crc_length, 1) > 0.5; 74 | info_with_crc = [info; mod(crc_parity_check * info, 2)]; 75 | switch systematic_encoding_algorithm 76 | case 1 77 | parity_check_bits = mod(Generate_xAC * info_with_crc, 2); 78 | x = zeros(N, 1); 79 | x(info_bits) = info_with_crc; 80 | x(frozen_bits) = parity_check_bits; 81 | case 2 82 | x = sarkis_systematic_polar_encoder(info_with_crc, info_bits, frozen_bits, N, lambda_offset, llr_layer_vec); 83 | case 3 84 | x = arikan_sc_systematic_polar_encoder(info_with_crc, frozen_bits, info_bits, lambda_offset, llr_layer_vec, bit_layer_vec); 85 | case 4 86 | x = zeros(N, 1); 87 | x(info_bits) = info_with_crc; 88 | x = arikan_recursive_systematic_polar_encoder(x, mod(frozen_bits + 1, 2)); 89 | end 90 | bpsk = 1 - 2 * x; 91 | noise = randn(N, 1); 92 | prev_decoded = zeros(length(ebno_vec), length(list_size_vec)); 93 | for i_ebno = 1 : length(ebno_vec) 94 | sigma = 1/sqrt(2 * R) * 10^(-ebno_vec(i_ebno)/20); 95 | y = bpsk + sigma * noise; 96 | llr = 2/sigma^2*y; 97 | %*******Simulaion Accelaration********* 98 | for i_list = 1 : length(list_size_vec) 99 | if i_list ~= 1 100 | if bler(i_ebno, i_list) == max_err 101 | continue; 102 | end 103 | else 104 | if all(bler(i_ebno, 2 : end) == max_err) 105 | continue 106 | end 107 | end 108 | num_runs(i_ebno, i_list) = num_runs(i_ebno, i_list) + 1; 109 | run_sim = 1; 110 | for i_ebno2 = 1 : i_ebno 111 | for i_list2 = 1 : i_list 112 | if prev_decoded(i_ebno2, i_list2) 113 | run_sim = 0; 114 | end 115 | end 116 | end 117 | if run_sim == 0 118 | continue; 119 | end 120 | %*******Simulaion Accelaration********* 121 | if list_size_vec(i_list) == 1 122 | polar_info_esti = SC_decoder(llr, frozen_bits, lambda_offset, llr_layer_vec, bit_layer_vec, info_bits); 123 | % polar_info_esti = FastSCdecoder(llr, info_bits, node_type_matrix, lambda_offset, llr_layer_vec, psi_vec, bit_layer_vec); 124 | else 125 | polar_info_esti = FastSCL_decoder(llr, list_size_vec(i_list), info_bits, lambda_offset, llr_layer_vec, bit_layer_vec, psi_vec, node_type_matrix, H_crc); 126 | end 127 | if any(polar_info_esti ~= info_with_crc) 128 | bler(i_ebno, i_list) = bler(i_ebno, i_list) + 1; 129 | ber(i_ebno, i_list) = ber(i_ebno, i_list) + sum(polar_info_esti(1 : K - crc_length) ~= info_with_crc(1 : K - crc_length)); 130 | %Caution, this is data bits error rate, regardless of CRC 131 | %bits. 132 | else 133 | prev_decoded(i_ebno, i_list) = 1; 134 | end 135 | 136 | end 137 | end 138 | end 139 | toc 140 | end 141 | 142 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PolarCodeDecodersInMatlab 2 | This is the Matlab realization of Polar Decoders, including CA-SCL, Fast CA-SCL and BP decoder. 3 | 4 | The .PDF file is in a textbook-style, for new learners of polar code in China. 5 | -------------------------------------------------------------------------------- /elements_of_polar_codes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuYongRun/PolarCodeDecodersInMatlab/f1b512d10bf057e83f18685ea012d242bdaaf6ac/elements_of_polar_codes.pdf --------------------------------------------------------------------------------