# comm.APPDecoder

Decode convolutional code by using APP method

## Description

The `APPDecoder` System object™ performs a posteriori probability (APP) decoding of a convolutional code.

To decode convolutional code by using APP method:

1. Create the `comm.APPDecoder` object and set its properties.

2. Call the object with arguments, as if it were a function.

## Creation

### Syntax

``appDec = comm.APPDecoder``
``appDec = comm.APPDecoder(Name,Value)``
``appDec = comm.APPDecoder(trellis,Name,Value)``

### Description

````appDec = comm.APPDecoder` creates an APP decoder System object, `appDec`, that decodes a convolutional code using the APP method.```

example

````appDec = comm.APPDecoder(Name,Value)` sets properties using one or more name-value pairs. For example, `comm.APPDecoder('Algorithm','True APP')` configures the System object, `appDec`, to implement true a posteriori probability decoding. Enclose each property name in quotes.```

example

````appDec = comm.APPDecoder(trellis,Name,Value)` creates an APP decoder object, `appDec`, with the TrellisStructure property set to `trellis`.```

## Properties

expand all

Unless otherwise indicated, properties are nontunable, which means you cannot change their values after calling the object. Objects lock when you call them, and the `release` function unlocks them.

If a property is tunable, you can change its value at any time.

Trellis description, specified as a MATLAB® structure that contains the trellis description for a rate K/N code. K represents the number of input bit streams, and N represents the number of output bit streams.

You can either use the `poly2trellis` function to create the trellis structure or create it manually. For more about this structure, see Trellis Description of a Convolutional Code and the `istrellis` function.

The trellis structure contains these fields.

Number of symbols input to the encoder, specified as an integer equal to 2K, where K is the number of input bit streams.

Data Types: `double`

Number of symbols output from the encoder, specified as an integer equal to 2N, where N is the number of output bit streams.

Data Types: `double`

Number of states in the encoder, specified as a power of 2.

Data Types: `double`

Next states for all combinations of current states and current inputs, specified as a matrix of integers. The matrix size must be `numStates` by 2K.

Data Types: `double`

Outputs for all combinations of current states and current inputs, specified as a matrix of octal numbers. The matrix size must be `numStates` by 2K.

Data Types: `double`

Data Types: `struct`

Termination method of encoded frame, specified as `'Truncated'` or `'Terminated'`. When you set this property to `'Truncated'`, this System object assumes that the encoder stops after encoding the last symbol in the input frame. When you set this property to `'Terminated'`, this System object assumes that the encoder forces the trellis to end each frame in the all-zeros state by encoding additional symbols. If you use the `comm.ConvolutionalEncoder` System object to generate the encoded frame, this property value must match the property value of the convolutional encoder and this System object.

Data Types: `char` | `string`

Decoding algorithm, specified as `'Max*'`, ```'True APP'```, or `'Max'`. When you set this property to `'True APP'`, this System object implements true APP decoding. When you set this property to any other value, this System object uses approximations to increase the speed of the computations. For more information, see Algorithms.

Data Types: `char` | `string`

Number of scaling bits, specified as an integer in the range [0, 8]. This property specifies the number of bits the decoder uses to scale the input data to avoid losing precision during the computations.

#### Dependencies

To enable this property, set the Algorithm property to `'Max*'`.

Data Types: `double`

Option to enable coded-bit log-likelihood ratio (LLR) output, specified as a numeric or logical `1` (`true`) or `0` (`false`). To disable the second output when you call this System object, set this property to `0` (`false`).

Data Types: `logical`

## Usage

### Syntax

``[LUD,LCD] = appDec(LU,LC)``
``LUD = appDec(LU,LC)``

### Description

````[LUD,LCD] = appDec(LU,LC)` performs APP decoding on the sequence of LLRs of encoder input bits, `LU`, and the sequence of LLRs of encoded bits, `LC`. The System object returns `LUD` and `LCD`. These output values are the updated versions of `LU` and `LC`, respectively, and are obtained based on the encoder information.```
````LUD = appDec(LU,LC)` performs APP decoding with the `LCD` output disabled. To disable the `LCD` output, set the CodedBitLLROutputPort property to `0` (`false`).```

