⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decode.m

📁 数字通信第四版原书的例程
💻 M
字号:
function [msg, err, ccode, cerr] = decode(code, n, k, method, opt1, opt2, opt3, opt4)
%DECODE Error-control code decoding computation.
%       MSG = DECODE(CODE, N, K) decodes binary codeword in CODE using Hamming
%       code method. The code word length is N and the message length is K.
%       The format of CODE can be either a vector or an N column matrix. A
%       Hamming code has codeword length 2^M -1, where M is an integer no less
%       than 3. The message length is 2^M - M - 1. Hamming code is a single 
%       error-correction code.
%
%       MSG = DECODE(CODE, N, K, METHOD, OPT1, OPT2, OPT3, OPT4) decodes the
%       codeword signal CODE using an error-control coding method such that
%       the message length is K and code word length is N with the coding
%       method as specified in variable METHOD. OPT1 to OPT4 are extra
%       optional parameters used in some of the methods.
%       
%        METHOD          ENCODE SCHEME
%       'hamming'       Hamming code
%       'linear'         Linear block code
%       'cyclic'        Cyclic code
%       'bch'           BCH code
%       'rs'            Reed-Solomon code
%       'convol'        Convolution code
%
%       To use all of the methods, message signal in CODE could be a binary
%       vector or a L-column matrix. In using methods other than the "rs"
%       method, L equals to N. In using "rs" method, L = M, where 
%       N = 2^M - 1. M is a integer >= 3. CODE can also be a non-negative
%       integer in the range of [0, 2^L-1]. In this case, you have to add 
%       '/decimal' in the method specification. For example, 'bch' is 
%       equivalent to 'bch/binary'. 'bch/decimal' means the data in MSG is
%       binary. Except 'rs' method, MSG could be only be a vector when 
%       using decimal method.
%
%       The output MSG contains decoded message. The format of MSG matches the
%       format of CODE. When CODE is a N-column matrix, the output MSG is a 
%       K-column matrix. 
%
%       When the format of the inputted CODE is not the same as the output
%       of function ENCODE, this function stops processing.
%
%       [MSG, ERR] = DECODE(...) indicates the number of errors detected in
%       the decoding. If the element in ERR is a negative number, it means
%       that more errors occurred than the error-correction capability.
%       
%       [MSG, ERR, CCODE] = DECODE(...) outputs the corrected CODE in CCODE.
%
%       [MSG, ERR, CCODE, CERR] = DECODE(...) outputs errors corresponding to
%       each row of CCODE.
%
%       Use DECODE(METHOD) to view the help for a specific method.
%
%       See also: ENCODE, BCHPOLY, BCHDECO, RSPOLY, RSDECO, CYCLPOLY, CYCLGEN.

%       Wes Wang 8/16/94, 10/3/95
%       Copyright (c) 1995-96 by The MathWorks, Inc.
%       $Revision: 1.1 $  $Date: 1996/04/01 17:56:30 $

% routine check
if (nargin == 2) 
    error('Not enough input parameters')
elseif nargin == 3
    method = 'hamming';
elseif nargin > 3
    method = lower(method);
end;

if nargin < 1
    feval('help', 'decode');
    return;
elseif isstr(code)
    method = lower(deblank(code));
    if length(method) < 2
        error('Invalid method option for decode.')
    end
    if nargin == 1
        addition = 'See also ENCODE, BCHPOLY, HAMMGEN, GEN2PAR, SIM2GEN, CYCLPOLY.';
        callhelp('decode.hlp',method(1:2),addition);
    else
        disp('Warning: Worng number of input variable for DECODE.')
    end;
    return;
elseif ~isempty(findstr(method, 'rs'))
    % Reed-Solomon method.
    if ~isempty(findstr(method, 'pow'))
        type_flag = 'power';
    elseif ~isempty(findstr(method, 'dec'))
        type_flag = 'decimal';
    else
        type_flag = 'binary';
    end;
    if nargin > 4
        n = opt1;
    end;
    if nargout <= 1
        msg = rsdeco(code, n, k, type_flag);
    elseif nargout == 2
        [msg, err] = rsdeco(code, n, k, type_flag);
    elseif nargin == 3
        [msg, err, ccode] = rsdeco(code, n, k, type_flag);
    elseif nargin == 4
        [msg, err, ccode, cerr] = rsdeco(code, n, k, type_flag);
    else
        error('Too many output parameters.');
    end;
