Main Content


Decode convolutional code by using APP method


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.

To learn more about how System objects work, see What Are System Objects?



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


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.


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


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.

For more information on changing property values, see System Design in MATLAB Using System Objects.

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.

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

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

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.

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: 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.


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



[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.

This object accepts variable-size inputs. After the object is locked, you can change the size of each input channel, but you cannot change the number of channels. For more information, see Variable-Size Signal Support with System Objects.

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


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:


expand all

stepRun System object algorithm
releaseRelease resources and allow changes to System object property values and input characteristics
resetReset internal states of System object


collapse all

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

M = 8;
snr = 7;
frameLength = 300;
convEncoder = comm.ConvolutionalEncoder( ...

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

appDecoder = comm.APPDecoder(...
    'TrellisStructure',poly2trellis(7,[171 133]), ...
    'Algorithm','True APP', ...
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);
     psksig = pskmod(encodedData,M,InputType='bit');
     [rxsig,noisevar] = awgn(psksig,snr);
     demodsig = pskdemod(rxsig,M, ...
         OutputType='approxllr', ...
     % 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( ...
     % Convert from soft-decision to hard-decision.
     receivedBits = double(receivedSoftBits > 0);
     % Count errors
     errorStats = errRate(data,receivedBits);

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, AWGN channel, and error rate computation. The demodulation output soft bits using a log-likelihood ratio method.

cEnc1 = comm.ConvolutionalEncoder( ...
    'TrellisStructure',trellis, ...
cEnc2 = comm.ConvolutionalEncoder( ...
    'TrellisStructure',trellis, ...
cAPPDec1 = comm.APPDecoder( ...
    'TrellisStructure',trellis, ...
    'TerminationMethod','Truncated', ...
cAPPDec2 = comm.APPDecoder( ...
    'TrellisStructure',trellis, ...
    'TerminationMethod','Truncated', ...

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 Eb/N0 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, ...

        % 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, ...
        % Calculate the error statistics
        errorStats = bitError(data,receivedBits);        
    ber(ebNoIdx) = errorStats(1);

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.

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

Helper Functions

function [yEnc,outIndices] = helperTurboEnc( ...
% 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( ...
    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);

function yDec = helperTurboDec( ...
    yEnc,cAPPDec1,cAPPDec2,trellis, ...
% 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);
    % Calculate llr and decoded bits for the final iteration
    llr = reshape(out1', [], 1) + Lu1_out(1:blkLength);
    yDec = cast((llr>=0), typeyEnc);


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 logiexp(ai) 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 ln(1+exp(|ai1ai|)).

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 2NumScalingBits and divides the pre-output by the same factor). Use this property to avoid losing precision during computations.


[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.

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

Extended Capabilities

Version History

Introduced in R2012a