### Input Arguments

expand all

Sequence of LLRs of encoder input data, specified as a real-valued column vector. A positive soft input is interpreted as a logical `1`, and a negative soft input is interpreted as a logical `0`.

Data Types: `single` | `double`

Sequence of LLRs of encoded data, specified as a real-valued column vector of. A positive soft input is interpreted as a logical `1`, and a negative soft input is interpreted as a logical `0`.

Data Types: `single` | `double`

### Output Arguments

expand all

Updated value of LU, returned as a real-valued column vector.

Data Types: `single` | `double`

Updated value of LC, returned as a real-valued column vector.

Data Types: `single` | `double`

Note

If the convolutional code uses an alphabet of 2n possible symbols, where n is the number of bits per input symbol, then the `LC` and `LCD` vector lengths are L × n for some positive integer L. Similarly, if the decoded data uses an alphabet of 2k output symbols, where k is the number of bits per output symbol, then the `LU` and `LUD` vector lengths are L × k .

This System object accepts a column vector input signal with any positive integer value for L. For variable-sized inputs, L can vary during multiple calls.

## Object Functions

To use an object function, specify the System object as the first input argument. For example, to release system resources of a System object named `obj`, use this syntax:

`release(obj)`

expand all

 `step` Run System object algorithm `release` Release resources and allow changes to System object property values and input characteristics `reset` Reset internal states of System object

## Examples

collapse all

Specify noise variance and the frame length in bits. Create convolutional encoder, PSK modulator, and AWGN channel System objects.

```noiseVar = 2e-1; frameLength = 300; convEncoder = comm.ConvolutionalEncoder( ... 'TerminationMethod','Truncated'); pskMod = comm.PSKModulator('BitInput',true,'PhaseOffset',0); awgnChan = comm.AWGNChannel('NoiseMethod','Variance', ... 'Variance',noiseVar);```

Create convolutional APP decoder, PSK demodulator, and error rate System objects.

```appDecoder = comm.APPDecoder(... 'TrellisStructure',poly2trellis(7,[171 133]), ... 'Algorithm','True APP', ... 'CodedBitLLROutputPort',false); pskDemod = comm.PSKDemodulator( ... 'BitOutput',true, ... 'PhaseOffset',0, ... 'DecisionMethod','Approximate log-likelihood ratio', ... 'Variance',noiseVar); errRate = comm.ErrorRate;```

Transmit a convolutionally encoded 8-PSK-modulated bit stream through an AWGN channel. Demodulate the received signal using soft-decision. Decode the demodulated signal using the APP decoder.

```for counter = 1:5 data = randi([0 1],frameLength,1); encodedData = convEncoder(data); modSignal = pskMod(encodedData); receivedSignal = awgnChan(modSignal); demodSignal = pskDemod(receivedSignal); % The APP decoder assumes a polarization of the soft % inputs that is inverse to that of the demodulator % soft outputs. Change the sign of demodulated signal. receivedSoftBits = appDecoder( ... zeros(frameLength,1),-demodSignal); % Convert from soft-decision to hard-decision. receivedBits = double(receivedSoftBits > 0); % Count errors errorStats = errRate(data,receivedBits); end```

Display the error rate information.

```fprintf('Error rate = %f\nNumber of errors = %d\n', ... errorStats(1), errorStats(2))```
```Error rate = 0.000000 Number of errors = 0 ```

Concatenated convolutional codes offer high reliability and have gained in prominence and usage as turbo codes. The `comm.TurboEncoder` and `comm.TurboDecoder` System objects support rate 1/n convolutional codes only. This example shows the parallel concatenation of two rate 2/3 convolutional codes to achieve an effective rate 1/3 turbo code by using `comm.ConvolutionalEncoder` and `comm.APPDecoder` System objects.

System Parameters

```blkLength = 1024; % Block length EbNo = 0:5; % Eb/No values to loop over numIter = 3; % Number of decoding iterations maxNumBlks = 1e2; % Maximum number of blocks per Eb/No value```

Convolutional Encoder/Decoder Parameters