else
    % make msg to be a column vector when it is a vector.
    if min(size(code)) == 1
        code = code(:);
    end;

    [n_code, m_code] = size(code);

    if ~isempty(findstr(method, 'decimal'))
        type_flag = 1;      % decimal
        if m_code > 1
            method = method(1:find(method=='/'));
            error(['The MSG format for ',method,' code with decimal style can only be a vector'])
        else
            if ~isempty([find(code > 2^n-1); find(code < 0); find(floor(code)~=code)])
                error('MSG contains invalid elements')
            end;
        end;
        code = de2bi(code, k);
        [n_code, m_code] = size(code);
    else
        type_flag = 0;      % binary matrix
        if ~isempty([find(code > 1); find(code < 0); find(floor(code)~=code)])
            error('CODE contains invalid elements')
        end;
        if m_code == 1
            type_flag = 2;  % binary vector
            [code, added] = vec2mat(code, n);
            if added
                disp('Warning: The input CODE does not the exact format as output of ENCODE.');
                disp('         Please check your computation procedures for possible errors.');
            end;
            [n_code, m_code] = size(code);
        elseif m_code ~= n
            error('Matrix CODE must have column length same as variable N in ENCODE');
        end;
    end;
    % at this stage CODE is a N-colomn matrix
    if ~isempty(findstr(method, 'bch'))
        % BCH code.
        if nargin <= 4
            t = 0;
        else
            t = opt1;
        end;
        if ~(t>0)
            [tmp1, tmp2, tmp3, tmp4, t] = bchpoly(n, k);
        end;
        if nargin <= 5
            [msg, err, ccode] = bchdeco(code, k, t);            
        else
            [msg, err, ccode] = bchdeco(code, k, t, opt2);
        end;
    elseif ~isempty(findstr(method, 'convol'))
        if nargin < 5
            error('Not enough input parameters.')
        elseif nargin == 5
            [msg, err, ccode] = viterbi(code, opt1);
        elseif nargin == 6
            [msg, err, ccode] = viterbi(code, opt1, opt2);
        elseif nargin == 7
            [msg, err, ccode] = viterbi(code, opt1, opt2, opt3);
        else
            [msg, err, ccode] = viterbi(code, opt1, opt2, opt3, opt4);
        end;
    else
        % the msg calculation is the same, different trt and h calculation.
        % for hamming, block and cyclic code.
        if ~isempty(findstr(method, 'hamming'))
            % hamming code.
            m = n - k;
            if 2^m - 1 ~= n
                error('The specified code-word length and message length are not valid.')
            end;
            if nargin <= 4
                [h, gen] = hammgen(m);
            else
                [h, gen] = hammgen(m, opt1);
            end;
            % truth table.
            trt = htruthtb(gen);
        elseif ~isempty(findstr(method, 'linear'))
            % block code.
            if nargin < 5
                error('The generator matrix must be specified for linear block code.');
            end;
            [n_opt1, m_opt1] = size(opt1);
            if (m_opt1 ~= n) | (n_opt1 ~= k)
                error('The matrix dimension for opt1 is not valid');
            end;
%            h = opt1;
%            gen = gen2par(h);
            gen = opt1;
            h = gen2par(gen);
            if nargin < 6
                opt2 = htruthtb(gen);
            end;
            trt = opt2;
        elseif ~isempty(findstr(method, 'cyclic'))
            % cyclic code.
            if nargin < 4
                error('Not enough input parameters.')
            elseif nargin < 5
                opt1 = cyclpoly(n, k);
            end;
            [h, gen] = cyclgen(n, opt1);
            if nargin < 6
                opt2 = htruthtb(gen);
            end;
            trt = opt2;
        else
          error(['Unknown encode method ''',method,'''']);
        end;

        %calculation:
        syndrome = rem(code * h', 2);

        % error location:
        err = bi2de(fliplr(syndrome));
        err_loc = trt(err + 1, :);

        % corrected code
        ccode = rem(err_loc + code, 2);

        % corrected message
        msg = ccode(:, n-k+1:n);

        % check the error number for the corresponding msg.
        if nargout > 1
            err = sum(err_loc')';       % number of errors has been found.
            err_loc = rem(msg * gen, 2);    % bring back the code to check the error
            indx = find(sum(abs(err_loc - ccode)') > 0); % find the error location
            err(indx) = indx - indx - 1;             % assigne the uncorrected one to be -1
            indx = find(sum(abs(err_loc - code)') ~= err');
            err(indx) = indx - indx - 1;             % assigne the uncorrected one to be -1
        end;
        % finish the calculation for hamming code, cyclic code and linear block code.
    end;
    % convert back to the original strucutre.
    if nargout > 3
        cerr = err;
    end;
    if type_flag == 1
        msg = bi2de(msg);
        if nargout > 2
            ccode = bi2de(ccode);
        end;
    elseif type_flag == 2
        msg = msg';
        msg = msg(:);
        if nargout > 1
            err = err * ones(1, k);
            err = err';
            err=err(:);
        end;
        if nargout > 2
            ccode = ccode';
            ccode = ccode(:);
        end;
        if nargout > 3
            cerr = cerr * ones(1, n);
            cerr = cerr';
            cerr = cerr(:);
        end;    
    end;
end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -