๐ป MATLAB Tutorial
ECOM 561 - Information Theory and Coding | Spring 2026
๐ Table of Contents
๐ Introduction & Setup
This tutorial provides MATLAB implementations for key concepts in Information Theory and Coding. These examples will help you understand theoretical concepts through practical implementation and prepare you for course assignments and projects.
๐ Course Learning Outcome
CLO-6: Evaluate the performance of selected coding algorithms on some error-correction and coding techniques using MATLAB.
Required Toolboxes
% Check if Communications Toolbox is installed
v = ver;
hasCommToolbox = any(strcmp({v.Name}, 'Communications Toolbox'));
if hasCommToolbox
disp('โ Communications Toolbox is installed')
else
disp('โ Communications Toolbox not found - some functions may not work')
end
% Alternative: Use built-in functions for most examples in this tutorial
Basic Setup Template
%% ECOM 561 - Information Theory and Coding
% Assignment/Project: [Title]
% Student Name: [Your Name]
% Student ID: [Your ID]
% Date: [Date]
% Description: [Brief description of what this code does]
clear all; % Clear all variables
close all; % Close all figures
clc; % Clear command window
%% Main Code Starts Here
% Your implementation goes here
๐ก Tip: Using Sections
Use %% to create sections in your code. Press Ctrl+Enter to run the current section only. This is very useful for testing parts of your code!
๐ Entropy & Information Measures CLO-1
๐ Theory Review
Self-Information: I(x) = -logโ(P(x)) bits
Entropy: H(X) = -ฮฃ P(xแตข) logโ(P(xแตข)) bits
Joint Entropy: H(X,Y) = -ฮฃแตข ฮฃโฑผ P(xแตข,yโฑผ) logโ(P(xแตข,yโฑผ))
Mutual Information: I(X;Y) = H(X) + H(Y) - H(X,Y)
Self-Information Calculator
function I = self_information(p)
% SELF_INFORMATION Calculate self-information of an event
% I = self_information(p) returns the self-information in bits
% Input: p - probability of the event (0 < p <= 1)
% Output: I - self-information in bits
if p <= 0 || p > 1
error('Probability must be in range (0, 1]');
end
I = -log2(p);
end
%% Example Usage
% Event with probability 0.5 (fair coin flip)
p = 0.5;
I = self_information(p);
fprintf('Self-information for P=%.2f: %.4f bits\n', p, I);
% Multiple events
probs = [0.9, 0.5, 0.1, 0.01];
for i = 1:length(probs)
I = self_information(probs(i));
fprintf('P = %.2f โ I = %.4f bits\n', probs(i), I);
end
Entropy Calculator
function H = calculate_entropy(P)
% CALCULATE_ENTROPY Calculate entropy of a discrete source
% H = calculate_entropy(P) returns entropy in bits
% Input: P - probability distribution (must sum to 1)
% Output: H - entropy in bits
% Validate input
if abs(sum(P) - 1) > 1e-10
error('Probabilities must sum to 1. Sum = %.6f', sum(P));
end
if any(P < 0)
error('Probabilities cannot be negative');
end
% Calculate entropy (handle P=0 case)
H = 0;
for i = 1:length(P)
if P(i) > 0
H = H - P(i) * log2(P(i));
end
end
end
%% Example: Binary Source Entropy
p = 0:0.01:1;
H_binary = zeros(size(p));
for i = 1:length(p)
if p(i) == 0 || p(i) == 1
H_binary(i) = 0;
else
H_binary(i) = calculate_entropy([p(i), 1-p(i)]);
end
end
% Plot binary entropy function
figure('Position', [100, 100, 800, 500]);
plot(p, H_binary, 'b-', 'LineWidth', 2);
xlabel('Probability p', 'FontSize', 12);
ylabel('H(p) [bits]', 'FontSize', 12);
title('Binary Entropy Function', 'FontSize', 14);
grid on;
xlim([0 1]);
ylim([0 1.1]);
% Mark maximum entropy point
hold on;
plot(0.5, 1, 'ro', 'MarkerSize', 10, 'MarkerFaceColor', 'r');
text(0.52, 1, 'Maximum at p=0.5', 'FontSize', 11);
hold off;
Joint and Conditional Entropy
function [H_XY, H_X, H_Y, H_X_given_Y, H_Y_given_X, I_XY] = joint_conditional_entropy(P_XY)
% JOINT_CONDITIONAL_ENTROPY Calculate all entropy measures
% Input: P_XY - joint probability matrix P(X,Y)
% Output: Various entropy measures
% Marginal distributions
P_X = sum(P_XY, 2); % Sum over Y (columns)
P_Y = sum(P_XY, 1); % Sum over X (rows)
% Individual entropies
H_X = calculate_entropy(P_X);
H_Y = calculate_entropy(P_Y);
% Joint entropy H(X,Y)
H_XY = 0;
[m, n] = size(P_XY);
for i = 1:m
for j = 1:n
if P_XY(i,j) > 0
H_XY = H_XY - P_XY(i,j) * log2(P_XY(i,j));
end
end
end
% Conditional entropies
H_X_given_Y = H_XY - H_Y; % H(X|Y) = H(X,Y) - H(Y)
H_Y_given_X = H_XY - H_X; % H(Y|X) = H(X,Y) - H(X)
% Mutual information
I_XY = H_X + H_Y - H_XY; % I(X;Y) = H(X) + H(Y) - H(X,Y)
end
%% Example: Binary Symmetric Channel Analysis
p = 0.1; % Crossover probability
% Assume uniform input: P(X=0) = P(X=1) = 0.5
P_XY = [0.5*(1-p), 0.5*p; % P(X=0,Y=0), P(X=0,Y=1)
0.5*p, 0.5*(1-p)]; % P(X=1,Y=0), P(X=1,Y=1)
[H_XY, H_X, H_Y, H_X_given_Y, H_Y_given_X, I_XY] = joint_conditional_entropy(P_XY);
fprintf('===== Binary Symmetric Channel Analysis (p=%.2f) =====\n', p);
fprintf('H(X) = %.4f bits\n', H_X);
fprintf('H(Y) = %.4f bits\n', H_Y);
fprintf('H(X,Y) = %.4f bits\n', H_XY);
fprintf('H(X|Y) = %.4f bits\n', H_X_given_Y);
fprintf('I(X;Y) = %.4f bits\n', I_XY);
โ Key Relationships to Remember
- Chain Rule: H(X,Y) = H(X) + H(Y|X) = H(Y) + H(X|Y)
- Conditioning Reduces Entropy: H(X|Y) โค H(X)
- Mutual Information: I(X;Y) = H(X) - H(X|Y) โฅ 0
- Maximum Entropy: Uniform distribution maximizes entropy
๐ฆ Source Coding Fundamentals CLO-2
๐ Source Coding Theorem
For a discrete memoryless source with entropy H(X), the average codeword length L satisfies:
H(X) โค L < H(X) + 1
The minimum average length approaches H(X) for optimal prefix-free codes.
Kraft Inequality Checker
function [K, is_valid] = kraft_inequality(lengths, r)
% KRAFT_INEQUALITY Check if codeword lengths satisfy Kraft inequality
% Input: lengths - vector of codeword lengths
% r - radix/alphabet size (default: 2 for binary)
% Output: K - Kraft sum
% is_valid - true if K <= 1 (prefix-free code exists)
if nargin < 2
r = 2; % Binary by default
end
K = sum(r.^(-lengths));
is_valid = K <= 1;
fprintf('===== Kraft Inequality Check =====\n');
fprintf('Codeword lengths: [%s]\n', num2str(lengths));
fprintf('Kraft sum K = %.4f\n', K);
if is_valid
fprintf('โ K โค 1: A prefix-free code EXISTS\n');
else
fprintf('โ K > 1: NO prefix-free code exists\n');
end
end
%% Examples
fprintf('Example 1: Valid code\n');
kraft_inequality([1, 2, 3, 3], 2);
fprintf('\nExample 2: Invalid lengths\n');
kraft_inequality([1, 1, 2, 2], 2);
๐ณ Huffman Coding CLO-2
๐ Huffman Algorithm
Huffman coding produces an optimal prefix-free code:
- Sort symbols by probability (ascending)
- Combine two lowest probability symbols
- Repeat until single node remains
- Assign bits by traversing tree (0=left, 1=right)
Huffman Coding Implementation
function [codes, lengths, L_avg] = huffman_encode(symbols, P)
% HUFFMAN_ENCODE Generate Huffman codes for given symbols
% Input: symbols - cell array of symbol names
% P - probability distribution
% Output: codes - cell array of binary code strings
% lengths - codeword lengths
% L_avg - average codeword length
n = length(P);
% Initialize nodes
nodes = cell(1, n);
for i = 1:n
nodes{i}.prob = P(i);
nodes{i}.symbols = {i};
nodes{i}.code = '';
end
% Build Huffman tree
while length(nodes) > 1
% Sort by probability
probs = cellfun(@(x) x.prob, nodes);
[~, idx] = sort(probs);
nodes = nodes(idx);
% Combine two smallest nodes
new_node.prob = nodes{1}.prob + nodes{2}.prob;
new_node.left = nodes{1};
new_node.right = nodes{2};
new_node.symbols = [nodes{1}.symbols, nodes{2}.symbols];
% Remove combined nodes and add new node
nodes = nodes(3:end);
nodes{end+1} = new_node;
end
% Generate codes by traversing tree
codes = cell(1, n);
lengths = zeros(1, n);
function traverse(node, code)
if isfield(node, 'left')
traverse(node.left, [code '0']);
traverse(node.right, [code '1']);
else
idx = node.symbols{1};
codes{idx} = code;
lengths(idx) = length(code);
end
end
traverse(nodes{1}, '');
% Calculate average length
L_avg = sum(P .* lengths);
% Display results
H = calculate_entropy(P);
fprintf('===== Huffman Coding Results =====\n');
fprintf('Symbol | Prob | Length | Code\n');
fprintf('-------|--------|--------|----------\n');
for i = 1:n
fprintf(' %s | %.4f | %d | %s\n', symbols{i}, P(i), lengths(i), codes{i});
end
fprintf('\nEntropy H(X) = %.4f bits\n', H);
fprintf('Average Length L = %.4f bits\n', L_avg);
fprintf('Efficiency = %.2f%%\n', H/L_avg*100);
end
%% Example
symbols = {'A', 'B', 'C', 'D', 'E'};
P = [0.4, 0.2, 0.2, 0.1, 0.1];
[codes, lengths, L_avg] = huffman_encode(symbols, P);
๐ Lempel-Ziv Coding CLO-2
๐ LZ78 Algorithm
Dictionary-based compression that builds a codebook dynamically:
- Start with empty dictionary
- Read input until finding longest match in dictionary
- Output (index, next_symbol) pair
- Add new phrase to dictionary
LZ78 Encoder
function [output, dictionary] = lz78_encode(input)
% LZ78_ENCODE Encode a string using LZ78 algorithm
% Input: input - string to encode
% Output: output - cell array of (index, symbol) pairs
% dictionary - final dictionary
dictionary = {''}; % Start with empty string
output = {};
i = 1;
fprintf('===== LZ78 Encoding Process =====\n');
while i <= length(input)
% Find longest match in dictionary
match_idx = 0;
match_len = 0;
for j = 1:length(dictionary)
dict_entry = dictionary{j};
entry_len = length(dict_entry);
if i + entry_len - 1 <= length(input)
if strcmp(input(i:i+entry_len-1), dict_entry) && entry_len > match_len
match_idx = j - 1;
match_len = entry_len;
end
end
end
% Get next symbol after match
next_pos = i + match_len;
if next_pos <= length(input)
next_symbol = input(next_pos);
else
next_symbol = '';
end
% Output pair
output{end+1} = {match_idx, next_symbol};
% Add new phrase to dictionary
if ~isempty(next_symbol)
new_phrase = [dictionary{match_idx+1}, next_symbol];
dictionary{end+1} = new_phrase;
end
i = next_pos + 1;
end
fprintf('Final Dictionary: {%s}\n', strjoin(dictionary(2:end), ', '));
end
%% Example
input_string = 'AABABAABAB';
fprintf('Input: %s\n\n', input_string);
[encoded, dict] = lz78_encode(input_string);
๐ก Channel Capacity CLO-3
๐ Shannon's Channel Capacity
Binary Symmetric Channel (BSC):
C = 1 - H(p) = 1 + p logโ(p) + (1-p) logโ(1-p)
AWGN Channel:
C = W logโ(1 + SNR) bits/second
Binary Symmetric Channel Capacity
function C = bsc_capacity(p)
% BSC_CAPACITY Calculate capacity of Binary Symmetric Channel
% Input: p - crossover probability (error probability)
% Output: C - channel capacity in bits per channel use
if p == 0 || p == 1
C = 1; % Perfect channel
else
H_p = -p*log2(p) - (1-p)*log2(1-p); % Binary entropy
C = 1 - H_p;
end
end
%% Plot BSC Capacity vs Error Probability
p = 0:0.001:0.5;
C = zeros(size(p));
for i = 1:length(p)
C(i) = bsc_capacity(p(i));
end
figure('Position', [100, 100, 800, 500]);
plot(p, C, 'b-', 'LineWidth', 2);
xlabel('Crossover Probability p', 'FontSize', 12);
ylabel('Channel Capacity C (bits/use)', 'FontSize', 12);
title('Binary Symmetric Channel Capacity', 'FontSize', 14);
grid on;
xlim([0 0.5]);
ylim([0 1]);
AWGN Channel Capacity
function C = awgn_capacity(SNR_dB, W)
% AWGN_CAPACITY Calculate capacity of AWGN channel
% Input: SNR_dB - Signal-to-noise ratio in dB
% W - Bandwidth in Hz (default: 1 for normalized)
% Output: C - Channel capacity in bits/second
if nargin < 2
W = 1;
end
SNR_linear = 10^(SNR_dB/10);
C = W * log2(1 + SNR_linear);
end
%% Plot AWGN Capacity vs SNR
SNR_dB = -10:0.5:30;
C = zeros(size(SNR_dB));
for i = 1:length(SNR_dB)
C(i) = awgn_capacity(SNR_dB(i), 1);
end
figure('Position', [100, 100, 800, 500]);
plot(SNR_dB, C, 'b-', 'LineWidth', 2);
xlabel('SNR (dB)', 'FontSize', 12);
ylabel('Channel Capacity C (bits/s/Hz)', 'FontSize', 12);
title('AWGN Channel Capacity (Shannon Limit)', 'FontSize', 14);
grid on;
๐ฒ Linear Block Codes CLO-4
๐ Linear Block Code Basics
An (n, k) linear block code encodes k information bits into n coded bits.
Generator Matrix G: c = m ร G
Parity-Check Matrix H: c ร HT = 0 for valid codewords
Syndrome: s = r ร HT (non-zero indicates errors)
Hamming (7,4) Code Implementation
%% Hamming (7,4) Code - Complete Implementation
% Parameters: n=7 (codeword length), k=4 (message length), d_min=3
clear all; close all; clc;
%% Generator Matrix (Systematic Form: G = [I_k | P])
G = [1 0 0 0 1 1 0;
0 1 0 0 1 0 1;
0 0 1 0 0 1 1;
0 0 0 1 1 1 1];
% Parity-check matrix H = [P' | I_(n-k)]
H = [1 1 0 1 1 0 0;
1 0 1 1 0 1 0;
0 1 1 1 0 0 1];
fprintf('===== Hamming (7,4) Code =====\n\n');
fprintf('Generator Matrix G:\n');
disp(G);
fprintf('Parity-Check Matrix H:\n');
disp(H);
%% Verify G and H relationship: G * H' = 0
GHt = mod(G * H', 2);
fprintf('Verification G ร H^T (should be all zeros):\n');
disp(GHt);
%% Generate all codewords
fprintf('\n===== All 16 Codewords =====\n');
fprintf('Message | Codeword | Weight\n');
fprintf('--------|-------------|-------\n');
all_messages = dec2bin(0:15, 4) - '0';
all_codewords = mod(all_messages * G, 2);
for i = 1:16
msg = num2str(all_messages(i,:), '%d');
cw = num2str(all_codewords(i,:), '%d');
wt = sum(all_codewords(i,:));
fprintf(' %s | %s | %d\n', msg, cw, wt);
end
% Minimum distance
weights = sum(all_codewords, 2);
d_min = min(weights(weights > 0));
fprintf('\nMinimum distance d_min = %d\n', d_min);
fprintf('Error correction capability: %d error\n', floor((d_min-1)/2));
Encoding and Syndrome Decoding
function codeword = hamming_encode(message, G)
% HAMMING_ENCODE Encode message using generator matrix
codeword = mod(message * G, 2);
end
function [syndrome, error_pos] = hamming_syndrome(received, H)
% HAMMING_SYNDROME Calculate syndrome and find error position
syndrome = mod(received * H', 2);
if all(syndrome == 0)
error_pos = 0; % No error
else
error_pos = bi2de(syndrome, 'left-msb');
end
end
function corrected = hamming_correct(received, H)
% HAMMING_CORRECT Correct single-bit error
[syndrome, error_pos] = hamming_syndrome(received, H);
corrected = received;
if error_pos > 0
corrected(error_pos) = mod(corrected(error_pos) + 1, 2);
fprintf('Error detected at position %d, corrected.\n', error_pos);
elseif error_pos == 0
fprintf('No error detected.\n');
end
end
%% Example: Encode, Add Error, Decode
G = [1 0 0 0 1 1 0;
0 1 0 0 1 0 1;
0 0 1 0 0 1 1;
0 0 0 1 1 1 1];
H = [1 1 0 1 1 0 0;
1 0 1 1 0 1 0;
0 1 1 1 0 0 1];
message = [1 0 1 1];
fprintf('Original message: %s\n', num2str(message, '%d'));
codeword = hamming_encode(message, G);
fprintf('Encoded codeword: %s\n', num2str(codeword, '%d'));
% Introduce single-bit error
error_position = 3;
received = codeword;
received(error_position) = mod(received(error_position) + 1, 2);
fprintf('\nReceived with error at position %d: %s\n', error_position, num2str(received, '%d'));
corrected = hamming_correct(received, H);
fprintf('Corrected codeword: %s\n', num2str(corrected, '%d'));
fprintf('Matches original: %s\n', string(isequal(corrected, codeword)));
โป๏ธ Cyclic Codes CLO-4
๐ Cyclic Code Properties
A cyclic code is a linear block code where any cyclic shift of a codeword is also a codeword.
Generator Polynomial g(x): Divides xn + 1
CRC Implementation
function [codeword, fcs] = crc_encode(data, generator)
% CRC_ENCODE Generate CRC codeword
r = length(generator) - 1;
augmented = [data, zeros(1, r)];
temp = augmented;
for i = 1:(length(data))
if temp(i) == 1
temp(i:i+r) = xor(temp(i:i+r), generator);
end
end
fcs = temp(end-r+1:end);
codeword = [data, fcs];
end
function is_valid = crc_check(received, generator)
% CRC_CHECK Verify received codeword
r = length(generator) - 1;
temp = received;
for i = 1:(length(received) - r)
if temp(i) == 1
temp(i:i+r) = xor(temp(i:i+r), generator);
end
end
remainder = temp(end-r+1:end);
is_valid = all(remainder == 0);
end
%% Example: CRC-4
data = [1 1 0 1 0 1 1];
generator = [1 0 0 1 1]; % x^4 + x + 1
fprintf('===== CRC Example =====\n');
fprintf('Data: %s\n', num2str(data, '%d'));
[codeword, fcs] = crc_encode(data, generator);
fprintf('FCS (CRC): %s\n', num2str(fcs, '%d'));
fprintf('Transmitted: %s\n', num2str(codeword, '%d'));
is_valid = crc_check(codeword, generator);
fprintf('Verification (no error): %s\n', string(is_valid));
๐ Convolutional Codes CLO-5
๐ Convolutional Code Parameters
Rate: R = k/n (k input bits, n output bits)
Constraint Length: K (memory + 1)
Generator Polynomials: Define connections to output
Rate 1/2 Convolutional Encoder
function [output, states] = conv_encode(input, g1, g2, K)
% CONV_ENCODE Rate 1/2 convolutional encoder
% Input: input - binary input sequence
% g1, g2 - generator polynomials
% K - constraint length
% Output: output - encoded sequence (2ร length of input)
memory = K - 1;
state = zeros(1, memory);
n_bits = length(input);
output = zeros(1, 2*n_bits);
states = zeros(n_bits, memory);
for i = 1:n_bits
in_bit = input(i);
reg = [in_bit, state];
out1 = mod(sum(reg .* g1), 2);
out2 = mod(sum(reg .* g2), 2);
output(2*i-1) = out1;
output(2*i) = out2;
states(i, :) = state;
state = [in_bit, state(1:end-1)];
end
end
%% Example: Standard rate 1/2, K=3 encoder
K = 3;
g1 = [1 1 1]; % Connections for output 1 (octal 7)
g2 = [1 0 1]; % Connections for output 2 (octal 5)
fprintf('===== Rate 1/2, K=3 Convolutional Encoder =====\n');
fprintf('Generator 1: [%s] (octal 7)\n', num2str(g1, '%d '));
fprintf('Generator 2: [%s] (octal 5)\n', num2str(g2, '%d '));
input = [1 0 1 1 0];
fprintf('\nInput sequence: %s\n', num2str(input, '%d'));
[output, states] = conv_encode(input, g1, g2, K);
fprintf('Output sequence: %s\n', num2str(output, '%d'));
fprintf('\nCode rate: 1/2\n');
State Transition Table
function print_state_table(g1, g2, K)
% PRINT_STATE_TABLE Generate and display state transition table
memory = K - 1;
num_states = 2^memory;
fprintf('===== State Transition Table =====\n');
fprintf('Current State | Input | Next State | Output\n');
fprintf('--------------|-------|------------|-------\n');
for s = 0:num_states-1
state = de2bi(s, memory, 'left-msb');
for in_bit = 0:1
reg = [in_bit, state];
out1 = mod(sum(reg .* g1), 2);
out2 = mod(sum(reg .* g2), 2);
next_state = [in_bit, state(1:end-1)];
next_dec = bi2de(next_state, 'left-msb');
fprintf(' %s | %d | %s | %d%d\n', ...
dec2bin(s, memory), in_bit, dec2bin(next_dec, memory), out1, out2);
end
end
end
%% Generate table
K = 3;
g1 = [1 1 1];
g2 = [1 0 1];
print_state_table(g1, g2, K);
๐ฏ Viterbi Algorithm CLO-5
๐ Viterbi Decoding
Maximum likelihood sequence decoding algorithm:
- Initialize: Set initial path metrics
- Branch Metrics: Calculate Hamming distance to received bits
- Add-Compare-Select: Keep best path to each state
- Traceback: Find path with minimum metric
Viterbi Decoder Implementation
function [decoded, path_metric] = viterbi_decode(received, g1, g2, K)
% VITERBI_DECODE Decode convolutional code using Viterbi algorithm
memory = K - 1;
num_states = 2^memory;
n_branches = length(received) / 2;
path_metrics = inf(num_states, 1);
path_metrics(1) = 0; % Start at state 00
survivors = zeros(num_states, n_branches);
for t = 1:n_branches
r1 = received(2*t - 1);
r2 = received(2*t);
new_metrics = inf(num_states, 1);
for curr_state = 0:num_states-1
if path_metrics(curr_state + 1) == inf
continue;
end
state_bits = de2bi(curr_state, memory, 'left-msb');
for in_bit = 0:1
reg = [in_bit, state_bits];
exp1 = mod(sum(reg .* g1), 2);
exp2 = mod(sum(reg .* g2), 2);
branch_metric = (r1 ~= exp1) + (r2 ~= exp2);
next_state_bits = [in_bit, state_bits(1:end-1)];
next_state = bi2de(next_state_bits, 'left-msb');
total_metric = path_metrics(curr_state + 1) + branch_metric;
if total_metric < new_metrics(next_state + 1)
new_metrics(next_state + 1) = total_metric;
survivors(next_state + 1, t) = curr_state * 2 + in_bit;
end
end
end
path_metrics = new_metrics;
end
% Traceback
[path_metric, final_state] = min(path_metrics);
final_state = final_state - 1;
decoded = zeros(1, n_branches);
current_state = final_state;
for t = n_branches:-1:1
survivor_info = survivors(current_state + 1, t);
prev_state = floor(survivor_info / 2);
input_bit = mod(survivor_info, 2);
decoded(t) = input_bit;
current_state = prev_state;
end
end
%% Test Viterbi decoder
K = 3;
g1 = [1 1 1];
g2 = [1 0 1];
message = [1 0 1 1 0 0];
fprintf('===== Viterbi Decoder Test =====\n');
fprintf('Original message: %s\n', num2str(message, '%d'));
[encoded, ~] = conv_encode(message, g1, g2, K);
fprintf('Encoded: %s\n', num2str(encoded, '%d'));
% Add error
received = encoded;
received(5) = mod(received(5) + 1, 2);
fprintf('Received (with error): %s\n', num2str(received, '%d'));
[decoded, metric] = viterbi_decode(received, g1, g2, K);
fprintf('Decoded: %s\n', num2str(decoded, '%d'));
fprintf('Path metric: %d\n', metric);
fprintf('Decoding successful: %s\n', string(isequal(decoded, message)));
๐ BER Performance Simulation CLO-6
Complete BER Simulation
function ber_simulation()
% BER_SIMULATION Compare coded vs uncoded BER performance
K = 3;
g1 = [1 1 1];
g2 = [1 0 1];
num_bits = 10000;
EbN0_dB = 0:0.5:10;
num_trials = 5;
ber_uncoded = zeros(size(EbN0_dB));
ber_coded = zeros(size(EbN0_dB));
fprintf('===== BER Simulation =====\n');
for idx = 1:length(EbN0_dB)
errors_uncoded = 0;
errors_coded = 0;
total_bits = 0;
for trial = 1:num_trials
bits = randi([0, 1], 1, num_bits);
bits_tail = [bits, zeros(1, K-1)];
[coded, ~] = conv_encode(bits_tail, g1, g2, K);
tx_uncoded = 2*bits - 1;
tx_coded = 2*coded - 1;
EbN0_linear = 10^(EbN0_dB(idx)/10);
noise_var_uncoded = 1 / (2 * EbN0_linear);
rx_uncoded = tx_uncoded + sqrt(noise_var_uncoded) * randn(size(tx_uncoded));
noise_var_coded = 1 / (2 * EbN0_linear * 0.5);
rx_coded = tx_coded + sqrt(noise_var_coded) * randn(size(tx_coded));
decoded_uncoded = rx_uncoded < 0;
received_hard = rx_coded < 0;
[decoded_coded, ~] = viterbi_decode(double(received_hard), g1, g2, K);
errors_uncoded = errors_uncoded + sum(bits ~= decoded_uncoded);
errors_coded = errors_coded + sum(bits ~= decoded_coded(1:num_bits));
total_bits = total_bits + num_bits;
end
ber_uncoded(idx) = errors_uncoded / total_bits;
ber_coded(idx) = errors_coded / total_bits;
fprintf('Eb/N0 = %4.1f dB: BER_coded = %.2e\n', EbN0_dB(idx), ber_coded(idx));
end
figure('Position', [100, 100, 800, 600]);
semilogy(EbN0_dB, ber_uncoded, 'bo-', 'LineWidth', 1.5, 'DisplayName', 'Uncoded BPSK');
hold on;
semilogy(EbN0_dB, ber_coded, 'rs-', 'LineWidth', 1.5, 'DisplayName', 'Conv Code R=1/2, K=3');
xlabel('E_b/N_0 (dB)', 'FontSize', 12);
ylabel('Bit Error Rate (BER)', 'FontSize', 12);
title('BER Performance: Coded vs Uncoded BPSK', 'FontSize', 14);
legend('Location', 'southwest');
grid on;
hold off;
end
ber_simulation();
โ ๏ธ Simulation Tips
- Use enough bits for statistical significance (โฅ10,000)
- Run multiple trials and average results
- Account for code rate when calculating noise variance
๐ก Tips & Best Practices
MATLAB Shortcuts
| Shortcut | Action |
|---|---|
Ctrl + C | Stop running code |
Ctrl + Enter | Run current section |
F5 | Run script |
F9 | Run selected code |
Ctrl + R | Comment lines |
Ctrl + T | Uncomment lines |
Useful Functions Reference
Binary Operations
de2bi(), bi2de()dec2bin(), bin2dec()mod(x, 2)xor(), bitxor()
Matrix Operations
eye(), zeros(), ones()transpose(), 'reshape(), repmat()sum(), prod()
Communications
gfdeconv()- GF(2) divisionconvenc()- Conv encodingvitdec()- Viterbi decoderbiterr()- Count bit errors
Plotting
semilogy()- Log y-axissubplot()- Multiple plotslegend(), title()grid on, hold on
โ Assignment Submission Checklist
- โ Header with name, ID, assignment number
- โ Code runs without errors from start to finish
- โ All variables properly defined
- โ Comments explain complex operations
- โ Figures have titles, labels, and legends
- โ Results displayed with
fprintf() - โ Code properly indented and readable
๐ Additional Resources
- MATLAB Documentation: mathworks.com/help/matlab/
- Communications Toolbox: mathworks.com/help/comm/
- Textbook: Simon Haykin, Communication Systems, 4th Ed.
- Course Materials: Check Blackboard for sample codes
- YouTube: Dr. Al Bataineh's lecture videos
Need Help?
Contact Dr. Al Bataineh during office hours (Tuesday/Thursday 11:00 AM - 12:00 PM)
Email: [email protected] | Office: F1-1175