```trellis = poly2trellis([5 4],[23 35 0; 0 5 13]); k = log2(trellis.numInputSymbols); % number of input bits n = log2(trellis.numOutputSymbols); % number of output bits intrIndices = randperm(blkLength/k)'; % Random interleaving decAlg = 'True App'; % Decoding algorithm modOrder = 2; % PSK-modulation order```

Initialize System Objects

Initialize Systems object™ for convolutional encoding, APP Decoding, BPSK modulation and demodulation, AGWN channel, and error rate computation. The demodulation output soft bits using a log-likelihood ratio method.

```cEnc1 = comm.ConvolutionalEncoder( ... 'TrellisStructure',trellis, ... 'TerminationMethod','Truncated'); cEnc2 = comm.ConvolutionalEncoder( ... 'TrellisStructure',trellis, ... 'TerminationMethod','Truncated'); cAPPDec1 = comm.APPDecoder( ... 'TrellisStructure',trellis, ... 'TerminationMethod','Truncated', ... 'Algorithm',decAlg); cAPPDec2 = comm.APPDecoder( ... 'TrellisStructure',trellis, ... 'TerminationMethod','Truncated', ... 'Algorithm',decAlg); bpskMod = comm.BPSKModulator; bpskDemod = comm.BPSKDemodulator( ... 'DecisionMethod','Log-likelihood ratio', ... 'VarianceSource','Input port'); awgnChan = comm.AWGNChannel( ... 'NoiseMethod','Variance', ... 'VarianceSource','Input port'); bitError = comm.ErrorRate; % BER measurement```

Frame Processing Loop

Loop through a range of ${\mathit{E}}_{\mathrm{b}}/{\mathit{N}}_{0}$ values to generate results for BER performance. The `helperTurboEnc` and `helperTurboDec` helper functions perform the turbo encoding and decoding.

```ber = zeros(length(EbNo),1); bitsPerSymbol = log2(modOrder); turboEncRate = k/(2*n); for ebNoIdx = 1:length(EbNo) % Calculate the noise variance from EbNo EsNo = EbNo(ebNoIdx) + 10*log10(bitsPerSymbol); SNRdB = EsNo + 10*log10(turboEncRate); % Account for code rate noiseVar = 10^(-SNRdB/10); for numBlks = 1:maxNumBlks % Generate binary data data = randi([0 1],blkLength,1); % Turbo encode the data [encodedData,outIndices] = helperTurboEnc( ... data,cEnc1,cEnc2, ... trellis,blkLength,intrIndices); % Modulate the encoded data modSignal = bpskMod(encodedData); % Pass the modulated signal through an AWGN channel receivedSignal = awgnChan(modSignal,noiseVar); % Demodulate the noisy signal using LLR to output soft bits demodSignal = bpskDemod(receivedSignal,noiseVar); % Turbo decode the demodulated data receivedBits = helperTurboDec( ... -demodSignal,cAPPDec1,cAPPDec2, ... trellis,blkLength,intrIndices,outIndices,numIter); % Calculate the error statistics errorStats = bitError(data,receivedBits); end ber(ebNoIdx) = errorStats(1); reset(bitError); end```

Display Results

While the practical wireless systems, such as LTE and CCSDS, specify base rate-1/n convolutional codes for turbo codes, the results show use of higher rate convolutional codes as turbo codes is viable.

```figure; semilogy(EbNo, ber, '*-'); grid on; xlabel('E_b/N_0 (dB)'); ylabel('BER'); title('High Rate Convolutional Codes for Turbo Coding'); legend(['N = ' num2str(blkLength) ', ' num2str(numIter) ' iterations']);```

Helper Functions

