├── CODES ├── BCH_k_113_n_127.mat └── capolar_k_116_n_128_ul.mat ├── GRAND Codebase Non-Commercial Academic Research Use License 021722.pdf ├── GRAND_Code ├── README.txt ├── bin_GRAND.m ├── bin_ORBGRAND.m ├── bin_ORBGRAND1.m ├── driver_GRAND.m ├── koopman2matlab.m ├── landslide.m ├── make_CRC_GH.m ├── make_RLC.m └── make_pac_code.m ├── MAKE_FIGS └── driver_sample_figs.m ├── README.md └── RESULTS ├── GRAND_CAPOLAR_128_116_1.mat ├── GRAND_CRC_0x8f3_128_116_1.mat ├── GRAND_PAC_237_128_116_1.mat ├── GRAND_RLC_128_116_1.mat ├── ORBGRAND1_CAPOLAR_128_116_1.mat ├── ORBGRAND1_CRC_0x8f3_128_116_1.mat ├── ORBGRAND1_CRC_0x9eb2_128_112_1.mat ├── ORBGRAND1_CRC_0x9eb2_64_48_1.mat ├── ORBGRAND1_CRC_0xac9a_256_240_1.mat ├── ORBGRAND1_CRC_0xd175_512_496_1.mat ├── ORBGRAND1_PAC_237_128_116_1.mat ├── ORBGRAND1_RLC_128_116_1.mat ├── ORBGRAND_CAPOLAR_128_116_1.mat ├── ORBGRAND_CRC_0x8f3_128_116_1.mat ├── ORBGRAND_PAC_237_128_116_1.mat └── ORBGRAND_RLC_128_116_1.mat /CODES/BCH_k_113_n_127.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/CODES/BCH_k_113_n_127.mat -------------------------------------------------------------------------------- /CODES/capolar_k_116_n_128_ul.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/CODES/capolar_k_116_n_128_ul.mat -------------------------------------------------------------------------------- /GRAND Codebase Non-Commercial Academic Research Use License 021722.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/GRAND Codebase Non-Commercial Academic Research Use License 021722.pdf -------------------------------------------------------------------------------- /GRAND_Code/README.txt: -------------------------------------------------------------------------------- 1 | % Ken R. Duffy, 2018-2022. 2 | 3 | % Guessing Random Additive Noise Decoding (GRAND) 4 | 5 | % Subject to license: 6 | % GRAND Codebase Non-Commercial Academic Research Use License 021722.pdf 7 | 8 | % For an [n,k] code, where k information bits become n coded bits, 9 | % GRAND algorithms accurately and efficiently decode codes where n-k 10 | % is moderate. This MATLAB implementation is solely intended to be 11 | % instructive and is not optimized. In particular, highly-parallelised 12 | % implementations are possible, but this is not one. 13 | 14 | % As a result, obtaining the full performance a code with n-k>16 may 15 | % be time-consuming with the present implementation. 16 | 17 | % The following should be cited in association with results from this code. 18 | 19 | % GRAND 20 | 21 | % K. R. Duffy, J. Li, and M. Medard, "Capacity-achieving guessing random 22 | % additive noise decoding," IEEE Trans. Inf. Theory, vol. 65, no. 7, pp. 23 | % 4023–4040, 2019. 24 | 25 | % ORBGRAND 26 | 27 | % K. R. Duffy, “Ordered reliability bits guessing random additive noise 28 | % decoding," in IEEE ICASSP, 2021, pp. 8268–8272. 29 | 30 | % K. R. Duffy, W. An, and M. Medard, "Ordered reliability bits guessing 31 | % random additive noise decoding,” IEEE Trans. Signal Process., vol. 70, 32 | % pp. 4528-4542, 2022. 33 | -------------------------------------------------------------------------------- /GRAND_Code/bin_GRAND.m: -------------------------------------------------------------------------------- 1 | % GRAND (hard detection, BSC) 2 | 3 | % Inputs: 4 | % n - code length 5 | % H - Parity check matrix or CRC function 6 | % max_query - Maximum number of code-book queries to abandonment 7 | % y_demod - Channel hard output 8 | % 9 | % Outputs: 10 | % y_decoded - Decoded codeword 11 | % putative_noise - noise 12 | % n_guesses - Number of guesses performed 13 | % abandoned - 1 if abandoned, 0 if found a codeword 14 | 15 | function [y_decoded,putative_noise,n_guesses,abandoned] = bin_GRAND(H,max_query,y_demod) 16 | 17 | n=size(H,2); 18 | n_guesses = 0; 19 | abandoned = 0; 20 | 21 | [err_loc_vec, err_vec, ~] = gen_next_err(n); %Generate initial vectors 22 | 23 | while n_guesses < max_query 24 | [decoded,putative_noise,ng]=bin_syn_check(H,y_demod,err_vec); 25 | %How many guesses have been made 26 | n_guesses = n_guesses+ng; 27 | if (decoded == 1) 28 | y_decoded = mod(y_demod-putative_noise,2); 29 | return; 30 | end 31 | [err_loc_vec, err_vec, ~] = gen_next_err(n, err_loc_vec); %Generate next error vector 32 | end 33 | 34 | % If abandoned 35 | y_decoded = -1*ones(size(y_demod)); 36 | abandoned = 1; 37 | 38 | 39 | end 40 | 41 | function [decoded,noise_found,n_guesses]=bin_syn_check(H,y_demod,err_vec) 42 | 43 | decoded = 0; 44 | noise_found = NaN(1,size(err_vec,2)); 45 | % How many guesses have we made 46 | n_guesses=0; 47 | while (decoded == 0 && n_guesses16 may be time-consuming. 11 | 12 | % GRAND 13 | % K. R. Duffy, J. Li, and M. Medard, "Capacity-achieving guessing random 14 | % additive noise decoding," IEEE Trans. Inf. Theory, vol. 65, no. 7, pp. 15 | % 4023–4040, 2019. 16 | 17 | % Ordered Reliability Bits GRAND (ORBGRAND) 18 | % Basic ORBGRAND as introduced in 19 | % K. R. Duffy, “Ordered reliability bits guessing random additive noise 20 | % decoding," in IEEE ICASSP, 2021, pp. 8268–8272 21 | % and implemented using the Landslide algorithm introduced in 22 | % ORBGRAND 23 | % K. R. Duffy, W. An, and M. Medard, "Ordered reliability bits guessing 24 | % random additive noise decoding,” IEEE Trans. Signal Process., vol. 70, 25 | % pp. 4528-4542, 2022. 26 | 27 | % 1-line ORBGRAND from 28 | % K. R. Duffy, W. An, and M. Medard, "Ordered reliability bits guessing 29 | % random additive noise decoding,” IEEE Trans. Signal Process., vol. 70, 30 | % pp. 4528-4542, 2022. 31 | % and implemented here using materials introduced in 32 | % K. Galligan, M. Médard, K. R. Duffy, "Block turbo decoding with ORBGRAND" 33 | % arXiv:2207.11149, 2022. 34 | 35 | clear; 36 | 37 | % Chose the decoder from: 38 | % 'GRAND' (hard detection); 39 | % 'ORBGRAND' (soft detection); 40 | % 'ORBGRAND1' (soft detection); 41 | DECODER='ORBGRAND1'; 42 | 43 | % Sim range in Eb/N0 44 | ebn0=4:0.5:6; 45 | 46 | % Run simulation until this many errors observed for each Eb/N0 value 47 | err_thresh = 50; 48 | 49 | % Modulation schemes available using MATLAB's toolbox, which will be used 50 | % in a complex-valued channel 51 | modlist = {'pi/2-BPSK','BPSK','QPSK','16QAM','64QAM','256QAM'}; 52 | bpsList = [1 1 2 4 6 8]; 53 | % Pick the modulation 54 | modulation = 'BPSK'; 55 | % Determine the number of bits per symbol in the modulation 56 | nmodbits = bpsList(strcmpi(modlist,modulation)); 57 | 58 | % Pick the code 59 | % RLC, PAC, CAPOLAR, BCH or CRC. 60 | code_class = 'RLC'; 61 | 62 | % Random Linear Code. 63 | if isequal(code_class,'RLC') 64 | n=128; 65 | k=116; 66 | 67 | % If a RLC was previously used, reload it and reuse the code 68 | filename = ['../RESULTS/' DECODER '_' code_class '_' num2str(n) '_' num2str(k) '_' num2str(nmodbits) '.mat']; 69 | if exist(filename, 'file') == 2 70 | load(filename,'code'); 71 | G=code.G; 72 | H=code.H; 73 | % If not, make a random generator 74 | else 75 | % Make a random parity check matrix 76 | [G,H] = make_RLC(k,n,0.5); 77 | code.G=G; 78 | code.H=H; 79 | end 80 | 81 | % Polar-assisted convolutional codes, as introduced by 82 | % E. Arikan, "From sequential decoding to channel polarization 83 | % and back again", arXiv:1908.09594, 2019. 84 | elseif isequal(code_class,'PAC') 85 | n=128; % Must be power of 2. 86 | k=116; 87 | % Generator for convolutional code, taken from arXiv:1908.09594. 88 | conv_code = [1 1 1 0 1 1 0 1]; 89 | [G, H] = make_pac_code(n,k,conv_code); 90 | code.G = G; 91 | code.H = H; 92 | % Record what convolution was used. 93 | code.conv_code = conv_code; 94 | 95 | % CRC-Assisted Polar code. As GRAND algorithms are universal, rather than 96 | % use the Polar bits for error correction and the CRC bits for error 97 | % detection, as the product of linear codes is linear, instead GRAND uses 98 | % all bits for error correction. 99 | elseif isequal(code_class,'CAPOLAR') 100 | % 5G New Radio uplink code 101 | filename = '../CODES/capolar_k_116_n_128_ul.mat'; 102 | code = open(filename); 103 | G = code.G; 104 | H = code.H; 105 | % k,n is the code length 106 | [k,n]=size(G); 107 | 108 | % Bose–Chaudhuri–Hocquenghem code. Normally only used with hard 109 | % detection decoding, but soft version of GRAND can decode too. 110 | elseif isequal(code_class,'BCH') 111 | filename = '../CODES/BCH_k_113_n_127.mat'; 112 | code = open(filename); 113 | code.class=code_class; 114 | G = code.G; 115 | H = code.H; 116 | % k,n is the code length 117 | [k,n]=size(G); 118 | 119 | % Cyclic Redundancy Check (CRC) code. Normally only used for error 120 | % detection, but GRAND algorithms can decode with hard or soft information. 121 | elseif isequal(code_class,'CRC') 122 | k=116; 123 | % Polynomial from https://users.ece.cmu.edu/~koopman/crc/ which has a 124 | % repository of high quality CRCs curated and maintained by 125 | % Philip Koopman, Carnegie Mellon University. 126 | hex_poly = '0x8f3'; % 12 bit 127 | poly=koopman2matlab(hex_poly); % Convert from Koopman notation 128 | % Record the polynomial 129 | code.poly = poly; 130 | % Set up the CRC check using MATLAB toolbox 131 | [G,H,n] = make_CRC_GH(k,poly); 132 | code.G=G; 133 | code.H=H; 134 | end 135 | 136 | % Reminder that this implementation is not optimized or parallelized, so 137 | % larger n-k may take time to run. 138 | if n-k>16 139 | disp('GRAND and ORBGRAND are readily highly parallelizable in software and hardware.') 140 | disp('The MATLAB implementations here are for instruction and are NOT parallelized.') 141 | disp(['If GRAND algorithms find an error, they do so after ' ... 142 | 'approximately 2^{n-k} code-book queries']) 143 | disp('and so 2^{n-k} is an upper bound on complexity in terms of query numbers.') 144 | disp(['With n-k=' num2str(n-k) ' expect slow decoding in noisy channels with this inefficient implementation.']) 145 | end 146 | 147 | % Record the code_class in the data construct 148 | code.class = code_class; 149 | 150 | %GRAND parameters 151 | max_query=inf; % Can reduce to an abandonment value. 152 | 153 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 154 | % Simulation 155 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 156 | % Convert Eb/N0 to SNR 157 | snr_db = ebn0+10*log10(k/n)+10*log10(nmodbits); 158 | 159 | % Pad modulation with meaningless bits if necessary. 160 | mod_pad=zeros(1,mod(n,nmodbits)); 161 | 162 | %For each SNR record the following 163 | num_decoded = zeros(1,length(snr_db)); % Number of packets decoded 164 | num_demod_errs = num_decoded; % Number of demodulations that are in error 165 | num_demod_bit_errs = num_decoded; % Number of erroneous demodulated bits 166 | num_errs = num_decoded; % Number of erroneous decodings 167 | num_bit_errs = num_decoded; % Number of erroneous bits 168 | num_aband = num_decoded; % Number of abandoned decodings 169 | num_queries = num_decoded; % Total number of code-book queries 170 | 171 | for ii=1:length(snr_db) 172 | 173 | % Noise variance 174 | sigma2 = 1/(10^(0.1*snr_db(ii))); 175 | % Using MATLAB's channel function 176 | awgnchan = comm.AWGNChannel('NoiseMethod','Variance','Variance',sigma2); 177 | 178 | % Keep decoding pacekts until you see err_thresh erroneous decodings 179 | while num_errs(ii)=2 28 | % Find the last index with an accumulated drop >=2 29 | k=find(D>=2,1,'last'); 30 | % Increase its index by one. 31 | u(k)=u(k)+1; 32 | u = mountain_build(u,k,w,W1,n1); 33 | % Record the partition 34 | jj=jj+1; 35 | z(jj,:)=u; 36 | % Evaluate drops 37 | d=circshift(u,-1)-u; 38 | d(w)=0; 39 | % Evaluate accumulated drops 40 | D = cumsum(d,'reverse'); 41 | end 42 | z = z + repmat([1:w],size(z,1),1); 43 | end 44 | 45 | function u = mountain_build(u,k,w,W1,n1) 46 | u(k+1:w) = u(k)*ones(1,w-k); 47 | W2 = W1-sum(u); 48 | q = floor(W2/(n1-u(k))); 49 | r = W2-q*(n1-u(k)); 50 | if q ~= 0 51 | u(w-q+1:w)=n1*ones(1,q); 52 | end 53 | if w-q>0 54 | u(w-q)=u(w-q)+r; 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /GRAND_Code/make_CRC_GH.m: -------------------------------------------------------------------------------- 1 | % Convert a generator polynomial into [G,H] binary code matrices 2 | % Requires MATLAB's comms toolbox 3 | 4 | 5 | function [G,H,n] = make_CRC_GH(k,poly) 6 | 7 | GCRC = comm.CRCGenerator(poly); 8 | n = length(GCRC(zeros(k,1))); 9 | 10 | u=[zeros(1,k-1) 1]; 11 | 12 | G = zeros(k,n); 13 | 14 | for ii=1:k 15 | u=circshift(u,1); 16 | G(ii,:) = (GCRC(u')'==1); 17 | end 18 | 19 | H =[G(:,k+1:end)' eye(n-k)]; 20 | 21 | end 22 | -------------------------------------------------------------------------------- /GRAND_Code/make_RLC.m: -------------------------------------------------------------------------------- 1 | % Make random linear parity code matrix without duplicate rows or all zero 2 | % rows. 3 | 4 | function [G,H] = make_RLC(k,n,p) 5 | 6 | P = make_parity_check(k,n,p); 7 | % If there are duplicate rows, re-randomise 8 | while (size(unique(P','rows'),1)0) 22 | tf=ismember(P,zeros(1,n-k),'rows'); 23 | P(tf,:) = binornd(1,p,sum(tf),n-k); 24 | end 25 | end -------------------------------------------------------------------------------- /GRAND_Code/make_pac_code.m: -------------------------------------------------------------------------------- 1 | % Create a Polar-assisted convolutional code, following the instruction 2 | % in E. Arikan, "From sequential decoding to channel polarization 3 | % and back again", arXiv:1908.09594, 2019. 4 | 5 | function [G, H] = make_pac_code(N, K, c) 6 | 7 | %Inputs: codeword length as integer N, 8 | % number of data bits as integer K, 9 | % convolution polynomial c as array of ints, 10 | 11 | %Outputs: K by N binary generator matrix G 12 | % N-K by N binary parity check matrix H 13 | 14 | %generate rate-profiling vector A using score metric 15 | 16 | [~, indices] = sort(sum(de2bi([0:(N-1)]),2), 'descend'); 17 | A = sort(indices(1:K)'); 18 | 19 | %rate profiling matrix given vector A of indices 20 | rate_prof_mat = zeros(K,N); 21 | for i = 1:K 22 | rate_prof_mat(i, A(1,i)) = 1; 23 | end 24 | 25 | %Generate convolutional precoding matrix given polynomial c, 26 | 27 | %T is convolution matrix 28 | T = zeros(N,N); 29 | for i = 1:length(c) 30 | k = 0; 31 | for j = 1:(N+1-i) 32 | T(j,i+k) = c(1,i); 33 | k = k+1; 34 | end 35 | end 36 | 37 | %polar coding matrix, the Kronecker power of polar transform to 38 | %power of log2(N) 39 | P_1 = [1 0; 1 1]; 40 | P_n = P_1; 41 | for i = 1:(log2(N)-1) 42 | P_n = kron(P_n, P_1); 43 | end 44 | 45 | %generator matrix G is product of these matrices, modulo 2 46 | G = mod(rate_prof_mat*T*P_n,2); 47 | 48 | %need to get G in standard form through row ops of modulo 2 49 | stand_G = G; 50 | i = 1; 51 | j = 1; 52 | 53 | %for each column find non-zero element, swap rows, subtract from other 54 | %rows 55 | while (i<=K)&&(j<=N) 56 | row_offset = find(stand_G(i:K,j),1); 57 | 58 | if isempty(row_offset) 59 | j=j+1; 60 | else 61 | pivot_row = row_offset + i - 1; 62 | 63 | %swap rows 64 | stand_G([i pivot_row],j:N) = stand_G([pivot_row i],j:N); 65 | for ii = [1:i-1 i+1:K] 66 | stand_G(ii,j:N) = mod(stand_G(ii,j:N) - stand_G(ii,j)*stand_G(i,j:N),2); 67 | end 68 | i = i+1; 69 | j = j+1; 70 | end 71 | end 72 | 73 | %only valid if G is full rank 74 | if rank(stand_G) == K 75 | 76 | %if not in standard form still, swap columns and find a column 77 | %swapped parity check matrix, and switch columns back to get H 78 | if ~isequal(stand_G(:,1:K),eye(K)) 79 | swap_cols = [1:N]; 80 | col_swap_G = stand_G; 81 | for i = 1:K 82 | if col_swap_G(i,i) == 0 83 | for j = i+1:N 84 | if col_swap_G(i,j) == 1 85 | col_swap_G(:,[i j]) = col_swap_G(:, [j i]); 86 | swap_cols(1, [i j]) = swap_cols(1, [j i]); 87 | break 88 | end 89 | end 90 | end 91 | end 92 | 93 | %make makeshift H then swaps cols back to get our true H 94 | col_swap_H = mod(gen2par(col_swap_G),2); 95 | H(:, swap_cols) = col_swap_H; 96 | 97 | %already in standard form 98 | else 99 | H = mod(gen2par(stand_G),2); 100 | end 101 | 102 | else 103 | error('Needs full rank G - try different c array.') 104 | end 105 | end 106 | -------------------------------------------------------------------------------- /MAKE_FIGS/driver_sample_figs.m: -------------------------------------------------------------------------------- 1 | % Two sets of figures. 2 | 3 | % Sample plotted output from simulations with [128,116] codes and 4 | % GRAND (hard detection), ORBGRAND (soft detection), ORBGRAND1 (soft 5 | % detection). 6 | 7 | clear codes 8 | 9 | n=128; 10 | k=116; 11 | n_CODES = 0; 12 | 13 | % GRAND (hard detection) 14 | DECODER = 'GRAND'; 15 | 16 | code.class = 'CAPOLAR'; 17 | n_CODES=n_CODES+1; 18 | filename = ['../RESULTS/' DECODER '_' code.class '_' num2str(n) '_' num2str(k) '_1.mat']; 19 | load(filename,'code'); 20 | code.decoder = DECODER; 21 | code.LT = '--d'; 22 | code.color = 'b'; 23 | codes(n_CODES).code = code; 24 | 25 | code.class = 'PAC'; 26 | conv_code = [1 1 1 0 1 1 0 1]; 27 | n_CODES=n_CODES+1; 28 | filename = ['../RESULTS/' DECODER '_' code.class '_' num2str(bin2dec(num2str(conv_code))) '_' num2str(n) '_' num2str(k) '_1.mat']; 29 | load(filename,'code'); 30 | code.decoder = DECODER; 31 | code.LT = '--s'; 32 | code.color = [0.1250, 0.6940, 0.9290]; 33 | codes(n_CODES).code = code; 34 | 35 | code.class = 'CRC'; 36 | poly='0x8f3'; 37 | n_CODES=n_CODES+1; 38 | filename = ['../RESULTS/' DECODER '_' code.class '_' poly '_' num2str(n) '_' num2str(k) '_1.mat']; 39 | load(filename,'code'); 40 | code.decoder = [DECODER ' ' poly]; 41 | code.LT = '--o'; 42 | code.color = 'r'; 43 | codes(n_CODES).code = code; 44 | 45 | code.class = 'RLC'; 46 | n_CODES=n_CODES+1; 47 | filename = ['../RESULTS/' DECODER '_' code.class '_' num2str(n) '_' num2str(k) '_1.mat']; 48 | load(filename,'code'); 49 | code.decoder = DECODER; 50 | code.LT = '--x'; 51 | code.color = 'm'; 52 | codes(n_CODES).code = code; 53 | 54 | % ORBGRAND (soft detection) 55 | DECODER = 'ORBGRAND'; 56 | 57 | 58 | code.class = 'CAPOLAR'; 59 | n_CODES=n_CODES+1; 60 | filename = ['../RESULTS/' DECODER '_' code.class '_' num2str(n) '_' num2str(k) '_1.mat']; 61 | load(filename,'code'); 62 | code.decoder = DECODER; 63 | code.LT = '-d'; 64 | code.color = 'b'; 65 | codes(n_CODES).code = code; 66 | 67 | code.class = 'PAC'; 68 | conv_code = [1 1 1 0 1 1 0 1]; 69 | n_CODES=n_CODES+1; 70 | filename = ['../RESULTS/' DECODER '_' code.class '_' num2str(bin2dec(num2str(conv_code))) '_' num2str(n) '_' num2str(k) '_1.mat']; 71 | load(filename,'code'); 72 | code.decoder = DECODER; 73 | code.LT = '-s'; 74 | code.color = [0.1250, 0.6940, 0.9290]; 75 | codes(n_CODES).code = code; 76 | 77 | code.class = 'CRC'; 78 | poly='0x8f3'; 79 | n_CODES=n_CODES+1; 80 | filename = ['../RESULTS/' DECODER '_' code.class '_' poly '_' num2str(n) '_' num2str(k) '_1.mat']; 81 | load(filename,'code'); 82 | code.decoder = [DECODER ' ' poly]; 83 | code.LT = '-o'; 84 | code.color = 'r'; 85 | codes(n_CODES).code = code; 86 | 87 | code.class = 'RLC'; 88 | n_CODES=n_CODES+1; 89 | filename = ['../RESULTS/' DECODER '_' code.class '_' num2str(n) '_' num2str(k) '_1.mat']; 90 | load(filename,'code'); 91 | code.decoder = DECODER; 92 | code.LT = '-x'; 93 | code.color = 'm'; 94 | codes(n_CODES).code = code; 95 | 96 | 97 | % 1-line ORBGRAND (soft detection) 98 | DECODER = 'ORBGRAND1'; 99 | 100 | code.class = 'CAPOLAR'; 101 | n_CODES=n_CODES+1; 102 | filename = ['../RESULTS/' DECODER '_' code.class '_' num2str(n) '_' num2str(k) '_1.mat']; 103 | load(filename,'code'); 104 | code.decoder = DECODER; 105 | code.LT = '-.d'; 106 | code.color = 'b'; 107 | codes(n_CODES).code = code; 108 | 109 | code.class = 'PAC'; 110 | conv_code = [1 1 1 0 1 1 0 1]; 111 | n_CODES=n_CODES+1; 112 | filename = ['../RESULTS/' DECODER '_' code.class '_' num2str(bin2dec(num2str(conv_code))) '_' num2str(n) '_' num2str(k) '_1.mat']; 113 | load(filename,'code'); 114 | code.decoder = DECODER; 115 | code.LT = '-.s'; 116 | code.color = [0.1250, 0.6940, 0.9290]; 117 | codes(n_CODES).code = code; 118 | 119 | code.class = 'CRC'; 120 | poly='0x8f3'; 121 | n_CODES=n_CODES+1; 122 | filename = ['../RESULTS/' DECODER '_' code.class '_' poly '_' num2str(n) '_' num2str(k) '_1.mat']; 123 | load(filename,'code'); 124 | code.decoder = [DECODER ' ' poly]; 125 | code.LT = '-.o'; 126 | code.color = 'r'; 127 | codes(n_CODES).code = code; 128 | 129 | code.class = 'RLC'; 130 | n_CODES=n_CODES+1; 131 | filename = ['../RESULTS/' DECODER '_' code.class '_' num2str(n) '_' num2str(k) '_1.mat']; 132 | load(filename,'code'); 133 | code.decoder = DECODER; 134 | code.LT = '-.x'; 135 | code.color = 'm'; 136 | codes(n_CODES).code = code; 137 | 138 | make_fig(codes,1) 139 | 140 | % Sample plotted output from simulations with ORBGRAND1 (soft 141 | % detection) and different length codes with the same n-k. 142 | 143 | clear codes 144 | n_CODES=0; 145 | 146 | % 1-line ORBGRAND (soft detection) 147 | DECODER = 'ORBGRAND1'; 148 | 149 | n=64; 150 | k=n-16; 151 | code.class = 'CRC'; 152 | poly='0x9eb2'; 153 | n_CODES=n_CODES+1; 154 | filename = ['../RESULTS/' DECODER '_' code.class '_' poly '_' num2str(n) '_' num2str(k) '_1.mat']; 155 | load(filename,'code'); 156 | code.decoder = [DECODER ' ' poly]; 157 | code.LT = '-.o'; 158 | codes(n_CODES).code = code; 159 | 160 | n=128; 161 | k=n-16; 162 | code.class = 'CRC'; 163 | poly='0x9eb2'; 164 | n_CODES=n_CODES+1; 165 | filename = ['../RESULTS/' DECODER '_' code.class '_' poly '_' num2str(n) '_' num2str(k) '_1.mat']; 166 | load(filename,'code'); 167 | code.decoder = [DECODER ' ' poly]; 168 | code.LT = '-.o'; 169 | codes(n_CODES).code = code; 170 | 171 | n=256; 172 | k=n-16; 173 | code.class = 'CRC'; 174 | poly='0xac9a'; 175 | n_CODES=n_CODES+1; 176 | filename = ['../RESULTS/' DECODER '_' code.class '_' poly '_' num2str(n) '_' num2str(k) '_1.mat']; 177 | load(filename,'code'); 178 | code.decoder = [DECODER ' ' poly]; 179 | code.LT = '-.o'; 180 | codes(n_CODES).code = code; 181 | 182 | n=512; 183 | k=n-16; 184 | code.class = 'CRC'; 185 | poly='0xd175'; 186 | n_CODES=n_CODES+1; 187 | filename = ['../RESULTS/' DECODER '_' code.class '_' poly '_' num2str(n) '_' num2str(k) '_1.mat']; 188 | load(filename,'code'); 189 | code.decoder = [DECODER ' ' poly]; 190 | code.LT = '-.o'; 191 | codes(n_CODES).code = code; 192 | 193 | % Colour code lines 194 | colours = zeros(n_CODES,3); 195 | colours(:,1) = [1:n_CODES]/(n_CODES); 196 | colours(:,3) = 1-[1:n_CODES]/(n_CODES); 197 | for ii=1:n_CODES 198 | codes(ii).code.color = colours(ii,:); 199 | end 200 | 201 | make_fig(codes,2) 202 | 203 | function make_fig(codes,fig_no) 204 | 205 | FONT=16; 206 | MS=8; 207 | LW=2; 208 | num_codes = length(codes); 209 | 210 | figure(fig_no) 211 | clf 212 | % BLER 213 | subplot(1,3,1) 214 | hold on 215 | for ii=1:num_codes 216 | code_info = [codes(ii).code.decoder ', ' codes(ii).code.class ' [' num2str(codes(ii).code.n) ',' num2str(codes(ii).code.k) '], R=' num2str(codes(ii).code.k/codes(ii).code.n,'%.2f')]; 217 | plot(codes(ii).code.ebn0,codes(ii).code.BLER,codes(ii).code.LT,'displayname',code_info,'color',codes(ii).code.color,'LineWidth',LW, 'MarkerSize',MS) 218 | end 219 | hold off 220 | legend('show','Location','NorthEast'); 221 | ylabel('BLER') 222 | xlabel('Eb/N0') 223 | grid 'on' 224 | xl = xlim; 225 | xlim([xl(1)-1 xl(2)+1]) 226 | set(gca, 'YScale', 'log') 227 | yl=ylim; 228 | ylim([10^floor(log10(yl(1))) 10^0]) 229 | set(gca,'FontSize',FONT) 230 | 231 | % BER 232 | subplot(1,3,2) 233 | hold on 234 | for ii=1:num_codes 235 | code_info = [codes(ii).code.decoder ', ' codes(ii).code.class ' [' num2str(codes(ii).code.n) ',' num2str(codes(ii).code.k) '], R=' num2str(codes(ii).code.k/codes(ii).code.n,'%.2f')]; 236 | plot(codes(ii).code.ebn0,codes(ii).code.BER,codes(ii).code.LT,'displayname',code_info,'color',codes(ii).code.color,'LineWidth',LW, 'MarkerSize',MS) 237 | end 238 | hold off 239 | legend('show','Location','NorthEast'); 240 | ylabel('BER') 241 | xlabel('Eb/N0') 242 | grid 'on' 243 | xl = xlim; 244 | xlim([xl(1)-1 xl(2)+1]) 245 | set(gca, 'YScale', 'log') 246 | yl=ylim; 247 | ylim([10^floor(log10(yl(1))) 10^0]) 248 | set(gca,'FontSize',FONT) 249 | 250 | % Average number of codebook queries 251 | subplot(1,3,3) 252 | hold on 253 | for ii=1:num_codes 254 | code_info = [codes(ii).code.decoder ', ' codes(ii).code.class ' [' num2str(codes(ii).code.n) ',' num2str(codes(ii).code.k) '], R=' num2str(codes(ii).code.k/codes(ii).code.n,'%.2f')]; 255 | plot(codes(ii).code.ebn0,codes(ii).code.EG,codes(ii).code.LT,'displayname',code_info,'color',codes(ii).code.color,'LineWidth',LW, 'MarkerSize',MS) 256 | end 257 | hold off 258 | legend('show','Location','NorthEast'); 259 | ylabel('Average number of code-book queries') 260 | xlabel('Eb/N0') 261 | grid 'on' 262 | xl = xlim; 263 | xlim([xl(1)-1 xl(2)+1]) 264 | set(gca, 'YScale', 'log') 265 | set(gca,'FontSize',FONT) 266 | 267 | 268 | end 269 | 270 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GRAND-MATLAB 2 | Guessing Random Additive Noise Decoding (GRAND) (TM) 3 | 4 | Subject to license: 5 | "GRAND Codebase Non-Commercial Academic Research Use License 021722.pdf" 6 | 7 | Non-parallelized MATLAB implementations of: GRAND (hard detection); basic ORBGRAND (soft detection); 1-line ORBGRAND (soft detection). 8 | 9 | Simulation is setup and run with GRAND_Code/driver_GRAND.m 10 | 11 | Sample output is in RESULTS, and sample plots from those results can be made with MAKE_FIGS/driver_sample_figs.m 12 | 13 | Note that for an [n,k] code, where k information bits become n coded bits, GRAND algorithms accurately and efficiently decode codes where n-k is moderate. This MATLAB implementation is solely intended to be instructive and is not parallelised, even though highly-parallelised implementations are possible. As a result, obtaining the full performance of a code with n-k>16 may prove time-consuming with the present implementation. 14 | 15 | The following should be cited in association with results from this code. 16 | 17 | K. R. Duffy, J. Li, and M. Medard, "Capacity-achieving guessing random additive noise decoding," IEEE Trans. Inf. Theory, vol. 65, no. 7, pp. 4023–4040, 2019. 18 | 19 | A. Riaz, V. Bansal, A. Solomon, W. An, Q. Liu, K. Galligan, K. R. Duffy, M. Medard and R. T. Yazicigil, "Multi-code multi-rate universal maximum likelihood decoder using GRAND," Proceedings of IEEE ESSCIRC, 2021. 20 | 21 | K. R. Duffy, “Ordered reliability bits guessing random additive noise decoding," Proceedings of IEEE ICASSP, 2021, pp. 8268–8272. 22 | 23 | K. R. Duffy, W. An, and M. Medard, "Ordered reliability bits guessing random additive noise decoding,” IEEE Trans. Signal Process., vol. 70, pp. 4528-4542, 2022. 24 | 25 | For further details on GRAND, see: https://www.granddecoder.mit.edu/ 26 | -------------------------------------------------------------------------------- /RESULTS/GRAND_CAPOLAR_128_116_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/RESULTS/GRAND_CAPOLAR_128_116_1.mat -------------------------------------------------------------------------------- /RESULTS/GRAND_CRC_0x8f3_128_116_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/RESULTS/GRAND_CRC_0x8f3_128_116_1.mat -------------------------------------------------------------------------------- /RESULTS/GRAND_PAC_237_128_116_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/RESULTS/GRAND_PAC_237_128_116_1.mat -------------------------------------------------------------------------------- /RESULTS/GRAND_RLC_128_116_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/RESULTS/GRAND_RLC_128_116_1.mat -------------------------------------------------------------------------------- /RESULTS/ORBGRAND1_CAPOLAR_128_116_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/RESULTS/ORBGRAND1_CAPOLAR_128_116_1.mat -------------------------------------------------------------------------------- /RESULTS/ORBGRAND1_CRC_0x8f3_128_116_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/RESULTS/ORBGRAND1_CRC_0x8f3_128_116_1.mat -------------------------------------------------------------------------------- /RESULTS/ORBGRAND1_CRC_0x9eb2_128_112_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/RESULTS/ORBGRAND1_CRC_0x9eb2_128_112_1.mat -------------------------------------------------------------------------------- /RESULTS/ORBGRAND1_CRC_0x9eb2_64_48_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/RESULTS/ORBGRAND1_CRC_0x9eb2_64_48_1.mat -------------------------------------------------------------------------------- /RESULTS/ORBGRAND1_CRC_0xac9a_256_240_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/RESULTS/ORBGRAND1_CRC_0xac9a_256_240_1.mat -------------------------------------------------------------------------------- /RESULTS/ORBGRAND1_CRC_0xd175_512_496_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/RESULTS/ORBGRAND1_CRC_0xd175_512_496_1.mat -------------------------------------------------------------------------------- /RESULTS/ORBGRAND1_PAC_237_128_116_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/RESULTS/ORBGRAND1_PAC_237_128_116_1.mat -------------------------------------------------------------------------------- /RESULTS/ORBGRAND1_RLC_128_116_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/RESULTS/ORBGRAND1_RLC_128_116_1.mat -------------------------------------------------------------------------------- /RESULTS/ORBGRAND_CAPOLAR_128_116_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/RESULTS/ORBGRAND_CAPOLAR_128_116_1.mat -------------------------------------------------------------------------------- /RESULTS/ORBGRAND_CRC_0x8f3_128_116_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/RESULTS/ORBGRAND_CRC_0x8f3_128_116_1.mat -------------------------------------------------------------------------------- /RESULTS/ORBGRAND_PAC_237_128_116_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/RESULTS/ORBGRAND_PAC_237_128_116_1.mat -------------------------------------------------------------------------------- /RESULTS/ORBGRAND_RLC_128_116_1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenrduffy/GRAND-MATLAB/860d26bc63a5eefd769662ff7527946ab1ba6d35/RESULTS/ORBGRAND_RLC_128_116_1.mat --------------------------------------------------------------------------------