├── 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 |
--------------------------------------------------------------------------------