```function [yEnc,outIndices] = helperTurboEnc( ... data,hCEnc1,hCEnc2,trellis,blkLength,intrIndices) % Turbo encoding using two parallel convolutional encoders. % No tail bits handling and assumes no output stream puncturing. % Trellis parameters k = log2(trellis.numInputSymbols); n = log2(trellis.numOutputSymbols); cLen = blkLength*n/k; punctrVec = [0;0;0;0;0;0]; % assumes all streams are output N = length(find(punctrVec==0)); % Encode random data bits y1 = hCEnc1(data); y2 = hCEnc2( ... reshape(intrlv(reshape(data,k,[])',intrIndices)',[],1)); y1D = reshape(y1(1:cLen),n,[]); y2D = reshape(y2(1:cLen),n,[]); yDTemp = [y1D; y2D]; y = yDTemp(:); % Generate output indices vector using puncturing vector idx = 0 : 2*n : (blkLength - 1)*2*(n/k); punctrVecIdx = find(punctrVec==0); dIdx = repmat(idx, N, 1) + punctrVecIdx; outIndices = dIdx(:); yEnc = y(outIndices); end function yDec = helperTurboDec( ... yEnc,cAPPDec1,cAPPDec2,trellis, ... blkLength,intrIndices,inIndices,numIter) % Turbo decoding using two a-posteriori probability (APP) decoders % Trellis parameters k = log2(trellis.numInputSymbols); n = log2(trellis.numOutputSymbols); rCodLen = 2*(n/k)*blkLength; typeyEnc = class(yEnc); % Re-order encoded bits according to outIndices x = zeros(rCodLen,1); x(inIndices) = yEnc; % Generate output of first encoder yD = reshape(x(1:rCodLen),2*n,[]); lc1D = yD(1:n, :); Lc1_in = lc1D(:); % Generate output of second encoder lc2D = yD(n+1:2*n, :); Lc2_in = lc2D(:); % Initialize unencoded data input Lu1_in = zeros(blkLength,1,typeyEnc); % Turbo Decode out1 = zeros(blkLength/k,k,typeyEnc); for iterIdx = 1 : numIter [Lu1_out, ~] = cAPPDec1(Lu1_in,Lc1_in); tmp = Lu1_out(1:blkLength); Lu2_in = reshape(tmp,k,[])'; [Lu2_out, ~] = cAPPDec2( ... reshape(Lu2_in(intrIndices, :)',[],1),Lc2_in); out1(intrIndices, :) = reshape(Lu2_out(1:blkLength),k,[])'; Lu1_in = reshape(out1',[],1); end % Calculate llr and decoded bits for the final iteration llr = reshape(out1', [], 1) + Lu1_out(1:blkLength); yDec = cast((llr>=0), typeyEnc); end```

## Algorithms

This System object implements the soft-input-soft-output APP decoding algorithm according to [1] and [2].

The `'True APP'` option of the `Algorithm` property implements APP decoding as per equations 20–23 in section V of [1]. To gain speed, the `'Max*'` and `'Max'` values of the `Algorithm` property approximate expressions like $\mathrm{log}\sum _{i}\mathrm{exp}\left({a}_{i}\right)$ by other quantities. The `'Max'` option uses max(ai) as the approximation. The `'Max*'` option uses max(ai) plus a correction term given by the expression $\mathrm{ln}\left(1+\mathrm{exp}\left(-|{a}_{i-1}-{a}_{i}|\right)\right)$.

Setting the `Algorithm` property to `'Max*'` enables the `NumScalingBits` property of this System object. This property denotes the number of bits by which this System object scales the data it processes (multiplies the input by 2`NumScalingBits` and divides the pre-output by the same factor). Use this property to avoid losing precision during computations.

## References

[1] Benedetto, S., G. Montorsi, D. Divsalar, and F. Pollara. "A Soft-Input Soft-Output Maximum A Posterior (MAP) Module to Decode Parallel and Serial Concatenated Codes." Jet Propulsion Lab TDA Progress Report, 42–127, (November 1996).

[2] Viterbi, A.J. “An Intuitive Justification and a Simplified Implementation of the MAP Decoder for Convolutional Codes.” IEEE Journal on Selected Areas in Communications 16, no. 2 (February 1998): 260–64. https://doi.org/10.1109/49.661114.

[3] Benedetto, S., and G. Montorsi. “Performance of Continuous and Blockwise Decoded Turbo Codes.” IEEE Communications Letters 1, no. 3 (May 1997): 77–79. https://doi.org/10.1109/4234.585802.

## Version History

Introduced in R2012a