Breaking changes
- Removed `BlockEncoder` and `BlockDecoder` classes in favor of direct methods and specialized decoder classes.
- Block code methods are now called directly: `code.encode(u)`, `code.inverse_encode(v)`, and `code.check(r)` (previously `enc_mapping`, `inv_enc_mapping`, and `chk_mapping`). These methods are now vetorized (i.e., support input arrays of any shape). For example, for a code with dimension $k = 2$, instead of `encoder = BlockEncoder(code); encoder([0, 1, 0, 1])`, use `code.encode([[0, 1], [0, 1]])`.
- Decoder methods are now individual classes: `BCJRDecoder`, `BerlekampDecoder`, `ExhaustiveSearchDecoder`, `ReedDecoder`, `SyndromeTableDecoder`, `ViterbiDecoder`, and `WagnerDecoder`. For example, instead of `decoder = komm.BlockDecoder(code, method="exhaustive-search-hard")`, use `decoder = komm.ExhaustiveSearchDecoder(code, input_type="hard")`. The decoder `__call__` are now vectorized (i.e., support input arrays of any shape). For example, for a code with length $n = 3$, instead of `decoder([0, 1, 0, 1, 1, 0])`, use `decoder([[0, 1, 0], [1, 1, 0]])`.
- The decoders `majority-logic-repetition-code` and `meggitt` were removed for now.
- Renamed `ConvolutionalStreamDecoder` to `ViterbiStreamDecoder`.
- Merged lossless source coding encoders/decoders into code classes.
- Removed `FixedToVariableEncoder`, `FixedToVariableDecoder`, `VariableToFixedEncoder`, `VariableToFixedDecoder`. For example, instead of `encoder = FixedToVariableEncoder(code); output = encoder(input)`, use `output = code.encode(input)`.