Bài giảng Matlab và ứng dụng trong viễn thông
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Matlab và ứng dụng trong viễn thông", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tài liệu đính kèm:
- bai_giang_matlab_va_ung_dung_trong_vien_thong.pdf
Nội dung text: Bài giảng Matlab và ứng dụng trong viễn thông
- TS. PHẠM HỒNG LIÊN ĐẶNG NGỌC KHOA - TRẦN THANH PHƯƠNG MATLAB VÀ ỨNG DỤNG TRONG VIỄN THƠNG Tháng 11/2005
- LỜI NÓI ĐẦU
- MỤC LỤC LỜI NÓI ĐẦU i MUC̣ LỤC iii 1. MỞ ĐẦU 3 1.1. NHẬP MỘT DÒNG LỆNH 3 1.2. CÔNG CỤ GIÚP ĐỠ 5 1.3. DỪNG MỘT LỆNH HAY CHƯƠNG TRÌNH 6 1.4. ĐƯỜNG DẪN 6 1.5. KHÔNG GIAN LÀM VIỆC (WORKSPACE) 6 1.6. SAVE VÀ LOAD DỮ LIỆU 7 2. CƠ BẢN VỀ CÚ PHÁP VÀ BIẾN 9 2.1. MATLAB NHƯ LÀ MỘT CÔNG CỤ TÍNH TOÁN 9 2.2. PHÉP GÁN VÀ BIẾN 10 3. PHÉP TOÁN VỚI VECTOR VÀ MA TRẬN 14 3.1. VECTOR 14 3.1.1. DẤU ‘:’ VÀ PHẦN TRÍCH RA TỪ VECTOR 15 3.1.2. VECTOR CỘT VÀ PHÉP CHUYỂN VỊ 16 3.1.3. NHÂN, CHIA VÀ SỐ MŨ CỦA VECTƠ 17 3.2. MA TRẬN 19 3.2.1. NHỮNG MA TRẬN ĐẶC BIỆT 21 3.2.2. XÂY DỰNG MA TRẬN VÀ TRÍCH RA MỘT MA TRẬN CON TỪ MỘT MA TRẬN LỚN HƠN 23 3.2.3. TÍNH TOÁN VỚI MA TRẬN 27 4. ĐỒ THỊ 2D VÀ 3D 32 4.1. NHỮNG ĐỒ THỊ ĐƠN GIẢN 32 4.2. MỘT SỐ HÀM ĐƯỢC SỬ DỤNG TRONG VẼ ĐỒ THỊ 34 4.3. CÁC THUỘC TÍNH KHÁC CỦA ĐƯỜNG CONG 2D 37 4.4. IN ẤN 38 4.5. ĐỒ THỊ 3D 39 iii
- 4.6. BỀ MẶT ĐỒ THỊ 40 4.7. HÌNH ĐỘNG 46 5. BIỂU THỨC RẼ NHÁNH 49 5.1. CÁC TOÁN TỬ LOGIC VÀ BIỂU THỨC QUAN HỆ 49 5.2. BIỂU THỨC ĐIỀU KIỆN 53 5.3. VÒNG LẶP 56 6. TẬP LỆNH VÀ HÀM 60 6.1. TẬP LỆNH M-FILE 60 6.2. HÀM M-FILE 61 6.2.1. NHỮNG BIẾN ĐẶC BIỆT TRONG HÀM 63 6.2.2. BIẾN TOÀN CỤC VÀ BIẾN CỤC BỘ 64 6.2.3. CÁCH GỌI HÀM GIÁN TIẾP 65 6.3. TẬP TIN VÀ HÀM 66 7. VĂN BẢN 69 7.1. CHUỖI KÝ TỰ 69 7.2. XUẤT VÀ NHẬP VĂN BẢN 71 8. GIAO DIỆN NGƯỜI SỬ DỤNG (GUI) 77 8.1. CÁCH LÀM VIỆC CỦA MỘT GUI 77 8.2. TẠO VÀ HIỂN THỊ MỘT GUI 79 8.3. THUỘC TÍNH CỦA CÁC ĐỐI TƯỢNG 85 8.4. CÁC THÀNH PHẦN TẠO NÊN GUI 86 8.4.1. Text Fields 87 8.4.2. Edit Boxes 87 8.4.3. Frames 88 8.4.4. Pushbuttons 89 8.4.5. Toggle Buttons 89 8.4.6. Checkboxes và Radio Buttons 90 8.4.7. Popup Menus 91 8.4.8. List Boxes 93 8.4.9. Sliders 95 9. TÍN HIỆU VÀ HỆ THỐNG 91 iv
- 9.1. BIỂU DIỄN MỘT TÍN HIỆU TRONG MATLAB 91 9.2. TẠO TÍN HIỆU: VECTOR THỜI GIAN 91 9.3. LÀM VIỆC VỚI CÁC FILE DỮ LIỆU 94 9.4. PHÂN TÍCH VÀ THIẾT KẾ CÁC BỘ LỌC 94 9.5. CÁC HÀM KHÁC ĐỂ THỰC HIỆN LỌC 97 9.5.1. THỰC HIỆN BĂNG LỌC ĐA TỐC ĐỘ (MULTIRATE FILTER BANK) 97 9.5.2. KHỬ MÉO PHA CHO BỘ LỌC IIR 98 9.5.3. THỰC HIỆN BỘ LỌC TRONG MIỀN TẦN SỐ 99 9.6. ĐÁP ỨNG XUNG 100 9.7. ĐÁP ỨNG TẦN SỐ 100 9.7.1. TRONG MIỀN SỐ 100 9.7.2. TRONG MIỀN ANALOG 101 9.7.3. ĐÁP ỨNG BIÊN ĐỘ VÀ ĐÁP ỨNG PHA 101 9.7.4. THỜI GIAN TRỄ 102 9.8. GIẢN ĐỒ CỰC – ZERO 103 9.9. CÁC MÔ HÌNH HỆ THỐNG TUYẾN TÍNH 104 9.9.1. CÁC MÔ HÌNH HỆ THỐNG RỜI RẠC THEO THỜI GIAN 104 9.9.2. CÁC MÔ HÌNH HỆ THỐNG LIÊN TỤC THEO THỜI GIAN 108 9.9.3. CÁC PHÉP BIẾN ĐỔI HỆ THỐNG TUYẾN TÍNH 108 9.10. BIẾN ĐỔI FOURIER RỜI RẠC 109 10. THIẾT KẾ CÁC BỘ LỌC 117 10.1. CÁC CHỈ TIÊU THIẾT KẾ BỘ LỌC 117 10.2. THIẾT KẾ BỘ LỌC IIR 118 10.2.1. THIẾT KẾ CÁC BỘ LỌC IIR CỔ ĐIỂN DỰA TRÊN CÁC NGUYÊN MẪU ANALOG 119 10.2.2. THIẾT KẾ TRỰC TIẾP CÁC BỘ LỌC IIR TRONG MIỀN SỐ 126 10.2.3. THIẾT KẾ BỘ LỌC BUTTERWORTH TỔNG QUÁT 127 10.2.4. PHƯƠNG PHÁP MÔ HÌNH THÔNG SỐ 128 10.3. THIẾT KẾ BỘ LỌC FIR 129 10.3.1. CÁC BỘ LỌC CÓ PHA TUYẾN TÍNH 129 10.3.2. PHƯƠNG PHÁP CỬA SỔ (WINDOWING) 130 v
- 10.3.3. THIẾT KẾ BỘ LỌC FIR NHIỀU DẢI TẦN VỚI CÁC DẢI CHUYỂN TIẾP 133 10.3.4. THIÊÁT KẾ BỘ LỌC FIR VỚI GIẢI THUẬT BÌNH PHƯƠNG CỰC TIỂU CÓ GIỚI HẠN (CLS – CONSTRAINED LEAST SQUARE) 136 10.3.5. THIẾT KẾ BỘ LỌC FIR CÓ ĐÁP ỨNG TẦN SỐ TÙY CHỌN 139 10.4. THỰC HIỆN BỘ LỌC 141 11. CƠ BẢN VỀ XỬ LÝ ẢNH SỐ 147 11.1. BIỂU DIỄN ẢNH VÀ XUẤT NHẬP ẢNH 147 11.1.1. CÁC KIỂU HÌNH ẢNH TRONG MATLAB 147 11.1.2. ĐỌC VÀ GHI CÁC DỮ LIỆU ẢNH 150 11.1.3. CHUYỂN ĐỔI GIỮA CÁC KIỂU DỮ LIỆU 151 11.1.4. CÁC PHÉP TOÁN SỐ HỌC CƠ BẢN ĐỐI VỚI DỮ LIỆU ẢNH 152 11.1.5. CÁC HÀM HIỂN THỊ HÌNH ẢNH TRONG MATLAB 155 11.2. CÁC PHÉP BIẾN ĐỔI HÌNH HỌC 156 11.2.1. PHÉP NỘI SUY ẢNH 156 11.2.2. THAY ĐỔI KÍCH THƯỚC ẢNH 156 11.2.3. PHÉP QUAY ẢNH 157 11.2.4. TRÍCH XUẤT ẢNH 158 11.2.5. THỰC HIỆN PHÉP BIẾN ĐỔI HÌNH HỌC TỔNG QUÁT 158 11.3. CÁC PHÉP BIẾN ĐỔI ẢNH 160 11.3.1. BIẾN ĐỔI FOURIER 160 11.3.2. BIẾN ĐỔI COSINE RỜI RẠC 163 11.3.3. BIẾN ĐỔI RADON 165 11.3.4. PHÉP BIẾN ĐỔI FAN-BEAM 168 12. NÂNG CAO CHẤT LƯỢNG ẢNH 176 12.1. PHƯƠNG PHÁP BIẾN ĐỔI MỨC XÁM 176 12.2. CÂN BẰNG HISTOGRAM 180 12.2.1. TẠO VÀ VẼ BIỂU ĐỒ HISTOGRAM 180 12.2.2. CÂN BẰNG HISTOGRAM 181 12.3. LỌC ẢNH 186 12.3.1. LỌC TUYẾN TÍNH 187 12.3.2. LỌC PHI TUYẾN 191 vi
- 12.3.3. LỌC THÍCH NGHI 194 13. NÉN ẢNH SỐ 199 13.1. PHƯƠNG PHÁP MÃ HOÁ XỬ LÝ KHỐI BTC (BLOCK TRUNCATING CODING) 199 13.2. NÉN TỔN HAO DỰA VÀO DCT 201 13.3. NÉN ẢNH BẰNG GIẢI THUẬT PHÂN TÍCH TRỊ RIÊNG (SVD) 205 13.3.1. GIỚI THIỆU PHƯƠNG PHÁP SVD 205 13.3.2. ỨNG DỤNG SVD ĐỂ NÉN ẢNH SỐ 206 14. MÃ HÓA NGUỒN 203 14.1. TẠO MỘT NGUỒN TÍN HIỆU 203 14.2. LƯỢNG TỬ HÓA TÍN HIỆU 206 14.3. TỐI ƯU HÓA CÁC THÔNG SỐ CỦA QUÁ TRÌNH LƯỢNG TỬ 208 14.4. ĐIỀU CHẾ MÃ XUNG VI SAI DPCM (DIFFERENTIAL PULSE CODE MODULATION) 209 14.5. TỐI ƯU HOÁ CÁC THÔNG SỐ CỦA QUÁ TRÌNH MÃ HÓA DPCM 210 14.6. NÉN VÀ GIÃN TÍN HIỆU 211 14.7. MÃ HÓA HUFFMAN 213 14.8. MÃ HÓA SỐ HỌC (ARITHMETIC CODING) 215 15. TRUYỀN DẪN BASEBAND VÀ PASSBAND 219 15.1. ĐIỀU CHẾ TƯƠNG TỰ 219 15.2. ĐIỀU CHẾ SỐ 221 16. KÊNH TRUYỀN VÀ ĐÁNH GIÁ CHẤT LƯỢNG KÊNH TRUYỀN 231 16.1. KÊNH TRUYỀN AWGN (ADDITIVE WHITE GAUSSIAN NOISE) 231 16.2. KÊNH TRUYỀN FADING 235 16.3. KÊNH TRUYỀN ĐẢO BIT NHỊ PHÂN 239 16.4. ĐÁNH GIÁ CHẤT LƯỢNG THÔNG QUA MÔ PHỎNG (PHƯƠNG PHÁP MONTE CARLO) 240 16.5. TÍNH XÁC SUẤT LỖI TRÊN LÝ THUYẾT 243 16.6. MỘT SỐ CÔNG CỤ HỖ TRỢ ĐỂ VẼ ĐỒ THỊ BER 245 16.7. GIẢN ĐỒ MẮT (EYE DIAGRAM) 247 16.8. ĐỒ THỊ PHÂN BỐ (SCATTER PLOT) 249 vii
- 16.9. ĐÁNH GIÁ CHẤT LƯỢNG DÙNG KỸ THUẬT SEMIANALYTIC (BÁN PHÂN TÍCH) 250 17. MÃ HÓA KÊNH TRUYỀN 256 17.1. MÃ KHỐI 256 17.1.1. BIỂU DIỄN MỘT PHẦN TỬ TRONG TRƯỜNG GALOIS 257 17.1.2. MÃ REED-SOLOMON 258 17.1.3. MÃ BCH 262 17.1.4. MÃ KHỐI TUYẾN TÍNH 264 17.2. MÃ CHẬP 269 17.2.1. DẠNG ĐA THỨC CỦA BỘ MÃ HOÁ CHẬP 270 17.2.2. DẠNG CẤU TRÚC TRELLIS CỦA BỘ MÃ HÓA CHẬP 271 17.2.3. MÃ HÓA VÀ GIẢI MÃ MÃ CHẬP 273 18. CÁC BỘ CÂN BẰNG 281 18.1. CÁC BỘ CÂN BẰNG THÍCH NGHI 281 18.1.1. BỘ CÂN BẰNG KHOẢNG CÁCH KÝ HIỆU 281 18.1.2. BỘ CÂN BẰNG ĐỊNH KHOẢNG TỶ LỆ 282 18.1.3. BỘ CÂN BẰNG HỒI TIẾP QUYẾT ĐỊNH 283 18.2. CÁC GIẢI THUẬT CÂN BẰNG THÍCH NGHI 284 18.2.1. GIẢI THUẬT BÌNH PHƯƠNG TRUNG BÌNH CỰC TIỂU (LMS – LEAST MEAN SQUARE) 284 18.2.2. GIẢI THUẬT LMS CÓ DẤU (SIGN LMS) 285 18.2.3. GIẢI THUẬT LMS CHUẨN HÓA (NORMALIZED LMS) 285 18.2.4. GIẢI THUẬT LMS CÓ BƯỚC NHẢY THAY ĐỔI (VARIABLE-STEP- SIZE LMS) 285 18.2.5. GIẢI THUẬT BÌNH PHƯƠNG CỰC TIỂU HỒI QUY (RLS – RECURSIVE LEAST SQUARE) 285 18.2.6. GIẢI THUẬT MODULUS HẰNG SỐ (CONSTANT MODULUS ALGORITHM) 286 18.3. SỬ DỤNG CÁC BỘ CÂN BẰNG THÍCH NGHI TRONG MATLAB 286 18.3.1. XÁC ĐỊNH GIẢI THUẬT THÍCH NGHI 286 18.3.2. XÂY DỰNG ĐỐI TƯỢNG MÔ TẢ BỘ CÂN BẰNG THÍCH NGHI 288 18.3.3. TRUY XUẤT VÀ HIỆU CHỈNH CÁC ĐẶC TÍNH CỦA BỘ CÂN BẰNG THÍCH NGHI 289 viii
- 18.3.4. SỬ DỤNG BỘ CÂN BẰNG THÍCH NGHI 289 18.4. CÁC BỘ CÂN BẰNG MLSE 295 PHỤ LỤC 303 TÀI LIỆU THAM KHẢO 324 ix
- PHẦN I CƠ BẢN VỀ MATLAB VÀ LẬP TRÌNH TRÊN MATLAB
- Mở đầu 3 Chương 1 1. MỞ ĐẦU MATLAB là một cơng cụ tính tốn tốn học. MATLAB cĩ thể được sử dụng để tính tốn, nĩ cũng cho phép chúng ta vẽ các biểu đồ, đồ thị theo nhiều cách khác nhau. Giống như một chương trình phần mềm, chúng ta cĩ thể tạo, thực thi và lưu một dãy các lệnh để máy tính cĩ thể chạy tự động. Cuối cùng, MATLAB cũng cĩ thể được coi như là một ngơn ngữ lập trình. Tĩm lại, như là một mơi trường dùng để lập trình hay tính tốn, MATLAB được thiết kế để làm việc với những tập dữ liệu đặc biệt chẳng hạn như ma trận, vector, hình ảnh. Trong mơi trường Windows, sau khi cài MATLAB biểu tượng của nĩ sẽ xuất hiện trên màn hình của máy tính, chúng ta cĩ thể khởi động MATLAB bằng cách double click vào biểu tượng của nĩ. Trong khi chạy, tùy theo yêu cầu của người sử dụng, MATLAB sẽ tạo ra một hoặc nhiều cửa sổ trên màn hình. Cửa sổ quan trọng nhất là cửa sổ lệnh (Command Window), đây là nơi chúng ta giao tiếp (tương tác) với MATLAB và cũng là nơi chúng ta nhập vào các lệnh và MATLAB sẽ cho ra các kết quả. Chuỗi >> là dấu nhắc của chương trình MATLAB. Khi MATLAB hoạt động, con trỏ chuột sẽ xuất hiện sau dấu nhắc, lúc này MATLAB đang chờ người sử dụng nhập lệnh vào. Sau khi nhập lệnh và nhấn enter, MATLAB đáp ứng lại bằng cách in ra các dịng kết quả trong cửa sổ lệnh hay tạo ra một cửa sổ hình (Figure Window). Để thốt khỏi chương trình MATLAB chúng ta sử dụng lệnh exit hoặc quit. 1.1. NHẬP MỘT DÒNG LỆNH Bảng 1.1: Tương quan giữa các phép tốn và lệnh. Phép tốn Lệnh MATLAB a + b a + b a – b a – b ab a*b a/b a/b hay b\a xb x^b x sqrt(x) hay x^0.5 x abs(x) π pi 4.103 4e3 hay 4*10^3 i i hay j 3 – 4i 3- 4*i hay 3 – 4*j e, ex exp(1), exp(x) lnx, logx log(x), log10(x) sinx, arctanx, sin(x), atan(x), MATLAB là một hệ thống tương tác, lệnh sẽ được thực thi ngay lập tức khi nhấn Enter. Những kết quả của mỗi lệnh, nếu được yêu cầu, sẽ được xuất hiện trên màn hình. Tuy nhiên, một lệnh chỉ được thực thi nếu lệnh được nhập vào đúng cú pháp. Bảng 1.1 là danh sách các
- Mở đầu 4 phép tốn cơ bản và lệnh tương ứng của chúng được sử dụng trong chương trình MATLAB để giải những phương trình tốn học (a, b và x là những số). Sau đây là một số lưu ý để nhập vào một dịng lệnh đúng: • Những lệnh trong MATLAB được thực thi ngay lập tức khi nhấn Enter. Kết quả của mỗi lệnh sẽ được hiển thị trên màn hình ngay lập tức. Thử thi hành với các lệnh sau đây: >> 3 + 7.5 >> 18/4 >> 3 * 7 Lưu ý rằng khoảng trống trong MATLAB là khơng quan trọng. • Kết quả của phép tính cuối cùng sẽ được gán cho biến ans. >> 14/4 ans = 3.5000 >> ans^(-6) ans = 5.4399e-04 5.4399e-04 là một cách thể hiện của 5.4399*10-4. Lưu ý rằng ans luơn được cập nhật giá trị bởi kết quả của phép tính cuối cùng. • Chúng ta cũng cĩ thể định nghĩa những biến mới. Theo dõi giá trị được lưu trong biến a và b: >> a = 14/4 a = 3.5000 >> b = a^(-6) b = 5.4399e-04 • Khi một lệnh được kết thúc bởi dấu ‘;” thì kết quả của nĩ sẽ khơng được xuất hiện trên màn hình. Kiểm nghiệm sự khác biệt giữa hai biểu thức sau: >> 3 + 7.5 >> 3 + 7.5; • Để cĩ thể thực thi nhiều lệnh cùng một lúc, các lệnh cần được cách nhau bởi dấu “,” (hiển thị kết quả) hay cách nhau bởi dấu “;” (khơng hiển thị kết quả) >> sin (pi/4), cos(pi); sin(0) ans = 0.7071 ans = 0 Lưu ý rằng trong các kết quả trên giá trị của cos(pi) khơng được hiển thị.
- Mở đầu 5 • Với mỗi giá trị MATLAB mặc định sẽ hiển thị ở dạng cĩ 5 chữ số. Lệnh format long sẽ tăng số chữ số hiển thị lên 15 và lệnh format short sẽ giảm trở về 5. >> 312/56 ans = 5.5714 >> format long >> 312/56 ans = 5.57142857142857 • Kết quả của mỗi lệnh cĩ thể chứa vài dịng trống, điều này cĩ thể được khắc phục bởi lệnh format compact. Ngược lại lệnh format loose sẽ thêm vào những dịng trống. • Để nhập vào một biểu thức quá dài ta sử dụng dấu ‘ ’ để xuống hàng >> sin(1) + sin(2) - sin(3) + sin(4) - sin(5) + sin(6) - sin(8) + sin(9) - sin(10) + sin(11) - sin(12) • MATLAB phân biệt chữ thường và chữ hoa. • Tất cả các ký tự từ sau dấu ‘%’ đến cuối dịng chỉ cĩ tác dụng ghi chú. >> sin(3.14159) % gần bằng sin(pi) • Nội dung của lệnh đã thực thi cũng cĩ thể được lấy lại bằng phím ↑. Để thay đổi nội dung của lệnh ta sử dụng các phím mũi tên → và ← để di chuyển con trỏ đến vị trí mong muốn và sửa lệnh. Trong trường hợp lệnh quá dài, Ctrl-a và Ctrl-e được sử dụng để di chuyển nhanh con trỏ đến vị trí đầu và cuối của lệnh. • Để gọi lại lệnh đã thực thi bắt đầu bằng ký tự, ví dụ ‘c’, ta nhấn phím ↑ sau khi nhấn phím ‘c’. Điều này cũng đúng với một cụm từ, ví dụ, cos theo sau bởi phím ↑ sẽ tìm những lệnh đã thực thi bắt đầu bởi cos. Lưu ý: nên kết thúc mỗi lệnh bằng dấu ‘;’ để tránh trường hợp xuất ra màn hình một kết quả quá lớn, ví dụ xuất ra màn hình một ma trận 1000x1000. 1.2. CÔNG CỤ GIÚP ĐỠ MATLAB cung cấp một cơng cụ giúp đỡ trực tiếp. Lệnh help là cách đơn giản nhất để được giúp đỡ. Để biết chi tiết hơn về lệnh help: >> help help Nếu đã biết tên đề mục hay tên một lệnh cụ thể nào đĩ, ta cĩ thể sử dụng lệnh help một cách cụ thể hơn, ví dụ: >> help ops cho ta biết thơng tin về các tốn tử và các ký tự đặc biệt trong MATLAB. Khi sử dụng lênh help tên đề mục mà bạn muốn giúp đỡ phải chính xác và đúng. Lệnh lookfor hữu dụng hơn trong trường hợp bạn khơng biết chính xác tên của lệnh hay đề mục. Ví dụ: >> lookfor inverse thể hiện danh sách các lệnh và một mơ tả ngắn gọn của các lệnh mà trong phần giúp đỡ cĩ từ inverse. Bạn cũng cĩ thể sử dụng một tên khơng hồn chỉnh, ví dụ lookfor inv. Bên cạnh lệnh help và lệnh lookfor cịn cĩ lệnh helpwin, lệnh helpwin mở ra một cửa sổ mới thể hiện thư mục các đề mục giúp đỡ.
- Mở đầu 6 # Bài tập 1-1. Sử dụng lệnh help hoặc lookfor để tìm kiếm thơng tin cho các câu hỏi sau: • Hãy tìm lệnh thể hiện phép tốn hàm cosin đảo hay cos-1. • Cĩ phải MATLAB cĩ một hàm tốn học dùng để tính ước số chung lớn nhất (the greatest common divisor)? • Tìm thơng tin về hàm logarithms. 1.3. DỪNG MỘT LỆNH HAY CHƯƠNG TRÌNH Thỉnh thoảng chúng sẽ gặp một lỗi bên trong lệnh hay chương trình của mình, lỗi này cĩ thể làm cho lệnh hay chương trình khơng thể dừng lại. Để dừng lệnh hay chương trình này lại ta nhấn tổ hợp phím Ctrl-C hoặc Ctrl-Break. Đơi khi để chương trình dừng lại ta phải làm động tác này vài lần và phải chờ trong vài phút. 1.4. ĐƯỜNG DẪN Trong MATLAB, lệnh hay chương trình cĩ thể chứa m-flie, các file này chỉ là các file text và cĩ phần mở rộng là ‘.m’. Các file này phải được đặt trong các thư mục mà MATLAB thấy được. Danh sách các thư mục này cĩ thể được liệt kê bởi lệnh path. Một trong các thư mục mà MATLAB luơn nhìn thấy là thư mục làm việc hiện tại, thư mục này cĩ thể được xác định bởi lệnh pwd. Sử dụng hàm path, addpath và rmpath để thêm hay xĩa các thư mục đường dẫn. Cơng việc này cũng cĩ thể được thực hiện từ thanh cơng cụ: File – Set path # Bài tập 1-2. Gõ lệnh path để kiểm tra các thư mục cĩ trong đường dẫn. Cộng một thư mục bất kỳ vào trong đường dẫn. 1.5. KHÔNG GIAN LÀM VIỆC (WORKSPACE) Khi làm việc trong cửa sổ lệnh (Command Window), MATLAB sẽ nhớ tất cả các lệnh và tất cả các biến mà chúng ta đã tạo ra. Các lệnh và biến này được hiện thị trong workspace. Chúng ta cĩ thể dễ dàng gọi lại các lệnh này khi cần, ví dụ để gọi lệnh trước ta sử dụng phím ↑. Các giá trị biến cĩ thể được kiểm tra lại bởi lệnh who, lệnh who sẽ cho danh sách các biến cĩ trong workspace. Và lệnh whos thể hiện cả tên, kích thước và lớp của biến. Ví dụ, giả sử rằng bạn đã thực thi tất cả các lệnh trong phần 1, khi thực thi lệnh who bạn sẽ cĩ được các thơng tin như sau: >> who Your variables are: a ans b x Lệnh clear sẽ xĩa biến này khỏi workspace, clear hay clear all sẽ xĩa tất cả các giá trị biến. Việc xĩa tất cả các giá trị biến là cần thiết khi ta bắt đầu một chương trình hay một bài tập mới >> clear a x >> who Your variables are: ans b
- Mở đầu 7 1.6. SAVE VÀ LOAD DỮ LIỆU Cách dễ nhất để save hay load các biến là sử dụng thanh cơng cụ, chọn File và sau đĩ chọn Save Workspace as hay Load Workspace .MATLAB cũng cĩ lệnh để save dữ liệu vào file hoặc load dữ liệu ra từ file. Lệnh Save sẽ lưu các biến trong workspace một file nhị phân hoặc file ASCII, file nhị phân tự động cĩ phần ở rộng ‘.mat’. # Bài tập 1-3. Học cách thực thi lệnh save. >> s1 = sin(pi/4); >> c1 = cos(pi/4); c2 = cos(pi/2); >> str = ‘hello word’; % đây là một chuỗI ký tự. >> save % lưu các biến ở dạng nhị phân vào file matlab.mat. >> save numdata s1, c1 % lưu hai biến s1 và c1 vào file numdata.mat >> save strdata str % lưu chuỗi str vào file strdata >> save allcos.dat c* -ascii % lưu 2 biến c1 và c2 dưới dạng ascci vào file allcos.dat Lệnh load cho phép chép các biến và giá trị của chúng từ file vào workspace. Cú pháp giống như lệnh save. Lệnh load được sử dụng khi chúng ta cần nạp các giá trị đã được khởi tạo trước vào trong chương trình. # Bài tập 1-4. Giả sử rằng chúng ta đã làm bài tập trước, thực thi các lệnh load sau đây. Trước mỗi lệnh load, sử dụng lệnh clear all để xĩa workspace và sau đĩ sử dụng lệnh who để kiểm tra giá trị các biến cĩ trong workspace. >> load % load tất cả các biến trong file matlab.mat >> load data s1 c1 % chỉ load các biến được chỉ định trong file data.mat >> load strdata % load tất cả các biến trong file strdata.mat Ta cũng cĩ thể đọc được file ASCII, là file chứa một dãy các biến riêng rẽ. Chẳng hạn như file chứa các chú thích được bắt đầu từ ký tự ‘%’. Kết quả được đặt vào biến cĩ cùng tên với file ASCII (ngoại trừ phần mở rộng). >> load allcos.dat % load dữ liệu từ file allcos vào biến allcos >> who % liệt kê tất cả các biến cĩ trong workspace
- Mở đầu 8 Danh sách các lệnh và hàm được giới thiệu trong chương 1 addpath Thêm đường dẫn vào danh sách các đường dẫn của MATLAB clear Xố khơng gian làm việc (workspace) exit Thốt khỏi MATLAB format Định dạng dữ liệu hiển thị help Xem thơng tin giúp đỡ về một hàm nào đĩ helpwin Mở một cửa sổ hướng dẫn mới load Tải dữ liệu từ file .mat vào khơng gian làm việc hiện tại lookfor Tìm kiếm các hàm MATLAB nhờ từ khố cho trước path Liệt kê các đường dẫn mà MATLAB cĩ thể thấy được pwd Xác định thư mục hiện hành của MATLAB quit Thốt khỏi MATLAB rmpath Xố một đường dẫn khỏi danh sách các đường dẫn của MATLAB save Lưu các biến dữ liệu vào file .mat who Liệt kê danh sách các biến cĩ trong workspace whos Liệt kê các biến cĩ trong workspace: gồm tên, kích thước và lớp của biến
- Cơ bản về cú pháp và biến 9 Chương 2 2. CƠ BẢN VỀ CÚ PHÁP VÀ BIẾN 2.1. MATLAB NHƯ LÀ MỘT CÔNG CỤ TÍNH TOÁN Các kiểu số cơ bản được sử dụng trong MATLAB là số nguyên, số thực và số phức. MATLAB cũng cĩ thể biểu diễn các số non-number. Cĩ hai dạng số non-number trong MATLAB: Inf, là số vơ cực dương được tạo ra bởi phép chia 1/0 và NaN, là số được tạo ra từ các phép tốn chẳng hạn như 0/0 hay ∞ - ∞. Như chúng ta đã biết, MATLAB là một cơng cụ thực sự hữu dụng đối với các phép tính. Chẳng hạn khi nhập vào lệnh: >> (23*17)/7 Kết quả sẽ là ans = 55.8571 MATLAB cĩ sáu phép tốn số học cơ bản: +, -, *, / hoặc \ và ^ (số mũ). Lưu ý rằng hai phép tốn chia trái và chia phải là khác nhau >> 19/3 % 19/3 ans = 6.3333 >> 19\3, 3/19 % 3/19 ans = 0.1579 ans = 0.1579 Các hàm lượng giác và các hàm mũ logarith cũng được sử dụng trong MATLAB. Sử dụng help elfun để liệt kê danh sách các hàm cơ bản cĩ trong MATLAB. # Bài tập 2-1. Thử tính tốn các biểu thức sau đây bằng tay và sau đĩ sử dụng MATLAB để kiểm tra lại kết quả. Lưu ý sự khác nhau giữa phép chia trái và phải. Sử dụng lệnh help để cĩ hướng dẫn về cách sử dụng các lệnh mới, chẳng hạn như các lệnh làm trịn số: round, floor, ceil, • 2/2*3 • 3^2/4 • 8*5\4 • 3^2^3 • 8*(5\4) • 2 + round(6/9 + 3*2)/2 • 7 – 5*4\9 • 2 + floor(6/9 + 3*2)/2 • 6 – 2/5 + 7^2 – 1 • 2 + ceil(6/9 + 3*2)/2 • 10/2\5 – 3 + 2*4 • x = pi/3, x = x – 1, x = x + 5, x=abs(x)/x
- Cơ bản về cú pháp và biến 10 # Bài tập 2-2. Sử dụng các lệnh để định dạng MATLAB khơng xuất hiện dịng trống trong kết quả và kết quả được xuất ra ở dạng số cĩ 15 chữ số. Thực hiện các lệnh: >> pi >> sin(pi) sau đĩ sử dụng lệnh các lệnh format để khơi phục lại định dạng chuẩn. 2.2. PHÉP GÁN VÀ BIẾN Các phép tốn liên quan đến số phức được thực thi một cách dễ dàng bởi MATLAB. # Bài tập 2-3. • Cho hai số phức bất kỳ, ví dụ –3 + 2i và 5 – 7i. Hãy thực hiện các phép tốn để cộng, trừ, nhân và chia hai số phức này với nhau. Trong bài tập này với 4 phép tính thì các số phức phải được nhập 4 lần, để đơn giản việc này ta gán mỗi số phức cho một biến. Kết quả của bài tập này sẽ là: >> z = -3 + 2*i; >> w = 5 – 7*i; >> y1 = z + w; >> y2 = z – w; >> y3 = z*w; >> y4 = z/w; y5 = w\z; Khơng giống như các ngơn ngữ lập trình thơng thường, trong MATLAB ta khơng cần phải khai báo biến. Một biến sẽ được tự động tạo ra trong quá trình gán dữ liệu cho biến đĩ. Mỗi giá trị khi mới tạo ra thì được mặc định cĩ kiểu số là double, kiểu số 32 bit. Chúng ta cĩ thể sử dụng lệnh single để chuyển kiểu số từ dạng double sang dạng single, là kiểu số 16 bit. >> a = single(a); Lệnh single nên được sử dụng trong trường hợp cần xử lý những ma trận cĩ kích thước lớn. Tuy nhiên trong trường hợp chỉ cĩ vài giá trị được sử dụng thì ta nên chuyển qua dạng double để cĩ được sự chính xác hơn. Sử dụng lệnh double để thực hiện phép biến đổi này. >> a = double(a); Lưu ý rằng một biến chưa được định nghĩa thì khơng được sử dụng để gán cho một biến khác >> clear x; >> f = x^2 + 4*sin(x); Đoạn lệnh ở trên sẽ khơng cho ra một kết quả đúng bởi vì giá trị của x chưa được khởi tạo. Biểu thức trên cĩ thể sửa lại bằng cách gán một giá trị bất kỳ cho biến x. >> x = pi; >> f = x^2 + 4*sin(x); Trong MATLAB, tên của một biến phải được bắt đầu bởi một ký tự chữ, cĩ thể là chữ thường hay chữ in hoa, và theo sau bởi các ký tự chữ, các ký tự số số hoặc dấu gạch chân. MATLAB chỉ cĩ thể phân biệt được các biến với nhau bởi tối đa 31 ký tự đầu tiên của tên biến.
- Cơ bản về cú pháp và biến 11 # Bài tập 2-4. Sau đây là ví dụ về một vài kiểu biến số khác nhau của MATLAB. Chúng ta sẽ được học kỹ hơn về các lệnh này ở phần sau. >> this_is_my_very_simple_variable_today = 5 % điều gì sẽ xảy ra? >> 2t = 8; % điều gì sẽ xảy ra? >> M = [1 2; 3 4; 5 6]; % một ma trận >> c = ‘E’ % một ký tự >> str = ‘Hello word’; % một chuỗi >> m = [‘J’,’o’,’h’,’n’] % m là cái gì? Sử dụng lệnh who để kiểm tra thơng tin về các biến. Sử dụng lệnh clear để xố các biến khỏi workspace. Trong MATLAB cĩ những số được mặc định tạo ra và được xem như là các hằng số, ví dụ như pi, eps, hay i, một số các giá trị khác được cho trong bảng 2.1. Bảng 2.1: Một số biến mặc định trong MATLAB Tên biến Giá trị / Ý nghĩa ans Tên biến mặc định dùng để lưu kết quả của phép tính cuối cùng. pi π = 3.14159 eps Số dương nhỏ nhất inf Mơ tả số dương ∞ nan hay NaN Mơ tả một not-a-number, ví dụ 0/0 i hay j i = j = −1 nargin/nargout Số đối số input/output của hàm realmin/realmax Số thực dương nhỏ nhất/lớn nhất cĩ thể • Các biến được tạo ra bằng cách gán giá trị cho chúng. Một cách khác là gán giá trị của biến này cho biến khác. >> b = 10.5 >> a = b Theo cách này biến a tự động được tạo ra, nếu biến a đã tồn tại thì giá trị cũ của nĩ sẽ bị chồng lên bởi một giá trị mới. Một biến cũng cĩ thể được tạo ra bởi kết quả của một phép tốn: >> a = 10.5; >> c = a^2 + sin(pi*a)/4; Kết quả trả về của một hàm cĩ thể được sử dụng để gán và tạo ra các biến mới. Ví dụ, nếu min là tên của một hàm (tìm hiểu thêm chức năng và cách sử dụng của hàm min bởi lệnh help min) thì: >> b = 5; c = 7;
- Cơ bản về cú pháp và biến 12 >> a = min(b,c); % giá trị nhỏ nhất của b và c sẽ gọi một hàm với hai biến b và c là hai đối số. Kết quả của hàm này (giá trị trả về của hàm) sẽ được gán cho biến a. Lưu ý: ta khơng được sử dụng tên biến trùng với tên hàm. Để kiểm tra một tên nào đĩ cĩ phải tên hàm hay khơng ta sử dụng lênh help để xác định. Nếu kết quả là các hương dẫn liên quan đến hàm thì tên đĩ đã được sử dụng để làm tên hàm. Ví dụ, trong trường hợp thực hiện các vịng lặp liên quan đến số phức, ta khơng sử dụng biến i hoặc j để làm biến đếm bởi vì các giá trị này được sử dụng để làm số phức.
- Cơ bản về cú pháp và biến 13 Danh sách các lệnh và hàm được giới thiệu trong chương 2 ceil Làm trịn lên double Chuyển sang kiểu số chiều dài 32 bit floor Làm trịn xuống format Định dạng các dữ liệu số min Trả về giá trị nhỏ nhất của hai hay nhiều số round Làm trịn về số nguyên gần nhất single Chuyển sang kiểu số chiều dài 16 bit who Liệt kê các biến cĩ trong workspace
- Phép tốn với vector và ma trận 14 Chương 3 3. PHÉP TOÁN VỚI VECTOR VÀ MA TRẬN Trong Matlab, tất cả các đối tượng đều được xem như là một ma trận hay cịn được gọi là mảng. Một chữ số được xem như là một ma trận 1x1 và ma trận chỉ cĩ một hàng hay một cột được gọi là vector. 3.1. VECTOR Trong quá trình khởi tạo, các thành phần của một vector được phân biệt với nhau bởi khoảng trống hoặc dấu ‘,’. Chiều dài của một vector là số thành phần tồn tại trong nĩ (lệnh length được sử dụng để xác định chiều dài của vector). Tất cả các thành phần của một vector phải được đặt trong dấu []: >> v = [-1 sin(3) 7] v = -1.0000 0.1411 7.0000 >> length(v) ans = 3 Ta cĩ thể áp dụng nhiều phép tính cơ bản khác nhau đối với vector. Một vector cĩ thể nhân với một hệ số hoặc cộng/trừ với một vector khác cĩ cùng chiều dài. Trong phép cộng/trừ, từng thành phần của hai vector cộng/ trừ với nhau và cho ra một vector cĩ cùng chiều dài. Ta cũng cĩ thể sử dụng phép gán đối với vector. >> v = [-1 2 7]; >> w = [2 3 4]; >> z = v + w % cộng từng thành phần với nhau z = 1 5 11 >> vv = v + 2 % 2 được cộng vào từng thành phần của vector v vv = 1 4 9 >> t = [2*v, -w] ans = -2 4 14 -2 -3 -4 Mỗi thành phần của vector cũng cĩ thể được sử dụng một cách riêng biệt: >> v(2) = -1 % thay đổI giá trị thành phần thứ 2 của v v = -1 -1 7 >> w(2) % hiển thị giá trị thành phần thứ 2 của w ans = 3
- Phép tốn với vector và ma trận 15 3.1.1. DẤU ‘:’ VÀ PHẦN TRÍCH RA TỪ VECTOR Dấu ‘:’ là một tốn tử quan trọng, nĩ được sử dụng để xử lý với các vector hàng (xem thêm ở bảng 3.1 hoặc sử dụng lệnh help colon để cĩ nhiều thơng tin hơn về tốn tử này): Bảng 3.1: Những thành phần con của ma trận Lệnh Kết quả A(i, j) Aij A(:, j) Cột thứ j của A A(i, :) Hàng thứ i của A A(k:l,m:n) Ma trận con của ma trận A v(i:j) Một phần của vector v >> 2:5 ans = 2 3 4 5 >> -2:3 ans = -2 -1 0 1 2 3 Một cách tổng quát, lệnh cĩ cấu trúc first:step:last sẽ tạo ra một vector cĩ thành phần đầu tiên bằng first, giá trị của các thành phần tiếp theo được tăng bởi step và thành phần cuối cùng cĩ giá trị ≤ last: >> 0.2:0.5:2.4 ans = 0.2000 0.7000 1.2000 1.7000 2.2000 >> -3:3:10 ans = -3 0 3 6 9 >> 1.5:-0.5:-0.5 % step cũng cĩ thể là số âm ans = 1.5000 1.0000 0.5000 0 -0.5000 Tốn tử ‘:’ cũng được sử dụng để trích ra một số thành phần từ một vector. >> r = [-1:2:6, 2, 3, -2] % -1:2:6 ≡ -1 1 3 5 r = -1 1 3 5 2 3 -2 >> r(3:6) % các giá trị của r từ 3 đến 6 ans = 3 5 2 3 >> r(1:2:5) % lấy các vị trí 1, 3, 5 ans =
- Phép tốn với vector và ma trận 16 -1 3 2 >> r(5:-1:2) % điều gì sẽ xảy ra? 3.1.2. VECTOR CỘT VÀ PHÉP CHUYỂN VỊ Đối với một vector cột, các thành phần của nĩ phải được phân biệt với nhau bởi dấu ‘;’ hoặc xuống dịng: >> z = [1 7 7]; z = 1 7 7 >> u = [-1; 3; 5] u = -1 3 5 Những phép tốn áp dụng với vector hàng cũng cĩ thể được sử dụng ở vector cột. Tuy nhiên, chúng ta khơng thể cộng một vector hàng với một vector cột. Để thực hiện được phép tính này, ta cần sử dụng tốn tử chuyển vị, tốn tử này sẽ chuyển một vector hàng thành một vector cột và ngược lại: >> u' % u là vector cột, u’ sẽ là vector hàng ans = -1 3 5 >> v = [-1 2 7]; % v là một vector hàng >> u + v % khơng thể cộng một vector cột và vector hàng ??? Error using ==> + Matrix dimensions must agree. >> u' + v ans = -2 5 12 >> u + v' ans = -2 5 12 Nếu z là một vector phức thì z’ sẽ cho ra một chuyển vị liên hợp của z, nghĩa là từng thành phần của z’ là liên hợp phức với các thành phần trong z. Trong trường hợp cần chuyển vị theo kiểu thơng thường (các số phức được giữ nguyên giá trị) ta phải sử dụng tốn tử ‘.’’
- Phép tốn với vector và ma trận 17 >> z = [1+2i, -1+i] z = 1.0000 + 2.0000i -1.0000 + 1.0000i >> z' % chuyển vị liên hợp ans = 1.0000 - 2.0000i -1.0000 - 1.0000i >> z.' % phép chuyển vị thơng thường ans = 1.0000 + 2.0000i -1.0000 + 1.0000i 3.1.3. NHÂN, CHIA VÀ SỐ MŨ CỦA VECTƠ Chúng ta cĩ thể nhân hai vector cĩ cùng chiều dài, xT y = x y theo cách đơn giản: ∑i i i >> u = [-1; 3; 5] % một vector cột >> v = [-1; 2; 7] % một vector cột >> u * v % khơng thể nhân 2 vector cột với nhau ??? Error using ==> * Inner matrix dimensions must agree. >> u' * v % kết quả nhân 2 vector ans = 42 Một cách khác để nhân hai vector là sử dụng tốn tử ‘.*’. Với tốn tử này các thành phần tương ứng của hai vector sẽ được nhân với nhau. Cho hai vector x và y cĩ cùng chiều dài, tích ‘.*’ của hai vector là [x1y1, x2y2, , xnyn]: >> u .* v % nhân từng thành phần tương ứng 1 6 35 >> sum(u.*v) % tương đương phép nhân 2 vector ans = 42 >> z = [4 3 1]; % z là vector hàng >> sum(u'.*z) % phép nhân 2 vector ans = 10 >> u'*z' % tích 2 vector ans =
- Phép tốn với vector và ma trận 18 10 Ví dụ 3-1: >> x = 1:0.5:4; >> y = sqrt(x) .* cos(x) y = 0.5403 0.0866 -0.5885 -1.2667 -1.7147 -1.7520 -1.3073 Trong tốn học khơng tồn tại phép chia hai ma trận cho nhau. Tuy nhiên, trong MATLAB tốn tử ‘./’ được định nghĩa như là phép chia từng thành phần tương ứng của hai ma trận với nhau. Kết quả cũng là một ma trận cĩ cùng kích thước: >> x = 2:2:10 x = 2 4 6 8 10 >> y = 6:10 y = 6 7 8 9 10 >> x./y ans = 0.3333 0.5714 0.7500 0.8889 1.0000 >> z = -1:3 z = -1 0 1 2 3 >> x./z % 4/0, kết quả là Inf Warning: Divide by zero. ans = -2.0000 Inf 6.0000 4.0000 3.3333 >> z./z % 0/0, kết quả là NaN Warning: Divide by zero. ans = 1 NaN 1 1 1 Tốn tử ‘./’ cũng cĩ thể được sử dụng để chia một số cho một vector: >> x=1:5; 2/x % chương trình báo lỗi ??? Error using ==> / Matrix dimensions must agree. >> 2./x % phép tính đúng ans = 2.0000 1.0000 0.6667 0.5000 0.4000 # Bài tập 3-1.
- Phép tốn với vector và ma trận 19 Để làm quen với các phép tốn về vector hàng và vector cột, hãy thực hiện các vấn đề sau đây: • Tạo một vector bao gồm những số lẻ trong khoảng từ 21 đến 47. • Cho x = [4 5 9 6]. - Trừ đi 3 ở mỗi thành phần của vector - Cộng 11 vào các thành phần cĩ vị trí lẻ - Tính căn bậc 2 của mỗi thành phần - Mũ 3 mỗi thành phần • Tạo một vector với các thành phần - 2, 4, 6, 8, , 20 - 9, 7, 5, , -3, -5 - 1, ½, 1/3, ¼, 1/5, , 1/10 - 0, ½, 2/3, ¾, 4/5, , 9/10 (−1)n • Tạo một vector với các thành phần: x = với n = 1, 2, 3, , 100. Tìm tổng 50 thành n 2n −1 phần đầu tiên của vector này. • Cho vector t bất kỳ, viết biểu thức MATLAB để tính - ln(2 + t + t2) - cos(t)2 – sin(t)2 - et(1 + cos(3t)) - tan-1(t) Kiểm tra với t = 1:0.2:2 • Cho x = [1 + 3i, 2 – 2i] là một vector phức. Kiểm tra các biểu thức sau: - x’ - x*x’ - x.’ - x*x.’ # Bài tập 3-2. Cho x = [2 1 3 7 9 4 6], hãy giải thích các lệnh sau đây (x(end) là thành phần cuối cùng của vector x) - x(3) - x(6:-2:1) - x(1:7) - x(end-2:-3:2) - x(1:end) - sum(x) - x(1:end-1) - mean(x) - x(2:2:6) - min(x) 3.2. MA TRẬN Vector hàng và vector cột là những trường hợp đặc biệt của ma trận. Ma trận nxk là một mảng gồm cĩ n hàng và k cột. Định nghĩa một ma trận trong MATLAB tương tự như định nghĩa
- Phép tốn với vector và ma trận 20 một vector. Các thành phần của hàng được phân biệt với nhau bởi dấu ‘,’ hoặc khoảng trống, ⎛1 2 3⎞ ⎜ ⎟ cịn các hàng được phân biệt bởi dấu ‘;’. Ví dụ ma trận A = ⎜4 5 6⎟ được định nghĩa như ⎜ ⎟ ⎝7 8 9⎠ sau: >> A = [1 2 3; 4 5 6; 7 8 9] A = 1 2 3 4 5 6 7 8 9 Một số ví dụ khác: >> A2 = [1:4; -1:2:5] A2 = 1 2 3 4 -1 1 3 5 >> A3 = [1 3 -4 7] A3 = 1 3 -4 7 Từ những ví dụ ở trên ta nhận thấy rằng một vector hàng là một ma trận 1xk và một vector cột là một ma trận nx1. Phép chuyển vị sẽ chuyển một vector hàng thành một vector cột và ngược lại. Điều này cĩ thể mở rộng cho một ma trận, phép chuyển vị sẽ biến các hàng của ma trận thành các cột và ngược lại. >> A2 A2 = 1 2 3 4 -1 1 3 5 >> A2' % chuyển vị của ma trận A2 ans = 1 -1 2 1 3 3 4 5 >> size(A2) % kích thước của ma trận A2 ans = 2 4 >> size(A2')
- Phép tốn với vector và ma trận 21 ans = 4 2 3.2.1. NHỮNG MA TRẬN ĐẶC BIỆT Trong MATLAB cĩ một số hàm được sử dụng để tạo ra các ma trận đặc biệt, tham khảo thêm ở bảng 3.2. Bảng 3.2: Một số hàm và phép tốn thường sử dụng với ma trận. Lệnh Kết quả n = rank(A) Số chiều của ma trận A x = det(A) Định thức của ma trận A x = size(A) Kích thước của A x = trace(A) Tổng các thành phần trên đường chéo của A x = norm(v) Chiều dài Euclide của vector v C = A + B Tổng hai ma trận C = A – B Hiệu hai ma trận C = A*B Tích hai ma trận C = A.*B Tích từng thành phần tương ứng của hai ma trận C = A^k Lũy thừa của ma trận C = A.^k Lũy thừa từng thành phần của ma trận C = A’ Ma trận chuyển vị AT C = A./B Chia từng thành phần tương ứng của hai ma trận C = inv(A) Nghịch đảo của ma trận A X = A\B Giải phương trình AX = B X = B\A Giải phương trình XA = B x = linspace(a,b,n) Vector x cĩ n thành phần phân bố đều trong khoảng [a,b] x = logspace(a,b,n) Vector x cĩ n thành phần bắt đầu 10a và kết thúc với 10b A = eye(n) Ma trận đồng nhất A = zeros(n,m) Ma trận all-0 A = ones(n,m) Ma trận all-1 A = diag(v) Ma trận zero với đường chéo là các thành phần của vector v X = tril(A) Trích ra ma trận tam giác dưới X = triu(A) Trích ra ma trận tam giác trên A = rand(n,m) Ma trận A với các thành phần là phân bố đồng nhất giữa (0,1) A = randn(n,m) Giống như trên với các thành phần phân bố chuẩn. Nếu A là một vector thì v là giá trị lớn nhất của A v = max(A) Nếu A là ma trận thì v là một vector với các thành phần là giá trị lớn nhất trên mỗi cột của A v = min(A) Như trên với giá trị nhỏ nhất v = sum(A) Như trên với tổng
- Phép tốn với vector và ma trận 22 >> E = [] % một ma trận rỗng 0 hàng 0 cột E = [] >> size(E) ans = 0 0 >> I = eye(3); % ma trận đồng nhất 3x3 I = 1 0 0 0 1 0 0 0 1 >> x = [2; -1; 7]; I*x % I*x = x ans = 2 -1 7 >> r = [1 3 -2]; >> R = diag(r) % tạo một ma trận đường chéo R = 1 0 0 0 3 0 0 0 -2 >> A = [1 2 3; 4 5 6; 7 8 9]; >> diag(A) % trích ra đường chéo của ma trận A ans = 1 5 9 >> B = ones(3,2) B = 1 1 1 1 1 1 >> C = zeros (size(C')) % ma trận all zero với kích thước của C’ C = 0 0 0 0 0 0
- Phép tốn với vector và ma trận 23 >> D = rand(2,3) % ma trận các giá trị ngẫu nhiên trong khoảng (0, 1) D = 0.0227 0.9101 0.9222 0.0299 0.0640 0.3309 >> v = linspace(1, 2, 4) % v là một vector cĩ 4 giá trị cách đều nhau trong khoảng [1, 2] v = 1.0000 1.3333 1.6667 2.0000 3.2.2. XÂY DỰNG MA TRẬN VÀ TRÍCH RA MỘT MA TRẬN CON TỪ MỘT MA TRẬN LỚN HƠN Chúng ta cĩ thể tạo ra một ma trận lớn từ các ma trận nhỏ hơn: >> x = [4; -1], y = [-1 3] x = 4 -1 y = -1 3 >> X = [x y'] % X bao gồm các cột của x và y' X = 4 -1 -1 3 >> T = [ -1 3 4; 4 5 6]; t = 1:3; >> T = [T; t] % cộng thêm vào T một dịng mới, t T = -1 3 4 4 5 6 1 2 3 >> G = [1 5; 4 5; 0 2]; % G là ma trận 3x2 >> T2 = [T G] % kết nối 2 ma trận T2 = -1 3 4 1 5 4 5 6 4 5 1 2 3 0 2 >> T3 = [T; G ones(3,1)] % G là ma trận 3x2 % T là ma trận 3x3 T3 = -1 3 4 4 5 6
- Phép tốn với vector và ma trận 24 1 2 3 1 5 1 4 5 1 0 2 1 >> T3 = [T; G']; % điều gì xảy ra? >> [G' diag(5:6); ones(3,2) T] % kết nối nhiều ma trận ans = 1 4 0 5 0 5 5 2 0 6 1 1 -1 3 4 1 1 4 5 6 1 1 1 2 3 Cũng tương tự như với vector, chúng ta cĩ thể trích ra một số thành phần của ma trận. Mỗi thành phần của ma trận được đánh dấu bởi vị trí hàng và cột. Thành phần ở hàng i và cột j được ký hiệu là Aij, và ký hiệu trong MATLAB là A(i,j). >> A = [1:3; 4:6; 7:9] A = 1 2 3 4 5 6 7 8 9 >> A(1,2), A(2,3), A(3,1) ans = 2 ans = 6 ans = 7 >> A(4,3) % khơng đúng vì A là ma trận 3x3 ??? Index exceeds matrix dimensions. >> A(2,3) = A(2,3) + 2*A(1,1) % thay đổI giá trị của A(2,3) A = 1 2 3 4 5 8 7 8 9 Một ma trận cũng cĩ thể được mở rộng theo cách sau đây: >> A(5,2) = 5 % gán 5 cho vị trí A(5,2) và % các thành phần khác là zero A =
- Phép tốn với vector và ma trận 25 1 2 3 4 5 8 7 8 9 0 0 0 0 5 0 Các thành phần zero của ma trận A ở trên cũng cĩ thể được thay đổi: >> A(4,:) = [2, 1, 2]; % gán vector [2, 1, 2] vào hàng thứ 4 của A >> A(5,[1,3]) = [4, 4]; % gán A(5,1) = 4 và A(5,3) = 4 >> A % kiểm tra sự thay đổi của ma trận A? Những phần khác nhau của ma trận A được trích ra theo cách sau đây: >> A(3,:) % trích ra hàng thứ 3 của A ans = 7 8 9 >> A(:,2) % trích ra cột thứ 2 của A ans = 2 5 8 1 5 >> A(1:2,:) % trích ra hàng thứ 1 và 2 của A ans = 1 2 3 4 5 8 >> A([2,5],1:2) % trích ra một phần của A ans = 4 5 4 5 Các lệnh ở những ví dụ trên được giải thích ngắn ngọn trong bảng 3.1. Lưu ý khái niệm ma trận rỗng [], chẳng hạn các hàng hay cột của ma trận cĩ thể được xĩa bỏ bằng cách gán giá trị của nĩ cho ma trận rỗng []. >> C = [1 2 3 4; 5 6 7 8; 1 1 1 1]; >> D = C; D(:,2) = [] % xĩa cột thứ 2 của D >> C ([1,3],:) = [] % xĩa cột thứ 1 và 2 của C # Bài tập 3-3. Hãy xĩa tất cả các biến (sử dụng lệnh clear). Định nghĩa ma trận A = [1:4; 5:8; 1 1 1 1]. Hãy thực thi và kiểm tra kết quả của các phép tính sau:
- Phép tốn với vector và ma trận 26 • x = A(:, 3) • y = A(3 : 3, 1 : 4) • B = A(1 : 3, 2 : 2) • A = [A; 2 1 7 7; 7 7 4 5] • A(1, 1) = 9 + A(2, 3) • C = A([1, 3], 2) • A(2 : 3, 1 : 3) = [0 0 0; 0 0 0] • D = A([2, 3, 5], [1, 3, 4]) • A(2 : 3, 1 : 2) = [1 1; 3 3] • D(2, :) = [ ] # Bài tập 3-4. Cho A = [1, 5, 6; 3, 0, 8], B = [7, 3, 5; 2, 8, 1], C = 10 và D = 2. Hãy thực hiện các phép tính sau đây: • E = A – B • Gán cột đầu tiên của A cho M • F = D*B • Gán cột thứ hai của của G cho N • G = A.*B • Chỉ nhân cột thứ 3 của A cho 5 • H = A’ • Cộng M và N • J = B/D • Tìm tổng tất cả các giá trị của ma trận A # Bài tập 3-5. Định nghĩa ma trận T = [ 3 4; 1 8; -4 3]; A = [diag(-1:2:3) T; -4 4 1 2 1]. Thực hiện các phép biến đổi sau đây đối với ma trận A: • Trích ra một vector bao gồm thành phần thứ 2 và 4 của hàng thứ 3. • Tìm giá trị nhỏ nhất của cột thứ 3 • Tìm giá trị lớn nhất của hàng thứ 2 • Tính tổng các thành phần của cột thứ 2 • Tính giá trị trung bình của hàng thứ 1 và thứ 4. • Trích ma trận con bao gồm hàng thứ 1 và thứ 3. • Trích ma trận con bao gồm hàng thứ 1 và 2 của cột 3, 4, 5. • Tính tổng các thành phần của hai hàng 1 và 2. • Cộng các thành phần của cột thứ 2 và thứ 3 với 3. # Bài tập 3-6. Cho ma trận A = [2 4 1; 6 7 2; 3 5 9]. Thực thi các phép tốn sau đối với ma trận A: • Gán hàng thứ 1 cho vector x • Gán 2 hàng cuối của A cho y. • Cộng các thành phần trong từng hàng của A • Cộng các thành phần trong từng cột của A # Bài tập 3-7. Cho A = [2 7 9 7; 3 1 5 6; 8 1 2 5]. Giải thích kết quả của các lệnh sau: • A’ • sum (A)
- Phép tốn với vector và ma trận 27 • A(1, :) • sum (A’) • A(:, [1 4]) • mean (A) • A([2 3], [3 1]) • mean (A’) • reshape (A, 2, 6) • sum (A, 2) • A(:) • mean (A, 2) • flipud (A) • min (A) • fliplr (A) • max (A’) • [A; A(end, :)] • min (A(:, 4)) • [A; A(1 : 2, :)] • [min(A)’ max(A)’] • max (min(A)) • Xĩa cột thứ 2 của A • [[A; sum (A)] [sum (A,2); sum (A(:))]] • Gán các cột chẵn của A cho B • Gán các hàng lẻ của A cho C • Biến A thành ma trận 4x3 • Tính 1/x các thành phần của A • Tính bình phương các thành phần A • Cộng một hàng all-1 vào đầu và cuối A • Hốn đổi hai hàng 2 và 3 Lưu ý: sử dụng lệnh help để tìm hiểu ý nghĩa của các lệnh mới. 3.2.3. TÍNH TOÁN VỚI MA TRẬN Các hàm và phép tốn thường sử dụng với ma trận được cho trong bảng 3.2. Lưu ý tốn tử ‘.’ trong phép nhân ma trận với ma trận và phép nhân ma trận với vector. Tốn tử ‘.’ xuất hiện trong phép nhân, phép chia và số mũ. Khi cĩ tốn tử này, phép tốn sẽ được thực hiện với từng thành phần của ma trận. Cụ thể trong phép nhân/chia, từng thành phần tương ứng của 2 ma trận sẽ nhân/chia với nhau và kết quả sẽ là một ma trận cĩ cùng kích thước với 2 ma trận ban đầu. Như vậy trong trường hợp sử dụng tốn tử này 2 ma trận phải cĩ cùng kích thước với nhau. Xem xét các ví dụ sau: >> B = [1 -1 3; 4 0 7] B = 1 -1 3 4 0 7 >> B2 = [1 2; 5 1; 5 6]; >> B = B + B2' % cộng 2 ma trận B = 2 4 8 6 1 13
- Phép tốn với vector và ma trận 28 >> B-2 % trừ các thành phần của B cho 2 ans = 0 2 6 4 -1 11 >> ans = B./4 % chia các thành phần của B cho 4 ans = 0.5000 1.0000 2.0000 1.5000 0.2500 3.2500 >> 4/B % sai cú pháp ??? Error using ==> / Matrix dimensions must agree. >> 4./B % tương đương với 4.*ones(size(B))./B ans = 2.0000 1.0000 0.5000 0.6667 4.0000 0.3077 >> C = [1 -1 4; 7 0 -1]; >> B .* C % nhân từng vị trí với nhau ans = 2 -4 32 42 0 -13 >> ans.^3 - 2 % mũ 3 các thành phần sau đĩ trừ cho 2 ans = 6 -66 32766 74086 -2 -2199 >> ans ./ B.^2 % từng vị trí chia cho nhau ans = 0.7500 -1.0312 63.9961 342.9907 -2.0000 -1.0009 >> r = [1 3 -2]; r * B2 ans = 6 -7 Lưu ý các phép nhân ma trận-ma trận và phép nhân ma trận-vector. >> b = [1 3 -2]; >> B = [1 -1 3; 4 0 7] B = 1 -1 3 4 0 7
- Phép tốn với vector và ma trận 29 >> b * B % khơng thể thực hiện được ??? Error using ==> * Inner matrix dimensions must agree. >> b * B' % thực hiện được ans = -8 -10 >> B' *ones(2,1) ans = 5 -1 10 >> C = [3 1; 1 -3]; >> C * B ans = 7 -3 16 -11 -1 -18 >> C.^3 % mủ 3 từng thành phần ans = 27 1 1 -27 >> C^3 % tương đương với C*C*C ans = 30 10 10 -30 >> ones(3,4)./4 * diag(1:4) ans = 0.2500 0.5000 0.7500 1.0000 0.2500 0.5000 0.7500 1.0000 0.2500 0.5000 0.7500 1.0000 # Bài tập 3-8. Hãy thực thi tất cả phép tốn trong bảng 3.2, tự chọn các giá trị cho ma trận A, B vector v và các hệ số k, a, b, n và m. # Bài tập 3-9. Cho A là một ma trận vuơng, tạo ma trận B giống ma trận A nhưng tất cả các thành phần trên đường chéo chính đều bằng 1. # Bài tập 3-10. Cho vector x = [1 3 7], y = [2 4 2] và ma trận A = [3 1 6; 5 2 7], B = [1 4; 7 8; 2 2]. Phép tốn nào sau đây là khơng đúng? Kết quả của mỗi phép tính?
- Phép tốn với vector và ma trận 30 • x + y • [x; y’] • x + A • [x; y] • x’ + y • A – 3 • A - [x’ y’] • A + B • [x; y] + A • B’ + A • B*A • B./x’ • A.* B • B./[x’ x’] • A’.* B • 2/A • 2*B • ones(1, 3)*A • 2.* B • ones(1, ê5 # Bài tập 3-11. Cho A là một ma trận ngẫu nhiên 5x5, b là một vector ngẫu nhiên 5x1. Tìm x thỏa mãn biểu thức Ax = b (tham khảo thêm ở bảng 3.2). Giải thích sự khác nhau giữa tốn tử ‘\’, ‘/’ và lệnh inv. Sau khi cĩ x, hãy kiểm tra Ax – b cĩ phải là một vector all-zero hay khơng? # Bài tập 3-12. Hãy tìm hai ma trận 2x2 A và B thỏa mãn A.*B ≠ A*B. Sau đĩ tìm tất cả các ma trận A và B sao cho A.*B = A*B (gợi ý: sử dụng các tốn tử ‘/’, ‘\’ và lệnh inv).
- Phép tốn với vector và ma trận 31 Danh sách các lệnh và hàm được giới thiệu trong chương 3 det Định thức của ma trận diag Tạo ma trận đường chéo eye Ma trận đơn vị inv Nghịch đảo của 1 ma trận length Chiều dài của vector linspace Chia một đoạn thành các khoảng chia tuyến tính logspace Chia một đoạn thành các khoảng chia logarithm max Hàm giá trị lớn nhất min Hàm giá trị nhỏ nhất norm Chiều dài Euclide của vector ones Ma trận tồn 1 rand Ma trận ngẫu nhiên với các thành phần phân bố đều trên (0,1) randn Ma trận ngẫu nhiên với các thành phần phân bố chuẩn rank Hạng của ma trận size Kích thước của ma trận sum Hàm tính tổng trace Tổng các thành phần trên đường chéo của ma trận (vết của ma trận) tril Trích ra ma trận tam giác dưới triu Trích ra ma trận tam giác trên zeros Ma trận tồn zero
- Đồ thị 2D và 3D 32 Chương 4 4. ĐỒ THỊ 2D VÀ 3D MATLAB cĩ thể được sử dụng để thể hiện các kết quả dưới dạng đồ thị, mỗi biến sẽ chứa tất cả các giá trị của một đối số trong lệnh vẽ đồ thị. 4.1. NHỮNG ĐỒ THỊ ĐƠN GIẢN Với lệnh plot chúng ta dễ dàng vẽ được những đồ thị đơn giản. Cho vector y, lệnh plot(y) sẽ xác định những điểm [1, y(1)], [2, y(2)], , [n, y(n)] và nối các điểm này lại bằng những đường thẳng. Lệnh plot(x,y) thực hiện một cơng việc tương tự như vậy với những điểm [x(1), y(1)], [x(2), y(2)], , [x(n), y(n)]. Lưu ý rằng hai vector x và y phải cùng là vector hàng hoặc vector cột và cĩ cùng chiều dài (số thành phần trong vector). Những lệnh loglog, semilogx và semilogy cĩ chức năng tương tự như lệnh plot, ngoại trừ một hoặc hai trục đồ thị của chúng được xác định theo logarith. # Bài tập 4-1. Dự đốn kết quả của đoạn chương trình sau đây, sau đĩ hãy kiểm chứng kết quả bằng MATLAB: >> x = 0:10; >> y = 2.^x; % y = [1 2 4 8 16 32 64 128 256 512 1024] >> plot(x,y) % biểu diễn dưới dạng đồ thị >> semilogy(x,y) % vẽ đồ thị với trục y theo logarith Sau khi thực thi xong đoạn chương trình trên ta nhận thấy, cả hai đồ thị đều được thể hiện trong cùng một cửa sổ Figure No.1. Đồ thị thứ nhất sẽ bị xĩa bỏ ngay khi đồ thị thứ hai xuất hiện. Để vẽ hai đồ thị trên hai cửa sổ khác nhau, ta sử dụng lệnh figure để tạo ra một cửa sổ mới trước khi thực hiện lệnh vẽ đồ thị thứ hai. Bằng cách này chúng ta sẽ cĩ hai cửa sổ riêng biệt để thể hiện 2 đồ thị. Chúng ta cũng cĩ thể chuyển đến các cửa sổ khác nhau bằng lệnh figure(n), lệnh này sẽ đưa cửa sổ No.n lên trên màn hình. Thực thi lại đoạn chương trình trên và quan sát sự thay đổi. >> x = 0:10; >> y = 2.^x; >> plot(x,y) >> figure >> semilogy(x,y) Để vẽ một đồ thị hàm tương đối chính xác và đẹp, điều quan trọng là phải lấy mẫu một cách thích hợp: >> n = 5; >> x = 0:1/n:3; % lấy mẫu khơng tốt >> y = sin(5*x); >> plot(x,y)
- Đồ thị 2D và 3D 33 Lấy mẫu khơng tốt Lấy mẫu tốt >> n = 25; >> x = 0:1/n:3; % lấy mẫu tốt >> y = sin(5*x); >> plot(x,y) Lệnh plot mặc định sẽ vẽ đồ thị bằng những đường nét liền màu đen. Ta cĩ thể thay đổi kiểu cũng như màu sắc của nét vẽ, ví dụ: >> x = 0:0.4:3; y = sin(5*x); >> plot(x,y,'r ') Hình 4.1. đồ thị trên được vẽ bởi đường nét đứt màu đỏ. Thơng số thứ ba của lệnh plot chỉ định màu và kiểu đường của nét vẽ. Bảng 4.1 trình bày một số trường hợp cĩ thể, sử dụng lệnh help plot để cĩ những thơng tin chi tiết hơn. Bảng 4.1: Các ký hiệu màu và kiểu vẽ của đồ thị Ký hiệu Màu Ký hiệu Kiểu vẽ r Red . , o Đánh dấu các điểm bằng dấu ‘.’, ‘o’ g Green * Đánh dấu các điểm bằng dấu ‘*’ b Blue x , + Đánh dấu các điểm bằng dấu ‘x’. ‘+’ y Yellow - Vẽ bằng đường nét liền m Magenta Vẽ bằng đường nét đứt dài c Cyan : Vẽ bằng đường nét đứt ngắn k Black -. Vẽ bằng đường nét đứt chấm – gạch. Tiêu đề của đồ thị, đường kẻ và nhãn cho các trục được xác định bởi các lệnh sau: >> title('Function y = sin(5*x)');
- Đồ thị 2D và 3D 34 >> xlabel('x-axis'); >> ylabel('y-axis'); >> grid % loại bỏ các đường kẻ bằng lệnh grid off Hình 4.2. # Bài tập 4-2. Vẽ một đường bằng nét gạch ngắn màu đỏ nối các đểm sau lại với nhau: (2, 6), (2.5, 18), (5, 17.5), (4.2, 12.5) và (2, 12). # Bài tập 4-3. Vẽ đồ thị của hàm y = sin(x) + x - xcos(x) trong hai cửa sổ riêng biệt với hai khoảng 0 > x1 = 1:.1:3.1; y1 = sin(x1); >> plot(x1,y1,'md'); >> x2 = 1:.3:3.1; y2 = sin(-x2+pi/3); >> hold on >> plot(x2,y2,'k*-.') >> plot(x1,y1,'m-') >> hold off
- Đồ thị 2D và 3D 35 Hình 4.3. Cách thứ hai là vẽ nhiều hàm cùng một lúc. Với cách này , các hàm sẽ được vẽ cùng một lúc trên cùng một cửa sổ hình: >> x1 = 1:.1:3.1; y1 = cos(x1); >> x2 = 1:.3:3.1; y2 = cos(-x2+pi/3); >> plot(x1, y1,'md', x2, y2, 'k*-.', x1, y1, 'm-') Hình 4.4. Để xác định cụ thể độ dài của mỗi trục ta sử dụng lệnh axis. Để thấy sự thay đổi hãy thêm lệnh sau vào đoạn lệnh ở trên. >> axis([0,4,-2,2]) Hình 4.5.
- Đồ thị 2D và 3D 36 Lệnh axis tight cũng cho ra kết quả tương tự. Sử dụng lệnh help để tìm hiểu thêm về các lệnh axis on/off, axis equal, axis image và axis normal. Để tạo dịng ghi chú cho mỗi đồ thị ta sử dụng lệnh legend, thêm lệnh sau vào đoạn chương trình ở trên >> legend ('cos(x)', 'cos(-x+pi/3)'); Hình 4.6. Để tạo ra nhiều cửa sổ con trong cùng một cửa sổ hình ta sử dụng lệnh subplot. Với lệnh subplot, cửa sổ hình được chia thành pxr cửa sổ con được đánh số từ 1 đến p.r, bắt đầu từ cửa sổ trên cùng bên trái và đếm theo từng hàng. Các lệnh plot, title, grid chỉ làm việc với cửa sổ con hiện tại. >> x = 1:.1:4; >> y1 = sin(3*x); >> y2 = cos(5*x); >> y3 = sin(3*x).*cos(5*x); >> subplot(1,3,1); plot(x,y1,'m-'); title('sin(3*x)') >> subplot(1,3,2); plot(x,y2,'g-'); title('cos(5*x)') >> subplot(1,3,3); plot(x,y3,'k-'); title('sin(3*x) * cos(5*x)') Hình 4.7. # Bài tập 4-5.
- Đồ thị 2D và 3D 37 Vẽ đồ thị các hàm f(x) = x, g(x) = x3, h(x) = ex và z(x) = e^x2 với x∈[0, 4] trên cùng một cửa sổ hình và với hệ trục cĩ độ chia bình thường và hệ trục tọa độ cĩ độ chia log-log. Lấy mẫu thích hợp để làm phẳng đồ thị. Mơ tả mỗi đồ thị bằng các hàm: xlabel, ylabel, title, legend. # Bài tập 4-6. Vẽ đồ thị của các hàm f(x) = sin(1/x), f(x) = cos(1/x) trên cùng một cửa sổ hình, với x∈ [0.01, 0.1]. Lấy mẫu thích hợp để các đường cong rõ ràng nhất. 4.3. CÁC THUỘC TÍNH KHÁC CỦA ĐƯỜNG CONG 2D MATLAB cĩ một số hàm được thiết kế đặc biệt để sử dụng với những hình 2D, ví dụ như các hàm: fill, polar, bar, barh, pie, hist, errorbar hay stem. Trong ví dụ sau, lệnh fill được sử dụng để tạo ra một hình đa giác: >> N = 5; k = -N:N; >> x = sin(k*pi/N); >> y = cos(k*pi/N); % (x, y) là các đỉnh của đa giác >> fill(x,y,'g') >> axis square >> text(-0.7,0,'I am a green polygon') Hình 4.8. # Bài tập 4-7. Thực thi các lệnh sau và mơ tả kết quả (lưu ý rằng lệnh figure sẽ tạo ra một cửa sổ hình mới): >> figure % vẽ đồ thị cột của một đường cong hình chuơng. >> x = -2.9:0.2:2.9; >> bar(x,exp(-x.*x)); >> figure % vẽ sĩng hình sin ở dạng bậc thang >> x = 0:0.25:10; >> stairs(x,sin(x)); >> figure % vẽ errorbar >> x = -2:0.1:2; >> y = erf(x); % dùng lệnh help để hiểu thêm
- Đồ thị 2D và 3D 38 >> e = rand(size(x)) / 10; >> errorbar (x,y,e); >> figure >> r = rand(5,3); >> subplot(1,2,1); bar(r,'grouped') >> subplot(1,2,2); bar(r,'stacked') >> figure >> x = randn(200,1); % số ngẫu nhiên của phân bố bình thường >> hist(x,15) % biểu đồ với 15 cột 4.4. IN ẤN Trước khi tiến hành in để miêu tả một cách rõ ràng hơn chúng ta cĩ thể thêm một số thơng tin vào đồ thị, chẳng hạn như tựa đề, hay thay đổi cách trình bày. Bảng 4.2 trình bày một số lệnh được sử dụng để trình bày hình vẽ hay đồ thị. Bảng 4.2: Một số lệnh thao tác với đồ thị Lệnh Kết quả grid on/off Cộng lưới vào đồ thị axis([xmin xmax ymin ymax]) Xác định giá trị lớn nhất và nhỏ nhất của các trục box off/on Xĩa/hiển thị đường viền khung của đồ thị. xlabel('text') Nhãn của trục x ylabel('text') Nhãn của trục y title('text') Tựa đề ở trên đồ thị. text(x,y,'text') Cộng dịng ký tự vào điểm (x,y) gtext('text') Cộng dịng ký tự vào vị trí xác định bởi chuột. legend('fun1','fun2') Cộng vào tên của các hàm. legend off Xĩa tên của các hàm. clf Xĩa cửa sổ hình hiện tại. subplot Tạo ra những cửa sổ hình con. # Bài tập 4-8. Vẽ đồ thị các hàm y1 = sin(4x), y2 = xcos(x), y3 = (x + 1)-1x1/2 với x = 1:0.25:10, và một điểm (x; y) = (4; 5) trên cùng một cửa sổ hình. Sử dụng các màu và kiểu khác nhau cho các đồ thị. Cộng thêm vào lời chú thích, nhãn cho cả hai trục và một tựa đề. Cộng một đoạn text ‘single point’ đến vị trí (4; 5). Thay đổi giá trị lớn nhất và nhỏ nhất của các trục sao cho cĩ thể quan sát hàm y3 một cách chi tiết nhất. Cách đơn giản nhất để tiến hành in là chọn File trên thanh cơng cụ và sau đĩ chọn Print. Lệnh print được sử dụng để gửi một đồ thị đến máy in hoặc lưu vào một file. Do cĩ nhiều thơng số khơng được giải thích chi tiết ở đây, sử dụng lệnh help để hiểu rõ hơn. Cố gắng hiểu các ví dụ sau đây.
- Đồ thị 2D và 3D 39 >> print -dwinc % sử dụng máy in hiện hành để in màu hình đang hiển thị >> print -f1 -deps myfile.eps % lưu hình Figure no.1 đến file myfile.eps ở dạng đen trắng. >> print -f1 -depsc myfilec.eps % lưu hình Figure no.1 đến file myfilec.eps ở dạng màu. >> print -dtiff myfile1.tiff % lưu hình hiện hành đến file myfile1.tiff >> print -dpsc myfile1c.ps % lưu hình hiện hành đến file myfile1.ps ở dạng màu >> print -f2 -djpeg myfile2 % lưu hình Figure no.2 đến file myfile2.jpg # Bài tập 4-9. Trong những bài tập ở trước, thực hành lưu các hình đồ thị đến một file được chỉ định. 4.5. ĐỒ THỊ 3D Lệnh plot3 được sử dụng để vẽ đồ thị 3D, lệnh này tương đương với lệnh plot trong 2D. Về hình thức nĩ giống như lệnh plot tuy nhiên lệnh plot3 được mở rộng thêm cho một trục tọa độ thứ 3. Ví dụ vẽ đường cong r được định nghĩa r(t) = [t sin(t); t cos(t); t] với t nằm trong khoảng [-10π; 10π]. >> t = linspace(-10*pi,10*pi,200); >> plot3(t.*sin(t), t.*cos(t), t, 'md-'); % vẽ đường cong với màu hồng >> title('Curve r(t) = [t sin(t), t cos(t), t]'); >> xlabel('x-axis'); ylabel('y-axis'); zlabel('z-axis'); >> grid Hình 4.9.
- Đồ thị 2D và 3D 40 # Bài tập 4-10. Vẽ một đồ thị 3D được định nghĩa [x(t); y(t); z(t)] = [sin(t); cos(t); sin2(t)] với t = [0, 2π]. Vẽ đường ở trên bằng màu xanh và các điểm đánh dấu là các vịng trịn. Cộng thêm tựa đề của đồ thị, mơ tả các trục và vẽ các đường kẻ. Chúng ta cĩ thể xoay hình 3D vừa vẽ bằng cách chọn mục Tools trên thanh cơng cụ của cửa sổ hình và chọn mục Rotate 3D hay bằng cách nhập vào lệnh rotate3D. Sau đĩ nhấn chuột vào hình, giữ và bắt đầu xoay theo hướng mình mong muốn. Trước khi xoay Sau khi xoay Hình 4.10. 4.6. BỀ MẶT ĐỒ THỊ Một bề mặt được định nghĩa bởi một hàm f(x, y), với mỗi cặp giá trị của (x,y), độ cao z được tính z = f(x, y). Để vẽ một bề mặt, vùng lấy mẫu (x, y) nên là một vùng hình chữ nhật. Hệ thống các giá trị x và y được tạo ra bởi lệnh meshgrid như sau: >> [X, Y] = meshgrid (-1:.5:1, 0:.5:2) X = -1.0000 -0.5000 0 0.5000 1.0000 -1.0000 -0.5000 0 0.5000 1.0000 -1.0000 -0.5000 0 0.5000 1.0000 -1.0000 -0.5000 0 0.5000 1.0000 -1.0000 -0.5000 0 0.5000 1.0000 Y = 0 0 0 0 0 0.5000 0.5000 0.5000 0.5000 0.5000 1.0000 1.0000 1.0000 1.0000 1.0000 1.5000 1.5000 1.5000 1.5000 1.5000 2.0000 2.0000 2.0000 2.0000 2.0000
- Đồ thị 2D và 3D 41 Vùng lấy mẫu trong trường hợp này là [-1, 1]x[0, 2] và khoảng lấy mẫu là 0.5. Để bề mặt đồ thị phẳng hơn ta nên lấy mẫu dày đặc hơn. >> [X,Y] = meshgrid(-1:.05:1, 0:.05:2); >> Z = sin(5*X) .* cos(2*Y); >> mesh(X,Y,Z); >> title ('Function z = sin(5x) * cos(2y)') Sử dụng lệnh mesh Sử dụng lệnh waterfall Hình 4.11 Thử thay lệnh mesh bằng lệnh waterfall và nhận xét sự khác nhau giữa hai lệnh. # Bài tập 4-11. xy 2 Vẽ đồ thị mặt của hàm f(x,y) = tại vùng gần điểm (0, 0). Lưu ý nên sử dụng mật độ x 2 + y 4 lấy mẫu dày đặc. Hình 4.12.
- Đồ thị 2D và 3D 42 # Bài tập 4-12. Vẽ một quả cầu với các thơng số được định nghĩa [x(t, s), y(t, s), z(t, s)] = [cos(t)cos(s), cos(t)sin(s), sin(t)], với t,s = [0, 2π] (sử dụng lệnh surf). Sử dụng lệnh shading interp để xĩa các đường màu đen, sau đĩ sử dụng lệnh shading faceted để phục hồi lại hình nguyên thủy. Sử dụng lệnh mesh Sử dụng lệnh surf Hình 4.13 # Bài tập 4-13. Vẽ hàm theo r và θ: [x(r, θ); y(r, θ); z(r, θ)] = [rcos(θ); rsin(θ); sin(6cos(r)-nθ)]. Chọn n là một hằng số. Quan sát sự thay đổi của hình theo n. Trong MATLAB, hàm peaks là một hàm hai biến, cĩ được từ phép biến đổi phân bố Gauss. Cơng dụng của hàm peaks là tạo ra các biến giá trị để sử dụng trong các hàm 3D như: mesh, surf, pcolor, contour, . Ví dụ: >> [X,Y,Z] = peaks; % tạo các giá trị để vẽ, % X, Y, Z là các ma trận 49x49 >> surf(X,Y,Z); % vẽ bề mặt
- Đồ thị 2D và 3D 43 Hình 4.14 >> figure >> contour (X,Y,Z,30); % vẽ đường viền trong 2D >> colorbar % thêm vào trục z một thanh màu tương ứng với % giá trị của Z. >> title('2D-contour of PEAKS'); Hình 4.15 >> figure >> contour3(X,Y,Z,30); % vẽ đường viền trong 3D >> title('3D-contour of PEAKS');
- Đồ thị 2D và 3D 44 >> pcolor(X,Y,Z); % giá trị z được thể hiện với giá trị % màu tương ứng, xem thêm lệnh colorbar Hình 4.16 Lệnh close all được sử dụng để đĩng tất cả các cửa sổ hình, để đĩng từng cửa sổ ta cĩ thể sử dụng lệnh close (close 1 để đĩng cửa sổ hình Figure No.1). Đoạn chương trình sau đây dùng để xác định vị trí cĩ giá trị nhỏ nhất của đồ thị 3D. >> [mm,I] = min(Z); % mm là vector hàng chứa các giá trị nhỏ nhất. % I chứa các vị trí cĩ giá trị nhỏ nhất. >> [Zmin, j] = min (mm); % Zmin là giá trị nhỏ nhất và j là vị trí % tương ứng. Zmin mang giá trị của Z(I(j),j) >> xpos = X(I(j),j); % giá trị tương ứng của X. >> ypos = Y(I(j),j); % giá trị tương ứng của Y. >> contour (X,Y,Z,25); >> xlabel('x-axis'); ylabel('y-axis'); >> hold on >> plot(xpos,ypos,'*'); >> text(xpos+0.1,ypos,'Minimum'); >> hold off Thực hiện tương tự để xác định được vị trí cĩ giá trị lớn nhất:
- Đồ thị 2D và 3D 45 Hình 4.17 Chúng ta cũng cĩ thể kết hợp hai hay nhiều đồ thị vào trong cùng một hình. >> surf(peaks(25)+6); % dịch đồ thị theo trục z +6 đơn vị. >> hold on >> pcolor(peaks(25)); >> hold off Hình 4.18 # Bài tập 4-14. 2 2 Vẽ bề mặt của hàm f(x,y) = xye −x −y với vùng lấy mẫu [-2, 2]x[-2, 2]. Tìm vị trí, giá trị lớn nhất và nhỏ nhất của hàm.
- Đồ thị 2D và 3D 46 4.7. HÌNH ĐỘNG Trong MATLAB chúng ta cĩ thể tạo ra hình chuyển động bằng cách tạo ra một chuỗi các hình. Để hiểu cách tạo ra một hình động, phân tích đoạn chương trình sau đây với đồ thị của hàm f(x) = sin(nx) trong đĩ x = [0, 2π] và n = 1, , 5. N = 5; M = moviein(N); x = linspace (0,2*pi); for n=1:N plot (x,cos(n*x),'r-'); xlabel('x-axis') if n > 1, ss = strcat('cos(',num2str(n),'x)'); else ss = 'cos(x)'; end ylabel(ss) title('Cosine functions cos(nx)','FontSize',12) axis tight % giới hạn các trục theo giá trị. grid M(:,n) = getframe; pause(1.8) end movie(M) % chạy đoạn film. Các lệnh được tơ đậm ở trên là các thành phần chính để tạo nên một đoạn hình chuyển động trong MATLAB. Trong đoạn chương trình ở trên, cấu trúc vịng lặp for được sử dụng để tạo ra các khung ảnh cho đoạn film. Chúng ta sẽ đề cập đến cấu trúc vịng lặp một cách chi tiết hơn ở phần sau. Lệnh strcat dùng để nối các chuỗi lại với nhau, sử dụng lệnh help strcat để hiểu rõ hơn. Khi chạy đoạn film, đầu tiên 5 frame được hiển thị và sau đĩ 5 frame xuất hiện lại với tốc độ nhanh hơn. Lệnh moviein(M) báo với MATLAB rằng cĩ một đoạn film gồm cĩ M frame sẽ được tạo ra. Các frame liên tiếp nhau sẽ được tạo ra bên trong vịng lặp. Với lệnh getframe, các frame sẽ được lưu vào các cột của ma trận M. Lệnh movie(M) sẽ chạy đoạn film vừa tạo. Lưu ý rằng việc tạo ra đoạn film yêu cầu khá nhiều bộ nhớ, do vậy khi kết thúc cơng việc nên clear M ra khỏi workspace. # Bài tập 4-15. Viết chương trình tạo một đoạn film gồm cĩ 5 frame là bề mặt của hàm f(x; y) = sin(nx)sin(ny) với x,y = [0; 2π] và n = 1 : 5. Thêm vào đoạn film tựa đề, miêu tả của các trục.
- Đồ thị 2D và 3D 47 Danh sách các lệnh và hàm được giới thiệu trong chương 4 Các hàm vẽ đồ thị 2D bar Vẽ biểu đồ cột barh Vẽ biểu đồ cột nằm ngang errorbar Vẽ đồ thị lỗi fill Tơ màu một đa giác 2D hist Vẽ biểu đồ histogram loglog Vẽ đồ thị trên hệ trục logarithm pie Vẽ biểu đồ phần trăm plot Vẽ đồ thị trên hệ trục tuyến tính polar Vẽ đồ thị trên hệ toạ độ cực semilogx Vẽ đồ thị trên hệ trục cĩ trục hồnh chia theo thang logarithm semilogy Vẽ đồ thị trên hệ trục cĩ trục tung chia theo thang logarithm stem Vẽ đồ thị xung Các hàm phục vụ cho đồ thị 2D axis Điều chỉnh các giới hạn của các trục toạ độ box off/on Xĩa/hiển thị đường viền khung của đồ thị. clf Xố cửa sổ hình hiện tại close Đĩng một hay nhiều figure đang mở figure Tạo một figure mới để vẽ đồ thị grid Hiển thị hoặc khơng hiển thị lưới ơ vuơng gtext Thêm dịng ký tự tại điểm xác định bởi con trỏ chuột hold on Cho phép vẽ đồ thị khác lên cùng hệ trục toạ độ hiện hành hold off Xố các đồ thị cũ trước khi vẽ đồ thị mới legend Hiển thị các chú thích trên đồ thị legend off Xố các chú thích trên đồ thị subplot Chia figure thành nhiều phần, mỗi phần vẽ một đồ thị text Thêm dịng ký tự tại một điểm xác định trên đồ thị title Hiển thị tiêu đề của đồ thị xlabel Hiển thị tên của trục X ylabel Hiển thị tên của trục Y Các hàm vẽ đồ thị 3D contour Vẽ đồ thị đường đồng mức mesh Vẽ đồ thị 3D với bề mặt dạng lưới
- Đồ thị 2D và 3D 48 meshgrid Tạo lưới các điểm (miền xác định) để vẽ đồ thị pcolor Vẽ bảng màu từ một ma trận các toạ độ peaks Một hàm hai biến dùng để minh hoạ cho các đồ thị 3D plot3 Vẽ đồ thị 3D rotate3D on/off Cho phép / khơng cho phép xoay đồ thị 3D bằng chuột shading Chọn chế độ phủ màu surf Vẽ đồ thị 3D bắng cách tơ màu waterfall Vẽ đồ thị 3D dạng waterfall Các hàm liên quan đến hình động getframe Lưu các frame hình động vào một ma trận moviein Khởi động bộ nhớ chứa các frame (khung) hình động movie Hiển thị đoạn ảnh động Các lệnh và hàm khác for end Thực hiện vịng lặp cĩ số lần lặp hữu hạn strcat Nối hai hay nhiều chuỗi với nhau
- Biểu thức rẽ nhánh 49 Chương 5 5. BIỂU THỨC RẼ NHÁNH Cấu trúc của biểu thức rẽ nhánh bao gồm một nhĩm lệnh cho phép thực thi một đoạn chương trình cĩ điều kiện hay thực hiện một vịng lặp. 5.1. CÁC TOÁN TỬ LOGIC VÀ BIỂU THỨC QUAN HỆ Để thực thi biểu thức rẽ nhánh, chương trình cần thực hiện những phép tốn mà kết quả của nĩ là ĐÚNG hay SAI (TRUE hay FALSE). Trong MATLAB, kết quả trả về của một tốn tử logic là 1 nếu nĩ đúng và kết quả là 0 nếu nĩ sai. Bảng 5.1 trình bày những tốn tử logic và những biểu thức quan hệ trong MATLAB. Sử dụng lệnh help relop để hiểu rõ hơn về tốn tử logic và các biểu thức quan hệ. Những tốn tử quan hệ , >=, == và ~= cĩ thể được sử dụng để so sánh hai ma trận cĩ cùng kích thước (lưu ý rằng một số thực được xem như là một ma trận 1x1). Hơn nữa, các hàm xor, any, và all cũng được sử dụng như là các tốn tử logic (sử dụng lệnh help để hiểu rõ hơn) Bảng 5.1: Tốn tử logic và biểu thức quan hệ. Lệnh Kết quả a = (b > c) a là 1 nếu b lớn hơn c. Tương tự với =, > b = 10; >> 1 | b > 0 & 0 % ‘|’ là logic OR, ‘&’ là logic AND. ans = 0 >> (1 | b > 0) & 0 % biểu thức này tương đương với biểu thức ở trên. ans = 0 >> 1 | (b > 0 & 0) ans = 1 Lưu ý rằng để tránh các trường hợp nhầm lẫn ta nên sử dụng dấu ngoặc để phân biệt các biểu thức logic cĩ cấp độ ưu tiên khác nhau.
- Biểu thức rẽ nhánh 50 # Bài tập 5-1. • Dự đốn trước kết quả và sau đĩ kiểm tra lại bằng MATLAB các biểu thức quan hệ trong bảng 5.1 với b = 0 và c = -1. • Dự đốn trước kết quả và sau đĩ kiểm tra lại bằng MATLAB các tốn tử logic (and, or) với b = [2, 31, -40, 0] và c = 0. • Định nghĩa hai vector ngẫu nhiên (randn(1,7)) và thực thi tất cả các tốn tử logic bao gồm cả xor, any, và all. # Bài tập 5-2. 1. Cho x = [1, 5, 2, 8, 9, 0, 1] và y = [5, 2, 2, 6, 0, 0, 2]. Thực thi và giải thích kết quả của các lệnh sau: • x > y • x = x • (x > y) | (y y) & (y 3) & (x = 8)) • x(x > 5) • y ((x = 8)) • y(x > hold on >> x = -3:0.05:3; >> y = sin(3*x); >> subplot(1, 2, 1); >> plot(x, y); >> axis tight >> z = (y > subplot(1, 2, 2); >> plot(x, y, 'r:'); >> plot(x, z, 'r');
- Biểu thức rẽ nhánh 51 >> axis tight >> hold off Trước khi tiếp tục, chắc chắn rằng bạn đã hiểu được ý nghĩa và hoạt động các biểu thức sau: >> a = randperm(10); % hốn vị ngẫu nhiên. >> b = 1:10; >> b - (a 7) >> (a >= 2) & (a > ~(b > 4) % bằng 1 nếu b > (a == b) | b == 3 % bằng 1 nếu a = b hoặc b = 3 >> any(a > 5) % bằng 1 nếu bất kỳ thành phần nào % của a lớn hơn 5. >> any(b 8) % bằng 1 nếu tồn tại a và b sao cho % (b 8) >> all(b > 2) % bằng 1 nếu tất cả các giá trị % của b lớn hơn 2. Các thành phần của vector hay ma trận cĩ thể được trích ra khi chúng thỏa mãn một điều kiện nào đĩ. Sử dụng lệnh find cũng cho ta một kết quả tương tự. Kết quả trả về của lệnh find là vị trí của các thành phần thỏa mãn điều kiện. Ví dụ: >> x = [1 1 3 4 1]; >> i = (x == 1) i = 1 1 0 0 1 >> y = x(i) y = 1 1 1 >> j = find(x == 1) % j là các vị trí của x thỏa mãn x(j) = 1. j = 1 2 5 >> z = x(j) z = 1 1 1 Một ví dụ khác là: >> x = -1:0.05:1; >> y = sin(x) .* sin(3*pi*x); >> plot (x, y, '-'); >> hold on >> k = find (y <= -0.1) k =
- Biểu thức rẽ nhánh 52 9 10 11 12 13 29 30 31 32 33 >> plot (x(k), y(k), 'ro'); >> r = find (x > 0.5 & y > 0) r = 35 36 37 38 39 40 41 >> plot (x(r), y(r), 'r*'); Với ma trận, lệnh find cũng được thực thi theo cách tương tự. >> A = [1 3 -3 -5; -1 2 -1 0; 3 -7 2 7]; >> k = find (A >= 2.5) k = 3 4 12 >> A(k) ans = 3 3 7 Theo cách này, đầu tiên lệnh find sắp xếp ma trận A lại thành một vector cột theo cách cột sau được nối tiếp vào cột trước nĩ. Do vậy, k là vị trí các thành phần của vector vừa tạo ra cĩ giá trị lớn hơn hoặc bằng 2,5 và A(k) là giá trị của các thành phần này. Các giá trị cột và dịng của các thành phần này cũng cĩ thể được xác định: >> [I, J] = find (A >= 2.5) I = 3 1 3 J = 1 2 4 >> [A(I(1),J(1)),A(I(2),J(2)),A(I(3),J(3))] ans = 3 3 7 # Bài tập 5-5. Cho A = ceil(5 * randn(6, 6)) • Tìm các thành phần của A nhỏ hơn –3. • Tìm các thành phần của A lớn hơn –1 và nhỏ hơn 5.
- Biểu thức rẽ nhánh 53 • Loại bỏ các cột cĩ chứa thành phần 0. 5.2. BIỂU THỨC ĐIỀU KIỆN Cấu trúc điều kiện if được sử dụng để quyết định nhĩm lệnh nào sẽ được thực thi. Dưới dây là mơ tả tổng quát của các lệnh điều kiện. Trong những ví dụ này, lệnh disp được sử dụng thường xuyên. Lệnh này in ra màn hình đoạn văn bản ở giữa hai dấu nháy. • Cấu trúc if end Cú pháp Ví dụ if biểu thức logic if (a > 0) lệnh thứ 1 b = a; lệnh thứ 1 disp ('a is positive'); end end • Cấu trúc if else end Cú pháp Ví dụ if biểu thức logic if (temperature > 100) các lệnh được thực thi khi biểu disp ('Above boiling.'); thức logic TRUE toohigh = 1; else else các lệnh được thực thi khi biểu disp ('Temperature is OK.'); thức logic FALSE toohigh = 0; end end • Cấu trúc if elseif else end Cú pháp Ví dụ if biểu thức logic 1 if (height > 190) các lệnh được thực thi khi biểu disp ('very tall'); thức logic 1 TRUE elseif (height > 170) elseif biểu thức logic 2 disp ('tall'); các lệnh được thực thi khi biểu elseif (height < 150) thức logic 2 TRUE disp ('small'); else else các lệnh được thực thi khi khơng cĩ biểu thức logic nào disp ('average'); TRUE end end
- Biểu thức rẽ nhánh 54 Lưu ý: Chúng ta cĩ thể sử dụng một m-file để thực thi các ví dụ ở trên. m-file là một tập tin chứa một chuỗi các lệnh trong MATLAB. Để tạo ra một m-file, đầu tiên chúng ta mở một chương trình soạn thảo sau đĩ nhập vào tất cả các lệnh cần thiết (khơng cĩ dấu nhắc’>>’ ở đầu mỗi lệnh). Cuối cùng lưu file này với phần mở rộng “.m”, ví dụ mytask.m. Để thực thi m- file vừa tạo, từ cửa sổ lệnh của MATLAB chúng ta gõ vào lệnh mytask. Một cách khác để tạo ra m-file là sử dụng chương trình soạn thảo cĩ sẵn của MATLAB, chọn File trên thanh cơng cụ, sau đĩ chọn New và cuối cùng chọn m-file. Một cửa sổ mới sẽ xuất hiện, trong cửa sổ này chúng ta cĩ thể nhập vào đoạn chương trình cần thiết và lưu chúng vào trong ổ cứng (chương trình sẽ tự động lưu file này với phần mở rộng .m). Tất cả các lệnh trong tập tin này sẽ được thực thi một cách tuần tự trong MATLAB. Để m-file cĩ thể được thực thi thì chúng phải được lưu vào những thư mục mà MATLAB cĩ thể “thấy” được, đây chính là các thư mục nằm trong danh sách đường dẫn của MATLAB. Chúng ta sẽ đề cập một tiết hơn về m-file trong những phần sau. Ví dụ 5-1. Tạo một m-file short.m chứa hai dịng lệnh sau đây và thực thi chúng bằng lệnh short. x = 0:0.5:4; plot(x, sin(x), '*-'); # Bài tập 5-6. Hãy xác định các giá trị trả về của mỗi đoạn chương trình dưới đây, (lưu ý rằng khơng phải tất cả các lệnh đều đúng). 1. if n > 1 a) n = 7 m = ? m = n + 2 b) n = 0 m = ? else c) n = -7 m = ? m = n - 2 end 2. if s = 24 a) t = 50 h = ? z = 3t + 1 b) t = 19 h = ? elseif t < 9 c) t = -6 h = ? z = t^2/3 - 2t d) t = 0 h = ? else
- Biểu thức rẽ nhánh 55 z = -t end 4. if 0 5e5 Sử dụng đoạn chương trình trên để tính C với N = -3e3, 0.01, 56, 1e3, 3e6 (lưu ý rằng 3e3 được thể hiện trong MATLAB là 3*10^3). # Bài tập 5-8. Viết một đoạn chương trình nhập vào một số nguyên và kiểm tra nĩ cĩ chia hết cho 2 hay 3 khơng. Thực hiện với tất cả các trường hợp cĩ thể: chia hết cho cả 2 và 3, chia hết cho 2 nhưng khơng chia hết cho 3, (sử dụng lệnh rem). Cấu trúc switch cũng thường được sử dụng trong biểu thức điều kiện, switch chuyển đổi giữa các trường hợp phụ thuộc vào giá trị của một biểu thức, biểu thức này cĩ thể là số hay là chuỗi. Cú pháp Ví dụ switch biểu thức method = 2; case choice1 switch method khối lệnh thứ 1 case {1,2} case choice2 disp('Method is linear.'); khối lệnh thứ 2 case 3 disp('Method is cubic.'); case 4 otherwise disp('Method is nearest.'); khối lệnh otherwise end disp('Unknown method.'); end
- Biểu thức rẽ nhánh 56 Những phát biểu trong lệnh case đầu tiên cĩ biểu thức đúng sẽ được chọn để thực thi. Biểu thức cĩ thể là một số hay là một chuỗi ký tự. Trong trường hợp là số, nhĩm lệnh được chọn nếu biểu thức = choice. Cịn trong trường hợp là chuỗi biểu thức được chọn khi strcmp(biểu thức, choice) trả về giá trị 1 (đúng) (lệnh strcmp được sử dụng để so sánh hai chuỗi với nhau). Lưu ý rằng cấu trúc switch chỉ cho phép thực thi duy nhất một nhĩm lệnh. # Bài tập 5-9. Giả sử rằng biến tháng cĩ giá trị từ 1 đến 12. Sử dụng cấu trúc switch, viết một đoạn chương trình nhập vào giá trị của biến tháng, kết quả trả về là số ngày trong tháng đĩ và tên tháng (‘November’, ‘October’, ‘December’, ). 5.3. VÒNG LẶP Cấu trúc vịng lặp sẽ lặp lại một khối các phát biểu cho đến khi một số điều kiện khơng cịn thỏa mãn. Cĩ hai kiểu cấu trúc lặp phổ biến là for và while. • Vịng lặp for sẽ thực hiện một nhĩm các phát biểu trong một số lần xác định. Cú pháp Ví dụ for index = first : step : last sumx = 0; nhĩm các phát biểu for i = 1:length(x) end sumx = sumx + x(i); end Trong cấu trúc vịng lặp for, step cĩ thể là số âm, index cĩ thể là một vector. Xem các ví dụ sau: Ví dụ 1 Ví dụ 2 for i = 1 : 2 : n for i = n : -1 : 3 end end Ví dụ 3 Ví dụ 4 for i = 0 : 0.5 : 4 for i = [25 9 8] disp(x^2); disp(sqrt(x)); end end • Vịng lặp while thực hiện một nhĩm các phát biểu cho đến khi biểu thức điều kiện là FALSE. Cú pháp Ví dụ N = 100; while biểu thức điều kiện phát biểu 1; iter = 1; phát biểu 2; msum = 0; phát biểu 3; while iter <= N msum = msum + iter; iter = iter + 1; end end;
- Biểu thức rẽ nhánh 57 Sau đây là một ví dụ đơn giản, sử dụng cấu trúc vịng lặp để vẽ đồ thị hàm f(x) = cos(nx) với n = 1, , 9 trong các cửa sổ con (subplots) khác nhau. figure hold on x = linspace(0, 2*pi); for n=1:9 subplot(3, 3, n); y = cos(n*x); plot(x, y); axis tight end Cho hai vector x và y, ví dụ sau đây sử dụng cấu trúc vịng lặp để tạo ra một ma trận cĩ các thành phần được định nghĩa như sau: Aij = xiyj. n = length(x); m = length(y); for i=1:n for j=1:m A(i,j) = x(i) * y(j); end end Sử dụng cấu trúc vịng lặp while để làm lại ví dụ trên với x = [1 2 -1 5 -7 2 4] và y = [3 1 -5 7]. n = length(x); m = length(y); i = 1; j = 1; % gán giá trị ban đầu cho i và j while i <= n while j <= m A(i,j) = x(i) * y(j); j = j+1; % tăng j lên 1 end i = i+1; % tăng i lên 1 end # Bài tập 5-10. Sử dụng cấu trúc vịng lặp để tính tổng của bình phương 50 số đầu tiên. # Bài tập 5-11. Viết đoạn chương trình tìm số lớn nhất của n sao cho: 12 + 22 + + n 2 < 1000 # Bài tập 5-12.
- Biểu thức rẽ nhánh 58 Sử dụng cấu trúc vịng lặp để viết các đoạn chương trình sau đây: 1. Cho vector x = [1 8 3 9 0 1], cộng tất cả các thành phần của vector (kiểm tra lại với lệnh sum) 2. Cho x = [4 1 6 -1 -2 2] và y = [6 2 -7 1 5 -1], xác định ma trận cĩ các thành phần như sau: yi • aij = x j • bi = xi yi xi • cij = ()2 + xi + y j 1 • d ij = max()xi , y j 3. Cho một ma trận A bất kỳ, viết đoạn chương trình xác định ma trận B là ma trận nghịch đảo của ma trận A (kiểm tra lại với tốn tử A’). 4. Tạo một ma trận ngẫu nhiên A bằng lệnh rand, xĩa bỏ tất cả các thành phần nhỏ hơn 0.5 của A. # Bài tập 5-13. Viết đoạn chương trình yêu cầu nhập vào giá trị nhiệt độ oC (biến tc) và tính tốn giá trị nhiệt 9 độ oF tương đương (biến tf), tf = *tc + 32 . Đoạn chương trình sẽ chạy cho đến khi khơng 5 cĩ số nào được nhập để biến đổi. Sử dụng lệnh input để nhập vào các giá trị và lệnh isempty để kiểm tra cĩ giá trị nào được nhập hay khơng (sử dụng lệnh help input và lệnh help isempty để hiểu rõ thêm). # Bài tập 5-14. Sử dụng cấu trúc while viết đoạn chương trình tìm giá trị dương nhỏ nhất của x (lấy 4 số lẻ) sao cho 0.91 < sin(x) + cos(x) < 0.92 . # Bài tập 5-15. Sử dụng cấu trúc vịng lặp for viết một đoạn chương trình nhập vào hai số a và b, sau đĩ cho biết sự tương quan giữa chúng (lớn hơn, nhỏ hơn, bằng).
- Biểu thức rẽ nhánh 59 Danh sách các lệnh và hàm được giới thiệu trong chương 5 Các lệnh rẽ nhánh for end Vịng lặp cĩ số lần lặp hữu hạn if end if else end Rẽ nhánh theo điều kiện if elseif else end switch case end Rẽ nhánh theo điều kiện while end Lặp theo điều kiện Các hàm khác all Trả về giá trị true nếu tất cả các phần tử của một vector đều khác 0 any Trả về giá trị true nếu ít nhất một phần tử của vector khác 0 disp Hiển thị một chuỗi lên màn hình find Tìm vị trí của các phần tử khác 0 trong một vector input Yêu cầu người sử dụng nhập một chuỗi và trả về chuỗi được nhập isempty Kiểm tra một ma trận cĩ rỗng hay khơng rand Ma trận ngẫu nhiên với các thành phần phân bố đều trên (0,1) rem Tính phần dư của phép chia hai số xor Xor hai phần tử logic
- Tập lệnh và hàm 60 Chương 6 6. TẬP LỆNH VÀ HÀM 6.1. TẬP LỆNH M-FILE Để giải quyết những vấn đề đơn giản, số lệnh sử dụng trong chương trình ít, các lệnh của MATLAB cĩ thể được nhập trực tiếp vào cửa sổ lệnh. Tuy nhiên trong trường hợp phức tạp, số lệnh cần được sử dụng là khá nhiều và do vậy việc nhập trực tiếp vào cửa sổ lệnh là khơng khả thi. Giải pháp trong trường hợp này là sử dụng tập lệnh m-file. Ngồi ưu điểm trong trường hợp chương trình cần sử dụng nhiều lệnh, tập lệnh m-flie cịn hữu ích khi chúng ta muốn thay đổi một vài giá trị của biến hay cho chương trình thực thi nhiều lần. Trong trường hợp này, m-file là một tập tin chứa một chuỗi các lệnh hay phát biểu trong MATLAB. Tuy nhiên do chúng khơng cĩ các đối số vào và ra nên tập tin m-file khơng phải là hàm, nĩ đơn giản chỉ là tập hợp của nhiều lệnh được thực thi một cách trình tự. # Bài tập 6-1. Mở chương trình soạn thảo của MATLAB (chọn File trên thanh cơng cụ, chọn New và sau đĩ chọn m-file) nhập vào cửa sổ chương trình các dịng lệnh sau đây và lưu tập tin với tên sinplot.m x = 0:0.2:6; y = sin(x); plot(x,y); title('Plot of y = sin(x)'); Thực thi tập tin vừa tạo bằng cách: trong cửa sổ lệnh của chương trình MATLAB, nhập vào lệnh sinplot. Quan sát các kết quả thu được. >> sinplot # Bài tập 6-2. Đoạn chương trình trong bài tập 51 được sử dụng để vẽ hình sin. Tương tự như bài tập 51 hãy tạo các tập lệnh để vẽ những đồ thị hàm sau đây: - Vẽ đồ thị hàm y = 2cos(x) với x trong khoảng [-10, 10]. - Vẽ hàm y = x 2 và x = y 2 trong cùng một cửa sổ hình. Cộng thêm vào tựa đề và các mơ tả của đồ thị. # Bài tập 6-3. Tạo một tập lệnh cubic_roots yêu cầu nhập vào ba biến a, b, c và kết quả trả về là nghiệm của phương trình bậc ba: ax 2 + bx + c = 0 . # Bài tập 6-4. Hãy viết một tập lệnh yêu cầu nhập vào hai số a và b. Xác định đỉnh cịn lại của tam giác đều cĩ hai đỉnh là [a, a] và [a, b]. Vẽ tam giác đều vừa mới được xác định, tơ hình tam giác đĩ với lệnh fill (sử dụng lệnh help fill để tìm hiểu cách sử dụng của lệnh này).
- Tập lệnh và hàm 61 6.2. HÀM M-FILE Hàm m-file là một chương trình con do chúng yêu cầu các đối số ngõ vào và cĩ thể trả về đối số ngõ ra. Các biến được định nghĩa và sử dụng trong hàm thì chỉ cĩ giá trị bên trong hàm đĩ. Cú pháp tổng quát của một hàm như sau: function [outputArgs] = function_name(inputArgs) outputArgs (đối số ngõ ra) được đặt trong dấu []: - tên các đối số ngõ ra được liệt kê và cách nhau bởi dấu ‘,’ - cĩ thể khơng sử dụng dấu [] nếu chỉ cĩ duy nhất một đối số. - một hàm cũng cĩ thể khơng cĩ đối số ngõ ra1. outputArgs (đối số ngõ vào) được đặt trong dấu (): - tên các đối số ngõ vào được liệt kê và cách nhau bởi dấu ‘,’ - một hàm cũng cĩ thể khơng cĩ đối số ngõ vào. Cấu trúc chung của một hàm trong MATLAB như sau: - Dịng đầu tiên là định nghĩa của hàm, dịng này bao gồm: từ khĩa khai báo hàm, tên hàm và các đối số ngõ vào và ngõ ra. - Tiếp theo là các dịng chú thích, các dịng này được bắt đầu bởi dấu ‘%’, nội dung của các dịng này là giải thích mục đích của hàm cũng như mơ tả ý nghĩa các đối số ngõ vào và ngõ ra. Các dịng chú thích này sẽ xuất hiện khi ta sử dụng lệnh help để tìm hiểu về hàm chúng ta đang tạo ra. - Cuối cùng là phần nội dung, đây chính là phần chính của hàm. Việc thực thi nội dung của hàm sẽ kết thức khi chương trình gặp lệnh return hoặc thực thi xong lệnh cuối cùng. Khi quá trình thực thi kết thúc các đối số ngõ ra sẽ được trả về. Ví dụ hàm average được định nghĩa như sau: Đối số ngõ ra Tên hàm Đối số ngõ vào function avr = average(x) Dịng đầu tiên là dịng định nghĩa hàm % AVERAGE tính giá trị trung bình của vector x % và gán kết quả vào biến avr. Chú thích % Lưu ý: đây là một ví dụ về cấu trúc hàm n = length(x); Dịng trắng trong chú thích; Mục Nội dung của hàm avr = sum(x)/n; lưu ý sẽ khơng xuất hiện khi ta sử return; dụng lệnh help average Lưu ý rằng tên của hàm và tên của file lưu phải giống nhau. Trong trường hợp trên, hàm nên được lưu với tên average.m. 1 Trong các ngơn ngữ lập trình khác, một hàm khơng cĩ đối số ngõ ra được gọi là thủ tục.
- Tập lệnh và hàm 62 # Bài tập 6-5. Tạo hàm average (cĩ phần chú thích) và lưu với tên average.m. Kiểm tra khả năng và cơng dụng của hàm bởi lệnh help average. Thực thi hàm average.m bằng lệnh avr1 = average(1:10). Giải thích các kết quả đạt được. Một ví dụ khác về hàm: function d = determinant(A) %DETERMINANT Tính định thức của ma trận A. [m,n] = size(A); if (m ~= n) disp ('Lỗi. Ma trận khơng phải là ma trận vuơng.'); return; else d = det(A); % det là hàm cơ bản của MATLAB. end return; Hàm error cĩ thể được sử dụng để kiểm tra các điều kiện của thơng số. Hàm này sẽ hiển thị một thơng báo lỗi, lờ đi tất cả các lệnh khác trong chương trình và quay về cửa cửa sổ lệnh của chương trình MATLAB. Ví dụ hãy tạo một tập lệnh chứa đoạn chương trình sau đây, đoạn chương trình này kiểm tra điều kiện của thơng số a. a = input(‘Hãy nhập vào giá trị của a:’); if (a >= 1) error ('a phải nhỏ hơn 1'); end # Bài tập 6-6. Viết hàm [elems, mns] = nonzero(A), với đối số ngõ vào là ma trận A và giá trị trả về là vector elems chứa tất cả các thành phần nonzero của A, đối số mns chứa giá trị trung bình từng cột của A. # Bài tập 6-7. Viết hàm [A,B] = sides(a,b,c), với đối số ngõ vào là 3 số dương. Nếu 3 số đĩ cĩ thể là ba cạnh của một tam giác chương trình sẽ trả về giá trị diện tích và chu vi của nĩ. Trong trường hợp cịn lại thì thơng báo lỗi cho các trường hợp. # Bài tập 6-8. Viết hàm [A] = matrix(n, m, min, max), các đối số ngõ vào là các số nguyên. Nếu n và m là các số dương, chương trình sẽ trả về một ma trận nxm cĩ các thành phần là các số ngẫu nhiên trong khoảng [min, max]. Thơng báo lỗi cho các trường hợp cịn lại. # Bài tập 6-9. Viết hàm [x1, x2] = bac_hai(a, b, c). Trong trường hợp a, b, c khác zero, chương trình trả về nghiệm của phương trình ax2 + bx + c = 0. Thơng báo lỗi cho các trường hợp cịn lại. Một hàm m-file cĩ thể chứa nhiều hơn một hàm. Trong trường hợp một m-file chứa nhiều hàm thì hàm xuất hiện đầu tiên được gọi là hàm chính, hàm chính vẫn cĩ các tính chất thơng thường của một hàm: cách hoạt động, các đối số, tên hàm , . Những hàm cịn lại được gọi là
- Tập lệnh và hàm 63 hàm con, chúng chỉ cĩ thể được truy xuất từ hàm chính và khơng thể được truy xuất từ bất kỳ hàm nào khác, kể cả từ cửa sổ lệnh. Cấu trúc của một hàm con cũng gồm ba phần: khai báo hàm, chú thích và thân hàm. Các hàm con cần được sử dụng trong trường hợp một hàm quá dài hay quá phức tạp. Ví dụ hàm average bây giờ là một hàm con của hàm stat.m. function [a,sd] = stat(x) % STAT Simple statistics. % Computes the average value and the standard deviation of a vector x. n = length(x); a = average(x,n); sd = sqrt(sum((x - avr).^2)/n); return; function a = average (x,n) % AVERAGE subfunction a = sum(x)/n; return; Trong đoạn chương trình trên, lệnh a = average(x, n) được sử dụng trong nội dung của hàm stat để gọi một hàm con. Trong trường hợp này stat là hàm chính và average là hàm con. 6.2.1. NHỮNG BIẾN ĐẶC BIỆT TRONG HÀM Khi một hàm được sử dụng, chương trình sẽ tự động tạo ra hai biến nội là nargin, nargout. Biến nargin là số đối số ngõ vào được sử dụng khi gọi hàm, nargout là số đối số ngõ ra. Phân tích hàm sau đây: function [out1,out2] = checkarg (in1,in2,in3) %CHECKARG Một ví dụ sử dụng biến nargin và nargout. if (nargin == 0) disp('no input arguments'); return; elseif (nargin == 1) s = in1; p = in1; disp('1 input argument'); elseif (nargin == 2) s = in1+in2; p = in1*in2; disp('2 input arguments'); elseif (nargin == 3) s = in1+in2+in3; p = in1*in2*in3; disp('3 input arguments');
- Tập lệnh và hàm 64 else error('Too many inputs.'); end if (nargout == 0) return; elseif (nargout == 1) out1 = s; else out1 = s; out2 = p; end Trong ví dụ ở trên, chương trình sẽ cho ra các kết quả khác nhau tùy thuộc vào cĩ bao nhiêu đối số ngõ vào được sử dụng và cĩ bao nhiêu đối số ngõ ra. Trong các chương trình lớn, một cách tổng quát người ta thường hay sử dụng biến nargin và nargout để điều khiển linh hoạt nội dung của chương trình. # Bài tập 6-10. Xây dựng hàm checkarg với nội dung như trên, hãy gọi hàm checkarg với các đối số ngõ vào và ngõ ra khác nhau. Một số trường hợp gợi ý: >> checkarg >> s = checkarg(-6) >> s = checkarg(23,7) >> [s,p] = checkarg(3,4,5) 6.2.2. BIẾN TOÀN CỤC VÀ BIẾN CỤC BỘ Mỗi hàm m-file truy cập đến một phần riêng biệt của bộ nhớ trong khơng gian làm việc của MATLAB. Điều này cĩ nghĩa là mỗi hàm m-file cĩ những biến cục bộ của riêng nĩ, những hàm khác khơng thể truy cập đến các biến này. Để hiểu rõ hơn chúng ta hãy phân tích sơ đồ sau đây: MATLAB myfun.m >> a = -1; function z = myfun(x, y) >> b = 20; (a, b) → (x, y) >> c = myfun(a, b); z = x + cos(x-y) c ← z return; Hình 6.1 Các biến a, b, c xuất hiện trong khơng gian làm việc của MATLAB, trong khi các biến x, y, z chỉ cĩ giá trị bên trong hàm myfun. Tuy nhiên, nếu ta khai báo biến ở dạng tồn cục thì tất cả các hàm khác đều cĩ thể sử dụng được biến này (tham khảo thêm bằng lệnh help global). Lưu ý rằng chúng ta nên cẩn thận khi sử dụng biến tồn cục, nĩ dễ gây nên những xáo trộn và nhầm lẫn.
- Tập lệnh và hàm 65 6.2.3. CÁCH GỌI HÀM GIÁN TIẾP Để chương trình trở nên tổng quát hơn ta nên sử dụng cách gọi hàm gián tiếp, trong trường hợp này tên hàm được coi như là một đối số ngõ vào. Ta sử dụng lệnh feval (function evaluation) để gọi hàm gián tiếp. Cách sử dụng thơng thường của lệnh feval như sau: [y1, , yn] = feval (F, x1, , xn), với F là tên của hàm được định nghĩa trong MATLAB, x1, xn là các đối số ngõ vào, y1, , yn là các đối số ngõ ra. Ví dụ: >> x = pi; y = cos(x); >> z = feval('cos', x); Lệnh sau thì tương đương với cả hai lệnh đầu tiên. Một cách sử dụng khác của hàm feval. >> F = 'cos'; >> z = feval(F, x) Cách gọi hàm gián tiếp là một cơng cụ cần thiết để xây dựng chương trình xem hàm như là một đối số. # Bài tập 6-11. Hãy miêu tả hoạt động của hàm funplot sau: function funplot (F, xstart, xend, col); %FUNPLOT makes a plot of the function F at the interval % [xstart, xend]. The plot should be made in one % of the standard Matlab colors, so 'col' is one % of the following value: % 'b','k','m','g','w','y' or 'r'. % default values: % [xstart,xend] = [0,10] % col = 'b' % Note: illustrates the use of feval command if (nargin == 0) error ('No function is provided.'); end if (nargin < 2) xstart = 0; xend = 10; end if (nargin == 2) error ('Wrong number of arguments. You should provide xstart and xend.'); end if (nargin < 4)
- Tập lệnh và hàm 66 col = 'b'; end if (xstart == xend), error ('The [xstart, xend] should be a non-zero range.'); elseif (xstart > xend), exchange = xend; xend = xstart; xstart = exchange; end switch col case {}'b','k','m','g','w',' y','r' ; % do nothing; the right color choice otherwise error ('Wrong col value provided.') end x = linspace(xstart, xend); y = feval(F, x); plot (x, y, col); description = ['Plot of ', F]; title (description); return; Lưu ý cách ghi chú thích, biến nargin và cấu trúc switch. Hãy sử dụng hàm funplot vừa tạo để vẽ các đồ thị hàm khác nhau, ví dụ: sin, cos, exp, . 6.3. TẬP TIN VÀ HÀM Điểm khác nhau cơ bản nhất giữa tập tin và hàm là tất cả các tham số và biến số trong tập tin đều cĩ thể được sử dụng từ bên ngồi (các tham số và biến này nằm trong workspace), trong khi các biến của hàm chỉ cĩ giá trị bên trong hàm đĩ và khơng được truy xuất hoặc sử dụng bởi các hàm khác. Do vậy trong trường hợp cần giải quyết một vấn đề với các thơng số bất kỳ ta nên sử dụng hàm, cịn trong trường hợp cần thử nghiệm nhiều lần một vấn đề ta nên sử dụng tập tin. # Bài tập 6-12. ⎛n⎞ Tạo ra một hàm binom, cĩ header function b = binom(n, k), để tính giá trị của nhị thức⎜ ⎟ . ⎝k ⎠ Lưu ý rằng trong trường hợp này ta nên tạo ra một hàm con factorial để tính giá tri của biểu thức n! = 1* 2* * n . Hàm factorial cĩ thể là một hàm độc lập hay cũng cĩ thể là một hàm
- Tập lệnh và hàm 67 con trong file binom.m. Sau khi tạo xong hàm binom, hãy viết một tập tin tính tốn các nhị ⎛n⎞ thức ⎜ ⎟ với n = 8 và k = 1, 2, , 8. ⎝k⎠ # Bài tập 6-13. Viết một hàm cĩ ba đối số là các số nguyên dương. - Nếu ba số đĩ cĩ thể là ba cạnh của một tam giác, kết quả trả về là diện tích của hình tam giác đĩ. Biết cơng thức tính diện tích của một tam giác: a + b + c A = s(s − a)(s − b)(s − c) với s = 2 - Ngược lại nếu ba số nhập vào khơng phải là ba cạnh của một tam giác thì thơng báo lỗi. # Bài tập 6-14. Viết một hàm kiểm tra hai đối số nguyên dương cĩ phải là hai số nguyên tố tương đối hay khơng? Hai số được gọi là nguyên tố tương đối khi chúng cĩ ước số chung lớn nhất là 1. # Bài tập 6-15. Một cơng ty điện lực tính giá tiền điện theo tỷ giá sau đây: - 1000đ/kwh cho 300 kwh đầu tiên. - 800đ/kwh cho 300 kwh tiếp theo. - 600đ/kwh cho 200 kwh tiếp theo. - 500đ/kwh cho tất cả các mức sử dụng điện trên 800 kwh. Hãy viết chương trình tính tiền điện theo số kwh. # Bài tập 6-16. Viết hàm cĩ một đối số là vector x (vector của các số nguyên dương), kết quả trả về là vector y chứa các ước số nhỏ nhất lớn hơn 1 của các thành phần trong vector x. # Bài tập 6-17. Viết hàm sắp xếp các thành phần trong vector x theo thứ tự tăng dần hoặc giảm dần. # Bài tập 6-18. Viết chương trình phân loại sinh viên theo điểm trung bình: - Yếu: 0 ≤ đtb < 5 - Trung bình: 5 ≤ đtb < 6.5 - Khá: 6.5 ≤ đtb < 8 - Giỏi: 8 ≤ đtb < 9 - Xuất sắc: 9 ≤ đtb ≤ 10
- Tập lệnh và hàm 68 Danh sách các lệnh và hàm được giới thiệu trong chương 6 error Hiển thị một thơng báo lỗi và dừng đoạn chương trình đang thực thi feval Thực thi một hàm được định nghĩa trước fill Tơ màu một đa giác phẳng (2D) global Định nghĩa biến tồn cục return Kết thúc gọi hàm và trả về giá trị của hàm
- Văn bản 69 Chương 7 7. VĂN BẢN 7.1. CHUỖI KÝ TỰ Trong MATLAB văn bản được lưu ở dạng là chuỗi của các ký tự. Chuỗi là một vector mà các thành phần của nĩ lưu trữ giá trị ASCII của các ký tự trong chuỗi. Do văn bản là một vector của các ký tự nên ta cũng cĩ thể xử lý văn bản giống như xử lý một vector bất kỳ. Ví dụ: >> t = 'This is a character string' t = This is a character string >> size(t) ans = 1 27 >> whos Name Size Bytes Class t 1x27 54 char array >> t(10 : 19) ans = character >> t([2, 3, 10, 17]) ans = hi t Để miêu tả chuỗi dưới dạng mã ASCII ta sử dụng lệnh double hoặc abs để biến đổi: >> double(t(1:12)) ans = 84 104 105 115 32 105 115 32 97 32 99 104 Hàm char được sử dụng để biến đổi từ dạng mã ASCII sang ký tự chuỗi: >> t([16:17]) ans = ct >> t([16:17])+3 % mã ASCII được sử dụng. ans = 102 119 >> t([16:17])-3 % thay đổi mã ASCII ans = 96 113 >> char(t([16:17])-2) % biến đổi mã ASCII sang ký tự chuỗi.
- Văn bản 70 ans = ar # Bài tập 7-1. Thực thi các lệnh được miêu tả ở trên, sử dụng chuỗi t để tạo ra chuỗi u chỉ chứa các ký tự ‘character’. Biến đổi chuỗi u thành chuỗi u1 = ‘retcarahc’. Sau đây là một số ví dụ về các hàm được sử dụng để biến đổi chuỗi. Ví dụ hàm findstr được sử dụng để tìm một ký tự hay một nhĩm các ký tự xuất hiện trong chuỗi. >> findstr(t, 'c') % tìm vị trí của 'c' xuất hiện trong t ans = 11 16 >> findstr(t, 'racter') % tìm vị trí của chuỗi 'racter' trong t ans = 14 >> findstr(t,u) % tìm chuỗi u trong chuỗi t ans = 11 >> strcat(u,u1) % nối hai chuỗi u và u1 lại với nhau ans = characterretcarahc >> strcmp(u,u1) % so sánh hai chuỗi ans = % trả về 1 nếu hai chuỗi giống nhau % và ngược lại là 0 0 >> q = num2str(34.35) % biến đổi số thành chuỗi q = 34.35 >> z = str2num('7.6') % biến đổi chuỗi thành số. z = 7.6 >> whos q z % q là chuỗi (ma trận các ký tự), z là số. Name Size Bytes Class q 1x5 10 char array z 1x1 8 double array >> t = str2num('1 -7 2') % biến đổi chuỗi thành vector của các số. t = 1 -7 2 >> t = str2num('1 - 7 2') % lưu ý các khoảng trắng xung quanh
- Văn bản 71 % dấu '-' hoặc '+', trong trường hợp % này là: [1-7, 2] t = -6 2 Lưu ý rằng khi biến đổi từ chuỗi sang số hoặc từ số sang chuỗi, các khoảng trắng xung quanh dấu ‘-‘ hoặc ‘+’ mang ý nghĩa rất quan trọng. >> A = round(4*rand(3,3))+0.5; >> ss = num2str(A) % biến đổi ma trận A thành chuỗi các ký tự. ss = -3.5 -3.5 6.5 -2.5 -1.5 0.5 5.5 -1.5 -3.5 >> whos ss Name Size Bytes Class ss 3x28 168 char array >> ss(2,1), ss(3,15:28) % ss là một ma trận các ký tự. ans = - ans = .5 -3.5 >> ss(1:2,1:3) ans = -3. -2. # Bài tập 7-2. Thực thi các lệnh trong ví dụ ở trên. Định nghĩa một chuỗi mới s = 'Nothing wastes more energy than worrying' và thực hiện các ví dụ với lệnh findstr. 7.2. XUẤT VÀ NHẬP VĂN BẢN Lệnh input được sử dụng để yêu cầu nguời dùng nhập vào một số hay một chuỗi. >> myname = input('Enter your name: ','s'); >> age = input('Enter your age: '); Lưu ý ý nghĩa của hai lệnh trên, lệnh thứ nhất yêu cầu nhập vào một chuỗi và lệnh thứ hai yêu cầu nhập vào một số. Cĩ hai hàm được sử dụng để xuất văn bản là disp và fprintf. Hàm disp chỉ thể hiện giá trị của một đối số là một ma trận số hay ma trận chuỗi. Ví dụ: >> disp('This is a statement.') % xuất ra một chuỗi. This is a statement. >> disp(rand(3)) % xuất ra một ma trận.
- Văn bản 72 0.2221 0.0129 0.8519 0.4885 0.0538 0.5039 0.2290 0.3949 0.4239 Hàm fprintf (tương tự trong ngơn ngữ lập trình C) được sử dụng để ghi dữ liệu vào file hay xuất ra màn hình định dạng chính xác của đối số. Ví dụ: >> x = 2; >> fprintf('Square root of %g is %8.6f.\n', x, sqrt(x)); Square root of 2 is 1.414214. >> str = 'beginning'; >> fprintf('Every %s is difficult.\n',str); Every beginning is difficult. Hàm fprintf cĩ khả năng biến đổi, định dạng và ghi đối số của nĩ vào một file hay thể hiện chúng trên màn hình theo một định dạng đặc biệt. Cú pháp sau đây được sử dụng để xuất ra màn hình: fprintf (format, a, ) Chuỗi format chứa các ký tự thơng thường sẽ được đưa đến ngõ ra và các chỉ định biến đổi, mỗi chỉ định biến đổi sẽ chuyển đổi một đối số của hàm fprintf thành chuỗi ký tự cĩ định dạng tương ứng và sau đĩ in ra màn hình. a là các đối số của hàm fprintf. Mỗi chỉ định biến đổi bắt đầu bằng ký tự ‘%’ và kết thúc bởi một ký tự chuyển đổi. Giữa ‘%’ và ký tự chuyển đổi cĩ thể là: • dấu ‘-‘: khi cĩ ký tự này đối số sẽ được in ra với định dạng canh lề trái, trong trường hợp ngược lại, mặc định là canh lề phải. • số xác định chiều dài tối thiểu: là phạm vi tối thiểu mà đối số sẽ được in ra, trong trường hợp chiều dài của đối số lớn hơn chiều dài tối thiểu thì phạm vi in ra sẽ bằng với chiều dài của đối số. • số xác định số các chữ số thập phân • dấu ‘.’: là dấu dùng để phân biệt hai định dạng trên. Bảng 7.1: Một số ký tự chuyển đổi và ý nghĩa của chúng Ký tự Ý nghĩa. d biến đổi đối số sang kiểu số thập phân u biến đổi đối số sang kiểu số thập phân khơng dấu c biến đổi đối số thành một ký tự s biến đổi đối số thành một chuỗi e biến đổi số single hay double thành số thập phân cĩ dạng [±]m.nnnnnnE[±]xx. Xem thêm ví dụ bên dưới f biến đổi số single hay double thành số thập phân cĩ dạng [±]mmm.nnnnnn. Xem thêm ví dụ bên dưới g định dạng giống trường hợp e và f nhưng được viết ở dạng ngắn hơn. Các số zero khơng cĩ ý nghĩa sẽ khơng được in ra
- Văn bản 73 Các định dạng \n, \r, \t, \b lần lượt được sử dụng để để tạo ra một dịng mới, xuống dịng, tab và tab ngược (ngược với phím tab). Để in ra ra ký tự ‘\’ ta sử dụng ‘\\’, tương tự, để in ra ký tự ‘%’ ta sử dụng ‘%%’. Phân tích ví dụ sau đây: >> fprintf('look at %20.6e!\n', 1000*sqrt(2)) look at 1.414214e+3! >> fprintf('look at %-20.6f!', 1000*sqrt(2)) look at 1414.213562 ! Trong cả hai trường hợp, khoảng tối thiểu để in đối số là 20 và số chữ số thập phân là 6. Trong trường hợp đầu, giá trị 1000*sqrt(2) được định dạng canh lề phải và trong trường hợp thứ hai, bởi vì cĩ dấu ‘-‘ nên giá trị 1000*sqrt(2) được định dạng canh lề trái. Sự khác nhau của hai kết quả cịn do ý nghĩa của các ký tự biến đổi e và f. # Bài tập 7-3. Sử dụng lệnh input để nhập vào các giá trị của một vector. Sau đĩ sử dụng lệnh disp hay lệnh fprintf để xuất vector mới vừa tạo ra màn hình. # Bài tập 7-4. Xem xét các ví dụ sau đây về lệnh fprintf và sau đĩ tự làm các bài tập tương tự để hiểu rõ hơn về các chỉ định này: >> str = 'life is beautiful'; >> fprintf('My sentence is: %s\n',str); % lưu ý định dạng \n My sentence is: life is beautiful >> fprintf('My sentence is: %30s\n',str); My sentence is: life is beautiful >> fprintf('My sentence is: %30.10s\n',str); My sentence is: life is be >> fprintf('My sentence is: %-20.10s\n',str); My sentence is: life is be >> >> name = 'John'; >> age = 30; >> salary = 6130.50; >> fprintf('My name is %4s. I am %2d. My salary is f %7.2f.\n',name, age, salary); My name is John. I am 30. My salary is f 6130.50. >> >> x = [0, 0.5, 1]; >> y = [x; exp(x)]; >> fprintf('%6.2f %12.8f\n',y); 0.00 1.00000000 0.50 1.64872127 1.00 2.71828183
- Văn bản 74 >> >> fprintf('%6.1e %12.4e\n',y); 0.0e+00 1.0000e+00 5.0e-01 1.6487e+00 1.0e+00 2.7183e+00 >> >> x = 1:3:7; >> y = [x; sin(x)]; >> fprintf('%2d %10.4g\n',y); 1 0.8415 4 -0.7568 7 0.657 Lưu ý rằng lệnh fprintf sử dụng các chỉ định biến đổi để khai báo cĩ bao nhiêu đối số theo sau và kiểu của từng đối số. Nếu chúng ta khơng cung cấp đủ đối số hay cung cấp đối số khơng đúng kiểu thì chúng ta sẽ nhận được một kết quả khơng đúng. Do vậy, cần cẩn thận với việc khai báo đối số trong lệnh fprintf. Xem xét ví dụ sau: >> fprintf('My name is %4s. I am %2d. My salary is f %7.2f.\n',name,salary); My name is John. I am 6.130500e+03. My salary is f Chú ý rằng lệnh sprintf cũng tương tự như lệnh fprintf ngoại trừ lệnh sprintf được sử dụng để gán kết quả cho một chuỗi. Xem xét ví dụ sau đây: >> str = sprintf('My name is %4s. I am %2d. My salary is f %7.2f.\n',name,age,salary) str = My name is John. I am 30. My salary is f 6500.50. # Bài tập 7-5. Định nghĩa chuỗi s = 'How much wood could a wood-chuck chuck if a wood- chuck could chuck wood?', sử dụng lệnh findstr tìm các vị trí xuất hiện các chuỗi con ‘wood’, ‘o’, ‘uc’ hay ‘could’ trong chuỗi s. # Bài tập 7-6. • Viết một tập tin hay hàm để biến đổi số La Mã sang giá trị thập phân tương ứng. I V X L C D M 1 5 10 50 100 500 1000 Ví dụ: IV(4), IX(9), XL(40), XC(90), CD(400) và CM(900). • Viết một hàm làm cơng việc ngược lại, biến đổi số thập phân sang số La Mã. # Bài tập 7-7. Viết hàm mã hĩa và giải mã theo luật sau đây: tất cả các ký tự trong chuỗi sẽ cĩ giá trị ASCII của nĩ dịch đi n, với n là một đối số. Ví dụ trong trường hợp n = 1, chuỗi ‘abcde’ sẽ được mã hĩa thành ‘bcdef’ và ‘alphabet’ được mã hĩa thành ‘bmqibcfu’. Trong trường hợp này ‘z’ sẽ
- Văn bản 75 được mã hĩa thành ‘a’. Mã hĩa với n = 26 sẽ cho ta ta kết quả là chuỗi đã nhập vào. Viết hai hàm coder và decoder, mỗi hàm cĩ hai đối số, đối số thứ nhất là chuỗi cần mã hĩa/giải mã và đối số thứ hai là số cần dịch n. Trong trường hợp mã hĩa, chuỗi nhập vào nên là chuỗi đã được mã hĩa. # Bài tập 7-8. Viết một hàm xĩa bỏ tất cả các ký tự trắng trong chuỗi. # Bài tập 7-9. Viết một hàm nhập vào một danh từ và trả về dạng số nhiều của nĩ dựa trên những quy tắc sau: a) Nếu danh từ kết thúc bằng ‘y’, hãy loại bỏ ‘y’ rồi thêm vào ‘ies’ b) Nếu danh từ kết thúc bằng ‘s’, ‘ch’ hay ‘sh’ hãy thêm vào ‘es’ c) Trong các trường hợp khác thêm ‘s’. # Bài tập 7-10. Viết chương trình đảo ngược các từ trong chuỗi. Ví dụ ‘Nguyen Van An’ thành ‘An Van Nguyen’.
- Văn bản 76 Danh sách các hàm được giới thiệu trong chương 7 abs Chuyển kiểu ký tự thành mã ASCII char Chuyển mã ASCII thành ký tự disp Hiển thị một chuỗi ra cửa sổ lệnh của MATLAB double Chuyển kiểu ký tự thành mã ASCII findstr Tìm một chuỗi trong một chuỗi khác fprintf Biến đổi định dạng một chuỗi và ghi vào một file hoặc hiển thị ra màn hình input Yêu cầu người sử dụng nhập vào một chuỗi và trả vế chuỗi được nhập sprintf Giống fprintf nhưng kết quả được gán cho một chuỗi
- Giao diện người sử dụng 77 Chương 8 8. GIAO DIỆN NGƯỜI SỬ DỤNG (GUI) Giao diện người sử dụng (Graphical User Interface – GUI) là giao diện bằng hình ảnh của chương trình. Một GUI tốt cĩ thể làm cho chương trình trở nên dễ sử dụng bằng cách cung cấp những thơng tin ban đầu cần thiết và với những cơng cụ điều khiển như: nút nhấn (pushbutton), hộp liệt kê (list box), thanh trượt (slider), trình đơn (menu), . GUI nên được thiết kế một cách dễ hiểu và thân thiện để người sử dụng cĩ thể hiểu và dự đốn được kết quả của một tác động. 8.1. CÁCH LÀM VIỆC CỦA MỘT GUI GUI bao gồm các nút nhấn, hộp liệt kê, thanh trượt, menu, , chúng cung cấp cho người sử dụng một mơi trường làm việc thân thiện để họ tập trung vào các ứng dụng của chương trình hơn là đi tìm hiểu cách thức làm việc của chương trình. Tuy nhiên, tạo ra GUI là cơng việc khĩ khăn đối với người lập trình bởi vì chương trình phải được xử lý với các click chuột cho bất kỳ thành phần nào của GUI và vào bất kỳ thời điểm nào. Trong MATLAB, để tạo ra một GUI lưu ý ba yêu cầu chính sau đây: • Component (các thành phần): mỗi đối tượng trong GUI (nút nhấn, nhãn, hộp soạn thảo, ) là một thành phần. Các thành phần được phân loại thành: cơng cụ điều khiển (nút nhấn, hộp soạn thảo, thanh trượt, ), các thành phần tĩnh (khung hình, chuỗi ký tự, ), menu và axes (là các hệ trục dùng để hiển thị hình đồ họa). Các cơng cụ điều khiển và các thành phần tĩnh được tạo ra bởi hàm uicontrol, menu được tạo ra bởi các hàm uimenu và uicontextmenu, axes được tạo ra bởi hàm axes. • Figure: các thành phần của GUI phải được sắp xếp vào trong một figure, là một cửa sổ được hiển thị trên màn hình máy vi tính. Trong các chương trước, một figure được tự động tạo ra khi vẽ đồ thị. Lệnh figure tạo ra một figure được sử dụng để chứa các thành phần của GUI. • Callback: cuối cùng, khi người sử dụng tác động vào chương trình bằng cách nhấn chuột hay gõ bàn phím thì chương trình phải đáp ứng lại mỗi sự kiện này. Ví dụ, trong trường hợp người sử dụng tác động vào một nút nhấn thì MATLAB sẽ thực thi một hàm tương ứng với nút nhấn đĩ. Mỗi thành phần của GUI phải callback một hàm tương ứng của nĩ. Các thành phần cơ bản của GUI được tĩm tắt trong bảng 8.1 và được thể hiện trong hình 8.1. Chúng ta sẽ tìm hiểu những thành phần này thơng qua các ví dụ và sau đĩ sử dụng chúng để tạo ra các GUI.