DC LAB MANUAL
DC LAB MANUAL
1 Gram-Schmidt Orthogonalization: To find orthogonal basis vectors for the given set
of vectors and plot the orthonormal vectors
Gram-Schmidt Orthogonalization
The Gram-Schmidt process takes a set of linearly independent vectors and produces an
orthogonal or orthonormal set of vectors spanning the same subspace. Here’s how it works
step by step:
Code:
clc;
clear;
close all;
% Parameters
N = 1000; % Number of bits
M = 16; % 16-QAM (16 symbols, 4 bits per symbol)
k = log2(M); % Bits per symbol for 16-QAM
SNR_dB = 20; % Signal to noise ratio in dB
for i = 1:size(symbols_bits, 1)
% Convert first 2 bits to in-phase (I) value
I_bits = bi2de(symbols_bits(i, 1:2), 'left-msb');
I_val = qam_levels(I_bits + 1);
% Convert last 2 bits to quadrature (Q) value
Q_bits = bi2de(symbols_bits(i, 3:4), 'left-msb');
Q_val = qam_levels(Q_bits + 1);
Code:
clc;
clear;
close all;
% Parameters
N = 1e5; % Number of bits
Tb = 1; % Bit duration
fs = 100; % Sampling frequency
SNR_dB = 0:1:10; % SNR values in dB
% BER calculation
bit_errors = sum(detected_bits ~= data_bits);
BER(i) = bit_errors/N;
end
Code:
clc;
clear;
close all;
% Parameters
N = 1000; % Number of bits
fs = 100; % Sampling frequency for plotting
M = 4; % QPSK (4 symbols)
% AWGN Channel (optional: Add noise, set SNR to inf for no noise)
SNR_dB = 15; % SNR in dB
rx_signal = awgn(modulated_signal, SNR_dB, 'measured'); % Received signal with noise
% Display results
disp(['BER: ', num2str(BER)]);
o
4. QPSK Modulation:
o For each pair of bits, the corresponding QPSK symbol is chosen from the
constellation points (symbol_mapping).
5. Upsampling and Pulse Shaping:
o For plotting purposes, the QPSK signal is upsampled (increased sampling rate)
and passed through a rectangular pulse shaping filter.
6. Modulated Signal Plot:
o The real and imaginary parts of the modulated QPSK signal are plotted to
visualize the in-phase and quadrature components of the modulated signal.
7. Constellation Diagram:
o The QPSK symbols are plotted in the complex plane (real vs. imaginary) to
display the constellation diagram.
8. AWGN Channel (Optional):
o Noise is added to the QPSK signal using the awgn function, with the specified
SNR (SNR_dB). This simulates transmission through a noisy channel.
9. Demodulation:
o The received noisy signal is demodulated by finding the nearest QPSK symbol
for each received symbol.
o Each detected symbol is mapped back to the corresponding bit pair using the
reverse of the modulation process.
10. Bit Error Rate (BER) Calculation:
o The demodulated bits are compared to the original transmitted bits, and the
bit error rate (BER) is calculated.
11. Constellation Plot with Noise:
o After adding noise, the constellation diagram is plotted again to show how
the received symbols deviate from the ideal points due to the noise.
Results
Modulated QPSK Signal: Shows how the in-phase and quadrature components of
the signal vary over time.
Constellation Diagram (Before Channel): Displays the ideal QPSK constellation with
four distinct points representing the four symbols.
Constellation Diagram (After Channel): Displays the received symbols with noise,
showing deviation from the ideal constellation points.
BER Calculation: Displays the bit error rate, which should be low for high SNR values
but increases as noise increases.
Exp. 4 16-QAM (Quadrature Amplitude Modulation) Modulation and Constellation
In 16-QAM (Quadrature Amplitude Modulation), 16 symbols are used to transmit data, each
representing 4 bits (2 bits for the in-phase component and 2 bits for the quadrature
component). The symbols are arranged in a 4x4 grid on the constellation diagram, with both
amplitude and phase changes used to distinguish between different symbols.
Each symbol in 16-QAM is a complex number, where the real part represents the in-phase
(I) component, and the imaginary part represents the quadrature (Q) component.
Code:
clc;
clear;
close all;
% Parameters
N = 1000; % Number of bits
M = 16; % 16-QAM (16 symbols, 4 bits per symbol)
k = log2(M); % Bits per symbol for 16-QAM
SNR_dB = 20; % Signal to noise ratio in dB
for i = 1:size(symbols_bits, 1)
% Convert first 2 bits to in-phase (I) value
I_bits = bi2de(symbols_bits(i, 1:2), 'left-msb');
I_val = qam_levels(I_bits + 1);
Code:
clc;
clear;
close all;
Example of Encoding
For the input message ['A', 'B', 'A', 'D', 'F', 'C', 'B', 'E', 'C', 'A']:
The encoded message is a sequence of binary digits that represents the Huffman
codes for each symbol:
A -> 0
B -> 10
A -> 0
D -> 110
F -> 1010
C -> 111
B -> 10
E -> 1011
C -> 111
A -> 0
Code:
clc;
clear;
close all;
% Hamming (7,4) Code: Adding parity bits to 4-bit data to make it 7-bit
% The positions of the parity bits are at positions 1, 2, and 4 (powers of 2)
% Positions: [p1, p2, d1, p4, d2, d3, d4]
if all(remainder_no_error == 0)
disp('No errors detected.');
else
disp('Error detected.');
end
% ------------------------------
% Case 2: With Error
% ------------------------------
disp('Case 2: With Error');
received_data_with_error = encoded_data;
received_data_with_error(5) = mod(received_data_with_error(5) + 1, 2); % Introduce an
error at bit 5
if all(remainder_with_error == 0)
disp('No errors detected.');
else
disp('Error detected.');
end
for i = len_divisor:length(dividend)
if temp(1) == 1
temp = xor(temp, divisor); % XOR with the divisor if the first bit is 1
end
temp = [temp(2:end) dividend(i)]; % Shift left and append the next bit
end
remainder = temp(1:end-1); % The last (len_divisor - 1) bits are the remainder
end
Explanation of the MATLAB Code
1. Initialization:
o We define the CRC-CCITT generator polynomial (x^16 + x^12 + x^5 + 1),
which is represented by the binary vector generator = [1 0 0 0 1 0 0 0 0 0 0 0
1 0 0 0 1].
o The data_bits array contains the binary data to be transmitted (e.g., [1 0 1 1
0 1 0 1]).
2. Appending Zeros to the Data:
o Before performing the CRC computation, 16 zeros (same as the degree of the
polynomial) are appended to the original data. This is stored in the variable
data_with_zeros.
3. Modulo-2 Division (Binary Division):
o The function mod2div performs modulo-2 division, which is binary division
without carries. This function is used to divide the data (with appended
zeros) by the generator polynomial. The remainder from this division is the
CRC code.
4. Appending CRC Code to the Data:
o The calculated CRC code (remainder) is appended to the original data to form
the encoded data.
5. Case 1: Without Error
o The received data (without errors) is checked by performing the modulo-2
division again using the mod2div function. If the remainder is zero, it
indicates that no errors occurred during transmission.
6. Case 2: With Error
o To simulate an error, we flip one of the bits in the received data (e.g., at
position 5). After recalculating the CRC, if the remainder is non-zero, it
indicates that an error was detected.
7. Binary Division Function (mod2div)
o This function performs modulo-2 division on the dividend (data) using the
divisor (generator polynomial). It returns the remainder, which is used to
calculate the CRC and verify errors.
Results
Case 1: Without Error
For the case without errors, the receiver performs the CRC check and verifies that the
remainder is zero, indicating that the received data is error-free.
Case 2: With Error
For the case with an error (in this case, an error is introduced at position 5), the receiver's
CRC check results in a non-zero remainder, indicating that an error has occurred.
Example Output
Original Data Bits:
1 0 1 1 0 1 0 1
Encoded Data (with CRC):
1 0 1 1 0 1 0 1 0 1 0 0 0 0 1 1 0 1 1 0
Case 1: Without Error
No errors detected.
Case 2: With Error
Error detected.
Exp.8 Convolutional Coding: Encoding and Decoding
Convolutional coding is an error-correcting coding technique used in communication
systems to add redundancy to the transmitted data, allowing for error detection and
correction at the receiver. Unlike block codes, which operate on fixed-size blocks of data,
convolutional codes work on continuous data streams, encoding each bit of data based on
the current bit and a number of previous bits.
A common representation for convolutional codes is through a state machine or trellis
diagram, which shows how each bit transitions from one state to another.
MATLAB Code for Convolutional Encoding and Decoding
In this example, we will use a rate 12\frac{1}{2}21 convolutional code with constraint length
3 and generator polynomials g1=78g_1 = 7_8g1=78 and g2=58g_2 = 5_8g2=58. These
polynomials correspond to a memory-2 convolutional encoder, which looks at the current
input bit and the two previous bits to generate two encoded output bits.
Code:
clc;
clear;
close all;
% Convolutional Encoding
encoded_bits = conv_encode(data_bits, g1, g2);
% ------------------------------
% Decoding using Viterbi Algorithm
% ------------------------------
decoded_bits = viterbi_decode(encoded_bits, g1, g2);
% ----------------------------------------------
% Convolutional Encoder Function
% ----------------------------------------------
function encoded_bits = conv_encode(data_bits, g1, g2)
% Get the constraint length
K = length(g1); % Constraint length is 3 for this example
% ----------------------------------------------
% Viterbi Decoder Function
% ----------------------------------------------
function decoded_bits = viterbi_decode(encoded_bits, g1, g2)
% Define trellis states (4 states for constraint length 3: 00, 01, 10, 11)
K = length(g1); % Constraint length
num_states = 2^(K-1); % Number of states for trellis
% Trellis structure: Define state transitions and output for each state
trellis = [
0 0; % State 0 (00) -> next states 0 and 1
1 1; % State 1 (01) -> next states 2 and 3
2 2; % State 2 (10) -> next states 0 and 1
3 3 % State 3 (11) -> next states 2 and 3
];
% Initialize the path metrics and state paths
path_metrics = zeros(num_states, 1); % Path metrics (starting from zero)
state_paths = cell(num_states, 1); % Store state paths
% Update the path metrics for each state based on the received bits
for state = 1:num_states
% Find the possible transitions to the current state
prev_states = find(trellis(:, state) == state - 1); % State transitions
end
end