Skip to content

Commit

Permalink
Merge pull request #1 from krishna-praneet/bp-syndrome-decoding
Browse files Browse the repository at this point in the history
Bp syndrome decoding
  • Loading branch information
krishna-praneet authored Jul 27, 2023
2 parents abbed5a + 882a2e1 commit 102f48f
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 26 deletions.
37 changes: 31 additions & 6 deletions src/parity_generator.jl
Original file line number Diff line number Diff line change
@@ -1,21 +1,46 @@
using Random

function parity_check_matrix(n, rw, cw)
n_equations = (n * cw) ÷ rw
"""
parity_check_matrix(n, wr, wc)
Computes a regular LDPC matrix using Callager's algorithm
Block is created initially and then the columns are randomly
permuted to create additional parity check n_equations
# Arguments
* `n`: The length of the code
* `wr`: Row weight (Number of bits a parity check equations acts upon). Must divide n
* `wc`: Column weight (Number of parity check equations for a given bit)
# Examples
```julia
julia> using LDPC
julia> H = parity_check_matrix(1000, 10, 9)
```
"""
function parity_check_matrix(n::Int, wr::Int, wc::Int)

block_size = n_equations ÷ rw
block = zeros(Int64, block_size, n)
# 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)*cw + 1):((i)*cw)
for j in ((i-1)*wr + 1):((i)*wr)
block[i,j] = 1
end
end

H = block

for i in 1:rw - 1
for i in 1:wc - 1
H = [H; block[:, shuffle(1:end)]]
end

return H
end
40 changes: 40 additions & 0 deletions src/syndrome_it_decoder.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
function syndrome_it_decode(pcm::Matrix, syndrome, max_iters::Int)

# Get size of parity check matrix
## n is codeword length, m is number of parity check equations
m, n = size(pcm)

# Initialise error and success
error = zeros(Bool, n)
success = false

# Iterative decoding
for iter in 1:max_iters
curr_syn = (pcm * error) .% 2

# Check if the syndrome matches
if curr_syn == vec(syndrome)
success = true
break
end

# Initialise votes
votes = zeros(Int, n)
votes = vec(votes)

error_checks = .!(curr_syn .== syndrome)

for i in 1:m
if error_checks[i] == 1
votes += pcm[i, :]
else
votes -= pcm[i, :]
end
end

max_idx = argmax(votes)
error[max_idx] = 1 - error[max_idx]
end

return Bool.(error), success
end
56 changes: 36 additions & 20 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,46 @@ using Test

@testset "LDPC.jl" begin

## Syndrome decoding tests
error_rate = 0.1

parity_check_matrix = [1 0 1 0 1 0 1; 0 1 1 0 0 1 1; 0 0 0 1 1 1 1]
actual_message = [1 1 1 1 1 1 1]
received_message = [1 1 1 1 1 0 1] # 2nd bit from right is an error
decoded_message, success = bp_decode(parity_check_matrix, received_message, error_rate)

actual_message = vec(actual_message)
@test decoded_message == actual_message
pcm = [1 0 1 0 1 0 1; 0 1 1 0 0 1 1; 0 0 0 1 1 1 1]
error = [0 0 0 0 0 1 0]
syn = (pcm * error') .% 2
decoded_error, success = syndrome_decode(pcm, syn, error_rate, 100)
decoded_error_it, success = syndrome_it_decode(pcm, syn, 100)
@test decoded_error == vec(error)
@test decoded_error_it == vec(error)

parity_check_matrix = [1 0 1 1 1 0 0; 1 1 0 1 0 1 0; 1 1 1 0 0 0 1]
actual_message = [1 0 0 0 1 1 1]
received_message = [1 0 0 1 1 1 1] # 4th bit from left is an error
decoded_message, success = bp_decode(parity_check_matrix, received_message, error_rate)

actual_message = vec(actual_message)
@test decoded_message == actual_message
pcm = [1 0 1 1 1 0 0; 1 1 0 1 0 1 0; 1 1 1 0 0 0 1]
error = [0 0 0 1 0 0 0]
syn = (pcm * error') .% 2
decoded_error, success = syndrome_decode(pcm, syn, error_rate, 100)
decoded_error_it, success = syndrome_it_decode(pcm, syn, 100)
@test decoded_error == vec(error)
@test decoded_error_it == vec(error)

parity_check_matrix = [1 1 1 1 0 0 0 0 0 0; 1 0 0 0 1 1 1 0 0 0; 0 1 0 0 1 0 0 1 1 0; 0 0 1 0 0 1 0 1 0 1; 0 0 0 1 0 0 1 0 1 1]
actual_message = [1 1 0 0 1 0 0 0 0 0]
received_message = [1 1 0 0 1 0 0 0 0 1] # last bit is an error
decoded_message, success = bp_decode(parity_check_matrix, received_message, error_rate)
pcm = [1 1 1 1 0 0 0 0 0 0; 1 0 0 0 1 1 1 0 0 0; 0 1 0 0 1 0 0 1 1 0; 0 0 1 0 0 1 0 1 0 1; 0 0 0 1 0 0 1 0 1 1]
error = [0 0 0 0 0 0 0 0 0 1] # last bit is an error
syn = (pcm * error') .% 2
decoded_error, success = syndrome_decode(pcm, syn, error_rate, 100)
decoded_error_it, success = syndrome_it_decode(pcm, syn, 100)
@test decoded_error == vec(error)
@test decoded_error_it == vec(error)

actual_message = vec(actual_message)
@test decoded_message == actual_message

## Parity check matrix generation tests
wr = 10
wc = 9
n = 1000
H = parity_check_matrix(n, wr, wc)
rsums = sum(H, dims=2)
csums = sum(H, dims=1)

@test rsums[1] == wr
@test csums[1] == wc
@test all(rsums[1] .== rsums)
@test all(csums[1] .== csums)


end

0 comments on commit 102f48f

Please sign in to comment.