#[repr(C)]
pub enum LDPCCode { TC128 = 0, TC256 = 1, TC512 = 2, TM1280 = 3, TM1536 = 4, TM2048 = 5, TM5120 = 6, TM6144 = 7, TM8192 = 8, }
Expand description

Available LDPC codes, and methods to encode and decode them.

  • The TC codes are the Telecommand LDPC codes from CCSDS document 231.1-O-1.
  • The TM codes are the Telemetry LDPC codes from CCSDS document 131.0-B-2.
  • For full details please see: https://public.ccsds.org/default.aspx

For code parameters see the CodeParams structs also in this module: TC128_PARAMS etc.

Variants§

§

TC128 = 0

n=128 k=64 r=1/2

§

TC256 = 1

n=256 k=128 r=1/2

§

TC512 = 2

n=512 k=256 r=1/2

§

TM1280 = 3

n=1280 k=1024 r=4/5

§

TM1536 = 4

n=1536 k=1024 r=2/3

§

TM2048 = 5

n=2048 k=1024 r=1/2

§

TM5120 = 6

n=5120 k=4096 r=4/5

§

TM6144 = 7

n=6144 k=4096 r=2/3

§

TM8192 = 8

n=8192 k=4096 r=1/2

Implementations§

source§

impl LDPCCode

source

pub const fn params(self) -> CodeParams

Get the code parameters for a specific LDPC code

source

pub const fn n(self) -> usize

Get the code length (number of codeword bits)

source

pub const fn k(self) -> usize

Get the code dimension (number of information bits)

source

pub const fn punctured_bits(self) -> usize

Get the number of punctured bits (parity bits not transmitted)

source

pub const fn submatrix_size(self) -> usize

Get the size of the sub-matrices used to define the parity check matrix

source

pub const fn circulant_size(self) -> usize

Get the size of the sub-matrices used to define the generator matrix

source

pub const fn paritycheck_sum(self) -> u32

Get the sum of the parity check matrix (total number of parity check edges)

source

pub fn compact_generator(self) -> &'static [u64]

Get the reference to the compact generator matrix for this code

source

pub fn iter_paritychecks(self) -> ParityIter

Get an iterator over all parity check matrix edges for this code.

All included codes have a corresponding parity check matrix, which is defined using a very compact representation that can be expanded into the full parity check matrix. This function returns an efficient iterator over all edges in the parity check matrix, in a deterministic but otherwise unspecified order.

The iterator yields (check, variable) pairs, corresponding to the index of a row and column in the parity check matrix which contains a 1.

source§

impl LDPCCode

source

pub fn encode<'a, T>(&self, codeword: &'a mut [T]) -> &'a mut [u8]
where T: EncodeInto,

Encode a codeword. This function assumes the first k bits of codeword have already been set to your data, and will set the remaining n-k bits appropriately.

codeword must be exactly n bits long.

You can give codeword in u8, u32, or u64. The larger types are faster and are interpreted as packed bytes in little endian.

Returns a view of codeword in &mut u8 which may be convenient if you passed in a larger type but want to use the output as bytes. You can just not use the return value if you wish to keep your original view on codeword.

source

pub fn copy_encode<'a, T>( &self, data: &[u8], codeword: &'a mut [T] ) -> &'a mut [u8]
where T: EncodeInto,

Encode a codeword, first copying in the data.

This is the same as encode except you can pass the data which must be k bits long in as &[u8] and it will be copied into the first part of codeword, which must be n bits long.

Returns a view of codeword in &mut u8 which may be convenient if you passed in a larger type but want to use the output as bytes. You can just not use the return value if you wish to keep your original view on codeword.

source§

impl LDPCCode

source

pub const fn decode_bf_working_len(self) -> usize

Get the length of u8 required for the working area of decode_bf.

Equal to n + punctured_bits.

source

pub const fn decode_ms_working_len(self) -> usize

Get the length of [T] required for the working area of decode_ms.

Equal to 2 * paritycheck_sum + 3n + 3punctured_bits - 2*k.

source

pub const fn decode_ms_working_u8_len(self) -> usize

Get the length of u8 required for the working_u8 area of decode_ms.

