├── README.md ├── config.m ├── documentation ├── Polar Codes Diploma Thesis.pdf └── bp polar codes.pdf ├── main.m ├── results ├── AWGN_R=0.25 │ ├── polar_N128_K32_2018_09_25_16_33_51.mat │ ├── polar_N16_K4_2018_09_25_16_33_34.mat │ ├── polar_N16_K4_2018_09_25_16_33_51.mat │ ├── polar_N256_K64_2018_09_25_16_33_51.mat │ ├── polar_N32_K8_2018_09_25_16_33_51.mat │ └── polar_N64_K16_2018_09_25_16_33_51.mat └── AWGN_R=0.5 │ ├── ber.fig │ ├── fer.fig │ ├── polar_N128_K64_2018_09_27_14_44_38.mat │ ├── polar_N16_K8_2018_09_27_14_44_38.mat │ ├── polar_N256_K128_2018_09_27_14_44_38.mat │ ├── polar_N32_K16_2018_09_27_14_44_38.mat │ └── polar_N64_K32_2018_09_27_14_44_38.mat └── support ├── add_noise.m ├── b.m ├── butterfly.m ├── capacities.m ├── decode.m ├── decode2.m ├── encode.m ├── f_function ├── MSA │ ├── f.m │ └── l_f.m └── SPA │ ├── f.m │ └── l_f.m ├── fkronecker.m ├── g.m ├── initialize_frozen_bits.m ├── mex_files ├── l_f.mexw64 └── s_f.mexw64 ├── modulate.m ├── partial_sums_initialize.m ├── plot_script.m ├── polar_initialization.m ├── s_f.m ├── sc_array_initialize.m ├── sc_decode.m └── transform_inputs.m /README.md: -------------------------------------------------------------------------------- 1 | # Polar-Codes 2 | Polar Codes Simulation on Matlab, for my [Thesis Project](./Polar%20Codes%20Diploma%20Thesis.pdf) in Electrical and Computer Engineering at University of Patras. Succesive Cancellation schema, encoding-decoding.

