



















Preview text:
lOMoAR cPSD| 58737056
HỌC VIỆN CÔNG NGHỆ BƯU CHÍNH VIỄN THÔNG
CƠ SỞ THÀNH PHỐ HỒ CHÍ MINH KHOA VIỄN THÔNG 2 BỘ MÔN VÔ TUYẾN
TÀI LIỆU HƯỚNG DẪN THÍ NGHIỆM
Môn học: Mô phỏng hệ thống truyền thông Phòng thí nghiệm: Online GV: KVT2
Họ và tên sinh viên: Hoàng Ngọc Thạch..............................................................................
Nhóm: 1-4.....................................................Tổ:.................................................................
Lớp: D22CQVT01-N........................................................................................................... Điểm Nhận xét
Mục tiêu của môn học: Giúp sinh viên hiểu được những khái niệm cơ bản về ngôn ngữ
Matlab, hiểu được cách thức mô phỏng các mô hình kênh thông tin cở bản trong viễn thông.
Kiểm chứng lại các mô hình toán học của các kênh thông tin cơ bản.
Yêu cầu: Cài đặt và sử dụng phần mềm Matlab phiên bản 2019a trở lên hoặc dùng hỗ trợ
phần mềm Matlab online tại https://www.mathworks.com/products/matlab-online.html lOMoAR cPSD| 58737056
PHẦN LÝ THUYẾT LIÊN QUAN CẦN CHUẨN BỊ
a) Lý thuyết về xác suất
Cho biến ngẫu nhiên X có hàm mật độ phân phối xác suất là
+ X là biến ngẫu nhiên liên tục Kỳ vọng : Phương sai
+ X là biến ngẫu nhiên rời rạc Kỳ vọng Phương sai
b) Lý thuyết về kênh thông tin cơ bản
Xét mô hình kênh thông tin đơn giản phân tập thu như hình vẽ lOMoAR cPSD| 58737056
Phía máy phát Tx trang bị 1 ăng ten phát, máy thu Rx trang bị 2 ăng ten thu. Giả sử công suất phát tín
hiệu tại máy phát Tx là
, khi đó tín hiệu nhận được tại ăng ten thứ
của máy thu Rx được kí hiệu là với
là hệ số kênh truyền từ anten phát đến anten thứ của máy thu, là nhiễu trắng lại
anten máy thu có công suất là . Tỷ số tín hiệu trên nhiễu tại anten thứ có dạng như sau
Giả sử kênh truyền đang xét là kênh Rayleigh fading, và các kênh truyền từ máy phát đến
máy thu là như nhau nên tỷ số tín hiệu trên nhiễu trung bình tại các nhánh là như nhau có nghĩa là
ta có hàm PDF và CDF của các kênh truyền có dạng:
Trong mô hình trên, giả sử phía máy thu sử dụng kỹ thuật SC(select combining), khi đó
tỷ số tín hiệu tương đương phía máy thu ký hiệu là lOMoAR cPSD| 58737056
Giả sử khoảng cách giữa các ăng ten phía máy thu đủ lớn, do đó các sẽ độc lập với
nhau, hàm phân bố tích lũy xác suất của như sau:
Xác suất dừng của hệ thống
Tỷ lệ lỗi bit trung bình:
Dung lượng Shannon của hệ thống lOMoAR cPSD| 58737056 Với và
PHẦN THỰC HÀNH BUỔI 1
CÂU HỎI CHUẨN BỊ Ở NHÀ
Tìm hiểu và điền vào bảng chức năng các hàm matlab dưới đây TT Hàm Chức năng 1 rand
Tạo ra các số ngẫu nhiên. 2 plot Vẽ đồ thị 2D 3 suplot
Chia cửa sổ đồ thị thành nhiều phần nhỏ. 4 xlabel
Đặt nhãn cho trục hoành. 5 ylabel Đặt nhãn cho trục tung. 6 legend
Thêm chú thích cho đồ thị 7 title
Đặt tiêu đề cho đồ thị. 8 length
Trả về độ dài của vectơ. 9 zeros
Tạo ra ma trận toàn số 0. lOMoAR cPSD| 58737056 10 demention 11 max Tìm giá trị lớn nhất. 12 sort Sắp xếp các phần tử.
PHẦN CÁC KIẾN THỨC LỆNH LẬP TRÌNH CƠ BẢN
Bài 1: Viết chương trình nhập một số và trả về số bằng chữ. Ví dụ nhập trả về một trăm mười một.
function so_thanh_chu = so_thanh_chu(so)
% Chuyển đổi số nguyên dương thành chữ
if ~isnumeric(so) || so < 0 || mod(so, 1) ~= 0
so_thanh_chu = 'Số không hợp lệ'; return; end if so == 0 so_thanh_chu = 'không'; return; end
don_vi = {'', 'một', 'hai', 'ba', 'bốn', 'năm', 'sáu', 'bảy', 'tám', 'chín'}; hang_chuc = {'', 'mười',
'hai mươi', 'ba mươi', 'bốn mươi', 'năm mươi', 'sáu mươi', 'bảy mươi', 'tám mươi', 'chín
mươi'}; hang_tram = {'', 'một trăm', 'hai trăm', 'ba trăm', 'bốn trăm', 'năm trăm', 'sáu trăm',
'bảy trăm', 'tám trăm', 'chín trăm'}; bac = {'', 'nghìn', 'triệu', 'tỷ'};
function chuoi = doc_ba_so(n) tram = floor(n / 100); chuc =
floor((n - tram * 100) / 10); donvi = mod(n, 10); lOMoAR cPSD| 58737056
chuoi = ' ; if tram > 0 chuoi =
[chuoi, hang_tram{tram + 1}, ' ']; end
if chuc > 1 chuoi = [chuoi,
hang_chuc{chuc + 1}, ' ']; if donvi == 1
chuoi = [chuoi, 'mốt']; elseif donvi == 5
chuoi = [chuoi, 'lăm']; elseif donvi > 0
chuoi = [chuoi, don_vi{donvi + 1}]; end elseif chuc == 1
chuoi = [chuoi, 'mười ']; if donvi
== 1 chuoi = [chuoi, 'một'];
elseif donvi > 0 chuoi = [chuoi, don_vi{donvi + 1}]; end else
if donvi == 1 chuoi = [chuoi, 'một'];
elseif donvi == 5 chuoi = [chuoi,
'năm']; elseif donvi > 0 chuoi =
[chuoi, don_vi{donvi + 1}]; end end end
so_thanh_chu = ' ; i = 0; while so > 0 ba_so = mod(so, 1000); if
ba_so > 0 so_thanh_chu = [doc_ba_so(ba_so), ' ', bac{i + 1}, ' ',
so_thanh_chu]; end so = floor(so / 1000); i = i + 1; end
so_thanh_chu = strtrim(so_thanh_chu); end
% Ví dụ sử dụng so = input('Nhập một số nguyên
dương: '); chuoi_ket_qua = so_thanh_chu(so); lOMoAR cPSD| 58737056
disp(['Số ', num2str(so), ' đọc là: ',
chuoi_ket_qua]);
Bài 2: Viết chương trình nhập vào số bằng chữ và trả về số bằng số.
function soThanhChu = bai2() % Nhập chuỗi từ người
dùng chuoiNhap = input('Nhập số bằng chữ (tiếng Việt): ', 's');
% Xử lý chuỗi đầu vào chuoiNhap = lower(chuoiNhap);
chuoiNhap = strtrim(chuoiNhap);
% Định nghĩa từ điển chuyển đổi tu_don_vi = containers.Map(); tu_don_vi('không') = 0; tu_don_vi('một') = 1; tu_don_vi('mốt') = 1;
tu_don_vi('hai') = 2; tu_don_vi('ba') = 3; tu_don_vi('bốn') = 4; tu_don_vi('năm') = 5; tu_don_vi('lăm') = 5; tu_don_vi('sáu') = 6; tu_don_vi('bảy') = 7; tu_don_vi('tám') = 8; lOMoAR cPSD| 58737056 tu_don_vi('chín') = 9; tu_don_vi('mười') = 10;
tu_hang_chuc = containers.Map(); tu_hang_chuc('mười') = 10;
tu_hang_chuc('hai mươi') = 20;
tu_hang_chuc('ba mươi') = 30;
tu_hang_chuc('bốn mươi') = 40;
tu_hang_chuc('năm mươi') = 50;
tu_hang_chuc('sáu mươi') = 60;
tu_hang_chuc('bảy mươi') = 70;
tu_hang_chuc('tám mươi') = 80;
tu_hang_chuc('chín mươi') = 90; tu_hang = containers.Map(); tu_hang('trăm') = 100; tu_hang('nghìn') = 1000; tu_hang('ngàn') = 1000; tu_hang('triệu') = 1000000;
tu_hang('tỷ') = 1000000000; % Tách
chuỗi thành từng từ words = strsplit(chuoiNhap);
function [so, index] = docNhomDuoi1000(words, startIndex)
so = 0; index = startIndex; temp = 0; leLaHangChuc = false; lOMoAR cPSD| 58737056
while index <= length(words) word = words{index}; % Xử lý từ "lẻ" if strcmp(word, 'lẻ') leLaHangChuc = true; index = index + 1; continue; end
% Kiểm tra xem có phải là từ đơn vị if isKey(tu_don_vi, word) if
strcmp(word, 'mười') temp =
temp + 10; elseif leLaHangChuc
% Nếu trước đó là "lẻ" thì đây là hàng đơn vị
temp = temp + tu_don_vi(word); leLaHangChuc = false; else
temp = temp + tu_don_vi(word); end index = index + 1;
% Kiểm tra xem có phải là từ hàng chục elseif
contains(word, 'mươi') if index > 1 &&
isKey(tu_don_vi, words{index-1}) % Trường
hợp "hai mươi", "ba mươi",... num =
tu_don_vi(words{index-1}); temp = temp - num + num * 10; else lOMoAR cPSD| 58737056
% Trường hợp chuỗi bắt đầu với "mươi" temp = temp + 10; end index = index + 1;
% Kiểm tra xem có phải là từ hàng elseif
isKey(tu_hang, word) if strcmp(word, 'trăm')
if index > 1 && isKey(tu_don_vi, words{index-1})
% Trường hợp "hai trăm", "ba trăm",... num =
tu_don_vi(words{index-1}); temp = temp - num + num * 100; else temp = temp * 100; end index = index + 1; else
% Kết thúc nhóm dưới 1000 break; end else
% Từ không nhận dạng được, bỏ qua index = index + 1; end end so = temp; end
% Xử lý toàn bộ chuỗi ketQua = 0; i = 1; nhomGiaTri = 0; lOMoAR cPSD| 58737056 while i <= length(words) word = words{i}; % Đọc nhóm dưới 1000
[nhomNho, i] = docNhomDuoi1000(words, i);
nhomGiaTri = nhomGiaTri + nhomNho;
% Kiểm tra xem có phải là từ hàng lớn if i <= length(words) &&
isKey(tu_hang, words{i}) && ~strcmp(words{i}, 'trăm') nhomGiaTri =
nhomGiaTri * tu_hang(words{i}); ketQua = ketQua + nhomGiaTri;
nhomGiaTri = 0; i = i + 1; elseif i > length(words) ketQua = ketQua + nhomGiaTri; end end
% Trường hợp đặc biệt if ketQua
== 0 && nhomGiaTri > 0 ketQua = nhomGiaTri; end
% In kết quả fprintf('Chữ "%s" chuyển thành số là: %d\n',
chuoiNhap, ketQua); soThanhChu = ketQua; end
Bài 3: Cho một cell array lưu trữ họ và tên các sinh viên, ví dụ fullname={‘Nguyen Van
Tí’, ‘Tran Van Tho’, ‘Nguyen Canh Chan’, ‘ Tran Luu Nam’, ‘ Tan Hiep Phap’}. Hãy lập
trình trả về danh sách xếp theo thứ tự abc theo tên.
function sorted_names = sort_names_by_lastname(fullnames)
% Sắp xếp danh sách tên theo thứ tự bảng chữ cái của tên lOMoAR cPSD| 58737056
num_names = length(fullnames);
last_names = cell(num_names, 1); % Tách
tên khỏi họ và tên đầy đủ for i = 1:num_names name_parts =
strsplit(fullnames{i}); last_names{i} =
name_parts{end}; % Lấy phần tử cuối cùng là tên end
% Sắp xếp tên theo thứ tự bảng chữ cái
[~, sort_indices] = sort(last_names);
% Sắp xếp lại danh sách họ và tên đầy đủ
sorted_names = fullnames(sort_indices); end
% Ví dụ sử dụng fullnames = {}; % Khởi
tạo cell array rỗng name_count = 1;
disp('Nhập danh sách họ và tên (nhập "done" để kết thúc):');
while true name = input(['Tên sinh viên thứ ',
num2str(name_count), ': '], 's'); if strcmp(name, 'done') break; end fullnames{name_count} = name; name_count = name_count + 1; end lOMoAR cPSD| 58737056
sorted_names = sort_names_by_lastname(fullnames); disp(sorted_names);
Bài 4: Hãy khai báo một cấu trúc thông tin của sinh viên gồm 3 thành phần gồm họ và tên,
năm sinh, giới tính. Kiểm tra có phải là cấu trúc không? a. Liệt kê ra các trường của cấu trúc
b. Kiểm tra ‘Gioi_Tinh’ có phải là 1 trường trong cấu trúc sinh viên không?
c. Xếp thứ tự các trường
d. Thêm một trường ‘Noi_Sinh’
e. Kiểm tra tên trường “Ho_va_Ten” có hợp lệ không?
f. Tạo ra một mảng cấu trúc với sinh viên thứ 2.
i. Lấy năm sinh của hai sinh viên
% Khai báo cấu trúc thông tin của sinh viên
sinhvien(1).Ho_va_Ten = 'Nguyen Van An'; sinhvien(1).Nam_Sinh = 2000;
sinhvien(1).Gioi_Tinh = 'Nam';
% Kiểm tra có phải là cấu trúc không?
is_struct = isstruct(sinhvien); disp(['Có phải là cấu trúc
không? ', num2str(is_struct)]);
% a. Liệt kê ra các trường của cấu trúc
cac_truong = fieldnames(sinhvien);
disp('Các trường của cấu trúc sinh viên là:'); disp(cac_truong); lOMoAR cPSD| 58737056
% b. Kiểm tra ‘Gioi_Tinh’ có phải là 1 trường trong cấu trúc sinh viên không?
kiem_tra_gioi_tinh = isfield(sinhvien, 'Gioi_Tinh');
disp(['' Gioi_Tinh'' có phải là một trường trong cấu trúc sinh viên không? ',
num2str(kiem_tra_gioi_tinh)]);
% c. Xếp thứ tự các trường disp('Thứ tự các
trường (theo thứ tự định nghĩa):'); disp(cac_truong);
% d. Thêm một trường ‘Noi_Sinh’ sinhvien(1).Noi_Sinh =
'Ha Noi'; disp('Cấu trúc sinh viên sau khi thêm trường
' Noi_Sinh' :'); disp(sinhvien);
% e. Kiểm tra tên trường “Ho_va_Ten” có hợp lệ không?
% Tên trường trong MATLAB phải tuân theo quy tắc đặt tên biến:
% - Bắt đầu bằng một chữ cái.
% - Có thể chứa chữ cái, số và dấu gạch dưới (_).
% - Không được chứa khoảng trắng hoặc các ký tự đặc biệt khác.
ten_truong_kiem_tra = 'Ho_va_Ten'; hop_le =
regexp(ten_truong_kiem_tra, '^[a-zA-Z]\w*$'); if ~isempty(hop_le)
disp(['Tên trường "', ten_truong_kiem_tra, '" là hợp lệ.']); else
disp(['Tên trường "', ten_truong_kiem_tra, '" không hợp lệ.']); end lOMoAR cPSD| 58737056
% f. Tạo ra một mảng cấu trúc với sinh viên thứ 2.
sinhvien(2).Ho_va_Ten = 'Nguyen Thi Anh Vien'; sinhvien(2).Nam_Sinh = 2002; sinhvien(2).Gioi_Tinh = 'Nu';
sinhvien(2).Noi_Sinh = 'Ho Chi Minh';
disp('Mảng cấu trúc sinh viên với sinh viên thứ hai:'); disp(sinhvien);
% i. Lấy năm sinh của hai sinh viên
nam_sinh_sinhvien1 = sinhvien(1).Nam_Sinh;
nam_sinh_sinhvien2 = sinhvien(2).Nam_Sinh;
disp(['Năm sinh của sinh viên thứ nhất: ', num2str(nam_sinh_sinhvien1)]);
disp(['Năm sinh của sinh viên thứ hai: ', num2str(nam_sinh_sinhvien2)]); PHẦN
THỰC HÀNH VỀ MẢNG CHUỖI
Bài 5: Cho vector chứa một chuỗi số, hãy trả về một chuỗi số khác đếm các phần tử có trong chuỗi số. Ví dụ trả về .
function y = demVaTraVeChuoiDem(x) y = []; %
Khởi tạo vector kết quả y rỗng da_xet = []; %
Vector để theo dõi các số đã được xét for i =
1:length(x) so_hien_tai = x(i); % Lấy số hiện tại từ vector x lOMoAR cPSD| 58737056
% Kiểm tra xem số này đã được xét chưa
if ~ismember(so_hien_tai, da_xet)
% Nếu chưa xét, đếm số lần xuất hiện của nó trong toàn bộ vector x dem = sum(x == so_hien_tai);
% Thêm số lần đếm và số đó vào vector kết quả y y = [y, dem, so_hien_tai];
% Đánh dấu số này là đã xét
da_xet = [da_xet, so_hien_tai]; end end end
x = input('Nhập một vector: '); y = demVaTraVeChuoiDem(x); disp(y); % In ra kết quả
Bài 6: Cho ma trận hàng và 2 cột, chứa tọa độ xOy của điểm. Hãy tìm hai điểm có
khoảng cách xa nhất và trả về chỉ số hàng của hai điểm đó.
function [index1, index2] = timHaiDiemXaNhat(toaDo)
% INDEX1 và INDEX2 là chỉ số hàng của hai điểm đó.
n = size(toaDo, 1); if n < 2 error('Ma
trận tọa độ phải có ít nhất 2 điểm.'); end max_khoang = 0; index1 = -1; index2 = -1; lOMoAR cPSD| 58737056 for i = 1:n for j = i+1:n
% Tính khoảng cách bình phương giữa hai điểm i và j
dx = toaDo(i, 1) - toaDo(j, 1); dy = toaDo(i, 2) -
toaDo(j, 2); khoang_cach = dx^2 + dy^2;
% Cập nhật khoảng cách lớn nhất và chỉ số nếu cần
if khoang_cach > max_khoang_cach
max_khoang_cach = khoang_cach; index1 = i; index2 = j; end end end end
% Ví dụ sử dụng với nhập liệu từ bàn phím: num_diem =
input('Nhập số lượng điểm (n): '); if num_diem < 2
error('Cần ít nhất 2 điểm để tìm khoảng cách xa nhất.'); end
toa_do_cac_diem = zeros(num_diem, 2); % Khởi tạo ma trận tọa độ
disp('Nhập tọa độ x và y cho từng điểm:'); for i = 1:num_diem
prompt = sprintf('Nhập tọa độ điểm thứ %d (ví dụ: [1 2]): ', i);
toa_do = input(prompt); if length(toa_do) ~= 2
error('Vui lòng nhập đúng 2 tọa độ x và y cho mỗi điểm.');
end toa_do_cac_diem(i, :) = toa_do; end lOMoAR cPSD| 58737056
[chi_so_1, chi_so_2] = timHaiDiemXaNhat(toa_do_cac_diem);
fprintf('Hai điểm có khoảng cách xa nhất là điểm thứ %d và điểm thứ %d.\n', chi_so_1, chi_so_2);
fprintf('Tọa độ điểm thứ %d: (%f, %f)\n', chi_so_1, toa_do_cac_diem(chi_so_1, 1),
toa_do_cac_diem(chi_so_1, 2)); fprintf('Tọa độ điểm thứ %d: (%f, %f)\n', chi_so_2,
toa_do_cac_diem(chi_so_2, 1), toa_do_cac_diem(chi_so_2, 2));
Bài 7: Cho một chuỗi số, trả về chuỗi các số không trùng lặp. Ví dụ trả về .
x = input('Nhập một vector: ');
unique_x = unique(x); disp('chuỗi
các số không trùng lặp: '); disp(unique_x);
Bài 8: Tạo một ma trận ngẫu nhiên A có kích thước m,n nhập từ bàn phím. Ma trận B có
kích thước n,k với k nhập từ bàn phím
a) Thực hiện thao tác xóa hàng i và cột j của ma trận ngẫu nhiên vừa tạo. Với i = (n+m)mod n và j=(n+m) mod m
b) Thêm hàng i+1 và cột j+1 vào ma trận A. c) Xóa phần tử A[i,j]
d) Đưa ra các phần tử đường chéo của ma trận A
e) Đưa ra ma trận chuyển vị và ma trận nghịch đảo của ma trận A f) Tính ma trận A*B. clc; clear; close all; lOMoAR cPSD| 58737056
% --- Nhập kích thước ma trận từ bàn phím --while
true m_str = input('Nhập số hàng m của ma trận A:
', 's'); m = str2double(m_str);
if ~isnan(m) && m > 0 && floor(m) == m break; %
Thoát vòng lặp nếu nhập số nguyên dương hợp lệ else
disp('Vui lòng nhập một số nguyên dương cho m.'); end end
while true n_str = input('Nhập số cột n của ma trận A (và số hàng
của B): ', 's'); n = str2double(n_str); if ~isnan(n) && n > 0 &&
floor(n) == n break; % Thoát vòng lặp nếu nhập số nguyên
dương hợp lệ else disp('Vui lòng nhập một số nguyên dương cho n.'); end end
while true k_str = input('Nhập số cột k của ma trận B: ', 's');
k = str2double(k_str); if ~isnan(k) && k > 0 && floor(k) ==
k break; % Thoát vòng lặp nếu nhập số nguyên dương hợp
lệ else disp('Vui lòng nhập một số nguyên dương cho k.'); end end
% --- Tạo ma trận ngẫu nhiên A ---
% Sử dụng rand() để tạo số thực ngẫu nhiên trong khoảng [0, 1] A =
rand(m, n); fprintf('\n--- Ma trận A ngẫu nhiên (%d x %d) đã được tạo ---\n', m, n); disp(A);
% --- Nhập ma trận B từ bàn phím ---