Equal to (n + punctured_bits - k)/8.

source

pub const fn output_len(self) -> usize

Get the length of u8 required for the output of any decoder.

Equal to (n+punctured_bits)/8.

source

pub fn decode_bf( self, input: &[u8], output: &mut [u8], working: &mut [u8], maxiters: usize ) -> (bool, usize)

Bit flipping decoder.

This algorithm is quick but only operates on hard information and consequently leaves a lot of error-correcting capability behind. It is around 1-2dB worse than the min-sum decoder. However, it requires much less memory and is a lot quicker.

Requires:

  • input must be n/8 long, where each bit is the received hard information
  • output must be (n+punctured_bits)/8 (=self.output_len()) bytes long and is written with the decoded codeword, so the user data is present in the first k/8 bytes.
  • working must be n+punctured_bits (=self.decode_bf_working_len()) bytes long.

Runs for at most maxiters iterations, both when attempting to fix punctured erasures on applicable codes, and in the main bit flipping decoder.

Returns (decoding success, iters). For punctured codes, iters includes iterations of the erasure decoding algorithm which is run first.

source

pub fn decode_ms<T: DecodeFrom>( self, llrs: &[T], output: &mut [u8], working: &mut [T], working_u8: &mut [u8], maxiters: usize ) -> (bool, usize)

Message passing based min-sum decoder.

This algorithm is slower and requires more memory than the bit-flipping decode, but operates on soft information and provides very close to optimal decoding. If you don’t have soft information, you can use hard_to_llrs to go from hard information (bytes from a receiver) to soft information (LLRs).

Requires:

  • llrs must be n long, with positive numbers more likely to be a 0 bit.
  • output must be allocated to (n+punctured_bits)/8 bytes, aka output_len(), of which the first k/8 bytes will be set to the decoded message (and the rest to the parity bits of the complete codeword)
  • working is the main working area which must be provided and must have decode_ms_working_len() elements, equal to 2paritycheck_sum + 3n + 3punctured_bits - 2k
  • working_u8 is the secondary working area which must be provided and must have decode_ms_working_u8_len() elements, equal to (n + punctured_bits - k)/8.

Will run for at most maxiters iterations.

Returns decoding success and the number of iterations run for.

§Log Likelihood Ratios and choice of T

The llrs input is a list of signed numbers, one per bit, where positive numbers mean a bit is more likely to be 0, and larger magnitude numbers indicate increased confidence on a logarithmic scale (so every step increase is a multiplication of the confidence).

This decoder is invariant to a linear scaling of all the LLRs (in other words, it is invariant to the channel noise level), so you can choose any quantisation level and fixed-point interpretation you desire. This means you can view i8 as representing the 256 numbers between -1 and +0.9921875, or as just representing -128 to +127.

Internally, variables of type T are used to accumulate messages, so it is useful to leave some headroom in T after the range of your LLRs. For T=i8 you might assign -32 to 31 for LLR inputs, so that several full-scale messages can be accumulated before saturation occurs. On floating point types this is less of a concern.

This also means if you only have hard information it makes no practical difference what exact value you give the LLRs, but in the interests of avoiding saturation you may as well pick +-1 in any unit (and you may as well use i8 since the additional range will not be of benefit).

source

pub fn hard_to_llrs<T: DecodeFrom>(self, input: &[u8], llrs: &mut [T])

Convert hard information into LLRs.

The min-sum decoding used in decode_ms is invariant to linear scaling in LLR, so it doesn’t matter which value is picked so long as the sign is correct. This function just assigns -/+ 1 for 1/0 bits.

input must be n/8 long, llrs must be n long.

source

pub fn llrs_to_hard<T: DecodeFrom>(self, llrs: &[T], output: &mut [u8])

Convert LLRs into hard information.

llrs must be n long, output must be n/8 long.

Trait Implementations§

source§

impl Clone for LDPCCode

source§

fn clone(&self) -> LDPCCode

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for LDPCCode

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Hash for LDPCCode

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for LDPCCode

source§

fn eq(&self, other: &LDPCCode) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl Copy for LDPCCode

source§

impl Eq for LDPCCode

source§

impl StructuralPartialEq for LDPCCode

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.