3 | Alexander El-Kady, [Linkedin](https://www.linkedin.com/in/alexander-el-kady-8b3b0710a/), elkady.alexander@gmail.com 4 | -------------------------------------------------------------------------------- /config.m: -------------------------------------------------------------------------------- 1 | timestamp = [num2str(start_time(1),'%04d') '_' num2str(start_time(2),'%02d') '_' num2str(start_time(3),'%02d') '_' num2str(start_time(4),'%02d') '_' num2str(start_time(5),'%02d') '_' num2str(start_time(6),'%2.0f')]; 2 | result_path = './results/'; 3 | %% Configure parameters 4 | %Polar-Code values 5 | capacity = 0.5; %I(W), Channel's W Capacity 6 | n_values = [4,5,6,7,8]; %value of N 7 | code_rate = 1/4; 8 | %EbNo 9 | EbNo_dB = 0:5; %AWGN -4:2 %Fading 0:2:10 10 | %Channel 11 | Fading_Channel = 0; %0: AWGN, 1:Fading Channel 12 | %fading only parameters 13 | Fading_Independent = 0; %if Fading_Channel = 1 14 | quasi = 0; % quasi channel 15 | fading_channel = 'TU120'; %custom matlab channel 16 | %seed 17 | fix_seed = 1; %1:fix data, 0:random data 18 | %Simulation values 19 | decoding_algorithm = 'MSA'; % Set as 'SPA' for Sum-Product algorithm , or 'MSA' for Min-Sum Algorithm. 20 | fast_run = 1; %1:run of optimal-matlab code + mex-files, 0:run of hardware-code (suboptimal f/g) 21 | min_fer_errors = 100; %minimum frame errors to count 22 | min_codewords = 100; %minimum codewords to count 23 | NbitsPerSymbol = 1; %modulation parameter 24 | constDims = 1; %modulation parameter 25 | snrdb_values =EbNo_dB+10*log10(double(code_rate*NbitsPerSymbol*2/constDims)); 26 | %% Parfor configuration 27 | FLAG_Enable_parpool=0; % 0: Disable, 1: Enable 28 | parcore_nums = 4; 29 | %% Initializations 30 | %add required matlab paths 31 | restoredefaultpath; 32 | addpath('support'); 33 | addpath(['./support/f_function/' decoding_algorithm]); % for l_f function. 34 | if(fast_run == 1) % for mex-files 35 | addpath('./support/mex_files'); 36 | end 37 | %initialize seed 38 | if ~fix_seed 39 | rng(sum(100*clock)); 40 | else 41 | rand('seed',123456); 42 | end 43 | %initialize parcorenum 44 | if FLAG_Enable_parpool 45 | % determine the number of physical cores 46 | corenum = feature('numcores'); 47 | parcorenum = parcore_nums; 48 | % parcorenum = 15; % # of workers 49 | p = gcp('nocreate'); % Not create new pool if it does not exist 50 | if isempty(p) 51 | p = parcluster('local'); 52 | p.NumWorkers = parcorenum; 53 | parpool(p, p.NumWorkers); 54 | end 55 | if p.NumWorkers ~= parcorenum 56 | delete(p); 57 | p = parcluster('local'); 58 | p.NumWorkers = parcorenum; 59 | parpool(p, p.NumWorkers); 60 | end 61 | parallel_frames = 100*parcorenum; 62 | else 63 | parallel_frames = 100; 64 | end 65 | %% Variable Initializations 66 | bit_error_rate = zeros(length(n_values),length(snrdb_values)); 67 | fer_error_rate = zeros(length(n_values),length(snrdb_values)); 68 | legends = strings(1,length(n_values)); 69 | codewords = zeros(1,length(snrdb_values)); -------------------------------------------------------------------------------- /documentation/Polar Codes Diploma Thesis.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/documentation/Polar Codes Diploma Thesis.pdf -------------------------------------------------------------------------------- /documentation/bp polar codes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/documentation/bp polar codes.pdf -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | clc;clear all; 2 | start_time = clock; 3 | config; 4 | %% N LOOP 5 | for index_n = 1:length(n_values) %N=2^n 6 | N = power(2,n_values(index_n)); %Code Length 7 | K = N* code_rate; %Code keyword length 8 | mat_file = [result_path 'polar_N' num2str(N) '_K' num2str(K) '_' timestamp '.mat']; 9 | %Polar-code initializations 10 | [Fn,frozen_bits, frozen_indxs, non_frozen_indxs, partial_sum_adders, sc_functions, sc_2nd_indxs] = polar_initialization(N, K, capacity); 11 | fprintf("Polar Code %d/%d running:\n",N,K); 12 | %% SNR LOOP 13 | for i_index = 1:length(snrdb_values) 14 | %Initialize temporary variables 15 | codewords_tmp = 0;fer_errors = 0;bit_errors = 0; 16 | snr = snrdb_values(i_index); 17 | while (fer_errors0.5; %write random inputs 23 | %transform inputs 24 | inputs_to_encode = transform_inputs(inputs,non_frozen_indxs,N); 25 | %encode 26 | encoded_inputs = encode(inputs_to_encode,Fn); %Reversed Polar Encoding 27 | %modulate 28 | modulated_inputs = modulate(encoded_inputs);%encoded_inputs); %BPSK = 1-2*encoded_inputs(i) 29 | %noise 30 | noised_inputs = add_noise(modulated_inputs,constDims,Fading_Channel,Fading_Independent,fading_channel,snrdb_values(i_index)); 31 | %demodulate 32 | llr = (2 * power(10,snrdb_values(i_index)/10))*noised_inputs; %CARE NEGATIVE SIGN.2*yi/(s^2) = ln(Li), s^2 = 1/ 10^ (SNRdb/10) 33 | %decode 34 | if(fast_run) 35 | %optimal version (optimal-calculations of f/g) 36 | outputs = decode2(llr,frozen_bits); 37 | else 38 | %hardware-version (suboptimal-calculations of f/g) 39 | outputs = decode(llr,frozen_bits,partial_sum_adders,sc_functions,sc_2nd_indxs); %or decode2(llr,frozen_bits); for the other algorithm 40 | end 41 | final_outputs = outputs(non_frozen_indxs);%transform_outputs(outputs,frozen_bits,N); 42 | %Calculate temporary bit/frame errors 43 | temp_bit_errors = sum(final_outputs ~= inputs); 44 | bit_errors_parfor(frame) = temp_bit_errors; 45 | fer_errors_parfor(frame) = (temp_bit_errors>0); 46 | end 47 | codewords_tmp = codewords_tmp + parallel_frames; 48 | bit_errors = bit_errors + sum(bit_errors_parfor); 49 | fer_errors = fer_errors + sum(fer_errors_parfor); 50 | end 51 | %Calculate snr bit/frame errors 52 | bit_error_rate(index_n,i_index) = bit_errors/(codewords_tmp*K); 53 | fer_error_rate(index_n,i_index) = fer_errors/(codewords_tmp); 54 | codewords(index_n,i_index) = codewords_tmp; 55 | legends(index_n) = [num2str(N), '/', num2str(K)]; 56 | %Update plot figures 57 | %Save results for particular n & snr 58 | save(mat_file,'snrdb_values','EbNo_dB','bit_error_rate','fer_error_rate','codewords','N','K','Fading_Channel','Fading_Independent','fading_channel'); 59 | %Display 60 | fprintf('EbNo = %.1f\tber=%0.5f,fer=%0.5f\n',EbNo_dB(i_index),bit_error_rate(index_n,i_index),fer_error_rate(index_n,i_index)); 61 | end 62 | % file = fopen([result_path 'results_N=' num2str(N) '_SNR=' num2str(snrdb_values(1)) '-' num2str(snrdb_values(end)) '.txt'],'w'); 63 | end 64 | plot_script; 65 | -------------------------------------------------------------------------------- /results/AWGN_R=0.25/polar_N128_K32_2018_09_25_16_33_51.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/results/AWGN_R=0.25/polar_N128_K32_2018_09_25_16_33_51.mat -------------------------------------------------------------------------------- /results/AWGN_R=0.25/polar_N16_K4_2018_09_25_16_33_34.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/results/AWGN_R=0.25/polar_N16_K4_2018_09_25_16_33_34.mat -------------------------------------------------------------------------------- /results/AWGN_R=0.25/polar_N16_K4_2018_09_25_16_33_51.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/results/AWGN_R=0.25/polar_N16_K4_2018_09_25_16_33_51.mat -------------------------------------------------------------------------------- /results/AWGN_R=0.25/polar_N256_K64_2018_09_25_16_33_51.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/results/AWGN_R=0.25/polar_N256_K64_2018_09_25_16_33_51.mat -------------------------------------------------------------------------------- /results/AWGN_R=0.25/polar_N32_K8_2018_09_25_16_33_51.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/results/AWGN_R=0.25/polar_N32_K8_2018_09_25_16_33_51.mat -------------------------------------------------------------------------------- /results/AWGN_R=0.25/polar_N64_K16_2018_09_25_16_33_51.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/results/AWGN_R=0.25/polar_N64_K16_2018_09_25_16_33_51.mat -------------------------------------------------------------------------------- /results/AWGN_R=0.5/ber.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/results/AWGN_R=0.5/ber.fig -------------------------------------------------------------------------------- /results/AWGN_R=0.5/fer.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/results/AWGN_R=0.5/fer.fig -------------------------------------------------------------------------------- /results/AWGN_R=0.5/polar_N128_K64_2018_09_27_14_44_38.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/results/AWGN_R=0.5/polar_N128_K64_2018_09_27_14_44_38.mat -------------------------------------------------------------------------------- /results/AWGN_R=0.5/polar_N16_K8_2018_09_27_14_44_38.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/results/AWGN_R=0.5/polar_N16_K8_2018_09_27_14_44_38.mat -------------------------------------------------------------------------------- /results/AWGN_R=0.5/polar_N256_K128_2018_09_27_14_44_38.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/results/AWGN_R=0.5/polar_N256_K128_2018_09_27_14_44_38.mat -------------------------------------------------------------------------------- /results/AWGN_R=0.5/polar_N32_K16_2018_09_27_14_44_38.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/results/AWGN_R=0.5/polar_N32_K16_2018_09_27_14_44_38.mat -------------------------------------------------------------------------------- /results/AWGN_R=0.5/polar_N64_K32_2018_09_27_14_44_38.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/results/AWGN_R=0.5/polar_N64_K32_2018_09_27_14_44_38.mat -------------------------------------------------------------------------------- /support/add_noise.m: -------------------------------------------------------------------------------- 1 | function channel_out = add_noise(inputs,constDims,Fading_Channel,Fading_Independent,fading_channel,snr) 2 | %takes modulated inputs, adds AWGN/Fading noise with SNR in db. 3 | if Fading_Channel && ~Fading_Independent 4 | legacychannelsim(true); 5 | end 6 | % CHANNEL % 7 | if Fading_Channel % Fading Channel 8 | if Fading_Independent % i.i.d. fading channel 9 | %Time-domain 10 | if ~quasi 11 | fading = complex(randn(1,length(inputs)), randn(1,length(inputs)))/sqrt(2); %iid Rayleigh 12 | else 13 | fading = complex(randn(1), randn(1))/sqrt(2); %Quasi-static Rayleight 14 | end 15 | % attenu = abs(fading); 16 | % phase = angle(fading); 17 | else % Multipath Fading Channel 18 | if(strcmp(fading_channel,'TU120')) 19 | fs = 2048e3; %if frequency domain fs = 1536e3; 20 | fd = 20; %DAB-values for TU120 21 | c = 3e8; f=175.28e6; 22 | [ch,chanprofile] = stdchan(1/fs,fd,'cost207RAx6'); 23 | fading = filter(ch, ones(1,length(inputs))); 24 | attenu = abs(fading); 25 | phase = angle(fading); 26 | else 27 | ch = rayleighchan(5/345,1); %iid Rayleight Frequency domain 28 | fading = filter(ch, ones(1,length(inputs))); %Time response 29 | attenu = abs(fading); 30 | phase = angle(fading); 31 | end 32 | end 33 | in_decoder_tmp = fading.*inputs; 34 | %in_decoder_tmp = attenu.*out_mod; 35 | else % AWGN Channel 36 | % Tail-biting % 37 | in_decoder_tmp = inputs; 38 | % Received symbols amplitude 39 | fading = 1; 40 | attenu = 1; 41 | phase = 0; 42 | end 43 | 44 | noise_dev = sqrt(10^(-snr/10)/constDims); 45 | %BPSK 46 | channel_out = noise_dev*(randn(1,length(inputs))) + in_decoder_tmp; 47 | %QPSK 48 | % channel_out = noise_dev*complex(randn(1,length(inputs)),randn(1,length(inputs))) ... 49 | % + in_decoder_tmp; 50 | 51 | %old noise addition based on awgn 52 | % channel_out = awgn(inputs,snr,'measured'); 53 | end 54 | 55 | 56 | %correct -------------------------------------------------------------------------------- /support/b.m: -------------------------------------------------------------------------------- 1 | function output = b(a,b) 2 | output = floor(mod(b/power(2,a),2)); 3 | end 4 | 5 | -------------------------------------------------------------------------------- /support/butterfly.m: -------------------------------------------------------------------------------- 1 | function Gn = butterfly (bits) 2 | Gn = bitrevorder(fkronecker(bits)); 3 | end 4 | 5 | -------------------------------------------------------------------------------- /support/capacities.m: -------------------------------------------------------------------------------- 1 | function capacities = capacities( N, capacity) 2 | %Estimates the capacities of all channels 3 | %Outputs array with the capacities of the N channels 4 | bits = log2(N); 5 | capacities = ones(1,N)*capacity; 6 | for j=0:1:bits-1 7 | step = power(2,j); 8 | for i=1:2*step:power(2,bits) 9 | for z=i:1:i+step-1 10 | temp = capacities(z) * capacities(z); 11 | capacities(z+step) = 2*capacities(z+step) - temp; 12 | capacities(z)= temp; 13 | end 14 | end 15 | end 16 | 17 | 18 | end 19 | 20 | -------------------------------------------------------------------------------- /support/decode.m: -------------------------------------------------------------------------------- 1 | function outputs = decode(llr_inputs,frozen_bits,partial_sum_adders,sc_functions,sc_2nd_indxs) 2 | bits = length(llr_inputs); 3 | reverse_order = bitrevorder(1:1:bits); %same as 0:1:bits-1 4 | sc_array = zeros(bits,log2(bits)+1); 5 | sc_array(:,log2(bits)+1) = llr_inputs.'; 6 | outputs = zeros(1,bits); %NOT bit_reversed_array 7 | non_frozen_indxs = find(frozen_bits == 1); 8 | for bit=non_frozen_indxs %Arikan 0:1:bits-1 9 | for l= log2(bits):-1:1 %Arikan log2(bits)-1:-1:0 10 | partial_sums_l = partial_sum_adders(:,:,l) * (transpose(outputs)); %NOT bit_reversed_array 11 | partial_sums_l = mod(partial_sums_l,2); %mod 2 12 | z = 0; %number of partial sum 13 | for i = 1:1:bits 14 | if(sc_functions(i,l) == 0) 15 | sc_array(i,l,1) = f(sc_array(i+sc_2nd_indxs(i,l),l+1,1),sc_array(i,l+1,1)); %getting values from l+1 stage 16 | else 17 | z = z+1; %the number of adder 18 | sc_array(i,l,1) = g(sc_array(i+sc_2nd_indxs(i,l),l+1,1),sc_array(i,l+1,1),partial_sums_l(z)); %getting values from l+1 stage + partial_sum 19 | end 20 | end 21 | end 22 | if(sc_array(reverse_order(bit),1,1)<0) %if it's not frozen bit, update value 23 | outputs(bit)=1; 24 | end 25 | end 26 | end -------------------------------------------------------------------------------- /support/decode2.m: -------------------------------------------------------------------------------- 1 | function estimated = decode2(llr,frozen_bits) 2 | %takes llr values, frozen bits (0 frozen, 1 unfrozen) and outputs the 3 | %estimated decoded outputs Ui. Using 2 recursive functions l,s. 4 | N = length(llr); 5 | estimated = zeros(1,N); 6 | %llr should be in bit-reversed order 7 | reverse_llr = bitrevorder(llr); 8 | for i=1:1:N 9 | if(frozen_bits(i) == 1) 10 | a = l_f(1,i,reverse_llr,frozen_bits,estimated); 11 | if( a >= 0) 12 | estimated(i) = 0; 13 | else 14 | estimated(i) = 1; 15 | end 16 | end 17 | end 18 | end 19 | 20 | -------------------------------------------------------------------------------- /support/encode.m: -------------------------------------------------------------------------------- 1 | function outputs = encode(inputs,Fn) 2 | %outputs = x where x= u * G , where G = B(N) * Fn 3 | %basic encoding scheme with kronecker power of Fn. 4 | outputs = mod(bitrevorder(inputs) * Fn,2); %Reversed outputs 5 | end 6 | 7 | 8 | %correct -------------------------------------------------------------------------------- /support/f_function/MSA/f.m: -------------------------------------------------------------------------------- 1 | function y = f(x1,x2) 2 | %f(?a,?b) proccess 3 | %Min-Sum Algorithm (MSA) deployed 4 | y = sign(x1)*sign(x2)*min(abs(x1),abs(x2)); 5 | end -------------------------------------------------------------------------------- /support/f_function/MSA/l_f.m: -------------------------------------------------------------------------------- 1 | function output = l_f(l,j,llr,frozen_bits,estimated) 2 | %Takes l (stage from 1 to log2(N)+1), j-channel (from 1 to N), llr array, frozen 3 | %bits array and current estimated outputs array 4 | %outputs the l 5 | %Min-Sum Algorithm (MSA) deployed 6 | stages = log2(length(frozen_bits)); 7 | if (l == stages+1) 8 | output = llr(j); 9 | elseif( mod(floor((j-1)/power(2,l-1)),2) == 0) 10 | a = l_f(l+1,j,llr,frozen_bits,estimated); 11 | b = l_f(l+1,j+power(2,l-1),llr,frozen_bits,estimated); 12 | output = sign(a)*sign(b)*min(abs(a),abs(b)); 13 | else 14 | output = (1-2*s_f(l,j-power(2,l-1),frozen_bits,estimated)) * (l_f(l+1,j-power(2,l-1),llr,frozen_bits,estimated)) + l_f(l+1,j,llr,frozen_bits,estimated) ; 15 | end 16 | 17 | %correct -------------------------------------------------------------------------------- /support/f_function/SPA/f.m: -------------------------------------------------------------------------------- 1 | function y = f(x1,x2) 2 | %f(?a,?b) proccess 3 | %Sum-Product Algorithm (SPA) deployed 4 | y = 2*atanh(tanh(x1/2)*tanh(x2/2)); 5 | end -------------------------------------------------------------------------------- /support/f_function/SPA/l_f.m: -------------------------------------------------------------------------------- 1 | function output = l_f(l,j,llr,frozen_bits,estimated) 2 | %Takes l (stage from 1 to log2(N)+1), j-channel (from 1 to N), llr array, frozen 3 | %bits array and current estimated outputs array 4 | %outputs the l 5 | %Sum-Product Algorithm (SPA) deployed 6 | stages = log2(length(frozen_bits)); 7 | if (l == stages+1) 8 | output = llr(j); 9 | elseif( mod(floor((j-1)/power(2,l-1)),2) == 0) 10 | output = 2*atanh(tanh(l_f(l+1,j,llr,frozen_bits,estimated)/2) * tanh(l_f(l+1,j+power(2,l-1),llr,frozen_bits,estimated)/2)); 11 | else 12 | output = (1-2*s_f(l,j-power(2,l-1),frozen_bits,estimated)) * (l_f(l+1,j-power(2,l-1),llr,frozen_bits,estimated)) + l_f(l+1,j,llr,frozen_bits,estimated) ; 13 | end 14 | 15 | %correct -------------------------------------------------------------------------------- /support/fkronecker.m: -------------------------------------------------------------------------------- 1 | function Fn = fkronecker( bits ) 2 | %FKRONECKER, makes the Fn !!!array NOT REVERSED!!! 3 | F = [1,0;1,1]; 4 | Fn = F; 5 | for i=1:1:log2(bits)-1 6 | Fn=kron(F,Fn); 7 | %Fn=sparse(Fn); 8 | end 9 | end 10 | 11 | -------------------------------------------------------------------------------- /support/g.m: -------------------------------------------------------------------------------- 1 | function y = g(x1,x2,x3) % x3 is S partial 2 | %g(?a,?b,S) process 3 | y = x1*power(-1,x3)+x2 ; %power(x1,1-2*x3)*x2; lr 4 | end -------------------------------------------------------------------------------- /support/initialize_frozen_bits.m: -------------------------------------------------------------------------------- 1 | function frozen_bits = initialize_frozen_bits( N, K, capacity ) 2 | %inputs N codelength, K code keyword length, capacity of the channel 3 | %outputs a N-length array with 0,1. If 0 then the channel is frozen 4 | %if 1 not frozen. 5 | %calculate capacities and reverse them (reverse-encode) 6 | capacity_array = bitrevorder(capacities(N, capacity)); 7 | [~,sortIndex] = sort(capacity_array(:)); 8 | %freeze N-K worst-channels and keep K best-channels 9 | frozen_bits = ones(1,N); 10 | frozen_bits(sortIndex(1:N-K)) = 0; 11 | end -------------------------------------------------------------------------------- /support/mex_files/l_f.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/support/mex_files/l_f.mexw64 -------------------------------------------------------------------------------- /support/mex_files/s_f.mexw64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Spartak0s/Polar-Codes-Software-Matlab-/85996f4e2be9db8dfbd403874e121291504c3e5b/support/mex_files/s_f.mexw64 -------------------------------------------------------------------------------- /support/modulate.m: -------------------------------------------------------------------------------- 1 | function outputs = modulate(encoded_inputs) 2 | %takes encoded inputs array, and outputs modulated BPSK signal 3 | bits = length(encoded_inputs); 4 | outputs = zeros(1,bits); 5 | for i=1:1:bits 6 | outputs(i) = 1-encoded_inputs(i)*2; 7 | end 8 | 9 | %correct -------------------------------------------------------------------------------- /support/partial_sums_initialize.m: -------------------------------------------------------------------------------- 1 | function outputs = partial_sums_initialize(N) %!!!! care outputs are mapped to 0-->7 adders 2 | outputs = zeros(N/2,N,log2(N)); %outputs(z,i,l) -- l stage ,bit Ui is added,z is the number of g adder 3 | for l=0:1:log2(N)-1 4 | for z=0:1:N/2-1 5 | for i=0:1:N-1 6 | temp1 = 1; 7 | for u=l:1:log2(N)-2 8 | temp1=and(not(xor(b(log2(N)-u-2,z),b(u+1,i))),temp1); 9 | end 10 | temp2=1; 11 | for w=0:1:l-1 12 | temp2=and(or(not(b(log2(N)-w-2,z)),b(w,i)),temp2); 13 | end 14 | outputs(z+1,i+1,l+1) = temp1*temp2* not(b(l,i)); 15 | end 16 | end 17 | end 18 | end 19 | 20 | -------------------------------------------------------------------------------- /support/plot_script.m: -------------------------------------------------------------------------------- 1 | % % draw the BER vs Eb/N0 plot 2 | if(Fading_Channel) 3 | channel_str = 'Fading'; 4 | else 5 | channel_str = 'AWGN'; 6 | end 7 | figure(1) 8 | semilogy(EbNo_dB(1:length(find(bit_error_rate(index_n,:) ~= 0))), bit_error_rate(:,1:length(find(bit_error_rate(index_n,:) ~= 0))),'LineWidth', 2, 'MarkerSize',10); 9 | % axis([EbNo_dB(1) EbNo_dB(length(find(BER_list_1 ~= 0))) min(min(BER_list_1((BER_list_1 ~= 0))),min(BER_list_2((BER_list_2 ~= 0)))) max(max(BER_list_2((BER_list_1 ~= 0))),max(BER_list_1((BER_list_2 ~= 0))))]) 10 | hold on; 11 | xlabel('Eb/N0 [dB]'); 12 | ylabel('BER'); 13 | 14 | title(['Polar codes ,' channel_str]); 15 | if(index_n == length(legends)) 16 | legend(legends,'Location','SouthWest'); 17 | end 18 | grid on; 19 | % % draw the FER vs Eb/N0 plot 20 | figure(2) 21 | semilogy(EbNo_dB(1:length(find(fer_error_rate(index_n,:) ~= 0))), fer_error_rate(:,1:length(find(fer_error_rate(index_n,:) ~= 0))),'LineWidth', 2, 'MarkerSize',10); 22 | % axis([EbNo_dB(1) EbNo_dB(length(find(FER_list_1 ~= 0))) min(min(FER_list_1((FER_list_1 ~= 0))),min(FER_list_2((FER_list_2 ~= 0)))) max(max(FER_list_2((FER_list_1 ~= 0))),max(FER_list_1((FER_list_2 ~= 0))))]) 23 | hold on; 24 | xlabel('Eb/N0 [dB]'); 25 | ylabel('FER'); 26 | title(['Polar codes ,' channel_str]); 27 | if(index_n == length(legends)) 28 | legend(legends,'Location','SouthWest'); 29 | end 30 | grid on; -------------------------------------------------------------------------------- /support/polar_initialization.m: -------------------------------------------------------------------------------- 1 | function [ Fn,frozen_bits, frozen_indxs, non_frozen_indxs, partial_sum_adders, sc_functions, sc_2nd_indxs] = polar_initialization( N, K, capacity ) 2 | %POLAR_INITIALIZATION Summary of this function goes here 3 | % Detailed explanation goes here 4 | Fn = fkronecker(N); 5 | frozen_bits = initialize_frozen_bits(N,K,capacity); %0=frozen, 1=not_frozen 6 | frozen_indxs = find(frozen_bits == 0); 7 | non_frozen_indxs = find(frozen_bits == 1); 8 | partial_sum_adders = partial_sums_initialize(N); %!!!!! NOT bit_reversed array -- %outputs(z,i,l) -- l stage ,bit Ui is added,z is the number of g adder 9 | [sc_functions,sc_2nd_indxs] = sc_array_initialize(N); 10 | end 11 | 12 | -------------------------------------------------------------------------------- /support/s_f.m: -------------------------------------------------------------------------------- 1 | function output = s_f(l,j,frozen_bits,estimated) 2 | %Takes l (stage from 1 to log2(N)+1), j-channel (from 1 to N), frozen 3 | %bits array and current estimated outputs array 4 | %outputs the estimated s 5 | if (l ==1) 6 | if( frozen_bits(j) == 0) % or reverse_order(j) may be a solution? 7 | output = 0; 8 | else 9 | output = estimated(j); 10 | end 11 | else 12 | if (mod(floor((j-1)/power(2,l-2)),2) == 0) 13 | output = double(xor(s_f(l-1,j,frozen_bits,estimated),s_f(l-1,j+power(2,l-2),frozen_bits,estimated))); 14 | else 15 | output = s_f(l-1,j,frozen_bits,estimated); 16 | end 17 | end 18 | 19 | end 20 | 21 | %correct -------------------------------------------------------------------------------- /support/sc_array_initialize.m: -------------------------------------------------------------------------------- 1 | function [sc_function,sc_2nd_indxs] = sc_array_initialize(bits) 2 | %decoding initialization 3 | %sc_function:if 0 then f else g 4 | %sc_2nd_indxs: index of 2nd input 5 | sc_function = zeros(bits,log2(bits)+1); 6 | sc_2nd_indxs = zeros(bits,log2(bits)+1); 7 | reverse_i = bitrevorder(1:1:bits); 8 | %f-g function array 9 | for l=1:1:log2(bits) %array l, l=stages from right to left ( N+1->1 or N->1 )?? 10 | butterfly = [zeros(1,bits/pow2(l)) ones(1,bits/pow2(l))].'; 11 | factor = (bits/pow2(l)); 12 | second_index = [ones(1,bits/pow2(l))*(factor) ones(1,bits/pow2(l))*(-factor)].'; 13 | sc_function(:,l) = repmat(butterfly,[pow2(l-1),1]); 14 | sc_2nd_indxs(:,l) = repmat(second_index,[pow2(l-1),1]); 15 | end 16 | end 17 | 18 | % correct initialization checked. -------------------------------------------------------------------------------- /support/sc_decode.m: -------------------------------------------------------------------------------- 1 | function [ output_args ] = sc_decode( input_args ) 2 | 3 | 4 | end 5 | 6 | -------------------------------------------------------------------------------- /support/transform_inputs.m: -------------------------------------------------------------------------------- 1 | function outputs = transform_inputs(inputs,non_frozen_indxs,N) 2 | %takes Xi inputs,the position of frozen bits, and makes the outputs array 3 | %inputs at not frozen positions, 0 at frozen positions 4 | outputs = zeros(1,N); 5 | outputs(non_frozen_indxs) = inputs; 6 | % correct 7 | 8 | --------------------------------------------------------------------------------