diff --git a/Project.toml b/Project.toml index da547ab..f668bf2 100644 --- a/Project.toml +++ b/Project.toml @@ -1,12 +1,11 @@ name = "LDPCDecoders" uuid = "3c486d74-64b9-4c60-8b1a-13a564e77efb" authors = ["Krishna Praneet Gudipaty"] -version = "0.1.0" +version = "0.1.1" [deps] DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" RowEchelon = "af85af4c-bcd5-5d23-b03a-a909639aa875" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" @@ -15,14 +14,7 @@ SuiteSparseGraphBLAS = "c2e53296-7b14-11e9-1210-bddfa8111e1d" [compat] DelimitedFiles = "1" -PyPlot = "2" RowEchelon = "0.2" Statistics = "1" SuiteSparseGraphBLAS = "0.10" -julia = "1.9" - -[extras] -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[targets] -test = ["Test"] +julia = "1.9" \ No newline at end of file diff --git a/src/experiments.jl b/examples/experiments.jl similarity index 97% rename from src/experiments.jl rename to examples/experiments.jl index 4ae23e2..63bf31d 100644 --- a/src/experiments.jl +++ b/examples/experiments.jl @@ -1,9 +1,10 @@ using DelimitedFiles using PyPlot +using LDPCDecoders function simulate_bp(parity_check_matrix, physical_error_rates, max_trials, output_file_path) outputs = [] - + for per in physical_error_rates @info "Simulation for per: $per" ler = syndrome_simulate(parity_check_matrix, per, max_trials) @@ -16,7 +17,7 @@ function simulate_bp(parity_check_matrix, physical_error_rates, max_trials, out end function plot_per_vs_ler(file_path) - + # Read data from file data = readdlm(file_path) @@ -35,4 +36,4 @@ function plot_per_vs_ler(file_path) plt.ylabel("Logical error rate") plt.show() -end \ No newline at end of file +end diff --git a/src/experiments_it.jl b/examples/experiments_it.jl similarity index 96% rename from src/experiments_it.jl rename to examples/experiments_it.jl index 61c5b77..26c020d 100644 --- a/src/experiments_it.jl +++ b/examples/experiments_it.jl @@ -1,9 +1,10 @@ using DelimitedFiles using PyPlot +using LDPCDecoders function simulate_it(parity_check_matrix, physical_error_rates, max_trials, output_file_path) outputs = [] - + for per in physical_error_rates @info "Simulation for per: $per" ler = syndrome_it_simulate(parity_check_matrix, per, max_trials) diff --git a/src/LDPCDecoders.jl b/src/LDPCDecoders.jl index c8d90d0..57d524c 100644 --- a/src/LDPCDecoders.jl +++ b/src/LDPCDecoders.jl @@ -1,5 +1,14 @@ module LDPCDecoders +using DelimitedFiles +using LinearAlgebra +using Random +using SparseArrays +using Statistics + +using RowEchelon + + # Write your package code here. export parity_to_generator include("generator.jl") @@ -21,10 +30,6 @@ export syndrome_simulate include("syndrome_simulator.jl") export syndrome_it_decode include("syndrome_it_decoder.jl") -export simulate_bp, plot_per_vs_ler -include("experiments.jl") export syndrome_it_simulate include("syndrome_it_simulate.jl") -export simulate_it -include("experiments_it.jl") end diff --git a/src/bp_decoder.jl b/src/bp_decoder.jl index ec88ff2..8cff52c 100644 --- a/src/bp_decoder.jl +++ b/src/bp_decoder.jl @@ -1,6 +1,3 @@ -using LinearAlgebra - - # Bi-Symmetric Channel LLR (Bit flip) function llr(bit, error_rate) return ((-1) ^ bit) * log((1-error_rate)/error_rate) @@ -21,7 +18,7 @@ function estimate(message_c2v, num_vs, num_cs, vllr, parity_check_matrix) estimate[v] += message_c2v[c, v] end end - end + end return estimate end @@ -30,28 +27,28 @@ function send_variable_message!(parity_check_matrix, message_c2v, message_v2c, n for v in 1:num_vs if parity_check_matrix[check, v] == 1 sum = 0 - + for c in 1:num_cs if c != check && parity_check_matrix[c, v] == 1 - sum += message_c2v[c, v] + sum += message_c2v[c, v] end end - message_v2c[check, v] = sum + vllr[v] + message_v2c[check, v] = sum + vllr[v] end - end + end end end function send_check_message!(parity_check_matrix, message_c2v, message_v2c, num_cs, num_vs) - for variable in 1:num_vs + for variable in 1:num_vs for c in 1:num_cs - if parity_check_matrix[c, variable] == 1 + if parity_check_matrix[c, variable] == 1 sum = 0 sgn = 1 - for v in 1:num_vs - if parity_check_matrix[c, v] == 1 && v != variable + for v in 1:num_vs + if parity_check_matrix[c, v] == 1 && v != variable sgn *= sign(message_v2c[c, v]) sum += phi(abs(message_v2c[c,v])) end @@ -67,7 +64,7 @@ function initialise_checks!(pcm, message_c2v, syndrome, num_vs, num_cs) msg = syndrome[check] for variable in 1:num_vs if pcm[check, variable] == 1 - message_c2v = msg + message_c2v = msg end end end @@ -76,12 +73,12 @@ end # Belief Propagation Decoder function bp_decode(parity_check_matrix, received_message, error_rate, max_iterations=100) - + num_checks, num_bits = size(parity_check_matrix) num_edges = sum(parity_check_matrix) num_cs, num_vs = size(parity_check_matrix) - + # Initialize messages message_v2c = zeros(num_checks, num_bits) @@ -90,7 +87,7 @@ function bp_decode(parity_check_matrix, received_message, error_rate, max_iterat initialise_checks!(parity_check_matrix, message_c2v, syndrome, num_vs, num_cs) # Intialize llr for variable nodes - vllr = llr.(received_message, error_rate) + vllr = llr.(received_message, error_rate) # Send message from variable to check nodes send_variable_message!(parity_check_matrix, message_c2v, message_v2c, num_checks, num_bits, vllr) @@ -99,7 +96,7 @@ function bp_decode(parity_check_matrix, received_message, error_rate, max_iterat local syndrome for iter in 1:max_iterations - + # Send Message from check to variable nodes send_check_message!(parity_check_matrix, message_c2v, message_v2c, num_checks, num_bits) diff --git a/src/bp_simulator.jl b/src/bp_simulator.jl index 8a250f5..96ff540 100644 --- a/src/bp_simulator.jl +++ b/src/bp_simulator.jl @@ -1,6 +1,3 @@ -using LinearAlgebra -using Random - function bp_simulate(parity_check_matrix, generator_matrix, error_rate, max_trials) # Get size of parity check matrix @@ -12,7 +9,7 @@ function bp_simulate(parity_check_matrix, generator_matrix, error_rate, max_tria success = 0 for i in 1:max_trials println("******************* Iteration number : ", i) - + # Generate error based on error rate message = bitrand(message_size) println("message = ", message) @@ -30,12 +27,12 @@ function bp_simulate(parity_check_matrix, generator_matrix, error_rate, max_tria else error[j] = 0 end - end - - + end + + error = Int.(error) println("error = ", error) - received_message = vec(code) .⊻ error + received_message = vec(code) .⊻ error println("received message2 = ", received_message) display(received_message) @@ -60,13 +57,12 @@ function bp_simulate(parity_check_matrix, generator_matrix, error_rate, max_tria # if correct # success += 1 # end - - + + end println("The success rate of the decoder is ") println(success/max_trials) end - diff --git a/src/generator.jl b/src/generator.jl index e4c7378..c79cf7f 100644 --- a/src/generator.jl +++ b/src/generator.jl @@ -1,6 +1,3 @@ -using LinearAlgebra -using RowEchelon - # function parity_to_generator(H::Matrix{Int}) # rank, n = size(H) # n = size(H, 2) @@ -19,21 +16,21 @@ function gaussjordan(X) m, n = size(X) P = Matrix(I, m, m) - + pivot_old = 0 for j in 1:n filter_down = X[pivot_old+1:m, j] pivot = argmax(filter_down) + pivot_old println("Argmax ", argmax(filter_down)) - + if pivot <= m && X[pivot, j] == 1 pivot_old += 1 if pivot_old != pivot aux = X[pivot, :] X[pivot, :] = X[pivot_old, :] - X[pivot_old, :] = aux - + X[pivot_old, :] = aux + temp = P[pivot_old, :] P[pivot, :] = P[pivot_old, :] P[pivot_old, :] = temp @@ -46,7 +43,7 @@ function gaussjordan(X) end end end - + if pivot_old == m break end @@ -74,4 +71,4 @@ function parity_to_generator(H) G = tQ * Y return G -end \ No newline at end of file +end diff --git a/src/parity.jl b/src/parity.jl index 09fc320..1e4ff59 100644 --- a/src/parity.jl +++ b/src/parity.jl @@ -1,5 +1,3 @@ -using LinearAlgebra - function hamming_to_parity(rank) num_rows = 2^rank - 1 @@ -21,8 +19,8 @@ function repetition_to_parity(distance) for i in range(1, distance - 1) parity[i, i] = 1 - parity[i, i + 1] = 1 + parity[i, i + 1] = 1 end return parity -end \ No newline at end of file +end diff --git a/src/parity_generator.jl b/src/parity_generator.jl index cdd8024..169fed4 100644 --- a/src/parity_generator.jl +++ b/src/parity_generator.jl @@ -1,6 +1,3 @@ -using Random -using DelimitedFiles - """ parity_check_matrix(n, wr, wc) @@ -21,16 +18,16 @@ julia> H = parity_check_matrix(1000, 10, 9) ``` """ function parity_check_matrix(n::Int, wr::Int, wc::Int) - + # For a regular LDPC matrix ## wr = wc * (n / n-k) @assert n % wr == 0 - + n_equations = (n * wc) ÷ wr block_size = n_equations ÷ wc block = zeros(Bool, block_size, n) - + for i in 1:block_size for j in ((i-1)*wr + 1):((i)*wr) block[i,j] = 1 @@ -40,7 +37,7 @@ function parity_check_matrix(n::Int, wr::Int, wc::Int) H = block for i in 1:wc - 1 - H = [H; block[:, shuffle(1:end)]] + H = [H; block[:, shuffle(1:end)]] end return H diff --git a/src/syndrome_decoder.jl b/src/syndrome_decoder.jl index 29ff763..3c28256 100644 --- a/src/syndrome_decoder.jl +++ b/src/syndrome_decoder.jl @@ -1,7 +1,5 @@ -using SparseArrays - function syndrome_decode(pcm, pcmT, syndrome, max_iters, channel_probs, b2c, c2b, log_probabs, error) - + # Get size of Parity check matrix m, n = size(pcm) rows = rowvals(pcm) @@ -71,7 +69,7 @@ function syndrome_decode(pcm, pcmT, syndrome, max_iters, channel_probs, b2c, c2b log_probabs[j] = log(1 / temp) if temp >= 1 error[j] = 1 - else + else error[j] = 0 end @@ -96,7 +94,7 @@ function syndrome_decode(pcm, pcmT, syndrome, max_iters, channel_probs, b2c, c2b return error, converged end end - + return Bool.(error), converged -end \ No newline at end of file +end diff --git a/src/syndrome_it_simulate.jl b/src/syndrome_it_simulate.jl index 9cd2b3c..6ee6171 100644 --- a/src/syndrome_it_simulate.jl +++ b/src/syndrome_it_simulate.jl @@ -1,13 +1,8 @@ -using LinearAlgebra -using Random -using Statistics - - function syndrome_it_simulate(parity_check_matrix, physical_error_rate, max_trials) # Get size of parity check matrix num_checks, num_bits = size(parity_check_matrix) - + suc = 0 logical_error_rates = [] @info "Simulating for $physical_error_rate for $max_trials trials" @@ -20,16 +15,16 @@ function syndrome_it_simulate(parity_check_matrix, physical_error_rate, max_tria error_checks = zeros(Bool, num_checks) for i in 1:max_trials - - # Generate error + + # Generate error error = rand(num_bits) .< physical_error_rate - + # Calculate syndrome syndrome = (parity_check_matrix * error) .% 2 # Iterative bit flip decoder decoded_error, decoded = syndrome_it_decode(parity_check_matrix, syndrome, 100, copy(err), copy(votes)) - + if decoded == true suc += 1 end @@ -38,11 +33,10 @@ function syndrome_it_simulate(parity_check_matrix, physical_error_rate, max_tria @info "Completed $i trials" end end - - + + ler = (max_trials - suc) / max_trials println("The logical error rate is : ", ler) return ler end - diff --git a/src/syndrome_simulator.jl b/src/syndrome_simulator.jl index 2fa97d3..523855b 100644 --- a/src/syndrome_simulator.jl +++ b/src/syndrome_simulator.jl @@ -1,50 +1,44 @@ -using LinearAlgebra -using Random -using Statistics - - function syndrome_simulate(parity_check_matrix, physical_error_rate, max_trials) # Get size of parity check matrix num_checks, num_bits = size(parity_check_matrix) - + parity_check_matrix_T = sparse(parity_check_matrix') suc = 0 - + @info "Simulating for $physical_error_rate for $max_trials trials" tenths = floor(max_trials/10) - + # Initalization log_probabs = zeros(num_bits) channel_probabs = fill(physical_error_rate, num_bits) b2c = zeros(num_checks, num_bits) c2b = zeros(num_checks, num_bits) err = zeros(num_bits) - + for i in 1:max_trials - + # Generate error based on error rate error = rand(num_bits) .< physical_error_rate - + syndrome = (parity_check_matrix * error) .% 2 - + # Belief propogation decoder decoded_error, decoded = syndrome_decode(parity_check_matrix, parity_check_matrix_T, syndrome, 10, copy(channel_probabs), copy(b2c), copy(c2b), copy(log_probabs), copy(err)) - + if decoded == true suc += 1 end - + if i % tenths == 0 @info "Completed $i trials" end end - + # mean_ler = mean(logical_error_rates) ler = (max_trials - suc) / max_trials println("The logical error rate is : ", ler) return ler end - diff --git a/test/Project.toml b/test/Project.toml new file mode 100644 index 0000000..67e3a87 --- /dev/null +++ b/test/Project.toml @@ -0,0 +1,3 @@ +[deps] +SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" \ No newline at end of file