You are on page 1of 346

TRƯỜNG ĐẠI HỌC BÁCH KHOA, ĐẠI HỌC ĐÀ NẴNG

NGUYỄN THẾ HÙNG, TRẦN VĂN CHÍNH

PHƯƠNG PHÁPTÍNH

ĐÀ NẴNG 2012
LỜI NÓI ĐẦU

Giáo trình Phương pháp tính được biên soạn trên cơ sở các bài giảng của các tác giả cho
các lớp Cao học và Đại học ngành Điện, Xây dựng, thuộc Đại học Đà Nẵng và một số Đại học
khác mà các Tác giả có dịp tham gia giảng dạy.
Nội dung của Giáo trình bao quát những vấn đề cơ bản nhất và mở rộng của phương pháp
tính hiện đại, làm cơ sở để tính toán, giải quyết những vấn đề khoa học, kỹ thuật thường gặp thuộc
các ngành kỹ thuật, đặc biệt là ngành Điện và Xây dựng.
Để giúp độc giả dể dàng nắm bắt bài giảng và vận dụng lý thuyết, thuận lợi trong việc tính
toán, ở mổi mục khó của cuốn sách thường có kèm theo ví dụ tính toán đặc trưng, chương trình tính
và cuối mổi chương thường có một số bài tập.
Ngoài các ngành Điện và Xây dựng cơ bản, Giáo trình này còn làm tài liệu tham khảo cho
các ngành khoa học kỹ thuật khác liên quan đến các vấn đề tính toán gần đúng.
Các Tác giả cảm ơn các Trợ giảng và Trợ lý đã bổ sung các bài tập, đánh máy bản thảo
làm cho nội dung Giáo trình được phong phú, đẹp đẽ thêm.
Các Tác giả rất mong được bạn đọc góp ý, bổ khuyết để lần tái bản tới Giáo trình Phương
pháp tính này được hoàn hảo hơn.

Đà Nẵng, ngày 12 tháng 12 năm 2012


Các tác giả

GS. Nguyễn Thế Hùng – PGS. Trần Văn Chính


Trường Đại học Bách khoa, Đại học Đà Nẵng
MỤC LỤC
Chương 1: Sai số .............................................................................. 1
1.1. Tổng quan về phương pháp tính ...........................................................1
1.1.1. Khái niệm về phương pháp tính .......................................................... 2
1.1.2. Các đặc điểm của phương pháp tính .................................................... 2
1.1.3. Những dạng sai số thường gặp ............................................................ 3
1.2. Sai số tuyệt đối .....................................................................................4
1.3. Sai số tương đối .............................................................................4
1.4. Cách viết số xấp xỉ ...............................................................................4
1.5. Sai số quy tròn ..........................................................................4
1.6. Sai số của số đã quy tròn ..............................................................4
1.7. Ảnh hưởng của sai số quy tròn .............................................................5
1.8. Các quy tắc tính sai số ...............................................................5
1.9. Sai số do chặt cụt .....................................................................6
1.10. Sự ổn định của quá trình tính ......................................................7
Chương 2: Nội suy ............................................................... 10
2.1. Nội suy đa thức ..............................................................10
2.1.1. Sự duy nhất của đa thức nội suy ................................. 10
2.1.2. Tính giá trị đa thức bằng phương pháp Horner ............................ 11
2.1.3. Các phép tính trên đa thức ......................................................... 15
2.1.4. Sai số của đa thức nội suy ................................................................. 21
2.2. Đa thức nội suy Lagrange .............................................................21
Ứng dụng lập trình ........................................................................... 23
2.3. Nội suy Newton ................................................................................28
2.3.1. Nội suy Newton với mốc cách đều ................................................. 28
2.3.2. Nội suy Newton với mốc không cách đều ....................................... 29
2.3.3 Ứng dụng lập trình ....................................................................... 30
2.4. Nội suy Hermite .................................................................................34
2.5. Nội suy Spline .............................................................................38
Ứng dụng lập trình .............................................................................. 40
2.6. Phương pháp bình phương cực tiểu ....................................................41
2.6.1. Hàm xấp xỉ có dạng đa thức ...................................................... 42
2.6.2. Hàm dạng Aecx ..................................................................................... 47
2.6.3. Hàm dạng Axq .................................................................................... 51
2.6.4. Hàm lượng giác .................................................................................... 54
2.6.5. Hàm hữu tỉ ......................................................................................... 58

Chương 3: Tính gần đúng đạo hàm và tích phân ............................. 69


3.1. Tính gần đúng đạo hàm ......................................................................69
3.1.1. Đạo hàm Romberg ...................................................................... 69
Ứng dụng lập trình ........................................................................... 72
3.2. Tính gần đúng tích phân xác định ........................................................75
3.2.1. Công thức hình thang ........................................................................ 75
Ứng dụng lập trình ........................................................................ 77
3.2.2. Công thức Simpson ............................................................................ 79
Ứng dụng lập trình ....................................................................... 80
3.2.3. Công thức của Gauss ........................................................................ 83
a. Liên hệ giữa các hệ tọa độ tổng thể
và hệ tọa độ địa phương ..................................................................... 83
b. Tích phân số ..................................................................................... 86

Chương 4: Giải gần đúng phương trình và


hệ phương trình phi tuyến ................................................................. 92
4.1. Giải gần đúng phương trình ................................................................92
4.1.1 Phương pháp lặp đơn ............................................................. 92
4.1.2. Phương pháp dây cung ................................................................... 96
Ứng dụng lập trình ....................................................................... 96
4.1.3. Phương pháp Newton-Raphson .................................................. 99
Ứng dụng lập trình ..................................................................... 101
4.1.4. Phương pháp Muller .......................................................... 104
4.1.5. Phương pháp lặp Bernoulli ......................................................... 109
4.1.6. Phương pháp lặp Berge-Viette ................................................... 113
4.1.7. Phương pháp ngoại suy Aitken .................................................... 117
4.1.8. Phương pháp Bairtow .............................................................. 121
4.2. Giải hệ phương trình phi tuyến ...................................................129
Ứng dụng lập trình ........................................................................... 130
a. Dùng C++ ..................................................................................... 130
b. Dùng Matlab ....................................................................................... 135

Chương 5: Các phương pháp số của đại số tuyến tính ................... 139
5.1. Ma trận .............................................................................................139
5.1.1. Các định nghĩa ................................................................................ 139
5.1.2. Định thức của ma trận .................................................................... 139
5.1.3. Nghịch đảo ma trận ......................................................................... 145
5.1.4. Tích hai ma trận .............................................................................. 151
5.1.5. Phép biến đổi tuyến tính trong không gian n chiều ......................... 155
5.1.6. Các phép tính ma trận ..................................................................... 157
a. Nghịch đảo ma trận ........................................................................ 158
b. Nhân hai ma trận ........................................................................ 164
5.1.7. Véc tơ riêng, trị riêng và
các dạng toàn phương của ma trận ................................................................... 168
Phương pháp Mises .......................................................................... 174
5.2. Giải hệ đại tuyến ..............................................................................187
5.2.1. Phương pháp giải trực tiếp .............................................................. 188
a. Phương pháp khử Gauss ............................................................... 188
b. Phương pháp Gaus – Jordan .......................................................... 193
c. Phân tích LU và phân tích Cholesky ............................................. 200
5.2.2. Phương pháp lặp giải hệ phương trình ........................................... 218
a. Phương pháp lặp đơn hệ phương trình ........................................... 218
b. Phương pháp lặp Seidel ................................................................. 225
c. Phương pháp lặp với hệ số giảm dư SOR ...................................... 232
d. Phương pháp Gradient liên hợp ..................................................... 234
5.2.3. Hệ phương trình số phức .................................................................. 236
Chương 6: Nghiệm gần đúng của hệ phương trình vi phân thường ....... 243
6.1. Mở đầu ...........................................................................................243
6.2. Nghiệm gần đúng của bài toán Cauchy đối với phương
trình vi phân thường ................................................................................243
6.2.1. Phương pháp xấp xỉ liên tiếp Pica .................................................. 244
Ứng dụng lập trình ...................................................................... 245
6.2.2. Phương pháp Euler .......................................................................... 246
Ứng dụng lập trình ................................................................ 247
6.2.3. Phương pháp Runghe-Kutta bậc 4 .................................................. 251
Ứng dụng lập trình ...................................................................... 253
6.2.4. Phương pháp Adam ....................................................................... 256

Chương 7: Giải gần đúng phương trình đạo hàm riêng


bằng phương pháp số ................................................................ 261
7.1. Phân loại phương trình đạo hàm riêng bậc 2 ......................................261
7.1.1. Phân loại phương trình đạo hàm riêng bậc 2 tuyến tính .................. 262
a. Phương trình Hyperbol ................................................................... 263
b. Phương trình Ellip .......................................................................... 263
c. Phương trình Parabol ....................................................................... 264
7.1.2. Những lưu ý về phương trình đạo hàm riêng ................................ 264
7.2. Các bài toán biên thường gặp ...........................................................264
7.2.1. Bài toán Dirichlet ........................................................................... 265
7.2.2. Bài toán Neumann ........................................................................... 265
7.2.3. Bài toán hỗn hợp ............................................................................ 265
7.3. Tư tưởng cơ bản của các phương pháp gần đúng ................................266
7.4. Phương pháp đặc trưng .....................................................................267
7.5. Phương pháp sai phân ......................................................................267
7.5.1. Sơ đồ hiện – Sơ đồ ẩn .....................................................................269
7.5.2. Sự ổn định của sơ đồ ....................................................................... 270
7.5.3. Tính nhất quán của lược đồ sai phân .............................................. 270
7.5.4. Sự ổn định của lược đồ ................................................................... 271
7.5.5. Các ứng dụng trong cơ học ............................................................. 272
7.6. Phương pháp phần tử hữu hạn ...........................................................275
7.6.1 Phương pháp biến phân Reyleigh-Ritz ............................................. 276
7.6.2 Phương pháp biến phân Galerkin ...................................................... 276
7.6.3 Phương pháp phần tử hữu hạn .......................................................... 277
7.7. Phương pháp thể tích hữu hạn ..........................................................277
7.8. Phương pháp phần tử biên ................................................................278
Dạng biến phân trọng số dư ..................................................................... 278
Chương 8: Phương pháp phần tử hữu hạn .................................. 284
8.1. Các loại phần tử ...............................................................................284
8.2. Hàm nội suy ....................................................................................285
8.2.1. Hàm nội suy cho bài toán một chiều ...............................................289
8.2.2. Hàm nội suy cho bài toán hai chiều ................................................ 290
8.2.3. Hàm nội suy cho bài toán ba chiều ................................................. 293
8.3. Tích phân số ....................................................................................295
8.4. Các bước tính toán cơ bản và kỹ thuật lập trình cho máy tính
số theo phương pháp phần tử hữu hạn .......................................................295
8.5. Phương pháp PTHH trong Cơ học vật rắn ........................................310
Bài toán biên ........................................................................................... 311
a. Phương trình tích phân ................................................................... 311
b. Các phương trình cơ bản ................................................................ 312
8.6. Phương pháp phần tử hữu hạn trong Cơ học chất lỏng .................324

Phụ lục .......................................................................................... 328


A. Phép tính véc-tơ .........................................................................................328
B. Phép tính ten–xơ.........................................................................................331
C. Các phương pháp biến đổi..........................................................................332
1. Phép biến đổi tọa độ....................................................................................... 332
2. Phép biến hình bảo giác................................................................................. 333
3. Phép biến đổi Laplace.................................................................................... 334
4. Phép biến đổi Sigma ................................................................................... 334
D. Một vài ứng dụng của giải tích hàm ..........................................................335
1. Không gian mêtrix.......................................................................................... 335
2. Không gian tuyến tính định chuẩn ............................................................... 335
3. Không gian EUCLIC- Không gian HILBERT ........................................... 335
4. Toán Tử Tuyến Tính - Phiếm Hàm Tuyến Tính ........................................ 336
Chương 1 SAI SỐ
Error analysis

1.1 . Tổng quan về phương pháp tính


1.1.1. Khái niệm về phương pháp tính
Phương pháp số (numerical method) là một lĩnh vực của toán học chuyên
nghiên cứu những lý luận cơ bản và các phương pháp giải gần đúng các bài toán
thường gặp trong toán học và kỹ thuật, kết quả tính toán được cho dưới dạng số. Đôi
khi nó còn được gọi là Phương pháp tính (Computational method), Toán học tính toán
(Computational mathematics).
Giải tích số (Numerical analysis) nhấn mạnh cả phương pháp xấp xỉ và phân
tích toán học.
Phương pháp số quan tâm nhiều hơn đến sự lựa chọn và ứng dụng các kỷ thuật
để giải quyết vấn đề khoa học kỹ thuật hơn là phân tích toán học như Gải tích số.
Chúng ta thấy rằng hầu hết các bài toán trong toán học như giải các phương
trình đại số hay siêu việt, các hệ phương trình tuyến tính hay phi tuyến, các phương
trình vi phân thường hay đạo hàm riêng, tính các tích phân,... thường khó giải đúng
được, nghĩa là khó tìm kết quả dưới dạng giải tích.
Một số bài toán có thể giải đúng được nhưng biểu thức kết quả lại cồng kềnh,
phức tạp khối lượng tính toán rất lớn. Vì những lí do trên, việc giải gần đúng các bài
toán là vô cùng cần thiết.
Các bài toán trong kĩ thuật thường dựa trên số liệu thực đo và các giả thiết gần
đúng; do vậy việc tìm ra kết quả gần đúng với sai số cho phép là hoàn toàn có ý nghĩa
thực tế.
Từ lâu các nhà khoa học đã nghiên cứu phương pháp tính và đã đạt nhiều kết
quả quan trọng; tuy nhiên để lời giải đạt được độ chính xác cao, khối lượng tính toán
thường rất lớn. Khi các phương tiện tính toán thô sơ, nhiều phương pháp tính đã được
đề xuất, nhưng không thể thực hiện được vì khối lượng tính toán quá lớn; khó khăn
trên đã làm phương pháp tính không phát triển được.
Ngày nay nhờ máy tính điện tử người ta đã giải rất nhanh các bài toán khổng lồ,
phức tạp, đã kiểm nghiệm được các phương pháp tính cũ và đề ra các phương pháp

1
tính mới. Phương pháp tính nhờ đó phát triển rất mạnh mẽ; nó là cầu nối giữa toán học
và thực tiễn; là môn học không thể thiếu đối với các kỹ sư.
Ngoài nhiệm vụ chính của phương pháp tính là tìm các phương pháp giải gần
đúng các bài toán không tìm được lời giải giải tích hoặc lời giải giải tích quá phức tạp,
nó còn có nhiệm vụ khác như nghiên cứu tính chất nghiệm, nghiên cứu bài toán cực
trị, xấp xỉ hàm v.v...
1.1.2. Các đặc điểm của phương pháp tính
Đặc điểm về phương pháp của môn học này là hữu hạn hoá và rời rạc hoá.
Phương pháp tính thường biến cái vô hạn thành cái hữu hạn, cái liên tục thành
cái rời rạc và sau cùng lại trở về với cái vô hạn, cái liên tục. Nhưng cần chú ý rằng quá
trình trở lại cái vô hạn, cái liên tục phải trả giá đắt vì khối lượng tính toán tăng lên rất
nhiều. Cho nên trong thực tế người ta phải dừng lại khi nghiệm gần đúng sát với
nghiệm đúng ở một mức độ nào đó.
Đặc điểm thứ hai của môn học là sự tiến đến kết quả bằng quá trình liên tiếp.
Đó là quá trình chia ngày càng nhỏ hơn, càng dày đặc hơn hoặc quá trình tính toán
bước sau dựa vào các kết quả của các bước trước. Công việc tính toán lặp đi lặp lại
này rất thích hợp với máy điện toán.
Khi nghiên cứu phương pháp tính người ta thường triệt để lợi dụng các kết quả
đã đạt được trong toán học. Cùng một bài toán có thể có nhiều phương pháp tính khác
nhau.
Trong phương pháp tính, người ta thường quan tâm đến hai vấn đề chính:
 Phương pháp để giải bài toán.
 Sai số của lời giải.
Một phương pháp tính được coi là tốt nếu nó đạt các yêu cầu sau:
- Phương pháp tính được biểu diễn bằng một dãy hữu hạn các bước tính cụ
thể. Các bước tính toán cụ thể này của phương pháp tính được gọi là thuật toán. Thuật
toán càng đơn giản càng tốt.
- Đánh giá được sai số và sai số càng nhỏ càng tốt.
- Thuật toán thực hiện được trên máy điện toán và thời gian chạy máy ít
nhất.
Giải gần đúng nghĩa là lời giải của bài toán so với lời giải đúng có một sai số
nào đó. Sai số thường do rất nhiều nguồn tạo nên và nhiều khi rất khó ước lượng được.

2
Ví dụ khi cần tìm lời giải của phương trình phi tuyến, ta sẽ có nhiều phương pháp giải
khác nhau; mổi phương pháp giải cần thời gian tính toán và độ chính xác khác nhau.
Một người kỹ sư xây dựng khi tính toán để thiết kế một công trình, thực hiện rất nhiều
phép tính, và nhiều khi rất khó xác định sai số tích lũy trong quá trình tính toán;
nhưng kết quả vẫn được cơ quan có thẩm quyền duyệt chấp nhận. Tuy nhiên đối với
các bài toán phức tạp, số lượng phép tính lớn, cần độ chính xác cao, nhất thiết phải
được khảo sát nghiên cứu đầy đủ về sai số của lời giải.
Máy tính số có thể biểu diễn với độ chính xác bình thường (single), độ chính
xác gấp đôi (double) hay độ chính xác mở rộng (extended). Nếu ta biết được mối liên
hệ giữa lời giải số với lời giải đúng, sẽ biết nên chọn độ chính xác nào để kết quả đáp
ứng được yêu cầu thực tế.
1.1.3. Những dạng sai số thường gặp
Trong thực tế, khi bài toán tìm xấp xỉ một mô hình toán học đã biết, ví dụ tìm
nghiệm của một phương trình đã biết, tính tích phân xác định của một hàm số nào đó
trên miền cho trước hoặc có những bài toán thực tế mà ngay cả mô hình toán học cũng
chưa biết; ví dụ, dự báo về lượng mưa thay đổi do biến đổi khí hậu toàn cầu, nhu cầu
thuê bao internet, … Trong những trường hợp này, ta phải bắt đầu từ việc thu thập số
liệu, xây dựng mô hình toán rồi tìm phương pháp giải số thích hợp … Nói chung khi
thực hiện một bài toán bằng phương pháp số ta thường gặp những loại sai số sau đây:
Sai số do mô hình hoá bài toán, do ta không thể tính được hết những yếu tố
quan trọng ảnh hưởng đến bài toán, hoặc do ta biết được những yếu tố ảnh hưởng
nhưng phải đơn giản hóa mô hình để có thể tính toán được.
Sai số do phương pháp: Phương pháp thay bài toán phức tạp bằng bài toán đơn
giản (mổi phương pháp gần đúng đều có sai số và thường các sai số này là khác nhau)
sẽ tạo ra sai số phương pháp.
Sai số do số liệu: Khi đo đạc ta phải sử dụng dụng cụ đo, mổi dụng đo đều có
sai số.
Sai số tính toán và chặt cụt: Sai số tính toán là sai số do ta làm tròn bởi tất cả
các lần qui tròn trong quá trình tính toán; sai số chặt cụt là sai số gây ra khi phải chặt
cụt dãy số khai triển.
Những sai số trên đây, tùy theo bài toán, tích lũy lại nhiều khi dẫn đến những
lời giải không thể chấp nhận được. Chính vì vậy việc tìm ra những phương pháp tốt,

3
thuật toán hữu hiệu để giải các bài toán thực tế là điều rất cần thiết. Các phương pháp
số hiện nay có rất nhiều, và còn nhiều vấn đề hiện nay vẫn còn bỏ ngỏ. Trong cuốn
sách này chúng tôi chỉ giới thiệu một số phương pháp và thuật toán thông dụng để các
kỹ sư và độc giả quan tâm có thể sử dụng được.
1.2 . Sai số tuyệt đối
Gọi a là giá trị gần đúng của A, ta viết được A = a  a
a : gọi là sai số tuyệt đối giới hạn
1.3 . Sai số tương đối
a
a = , dạng khác: A = a (1  a)
a

Sai số tuyệt đối không nói lên đầy đủ “chất lượng“ của 1 số xấp xỉ, chất lượng
ấy được phản ảnh qua sai số tương đối.
1.4. Cách viết số xấp xỉ
Chữ số có nghĩa: Đó là chữ số  0 đầu tiên tính từ trái sang phải
Ví dụ. 002,74  2,74
00,0207  0,0207
Chữ số đáng tin: Một số a có thể được viết a =   10s
s

65,807 = 6.101 + 5.100 + 8.10-1 + 0.10-2 + 7.10-3


Vậy 1 = 6 , 0 = 5 , -1 = 8 , -2 = 0 , -3 = 7
Nếu a  0,5.10S thì S là chữ số đáng tin.
Nếu a  0,5.10S thì S là chữ số đáng nghi.
Ví dụ. a = 65,8274 ; a = 0,0043  Chữ số 6, 5, 8, 2 đáng tin
a = 0,0067  Chữ số 6, 5,8 đáng tin
1.5. Sai số quy tròn
Quy tắc quy tròn
Chữ số bỏ đi đầu tiên  5: Thêm vào chữ số giữ lại cuối cùng 1 đơn vị
Chữ số bỏ đi đầu tiên  5: Để nguyên chữ số giữ lại cuối cùng
Ví dụ. 65,8274  65,827; 65,827  65,83
1.6. Sai số của số đã quy tròn
Giả sử quy tròn a thành a’ với sai số quy tròn tuyệt đối a’

a 'a  a’ thì a’ = a + a’ (tức tăng sai số tuyệt đối)

4
1.7. Ảnh hưởng của sai số quy tròn
Áp dụng nhị thức Newton, ta có:  
2  1 10 3363 2378 2

Bây giờ thay 2 bởi các số quy tròn khác nhau:

2 Vế trái Vế phải
1,4 0,0001048576 33,8
1,41 0,00013422659 10,02
1,414 0,000147912 0,508
1,41421 0,00014866394 0,00862
1,414213563 0,00014867678 0,0001472

1.8. Các quy tắc tính sai số


Xét hàm số: u = f(x, y)
Ta ký hiệu x , y, u : chỉ các số gia của x, y, u
dx , dy , du : chỉ các vi phân của x , y, u
X , Y, U : sai số tuyệt đối của x, y, u
x   X
Ta luôn có:
y  y

Ta phải tìm U để có: u   U

Sai số của tổng: u = x + y

Ta có u = x + y  u  x  y

 u   X   Y   X Y 

+ Nếu u = x – y với x, y cùng dấu:


U X  Y
U =  nếu x  y là rất bé thì sai số rất lớn.
u xy

+ Nếu u = x.y  u  du = ydx + xdy = yx + xy


u  y  X  x  Y   U  y  X  x  Y

5
U X Y
Do đó : U =    X + Y
u x y

x
+ Nếu u = , với y  0, U = X + Y
y

Công thức tổng quát: u = f(x1, x2, x3, ..., xn)


n
f
Thì: U = 
i 1
X
x i i

Ví dụ. Tìm sai số tuyệt đối giới hạn và sai số tương đối giới hạn của thể tích
hình cầu.

1
V=  .d 3 .
6

Nếu đường kính d = 3,7cm  0,05 và  = 3,14. Biết d = 0,05,  = 0,0016.

Giải: Xem  và d là đối số của hàm V


Ta có:  v     3 d
0,0016
Với:   =  0,0005
3,14
0,05
d =  0,0135
3,7

  v = 0,0005+3.0,0135 = 0,04.

1
Mặt khác: V=  .d 3 = 26,5cm3.
6

v = 26,5.0,04 = 1,06  1,1cm .


3
Vậy có:

V = 26,5  1,1 cm3

1.9 Sai số do chặt cụt


Trong những bài toán gần đúng, các đại lượng tính toán được biểu diển bởi các
chuổi khác nhau, khi tính toán cần phải chặt cụt; nếu chúng ta không phân tích kỹ cũng
sẽ gây sai số rất lớn. Xét ví dụ sau.
^
Ví dụ. Giả sử rằng các chuỗi {αn} và { an } được mô tả bởi:

6
n 1 ^ n3
an  2
và an  3
n n
^ ^
Mặc dù cả hai giới hạn limn→∞ αn = 0 và limn→∞ an = 0, nhưng dãy số { an } hội
tụ đến giới hạn này nhanh hơn nhiều so với {αn}.
n 1 n  n 1
Từ an  0  2
 2  2.
n n n
^ n  3 n  3n 1
Và an  0  3
 3
 4. 2
n n n

1 ^
 1 
ta có: an  0  O   và an  0  O  2 
n n 
Kết quả này có nghĩa là sự hội tụ của chuỗi {αn} tương tự như hội tụ của {1/n}
^
tới không. Dãy số { an } hội tụ một cách tương tự và nhanh hơn, như hội tụ dãy số
{1/n2}.
Chúng ta cũng sử dụng khái niệm " độ lớn - big oh" để mô tả tốc độ hội tụ của
các hàm, đặc biệt là khi các biến độc lập tiệm cận bằng không.
Giả sử F là một hàm số hội tụ đến một số L như là h tiến về không. Nếu các
hằng số dương p và K tồn tại với:
|F(h) − L| ≤ Khp , với h → 0
Thì F(h) hội tụ tới L với tốc độ, hoặc bậc, của hội tụ O (hp). Cái này viết như
F(h) = L + O (hp) và được ghi là "F (h) → L với tốc độ hội tụ hp."

Chúng ta thường quan tâm đến giá trị lớn nhất của p để cho F(h) = L + O (hp).
Định nghĩa "độ lớn - oh" cho các hàm số cũng có thể được mở rộng để kết hợp tổng
quát hơn các hàm hội tụ về 0 trong chổ của hp.

1.10 Sự ổn định của quá trình tính


Một trong những tiêu chuẩn mà vấn đề tính toán gần đúng rất quan tâm đó là sự
ổn định của quá trình tính.
Một phương pháp được gọi là ổn định, nếu một sự thay đổi nhỏ trong số liệu
ban đầu, sẽ tạo ra một thay đổi nhỏ trong tính toán cuối cùng. Ngược lại, với một sự
thay đổi nhỏ trong số liệu ban đầu, tạo ra một sự thay đổi lớn trong tính toán cuối
cùng, phương pháp được gọi là không ổn định. Một số phương pháp chỉ ổn định đối

7
với sự lựa chọn một số điều kiện ban đầu; những phương pháp nầy được gọi là ổn định
có điều kiện (ví dụ, chúng ta hay gặp vấn đề này đối với các lược đồ sai phân).

Câu hỏi:
1) Định nghĩa sai số tuyệt đối, sai số tương đối ? Trong thực tế tính toán, người ta
sử dụng sai số tuyệt đối hay sai số tương đối ? Vì sao ?
2) Trình bày các quy tắc tính sai số?
3) Nêu sự khác nhau giữa sai số tính toán và sai số phương pháp? Hãy nêu ra một
quá trình tính có số liệu cụ thể minh họa và chỉ ra sai số tính toán và sai số
phương pháp ?
4) Đưa ra vài ví dụ tính toán, chỉ ra sự cần thiết phải chú ý đến sai số qui tròn ?

i t p:
1) Hãy xác định chữ số tin tưởng trong các số sau:
a) x = 0, 1 với  x = 0,25.10-2
y = 0,11 2 với  y = 0,1.10-3

b) z = 38,25 với  z = 0,27.10-2


2) Hãy xác định sai số tuyệt đối, biết sai số tương đối của các số xấp xỉ sau:
a) x = 1 26 nếu  x = 0,1%
b) x = 0, 6 nếu  y =10%

3) Hãy qui tròn các số dưới đây để có được chữ số tin tưởng và xác định sai số
tuyệt đối  và sai số tương đối  của chúng:
a) x=2,1514
b) y=0,16152
c) z=1,1225
d) v=0,01204
4) Hãy tính thương u = x1/x2 của hai số xấp xỉ: x1 = 5,735; x2 = 1,2 và xác định
sai số tương đối giới hạn  u , và sai số tuyệt đối giới hạn  u
5) Hãy xác định sai số tương đối giới hạn  a , sai số tuyệt đối giới hạn  a và số
chữ số đáng tin của cạnh a của hình vuông, biết diện tích hình vuông
s = 16,45 cm2 với  s = 0,01

8
áp số:
1) a) 2; b) 3; c)4
2) a)  x = 0,13.102
b)  y = 0,9.10-1
3) a) 2,15;  x = 0,14.10-2;  x = 0,65.10-3
b) 0,162;  y = 0,48.10-3;  y = 0,3.10-2
c) 1,23;  z = 0,5.10-2;  z = 0,41.10-2
d) 0,0120;  v = 0,4.10-4;  v = 0,33.10-2
4) u = 4,66;  u  0,0042;  u  0,02
5) a = x = 4,056cm;  a  0,0003 ;  a  0,0012; a có ba chữ số đáng tin

9
Chương 2 NỘI SUY
(INTERPOLATION)

Trong nhiều bài toán kỹ thuật, ta phải tìm các trị yi tại các điểm xi bên trong
đoạn [a, b] đã biết trước, hoặc khi quan hệ giải tích y = f(x) đã có sẵn nhưng phức tạp,
rất khó để tìm đạo hàm, tích phân… Khi đó ta dùng phép nội suy để dễ dàng tính toán
mà vẫn đảm bảo độ chính xác theo yêu cầu của thực tế.
2.1. Nội suy đa thức
2.1.1. Sự duy nhất của đa thức nội suy
Xét mẫu đo đạt gồm (n+1) cặp các giá trị đã biết của hai trạm x và y: (x0,y0),
(x1, y1),. . . ,(xn, yn). Hãy xây dựng một đa thức có bậc m ≤ n có dạng:
Pm(x) = a0 + a1x1+ . . . am-1xm-1 + amxm (2.1)
sao cho Pm(xi) = yi , với i = 0, 1,..., n (2.2)
Đây là bài toán nội suy đa thức, và đa thức Pm(x) được gọi là đa thức nội suy.
Ta có định lý:
Định lý: Tồn tại duy nhất một đa thức có bậc không quá n và đi qua (n + 1)
điểm cho trước (x0, y0), (x1, y1), . . . ,(xn, yn).
Chứng minh: Xét đa thức có dạng (2.1) ở trên và thỏa mãn (2.2). Kết hợp (2.1)
và (2.2), ta có:
 y0   1 x0 x02 x0n   a0 
    
 y1    1 x1 x12 x1n   a1 
(2.3)
    
    
 yn   1 xn xn2 xnn   an 

Hay có thể biểu diễn dưới dạng ma trận :


Y = V. a
Trong đó
1 x0 x02 x0n 
 
1 x1 x12 x1n 
V  (2.4)
 
 n
 1 xn xn2 xn 

Đây chính là ma trận Vandermon, ta có :


det V   x
0i  j  n
j  xi  (2.5)

10
Do ta đã giả thiết các điểm xi ≠ xj , do đó ma trận này khác 0 nên hệ phương
trình (2.3) có nghiệm duy nhất cho các ai, nên đa thức Pn(x) được xác định duy nhất.
2.1.2. Tính giá trị đa thức bằng phương pháp Horner
Với bài toán nội suy đa thức, thường phải tính giá trị của đa thức Pm(x)= a0 +
a1x1 + . . . am-1xm-1 + amxm tại điểm x. Khi tính trực tiếp, phải thực hiện khá nhiều
phép tính, và khi tính các giá trị mũ của x, có thể gặp các giá trị lớn, mặc dù trong
thực tế thường các thành phần của đa thức triệt tiêu lẫn nhau và giá trị của đa thức
không lớn. Để loại trừ các nhược điểm nêu trên, Horner đã đưa ra cách tính như sau:
Viết lại đa thức Pm(x) dưới dạng:
Pm(x) = amxm + am-1xm-1 + . . . + a1x1 + a0 = (...((amx + am-1)x + am-2)x+...+a1)x+a0
Thuật toán thiết lập cho máy tính, để tính Pm(x) như sau:
Đặt Pm = am
Pm-1 = Pmx + am-1
...
Pi = Pi-1x + ai
Chỉ cần lưu trữ Pi trong một ô nhớ của máy tính. Thuật toán trên trở thành:
Đặt P = am
Thiết lập vòng lặp i = m -1 → 0, tức là gán i = m -1, m -2,..., 0
Tính P = P.x + ai
Giá trị P cuối cùng (ứng với i = 0), cho ta giá trị của đa thức tại x.
Sau đây là chương trình thực hiện thuật toán trên:
Chương trình 1-1
#include <conio.h>
#include <stdio.h>
#define m 10
void main(void)
{
int k,n;
float p,x;
float a[m];
clrscr();
printf("\nCho bac cua da thuc n = ");

11
scanf("\%d",&n);
printf("Vao cac he so a:\n");
for (k=1;k<=n+1;k++)
{
printf("a[%d] = ",k-1);
scanf("%f",&a[k]);
};
printf("Cho gia tri x = ");
scanf("%f",&x);
p=0.0;
for (k=1;k<=n+1;k++)
p=p*x+a[k];
printf("Tri so cua da thuc P tai x =%.2f la :%.5f",x,p);
getch();
}
Sơ đồ Horner tổng quát: Giả sử chúng ta có đa thức:
Pn(x) = a0xn + a1xn - 1 + a2xn - 2 +....+ an (2.6)
Khai triển Taylor của đa thức tại x = xo có dạng:
P( x0 ) P( x0 ) P ( n ) ( x0 )
Pn ( x)  Pn ( x0 )  ( x  x0 )  ( x  x0 ) 2      ( x  x0 ) n (2.7)
1! 2! 2!
Mặt khác chúng ta có thể biến đổi đa thức về dạng:
Pn(x) = (x - xo)Pn-1(x) + Pn(xo) (2.8)
Trong đó Pn-1(x) là đa thức bậc n - 1 và có dạng:
Pn-1(x) = boxn-1 + bo-1xn - 2 + b2xn - 3 +....+ bn-1 (2.9)
Thuật toán để tìm các hệ số nhận được bằng cách so sánh (2.6) và (2.8):
bo = ao
bi = ai + bi-1xo
bn = Pn(xo)
So sánh (2.7) và (2.8) ta có:
P( x0 ) P( x0 )
( x  x0 ) Pn 1 ( x0 )  Pn ( x0 )  Pn ( x0 )  ( x  x0 )  ( x  x0 ) 2
1! 2!
(2.10)
P ( n ) ( x0 )
   ( x  x0 ) n
2!

12
Hay:
P( x0 ) P( x0 ) P ( n ) ( x0 )
( x  x0 ) Pn 1 ( x)  ( x  x0 )  ( x  x0 )     
2
( x  x0 ) n (2.11)
1! 2! 2!
Và khi chia hai vế cho (x - x0) ta nhận được :
P( x0 ) P( x0 ) P ( n ) ( x0 )
Pn 1 ( x)   ( x  x0 )      ( x  x0 ) n 1 (2.12)
1! 2! 2!
So sánh (2.9) và (2.12) ta nhận được kết quả :
P( x0 )
Pn 1 ( x0 )  (2.13)
1!
Trong đó Pn-1(x) lại có thể phân tích giống như Pn(x) dạng (2.3) để tìm ra
Pn-1(xo). Quá trình này được tiếp tục cho đến khi ta tìm hết các hệ số của chuỗi Taylor
của Pn(x).
Tổng quát thuật toán thể hiện ở bảng sau:
Pn(x) ao a1 a2 a3 ... an-1 an
x = xo 0 boxo b1xo b2xo bn-2xo bn-1xo

P+-1(x) bo b1 b2 b3 ... bn-1 bn = Pn(xo)


Để hiểu rõ hơn chúng ta lấy một ví dụ cụ thể sau: Khai triển đa thức sau tại xo= 2
P(x) = x5 - 2x4 + x3 -5x + 4
Ta lập bảng tính sau:
2 1 -2 1 0 -5 4
0 2 0 2 4 2
2 1 0 1 2 -1 2 = P(2)/0!
0 2 4 10 24
2 1 2 5 12 23 = P'(2)/1!
0 2 8 26
2 1 4 13 38 = P"(2)/2!
0 2 12
2 1 6 25 = P"'(2)/3!
0 2
2 1 8 = P""(2)/4!
0
1 = P""'(2)/4!
13
Như vậy:
Pn(x) = (x - 2)5 + 8(x - 2)4 + 25(x - 2)3 + 38(x - 2)2 + 23(x - 2) + 2
Chương trình sau được thiết lập dùng để xác định các hệ số của chuỗi Taylor
của đa thức P(x) tại xo.
Chương trình 1-2
#include <conio.h>
#include <stdio.h>
#define m 10

void main(void)
{
float a[m],b[m],c[m];
int n,i,j,k;
float x;

clrscr();
printf(“Cho bac cua da thuc n = “);
scanf(“%d”,&n);
printf(“Cho gia tri x = “);
scanf(“%f”,&x);
printf(“Vao cac he so a\n”);
for (k=n;k>=0;k--)
{
printf(“a[%d] = “,n-k);
scanf(“%f”,&a[k]);
}
printf(“\n”);
b[n] = a[n];
c[n] = a[n];
for (k=0;k<=n-1;k++)
{
for (i=n-1;i>=k;i--)

14
b[i] = b[i+1]*x + a[i];
c[k] = b[k];
for (j=n;j>=k+1;j--)
a[j] = b[j];
}
printf(“\nSo do Horner tong quat”);
printf(« \nKhai trien tai x = %.4f\n »,x) ;
for (k=n;k>=0;k--)
printf(“%10.4f\t”,c[k]);
getch();
}
2.1.3. Các phép tính trên đa thức
a. Phép cộng hai đa thức: Giả sử chúng ta có hai đa thức A(x) bậc n và B(x) bậc
m với n > m. Khi cộng hai đa thức này, chúng ta cộng lần lượt các hệ số cùng bậc của
chúng với nhau. Ta có chương trình sau:
Chương trình 1-3
#include <conio.h>
#include <stdio.h>
#define t 10

void main(void)
{
int k,n,m;
float a[t],b[t],c[t];

clrscr();
printf("Cho bac cua da thuc A n = ");
scanf("%d",&n);
printf("Vao cac he so a\n");
for (k=1;k<=n+1;k++)
{
printf("a[%d] = ",k-1);

15
scanf("%f",&a[k]);
}
printf("Cho bac cua da thuc B m = ");
scanf("%d",&m);
printf("Vao cac he so b\n");
for (k=1;k<=m+1;k++)
{
printf("b[%d] = ",k-1);
scanf("%f",&b[k]);
}
printf("\n");
for (k=1;k<=n+1;k++)
if (k<=n-m)
c[k] = a[k];
else
c[k] = a[k] + b[k-n+m];
printf("Cac he so cua da thuc tong C la :\n");
for (k=1;k<=n+1;k++)
printf("%.4f\t",c[k]);
getch();
}
b. Phép nhân hai đa thức: Để thấy rõ thuật toán xác định các hệ số của đa thức
C(x) là kết quả của phép nhân hai đa thức A(x) và B(x) ta cho một ví dụ cụ thể:
A(x) = aox5 + a1x4 + a2x3 + a3x2+ a4x + a5
B(x) = box3 + b1x2 + b2x + b3
C(x) = A(x).B(x) (2.14)
= aobox8 + (aob1 + a1bo)x7 +( aob2 + a1b1 + a2bo)x6 +
+ (aob3 + a1b2 + a2b1+ a3bo )x5 + (a1b3 + a2b2 + a3b1 + a4bo)x4 +
+ (a2b3 + a3b2 + a4b1 + a5b+)x3 + ( a3b3 + a4b2 + a5b1)x2 + a5b2x + a5b3
Các hệ số của đa thức kết quả là:
Co = aobo
C1 = aob1 + a1bo

16
C2 = aob2 + a1b1 + a2bo
C3 = aob3 + a1b2 + a2b1+ a3bo
C4 = a1b3 + a2b2 + a3b1 + a4bo
C5 = a2b3 + a3b2 + a4b1 + a5bo
C6 = a3b3 + a4b2 + a5b1
C7 = a5b2
C8 = a5b3
Ta nhận thấy là hệ số Ck của C(x) là tổng các tích các hệ số của đơn thức bậc i
của A(x) và bậc (k - i) của B(x). Chỉ số i = 0 khi k ≤ m + 1 và i = k + m khi k > m+1.
Chỉ số j = k khi k ≤ n + 1 và j = n +1 khi k > n + 1.
Sau đây là chương trình tính tích hai đa thức:
Chương trình 1-4
#include <conio.h>
#include <stdio.h>
#define t 10
void main()
{
int k,n,m,l,i,j,p;
float a[t],b[t],c[2*t];
clrscr();
printf("Cho bac cua da thuc A n = ");
scanf("%d",&n);
printf("Vao cac he so a\n");
for (k=1;k<=n+1;k++)
{
printf("a[%d] = ",k-1);
scanf("%f",&a[k]);
}
printf("Cho bac cua da thuc B m = ");
scanf("%d",&m);
printf("Vao cac he so b\n");
for (k=1;k<=m+1;k++)

17
{
printf("b[%d] = ",k-1);
scanf("%f",&b[k]);
}
printf("\n");
l=n+m;
for (k=1;k<=l+1;k++)
{
if (k<=(n+1))
j=k;
else
j=n+1;
if (k<=(m+1))
p=1;
else
p= k-m;
c[k]=0;
for (i=p;i<=j;i++)
c[k] = c[k] + a[i]*b[k-i+1];
}
printf("Cac he so cua da thuc tich C voi bac %d la :\n",l);
for (k=1;k<=l+1;k++)
printf("%.4f\t",c[k]);
getch();
}
c. Chia hai đa thức: Giả sử ta có hai đa thức là An(x) và Bm(x) với n  m.
Thương hai đa thức này là:
An ( x) R ( x)
 Qn m ( x)  m1 (2.15)
Bm ( x) Bm ( x)

Chương trình sau thực hiện việc chia 2 đa thức:

18
Chương trình 1-5
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define t 10
void main()
{
int k,n,m,l,i,j,jp;
float a[t],b[t],q[t],r[t],epsi;
clrscr();
printf("Cho bac cua da thuc A n = ");
scanf("%d",&n);
printf("Vao cac he so a\n");
for (k=1;k<=n+1;k++)
{
printf("a[%d] = ",k-1);
scanf("%f",&a[k]);
}
printf("\n");
printf("Cho bac cua da thuc B m = ");
scanf("%d",&m);
printf("Vao cac he so b\n");
for (k=1;k<=m+1;k++)
{
printf("b[%d] = ",k-1);
scanf("%f",&b[k]);
}
printf("\n");
printf("Cho gia tri sai so epsilon epsi = ");
scanf("%f",&epsi);
if ((m+1)>1)
{

19
l=n-m+1;
for (i=0;i<=t;i++)
r[i]=a[i];
j=n;
for (k=1;k<=l;k++)
{
q[k]=r[1]/b[1];
for (i=1;i<=j;i++)
if ((i<m+1))
r[i]=r[i+1]-q[k]*b[i+1];
else
r[i]=r[i+1];
j=j-1;
}
while ((abs(r[i])<epsi)&&(j>0))
{
for (i=1;i<=j;i++)
r[i]=r[i+1];
j=j-1;
}
if (abs(r[1])<epsi)
r[1]=0.0;
jp=j+1;
}
else
{
l=n+1;
for (k=1;k<=l;k++)
q[k]=a[k]/b[1];
jp=1;
r[1]=0.0;
}

20
printf("\n");
printf("Cac he so cua thuong Q(x) bac %d la : ",l);
for (k=1;k<=l;k++)
printf("%.3f\t",q[k]);
printf("\n");
printf("Cac he so cua phan du R(x) bac %d la : ",jp-1);
for (k=1;k<=jp;k++)
printf("%.3f",r[k]);
getch();
}
2.1.4. Sai số của đa thức nội suy
Định lý Rolle phát biểu:
Định lý Rolle: Cho f(x) là hàm số thực liên tục trên khoảng kín [a, b] và khả vi
trên khoảng hở (a, b) và f(a) = f(b). Khi đó tồn tại điểm ξ∈ (a, b) sao cho f '(ξ) = 0.
Định lý: Giả sử hàm f(x) có đạo hàm liên tục đến cấp (n + 1) trên khoảng kín
[a, b] và Pm(x) là đa thức nội suy, tức là: Pm(xi) = f(xi) = yi , với i = 0, 1,..., n. Với
các mốc nội suy là a = x0 < x1 < ... < xn = b.
n
Đặt n1  x     x  x  và
i 0
i r(x) = f(x) - Pm(x)

Khi đó với ∀ x ∈ [a, b] tồn tại η ∈ [a, b] (phụ thuộc vào x) sao cho:
f ( n1) ( )
r ( x)  n1 ( x) (2.16)
(n  1)!

Hệ quả:
Gọi M  sup f ( n1) ( x) khi đó ta có:
a  x b

M
r ( x)  f ( x)  pm ( x)  n 1 ( x) (2.17)
(n  1)!

đây là công thức đánh giá sai số của đa thức nội suy.
2.2. Đa thức nội suy Lagrange
Giả sử ta có các cặp điểm quan sát được cho ở bảng sau:
Bảng các giá trị:
x x1 x2 x3 .... . .. xn
y y1 y2 y3 ... ...yn
21
Cần lập đa thức: Pn(x) có bậc m  n - 1, nhận các giá trị yi cho trước ứng với
các xi:
yi = f(xi), với i = 1, 2, 3,…. ...,n
Ký hiệu: (x) = (x - x1)(x - x2)... ... (x - xn)
Ta có được đẳng thức:
y1 (x) y2 (x)
Pn (x)    ...
(x - x1 )( x1  x2 )( x1  x3 )...( x1  xn ) ( x  x2 )( x2  x1 )( x2  x3 )....( x2  xn )
(2.18)
yn ( x)

( x  xn )( xn  x1 )( xn  x2 ).......( xn  xn1 )

n
yk ( x )
Hay: Pn(x) = 
k 1  ( xk ).( x  xk )
'
(2.19)

Đây là đa thức nội suy Lagrange


Nếu hàm f(x) liên tục trên [a, b] và có đạo hàm liên tục đến cấp (n + 1) trong
(a, b), thì sai số nội suy rn(x) = f(x) - Pn(x), được cho bởi biểu thức:
 ( x)
rn ( x)  f ( n 1) (c) , c [a, b] (2.20)
 n  1!
Trong đó: a ≤ x1 ≤ x2 ≤ x3 ≤ … ≤ xn ≤ b
Nếu gọi M = max f ( n1) ( x) ; x   a, b thì sai số nội suy:

M
rn ( x)   ( x) (2.21)
 n  1!
Ví dụ. Cho bảng giá trị:
x 0 1 2 3

y 3 4 7 8
Tìm đa thức nội suy Lagrange và tìm y khi biết x = 1,5.
Ta có:  (x) = (x-x1)(x-x2)(x-x3)(x-x4)
= x(x-1)(x-2)(x-3)
3.x.( x  1).( x  2).( x  3) 4.x.( x  1).( x  2).( x  3)
 Pn(x) =  
x.(1).(2).( 3) ( x  1).1.( 1).( 2)
7.x.( x  1).( x  2).( x  3) 8.x.( x  1).( x  2).( x  3)

( x  2).2.1.(1) ( x  3).3.2.1

= -1/2(x-1)(x-2)(x-3)+2x(x-2)(x-3)-7/2x(x-1)(x-3)+4/3x(x-1)(x-2)
22
Tại x =1,5 thế vào Pn(x) ta có y = 5,67.
Đa thức nội suy Lagrange có ưu điểm là đơn giản, nhưng nếu thêm nút nội suy
thì phải tính lại toàn bộ, nhược điểm này sẽ được khắc phục trong công thức nội suy
Newton.
Ứng dụng lập trình
a. Dùng C++
#include <conio.h>
#include <stdio.h>
#include <ctype.h>
#define max 21

int maxkq,n;
float x[max],y[max],a[max],xx[max],yy[max];
float x0,p0;

void main()
{
int i,k;
char ok ;
void vaosolieu(void);
float lagrange(int,float [],float [],float);
void inkq(void);

clrscr();
printf("%24cNOI SUY DA THUC LAGRANGE\n",' ');
vaosolieu();
k=0;
ok='c';
while (ok=='c')
{
printf("Tinh gia tri cua y voi x la x0 = ");
scanf("%f",&x0);
23
p0=lagrange(n,x,y,x0);
printf("Gia tri cua y = %15.5f\n",p0);
printf("\n");
k=k+1;
maxkq=k;
xx[k]=x0;
yy[k]=p0;
flushall();
printf("Tinh tiep khong(c/k)?");
scanf("%c",&ok);
}
inkq();
}

void vaosolieu()
{
int i,t;
char ok;

printf("\n");
printf("Ham y = f(x)\n");
printf("So cap (x,y) nhieu nhat la max = 20\n");
printf("So diem da cho truoc n = ");
scanf("%d",&n);
for (i=1;i<=n;i++)
{
printf("x[%d] = ",i);
scanf("%f",&x[i]);
printf("y[%d] = ",i);
scanf("%f",&y[i]);
}
printf("\n");

24
printf(" SO LIEU BAN VUA NHAP\n");
printf(" x y\n");
for (i=1;i<=n;i++)
printf("%8.4f %8.4f\n",x[i],y[i]);
ok=' ';
t=1;
flushall();
while (t)
{
printf("\nCo sua so lieu khong(c/k):?");
scanf("%c",&ok);
if (toupper(ok)=='C')
{
printf("Chi so cua phan tu can sua i = ");
scanf("%d",&i);
printf("Gia tri moi : ");
printf("x[%d] = ",i);
scanf("%f",&x[i]);
printf("y[%d] = ",i);
scanf("%f",&y[i]);
flushall();
}
if (toupper(ok)!='C')
t=0;
}
}

float lagrange(int n,float x[max],float y[max],float x0)


{
int i,k;
float g0;

25
p0=0.0;
for (k=1;k<=n;k++)
{
g0=1.0;
for (i=1;i<=n;i++)
if (i!=k)
g0=g0*(x0-x[i])/(x[k]-x[i]);
p0=p0+y[k]*g0;
}
return(p0);
}
void inkq()
{
int i,j,k;
printf("\n");
printf("%24cBANG SO LIEU\n",' ');
printf("%18cx %24cy\n",' ',' ');
for (i=1;i<=n;i++)
printf("%20.4f %25.4f\n",x[i],y[i]);
printf("\n");
printf("%24cKET QUA TINH TOAN\n",' ');
printf("%14cx %10cy\n",' ',' ');
for (k=1;k<=maxkq;k++)
printf("%15.5f %15.5f\n",xx[k],yy[k]);
getch();
}

Áp dụng. Giả sử ta có bảng các giá trị x, y:

x 0 3 -2 2 4
y 0 -3.75 10 -2 4
Dùng chương trình tính nội suy, tại x = 2,5 tìm được: y = -3,3549.
26
b. Dùng Matlab
Xây dựng hàm nội suy:
function [l,L] = lagrange(x,y)
%Dua vao : x = [x0 x1 ... xn], y = [y0 y1 ... yn]
%ket qua: l = He so cua da thuc Lagrange bac n
% L = Da thuc Lagrange
n = length(x)-1; %bac cua da thucl
l = 0;
for m = 1:n + 1
p = 1;
for k = 1:n + 1
if k ~= m
p = conv(p,[1 -x(k)])/(x(m)-x(k));
end
end
L(m,:) = p; %da thuc Lagrange
l = l + y(m)*p;
end

Áp dụng: Cho hàm y(x) dưới dạng bảng

x -2 -1 1 2
y -6 0 0 6

Đi tìm y(1.5) = ? ta sử dụng chương trình trên:


clear all, clc
x = [-2 -1 1 2];
y = [-6 0 0 6];
l = lagrange(x, y);
yx = polyval(l, 1.5)
Kết quả y(1.5) = 1.8750

27
2.3. Nội suy Newton
Trong mục này, đề cập đến đa thức nội suy khi biết các mẫu quan sát rời rạc
(xi, yi), sao cho mỗi lần bổ sung thêm số liệu, thì ta vẫn kế thừa được đa thức nội suy
đã tính trước đó.
2.3.1. Nội suy Newton với mốc cách đều
Giả sử y0, y1, y2, ... là những giá trị nào đó của hàm y = f(x) tương ứng với các
giá trị cách đều nhau của các đối số x0, x1, x2 ...tức là:
xk + 1 - xk = xk = const
Ký hiệu:
y1 - y0 = y0 ; y2 - y1 = y1 ; ... ... ; yn - yn - 1 = yn - 1 là sai phân cấp 1.
y1 - y0 = 2y0 ; y2 - y1 = 2y1 ; ..... là sai phân cấp 2.
ny1 - ny0 = n + 1y0 ; ny2 - ny1 = n + 1 y1 ; ..... là sai phân cấp n + 1.
Tiến hành các phép thế liên tiếp, ta nhận được:
..., 2y0 = y2 - 2y1 + y0 ; 3y0 = y3 - 3y2 + 3y1 - y0 ,….
n
 y0 
n
 (1)
K 0
K
CnK yn  K (2.22)

Tương tự ta cũng nhận được:


y1 = y0 + y0 , y2 = y0 + 2y0 + 2y0 , y3 = y0 + 3y0 + 32y0 + 3y0 ,…
n(n  1) 2
yn = y0 + ny0 +  y0 + ... + ny0 (2.23)
2!
Nếu trong (2.23) ta xem n không những là chỉ là số nguyên dương mà có thể là
số n = t bất kỳ, ta nhận được công thức nội suy Newton (còn gọi là Nội suy Newton
tiến – do sử dụng sai phân tiến):
t t (t  1) 2 t (t  1)(t  2) 3
Pt = y0 + y0   y0   y0  ...  t y0 (2.24)
1! 2! 3!
x n  x0
Do bước tăng x = const, ta được xn = x0 + nh, suy ra n =
h
x  x0
Đặt x = x0 + t.h, suy ra t = , thế vào (2.24), ta có được dạng khác của
h
(2.23).
x  x0 ( x  x0 )( x  x0  h) 2
Pn = y 0 + y0   y0  .... (2.25)
h 2!h 2

28
Đánh giá sai số:
f ( n 1) (c) n 1
rn ( x)  h t  t  1 t  n  ; c [a, b] (2.26)
 n  1!
Trong đó: a ≤ x0 ≤ x1 ≤ x2 ≤ … ≤ xn ≤ b
Nếu gọi M = max f ( n1) ( x) ; x   a, b thì sai số nội suy:

M
rn ( x)  hn 1 t  t  1 t  n  ; (2.27)
 
n  1 !

Vídụ. x 1 2 3 4
y 5 7 10 12

Tìm hàm nội suy Newton.

Giải: Ta có:
Sai phân cấp 1 : y0  y1 - y0 = 7 - 5 = 2

Sai phân cấp 2 :  2 y0 = y2 – 2y1 + y0 = 10-2.7 + 5 = 1

Sai phân cấp 3: 3 y0 = y3 - 3y2 + 3y1 - y0 = 12-3.10 + 3.7 - 5 = -2


x  h  1
x  x0 ( x  x0 )( x  x0  h) 2 ( x  x0 )( x  x0  2h) 3
 Pn = y0 + y0  2
 y0   y0
h 2!h 3!h3
x 1 ( x  1)( x  1  1) ( x  1)( x  1  2.1)
=5+ .2  2
.1  3
(2)3
1 2!1 3!1
1 5 19
= - x3  x 2  x6
3 2 6
2.3.2. Nội suy Newton với mốc không cách đều
Với nội suy Newton khi sử dụng các mốc không cách đều công thức nội suy
phức tạp hơn.
Trong thực tế các điểm x0, x1, ... xn có thể không cách đều. Lúc này khoảng
cách xi+1 - xi = hi không phải là hằng số. Trong trường hợp này ta cũng xây dựng được
đa thức nội suy Newton có dạng như trường hợp cách đều, nhưng cách tính toán các
hệ số có khác.
Đa thức nội suy có dạng:

f n ( x)  b0  b1 ( x  x0 )  .....  bn ( x  x0 )( x  x1 )...( x  xn1 )..... (2.28)

29
Các điểm dữ liệu được sử dụng để tính các hệ số b0, b1, .... bn. Đối với một đa
thức bậc thứ n, có (n + 1) điểm dữ liệu được yêu cầu. Chúng ta sử dụng các điểm dữ
liệu và các phương trình sau đây để xác định các hệ số:
b0  f ( x0 )

b1  f [ x1 , x0 ]

b2  f [ x2 , x1 , x0 ]
.
.
.
bn  f [ xn , xn1 ,..., x1 , x0 ]

Tỷ sai phân cấp 1 của f tại xi, xj là:


f ( xi )  f ( x j )
f [ xi , x j ] 
xi  x j

Tỷ sai phân cấp 2 của f tại xi, xj, xk là:


f [ xi , x j ]  f [ x j , xk ]
f [ xi , x j , xk ] 
xi  xk

Tương tự như vậy, tỷ sai phân cấp n của f là:


f [ xn , xn 1 ,..., x1 ]  f [ xn 1 , xn 2 ,..., x0 ]
f [ xn , xn1 ,..., x1 , x0 ] 
xn  x0

Thay các hệ số trên vào phương trình (2.9) ta nhận được đa thức nội suy Newton:
Pn  f ( x0 )  ( x  x0 ). f [ x1 , x0 ]  ( x  x0 ).( x  x1 ) f [ x2 , x1, x0 ]
....  ( x  x0 ).( x  x1 )...( x  xn 1 ) f [ xn , xn 1,..., x0 ] (2.29)

2.3.3. Ứng dụng lập trình


a. Dùng C++
//Noi suy Newton
#include <conio.h>
#include <stdio.h>
#include <ctype.h>
#define max 11

void main()

30
{
int i,j,k,n,t;
float a[max],b[max],x[max],y[max];
char ok;
float x0,p;

clrscr();
printf("So diem da cho n = ");
scanf("%d",&n);
for (i=1;i<=n;i++)
{
printf("x[%d] = ",i);
scanf("%f",&x[i]);
printf("y[%d] = ",i);
scanf("%f",&y[i]);
}
printf("%10cBANG SO LIEU\n",' ');
printf("%8cx%30cy\n",' ',' ');
for (i=1;i<=n;i++)
printf("%4c%8.4f%23c%8.4f\n",' ',x[i],' ',y[i]);
ok=' ';
t=0;
flushall();
while (t)
{
printf("Co sua so lieu khong(c/k): ");
scanf("%c",&ok);
if (toupper(ok)=='C')
{
printf("Chi so cua phan tu can sua i = ");
scanf("%d",&i);
printf("Gia tri moi : ");

31
printf("x[%d] = ",i);
scanf("%f",&x[i]);
printf("y[%d] = ",i);
scanf("%f",&y[i]);
flushall();
}
if (toupper(ok)!='C')
t=0;
}
a[1]=y[1];
for (j=1;j<=n-1;j++)
{
for (i=1;i<=n-j;i++)
y[i]=(y[i+1]-y[i])/(x[i+j]-x[i]);
a[j+1]=y[1];
}
b[n]=a[n];
for (k=n-1;k>=1;k--)
{
for (j=n-1;j>=1;j--)
b[j]=a[j] ;
for (i=n-1;i>=k;i--)
a[i]=a[i]-b[i+1]*x[k];
}
for (i=n;i>=1;i--)
printf("He so bac %d la :%8.4f\n",i-1,a[i]);
printf("\n");
k=0;
ok='c';
flushall();
while (ok=='c')
{

32
printf("Tinh gia tri cua y tai x = ");
scanf("%f",&x0);
p=0;
for (k=n;k>=1;k--)
p=p*x0+a[k];
printf("Tri so noi suy tai x0 = %4.2f la : %10.5f\n",x0,p);
getch();
printf("Ban co muon tinh tiep cac diem khac khong(c/k)");
do
scanf("%c",&ok);
while ((ok!='c')&&(ok!='k'));
}
}

Áp dụng. Dùng chương trình này nội suy các giá trị cho trong bảng sau:

0 0.2 0.4 0.6 0.8 1.0

1 1.22140276 1.4918247 1.8221188 2.22554093 2.71828183

Ta có các hệ số của đa thức nội suy: 0.0139(bậc 5), 0.0349(bậc 4), 0.1704(bậc 3),
0.4991(bậc 2), 1.0001(bậc 1) và 1.0000 (bậc 0).

b. Dùng Matlab

Xây dựng hàm nội suy:


function [n,DD] = newton(x,y)
%Dua vao : x = [x0 x1 ... xN]
% y = [y0 y1 ... yN]
%Lay ra: n = he so cua da thuc Newton bac N
N = length(x)-1;
DD = zeros(N + 1,N + 1);
DD(1:N + 1,1) = y';
for k = 2:N + 1
for m = 1: N + 2 - k

33
DD(m,k) = (DD(m + 1,k - 1) - DD(m,k - 1))/(x(m + k - 1)- x(m));
end
end
a = DD(1,:);
n = a(N+1);
for k = N:-1:1
n = [n a(k)] - [0 n*x(k)];
end

Áp dụng: Cho hàm dưới dạng bảng

x -2 -1 1 2 4
y -6 0 0 6 60

Ta dùng chương trình thiết lập tính y = ?, tại x=2.5


clear all, clc

x = [-2 -1 1 2 4];

y = [-6 0 0 6 60];

a = newton(x, y)

yx = polyval(a, 2.5)

Kết quả y(2.5) = 13.1250


2.4. Nội suy Hermite

Các đa thức Lagrange, Newton thích hợp với bài toán mà hàm f xác định tại
các điểm cho trước; các giá trị của f thường được xác định từ quan sát hay đo đạc.
Tuy nhiên trong một số trường hợp ngoài việc xác định hàm f còn phải xác
định đạo hàm f ’ của nó nữa. Ví dụ, trường hợp biến độc lập là thời gian và hàm f mô
tả vị trí của một đối tượng; đạo hàm của hàm f trong trường hợp này là vận tốc v = f ‘;
hoặc bài toán kết cấu tính dầm trên nền đàn hồi, ta phải xác định chuyển vị yi và góc
xoay αi của dầm; thông số góc xoay αi chính là đạo hàm của chuyển vị yi, .
dy
i  ( )i  yi,
dx

34
Trong mục này, chúng ta sẽ xem xét nội suy Hermite, xác định đa thức phù hợp
với hàm và đạo hàm bậc nhất tại các điểm cho trước. Giả sử rằng (n + 1) điểm dữ liệu
và các giá trị của hàm (x0, f (x0)), (x1, f (x1)), ..., (xn, f (xn)), được cho, và hàm f có đạo
hàm liên tục bậc nhất trên khoảng kín [a, b] có chứa các điểm x0, x1, ..., xn. Đa thức
Lagrange thích hợp với f tại những điểm này, thường sẽ có bậc n. Nhưng nếu chúng ta
yêu cầu đạo hàm đa thức xác định còn phải phù hợp với đạo hàm của f tại x0, x1, ..., xn,
nữa, thì ta phải sử dụng nội suy Hermite và cần phải bổ sung (n +1) điều kiện nữa và
bậc của đa thức Hermite sẽ là (2n + 1).
Giả sử f ∈ C1 [a, b] và x0, x1,..., xn là các trị số khác biệt trong khoảng kín [a, b].
Đa thức duy nhất có bậc phù hợp nhất với f và f ‘ tại x0, ..., xn là đa thức có bậc lớn
nhất là (2n + 1) cho bởi

H 2 n1 ( x)   f  x j  H n, j  x    f '  x j  H n, j  x 
n n ^

j 0 j 0
(2.30)
Trong đó: H n, j  x   1  2  x  x j  L'n, j  x j  L2n, j  x 

H n, j  x    x  x j  L2 n, j  x 
^
Và:

Ở đây:
 ( x)
Ln,k ( x) 
 ( xk ).( x  xk )
,

Ln, j (x) biểu thị đa thức hệ số Lagrange thứ j của bậc n.


Số hạng sai số cho đa thức Hermite là tương tự như của đa thức Lagrange, với
những sữa đổi duy nhất là cần thiết để đáp ứng số lượng gia tăng của dữ liệu được sử
dụng trong các đa thức Hermite.
Nếu f ∈ C2n+ 2 [a, b], thì sai số đa thức Hermite là:
f (2 n  2)  ( x) 
f ( x)  H 2 n 1  x    x  x0   x  xn 
2 2

(2n  2)! (2.31)


Với ξ (x) là một giá trị nào đó trong khoảng hở (a, b).
Mặc dù công thức Hermite cung cấp việc mô tả đầy đủ các đa thức Hermite, sự
cần thiết để xác định và đánh giá các đa thức Lagrange và các đạo hàm của chúng làm
cho quá trình kéo dài ngay cả đối với các giá trị nhỏ của n. Một phương pháp khác để
tạo ra xấp xỉ Hermite được dựa trên mối liên hệ giữa sự phân chia sai phân bậc n và
đạo hàm bậc n của f.

35
Nếu f ∈ Cn [a, b] và x0, x1, ..., xn là các giá trị khác biệt trong [a, b], thì tồn tại trị
số ξ trong (a, b) với:
f ( n )  
f  x0 , x1 , xn  
n! (2.32)
Để sử dụng kết quả này tạo ra các đa thức Hermite, giả thiết đầu cho rằng
những trị số riêng biệt x0, x1, ..., xn được cho cùng với các giá trị của f và f ‘ tại những
trị số này. Xác định một chuỗi mới z0, z1, ..., z2n +1 bởi:
z2k  z2k 1  xk với k = 0, 1, 2, ..n

Bây giờ xây dựng bảng sai phân bằng cách sử dụng các biến z0, z1, ..., z2n+1. Từ
z2k = z2k +1 = xk cho mổi trị số k, chúng ta không thể xác định f [z2k, z2k +1] bởi mối
quan hệ sai phân cơ bản:
f [z2 k ] - f [z2 k 1 ]
f [z2 k , z2 k 1 ]=
z2 k  z2 k 1 (2.33)
Tuy nhiên, đối với mỗi trị số k chúng ta có f [xk, xk+1] = f ’(ξk) với một số ξk
trong (xk, xk +1), và lim xk+1→xk , f [xk, xk+1]= f’(xk). Vì vậy, một sự thay thế hợp lý
trong tình huống này là f [z2k, z2k+1] = f’(xk), và chúng ta sử dụng:
f '  x0  , f '  x1  , f '  xn 

Ở nơi sai phân đầu tiên.


f  z0 , z1  , f  z1 , z2  ,..., f  z2 n , z2 n1 

Sai phân còn lại được tạo ra như thường lệ, và sự xấp xỉ sai phân được sử dụng
như trong công thức sai phân của Newton. Điều này cung cấp cho chúng ta với một
phương pháp thay thế, dễ dàng hơn đánh giá, để xác định hệ số của đa thức Hermite.
Nếu f ∈ C1 [a, b] và x0, x1, ..., xn là các trị số khác biệt trong [a, b], thì
2 n 1
H 2n+1 (x)= f[z 0 ]+  f[z 0 ,z1 ,...,z k ](x - z0 ),..., (x - z k-1 )
k 1 (2.34)
Với z2k  z2k 1  xk và f  z2k , z2k 1   f '  xk  với k = 0, 1, 2,…,n

Bảng sai phân cho thấy các mục đã được sử dụng cho ba cột sai phân đầu tiên
khi xác định các đa thức Hermite H5(x) cho x0, x1, và x2. Mục còn lại được tạo ra theo
cách sai phân bình thường.

36
z f(z) sai phân bậc 1 sai phân bậc 2

z0 = x0 f [z0] = f (x0)
f [z0, z1]= f’(x0)
f [z2 ,z1 ] - f [z1 ,z0 ]
z1 = x0 f [z1] = f (x0) f [z0 , z1 , z2 ]=
z 2  z0
f [z2 ] - f [z1 ]
f [z1 , z2 ]=
z2  z1
f [z3 ,z2 ] - f [z2 ,z1 ]
z2 = x1 f [z2] = f (x1) f [z1 , z2 , z3 ]=
z3  z1
f  z2 , z3   f '  x1 
f [z4 ,z3 ] - f [z3 ,z2 ]
z3 = x1 f [z3] = f (x1) f [z2 , z3 , z4 ]=
z4  z2
f [z4 ] - f [z3 ]
f [z3 , z4 ]=
z4  z3
f [z5 ,z4 ] - f [z4 ,z3 ]
z4 = x2 f [z4] = f (x2) f [z3 , z4 , z5 ]=
z5  z3
f  z4 , z5   f '  x2 
z5 = x2 f [z5] = f (x2)

Ví dụ. Cho dữ liệu cho trong bảng dưới đây, dùng nội suy Hermite tính f(1.5).
Trong đó các mục gạch đít là các dữ liệu cho, phần còn lại được tạo ra theo phương
pháp sai phân chuẩn.
1.3 0.6200860
−0.5220232
1.3 0.6200860 −0.0897427
−0.5489460 0.0663657
1.6 0.4554022 −0.0698330 0.0026663
−0.5698959 0.0679655 −0.0027738
1.6 0.4554022 −0.0290537 0.0010020
−0.5786120 0.0685667
1.9 0.2818186 −0.0084837
−0.5811571
1.9 0.2818186

37
H5(1.5) = 0.6200860 − 0.5220232(1.5 − 1.3) − 0.0897427(1.5 − 1.3)2 +
+ 0.0663657(1.5 − 1.3)2(1.5 − 1.6) + 0.0026663(1.5 − 1.3)2(1.5 − 1.6)2 –
− 0.0027738(1.5 − 1.3)2(1.5 − 1.6)2(1.5 − 1.9)
= 0.5118277
Như vậy, với sử dụng nội suy Hermite, ta tính được giá trị của hàm f tại x = 1.5 là:
H5(1.5) = 0.5118277

2.5. Nội suy Spline

f1(x)
y0
x1
f2(x)

f3(x)

y2
y3

x0 x1 x2 x3 x
Trong các mục trước, ta đã xét các bài toán nội suy bằng đa thức và thấy rằng:
các đa thức nội suy thường có bậc rất lớn, khi số điểm mốc lớn; mặt khác có nhiều
hiện tượng vật lý như: sự phân bố mặn theo chiều sâu, mặt cong của sóng gián
đoạn,…nếu sử dụng theo các nội suy này sẽ gây ra sai số lớn. Do đó, cần phải sử dụng
một phương pháp nội suy khác sao cho phù hợp với hiện tượng vật lý quan sát và
không quá phức tạp thuật toán.
Trong mục này, ta nghiên cứu phương pháp nội suy spline, nó có thể đáp ứng
được một số bài toán trong thực tế.
Phương pháp Spline nội suy bằng cách gắn một số đa thức bậc thấp với nhau; ở
đây chỉ nghiên cứu nội suy Spline bậc 3, vì thường đáp ứng yêu cầu trong nhiều bài
toán thực tế và lời giải không phức tạp lắm.

38
Hình vẽ bên chỉ ra nội suy 4 điểm bằng cách dùng 3 hàm bậc 3 (cubic): f1(x),
f2(x), f3(x). Tổng quát nếu có (n + 1) điểm, ta cần n hàm Spline bậc 3 dạng:
fi(x) = A1i + A2i x + A3i x2 + A4i x3 , i = 1,2,3, . . . , n
Có 4n hệ số Aji có thể xác định theo các điều kiện sau:
(i) Hàm Cubic phải gặp tất cả các điểm ở bên trong: có được 2n phương trình
fi(xi) = yi , i = 1, . . . n ; fi + 1(xi) = yi , i = 0,1, . . . n - 1
(ii) Đạo hàm bậc 1 phải liên tục tại các điểm bên trong, dẫn đến được (n – 1)
phương trình:
f’i(xi) = f’i + 1(xi), i = 1, 2,. . . ,n - 1
(iii) Đạo hàm bậc 2 cũng phải liên tục tại các điểm bên trong, thêm được (n – 1)
phương trình nữa:
f”i(xi) = f”i + 1(xi), i = 1,2, . . ., n-1
(iv) Hai điều kiện cuối cùng dựa vào 2 điểm cuối của đường Spline, ở đây thường
đặt f”1(x0) = 0 và f”n(xn) = 0.
Sắp xếp lại hàm fi(x), ta chỉ cần (n - 1) phương trình cần thiết để giải, có dạng:

f "( xi 1 )( xi  x)3 f "( xi )( x  xi 1 )3


y = fi(x) =  
6xi 6xi

y f "( xi 1 )xi   yi f "( xi )xi 


  i 1    xi  x       x  xi 1  (2.35)
 xi 6   xi 6 
Với xi = xi - xi – 1, với i = 1,2,…,n (dạng sai phân lùi).
Đạo hàm phương trình này và áp dụng điều kiện liên tục về đạo hàm bậc nhất ta
được:

xif”(xi - 1) + 2(xi + xi + 1).f”(xi) + xi + 1. f”(xi + 1) = 6   y i  y i 1  (2.36)


 x i  x i 1 

Với yi = yi – yi-1, với i = 1, 2, . . . , n – 1


Điều này tương đương với hệ phương trình tuyến tính có ẩn là đạo hàm bậc 2
tại các điểm bên trong của đường cong nội suy:

2(x1  x2 ) x2   f ( x1 ) 


"
0 0
 x2 2(x2  x3 ) x3 0  " 
   f ( x2 ) 
 . 
 0 x3 2(x3  x4 ) 0   

 0 0  2( xn 1  x   
n   f ( xn 1 ) 
) "

39
 y1 y2 
 x  x 
 1 2

 y2 y3 
  
= 6.  x2 x3  (2.37)
 
 
 yn 1 yn 
 x  x 
 n 1 n

Giải hệ đại tuyến này ta tìm được f”(xi), với i = 1, 2, . . . , n - 1 cộng với hai
điều kiện biên 2 đầu:
f”(x0) = f”(xn) = 0, đường cong nội suy sẽ hoàn toàn xác định.
Ví dụ. x 1 2 2,2 3 4

y 5 7 ? 10 12
Tìm y = f(x) theo phương pháp nội suy spline bậc 3 và tính y (x = 2,2) = ?
Giải:
Ta có: x1  x2  x3  1

y1  2; y2  3; y3  2

 2 3
2(1  1)1 
 f ''
( x1 
)   1  1 
.  ''   6 .  
1 2(1  1)  f ( x2 )    3  2 
 1 1 


4 f ( x1 )  f ( x2 )  6
" "
 f " ( x1 )  2
  "  "
 f ( x1 )  4 f ( x2 )  6
  f ( x2 )  2
"

y = f(x) = y = fi(x) =
 y f " ( x1 )x2 
f " ( x1 )( x2  x) 3 f " ( x2 )( x  x1 ) 3  y f " ( x2 )x2 
    1  x2  x    2  x  x1 
6x2 6x2  x2 6   x2 6 
2(3  x) 3 (2)( x  2) 3  7 2.1   10 (2).1 
    3  x     x  2
6.1 6.1 1 6  1 6 
(3  x) 3 ( x  2) 3 203  x  31x  2
   
3 3 3 3
Thay vào ta được, tại x = 2.2  y = 7.568

Ứng dụng lập trình


Dùng Matlab

40
Xây dựng hàm nội suy:
function y = cubicspline(xData, yData, x)
%Ham nay xap xi bang da thuc bac 3 spline
%Cu phap: [yi,f] = cubicspline(xData, yData, x)
n = length(xData);
c = zeros(n-1,1); d = ones(n, 1);
e = zeros(n-1,1); k = zeros(n, 1);
c(1:n-2) = xData(1:n-2) - xData(2:n-1);
d(2:n-1) = 2*(xData(1:n-2) - xData(3:n));
e(2:n-1) = xData(2:n-1) - xData(3:n);
k(2:n-1) = 6*(yData(1:n-2) - yData(2:n-1))...
./(xData(1:n-2) - xData(2:n-1))...
- 6*(yData(2:n-1) - yData(3:n))...
./(xData(2:n-1) - xData(3:n));
[c,d,e] = band3(c,d,e);
k = band3sol(c,d,e,k);
i = findseg(xData,x);
h = xData(i) - xData(i+1);
y = ((x - xData(i+1))^3/h - (x - xData(i+1))*h)*k(i)/6.0...
- ((x - xData(i))^3/h - (x - xData(i))*h)*k(i+1)/6.0...
+ yData(i)*(x - xData(i+1))/h...
- yData(i+1)*(x - xData(i))/h;

2.6. Phương pháp bình phương cực tiểu (Least squares method)

Trong nội suy đa thức, đòi hỏi đa thức phải đi qua cặp điểm quan sát. Trong
thực tế, có những hiện tượng vật lý mà các cặp điểm quan trắc này chưa chắc đã chính
xác, ví dụ quan hệ lượng mưa giữa hai trạm đo mưa nào đó, do đó việc tìm đường
cong nội suy qua các cặp điểm này không hẳn là phù hợp. Hoặc thông qua kết quả
thực nghiệm, ta mường tượng được công thức tính toán và dựa vào số liệu thực
nghiệm này ta xác định các tham số của công thức này sao cho sai số ít nhất.
Giả sử có các mẫu quan sát (xi, yi ) của hàm y = f(x). Ta chọn hàm f(x) có dạng:
f(x) = a0f0(x) + a1f1(x) + a2f2(x)... (2.38)

41
Trong đó các hàm f0(x), f1(x), f2(x) v.v… là (m + 1) hàm độc lập tuyến tính mà
ta có thể chọn tuỳ ý và các hệ số ai là tham số chưa biết mà ta phải xác định dựa vào hệ
hàm đã chọn và các điểm quan sát. Sai số giữa trị đo được và trị tính theo (2.38) là:
ei = yi - f(xi) (2.39)
Sai số này có thể âm hay dương tuỳ từng giá trị của yi. Khi dùng phương pháp
bình phương bé nhất ta xét bình phương của sai số tại một điểm:
ei2   yi  f ( xi )
2
(2.40)

Với n điểm tổng bình phương của sai số sẽ là:


n n
S   ei2   yi   a0 f 0 ( xi )  a1 f1 ( xi )    an f n ( xi )
2
(2.41)
i 1 i 1

Rõ ràng S là hàm của các giá trị cần tìm ai và chúng ta sẽ chọn các hệ số ai này
sao cho S đạt giá trị cực tiểu, nghĩa là các đạo hàm S phải bằng không. Ta đi xét một
a i

số trường hợp cụ thể.


2.6.1. Hàm xấp xỉ có dạng đa thức
Trong trường hợp ta chọn hệ hàm xấp xỉ là một đa thức, nghĩa là:
f(x) = a0 + a1x + a2x2 +...+ amxm (2.42)
Vậy hàm S là:
S   yi  a0  a1 x  a2 x    am x 
2
(2.43)

S
Theo điều kiện đạo hàm  0 ta nhận được hệ phương trình:
a i
 n m n n

 a m  xi  a m 1  x m 1
i      na 0   yi
 i 1 i 1 i 1

 n m 1 n n n

 m i  m 1  i      0 i  
m
a x a x a x xi yi
 i 1 i  1 i 1 i 1

 n m2 n n n

 m i m 1  i 0 i 
m 1
a x  a x      a x 2
 xi2 yi
 i 1 i 1 i 1 i 1 (2.44)
 n n n n
am  xim  3  am 1  xim  2      a0  xi3   xi3 yi
 i 1 i 1 i 1 i 1
  

 n 2m n n n

 m i m 1  i 0 i 
2 m 1
a x  a x      a x m
 xim yi
 i 1 i 1 i 1 i 1

Đây là một hệ phương trình tuyến tính. Giải hệ này ta sẽ nhận được các gía trị
ai. Sau đây là chương trình viết theo thuật toán trên.
42
Chương trình 5-4
//Xap xi da thuc
#include <conio.h>
#include <stdio.h>
#include <ctype.h>
#define max 11

void main()
{
int i,j,k,m,n,p,kp,t;
float a[max],x[max],y[max],y1[max];
float b[max][max];
char ok;
float s,sx,s1,c,d;

clrscr();
printf("PHUONG PHAP BINH PHUONG TOI THIEU");
printf("\n");
printf("Cho bac cua da thuc xap xi m = ");
scanf("%d",&m);
printf("So diem da cho n = ");
scanf("%d",&n);
for (i=1;i<=n;i++)
{
printf("x[%d] = ",i);
scanf("%f",&x[i]);
printf("y[%d] = ",i);
scanf("%f",&y[i]);
}
x[0]=1;
printf("\n");
printf("%4cBANG SO LIEU\n",' ');

43
printf("%8cx%30cy\n",' ',' ');
for (i=1;i<=n;i++)
printf("%4c%8.4f%20c%8.4f\n",' ',x[i],' ',y[i]);
ok=' ';
t=1;
flushall();
while (t)
{
printf("Co sua so lieu khong(c/k): ");
scanf("%c",&ok);
if (toupper(ok)=='C')
{
printf("Chi so cua phan tu can sua i = ");
scanf("%d",&i);
printf("Gia tri moi : ");
printf("x[%d] = ",i);
scanf("%f",&x[i]);
printf("y[%d] = ",i);
scanf("%f",&y[i]);
flushall();
}
if (toupper(ok)!='C')
t=0;
}
//for (i=0;i<=n;i++)
//a[i]=0.0;
printf("\n");
printf("CAC GIA TRI DA CHO");
printf("\n");
printf("X = ");
for (i=1;i<=n;i++)
printf("%c%8.3f",' ',x[i]);

44
printf("\n");
printf("Y = ");
for (i=1;i<=n;i++)
printf("%c%8.3f",' ',y[i]);
printf("\n");
for (p=0;p<=m;p++)
{
y1[p]=0.0;
for (i=1;i<=n;i++)
{
sx=1.0;
for (j=1;j<=p;j++)
sx*=x[i];
y1[p]+=y[i]*sx;
}
}
for (p=0;p<=m;p++)
for (k=0;k<=m;k++)
{
kp=k+p;
b[p][k]=0.0;
for (i=1;i<=n;i++)
{
sx=1.0;
for (j=1;j<=kp;j++)
sx*=x[i];
b[p][k]+=sx;
}
}
for (i=0;i<=m-1;i++)
{
c=1.0/b[i][i];

45
for (k=i+1;k<=m;k++)
{
d=b[i][k];
for (j=i+1;j<=m;j++)
b[k][j]-=b[i][j]*c*d;
y1[k]-=y1[i]*c*d;
b[i][k]*=c;
}
y1[i]*=c;
}
y1[m]/=b[m][m];
for (i=m-1;i>=0;i--)
for (j=i+1;j<=m;j++)
y1[i]-=b[i][j]*y1[j];
printf("\n");
printf("CAC HE SO CUA DA THUC CAN TIM");
printf("\n");
for (i=0;i<=m;i++)
printf("a[%d] = %10.5f\n",i,y1[i]);
getch();
}
Ví dụ. Với đa thức được chọn có dạng cụ thể là: y = a + bx + cx2
Ta có: yi - a - bxi – cxi2 =  i , với i = 1, 2,.., n ở đây  i sai số tại xi.

Do đó: S = ( yi  a  bxi  cxi2 ) 2 là tổng các bình phương của các sai số.
S phụ thuộc a và b, còn xi, yi ta đã biết rồi.
Mục đích của phương pháp bình phương cực tiểu là xác định a, b và c sao cho
sai số nhỏ nhất: S  Smin.
S S S
Như vậy:  0,  0 và 0
a b c
Ta có được hệ phương trình:

46
na  b  xi  c  xi 2   yi


a  xi  b  xi  c  xi   xi yi
2 3
(2.45)

       x i2i yi
3 4

2
 a xi b xi c xi

Giải hệ này tìm được a, b, c.


Ví dụ.
x 0,7 1,5 2,3 3,1 3,8
y 2,5 1,2 1,7 2,4 4,3

Lập công thức nghiệm hàm y dạng y = a + bx + cx2.


Giải.
Lập bảng :
i x y xo x1 x2 x3 x4 Tk
0 0.7 2.5 1 0.7 0.49 0.34 0.24 11.60
1 1.5 1.2 1 1.5 2.25 3.38 5.06 30.09
2 2.3 1.2 1 2.3 5.29 12.17 27.98 95.43
3 3.1 2.4 1 3.1 9.61 29.79 92.35
4 3.8 4.3 1 3.8 14.44 54.87 208.51
S 5.00 11.40 32.08 100.55 334.15

5a  11,4b  32.08c  11.6 a  4,7


 
11.4a  32.08b  100.55c  30.4  b  3,8
32.08a  100.55b  334.15c  95.43 c  0,98
 
Ta được y = 0,98x2 – 3,8x + 4,7.
2.6.2. Hàm dạng Aecx
Khi các số liệu thể hiện một sự biến đổi đơn điệu ta dùng hàm xấp xỉ là
y = Aecx. Lấy logarit hai vế ta có:
lny = lnA + cxlne (2.46)
S
Theo điều kiện đạo hàm  0 , ta có hệ phương trình:
a i
 n n

 c 
 i 1
xi  n ln A  
i 1
ln yi
 n n n
(2.47)
c x 2  ln A x  x ln y
 i 1
i 
i 1
i 
i 1
i i

47
Giải hệ phương trình này ta có các hệ số A và c:
Chương trình 5-5
//xap_xi_e_mu;
#include <conio.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#define max 11
void main()
{
int i,n,t;
float x[max],y[max];
char ok;
float a,b,c,d,e,f,d1,d2,d3;

clrscr();
printf("PHUONG PHAP BINH PHUONG TOI THIEU");
printf("\n");
printf("So diem da cho n = ");
scanf("%d",&n);
for (i=1;i<=n;i++)
{
printf("x[%d] = ",i);
scanf("%f",&x[i]);
printf("y[%d] = ",i);
scanf("%f",&y[i]);
}
x[0]=1.0;
printf("%4cBANG SO LIEU\n",' ');
printf("%8cx%30cy\n",' ',' ');
for (i=1;i<=n;i++)
printf("%4c%8.4f%23c%8.4f\n",' ',x[i],' ',y[i]);

48
ok=' ';
t=1;
while (t)
{
printf("Co sua so lieu khong(c/k): ");
scanf("%c",&ok);
if (toupper(ok)=='C')
{
printf("Chi so cua phan tu can sua i = ");
scanf("%d",&i);
printf("Gia tri moi : ");
printf("x[%d] = ",i);
scanf("%f",&x[i]);
printf("y[%d] = ",i);
scanf("%f",&y[i]);
}
if (toupper(ok)!='C')
t=0;
}
printf("CAC GIA TRI DA CHO");
printf("\n");
printf("X = ");
for (i=1;i<=n;i++)
printf("%c%8.3f",' ',x[i]);
printf("\n");
printf("Y = ");
for (i=1;i<=n;i++)
printf("%c%8.3f",' ',y[i]);
printf("\n");
a=0.0;
for (i=1;i<=n;i++)
a+=x[i];

49
b=n;
c=0.0;
for (i=1;i<=n;i++)
c+=log(y[i]);
d=0.0;
for (i=1;i<=n;i++)
d+=x[i]*x[i];
e=0.0;
for (i=1;i<=n;i++)
e+=x[i]*log(y[i]);
d1=a*a-d*b;
d2=c*a-e*b;
d3=a*e-c*d;
c=d2/d1;
a=d3/d1;
printf("\n");
printf("He so A = %8.4f",exp(a));
printf(" va so mu c = %8.4",c);
printf("\n");
printf("\nBANG CAC GIA TRI TINH TOAN");
printf("\n");
printf("%5cx%28cy\n",' ',' ');
for (i=1;i<=n;i++)
{
printf("%8.4f%21c%8.4f\n",x[i],' ',exp(a)*exp(c*x[i]));
}
getch();

Áp dụng. Cho các giá trị x, y đo được theo bảng sau:

x 0 2 4 6 8 10 12

y 1280 635 324 162 76 43 19


50
Ta có n = 7 và dùng chương trình tính được các hệ số: A = 1285.44 và c = -
0.3476 và hàm xấp xỉ sẽ là: f(x) = 1285.44
2.6.3. Hàm dạng Axq
Khi các số liệu thể hiện một sự biến đổi đơn điệu ta cũng có thể dùng hàm xấp
xỉ là y = Axq. Lấy logarit hai vế ta có:
lny = lnA + qlnx (2.48)
Theo điều kiện đạo hàm triệt tiêu ta có hệ phương trình :
 n n

  i
q ln x  n ln A   ln yi
 i 1 i 1
 n n n
(2.49)
q ln 2 x  ln A ln x  ln x ln y
 i 1
i 
i 1
i  i 1
i i

Giải hệ phương trình này ta có các hệ số A và q:


Chương trình 5-6
//xap_xi_x_mu;
#include <conio.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#define max 11

void main()
{
int i,n,t;
float x[max],y[max];
char ok;
float a,b,c,d,e,f,d1,d2,d3;

clrscr();
printf("PHUONG PHAP BINH PHUONG TOI THIEU");
printf("\n");
printf("So diem da cho n = ");
scanf("%d",&n);

51
for (i=1;i<=n;i++)
{
printf("x[%d] = ",i);
scanf("%f",&x[i]);
printf("y[%d] = ",i);
scanf("%f",&y[i]);
}
x[0]=1.0;
printf("%4cBANG SO LIEU\n",' ');
printf("%8cx%30cy\n",' ',' ');
for (i=1;i<=n;i++)
printf("%4c%8.4f%23c%8.4f\n",' ',x[i],' ',y[i]);
ok=' ';
flushall();
t=1;
while (t)
{
printf("Co sua so lieu khong(c/k): ");
scanf("%c",&ok);
if (toupper(ok)=='C')
{
printf("Chi so cua phan tu can sua i = ");
scanf("%d",&i);
printf("Gia tri moi : ");
printf("x[",i,"] = ");
scanf("%f",&x[i]);
printf("y[%d] = ",i);
scanf("%f",&y[i]);
}
if (toupper(ok)!='C')
t=0;
}

52
printf("\n");
printf("\nCAC GIA TRI DA CHO");
printf("\n");
printf("X = ");
for (i=1;i<=n;i++)
printf("%c%8.3f",' ',x[i]);
printf("\n");
printf("Y = ");
for (i=1;i<=n;i++)
printf("%c%8.3f",' ',y[i]);
printf("\n");
a=0.0;
for (i=1;i<=n;i++)
a+=log(x[i]);
b=n;
c=0.0;
for (i=1;i<=n;i++)
c+=log(y[i]);
d=0.0;
for (i=1;i<=n;i++)
d+=log(x[i])*log(x[i]);
e=0.;
for (i=1;i<=n;i++)
e+=log(x[i])*log(y[i]);
d1=a*a-d*b;
d2=c*a-e*b;
d3=a*e-c*d;
c=d2/d1;
a=d3/d1;
printf("\n");
printf("He so A = %8.4f",exp(a));
printf(" va so mu q = %8.4f\n",c);

53
printf("\n");
printf("\nBANG CAC GIA TRI TINH TOAN\n");
printf("%5cx%27cy\n",' ',' ');
for (i=1;i<=n;i++)
{
printf("%8.4f%20c%8.4f\n",x[i],' ',exp(a)*exp(c*log(x[i])));
}
getch();
}
Áp dụng. Với các giá trị x,y khảo sát cho ở bảng sau:

x 1 2 4 5 6
y 7.1 27.8 62.1 110 161

Ta có n = 5 và sử dụng chương trình nầy, tính được các hệ số: A = 7.1641 và


q = 1.9531 và hàm xấp xỉ sẽ là: f(x) = 1285.44 x1.9531
2.6.4. Hàm lượng giác

Trường hợp quan hệ y = f(x) có dạng hàm tuần hoàn, ta nên dùng hàm xấp xỉ là
tổ hợp tuyến tính của các hàm sin và cosin có dạng:
n n

y = f ( x)  a 0  a i 1
i cos(ix)   bi sin(ix)
i 1
(2.50)

Để đơn giản, ta xét trường hợp hàm f(x) này có chỉ số i = 1


f ( x)  a0  a1 cos x  b1 sin x (2.51)
Sai số ở dạng bình phương:
n
E   [ yi  (a0  a1 cos x  b1 sin x)]2 (2.52)
i 1

Đạo hàm E triệt tiêu theo các biến a0, a1, b1 ta có:
n

 cos x  sin x  a
 0  y 
  
 cos x      .a 1   y cos x 
2
cos x cos x sin x
     (2.53)
 sin x  cos x sin x  sin x  b   y sin x 
2

Do :

54
 sin x  0 ;
 cos x  0
n n
 sin 2 x 
1
;
 cos 2 x 
1
n 2 n 2
 cos x sin x  sin x 2

 0
n
Nên hệ phương trình (2.53) có dạng đơn giản:
 
n 0 0
  a 0   y 
0 n    
0.a1    y cos x 
 2    
 y sin x 
 (2.54)
n  
b
0 0 
 2

Giải hệ này ta được:

y 2 2
a0 
n
; a1 
n
 y cos x ; b1 
n
 y sin x ;
Tương tự cho trường hợp tổng quát:

y 2 2
a0 
n
; ai 
n
 y cos ix ; bi 
n
 y sin ix ;
Chương trình tìm các hệ số ai và bi được viết như sau:
Chương trình 5-7
//xap_xi_sin_cos;
#include <conio.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#define max 11
#define pi 3.15159

void main()
{
int i,j,m,n,t;

55
float x[max],y[max],a[max],b[max];
char ok;
float omg,t1;

clrscr();
printf("PHUONG PHAP BINH PHUONG TOI THIEU");
printf("\n");
printf("Cho so so hang sin-cos m = ");
scanf("%d",&m);
printf("Cho chu ki T = ");
scanf("%f",&t1);
printf("So diem da cho n = ");
scanf("%d",&n);
for (i=1;i<=n;i++)
{
printf("x[%d] = ",i);
scanf("%f",&x[i]);
printf("y[%d] = ",i);
scanf("%f",&y[i]);
}
x[0]=1.0;
printf("%4cBANG SO LIEU\n",' ');
printf("%8cx%30cy\n",' ',' ');
for (i=1;i<=n;i++)
printf("%4c%8.4f%23c%8.4f\n",' ',x[i],' ',y[i]);
ok=' ';
t=1;
flushall();
while (t)
{
printf("Co sua so lieu khong(c/k): ");
scanf("%c",&ok);

56
if (toupper(ok)=='C')
{
printf("Chi so cua phan tu can sua i = ");
scanf("%d",&i);
printf("Gia tri moi : ");
printf("x[%d] = ",i);
scanf("%f",&x[i]);
printf("y[%d] = ",i);
scanf("%f",&y[i]);
flushall();
}
if (toupper(ok)!='C')
t=0;
}
printf("\nCAC GIA TRI DA CHO\n");
printf("\n");
printf(" X Y\n");
for (i=1;i<=n;i++)
printf("%c%8.3f%c%8.3f\n",' ',x[i],' ',y[i]);

printf("\n");
a[0]=0.0;
omg=2*pi/t1;
for (i=1;i<=n;i++)
a[0]+=y[i];
a[0]/=n;
for (j=1;j<=m;j++)
{
a[j]=0.0;
for (i=1;i<=n;i++)
a[j]+=y[i]*cos(j*omg*x[i]);
a[j]=2*a[j]/n;

57
}
for (j=1;j<=m;j++)
{
b[j]=0.0;
for (i=1;i<=n;i++)
b[j]+=y[i]*sin(j*omg*x[i]);
b[j]=2*b[j]/n;
}
printf("\n");
printf("TAN SO GOC OMEGA = %10.5f\n",omg);
printf("HE SO HANG\n");
printf("a[0] = %8.4f\n",a[0]);
printf("CAC HE SO BAC CAO\n");
printf("%5ccos%25csin\n",' ',' ');
for (i=1;i<=m;i++)
printf("%8.4f%21c%6.4f\n",a[i],' ',b[i]);
getch();
}
Áp dụng. Với hàm cho ở bảng số như sau:

x 0 0.15 0.3 0.45 0.6 0.75 0.9 1.05 1.2 1.3


y 2.2 1.595 1.031 0.722 0.786 1.2 1.81 2.369 2.678 2.614

Chọn số hệ số sin - cosm = 1, số điểm cho trước n = 10, chu kì T = 15 ta nhận


được kết quả tính a0 = 1.7, a1 = 0.5, b1 = -0.8661 và  = 4.18879. Như vậy hàm xấp xỉ
có dạng:
f(x) = 1.7 + 0.5cos(4.18879x) - 0.8661sin(4.18879x)
2.6.5. Hàm hữu tỉ
Khi quan hệ y = f(x) có dạng đường cong bão hoà hay dạng arctan, tan v.v ta
dùng hàm xấp xỉ là hàm hữu tỉ dạng đơn giản:
ax
y (2.55)
b x
Lấy nghịch đảo của nó ta có :

58
1 b1 1
  (2.56)
y ax a

Đặt 1/y = Y, 1/x = X, b/a = B và 1/a = A phương trình trên sẽ có dạng:


Y = A + BX (2.57)
Và là một đa thức bậc một. Do vậy ta có hệ phương trình đối với các hệ số A và
B là:
 n
1 n
1


nA  B 
i 1 xi
 i 1 yi
 n n n
(2.58)
A 1  B 1 1

 i1 xi i 1 xi
2
  i 1 xi yi

Và từ đó tính được a và b.
Chương trình viết theo thuật toán ở trên được cho như sau:
Chương trình 5-8
//xap xi huu_ty;
#include <conio.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#define k 11
void main()
{
float x[k],y[k];
float a,b,a1,b1,c,d,e;
int i,n,t;
char ok;

clrscr();
printf("PHUONG PHAP BINH PHUONG TOI THIEU");
printf("\n");
printf("So diem da cho n = ");
scanf("%d",&n);
for (i=1;i<=n;i++)
{
59
printf("x[%d] = ",i);
scanf("%f",&x[i]);
printf("y[%d] = ",i);
scanf("%f",&y[i]);
}
printf("%4cBANG SO LIEU\n",' ');
printf("%8cx%30cy\n",' ',' ');
for (i=1;i<=n;i++)
printf("%4c%8.4f%23c%8.4f\n",' ',x[i],' ',y[i]);
ok=' ';
t=1;
flushall();
while (t)
{
printf("Co sua so lieu khong(c/k): ");
scanf("%c",&ok);
if (toupper(ok)=='C')
{
printf("Chi so cua phan tu can sua i = ");
scanf("%d",&i);
printf("Gia tri moi : ");
printf("x[%d] = ",i);
scanf("%f",&x[i]);
printf("y[%d] = ",i);
scanf("%f",&y[i]);
flushall();
}
if (toupper(ok)!='C')
t=0;
}
printf("CAC GIA TRI DA CHO\n");
printf("\n");

60
printf("X = ");
for (i=1;i<=n;i++)
printf("%c%8.3f",' ',x[i]);
printf("\n");
printf("Y = ");
for (i=1;i<=n;i++)
printf("%c%8.3f",' ' ,y[i]);
printf("\n");
a=n;
b=0.0;
c=0.0;
d=0.0;
e=0.0;
for (i=1;i<=n;i++)
{
b+=1/x[i];
c+=1/y[i];
d+=1/(x[i]*x[i]);
e+=1/(x[i]*y[i]);
}
a1=(c*d-b*e)/(a*d-b*b);
b1=(a*e-b*c)/(a*d-b*b);
a=1/a1;
b=b1*a;
printf("\n");
printf("Cac he so cua ham huu ty\n");
printf("a = %10.5f b = %10.5f",a,b);
getch();
}

61
Áp dụng. Với dãy số liệu cho như sau:

x 1 2 3 4 5
y 0.3333333 0.5 0.6 0.66666 0.7142857

Ta nhận được từ chương trình trị số a = 1 và b = 2.

Câu hỏi:
1) Ưu nhược điểm của các phương pháp nội suy Lagrange, Newton, Spline,
Hermite ?
2) Hãy chỉ ra những trường hợp cụ thể và cách chọn phương pháp nội suy nào
thích hợp nhất ?
3) Phương pháp bình phương cực tiểu thường được áp dụng khi nào? Tại sao
người ta nói phương pháp này mang tính chủ quan của người sử dụng tính toán?
Một cách chính xác có gọi phương pháp này là nội suy được không ?

ài tập:

Nội suy Lagrange


1) Xây dựng đa thức nội suy Lagrange của hàm số y = f(x) cho dưới dạng bảng
sau:
x 0 2 3 5

y 1 3 2 5
2) Cho bảng giá trị của hàm số y = f(x)
x 321.0 322.8 324.2 325.0

y 2.50651 2.50893 2.51081 2.51188


Tính gần đúng f(323.5) bằng đa thức nội suy Lagrange.
3) Thành lập đa thức nội suy Lagrange từ bảng số sau:
x 2 4 6 8 10

y 0 3 5 4 1

62
4) Hãy đánh giá sai số nhận được khi xấp xỉ hàm số y = sinx bằng đa thức nội suy
Lagrange bậc 5: L5(x), biết rằng đa thức này trùng với hàm số đã cho tại các giá trị x
bằng: 00, 50, 100, 150, 200, 250. Xác định giá trị của sai số khi x = 12030’.
5) Tìm đa thức nội suy bậc 2 của hàm y = 3x trên đoạn  1,1 , từ đó suy ra giá trị

gần đúng của 3 .


6) Dùng đa thức nội suy Lagrange bậc 1 và 2 để đánh giá ln2 dựa trên số liệu:

x0 = 1 f(x0) = 0
x1 = 4 f(x1) = 1,386294
x2 = 6 f(x0) = 1,791760

Đáp số:
62 3 13
1) 1+ x + x3 - x2
15 10 6
2) 2,50987
1 4
3) f(x)= ( x  26 x 3  220 x 2  664 x  640)
32
1     5
4) sin( x)  L5 ( x)  x( x  )( x  )( x  )( x  )( x  ) , khi x=12030’
6! 36 18 12 9 36

thì sin(12 0 30'L5 (12 0 30' )  2,2.10 9

5) Để được đa thức nội suy bậc 2 thì cần 3 mốc: Ở đây ta chọn x0 = -1, 0, 1 thì

y=3x  (4 x 2  8 x  6) trên đoạn  1,1 , và 3  1,8


1
6
6) f2(2) = 0,5658444

Nội suy Newton:


1) Cho bảng giá trị của hàm số y = f(x)
x -1 0 3 6 7

y 3 -6 39 822 1611

a) Xây dựng đa thức nội suy Newton tiến xuất phát từ nút x0 = -1 của hàm số

63
y = f(x).
b) Dùng đa thức nội suy nhận được, tính gần đúng f(-0.25).
2) Cho bảng giá trị của hàm số y = sinx
x 0,1 0,2 0,3 0,4

y 0,09983 0,19867 0,29552 0,38942


a) Dùng đa thức nội suy tiến xuất phát từ nút x0 = 0,1 tính gần đúng sin(0,14)
b) Dùng đa thức nội suy lùi xuất phát từ nút x0 = 0,4 tính gần đúng sin(0,46)
3) Xây dựng đa thức nội suy Newton tiến xuất phát từ bảng số (x0 = 0).
x 0 2,5069 5,0154 7,5270

y 0,3989423 0,3988169 0,3984408 0,39781138


3x  x 3 x2
4) Cho giá trị của hàm số y = arctg - 3arctgx + (2 ln x  3) theo bảng số
1  3x 2 4
sau:
x 58 58,17 58,34 58,68 59,02 59,36 59,7

y 4303,52 ? 4364,11 4425,17 4486,69 4548,69 4611,16


Xây dựng đa thức nội suy Newton tiến và tính gần đúng giá trị của y tại x = 58,17.
5) Cho hàm như bảng sau:

x 0.1 0.2 0.3 0.4


y 0.09983 0.19867 0.29552 0.38942

Ta tính giá trị của hàm tại 0.14 bằng đa thức nội suy Newton với các mốc cách
đều h = 0.1.
6) Cho các giá trị dưới đây ước tính giá trị ln2 dùng nội suy đa thức Newton bậc 3:
x0 = 1 f(x0) = 0
x1 = 4 f(x1) = 1,386294
x2 = 6 f(x0) = 1,791760

Đáp số:
1) a) x4 - 3x3 + 5x2 - 6
b) -5,6367188
64
2) a) sin(0,14)  0,1395434
b) sin(0,46)  0,4439446
3) f(x)  0,3989423 - 0,0000500x - 0,0000199x(x - 2,5069)
0,47 t (t  1)(t  2) t (t  1)(t  2)(t  3)
4) y = 4303,52+60,59t+ t(t-1)-0,01 +0,03 -
2! 3! 4!
t (t  1)(t  2)(t  3)(t  4)
- 0,06
5!
x  58
Trong đó: t = ; y(x = 58,17) = 4333,75779688
0,34
5) y = 0,13954
6) f3(x) = 0,462098(x-1) – 0,05187311(x-1)(x-4) + 0,007865529(x-1)(x-4)(x-6)
f3(2) = 0,6287656

Nội suy Hermite


1) Sử dụng nội suy Hermite để xây dựng một đa thức xấp xỉ cho theo dữ liệu
như sau:
a)

x f(x) f’(x)

8.2 16.9692 3.016256

8.7 19.10515 3.171762


b)

x f(x) f’(x)

0.1 −0.72049958 3.68502082


0.2 −0.38398668 3.24033271
0.3 0.00760095 2.76668043
0.4 0.34842440 2.26529366

2) a) Sử dụng các giá trị và số làm tròn có năm chữ số sau để xây dựng
đa thức nội suy Hermite xấp xỉ sin0,34.

65
x sinx Dxsinx = cosx

0.30 0.29552 0.95534


0.32 0.31457 0.94924
0.35 0.34290 0.93937

b) Xác định sai số giới hạn cho xấp xỉ ở phần (a) và so sánh với sai số
hiện tại.
c) Thêm sin0.33 = 0.32404 và cos0.33 = 0.94604 dữ liệu và lặp lại tính toán
3) Theo bảng dữ liệu cho hàm được mô tả bởi f  x   e0.1x . Xấp xỉ f(1.25) bằng
2

cách sử dụng H5 (1.25) và H3 (1.25), với H5 sử dụng nút x0 = 1, x1 = 2, x2 = 3 và H3 sử


dụng các nút x0 = 1 và x1 = 1,5. Tìm giới hạn sai số cho những xấp xỉ này.

f  x   e0.1x f '  x   0, 2e0.1x


2 2
x

x0= x0 = 1 1.105170918 0.2210341836

x1 = 1,5 1.252322716 0.3756968148

x1 = 2 1.491824698 0.5967298792
x2 = 3 2.459603111 1.475761867

4) Cho f(x) = 2xex − e2x.


a) Xấp xỉ f(1.05) bởi đa thức nội suy Hermite tối đa bậc 3 bằng cách sử
dụng x0 = 1 và x1 = 1.10. So sánh sai số hiện tại với sai số giới hạn cho
phép.
b) Lặp lại (a) với đa thức nội suy Hermite bậc nhiều nhất là 5, sử dụng
x0 = 1, x1 = 1.07, và x2 = 1.10.
5) Một chiếc xe đi khách đi trên một con đường thẳng có tốc độ xung tại một số
điểm. Các dữ liệu từ các quan sát được đưa cho trong bảng dưới đây:

Thời gian (second) 0 4 6 9 15

Khoảng cách (m) 0 250 410 725 1130

Tốc độ (m/s) 85 87 90 85 82

66
a) Sử dụng đa thức Hermite để dự đoán vị trí của xe và tốc độ của xe khi
t = 12s.
b) Sử dụng đạo hàm của đa thức Hermite để xác định liệu xem xe có vượt
quá giới hạn tốc độ giới hạn 60 km / h trên đường. Nếu vậy, khi nào
chiếc xe vượt quá tốc độ này lần đầu?
c) Tốc độ tối đa được dự đoán cho xe là bao nhiêu ?
d)

Nội suy spline và phương pháp bình phương cực tiểu:


1) Dựng hàm spline bậc 3, xấp xỉ hàm y = 3x trên đoạn  1;1 , lấy với h =1, từ đó

suy ra 3 3 .
2) Cho hàm số y = sinx trên đoạn 0;  . Hãy lập hàm spline bậc 3 để xấp xỉ

hàm sinx trên đoạn đã cho, với các mốc nội suy x0 = 0, ,.
2
3) Cho hàm dưới dạng bảng:

x 1 2 3 4 5

y 0 1 0 1 0

Tìm giá trị của hàm tại x = 1.5

4) Cho hàm dưới dạng bảng:


x 3 4,5 5 7

y 2,5 1 ? 2,5

Tìm y = f(x) theo phương pháp nội suy spline bậc 3 và tính y(5) = ?

5) Cho bảng các giá trị:


x 2 4 6 8 10 12

y 7,32 8,24 9,20 10,19 11,01 12,05

67
Hãy tìm công thức thực nghiệm có dạng y = a + bx.
6) Cho bảng giá trị:
x 0,78 1,56 2,34 3,12 3,81

y 2,50 1,20 1,12 2,25 4,28


Hãy tìm công thức thực nghiệm có dạng y = a + bx + cx2
Đáp số:
3) y(1,5) = 0,7679
4) f2(x) = 0,111939(7 - x)3 – 0,102205(x - 4,5)3 – 0,299621(7 - x) +
+ 1,638783(x - 4,5)
f2(5) = 1,102886
5) y = 6,3733333 + 0,4707143x
6) y= 0,992 - 0,909

68
Chương 3 TÍNH GẦN ĐÚNG ĐẠO HÀM
VÀ TÍCH PHÂN
NUMERICAL DIFFERENTIATION
AND INTEGRATION

Trong nhiều bài toán kỹ thuật, ví dụ khi cần tính tích phân trong phương phương
số phần tử hữu hạn, phần tử biên… thường chúng không được nhận được kết quả bởi giải
tích; lúc đó người ta hay sử dụng các phương pháp tính gần đúng.
3.1. Tính gần đúng đạo hàm
Ta biểu diễn hàm f(x) bằng đa thức nội suy: f(x) = P(x), với P(x) là đa thức nội
suy (đa thức nội suy tiện lợi là spline bậc 3); Tiếp theo ta tính gần đúng đạo hàm f ’(x) ở
đa thức này:
f’(x) = P’(x)
Ta cũng có thể áp dụng khai triển Taylor:
h2
f(x + h) = f(x) + h f’(x) + f”(c), với c = x + h, 0 <  < 1
2!
f (x  h)  f (x)
Từ đó ta tính được: f’(x) 
h
3.1.1. Đạo hàm ROMBERG
Đạo hàm ROMBERG là một phương pháp ngoại suy để xác định đạo hàm với độ
chính xác cao theo mong muốn.
Để nhận được đạo hàm theo phương pháp này, ta sử dụng khai triển Taylor hàm
f(x) tại (x + h) và (x – h):
h 2 '' h3 h 4 ''
f ( x  h)  f ( x)  h. f ' ( x)  f ( x)  f ' ' ' ( x)  f ( x)  ... (3.1)
2! 3! 4!
h 2 '' h3 h 4 ''
f ( x  h)  f ( x)  h. f ' ( x)  f ( x)  f ' ' ' ( x)  f ( x)  ... (3.2)
2! 3! 4!
Trừ (3.1) cho (3.2), ta được:
h3 h 5 (v)
f ( x  h)  f ( x  h)  2h. f ' ( x)  2 f ' ' ' ( x)  2 f ( x)  ... (3.3)
3! 5!
Từ (3.3) ta rút ra f ’(x):
69
f ( x  h )  f ( x  h) h2 h 4 (v)
f ' ( x)   f ' ' ' ( x)  f ( x)  ... (3.4)
2h 3! 5!
Hay ta có thể viết lại:
1
f ' ( x)  [ f ( x  h)  f ( x  h)]  a 2 h 2  a4 h 4  a6 h 6  ... (3.5)
2h
Trong biểu thức (3.5), các hệ số ai phụ thuộc vào f và x.
Ta đặt :
1
 (h)  [ f ( x  h)  f ( x  h)] (3.6)
2h
Như vậy, từ (3.5) và (3.6) ta được :
D(1,1)   (h)  f ' ( x)  a2 h 2  a4 h 4  a6 h 6  ... (3.7)

Thay h = h/2 , ta có:


h h2 h4 h6
D(2,1)   ( )  f ' ( x)  a 2  a4  a6  ... (3.8)
2 4 16 64
Tổng quát, nếu thay h trong (3.7) bằng h = hi = h / 2i-1 , ta được:
D(i,1)   (hi )  f '( x)  a2hi 2  a4hi 4  a6hi 6  ... (3.9)

Để tạo ra sai phân có độ chính xác cao hơn, ta lấy D(1,1) – 4.D(2,1), được :
h 3 15
 (h)  4 ( )   3 f '( x)  a4 h4  a6 h6  ... (3.10)
2 4 16
Chia hai vế của (3.10) cho -3, ta được:
4 D(2,1)  D(1,1) 1 5
D(2, 2)   f '( x)  a4 h4  a6 h6  ... (3.11)
3 4 16
Đối chiếu các biểu thức (3.7), (3.8), (3.9) với biểu thức (3.11), ta nhận thấy:
D(i, 1) sai khác với f ’(x) bậc h2, trong khi D(2, 2) sai khác với f ‘(x) bậc 0(h)4.
Bây giờ, nếu chia đôi bức h, ta sẽ nhận được:
4 6
1 h 5 h
D(3, 2)  f '( x)  a4    a6    ... (3.12)
4  2  16  2 

Và để khử số hạng h4 , ta lấy (3.11) – 16.(3.12), được:


15
D(2, 2)  16 D(3, 2)   15 f '( x)  a6 h6  ... (3.13)
64
Ta đi chia hai vế của (3.13) cho -15, được:

70
16 D(3, 2)  D(2, 2) 1
D(3,3)   f '( x)  a6 h6  ... (3.14)
15 64
Với (3.14), ta thấy sai số bậc 0(h)6.
Nếu ta tiếp tục chia đôi bức h và tính D(4, 4) thì sai số của đạo hàm f ’(x) là bậc
0(h)8.
Một cách truy hồi, ta có sơ đồ tính đạo hàm theo phương pháp ROMBERG như
sau:
D(1,1)
D(2,1) D(2,2)
D(3,1) D(3,2) D(3,3)
D(4,1) D(4,2) D(4,3) D(4,4)
………………………………………….....
D(n,1) D(n,2) D(n,3) D(n,4) ........ D(n,n)
Trong đó, mỗi giá trị sau có được bằng cách ngoại suy các giá trị trước nó ở hàng
trên.
Với : 2 ≤ j ≤ i ≤ n ; ta có công thức tổng quát:
4 j 1 D(i, j  1)  D(i  1, j  1)
D(i, j )  (3.15)
4 j 1  1

Và giá trị khởi đầu là:


1
D(i, j )   (hi )  [ f ( x  hi )  f ( x  hi )] (3.16)
2hi

Với hi = h / 2i-1
Như vậy phương pháp ROMBERG có thể cho phép tính đạo hàm với độ chính xác
tùy ý; trong thực hành khi hai lần tính đạo hàm liên tiếp, nếu sai số nhỏ hơn sai số cho
phép, thì chương trình tính sẽ dừng lại.
Ví dụ. Tìm đạo hàm của hàm f(x) = x2 + arctan(x) tại x = 2 với bước tính h = 0.5.
Trị chính xác của đạo hàm là 4.2

1
D(1,1)  [ f (2.5)  f (1.5)]  4.207496266
2  0.5
1
D(2,1)  [ f (2.25)  f (1.75)]  4.201843569
2  0.25

71
1
D(3,1)  [ f (2.125)  f (1.875)]  4.200458976
2  0.125

4 D(2,1)  D(1,1)
D(2, 2)   4.19995935
4 1
4 D(3,1)  D(2,1)
D(3, 2)   4.200458976
4 1
42 D(3, 2)  D(2, 2)
D(3,3)   4.200492284
42  1
Chương trình tính đạo hàm như dưới đây. Dùng chương trình tính đạo hàm của
hàm cho trong function với bước h = 0.25 tại xo = 0 ta nhận được giá trị đạo hàm là
1.000000001.
Ứng dụng lập trình
(i) Dùng C++
//Daoham_Romberg;
#include <conio.h>
#include <stdio.h>
#include <math.h>
#define max 11
float h;
void main()
{
float d[max];
int j,k,n;
float x,p;

float y(float),dy(float);
clrscr();
printf("Cho diem can tim dao ham x = ");
scanf("%f",&x);
printf("Tinh dao ham theo phuong phap Romberg\n");
printf("cua ham f(x) = th(x) tai x = %4.2f\n",x);
n=10;

72
h=0.2;
d[0]=dy(x);
for (k=2;k<=n;k++)
{
h=h/2;
d[k]=dy(x);
p=1.0;
for (j=k-1;j>=1;j--)
{
p=4*p;
d[j]=(p*d[j+1]-d[j])/(p-1);
}
}
printf("y'= %10.5f\n",d[1]);
getch();
}

float y(float x)
{
float a=(exp(x)-exp(-x))/(exp(x)+exp(-x));
return(a);
}

float dy(float x)
{
float b=(y(x+h)-y(x-h))/(2*h);
return(b);
}

73
(ii) Dùng Matlab
Xây dựng hàm:
function df = diffromberg(f, x, h, maxiter, tol)
%Tinh dao ham bang phuong phap Romberg
D(1, 1) = (feval(f,x+h) - feval(f, x-h))/(2*h);
for i = 1:maxiter
h = h/2;
D(i + 1, 1) = (feval(f,x+h) - feval(f, x-h))/(2*h);
for j = 1:i
D(i + 1, j + 1) = (4^j*D(i + 1, j) - D(i, j))/(4^j - 1);
end
if (abs( D(i + 1, i + 1) - D(i, i) ) < tol)
df = D(i+1, i+1);
break;
elseif ( i == maxiter )
error( 'Ngoai suy Richardson khong hoi tu' );
end
end

Áp dụng. Tìm đạo hàm của hàm f ( x)  x2  2 xe x  1 tại x = 2 với bước tính h = 0.5.
Kết quả tính đạo hàm là 48.334.
Để tính đạo hàm của hàm cho trước ta dùng chương trình:
clear all, clc
format long;
f = inline('x^2 + 2*x*exp(x) + 1');
x = 2;
h = 0.5;
tol = 1e-6;
maxiter = 10;
df = diffromberg(f, x, h, maxiter, tol)

74
3.2. Tính gần đúng tích phân xác định
3.2.1. Công thức hình thang
Trong từng khoảng chia (i, i+1), đường cong Mi, Mi+1 được xấp xỉ thành đường
thẳng.
Đối với tích phân thứ (i + 1), ta có:
f(x)

x i 1 f(b)
y  yi 1 y1

xi
f ( x )dx  h i
2
f(a)
y0
b a
Với xi = a + ih, h = ,
n
i = 1, 2, . . . . . , n; a = x0 , b = xn x0 x1 x
b x1 x2 xn

I=  f (x )dx   f (x )dx   f (x )dx ........ f (x )dx (3.17)


a x0 x1 x n 1

IT 
h
y 0  y1   (y1  y 2 )  ....... (y n1  y n )
2
(3.18)
 y  yn 
I T  h 0  y1  y 2  ....... y n1 
 2 
M 2
Sai số: I - IT   h ( b  a) , với M = max f”(x), a  x  b
12
Ví dụ. Dùng công thức hình thang tổng quát với n=10 để tính gần đúng:
1
dx
I=  1 x
0

Đánh giá những sai số của những giá trị gần đúng nhận được.
Giải:
1 0
Ta có: h= = 0,1
10
Kết quả tính toán trong bảng sau:

75
i xi yi
0 0 1,00000
1 0,1 0,90909
2 0,2 0,83333
3 0,3 0,76923
4 0,4 0,71429
5 0,5 0,66667
6 0,6 0,62500
7 0,7 0,58824
8 0,8 0,55556
9 0,9 0,52632
10 1,0 0,50000

 6,18773

Theo công thức hình thang tổng quát ta có:


1, 0000  0,50000
I  0,1( +0,90909+0,83333+0,76923+0,71429+0,66667+
2
+ 0,62500+0,58824+0,55556+0,52632) =0,69377.
Sai số R được xác định như sau:
M 2
I  IT = h (b  a) (3.19)
12

Với M = max f x'' 0< x < 1

1
f(x) = =(1+x)-1
1 x
f ' ( x) = -(1+x)-2
2
f '' ( x) = (-1)(-2)(1+x)-3 = Trong (0, 1) M = max f x'' = 2
(1  x) 3

2.(0,1) 2
R (1  0)  0, 00167 (3.20)
12

76
Ứng dụng lập trình
(i) Dùng C++
//tinh tich phan bang phuong phap hinh_thang;
#include <conio.h>
#include <stdio.h>
#include <math.h>

float f(float x)
{
float a=exp(-x)*sin(x);
return(a);
};
void main()
{
int i,n;
float a,b,x,y,h,s,tp;
clrscr();
printf("Tinh tich phan theo phuong phap hinh thang\n");
printf("Cho can duoi a = ");
scanf("%f",&a);
printf("Cho can tren b = ");
scanf("%f",&b);
printf("Cho so buoc n = ");
scanf("%d",&n);
h=(b-a)/n;
x=a;
s=(f(a)+f(b))/2;
for (i=1;i<=n;i++)
{
x=x+h;
77
s=s+f(x);
}
tp=s*h;
printf("Gia tri cua tich phan la : %10.6f\n",tp);
getch();
}
(ii) Dùng Matlab
Xây dựng hàm:
function J = trapezoid(f, a, b, maxiter, tol)
% Quy tac hinh thang lap.
% Cu phap: J = trapezoid(f, a, b, k)
fa = feval(f, a);
fb = feval(f, b);
J1 = (fa + fb)*(b - a)/2;
for k = 2:maxiter
n = 2^(k -2 ); % so diem moi
h = (b - a)/n ; % khoang chia moi
x = a + h/2.0; % toa do diem moi thu nhat
sum = 0.0;
for i = 1:n
fx = feval(f, x);
sum = sum + fx;
x = x + h;
end
J = (J1 + h*sum)/2;
if abs(J1 - J) < tol
break;
end
J1 = J;
end

78
Áp dụng. Tính tích phân
1

 
J   x 3  1 sin xdx
0

Để tính tích phân ta dùng chương trình:


clear all, clc
f = inline('(x^3+1)*sin(x)','x');
a = 0;
b = 1;
maxiter = 50;
tol = 1e-6;
J = trapezoid(f, a, b, maxiter, tol)
Kết quả J = 0.63679
3.2.2. Công thức Simpson
Bây giờ cứ mỗi đoạn cong Mi, Mi+1 được xấp xỉ bằng đường cong bậc hai, đi qua
ba giá trị yi, yi+1 và giá trị y tại x = (xi + xi+1)/2, có nghĩa chia [a, b] thành 2n đoạn bằng
nhau, bởi các điểm chia xi:
a = x0 < x1 < x2 < ...< x2n = b, nghĩa là: xi = a + ih
Với h = (b – a)/2n, với: i = 0, 1, 2,…,2n
Dùng đa thức nội suy bậc 2 xấp xỉ theo Newton, ta có công thức tính gần đúng tích
phân theo Simpson:

t ( t  1) 2
x2 x2 2

 f ( x ) dx   p 2 ( x ) dx   h( y 0  t y 0 
2
 y 0 ) dt
(3.21)
x0 x0 0

x2
h
x0
 f ( x)dx 
3
( y 0  4 y1  y 2 ) (3.22)

Tổng quát:
x2 i 2
h

x2 i
f ( x)dx 
3
( y2i  4 y2i 1  y2i  2 ) (3.23)

Vậy:
79
h
 [( y0  4 y1  y2 )  ( y2  4 y3  y4 )  ....  ( y2 n 2  4 y2 n 1  y2 n )]
3
(3.24)
h
I  [( y0  y2 n )  4( y1  y3  ...  y2 n 1 )  2( y2  y4  ...  y2 n 2 )]
3
Sai số:
h4
I  IS  M (b  a) (3.25)
180

Với: M = max  fiv(x) , a  x  b.


Ứng dụng lập trình
(i) Dùng C++
//Phuong phap Simpson;
#include <conio.h>
#include <stdio.h>
#include <math.h>

float y(float x)
{
float a=4/(1+x*x);
return(a);
}
void main()
{
int i,n;
float a,b,e,x,h,x2,y2,x4,y4,tp;

clrscr();
printf("Tinh tich phan theo phuong phap Simpson\n");
printf("Cho can duoi a = ");
scanf("%f",&a);
printf("Cho can tren b = ");

80
scanf("%f",&b);
printf("Cho so diem tinh n = ");
scanf("%d",&n);
h=(b-a)/n;
x2=a+h;
x4=a+h/2;
y4=y(x4);
y2=y(x2);
for (i=1;i<=n-2;i++)
{
x2+=h;
x4+=h;
y4+=y(x4);
y2+=y(x2);
}
y2=2*y2;
y4=4*(y4+y(x4+h));
tp=h*(y4+y2+y(a)+y(b))/6;
printf("Gia tri cua tich phan la : %10.8f\n",tp);
getch();
}
(ii) Dùng Matlab
Xây dựng hàm:
function s = simpson(f, a, b, n)
%n so khoang chia
%neu f chua trong mot file dung ki hieu @ de goi
% s = simpson(@f, a, b, n).
%neu f la ham inline
% s = simpson(f, a, b, n).
if mod(n, 2) ~= 0
81
n=n+1
end
h = (b - a)/(2*n);
s1 = 0;
s2 = 0;
for k = 1:n
x = a + h*(2*k-1);
s1 = s1+ f(x);
end
for k = 1:(n-1)
x = a + h*2*k;
s2 = s2 + f(x);
end
s = h*(f(a) + f(b) + 4*s1 + 2*s2)/3;
clc
Áp dụng. Tính tích phân
1
J   e xsin xdx
0

Để tính tích phân ta dùng chương trình:


clear all, clc
f = inline('exp(x).*sin(x)','x');
a = 0;
b = 1;
n = 6;
s = simpson(f, a, b, n)
Kết quả là J = 0.9093
1
dx
Ví dụ. Dùng công thức Simpson tổng quát với n = 10 để tính gần đúng: I =  1 x
0

Đánh giá những sai số của những giá trị gần đúng nhận được.

82
3.2.3. Công thức của Gauss
a. Liên hệ giữa các hệ toạ độ tổng thể và hệ toạ độ địa phương
Trong nhiều trường hợp ta cần tính tích phân số với độ chính xác rất cao, như trong
phương pháp phần tử hữu hạn (PTHH), miền tính toán  được chia nhỏ thành nhiều miền
con, phương pháp biến phân trọng số xây dựng trên các miền con này. Do đó dẫn đến tích
phân hàm dạng trên miền con.
3
x   N i xi  N1 x1  N 2 x 2  N 3 x3
i 1

Nếu tích phân hàm dạng bậc cao với sử dụng hệ toạ độ tổng thể (x,y,z, global
coordinate) thì thông thường sẽ xuất hiện các biểu thức đại số rất phức tạp khi phần tử là
hai, ba chiều (Irons and Ahmad, 1980).
Thay vào đó nếu chúng ta thực hiện chúng trong hệ toạ độ địa phương (, , ,
local coordinate) hay còn gọi là toạ độ chuẩn hay toạ độ tự nhiên (normal coordinate hay
natural coordinate) thì sẽ đơn giản hơn rất nhiều Taig, 1961; bởi lẽ nó thuận lợi trong
việc xây dựng hàm nội suy, tích phân số dùng được cách thiết lập của Gauss-Legendre
(phổ biến nhất).
Phần tử chiếu Phần tử thực

 y xj
τ e

3
0,1
1 xi Ve
1 2 xj
3 xk xi
vr xk
1 2
0,0 1,0  x

Hình 3.1: Biểu thị phần tử chiếu Vr vào phần tử thực Ve


Với phần tử đẳng tham số (isoparametric), ta có thể viết công thức biến đổi toạ độ
cho phần tử tứ giác tuyến tính có bốn điểm nút như sau:
Với phần tử tam giác tuyến tính có ba điểm nút:
4
y  j 1
N j x j  N1 x1  N

83
Ở đây Ni, Nj là hàm dạng hay còn gọi là hàm nội suy (shape function hay
interpolation function).
3
y   N j y j  N1 y1  N 2 y2  N3 y3 (3.26)
j 1

Từ luật đạo hàm đạo hàm riêng phần, ta có:


    x y     
        x   x 
      
  J  (3.27)
    x y     
        y   y 

  
 x   
1   
Hay:  J   (3.28)
   
 y    

Ở đây J là ma trận Jacobian biến đổi toạ độ. Định thức của ma trận này, det J ,

cũng phải được ước lượng bởi lẽ nó được dùng trong các tích phân biến đổi như sau:
Cho phần tử tứ giác tuyến tính:
1 1

 dxdy    det J d d
1 1
(3.29)
e

Cho phần tử tam giác tuyến tính:


1 1

 dxdy    det J d d (3.30)


e 0 0

3 2
3

4 4
1 1

Hình 3.2: Phần tử tứ giác có ma trận Jacobian không xác định

84
Trong một số trường hợp, ví dụ như ở Hình 3.1, phần tử tứ giác có 4 điểm nút, nếu
dạng hình học như vậy, ma trận Jacobian trở nên không xác định; để nó có giá trị tốt, các
hình dạng phần tử như cạnh và góc của nó cần phải đều đặn hơn (ví dụ tam giác đều, tứ
giác đều  hình vuông, đây là các dạng phần tử lý tưởng).

(i) Ứng dụng lập trình


Xây dựng hàm:
function [x, w] = gaussjacobi(n, alfa, beta)
%tinh cac trong so va hoanh do trong tich phan Gauss-Jacobi
p = [0.5*(alfa + beta + 2) 0.5*(alfa - beta)];
a = 1;
b = p;
for i = 2:n+1
b1 = 2*i*(i + alfa + beta)*(2*i + alfa + beta -2);
b2 = (2*i + alfa + beta -1)*(alfa^2 - beta^2)/b1;
b3 = ((2*i + alfa + beta -2)*(2*i + alfa + beta -1 )*(2*i + alfa + beta))/b1;
b4= (2*(i + alfa -1)*(i + beta - 1)*(2*i + alfa + beta))/b1;
s = [b3 b2];
if i == n+1
pn1 = conv(s, b) - [0 0 b4*a];
break;
else
p = conv(s, b) - [0 0 b4*a];
end
a = b;
b = p;
end
x = roots(p);
w = zeros(n, 1);
dv = polyder(p);
if mod(n, 2) == 1
85
sign = -1;
else
sign = 1;
end
dv = dv*(2^n)*factorial(n)/sign;
pn1 = -pn1*(2^(n+1))*factorial(n+1)/sign;
for i = 1:n
num = (2*n + alfa + beta +...

2)*gamma(n+alfa+1)*gamma(n+beta+1)*(2^(2*n+alfa+beta+1))*factorial(n);
den = (n + alfa + beta + 1)*gamma(n+alfa+beta+1)*polyval(dv,...
x(i))*polyval(pn1, x(i));
w(i) = num/den;

end


Áp dụng. Tính tích phân J  e xsin xdx .
0

Để tính tích phân ta dùng chương trình:


clear al, clc
f = inline('exp(x).*sin(x)','x');
n = 6;%n <= 40
alfa = 1;
beta = 0;
J = intgaussjacobi(f, n, alfa, beta)
Kết quả J = -0,1266

b. Tích phân số

Một số tích phân của các loại bài toán hai chiều (2D), ba chiều (3D), theo phương
pháp PTHH có thể được ước lượng bằng giải tích, nhưng nó không thực dụng cho các
hàm số phức tạp, đặc biệt trong trường hợp tổng quát khi  ,  là toạ độ cong. Trong thực

86
hành (3.29), (3.30) được ước lượng bằng số, gọi là tích phân số (numerical integration
hay còn gọi là numerical quadrature). Dùng tích phân số của Gauss, với phần tử tứ giác,
miền hai chiều ta có:

f  , dd   wi w j f  i , j 
1 1 n n


1 1 i 1 j 1
(3.31)

Với phần tử tam giác:


1 1

 f  , dd 
1 n

2 i 1

wi f  i , i  (3.32)
0 0

Với phần tử tứ giác thì wi, wj là hệ số trọng số và  i , j là các vị trí toạ độ bên

trong phần tử, cho ở Bảng 3.2 (Xem Kopal 1961); còn với phần tử tam giác, tương tự như
phần tử tứ giác, nhưng các điểm tích phân là các điểm mẫu (Sampling Points), Bảng 3.1.
Thông thường người ta muốn các tích phân số đạt độ chính xác cao, nhưng có
những trường hợp đặc biệt lại không cần thiết. Ở tích phân Gauss (3.31), với n = 2, sẽ
chính xác khi hàm f là cubic (bậc 3), còn ở tích phân (3.32), n = 1, sẽ chính xác khi đa
thức f bậc nhất, còn n = 3, sẽ chính xác khi đa thức f bậc hai.
Bảng 3.1: Điểm tích phân cho phần tử tam giác theo công thức (3.32)

n i i wi
1 1/ 3 1/ 3 1

1/ 2 1/ 2 1/ 3
3 1/ 2 0 1/ 3
0 1/ 2 1/ 3

87
Bảng 3.2: Trọng số và điểm tích phân Gauss – Legendre theo công thức (3.31)

Điểm tích phân  i Số điểm tích phân r Trọng số wi


0.0000000000 Một điểm 2.0000000000
 0.5773502692 Hai điểm 1.0000000000
0.0000000000 Ba điểm 0.8888888889
 0.7745966692 0.5555555555
 0.3399810 435 Bốn điểm 0.6521451548
 0.8611363116 0.3478548451
0.0000000000 0.5688888889
 0.5384693101 Năm điểm 0.4786286705
 0.9061798459 0.2369268850
 0.2386191861 0.4679139346
 0.6612093865 Sáu điểm 0.3607615730
 0.9324695142 0.1713244924

Ví dụ 1. Tính tích phân:


1

 x  2 x 2 dx Tính tích phân Gauss với n = 3


3

1

Giải:
n = 3 tra bảng ta được:
a1 = 0,774 W1 ≡ H1 = 0,555
a2 = -0,774 W2 ≡ H2 = + 0,555
a3 = 0,000 W3 ≡ H3 = 0,888
1
I=  f ( )d
1
=H1f(a1) + H2f(a2) + H3f(a3)

I=0,555 3 0,774  2(0,774)2 +0,555 3  0,774  2(0,774)2 +0,888 3 0,000  2(0,000)2 =1,113

88
Ví dụ 2. Dùng chương trình matlab
1
Tính tích phân:  e x sin xdx
0

clc, clear all


% tinh tich phan ham f(x) tren doan [a, b]
% n <= 25;
f = inline('exp(x).*sin(x)','x');
a = 0;
b = 1;
n = 20;

J = intglegendre(f, a, b, n)

Kết quả: J = 0,9093

Câu hỏi:
1) Khi nào đạo hàm được tính gần đúng được chấp nhận (sai số nằm trong phạm vi
cho phép), khi nào nó không được chấp nhận. Cho vài ví dụ ?
2) Tại sao tích phân gần đúng Gauss tốt hơn tích phân gần đúng Simpson và Tp gần
đúng Simpson tốt hơn Tp gần đúng hình thang ?
3) Tại sao tích phân số (gần đúng) của Gauss càng chính xác khi điểm tích phân càng
nhiều ?

Bài tập:
1) Tính gần đúng y’(55), y’(60) của hàm y = lgx dựa vào bảng giá trị đ cho sau:

x 50 55 60

y 1,6990 1,7404 1,7782


So sánh với kết quả đúng tính đạo hàm của hàm số y = lgx.
89
2) Tính gần đúng y’(1) của hàm y = f(x) từ bảng số đ cho:
x 0,98 1,00 1,02

y 0,7739332 0,7651977 0,7563321


3) Tìm đạo hàm của hàm f(x) = x2 + arctan(x) tại x = 2 với bước tính h = 0.5 bằng
công thức Romberg.
2
4) Tính gần đúng tích phân =  x dx bằng công thức hình thang tổng quát, lấy
1

n=10. Đánh giá sai số.


0.8
5) Tính gần đúng tích phân =   0, 2  25 x  200 x 2  675 x3  900 x 4  400 x5 dx bằng
0

công thức hình thang tổng quát.


1
6) Tính gần đúng =  e x dx bằng công thức hình thang và Simpson bằng cách chia
2

đoạn 0;1 thành 10 đoạn bằng nhau.


1
dx 
7) Tính gần đúng I=    0,78539816 bằng công thức hình thang và
0 1 x
2
4

Simpson mở rộng. Với đoạn 0;1 chia thành 10 đoạn bằng nhau.
1


8) Tính I  sinxdx bằng công thức Simpson. Với đoạn  0;1 chia thành 10 đoạn
0

bằng nhau.
1
9) Tính gần đúng tích phân I=  1  x 2 dx bằng công thức Simpson tổng quát sao
0

cho đạt sai số 0,001.


10) Sử dụng bảng tra tích phân của Gauss (n = 2) để tính gần đúng tích phân.
1 1

  (x  2 y )dxdy
2
I=
1 1

90
Đáp số:
1) y’(55)  0,00792; y’(60)  0,0072
Giá trị đúng y’(55) = 0,0079862; y’(60) = 0,0072382
2) y’(1)  -0,4400275.
3) D(3, 3) = 4,2
4) I  I * =1,218; I  I *  0,02 .

5) I = 1,6405
6) Công thức hình thang: I  I * =1,4672; I  I *  0,0136 .

Công thức Simpson: I  I * =1,4627; I  I *  0,000115 .

7) Công thức hình thang: I  I * = 0,78498149


Công thức Simpson: I  I * = 0,78539815.
8) I = 0,0312
9) I = 1,1478

91
Chương 4 GIẢI GẦN ĐÚNG PHƯƠNG TRÌNH
VÀ HỆ PHƯƠNG TRÌNH PHI TUYẾN
ROOTS OF NONLINEAR EQUATIONS

4.1. Giải gần đúng phương trình


Nếu phương trình đại số hay siêu việt khá phức tạp thì ít khi tìm được nghiệm
đúng. Bởi vậy việc tìm nghiệm gần đúng và ước lượng sai số là rất cần thiết.
Ta xét phương trình : f(x) = 0 (4.1)
với f(x) là hàm cho trước của biến x. Chúng ta cần tìm giá trị gần đúng nghiệm của
phương trình này.
Quá trình giải thường chia làm hai bước: bước sơ bộ và bước kiện toàn nghiệm.
Bước giải sơ bộ có 3 nhiệm vụ: vây nghiệm, tách nghiệm và thu hẹp khoảng chứa
nghiệm.
Vây nghiệm là tìm xem các nghiệm của phương trình có thể nằm trên những
đoạn nào của trục x. Tách nghiệm là tìm các khoảng chứa nghiệm sao cho trong mỗi
khoảng chỉ có đúng một nghiệm. Thu hẹp khoảng chứa nghiệm là làm cho khoảng
chứa nghiệm càng nhỏ càng tốt. Sau bước sơ bộ ta có khoảng chứa nghiệm đủ nhỏ.
Bước kiện toàn nghiệm tìm các nghiệm gần đúng theo yêu cầu đặt ra.
Khi tách nghiệm trong khoảng [a, b], giả sử hàm f(x) liên tục cùng với các đạo
hàm f’(x), f”(x), của nó. Các giá trị f(a), f(b) là giá trị của hàm tại các điểm mút của
đoạn này, thì f(a).f(b) < 0 và f’(x) giữ nguyên dấu trên đoạn [a , b].
Đôi khi để cho thuận lợi, ta viết lại (4.1) như sau:
f(x) = 0   (x) = (x)
Nghiệm thực của phương trình f(x) = 0 là giao điểm của đồ thị các hàm:
y =  (x) và y = (x)
Có rất nhiều phương pháp xác định nghiệm của (4.1). Sau đây chúng ta xét một
số phương pháp tiêu biểu.
4.1.1. Phương pháp lặp đơn
Giả sử phương trình (4.1) được đưa về dạng tương đương:
x = g(x) (4.2)
Từ giá trị xo nào đó gọi là giá trị lặp đầu tiên ta lập dãy xấp xỉ bằng công thức:

92
xn = g(xn-1) (4.3)
Với n = 1, 2, 3,....
Hàm g(x) được gọi là hàm lặp. Nếu dãy xn   khi n  thì ta nói phép lặp
(4.3) hội tụ.
y y

x1 xo x xo x1 x
y
Hình 4.1: Minh họa phép lặp theo phương pháp lặp đơn
Ta có định lí: Xét phương pháp lặp (4.3), giả sử:
- [a, b] là khoảng phân li nghiệm  của phương trình (4.1) tức là của (4.2);
- Mọi xn tính theo (4.3) đều thuộc [a, b].
- g(x) có đạo hàm thoả mãn:
g ( x)  q  1 ,a  x  b (4.4)

Trong đó q là một hằng số thì phương pháp lặp (4.3) hội tụ.
Ta có thể minh hoạ phép lặp bằng hình vẽ 4.1.
Cách đưa phương trình f(x) = 0 về dạng x = g(x) được thực hiện như sau:
ta thấy f(x) = 0 có thể biến đổi thành x = x + f(x) với   0. Sau đó đặt x + f(x) =
g(x) sao cho điều kiện (4.4) được thoả mãn.
Ví dụ. Xét phương trình
x3 + x - 1000 = 0
Sau bước giải sơ bộ ta có nghiệm x1  (9, 10)
Nếu đưa phương trình về dạng:
x = 1000 - x3 = g(x)
Dễ dàng thấy |g'(x)| >1 trong khoảng (9,10), nên không thoả mãn điều kiện (4.4)
Chúng ta đưa phương trình về dạng:
x  3 1000  x
Thì ta thấy điều kiện (4.4) được thoả mãn. Xây dựng dãy xấp xỉ:

93
x n  1  3 1000  x n

Với xo chọn bất kì trong (9, 10).


Trên cơ sở phương pháp này chúng ta có các chương trình tính toán sau:
Chương trình giải phương trình exp((1/3)*ln(1000 - x)) với số lần lặp cho trước.
Chương trình 4-1
//lap don
#include <conio.h>
#include <stdio.h>
#include <math.h>
void main()
{
int i,n;
float x,x0;
float f(float);
clrscr();
printf("Cho so lan lap n = ");
scanf("%d",&n);
printf("Cho gia tri ban dau cua nghiem x0 = ");
scanf("%f",&x0);
x=x0;
for (i=1;i<=n;i++)
x=f(x);
printf("Nghiem cua phuong trinh la :%.4f",x);
getch();
}
float f(float x)
{
float a=exp((1./3.)*log(1000-x));
return(a);
}

và chương trình giải bài toán bằng phương pháp lặp với sai số cho trước
94
Chương trình 4-2
//lap don
#include <conio.h>
#include <stdio.h>
#include <math.h>
void main()
{
int i;
float epsi,x,x0,y;
float f(float);

clrscr();
printf("Cho sai so epsilon = ");
scanf("%f",&epsi);
printf("Cho gia tri ban dau cua nghiem x0 = ");
scanf("%f",&x0);
x=x0;
y=f(x);
if (abs(y-x)>epsi)
{
x=y;
y=f(x);
}
printf("Nghiem cua phuong trinh la %.6f",y);
getch();
}

float f(float x)
{
float a=exp((1./3.)*log(1000-x));
return(a);
}

95
Cho giá trị đầu xo = 1.Kết quả tính toán x = 9.966555
4.1.2. Phương pháp dây cung
Thay cung AB của y = f(x) bởi dây cung AB, lấy x1 tại giao điểm P của dây
cung với trục hoành làm giá trị gần đúng của nghiệm chính xác . Phương trình dây
cung AB:
y
Y  f (a) X a

f (b)  f (a) b  a B

Tại P ta có: Y = 0, X = x1,


f (a ) x a
Nên:   1
f ( b )  f (a ) b  a a P
o x1  x
(b  a )f (a ) af (b)  bf (a ) A b
Suy ra: x1 = a - 
f ( b)  f (a ) f ( b )  f (a )
Sau khi tính được x1 ta xét được khoảng phân li nghiệm mới là [a, x1] hay [x1,b]
rồi tiếp tục áp dụng phương pháp dây cung vào khoảng phân li mới, tiếp tục ta được
x2, x3, x4  ngày càng gần đến nghiệm chính xác .

f (a). f (b) f " ( x)


Sai số ước lượng:   x1   max
2 [ f ' ( x)]3
Ví dụ 1. Tìm nghiệm trong khoảng (1.1, 1.4) của phương trình:
f(x) = x3 - 0,2x2 - 0,2x - 1,2 = 0
Bằng phương pháp lặp dây cung (với 2 lần lặp).
Giải:
f ( xo )( xo  1,4) f (1,1)(1,1  1,4) (0,331)(0,3)
x 1 = x 0- =1,1- =1,1-  1,18254
f ( x0 )  f (1,4) f (1,1)  f (1,4)  0,331  0,872

f(x1)=f(1,18254)=-0,06252
f ( x1 )( x1  1,4) (0,06252)(1,18254  1,4)
x 2 = x 1- =1,18254-  1,19709
f ( x1 )  f (1,4)  0,06252  0,872

Ứng dụng lập trình


(i) Dùng C++
//phuong phap day cung

96
#include <conio.h>
#include <stdio.h>
#include <math.h>
#define epsi 0.00001

void main()
{
float a,b,fa,fb,dx,x;
float f(float);

clrscr();
printf("Tim nghiem cua phuong trinh phi tuyen\n");
printf("bang phuong phap day cung\n");
printf("Cho cac gia tri a,b\n");
printf("Cho gia tri cua a = ");
scanf("%f",&a);
printf("Cho gia tri cua b = ");
scanf("%f",&b);
fa=f(a);
fb=f(b);
dx=fa*(b-a)/(fa-fb);
while (fabs(dx)>epsi)
{
x=a+dx;
fa=f(x);
if((fa*fb)<=0)
a=x;
else
b=x;
fa=f(a);
fb=f(b);
dx=fa*(b-a)/(fa-fb);

97
}
printf("Nghiem x = %.3f",x);
getch();
}

float f(float x)
{
float e=x*x*x*x+2*x*x*x-x-1;
return(e);
}

(ii) Bằng Matlab


Xây dựng hàm:
function [x, err, xx] = chord(f, a, b, tolx, maxiter)
%giai pt f(x) = 0 bg phuong phap day cung.
%vao : f - ham can tim nghiem
% a/b - khoang tim nghiem
% tolx - sai so mong muon cua nghiem
% maxiter lan lap max
%ra: x - nghiem
% err - sai so
% xx - cac gia tri trung gian
tolfun = eps;
fa = feval(f, a);
fb = feval(f, b);
if fa*fb > 0
error('Nghiem khong o trong doan nay !');
end
for k = 1: maxiter
xx(k) = (a*fb - b*fa)/(fb - fa); %pt.(1)
fx = feval(f, xx(k));
err = min(abs(xx(k) - a), abs(b - xx(k)));
98
if abs(fx) < tolfun | err<tolx
break;
elseif fx*fa > 0
a = xx(k);
fa = fx;
else
b = xx(k);
fb = fx;
end
end
x = xx(k);
if k == maxiter
fprintf('Khong hoi tu sau %d lan lap\n', maxiter)
else
fprintf('Hoi tu sau %d lan lap\n', k)
end

Áp dụng. Để tìm nghiệm của hàm f(x) = tg( -x) - x ta dùng chương trình :
clear all, clc
f = inline('tan(pi - x) - x');
[x, ss, xx] = falsp(f, 1.7, 3, 1e-4, 50)
Kết quả: x0 = 2.0289

4.1.3. Phương pháp Newton-Raphson


Còn gọi là phương pháp Newton hay phương pháp tiếp tuyến.
Xét phương trình f(x) = 0
Khai triển Taylor hàm f(x) tại lân cận x0:
f(x) = f(x0) + (x - x0) f’(x0) +
( x  x0 ) 2 ( x  x0 ) n n ( x  x0 ) n 1 n 1
 f "( x0 )  ....  f ( x0 )  f (C )
2! n! (n  1)!

Với: C = x0 + (x - x0), với: 0 <  < 1, có nghĩa: x0 < C < x


Bây giờ ta chỉ lấy số hạng bậc 1 của chuỗi Taylor:
f(x0) + ( x - x0).f’(x0) = 0 (4.5)

99
f (x 0 )
Gọi x1 là nghiệm của (4.5), ta có: x1 = x0 -
f ' (x 0 )

f (x1 ) f (x n )
Tương tự: x2 = x1 - ,…, xn + 1 = xn - , với x0  [a, b]
f ' ( x1 ) f ' (x n )
Vì (4.5) dùng thay cho phương trình f(x) = 0, nó tuyến tính đối với x nên
phương pháp Newton cũng gọi là phương pháp tuyến tính hóa, f’(x0) chính là hệ số
góc của y = f(x) tại x0 .
Tại B(x0, f(x0)).
Y - f(x0) = f’(x0).(X - x0) ,
Tại P: x = x1, Y = 0 đó chính là phương trình (4.5)
Hội tụ và sai số y
Người ta sẽ áp dụng phương B
pháp lặp Newton nếu nghiệm y
xn   khi n   của phương trình:
f(x) = 0, f có đạo hàm f, f” với f’ liên tục
trên [a,b], f’ và f” không đổi dấu trên (a, b).
a M
Xấp xỉ đầu x0 chọn là a hay b sao cho
f(x0) cùng dấu với f”. Khi đó O p b x
α
xn   khi n . Cụ thể hơn xn A
đơn điệu tăng tới  nếu f’.f” < 0, và xn đơn điệu giảm tới  nếu f’.f” > 0 .

f (x n )
Sai số:   xn <
,
, với: 0 < m < f ( xn ) và   x  b
m
Trường Hợp Lặp Newton - Raphson Không Có Hiệu Quả (hàm 1 biến)

f(x) f(x)

xo
x2 x1 x x1
x0 x
O x2
O

100
f(x) f(x)

O x0 x4 x2 x3 x1 x O
X0 X1 X

Ví dụ 2. Hãy tính lặp theo phương pháp Newton- Raphson


Cho f(x) = e-x - x , với x0 = 0 (điểm ban đầu)

-X e x  x i
i

Giải: Ta có f’(x) = - e - 1, xi + 1 = xi -
 ex  1
i

Ta lập được bảng tính:


i xi (%)
0 0 100
1 0, 5 0 0 0 0 0 0 0 0 11,8
2 0, 5 6 6 3 1 1 0 0 3 0,147
3 0, 5 6 7 1 4 2 1 6 3 0,0000220
4 0, 5 6 7 1 4 3 2 7 0 < 10-8

Ứng dụng lập trình

(i) Dùng C++


//phuong phap Newton
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define n 50
#define epsi 1e-5

void main()
{
101
float t,x0;
float x[n];
int i;
float f(float);
float daoham(float);

clrscr();
printf("Tim nghiem cua phuong trinh phi tuyen\n");
printf("bang phuong phap lap Newton\n");
printf("Cho gia tri cua x0 = ");
scanf("%f",&x0);
i=1;
x[i]=x0;
do
{
x[i+1] = x[i]-f(x[i])/daoham(x[i]);
t = fabs(x[i+1]-x[i]);
x[i]=x[i+1];
i=i+1;
if (i>100)
{
printf("Bai toan khong hoi tu\n");
getch();
exit(1);
}
else
;
}
while (t>=epsi);
printf("Nghiem x = %.5f",x[i]);
getch();
}

102
float f(float x)
{
float a=x*x-x-2;
return(a);
}

float daoham(float x)
{
float d=2*x-1;
return(d);
}

(ii) Dùng Matlab

Xây dựng hàm:


function [x, fx, xx] = newtonraphson(f, df, x0, tolx, maxiter)
%giai pt f(x) = 0 bang pp Newton-Raphson.
%vao: f = ftn to be given as a string ’f’ if defined in an M-file
% df = df(x)/dx (neu khong cho se dung dao ham so.)
% x0 = gia tri ban dau
% tolx = sai so mong muon
% maxiter = so lan lap max
%ra: x = nghiem
% fx = f(x(last)), xx = cac gia tri trung gian
h = 1e-4;
h2 = 2*h;
tolf = eps;
if nargin == 4 & isnumeric(df)
maxiter = tolx;
tolx = x0;
x0 = df;

103
end
xx(1) = x0;
fx = feval(f,x0);
for k = 1: maxiter
if ~isnumeric(df)
dfdx = feval(df, xx(k)); %dao ham cua ham
else
dfdx = (feval(f, xx(k) + h)-feval(f, xx(k) - h))/h2; %dao ham so
end
dx = -fx/dfdx;
xx(k+1) = xx(k) + dx; %pt.(3)
fx = feval(f, xx(k + 1));
if abs(fx)<tolf | abs(dx) < tolx,
break;
end
end
x = xx(k + 1);
if k == maxiter
fprintf('Khong hoi tu sau %d lan lap\n', maxiter)
else
fprintf('Hoi tu sau %d lan lap\n', k)
end

Áp dụng. Để tính lại nghiệm của hàm f ( x)  x3  10 x 2  5 ta dùng chương trình :


clear all, clc
f = inline('x.^3 - 10*x.^2 + 5');
[x, ss, xx] = newtonraphson(f, 0.7, 1e-4, 50)
Kết quả: x0 = 0.7346
4.1.4. Phương pháp Muller
Trong phương pháp dây cung khi tìm nghiệm trong đoạn [a, b] ta xấp xỉ hàm
bằng một đường thẳng. Tuy nhiên để giảm lượng tính toán và để nghiệm hội tụ nhanh
hơn ta có thể dùng phương pháp Muller. Nội dung của phương pháp này là thay hàm

104
trong đoạn [a, b] bằng một đường cong bậc 2 mà ta hoàn toàn có thể tìm nghiêm chính
xác của nó. Gọi các điểm đó có hoành độ lần lượt là a = x2, b = x1 và ta chọn thêm một
điểm x0 nằm trong đoạn [x2, x1]. Gọi
h1 = x1 - x0
h2 = x0 - x2
v = x - x0
f(x0) = f0
f(x1) = f1
f(x2) = f2
h2

h1
Qua 3 điểm này ta có một đường parabol:
y = av2 + bv + c
Ta tìm các hệ số a,b,c từ các giá trị đã biết v:
v  0( x  x0 ) a(0) 2  b(0)  c  f 0
v  h1 ( x  x1 ) ah12  bh1  c  f1
v  h2 ( x  x2 ) ah22  bh2  c  f 2

Từ đó ta có:
f1  f 0 (1   )  f 2
a
h12 (1   )
f1  f 0  ah12
b
h1
c  f0

Sau đó ta tìm nghiệm của phương trình av2 + bv + c = 0 và có:


2c
n1, 2  x0 
b  b 2  4ac
Tiếp đó ta chọn nghiệm gần x0 nhất làm một trong 3 điểm để tính xấp xỉ mới.
Các điểm này được chọn gần nhau nhất. Tiếp tục quá trình tính đến khi đạt độ chính
xác yêu cầu thì dừng lại.
Ví dụ. Tìm nghiệm của hàm f(x) = sin(x) - x/2 trong đoạn [1.8, 2.2]. Ta chọn x0 = 2
Ta có : x0 = 2 f(x0) = -0.0907 h1 = 0.2
x1 = 2.2 f(x1) = -0.2915 h2 = 0.2
x2 = 1.8 f(x2) = 0.07385 =1
105
Vậy thì:
1 (0.2915)  (0.0907)  (1  1)  0.07385
a  0.45312
1 0.2 2  (1  1)

 0.2915  (0.097)  (0.45312)  0.2 2


b  0.91338
0.2
c  0.0907
Ta có nghiệm gần x0 nhất là :
2  (0.0907)
n1  2.0   1.89526
 0.91338  (0.91338) 2  4  (0.45312)  (0.0907)

Với lần lặp thứ hai ta có:


x0 = 1.89526 f(x0) = 1.918410-4 h1 = 0.10474
x1 = 2.0 f(x1) = -0.0907 h2 = 0.09526
x2 = 1.8 f(x2) = 0.07385  = 0.9095
Vậy thì:
0.9095  (0.0907)  (1.9184 10 4 ) 1.9095  0.07385
a  0.4728
0.9095  0.10474 2 1.9095
 0.0907  1.9184 10  4  (0.4728)  0.10474 2
b  0.81826
0.10474
c  1.9184 10  4
Ta có nghiệm gần x0 nhất là :
2 1.9184 10 4
n1  1.89526   1.89594
 0.81826  (0.81826) 2  4  (0.4728) 1.9184 10  4

Ta có thể lấy n1 = 1.895494 làm nghiệm của bài toán.


Chương trình giải bài toán bằng phương pháp Muller như sau:
Chương trình 4-3
//phuong phap Muller
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

void main()
{

106
float x0,x1,x2,h1,h2,eps;
float a,b,c,gamma,n1,n2,xr;
int dem;
float f(float);

clrscr();
printf("PHUONG PHAP MULLER\n");
printf("\n");
printf("Cho khoang can tim nghiem [a,b]\n");
printf("Cho gia tri duoi a = ");
scanf("%f",&x2);
printf("Cho gia tri tren b = ");
scanf("%f",&x1);
if (f(x1)*f(x2)>0)
{
printf("\n");
printf("Nghiem khong nam trong doan nay\n");
getch();
exit(1);
}
eps=1e-5;
x0=(x1+x2)/2;
dem=0;
do
{
dem=dem+1;
h1=x1-x0;
h2=x0-x2;
gamma=h2/h1;
a=(gamma*f(x1)-
f(x0)*(1+gamma)+f(x2))/(gamma*(h1*h1)*(1+gamma));
b=(f(x1)-f(x0)-a*(h1*h1))/h1;

107
c=f(x0);
if ((a==0)&&(b!=0))
{
n1=-c/b;
n2=n1;
}
if ((a!=0)&&(b==0))
{
n1=(-sqrt(-c/a));
n2=(sqrt(-c/a));
}
if ((a!=0)&&(b!=0))
{
n1=x0-2*c/(b+(sqrt(b*b-4*a*c)));
n2=x0-2*c/(b-(sqrt(b*b-4*a*c)));
}
if (fabs(n1-x0)>fabs(n2-x0))
xr=n2;
else
xr=n1;
if (xr>x0)
{
x2=x0;
x0=xr;
}
else
{
x1=x0;
x0=xr;
}
}
while (fabs(f(xr))>=eps);

108
printf("\n");
printf("Phuong trinh co nghiem x = %.5f sau %d lan lap",xr,dem);
getch();
}

float f(float x)
{
float a=sin(x)-x/2;
return(a);
}
4.1.5. Phương pháp lặp Bernoulli
Có nhiều phương pháp để tìm nghiệm của một đa thức. Ta xét phương trình:
aoxn + a1xn-1 +  + an = 0
Nghiệm của phương trình trên thoả mãn định lí: Nếu max{|a1|, |a2|,...,|an|} = A
thì các nghiệm của phương trình thoả mãn điều kiện |x| < 1 + A/ |a0|.
Phương pháp Bernoulli cho phép tính toán nghiệm lớn nhất  của một đa thức
Pn(x) có n nghiệm thực phân biệt. Sau khi tìm được nghiệm lớn nhất  ta chia đa thức
Pn(x) cho (x - ) và nhận được đa thức mới Qn-1(x). Tiếp tục dùng phương pháp
Bernoulli để tìm nghiệm lớn nhất của Qn-1(x).
Sau đó lại tiếp tục các bước trên cho đến khi tìm hết các nghiệm của Pn(x).
Chúng ta khảo sát phương trình sai phân  có dạng như sau:
 = aoyk+n + a1yk+n-1 +.....+ anyk = 0 (4.6)
Đây là một phương trình sai phân tuyến tính hệ số hằng. Khi cho trước các giá
trị đầu yo, y1,..yn-1 ta tìm được các giá trị yn, yn+1,.. Chúng được gọi là nghiệm của
phương trình sai phân tuyến tính (4.6).
Đa thức: Pn(x) = a0xn + a1xn-1 +..+an-1x + an (4.7)
Với cùng một hệ số ai như (4.6) được gọi là đa thức đặc tính của phương trình
sai phân tuyến tính (4.6). Nếu (4.7) có n nghiệm phân biệt x1, x2,.., xn thì (4.6) có các
nghiệm riêng là:
yi  xik

Nếu yi là các nghiệm của phương trình sai phân là tuyến tính (4.6),thì

109
yk  c1 x1k  c2 x2k      cn xnk (4.8)
Với các hệ số ci bất kì cũng là nghiệm của phương trình sai phân tuyến tính có
hệ số là hằng số (4.6).
Nếu các nghiệm cần sao cho:
|x1|  |x | ...|xn|
 c  x k 
Vậy yk  c x 1  1  2     
k
1 1
 c2  x1  

 c  x  k 1 
Và yk 1  c x k 1
1 1 1  1  2     
 c2  x1  

 c  x  k 1 
1  1  2     
 c2  x1  
 x1 
yk 1
Do đó
yk  c  x k 
1  1  2     
 c2  x1  

Do x1 > x2 >...> xn
k k 1
 x2  x 
Nên   ,  2   0 khi k  
 x1   x1 
y k 1
Vậy  0 khi k  
yk

yk 1
Nghĩa là lim  x1
k  yk

Nếu phương trình vi phân gồm n + 1 hệ số, một nghiệm riêng yk có thể được
xác định từ n giá trị yk-1, yk-2,...,yn-1. Điều cho phép tính toán bằng cách truy hồi các
nghiệm riêng của phương trình vi phân.
Để tính nghiệm lớn nhất của đa thức, ta xuất phát từ các nghiệm riêng y1 = 0,
y2 = 0,.., yn =1 để tính yn+1. Cách tính này được tiếp tục để tính yn+2 xuất phát từ
y1 = 0, y2 = 0,.., yn+1 và tiếp tục cho đến khi yk+1 / yk không biến đổi nữa. Trị số của
yk+n được tính theo công thức truy hồi:

yk  n  
1
a1 yk  n1      an yk  (4.9)
a0

Ví dụ. Tính nghiệm của đa thức Pn(x) = P3(x) = x3 - 10x2 + 31x - 30.
Như vậy ao = 1, a1 = -10, a2 = 31 và a3 = -30.

110
Phương trình sai phân tương ứng là:
yk+3 -10yk+2 + 31yk+1 - 30yk = 0
Ta cho trước các giá trị y1 = 0; y2 = 0 và y3 = 1. Theo (4.9) ta tính được:
y4 = - (-10y3 + 31y2 - 30y1) = 10
y5 = - (-10y4 + 31y3 - 30y2) = 69
y6 = - (-10y5 + 31y5 - 30y3) = 410
y7 = - (-10y6 + 31y5 - 30y4) = 2261
y8 = - (-10y7 + 31y6 - 30y5) = 11970
y9 = - (-10y8 + 31y7 - 30y6) = 61909
y10 = - (-10y9 + 31y8 - 30y8) = 315850
y11 = - (-10y10 + 31y9 - 30y8) = 1598421
y12 = - (-10y11 + 31y10 - 30y9) = 8050130
y13 = - (-10y12 + 31y11 - 30y10) = 40425749
y14 = - (-10y13 + 31y12 - 30y11) = 202656090
y15 = - (-10y14 + 31y13 - 30y12) = 1014866581
y16 = - (-10y15 + 31y14 - 30y13) = 5079099490
y17 = - (-10y16 + 31y15 - 30y14) = 24409813589
y18 = - (-10y17 + 31y16 - 30y15) = 127092049130
y19 = - (-10y18 + 31y17 - 30y16) = 635589254740
Tỉ số các số yk+1 / yk lập thành dãy:
10 ; 6.9 ; 5.942 ; 5.5146 ; 5.2941 ; 5.172 ; 5.1018 ; 5.0607 ; 5.0363 ; 5.0218 ;
5.013 ; 5.0078 ; 5.0047 ; 5.0028 ; 5.0017 ; 5.001
Nghĩa là chúng sẽ hội tụ tới nghiệm lớn nhất là 5 của đa thức.
Chương trình 4-4
//phuong phap Bernoulli
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define max 50

void main()

111
{
float a[max],y[max];
int k,j,i,n,l;
float s,e1,e2,x0,x1,x;

clrscr();
printf("Cho bac cua da thuc can tim nghiem n = ");
scanf("%d",&n);
e1=1e-5;
printf("Cho cac he so cua da thuc can tim nghiem\n");
for (i=0;i<=n;i++)
{
printf("a[%d] = ",i);
scanf("%f",&a[i]);
}
for (k=0;k<=n;k++)
a[k]=a[k]/a[0];
tt: x1=0;
for (k=2;k<=n;k++)
y[k]=0;
y[1]=1;
l=0;
do
{
l=l+1;
s=0;
for (k=1;k<=n;k++)
s=s+y[k]*a[k];
y[0]=-s;
x=y[0]/y[1];
e2=fabs(x1 - x);
x1=x;

112
for (k=n;k>=1;k--)
y[k]=y[k-1];
}
while((l<=50)||(e2>=e1));
if(e2>=e1)
{
printf("Khong hoi tu");
getch();
exit(1);
}
else
printf("Nghiem x = %.4f\n",x);
n=n-1;
if (n!=0)
{
a[1]=a[1]+x;
for (k=2;k<=n;k++)
a[k]=a[k]+x*a[k-1];
goto tt;
}
getch();
}
Kết quả nghiệm của đa thức x3 - 10x2 + 31x - 30 là: 5, 3 và 2
4.1.6. Phương pháp lặp Birge - Viette
Các nghiệm thực, đơn giản của một đa thức Pn(x) được tính toán khi sử dụng
phương pháp Newton:
Pn ( xi )
xi 1  xi  (4.10)
Pn( xi )

Để bắt đầu tính toán cần chọn một giá trị ban đầu xo. Chúng ta có thể chọn một
giá trị xo nào đó, ví dụ :
an
x0  
an 1

113
Và tính tiếp các giá trị sau:
Pn ( x0 )
x1  x0 
Pn( x0 )

Pn ( x1 )
x2  x1 
Pn( x1 )

Tiếp theo có thể đánh giá Pn(xi) theo thuật toán Horner:
P 0 = a0
P1 = P0xi + a1 (4.11)
P2 = P1xi + a2
P3 = P2xi + a3
..................
P(xi) = Pn = Pn-1xi + an
Mặt khác khi chia đa thức Pn(x) cho một nhị thức (x - xi) ta được :
Pn(x) = (x - xi)Pn-1(x) + bn (4.12)
Với bn = Pn(xi). Đa thức Pn-1(x) có dạng:
Pn-1(x) = boxn-1 + b1xn-2 + p3xn-3 +..+ bn-2x + bn-1 (4.13)
Để xác định các hệ số của đa thức (4.13) ta thay (4.13) vào (4.12) và cân bằng
các hệ số với đa thức cần tìm nghiệm Pn(x) mà các hệ số ai đã cho:
(x - xi)( boxn-1 + b1xn-2+b3xn-3 +..+ bn-2x + bn-1 ) + bn
= aoxn + a1xn-1 + a2xn-2 +...+ an-1x + a (4.14)
Từ (4.14) rút ra :
bo = ao
b1 = a1 + boxi (4.15)
b2 = a2 + b1xi
......
bk = ak + bk-1xi
.......
bn = an + bn-1xi = Pn(xi)
Đạo hàm (4.12) ta được :
Pn( x)  ( x  xi ) Pn1 ( x)  Pn 1 ( x)

Và: Pn( xi )  Pn 1 ( xi ) (4.16)

114
Như vậy với một giá trị xi nào đó theo (4.11) ta tính được Pn(xi) và kết hợp
(4.15) với (4.16) tính được Pn(xi). Thay các kết quả này vào (4.10) ta tính được giá trị
xi+1. Quá trình được tiếp tục cho đến khi | xi+1 - xi | <  hay Pn(xi+1)  0 nên 1  xi+1 là
một nghiệm của đa thức.
Phép chia Pn(x) cho (x - 1) cho ta Pn-1(x) và một nghiệm mới khác được tìm
theo cách trên khi chọn một giá trị xo mới hay chọn chính xo = 1. Khi bậc của đa thức
giảm xuống còn bằng 2 ta dùng các công thức tìm nghiệm của tam thức để tìm các
nghiệm còn lại.
Ví dụ. Tìm nghiệm của đa thức P3(x) = x3 - x2 -16x + 24
ao = 1 a1 = -1 a2 = -16 a3 = 24
Chọn xo = 3.5 ta có:
Po = ao = 1
P1 = a1 + pox0 = -1 + 3.5*1 = 2.5
P2 = a2 + p1x0 = -16 + 3.5*2.5 = -7.25
P3 = a3 + p2x0 = 24 + 3.5*(-7.25) = - 1.375
b0 = a0 = 1;
b1 = a1 + box0 = -1 + 3.5*1 = 2.5
b2 = a2 + b1x0 = -16 + 3.5*2.5 = -7.25
P2(3.5) = b0x2 + b1x + b2 = 13.75
Pn ( x0 ) 1.375
x1  x0   3.5   3.6
Pn( x0 ) 13.75

Lặp lại bước tính trên cho x1 ta có:


Po = ao = 1
P1 = a1 + pox1 = -1 + 3.6*1 = 2.6
P2 = a2 + p1x1 = -16 + 3.6*2.6 = -6.64
P3 = a3 + p2x1 = 24 + 3.6*(-6.64) = - 0.096
bo = ao = 1
b1 = a1 + box1 = -1 + 3.6*1 = 2.6
b2 = a2 + p1x1 = -16 + 3.6*2.6 = -6.64
P2(3.6) = b0x2 + b1x + b2 = 15.68
Pn ( x1 ) 0.096
x2  x1   3.6   3.606
Pn( x1 ) 15.68

115
Quá trình cứ thế tiếp tục cho đến khi sai số chấp nhận được. Chương trình dưới
đây mô tả thuật tính trên.
Chương trình 4-5
//phuong phap Birge-Viette
#include <conio.h>
#include <stdio.h>
#include <math.h>
#define max 20

void main()
{
float a[max],p[max],d[max],x[max];
int k,j,i,n;
float e1,e2,x0,x1;

clrscr();
printf("Cho bac cua da thuc n = ");
scanf("%d",&n);
e1=0.0001;
printf("Cho cac he so cua da thuc can tim nghiem\n");
for (i=0;i<=n;i++)
{
printf("a[%d] = ",i);
scanf("%f",&a[i]);
}
x0=a[0];
for (i=0;i<=n;i++)
a[i]=a[i]/x0;
printf("Nghiem cua phuong trinh : \n");
tt:x0=-a[n]/a[n-1];
j=0;
do

116
{
j=j+1;
p[1]=x0+a[1];
d[1]=1.0;
for (k=2;k<=n;k++)
{
p[k]=p[k-1]*x0+a[k];
d[k]=d[k-1]*x0+p[k-1];
}
x1=x0-p[n]/d[n];
e2=fabs(x1-x0);
if (e2>e1)
x0=x1;
}
while((j<=50)||(e2>=e1));
if (e2>=e1)
printf("Khong hoi tu");
else
printf(" x = %.4f\n",x1);
n=n-1;
if (n!=0)
{
for (k=1;k<=n;k++)
a[k]=p[k];
goto tt;
}
getch();
}
Dùng chương trình trên để tìm nghiệm của đa thức x4 + 2x3 - 13x2 - 14x + 24 ta
được các nghiệm là: -4, 3, -2 và 1.
4.1.7. Phương pháp ngoại suy Aitken
Xét phương pháp lặp:

117
x = f(x) (4.17)
Với f(x) thoả mãn điều kiện hội tụ của phép lặp, nghĩa là với mọi x [a, b] ta
có:
| f’(x) |  q < 1 (4.18)
Như vậy:
xn+1 = f(xn) (4.19)
xn = f(xn-1) (4.20)
Trừ (4.19) cho (4.20) và áp dụng định lí Lagrange cho vế phải với c  [a, b] ta
có:
xn+1- xn = f(xn) - f(xn-1) = (xn - xn-1)f’(c) (4.21)
Vì phép lặp (4.17) nên :
| xn+1- xn |  q | xn - xn-1 | (4.22)
Do (4.22) đúng với mọi n nên cho n = 1, 2, 3 , . . . ta có:
| x2 - x1 |  q | x1 - xo |
| x3 - x2 |  q | x2 - x1 |
...................
| xn+1 - xn |  q | xn - xn-1 |
Điều này có nghĩa là dãy xi+1 - xi, một cách gần đúng, là một cấp số nhân. Ta
cũng coi rằng dãy xn - y với y là nghiệm đúng của (4.17), gần đúng như một cấp số
nhân có công sai q . Như vậy:
x n 1  y
q 1 (4.23)
xn  y

Hay : xn1  y  q(xn  y) (4.24)


Tương tự ta có: xn2  y  q(xn1  y) (4.25)
Từ (4.24) và (4.25) ta có :
x n2  xn1
q (4.26)
x n 1  x n
Thay giá trị của q vừa tính ở (4.26) vào biểu thức của q ở trên ta có:

 x n  x n 1 
2

y  xn  (4.27)
x n  2x n1  x n1

118
Công thức (4.27) được gọi là công thức ngoại suy Adam. Như vậy theo (4.27)
trước hết ta dùng phương pháp lặp để tính giá trị gần đúng xn+2, xn+1, xn của nghiệm và
sau đó theo (4.27) tìm được nghiệm với sai số nhỏ hơn.
Để làm ví dụ chúng ta xét phương trình:
lnx - x2 + 3 = 0
Ta đưa về dạng lặp:
x  ln(x)  3
1
f(x) 
2x ln x  3
Phép lặp hội tụ trong đoạn [0.3,  ]. Ta cho x1 = 1 thì tính được:
x2 = 1,7320508076
x3 = 1.883960229
x4 = 1.90614167
y = 1.909934347
Để giảm sai số ta có thể lặp nhiều lần.
Chương trinh 4-6
//phuong phap Aitken
#include <conio.h>
#include <stdio.h>
#include <math.h>

#define m 5

void main()
{
float x[m];
float epsi,n,y;
int i,z;
float f(float);

clrscr();
printf("Cho tri so ban dau x[1] = ");
119
scanf("%f",&x[1]);
printf("Cho tri so sai so epsilon = ");
scanf("%f",&epsi);
printf("\n");
printf( "Ngoai suy Aitken cua ham\n");
z=0;
while (z<=20)
{
for (i=2;i<=4;i++)
x[i]=f(x[i-1]);
n=x[4]-2*x[3]+x[2];
if ((fabs(n)<1e-09)||(fabs(x[1]-x[2])<epsi*fabs(x[1])))
z=20;
else
{
y=x[2]-(x[3]-x[2])*(x[3]-x[2])/n;
if (z>20)
printf("Khong hoi tu sau hai muoi lan lap\n");
x[1]=y;
}
z=z+1;
}
printf("Nghiem cua phuong trinh y = %.6f",y);
getch();
}
float f(float x)
{
float s=sqrt(log(x)+3);
return(s);
}

120
4.1.8. Phương pháp Bairtow
Nguyên tắc của phương pháp Bairstow là trích từ đa thức Pn(x) một tam thức
Q2(x) = x2 - sx + p mà ta có thể tính nghiệm thực hay nghiệm phức của nó một cách
đơn giản bằng các phương pháp đã biết.
Việc chia đa thức Pn(x) cho tam thức Q2(x) đưa tới kết quả:
Pn(x) = Q2(x).Pn-2(x) + R1(x)
Với Pn(x) = aoxn + a1xn-1 + a2xn-2 +...+ an
Q2(x) = x2 - sx + p
Pn-2(x) = boxn-2 + b1xn-3 + b2xn-4 +...+ bn-2
R1(x) = x + 
Để có được một thương đúng, cần tìm các giá trị của s và p sao cho R1(x) = 0
(nghĩa là  và  triệt tiêu). Với s và p đã cho, các hệ số b của đa thức Pn-2(x) và các hệ
số  và  được tính bằng phương pháp truy hồi. Các công thức nhận được khi khai
triển biểu thức Pn(x) = Q2(x).Pn-2(x) + R1(x) và sắp xếp lại các số hạng cùng bậc:
aoxn + a1xn-1 + a2xn-2 +...+ an = (x2 - sx + p)( boxn-2 + b1xn-3 + b2xn-4 +...+ bn-2)
Số hạng bậc Hệ số của Pn(x) Hệ số của Q2(x).Pn-2(x)
xn ao bo
xn-1 a1 b1 - sbo
xn-2 a2 b2 - sb1 + pbo
...... ...... .....
xn-k ak bk - sbk-1 + pbk-2
x an-1  - sbn-2 + pbn-3
xo an  + pbn-2
Như vậy:
bo = a o
b1 = a1 + sbo
b2 = a2 + sb1 - pbo
.................. (4.28)
bk = ak + sbk-1 - pbk-2
 = an-1 + sbn-2 - pbn-3
 = an - pb-2

121
Chúng ta nhận thấy rằng  được tính toán xuất phát từ cùng một công thức truy
hồi như các hệ số bk và tương ứng với hệ số bn-1.
bn-1 = an-1 + sbn-2 - pbn-3 = 
Hệ số bn là:
bn = an + sbn-1 - pbn-2 = sbn-1 + 
Và cuối cùng :
R1(x) = x +  = b+-1(x - s) + bn
Ngoài ra các hệ số bi phụ thuộc vào s và p và bây giờ chúng ta cần phải tìm các
giá trị đặc biệt s* và p* để cho bn-1 và bn triệt tiêu. Khi đó r1(x) = 0 và nghiệm của tam
thức x2 - s*x + p*x sẽ là nghiệm của đa thức Pn(x). Ta biết rằng bn-1 và bn là hàm của s
và p:
bn-1 = f(s, p)
bn = g(s, p)
Việc tìm s* và p* đưa đến việc giải hệ phương trình phi tuyến:
 f ( s, p)0

 g ( s, p)0
Phương trình này có thể giải dễ dàng nhờ phương pháp Newton. Thật vậy với
một phương trình phi tuyến ta có công thức lặp:
xi+1 = xi - f(xi)/f'(xi)
Hay f'(xi)(xi+1 - xi) = -f(xi)
Với một hệ có hai phương trình, công thức lặp trở thành:
J(Xi)(Xi+1 - Xi) = -F(Xi)
Với Xi = {si, pi}T và Xi+1 = {si+1, pi+1}T
 f ( si , pi ) 
F ( X i )   
 g ( si , pi ) 

 f f 
 
s p 
J (Xi )  
 g g 
 s p 

Quan hệ: J(Xi)X = -F(Xi) với X = {si+1 - si,pi+1 - pi}T tương ứng với một hệ
phương trình tuyến tính hai ẩn số s = si+1 - si và p = pi+1 - pi :

122
 f f
 s s  p p   f ( si , pi )


 g s  g p   g ( s , p )
 s p
i i

Theo công thức Cramer ta có:


g f
f g
p p
s

f g
g f
p s s

f g f g
 
s p p s
 f  f g g
Để dùng được công thức này ta cần tính được các đạo hàm , , , .
s  p s  p
Các đạo hàm này được tính theo công thức truy hồi.
Do bo = ao nên:
b0 b0
0 0
s p

b1 = a1 + sbo nên:
b1 b1
 b0 0
s p

b2 = a2 + sb1- pbo nên:


b2 a2 ( sb1 ) ( pb0 )
  
s s s s
Mặt khác:
a2 ( sb1 ) (b ) ( pb0 )
0  s 1  b1 0
s s s s
b2
Nên:  b1  sb0
s
b3 = a3 + sb2- pb1 nên:
b3 b b
 b2  s 2  p 1
s s s
Nếu chúng ta đặt:
bk
 ck 1
s
123
Thì:
co = bo (4.29)
c1 = b1 + sbo = b1 + sco
c2 = b2 + sc1 - pco
....................
ck = bk + sck-1 - pck-2
cn-1 = bn-1 + scn-2 - pcn-3
Như vậy các hệ số cũng được tính theo cách như các hệ số bk. Cuối cùng với
f = bn-1 và g = bn ta được:
f f f f
 cn  2  cn  3  cn 1  cn  2
s s s s

bn 1cn  2  bn cn 3
s  (4.30)
cn 1cn 3  cn2 2

bn 1cn 1  bn cn  2
p  (4.31)
cn 1cn 3  cn2 2

Sau khi phân tích xong Pn(x) ta tiếp tục phân tích Pn-2(x) theo phương pháp
trên. Các bước tính toán gồm:
- Chọn các giá trị ban đầu bất kì s0 và p0
- Tính các giá trị bo, .., bn theo (4.28)
- Tính các giá trị co,...,cn theo (4.29)
- Tính so và po theo (4.30) và (4.31)
- Tính s1 = s0 + so và p1 = po+ po
- Lặp lại bước 1 cho đến khi pi+1 = pi = p và si+1 = si = s
- Giải phương trình x2 - sx + p để tìm 2 nghiệm của đa thức
- Bắt đầu quá trình trên cho đa thức Pn-2(x)
Ví dụ. Tìm nghiệm của đa thức P4(x) = x4 - 1.1x3 + 2.3x2 + 0.5x2 + 3.3.
Với lần lặp ban đầu ta chọn s = -1 và p =1, nghĩa là tam thức có dạng: x2+x+1

124
a0 a1 a2 a3 a4
1 -1.1 2.3 0.5 3.3
sbi -1 2.1 -3.4 0.8
-pbi-1 -1 2.1 -3.4
bi 1 -2.1 3.4 -0.8 = bn-1 0.7=bn
sbi -1.0 3.1 -5.5

-pbi-1 -1.0 3.1


ci 1 -3.1 5.5 -3.2

0.8  3.1
 0.7 5.5
s   0.11
5.5  3.1
 3.2 5.5

5.5 0.8
 3.2 0.7
p   0.06
5.5  3.1
 3.2 5.5

s* = -1 + 0.11 = -0.89
p* = 1 + 0.06 = 1.06
Tiếp tục lặp lần 2 với s1 = s* và p1 = p* ta có:
a0 a1 a2 a3 a4
1 -1.1 2.3 0.5 3.3
sbi -0.89 1.77 -2.68 0.06
-pbi-1 -1.06 2.11 -3.17
bi 1 -1.99 3.01 -0.07 = bn-1 0.17=bn
sbi -0.89 2.56 -4.01
-pbi-1 -1.0 3.1
ci 1 -2.88 4.51 -1.03
0.07  2.88
 0.7 5.5
s   0.01
4.51  2.88
 1.03 4.51

125
4.51 0.07
 1.03  0.17
p   0.04
4.51  2.88
 1.03 4.51

s* = -0.89 - 0.01 = -0.9


p* = 1.06 + 0.04 = 1.1
Như vậy:
P4(x) = (x2 + 0.9x + 1.1)(x2 + 2x + 3)
Chương trình sau áp dụng lí thuyết vừa nêu để tìm nghiệm của đa thức.
Chương trình 4-7
//phuong phap Bairstow
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define m 10

void main()
{
float a[m],b[m],c[m];
int i,n,v;
float s,e1,t,p,q,r,p1,q1;

clrscr();
printf("Cho bac cua da thuc n = ");
scanf("%d",&n);
printf("Cho cac he so cua da thuc can tim nghiem\n");
for (i=n;i>=0;i--)
{
printf("a[%d] = ",n-i);
scanf("%f",&a[i]);

126
}
printf("\n");
e1=0.0001;
if (n<=2)
if (n==1)
{
printf("Nghiem cua he\n");
printf("%.8f",(a[0]/(-a[1])));
getch();
exit(1);
}
do
{
v=0;
p=1;
q=-1;
b[n]=a[n];
c[n]=a[n];
do
{
b[n-1]=b[n]*p+a[n-1];
c[n-1]=b[n-1]+b[n]*p;
for (i=n-2;i>=0;i--)
{
b[i]=b[i+2]*q+b[i+1]*p+a[i];
c[i]=c[i+2]*q+c[i+1]*p+b[i];
}
r=c[2]*c[2]-c[1]*c[3];
p1=p-(b[1]*c[2]-b[0]*c[3])/r;
q1=q-(b[0]*c[2]-b[1]*c[1])/r;
if ((fabs(b[0])<e1)&&(fabs(b[1])<e1))
goto tt;

127
v=v+1;
p=p1;
q=q1;
}
while (v<=40);
if(v>40)
{
printf("Khong hoi tu sau 40 lan lap");
getch();
exit(1);
}
tt:s=p1/2;
t=p1*p1+4*q1;
if(t<0)
{
printf("Nghiem phuc\n");
printf("%.8f+%.8fj\n",s,(sqrt(-t)/2));
printf("%.8f-%.8fj\n",s,(sqrt(-t)/2));
printf("\n");
}
else
{
printf("Nghiem thuc\n");
printf("%.8f\n",(s+sqrt(t)/2));
printf("%.8f\n",(s-sqrt(t)/2));
printf("\n");
}
for (i=2;i<=n;i++)
a[i-2]=b[i];
n=n-2;
}
while ((n>2)&(r!=0.0));

128
s=-a[1]/(2*a[2]);
t=a[1]*a[1]-4*a[2]*a[0];
if (t<0)
{
printf("Nghiem phuc\n");
printf("%.8f+%.8fj\n",s,(sqrt(-t)/(2*a[2])));
printf("%.8f-%.8fj\n",s,(sqrt(-t)/(2*a[2])));
printf("\n");
}
else
{
printf("Nghiem thuc\n");
printf("%.8f\n",(s-sqrt(t)/(2*a[2])));
printf("%.8f\n",(s-sqrt(t)/(2*a[2])));
printf("\n");
}
getch();
}
Áp dụng. Dùng chương trình trên để xác định nghiệm của đa thức:
x6 - 2x5 - 4x4 + 13x3 - 24x2 + 18x - 4 = 0
Ta nhận được các nghiệm:
x1 = 2.61903399
x2 = -2.73205081
x3 = 0.732050755
x4 = 0.381966055
x5 = 0.500011056 + i*1.3228881
x6 = 0.500011056 - i*1.3228881
4.2. Giải hệ phương trình phi tuyến
Ở đây ta đi giải hệ phương trình phi tuyến theo phương pháp lặp Newton-
Raphson
Từ khai triển Taylor cho bài toán một biến:

129
f " ()
f(xi + 1) = f(xi) + f’(xi)(xi + 1- xi) + ( x i1  x i ) 2
2!
f ( xi )
xi 1  xi  vì f(xi + 1) = 0
f '( xi )

Tổng quát hoá cho bài toán 2 biến (hàm 2 biến):

 ui ui (4.32)


 u   u  ( x   x ).  ( y   y ).
xi yi
i 1 i i 1 i i 1 i


v  v  ( x  x ). vi  ( y  y ). vi (4.33)
 i 1 i i 1 i
xi
i 1 i
yi
 v u
 u i v i (4.33)
x i y i y
x 
 i 1 i u v u v
 i. i  i. i
Từ (4.32) và (4.33) ta có:  x y y x

 u v
 v i u i (4.34)
i x i x
y  y 
 i 1 i u v
i. i 
u v
i. i
 x y y x

Mẫu số của (4.33) và (4.34) gọi là định thức Jacobien (detJ), của hệ thống:
ui ui
x y
detJ  det
v i v i
x y

Một cách tổng quát cho phương trình: f(x) = 0


Với x = [x1, x2,...., xn]T và f = [f1, f2,...., f n]T
Phương pháp lặp Newton - Raphson cho hệ phương trình n ẩn này là:
x(k+1) = x(k) - Fx-1(x(k)).f(x(k))
Với ma trận Jacobi Fx như sau:
 f1 f1 f1 f1 
  
 x1 x2 x3 xn 
 f 2 f 2 f 2 f 2 
 x 
x2 x3 xn 
Fx   1 
   
   
 f f n f n f n 
 n  
 x1 x2 x3 xn 

130
Ứng dụng lập trình
a. Dùng C++
//giai he pt phi tuyen
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define n 4

float a[n+1][n+2];
float x[n+1],y[n+1];
int i,j,k,l,z,r;
float e,s,t;

void main()
{
void doc();
clrscr();
printf("Cho cac gia tri nghiem ban dau\n");
for (i=1;i<=n;i++)
{
printf("x[%d] = ",i);
scanf("%f",&x[i]);
}
e=1e-6;
z=30;
for (r=1;r<=z;r++)
{
doc();
for (k=1;k<=n-1;k++)
{
s=0 ;
131
for (i=k;i<=n;i++)
{
t=fabs(a[i][k]);
if (s<=t)
{
s=t;
l=i;
}
}
for (j=k;j<=n+1;j++)
{
s=a[k][j];
a[k][j]=a[l][j];
a[l][j]=s;
}
if (a[1][1]==0)
{
printf("Cac phan tu duong cheo cua ma tran bang khong");
getch();
exit(1);
}
else
{
if (fabs(a[k][k]/a[1][1])<(1e-08))
{
printf("Ma tran suy bien");
goto mot;
}
}
for (i=k+1;i<=n;i++)
{
if (a[k][k]==0)

132
{
printf("Cac phan tu duong cheo cua ma tran bang khong\n");
goto mot;
}
s=a[i][k]/a[k][k];
a[i][k]=0;
for (j=k+1;j<=n+1;j++)
a[i][j]=a[i][j]-s*a[k][j];
}
y[n]=a[n][n+1]/a[n][n];
for (i=n-1;i>=1;i--)
{
s=a[i][n+1];
for (j=i+1;j<=n;j++)
s=s-a[i][j]*y[j];
if (a[i][i]==0)
{
printf("Cac phan tu duong cheo cua ma tran bang khong\n");
goto mot;
}
y[i]=s/a[i][i];
}
}
if (r!=1)
for (i=1;i<=n;i++)
{
if (fabs(y[i])<e*fabs(x[i]))
goto ba;
}
for (i=1;i<=n;i++)
x[i]=x[i]-y[i];
printf("\n");

133
}
printf("Khong hoi tu sau %d lan lap\n",z);
goto mot;
clrscr();
ba:printf("Vec to nghiem\n");
for (i=1;i<=n;i++)
printf("%.5f\n",(x[i]-y[i]));
printf("\n");
printf("Do chinh xac cua nghiem la %.5f: \n", e);
printf("\n");
printf("Vec to tri so du :\n");
for (i=1;i<=n;i++)
printf("%.5f\n",(a[i][n+1]));
mot:printf("\n");
getch();
}

void doc()
{
a[1][1]=3*x[1]*x[1]-3*x[2]*x[4];
a[1][2]=-3*x[2]*x[2]-3*x[1]*x[4];
a[1][3]=0;
a[1][4]=-3*x[1]*x[2];
a[1][5]=x[1]*x[1]*x[1]-x[2]*x[2]*x[2]-3*x[1]*x[2]*x[4]-8;

a[2][1]=1;
a[2][2]=1;
a[2][3]=1;
a[2][4]=1;
a[2][5]=x[1]+x[2]+x[3]+x[4]-5;

a[3][1]=-x[1]/sqrt(25-x[1]*x[1]);

134
a[3][2]=0;
a[3][3]=8;
a[3][4]=0;
a[3][5]=sqrt(25-x[1]*x[1])+8*x[3]+4;

a[4][1]=2*x[2]*x[3];
a[4][2]=2*x[1]*x[3];
a[4][3]=2*x[1]*x[2];
a[4][4]=-1;
a[4][5]=2*x[1]*x[2]*x[3]-x[4]+8;

b. Dùng Matlab
Xây dựng hàm :
function [P, iter, err] = new4sys(f, jf, P, max1)
%vao -F la he pt luu trong M-file f.m
% -JF la ma tran jacobi luu trong M-file jf.m
% -P vec to nghiem ban dau
% -max1 so lan lap cuc dai
%ra -P la ve to nghiem
% -iter so lan lap thuc te
% -err sai so
Y = f(P);
for k = 1:max1
J = jf(P);
Q = P - (J\Y')';
Z = f(Q);
err = norm(Q - P);
relerr = err/(norm(Q) + eps);
P = Q;
Y = Z;

135
iter = k;
if (err<eps)|(relerr<eps)|(abs(Y)<eps)
break
end
end

Ví dụ 1. Dưới đây là chương trình giải hệ phương trình phi tuyến:


 x13  x22  3 x1 x2 x4  8  0

 x1  x2  x3  x4  5  0

 25  x1  8 x3  4  0
2

2 x x x  x  8  0
 1 2 3 4

Ma trận đạo hàm riêng J(Xi) là:


 3x12  3x2 x4  3x22  3x1 x4 0  3x1 x2 
 
 1 1 1 1 
 x1 
 0 8 0 
 25  x12 
 2x x  1 
 2 3 2 x1 x3 2 x1 x2

Ma trận này được chương trình đọc vào nhờ thủ tục doc.Trong thủ tục này,các
hệ số a[i, 5] là các hàm fi(x). Vectơ nghiệm ban đầu được chọn là {0,-1,-1,1}T. Kết
quả tính cho ta: x = {0.01328676, -1.94647929, -1.12499779, 8.05819031}T với độ
chính xác 0.000001. Vectơ số dư r = {0.00000536, -0.00000011, -0.00000001, -
0.00000006}T.
Ví dụ 2. Hãy tính lặp theo phương pháp Newton- Raphson hệ phương trình:

u ( x, y)  x  xy  10  0
2

Cho  cho biết nghiệm (x = 2, y = 3)



v( x, y)  y  3xy  57  0
2

Nghiệm ban đầu cho (x = 1.5 , y = 3.5)


Giải:
v0 v0
 1  6 xy  1  6(1,5)(3,5)  3, 25  2 y 2  3(3,5) 2  36, 75
y0 x0
u0 u0
 x  1,5  2 x  y  2(1,5)  3,5  6,5
y0 x0
Vậy định thức Jacobien: det J = 6,5(32,5) - 1,5(36,75) = 156,125
Và u0 = (1,5)2 + 1,5(3,5) - 10 = - 2,5
136
v0 = 3,5 + 3(1,5)(3,5)2 - 57 = 1,625
  2,5(32,5)  1,625(3,5)
 x  1,5   2,03603
156,125
Từ đó có: 
 y  3,5  1,625(6,5)  (3,5)(36,75)  2,84387
 156,125

Tiếp tục các phần xấp xỉ bị dư, lời giải sẽ tiến dần đến nghiệm chính xác:
 (x = 2 , y = 3)

Câu hỏi:
1) Phương trình (hoặc hệ phương trình) phi tuyến thông thường có nhiều nghiệm;
để giải nó (hoặc chúng nó), bước đầu tiên ta phải làm gì?
2) Trình bày cách giải hệ phương trình phi tuyến theo công thức lặp Newton-
Raphson?
3) Tại sao phương pháp lặp Newton – Raphson còn được gọi là phương pháp tiếp
tuyến?
4) Ưu nhược điểm của các phương pháp lặp để giải phương trình phi tuyến ?

Bài tập:
1) Dùng phương pháp dây cung, tìm nghiệm gần đúng với độ chính xác 10-2 của:
a) x3 + 3x + 5=0
b) x 4 -3x +1=0
2) p dụng hai lần phương pháp đây cung, tìm nghiệm thực gần đúng của phương
trình x3-10x+5 trong khoảng phân ly(0, 0.6). Đánh giá sai số của nghệm gần
đúng x2.
 
3) Cho phương trình x = sin3x, có khoảng phân ly nghiệm là( , ). Tìm nghiệm
6 3
gần đúng trong khoảng đã cho bằng phương pháp dây cung, tính đến phép lặp
thứ 3 là x3.
4) Tìm nghiệm gần đúng của hệ:

 x  2 xy  y  0
3 2

 2

x  2x  y  2  0
Bằng phương pháp Newton, cho x0=0.7, y0=1.0.
137
5) Tìm nghiệm dương nhỏ nhất của phương trình f(x) = 2x - 4x. Bằng phương
pháp Newton – Raphson với 3 lần lặp (cho x0 = 0.3)
6) Tìm nghiệm dương nhỏ nhất của phương trình x3 - 10x2 + 5 = 0. Bằng phương
pháp Newton – Raphson với 2 lần lặp (cho x0 = 0.7)
7) Tìm nghiệm gần đúng của hệ bằng phương pháp lặp Newton.
 Sinx  y  1,32

 x  cos y  0.85
Với xấp xỉ đầu(x0, y0)=(1.80, -0.33).
8) Tìm nghiệm gần đúng của hệ bằng phương pháp lặp Newton.


2 x  2 y  4 x  1  0
2 3

 4
x  4 y  4 y  4  0

4

Với xấp xỉ đầu(x0, y0)=(0.1, 0.7).


9) Cho hàm: f(x) = - 0.9x2 + 1.7x + 2.5, điểm ban đầu x0 = 5, chọn 0 = 0.01%.

Đáp số:
2)   0.51
3) x3  0.75649
4)  ,    (0.704402,1.087387)
5) x3  0.3099
6) x2  0.73460
7)  ,    (1.79,0.34)

138
Chương 5 CÁC PHƯƠNG PHÁP SỐ
CỦA ĐẠI SỐ TUYẾN TÍNH
NUMERICAL METHODS FOR LINEAR ALGEBRA

Các phương pháp số gắn liền với việc ứng dụng trên máy tính số. Ma trận được
ứng dụng rất thích hợp ở đây, như giải hệ phương trình vi phân, biểu diễn các vectơ ở
dạng ma trận.
Khi giải hệ đại tuyến A.X = B, ma trận A có thể là ma trận đầy hoặc thưa hoặc
có dạng 3, 5 đường chéo hoặc nhiều đường chéo (dạng BAND). Khi A là ma trận
thưa, đã có thuật toán để lưu trữ, tiết kiệm bộ nhớ và thời gian tính như lưu trữ dạng
BAND bình thường hoặc dạng BAND ép lại, hay kỹ thuật lưu trử Skyline (frontal
method), với nhiều thuật giải trực tiếp hay lặp rất hiệu quả; đặc biệt khi ma trận có
dạng 3, 5 đường chéo có những thuật toán giải riêng để tiết kiệm bộ nhớ và thời gian
tính.

5.1. Ma trận
5.1.1. Các định nghĩa
Ma trận là tập hợp gồm m  n phần tử, chia thành m hàng và n cột.
 a11 a12 ......a1n 
 a a ....a 
Kí hiệu: A m,n = ai , j m,n   21 22 2n 

 ............... 
 
am1 am 2 ....amn 
Có thể coi ma trận hàng (cột) là biểu diễn đại số của một vectơ (hình học).
Vết (trace) của ma trận A được tính: Tr(A) = a11 + a22 +.....+ ann
5.1.2. Định thức của ma trận
Mỗi một ma trận vuông A đều được gắn với một số, kí hiệu det(A) hoặc A ,

được gọi là định thức. Ma trận A được gọi là suy biến nếu det(A) = 0 và ngược lại là
không suy biến.
Để tìm định thức của ma trận vuông nxn, trước hết chúng ta nhắc lại một số tính
chất quan trọng của định thức:
- Nếu nhân tất cả các phần tử của một hàng (hay cột) với k thì định thức được
nhân với k.

139
- Định thức không đổi nếu ta cộng thêm vào một hàng tổ hợp tuyến tính của các
hàng còn lại.
Ta sẽ áp dụng các tính chất này để tính định thức của một ma trận cấp 4 như sau
(phương pháp này có thể mở rộng cho một ma trận cấp n) bằng phương pháp trụ:
 a11 a12 a13 a14 
 
a a22 a23 a24 
A  21
a a32 a33 a34 
 31 
a a44 
 41 a42 a43

Lấy giá trị trụ là p1 = a11.Ta chia các phần tử của hàng thứ nhất cho p1 = a11 thì
định thức sẽ là D/p1 (theo tính chất 1) và ma trận còn lại là:
 1 a12 
a13  
a14
 
 a21 a22 a23 a24 
a a32 a33 a34 
 31 
a a44 
 41 a42 a43

Lấy hàng 2 trừ đi hàng 1 đã nhân với a21, lấy hàng 3 trừ đi hàng 1 đã nhân với
a31 và lấy hàng 4 trừ đi hàng 1 đã nhân với a41 (thay hàng bằng tổ hợp tuyến tính của
các hàng còn lại) thì định thức vẫn là D/p1 và ma trận là:
1 
a12 
a13  
a14
 
0 
a22 
a23  
a24
0 
a32 
a33  
a34
 
0    
 a42 a43 a44

 . Ta chia các phần tử của hàng thứ hai cho p2 thì định
Lấy giá trị trụ là p2  a22
thức sẽ là D/(p1p2) và ma trận còn lại là:

 1 a12 
a13  
a14
 
0 1 
a23  
a24
 0 a 
a33  
a34
 32

 0 a   
 42 a43 a44

 , lấy hàng 3 trừ đi hàng 2 đã nhân với


Lấy hàng 1 trừ đi hàng 2 đã nhân với a12
a32 và lấy hàng 4 trừ đi hàng 2 đã nhân với a42
 thì thì định thức vẫn là D/(p1p2) và ma

trận là:
1 0 
a13  
a14
 
0 1 
a23  
a24
0 0 
a33  
a34
 
0   
 0 a43 a44
140
Tiếp tục lấy hàng 3 rồi hàng 4 làm trụ thì ma trận sẽ là:
1 0 0 0
 
0 1 0 0
0 0 1 0
 
0 1 
 0 0

 a33
Định thức của ma trận này là D/(p1p2p3p4) = D/( a11a22  a44
 ) = 1 nên định thức

của ma trận A là D = p1p2p3p4.


Sau đây là chương trình tìm định thức của một ma trận:
Chương trình 5-1
//tinh dinh thuc
#include <conio.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

void main()
{
int i,j,k,n,ok1,ok2,t;
float d,c,e,f,g,h;
float a[50][50];
char tl;

clrscr();
printf("** TINH DINH THUC CAP n **");
printf("\n");
printf("\n");
printf("Cho cap cua dinh thuc n = ");
scanf("%d",&n);
printf("Nhap ma tran a\n");
for (i=1;i<=n;i++)
{
printf("Dong %d:\n",i);
for (j=1;j<=n;j++)
141
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
}
printf("\n");
printf("Ma tran a ma ban da nhap\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%.5f\t",a[i][j]);
printf("\n");
}
printf("\n");
t=1;
flushall();
while (t)
{
printf("Co sua ma tran a khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i,j]);
}
if (toupper(tl)=='K')

142
t=0;
}
printf("Ma tran a ban dau\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%.5f\t",a[i][j]);
printf("\n");
}
printf("\n");
d=1;
i=1;
ok2=1;
while ((ok2)&&(i<=n))
{
if (a[i][i]==0)
{
ok1=1;
k=k+1;
while ((ok1)&&(k<=n))
if (a[k,i]!=0)
{
for (j=i;j<=n;j++)
{
c=a[i][j];
a[i][j]=a[k][j];
a[k][j]=c;
}
d=-d;
ok1=0;
}

143
else
k=k+1;
if (k>n)
{
printf("\n");
printf("** MA TRAN SUY BIEN **");
ok2=0;
d=0;
}
}
if (a[i][i]!=0)
{
c=a[i][i];
for (j=i+1;j<=n;j++)
a[i][j]=a[i][j]/c;
for (k=i+1;k<=n;k++)
{
c=a[k][i];
for (j=i+1;j<=n;j++)
a[k][j]=a[k][j]-a[i][j]*c;
}
}
i=i+1;
}
if (ok2)
{
for (i=1;i<=n;i++)
d=d*a[i][i];
printf("\n");
printf("** GIA TRI DINH THUC D **");
printf("\n");
printf("%.3f",d);

144
}
getch();
}
5.1.3. Nghịch đảo ma trận
Gọi A-1 là ma trận nghịch đảo của một ma trận A bậc n ta có AA-1 = E; trong
biểu thức này E là ma trận đơn vị (ma trận vuông có các phần tử trên đường chéo
chính bằng 1). Dạng của ma trận E, ví dụ cấp 4 là:
1 0 0 0
 
0 1 0 0
E 
0 0 1 0
 
0 1 
 0 0

Phương pháp khử để nhận được ma trận nghịch đảo A-1 được thực hiện qua
nhiều giai đoạn (n), mỗi một giai đoạn gồm hai bước. Đối với giai đoạn thứ k:
- Chuẩn hoá phần tử akk bằng cách nhân hàng với nghịch đảo của nó.
- Làm cho bằng không các phần tử phía trên và phía dưới đường chéo cho đến
cột thứ k. Khi k = n thì A(k) sẽ trở thành ma trận đơn vị và E trở thành A-.1
Qua thuật toán tính ma trận nghịch đảo ở trên, ta thấy rằng nếu ma trận không
có tính chất trội thì khi nghịch đảo có khả năng gây sai số lớn, do đó trong cách giải hệ
đại tuyến, các phương pháp giải thông dụng đều tránh sử dụng nghịch đảo ma trận.
Ví dụ. Tính ma trận nghịch đảo của ma trận.
2 1 1
 
A  1 2 1
1 1 2
 
Ta viết lại ma trận A và ma trận đơn vị tương ứng với nó:
2 1 1 1 0 0
   
A  1 2 1 E   0 1 0
 1 1 2 0 0 1
   
Giai đoạn 1:
Bước a: Nhân hàng 1 với 1/a11, nghĩa là a,1j = a1j/a11 đối với dòng thứ nhất,
a,ij = aij đối với các dòng khác.
1 1 2 1 2  1 2 0 0 
   
A  1 2 1  E   0 1 0
1 1 2   0 0 1
  

145
Bước b: Trừ hàng 3 và hàng 2 cho hàng 1, nghĩa là a(1)1j = aij - ai1aij đối với i  1
1 1 2 1 2   1 2 0 0
   
A  0 3 2 1 2  E   1 2 1 0 
 0 1 2 3 2  1 2 0 1 
   
Giai đoạn 2:
Bước a: Lấy hàng 2 làm chuẩn, nhân hàng 2 với 2/3, để nguyên các hàng khác.
1 1 2 1 2  12 0 0
   
A  0 1 1 3  E   1 3 2 3 0 
 0 1 2 3 2  1 2 0 1 
   
Bước b: Lấy hàng 1 trừ đi hàng 2 nhân 1/2 và lấy hàng 3 trừ đi hàng 2 nhân 1/2
1 0 1 3   2 3 1 3 0 
   
A  0 1 1 3  E   1 3 2 3 0 
 0 0 4 3  1 3 1 3 1 
   
Giai đoạn 3:
Bước a: Lấy hàng 3 làm chuẩn, nhân hàng 3 với 3/4, để nguyên các hàng khác.
 1 0 1 3  2 3 1 3 0 
   
A   0 1 1 3 E   1 3 2 3 0 
0 0 1   1 4 1 4 3 4 
   
Bước b: Lấy hàng 1 trừ đi hàng 3 nhân 1/3 và lấy hàng 2 trừ đi hàng 3 nhân 1/3
1 0 0  3 4 1 4 1 4 
   
A   0 1 0 E   1 4 3 4 1 4 
0 0 1  1 4 1 4 3 4 
   
Như vậy A-1 là:
 3 / 4  1/ 4  1/ 4 
 
A1    1 / 4 3 / 4  1 / 4 
  1/ 4  1/ 4 3 / 4 
 
Áp dụng phương pháp này chúng ta có chương trình sau:
Chương trình 5-2
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>

146
void main()
{
int i,j,k,n,t,t1;
float c,a[50][50],b[50][50];
char tl;

clrscr();
printf(" **MA TRAN NGHICH DAO** \n");
printf("Cho bac cua ma tran n = ");
scanf("%d",&n);
printf("Vao ma tran ban dau a\n");
for (i=1;i<=n;i++)
{
printf("Vao hang thu %d :\n",i);
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
}
printf("\n");
printf("Ma tran ban da nhap\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%.5f\t",a[i][j]);
printf("\n");
}
t=1;

147
flushall();
while (t)
{
printf("\nCo sua ma tran khong(c/k)?");
scanf("%c",&tl);
if(toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
if (toupper(tl)=='K')
t=0;
}
printf("\nMa tran ban dau\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%.5f\t",a[i][j]);
printf("\n");
}
printf("\n");
for (i=1;i<=n;i++)
for (j=n+1;j<=2*n;j++)
{
if (j==i+n)
a[i][j]=1;
else

148
a[i][j]=0;
}
i=1;
t1=1;
while (t1&&(i<=n))
{
if (a[i][i]==0)
{
t=1;
k=i+1;
while (t&&(k<=n))
if (a[k][i]!=0)
{
for (j=1;j<=2*n;j++)
{
c=a[i][j];
a[i][j]=a[k][j];
a[k][j]=c;
}
t=0;
}
else
k=k+1;
if (k==n+1)
{
if (a[i][k-1]==0)
{
printf("MA TRAN SUY BIEN\n ");
t1=0;
}
}
}

149
if (a[i][i]!=0)
{
c=a[i][i];
for (j=i;j<=2*n;j++)
a[i][j]=a[i][j]/c;
}
for (k=1;k<=n;k++)
{
if (k!=i)
{
c=a[k][i];
for (j=i;j<=2*n;j++)
a[k][j]=a[k][j]-a[i][j]*c;
}
}
i=i+1;
}
if (t1)
{
printf("\n");
printf("\nMA TRAN KET QUA\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=n+1;j<=2*n;j++)
printf("%.4f\t\t",a[i][j]);
printf("\n");
}
printf("\n");
}
getch();
}

150
Dùng chương trình tính nghịch đảo của ma trận:
9 9 8   1 2 1 
   
9 8 7  cho ta kết quả  2 10 9 
8 6   1 9 9 
 7  
5.1.4. Tích hai ma trận
Giả sử ta có ma trận Amn và ma trận Bnp. Tích của Amn và Bnp là ma trận Cmp
n
trong đó mỗi phần tử của Cmp là: c ij   a ik b kj
k 1

Chương trình dưới đây thực hiện nhân hai ma trận với nhau.
Chương trình 5-3
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>

#define max 50

void main()
{
int n,l,m,i,j,k,t;
float a[max][max],b[max][max],c[max][max];
char tl;

clrscr();
printf("Cho so hang cua ma tran a : ");
scanf("%d",&n);
printf("Cho so cot cua ma tran a : ");
scanf("%d",&l);
printf("Cho so cot cua ma tran b : ");
scanf("%d",&m);

151
printf("\nNHAP MA TRAN A\n");
for (i=1;i<=n;i++)
for (j=1;j<=l;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
printf("Ma tran a ma ban da nhap\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=l;j++)
printf("%10.5f",a[i][j]);
printf("\n");
}
flushall();
t=1;
while (t)
{
printf("Co sua ma tran khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
if (toupper(tl)=='K')
t=0;

152
}
printf("Ma tran a ban dau");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=l;j++)
printf("%10.5f",a[i][j]);
printf("\n");
}
printf("\n");

printf("NHAP MA TRAN B\n");


for (i=1;i<=l;i++)
for (j=1;j<=m;j++)
{
printf("b[%d][%d] = ",i,j);
scanf("%f",&b[i][j]);
}
printf("\n");
printf("Ma tran b ban da nhap\n");
for (i=1;i<=l;i++)
{
for (j=1;j<=m;j++)
printf("%10.5f",b[i][j]);
printf("\n");
}
flushall();
t=1;
while (t)
{
printf("Co sua ma tran khong(c/k)?");
scanf("%c",&tl);

153
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("b[%d][%d] = ",i,j);
scanf("%f",&b[i][j]);
}
if (toupper(tl)=='K')
t=0;
}
printf("Ma tran b ban dau");
printf("\n");
for (i=1;i<=l;i++)
{
for (j=1;j<=m;j++)
printf("%10.5f",b[i][j]);
printf("\n");
}
printf("\n");
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
{
c[i][j]=0;
for (k=1;k<=l;k++)
c[i][j]=c[i][j]+a[i][k]*b[k][j];
}
printf("Ma tran tich c :\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=m;j++)

154
printf("%10.5f",c[i][j]);
printf("\n");
}
getch();
}
Ví dụ. Dùng chương trình tính tính hai ma trận ở trên ta nhận được kết quả:
2 1 5 0 1 
   
 1 3   1 2  2   8  14 11 
 
1 0   3  4 3   1 2  2
   
5 3  14  2  1 
  

5.1.5. Phép biến đổi tuyến tính trong không gian n chiều

Giữa ma trận và các phép biến đổi tuyến tính trong không gian (đại số) có một
mối liên hệ mật thiết. Một phần tử của không gian n chiều có thể được mô tả bằng một
vectơ, hay viết dưới dạng ma trận cột.

Xét hai vectơ: Xn1 = x , x , x ,..., x  ,


1 2 3 n
T
Yn1 = y1 , y2 , y3 ,..., ym T
Với phép biến đổi: A.X = Y
Với A là ma trận cỡ m  n được gọi là phép biến đổi tuyến tính từ vectơ n chiều
sang vectơ m chiều. Khi m = n đơn giản là ta có một phép chuyển tọa độ. Nếu trong
không gian 2 hoặc 3 chiều với các tọa độ Descartes thì A chính là các ma trận chuyển
đổi.
Ở trường hợp đơn giản, A có thể là ma trận cosine chỉ phương khi thực hiện
phép quay giữa hai hệ tọa độ, có thể là ma trận cosine chỉ phương khi thực hiện phép
quay giữa hai hệ tọa độ, có thể là ma trận với một phần tử duy nhất khác không (các
ma trận cơ bản) khi thực hiện các phép tịnh tiến các hệ tọa độ theo các trục.
Một hệ cơ sở của không gian n chiều là một tập hợp đúng n vectơ độc lập tuyến
tính.
Ví dụ. Ta có thể chọn các vectơ đơn vị ei làm hệ cơ sở với vectơ X bất kỳ:
X = c1e1 + c2e2+....+ cnen

155
e1  1,0,0,.........0T

e2  0,1,0,.........0
T


............................
e  0,0,0,.........1T
1

Tích vô hướng của hai vectơ: X= x1, x2 ,..., xn T


Y= y1, y2 ,..., yn T
n
Được định nghĩa: X .Y = Y .X =T T
x y
1
i i (trong không gian Euclide)

Độ dài hay Module của vectơ X ký hiệu X được tính:

T
X = x .x

Khoảng cách d và góc  giữa hai vectơ:

d = x  y  ( x  y) T .(x  y)

xT.y = x . y . cos 

Hai vectơ x, y được gọi là trực giao với nhau nếu: xT.y = 0
Một tập hợp các vectơ trực giao với nhau từng đôi một được gọi là một hệ trực
giao. Một ma trận trực giao sẽ có các hàng và các cột là các vectơ trực giao.
Định lý: Các vectơ của một hệ trực giao là độc lập tuyến tính.
Chuẩn của vectơ, ký hiệu là X , được định nghĩa là một số không âm, thỏa

mãn các tính chất sau:


- X  0 và X khi và chỉ khi X = 0

- X =  . x với mọi  thực

- X  Y  X + Y bất đẳng thức tam giác

Có 3 chuẩn sau đây hay sử dụng trong các bài toán ứng dụng:

Với vectơ X = x 1 , x 2 ,..., x n 


T
-
n
- X 1 = x 1 + x 2 +....+ x n = x
1
i thường gọi chuẩn tuyệt đối

n
- X 2 = x 21  x 2 2  ...  x 2 n = x
i 1
2
i gọi là chuẩn Euclide

156
- X  = maxi x i gọi là chuẩn cực đại

Mở rộng khái niệm cho chuẩn các ma trận. Chuẩn của các ma trận A và B ký
hiệu là A và B , được định nghĩa là các số không âm thõa mãn các điều kiện sau:

- A  0 và A = 0 khi và chỉ khi A = 0

- A =  . A với mọi  thực

- AB  A + B

- A B  A  B

Ở đây, nêu 3 định nghĩa chuẩn hay dùng:


- A 1 = maxj (  ai j ) gọi là chuẩn cột.
i

- A 2 = a
i, j
2
ij gọi là chuẩn Euclide.

- A  = maxi(  ai j ) gọi là chuẩn hàng.


j

Chuẩn của ma trận là khái niệm hết sức quan trọng đối với các phương pháp số.
Chúng hay sử dụng khi xét tính hội tụ của các phương pháp lặp hoặc khi xét sự ổn
định của các hệ phương trình vi phân.
Liên hệ chuẩn của ma trận và vectơ:
Trong không gian n chiều Vn chuẩn của ma trận tương ứng với chuẩn của vectơ
nếu:
A.X  A . X với mọi A và X thuộc Vn.

5.1.6. Các phép tính ma trận


Với ma trận và cách đại số hóa các vectơ ta có thể định nghĩa các phép tính một
cách hoàn chỉnh và đầy đủ hơn.
Ta nhắc lại một số phép tính cơ bản:
Ma trận B gọi là ma trận chuyển vị của A (AT = B), nếu hàng của ma trận A là
cột của ma trận B.
[aji] = [bij ]=> bij = aji
m n nm

Ma trận nghịch đảo: A-1


A.B = E => B = A-1 => A.A-1 = A-1.A = E (với E là ma trận đơn vị)

157
Chú ý một số tính chất: A.B  B.A
(AT)T = A , (k.A)T = k.AT
(A+B)T = AT+BT , (A.B)T = BT.AT
(A-1)-1 = A , (A.B)-1 = B-1.A-1
(AT)-1 = (A-1)T , det(A.B) = det(A).det(B)
det(A) = det(AT)
1
a11 0 0 1 / a 11 0 0 
0 a  0 
 22 0  =  0 1 / a 22
 0 0 a33   0 0 1 / a 33 

 Ma trận A là suy biến, det (A) = 0 thì các hàng hoặc các cột của nó là các
vectơ phụ thuộc tuyến tính.
 Hạng của ma trận vuông A là số lớn nhất các hàng (hoặc các cột) độc lập
tuyến tính với nhau.
 Ma trận B có được từ ma trận A bằng cách đổi chỗ hai hàng cho nhau
thì:
det(B) = - det(A).
 Nếu A, B là các ma trận vuông trực giao thì AT, A-1, A.B cũng là các ma
trận trực giao.
 Nếu A, B là các ma trận vuông đối xứng thì  A, A + B cũng là những
ma trận vuông đối xứng. Nếu A không suy biến thì A-1 cũng đối xứng.
Cần chú ý rằng: Tích của hai ma trận đối xứng nói chung không phải là ma
trận đối xứng.
n
Nếu A = [aij] là ma trận vuông cấp n thoả a kk   a ks , với s  k, k = 1...n ,
s 1

thì det(A)  0. Ma trận A được gọi là có phần tử trên đường chéo chính aii trội. Hơn
nữa nếu akk > 0, k = 1 ,2,.., n thì det(A)>0 định thức xác định dương.
Sau đây là một số chương trình thực hiện các phép tính ma trận
a. Nghịch đảo ma trận
Gọi A-1 là ma trận nghịch đảo của một ma trận A bậc n ta có AA-1 = E (trong
biểu thức này E là một ma trận vuông có các phần tử trên đường chéo chính bằng 1).
Dạng của ma trận E, ví dụ cấp 4 là:

158
1 0 0 0
 
0 1 0 0
E 
0 0 1 0
 
0 1 
 0 0

Phương pháp khử để nhận được ma trận nghịch đảo A-1 được thực hiện qua
nhiều giai đoạn (n), mỗi một giai đoạn gồm hai bước. Đối với giai đoạn thứ k:
- Chuẩn hoá phần tử akk bằng cách nhân hàng với nghịch đảo của nó.
- Làm cho bằng không các phần tử phía trên và phía dưới đường chéo cho đến
cột thứ k. Khi k = n thì A(k) sẽ trở thành ma trận đơn vị và E trở thành A-1.
Ví dụ. Tính ma trận nghịch đảo của ma trận.
2 1 1
 
A  1 2 1
1 1 2
 
Ta viết lại ma trận A và ma trận đơn vị tương ứng với nó:
2 1 1 1 0 0
   
A  1 2 1 E   0 1 0
 1 1 2 0 0 1
   
Giai đoạn 1:
Bước a: Nhân hàng 1 với 1/a11, nghĩa là a,1j = a1j/a11 đối với dòng thứ nhất,
a,ij = aij đối với các dòng khác.
1 1 2 1 2  1 2 0 0 
   
A  1 2 1  E   0 1 0
1 1 2   0 0 1
  

Bước b: Trừ hàng 3 và hàng 2 cho hàng 1, nghĩa là a(1)1j = aij- ai1aij đối với i  1.
1 1 2 1 2   1 2 0 0
   
A  0 3 2 1 2  E   1 2 1 0 
 0 1 2 3 2  1 2 0 1 
   
Giai đoạn 2:
Bước a: Lấy hàng 2 làm chuẩn, nhân hàng 2 với 2/3, để nguyên các hàng khác.
1 1 2 1 2  12 0 0
   
A  0 1 1 3  E   1 3 2 3 0 
 0 1 2 3 2  1 2 0 1 
   
Bước b: Lấy hàng 1 trừ đi hàng 2 nhân 1/2 và lấy hàng 3 trừ đi hàng 2 nhân ½.

159
1 0 1 3   2 3 1 3 0 
   
A  0 1 1 3  E   1 3 2 3 0 
 0 0 4 3  1 3 1 3 1 
   
Giai đoạn 3:
Bước a: Lấy hàng 3 làm chuẩn, nhân hàng 3 với 3/4, để nguyên các hàng khác.
 1 0 1 3  2 3 1 3 0 
   
A   0 1 1 3 E   1 3 2 3 0 
0 0 1   1 4 1 4 3 4 
   
Bước b: Lấy hàng 1 trừ đi hàng 3 nhân 1/3 và lấy hàng 2 trừ đi hàng 3 nhân 1/3
1 0 0  3 4 1 4 1 4 
   
A   0 1 0 E   1 4 3 4 1 4 
0 0 1  1 4 1 4 3 4 
   
Như vậy A-1 là:
 3 / 4  1/ 4  1/ 4 
1
 
A    1/ 4 3 / 4  1/ 4 
  1/ 4  1/ 4 3 / 4 
 
Áp dụng phương pháp này chúng ta có chương trình sau:
Chương trình 5-4
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>

void main()
{
int i,j,k,n,t,t1;
float c,a[50][50],b[50][50];
char tl;

clrscr();
printf(" **MA TRAN NGHICH DAO** \n");
printf("Cho bac cua ma tran n = ");
160
scanf("%d",&n);
printf("Vao ma tran ban dau a\n");
for (i=1;i<=n;i++)
{
printf("Vao hang thu %d :\n",i);
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
}
printf("\n");
printf("Ma tran ban da nhap\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%.5f\t",a[i][j]);
printf("\n");
}
t=1;
flushall();
while (t)
{
printf("\nCo sua ma tran khong(c/k)?");
scanf("%c",&tl);
if(toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");

161
scanf("%d",&j);
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
if (toupper(tl)=='K')
t=0;
}
printf("\nMa tran ban dau\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%.5f\t",a[i][j]);
printf("\n");
}
printf("\n");
for (i=1;i<=n;i++)
for (j=n+1;j<=2*n;j++)
{
if (j==i+n)
a[i][j]=1;
else
a[i][j]=0;
}
i=1;
t1=1;
while (t1&&(i<=n))
{
if (a[i][i]==0)
{
t=1;
k=i+1;

162
while (t&&(k<=n))
if (a[k][i]!=0)
{
for (j=1;j<=2*n;j++)
{
c=a[i][j];
a[i][j]=a[k][j];
a[k][j]=c;
}
t=0;
}
else
k=k+1;
if (k==n+1)
{
if (a[i][k-1]==0)
{
printf("MA TRAN SUY BIEN\n ");
t1=0;
}
}
}
if (a[i][i]!=0)
{
c=a[i][i];
for (j=i;j<=2*n;j++)
a[i][j]=a[i][j]/c;
}
for (k=1;k<=n;k++)
{
if (k!=i)
{

163
c=a[k][i];
for (j=i;j<=2*n;j++)
a[k][j]=a[k][j]-a[i][j]*c;
}
}
i=i+1;
}
if (t1)
{
printf("\n");
printf("\nMA TRAN KET QUA\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=n+1;j<=2*n;j++)
printf("%.4f\t\t",a[i][j]);
printf("\n");
}
printf("\n");
}
getch();
}
b. Nhân hai ma trận
Giả sử ta có ma trận Amn và ma trận Bnp. Tích của Amn và Bnp là ma trận Cmp
n
trong đó mỗi phần tử của Cmp là: c ij   a ik b kj
k 1

Chương trình dưới đây thực hiện nhân hai ma trận với nhau.
Chương trình 5-5
#include <conio.h>
#include <stdio.h>
#include <math.h>

164
#include <stdlib.h>
#include <ctype.h>

#define max 50

void main()
{
int n,l,m,i,j,k,t;
float a[max][max],b[max][max],c[max][max];
char tl;

clrscr();
printf("Cho so hang cua ma tran a : ");
scanf("%d",&n);
printf("Cho so cot cua ma tran a : ");
scanf("%d",&l);
printf("Cho so cot cua ma tran b : ");
scanf("%d",&m);
printf("\nNHAP MA TRAN A\n");
for (i=1;i<=n;i++)
for (j=1;j<=l;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
printf("Ma tran a ma ban da nhap\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=l;j++)
printf("%10.5f",a[i][j]);
printf("\n");

165
}
flushall();
t=1;
while (t)
{
printf("Co sua ma tran khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
if (toupper(tl)=='K')
t=0;
}
printf("Ma tran a ban dau");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=l;j++)
printf("%10.5f",a[i][j]);
printf("\n");
}
printf("\n");

printf("NHAP MA TRAN B\n");


for (i=1;i<=l;i++)
for (j=1;j<=m;j++)

166
{
printf("b[%d][%d] = ",i,j);
scanf("%f",&b[i][j]);
}
printf("\n");
printf("Ma tran b ban da nhap\n");
for (i=1;i<=l;i++)
{
for (j=1;j<=m;j++)
printf("%10.5f",b[i][j]);
printf("\n");
}
flushall();
t=1;
while (t)
{
printf("Co sua ma tran khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("b[%d][%d] = ",i,j);
scanf("%f",&b[i][j]);
}
if (toupper(tl)=='K')
t=0;
}
printf("Ma tran b ban dau");
printf("\n");

167
for (i=1;i<=l;i++)
{
for (j=1;j<=m;j++)
printf("%10.5f",b[i][j]);
printf("\n");
}
printf("\n");
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
{
c[i][j]=0;
for (k=1;k<=l;k++)
c[i][j]=c[i][j]+a[i][k]*b[k][j];
}
printf("Ma tran tich c :\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=m;j++)
printf("%10.5f",c[i][j]);
printf("\n");
}
getch();
}

5.1.7. Vectơ riêng, trị riêng và các dạng toàn phương của ma trận
Cho A là ma trận vuông cấp n, số  được gọi là trị riêng và vectơ khác không
X gọi là vectơ riêng của A nếu chúng thỏa mãn điều kiện:
A.X =  .X hay (A-  E).X = 0 => A  .E =0 (5.1)

Giải phương trình (5.1), ta sẽ tìm được phương trình bậc n cho  , sao cho:
f(  ) = 0.

168
f(  ) được gọi là đa thức đặc trưng của A, nó có n trị riêng  1,  2,..,  n. Tập
hợp các giá trị riêng  1,  2,..,  n này được gọi là phổ và maxi (  i ) là bán kính phổ

của ma trận A.
Với mỗi  i có vô số Xi. Các vectơ riêng cùng tương ứng với một  i rõ ràng là
phụ thuộc tuyến tính và chỉ khác nhau một hằng số  . Do đó ta có thể chọn một vectơ
duy nhất làm cơ sở. Tập hợp n vectơ riêng, ứng với n trị riêng khác nhau tạo thành một
hệ vectơ độc lập tuyến tính. Ma trận gồm các cột là các vectơ riêng của ma trận A, gọi
là ma trận dạng riêng của A.
Định lý:
 Nếu A là ma trận thực, đối xứng thì các trị riêng là thực. Các vectơ riêng ứng
với các trị riêng khác nhau là các vectơ thực trực giao và độc lập tuyến tính.
 Nếu A là ma trận xác định dương thì các giá trị riêng là những số dương.
Định lý Sylvester:
Nếu định thức A và tất cả các tử thức nằm trên đường chéo chính đều là

dương thì A là xác định dương.


Tổng quát hơn, khái niệm xác định dương của ma trận A được định nghĩa nhờ
dạng toàn phương là đa thức: Q(X) = XT.A.X
Nếu Q xác định dương, tức Q(X) > 0 với mọi số thực X và Q(X) = 0 khi và chỉ
khi X = 0, thì A được gọi là xác định dương.
Bài toán tìm giá trị riêng liên quan mật thiết đến tốc độ đặc trưng trong cơ học
lưu chất, nghiên cứu ổn định và động lực học kết cấu công trình…Có nhiều thuật toán
tìm giá trị riêng và vectơ riêng của một ma trận. Giả sử ta có ma trận A, gọi E là ma
trận đơn vị thì theo (5.1) ta có:
(A - E)X = 0 (5.2)
Và (A - E) là ma trận có dạng:
 a11   a12  a1n 
 
 a21 a22      a2 n 
   (5.3)
 
 a    ann   
 n1 an 2

Như vậy do (5.2) là hệ phương trình tuyến tính thuần nhất nên điều kiện cần và
đủ để  là giá trị riêng của ma trận trên là định thức của nó bằng không:
det(A - E) = 0 (5.4)
169
Phương trình (5.4) được gọi là phương trình đặc trưng của ma trận A. Định thức
det(A - E) được gọi là định thức đặc trưng của ma trận A. Định thức của ma trận trên,
ký hiệu PA(), được gọi là đa thức đặc trưng của ma trận vuông A.
Ví dụ. Tìm vec tơ riêng và trị riêng của ma trận:
3 1 3 
 
3 1 1 
2 2 0 

Trước hết ta tính đa thức đặc trưng của ma trận A:
3   1 3
 
PA ( )   3 1   1   (4   )(2  4)
 2 2   

Nghiệm của PA() = 0 là 1 = 4, 2 = 2j và 3 = -2j. Vì trường cơ sở là số thực


nên ta chỉ lấy  = 4. Để tìm vec tơ riêng tương ứng với  = 4 ta giải hệ :
3   1  3   1 
   
 3 1  1    2   0
 2
 2      3 

Ta nhận được các giá trị của , chúng tạo thành vec tơ riêng ứng với .
Như vậy khi khai triển định thức ta có một đa thức bậc n có dạng:
Pn() = n - p1n-1 - p2n-2 - ··· - pn = 0
Muốn xác định các hệ số của đa thức đặc trưng này ta dùng phương pháp
Fadeev-Leverrier. Ta xét ma trận A:
 a11 a12    a1n 
 
a a22    a2 n 
A   21
    
 
a    ann 
 n1 an 2
Ta gọi vết của ma trận A là số:
vet(A) = a11 + a22 + ··· + ann
Khi đó tham số pi của Pn() được xác định như sau:
p1 = vet(B1) với B1 = A
p2 = (1/2)vet(B2) với B2 = A(B1-p1E)
p3 = (1/3)vet(B3) với B3 = A(B2-p2E)
......
Chương trình tính các hệ số pi như sau:
170
Chương trình 5-6
// Faddeev_Leverrier;
#include <stdio.h>
#include <conio.h>
#include <ctype.h>

#define max 50

void main()
{

int i,j,k,m,n,k1,t;
float vet,c1,d;
char tl;
float p[max];
float a[max][max],b[max][max],c[max][max],b1[max][max];

clrscr();
printf("Cho bac cua ma tran n = ");
scanf("%d",&n);
printf("Cho cac phan tu cua ma tran a : \n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j );
scanf("%f",&a[i][j]);
}
printf("\n");
clrscr();
printf("Ma tran ban da nhap");
printf("\n");
for (i=1;i<=n;i++)

171
{
for (j=1;j<=n;j++)
printf("%10.5f",a[i][j]);
printf("\n");
}
t=1;
flushall();
while (t)
{
printf("\n");
printf("Co sua ma tran khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
flushall();
}
if (toupper(tl)=='K')
t=0;
}
printf("Ma tran ban dau");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%10.5f",a[i][j]);
printf("\n");

172
}
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
b[i][j]=a[i][j];
for (k=1;k<=n-1;k++)
{
vet=0.0;
for (i=1;i<=n;i++)
vet+=b[i][i];
p[k]=vet/k;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
if (j!=i)
c[i][j]=b[i][j];
if (j==i)
c[i][j]=b[i][j]-p[k];
}
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
b[i][j]=0.0;
for (k1=1;k1<=n;k1++)
b[i][j]+=a[i][k1]*c[k1][j];
}
}
vet=0.0;
for (i=1;i<=n;i++)
vet+=b[i][i];
p[n]=vet/n;
printf("\n");
printf("Cac he so cua da thuc dac trung\n");

173
printf("\n");
d=1.0;
printf("%6.2f",d);
for (i=1;i<=n;i++)
{
c1=-p[i];
printf("%5c%6.2f",' ',c1);
}
getch();
}
Phương pháp Mises
Thuật toán Mises tìm giá trị riêng lớn nhất của một ma trận A. Nếu ma trận A
là thực và mỗi trị riêng bội k có đủ k vec tơ riêng độc lập tuyến tính thì việc tính toán
sẽ cho ta giá trị riêng lớn nhất.
Một vectơ V bất kì có thể được viết dưới dạng:
n
V  v1 X 1  v2 X 2      vn X n   vi X i (5.5)
i 1

Trong đó X1, X2,.., Xn là các véc tơ riêng tương ứng với các giá trị riêng 1, 2,
3,.., n và v1, v2, v3,..., vn là các hằng số.
Khi nhân A với V ta có:
AV = Av1X1 + Av2X2 +....+ AvnXn
Do: Av1X1 = v1AX1 = v11X1 ; Av2X2 = v2AX2 = v22X2 v.v.
Nên: AV = v11X1 + v22X2 +...+ vnnXn
n n
AV   vi Ai X i   vi i X i
i 1 i 1

Lại nhân biểu thức trên với A ta có:


A2V = v11 AX1 + v22 AX2 + ··· + vnnAXn
= v121X1 + v222 X2 +...+ vnn2 Xn
Và tiếp đến lần thứ p ta có:
n
AV   vi ip X i
i 1

Lấy p1 làm thừa số chung ta có:

174
  2 
p
 3 
p
 n 
p

A V   v1 X 1  v2   X 2  v3   X 3      vn   X n 
p p

 1   1   1 
1
 

Tương tự ta có:
  2 
p 1
 3 
p 1
 n 
p 1

A V 
p 1 p 1
v1 X 1  v2   X 2  v3   X 3      vn   X n 
 1   1   1 
1
 

Khi p rất lớn,vì 1 > 2 > 3 >,..., n nên:


 i 
   0 khi p  
 1 
Do đó: lim A pV  1p v1 X 1 (5.6)
p 

lim A p 1V  1p 1v1 X 1


p 

Nghĩa là khi p đủ lớn thì:


A pV  1p v1 X 1

A p 1V  1p 1v1 X 1

Do đó: A p 1V  1 A pV
Hay:  
A A pV  1 A pV

Như vậy A pV là véc tơ riêng của A ứng với 1 còn giá trị riêng 1 sẽ là:
A p 1V
lim  1
p  A pV

Trong thực tế để tránh vượt quá dung lượng bộ nhớ khi 1 khá lớn, các vectơ Vk
được chuẩn hoá sau mỗi bước bằng cách chia các phần tử của nó cho phần tử lớn nhất
mk và nhận được vectơ V’k
Như vậy các bước tính sẽ là:
- Cho một vec tơ V bất kì (có thể là V = { 1, 1, 1,..., 1}T)
- Tính V1 = AV và nhận được phần tử lớn nhất là m1j từ đó tính tiếp
V1 = V1/m1j
Một cách tổng quát, tại lần lặp thứ p ta nhận được vectơ Vp và phần tử lớn nhất
mpj thì V’p = Vp/ mpj.
Tính V p 1  AV p với vp+1,j là phần tử thứ j của Vp+1. Ta có:

 lim V p  X 1
 p 

 lim v p 1, j  1
p 

175
Ví dụ. Tìm giá trị riêng lớn nhất và vec tơ riêng tương ứng của ma trận:
 17 24 30 17 
 
 8 13 20 7 
A
2 10 8 6 
 
  23  43  54  26 
 
Chọn V= {1, 1, 1, 1}T ta tính được:

V V1 = AV V’1 V2 = V’2
AV’1
1 88 -0.6027 -6.4801 -0.5578
1 48 -0.3288 -5.6580 -0.4870
1 26 -0.1781 0.0818 0.0070
1 -146 1 11.6179 1
 11.6179
V3 = V’3 V4 = AV’3 V’4 V5 =
AV’2 AV’4
-3.9594 -0.5358 -3.6823 -0.5218 -3.5718
-3.6526 -0.4942 -3.5196 -0.4987 -3.4791
0.0707 0.0096 0.0630 0.0089 0.0408
7.3902 1 7.0573 1 6.9638
 7.3902 7.0573 6.9638

V’5 V6= AV’5 V’6 V7= AV’6 V’7


-0.5129 -3.5341 -0.5075 -3.5173 -0.5043
-0.4996 -3.4809 -0.4999 -3.4868 -0.5000
0.0059 0.0250 0.0036 0.0147 0.0021
1 6.9634 1 6.9742 1
 6.9634 6.9742

Ta xây dựng chương trình theo thuật toán trên như sau:

176
Chương trình 5-7
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#define max 50

void main()
{
int i,j,k,n,t;
char tl;
float t0,t1,epsi,s;
float a[max][max];
float x0[max],x1[max];

clrscr();
printf("Phuong phap lap luy thua tim tri rieng lon nhat\n");
printf("Cho so hang va cot cua ma tran n = ");
scanf("%d",&n);
printf("Cho cac phan tu cua ma tran a : \n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
printf("Ma tran ban da nhap\n");
printf("\n");
for (i=1;i<=n;i++)
{

177
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
flushall();
t=1;
while (t)
{
printf("\nCo sua ma tran khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
if (toupper(tl)=='K')
t=0;
}
epsi=1e-5;
printf("\nMa tran ban dau\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
printf("\n");

178
for (i=1;i<=n;i++)
x0[i]=1;
k=1;
t=0;
t1=0;
do
{
t0=t1;
for (i=1;i<=n;i++)
{
x1[i]=0;
for (j=1;j<=n;j++)
x1[i]=x1[i]+a[i][j]*x0[j];
}
s=0;
j=0;
for (i=1;i<=n;i++)
if (s<fabs(x1[i]))
{
j=i;
s=fabs(x1[i]);
}
t1=x1[j];
for (i=1;i<=n;i++)
x1[i]=x1[i]/t1;
if (fabs(t1-t0)<epsi)
{
printf("Da thuc hien %d buoc lap\n",k);
printf("Gia tri rieng lon nhat Vmax = %15.5f\n",t1);
printf("Vec to rieng tuong ung\n");
for (i=1;i<=n;i++)
printf("%.5f\n",x1[i]);

179
t=1;
}
if (fabs(t1-t0)>epsi)
{
for (i=1;i<=n;i++)
x0[i]=x1[i];
k=k+1;
}
if (k>max)
t=1;
}
while(t==0);
getch();
}
Áp dụng. Dùng chương trình này tính gía trị riêng và vectơ riêng của ma trận:
 2 1 0 
 
 9 4 6 
  8 0  3
 
Ta nhận được giá trị riêng là 3.0000 và vec tơ riêng là x = {-0.75, 0.75, 1}T
Như chúng ta đã nói trước đây, phương pháp Mises (hay còn gọi là phương
pháp lặp lũy thừa) chỉ cho phép tìm giá trị riêng lớn nhất và vectơ riêng tương ứng của
ma trận. Để xác định các giá trị riêng khác, ma trận A được biến đổi thành một ma trận
khác A1 mà các giá trị riêng là 2 > 3 >... Phương pháp này gọi là phương pháp
xuống thang. Sau đây là phương pháp biến đổi ma trận:
Giả sử X1 là vec tơ riêng của ma trận A tương ứng với giá trị riêng 1 và W1 là
vec tơ riêng của ma trận AT tương ứng với giá trị riêng 1. Từ định nghĩa AX1 = 1X1
ta viết:
(A - E)X1 = 0
Ta tạo ma trận A1 dạng:
 (5.7)
AA  1 T
1 T XW
1 1
W X1 1

180
Ta chú ý là X1W1T là một ma trận còn W 1T X 1 là một con số. Khi nhân hai vế của

biểu thức (5.7) với X1 và chý ý đến tính kết hợp của tích các ma trận, ta có:
1
A1 X 1  AX 1  T X 1W 1T X 1
W1 X 1

W T X1
 AX 11 X 1 1 (5.8)
W 1T X 1

 AX 11 X 1
0

A1 chấp nhận giá trị riêng bằng không.


Nếu X2 là vec tơ riêng tương ứng với giá trị riêng 2, thì khi nhân A1 với X2 ta
có:
   1
XW X
T
AX
1 2 AX 2 T 1 1 2 (5.9)
W X 1 1
T

 AX   X W X
2 1 1
1
T
2

W X 1 1

Theo định nghĩa vì W1 là vectơ riêng của AT nên:


1W1 = AT W1 (5.10)
Mặt khác do:
(AX)T = XTAT và (AT)T = A
Nên khi chuyển vị (5.10) ta nhận được:
(ATW1)T = 1WT1
Hay:
W1TA = 1W1T (5.11)
Khi nhân (5.11) với X2 ta có:
1W1TX2 = W1TAX2
Và do định nghĩa:
AX2 = 2X2
Nên:
1W1TX2 = W1T 2X2
Vậy thì:
(1 - 2) W1T X2 = 0
Khi 1  2 thì:
W1T X2 = 0 (5.12)
Cuối cùng thay (5.12) vào (5.9) ta có:
181
A1X2 = AX2 = 2X2
Như vậy 2 là giá trị riêng lớn nhất của ma trận A1 và như vậy có thể áp dụng
thuật toán này để tìm các giá trị riêng còn lại của ma trận. Các bước tính toán như sau:
- Khi đã có 1 và X1 ta tìm W1 là vec tơ riêng của AT ứng với giá trị riêng 1
(ví dụ tìm W1 bằng cách giải phương trình (AT - 1E)W1 = 0). Từ đó tính ma trận A12
theo (5.7).
- Tìm giá trị riêng và vec tơ riêng của A1 bằng cách lặp luỹ thừa và cứ thế tiếp
tục và xuống thang (n - 1) lần ta tìm đủ n giá trị riêng của ma trận A.
Ví dụ. Tìm giá trị riêng và vectơ riêng của ma trận sau:
 17 24 30 17 
 
 8 13 20 7 
A
2 10 8 6 
 
  23  43  54  26 
 
Ta đã tìm được giá trị riêng lớn nhất 1 = 7 và một vectơ riêng tương ứng:
X1 = { 1, 1, 0, -2}T.
Ma trận AT có dạng:
 17 8 2  23 
 
 24 13 10  43 
A
30 20 8  54 
 
 17 7 6  26 
 
Và theo phương trình (AT -1E)W1 = 0 ta tìm được vectơ W1 = {293,695,746,434}T
Ta lập ma trận mới A1 theo (5.7):
 293 695 746 434 
 
X 1W1T 7  293 695 746 434 
1 T 
W1 X 1 120  0 0 0 0 
 
  586  1390  1492  868 
 
Và:
  0.0917  16.5417  13.5167  8.3167 
 
  9.0917  27.5417  23.5167  18.3167 
A1   
2 10 8 6
 
 11.1833 38.0833 
 33.0333 24.6333 
Từ ma trận A1 ta tìm tiếp được 2 theo phép lặp luỹ thừa và sau đó lại tìm ma
trận A3 và tìm giá trị riêng tương ứng.
Chương trình lặp tìm các giá trị riêng và vec tơ riêng của ma trận như sau:
182
Chương trình 5-8
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#define max 50

void main()
{
float a[max][max],vv[max][max],at[max][max];
float x[max],y[max],vd[max];
int i,j,k,n,l,t;
float vp,v1,z,epsi,va,ps;
char tl;

clrscr();
epsi=0.000001;
printf("Cho bac cua ma tran n = ");
scanf("%d",&n);
printf("Cho cac phan tu cua ma tran a : \n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
clrscr();
printf("Ma tran ban da nhap");
printf("\n");
for (i=1;i<=n;i++)

183
{
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
t=1;
flushall();
while (t)
{
printf("\n");
printf("Co sua ma tran khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
if (toupper(tl)=='K')
t=0;
}
for (l=1;l<=n;l++)
{
for (i=1;i<=n;i++)
x[i]=1;
vp=1.23456789;
k=0;
for (k=1;k<=40;k++)
{

184
for (i=1;i<=n;i++)
{
y[i]=0;
for (j=1;j<=n;j++)
y[i]=y[i]+a[i][j]*x[j];
}
v1=y[1]/x[1];
z=0;
for (i=1;i<=n;i++)
if (fabs(y[i])>z)
z=y[i];
for (i=1;i<=n;i++)
x[i]=y[i]/z;
if (fabs(vp-v1)<epsi)
break;
vp=v1;
}
{
printf("Gia tri rieng : %9.6f\n",v1);
printf("Vec to rieng : \n");
for (i=1;i<=n;i++)
printf("%.5f\n",x[i]);
printf("\n");
getch();
}
vd[l]=v1;
va=v1;
for (i=1;i<=n;i++)
vv[l][i]=x[i];
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
at[i][j]=a[j][i];

185
for (i=1;i<=n;i++)
x[i]=1;
vp=1.23456;
k=0;
for (k=1;k<=40;k++)
{
for (i=1;i<=n;i++)
{
y[i]=0;
for (j=1;j<=n;j++)
y[i]=y[i]+at[i][j]*x[j];
}
v1=y[1]/x[1];
z=0;
for (i=1;i<=n;i++)
if (fabs(y[i])>z)
z=y[i];
for (i=1;i<=n;i++)
x[i]=y[i]/z;
if (fabs(vp-v1)<epsi)
break;
vp=v1;
}
if (fabs(vp-v1)>epsi)
{
printf("Khong hoi tu sau 40 lan lap\n");
getch();
exit(1);
}
if (fabs(va-v1)>3*epsi)
{
printf("Co loi\n");

186
getch();
exit(1);
}
ps=0;
for (i=1;i<=n;i++)
ps=ps+x[i]*vv[l][i];
ps=v1/ps;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
a[i][j]=a[i][j]-ps*vv[l][i]*x[j];
}
}
Ví dụ. Dùng chương trình này tìm giá trị riêng của ma trận:
 23  4 16 
 
 40  5 32 
  20 4  13 
 
Ta nhận được kết quả:
Giá trị riêng 3.00000 vec tơ riêng
0.529411
1.000000
-0.411765
Giá trị riêng 3.000000 vec tơ riêng
-0.833336
-0.166678
1.000000
Giá trị riêng -1.000000 vec tơ riêng
0.500000
1.000000
-0.500000
5.2. Giải hệ đại tuyến
Bài toán cơ bản:

187
Cho hệ gồm n phương trình đại số tuyến tính với n ẩn:
a11x1+ a12x2+...+ a1nxn = b1
a21x1+ a22x2+...+ a2nxn = b2
... ... ...
an1x1+ an2x2+...+ annxn = bn
Viết dưới dạng matrix:
A.X = B
Giả thiết det(A)  0: Hệ này có nghiệm duy nhất.
Ta có thể tìm nghiệm theo quy tắc CRAMER hoặc sử dụng ma trận nghịch đảo
nhưng cách này đòi hỏi phép tính khá lớn và không thuận lợi khi ma trận A xấu.
Chúng ta chỉ nghiên cứu các phương pháp triển khai hữu hiệu trên máy tính. Có
thể phân loại chúng thành hai nhóm chính:
- Các phương pháp trực tiếp: Gauss, Gauss Jordan, phân tích LU,...
- Các phương pháp lặp: Lặp đơn, Gauss - Seidel, lặp Gradient liên hợp…
5.2.1. Phương pháp giải trực tiếp
a. Phương pháp khử Gauss
Chúng ta biết rằng các nghiệm của hệ đại tuyến không đổi nếu ta thay một hàng
bằng tổ hợp tuyến tính của các hàng khác. Như vậy bằng một loạt các biến đổi ta có
thể đưa hệ đại tuyến ban đầu về dạng tam giác. Đó chính là nội dung của phương pháp
khử Gauss. Chúng ta đi xét hệ phương trình:
a11x1  a12 x2  a13 x3  b1

a21x1  a22 x2  a23 x3  b2
a x  a x  a x  b
 31 1 32 2 33 3 3

Nhân hàng thứ nhất với a21/a11 ta có:


a21 a a
a21x1  a12 x2  21 a13 x3  21 b1
a11 a11 a11

Số hạng đầu của phương trình bằng số hạng đầu của hàng thứ hai trong hệ
phương trình ban đầu. Khi trừ hàng một đã được biến đổi cho hàng 2 ta nhận được
hàng 2 mới:
 a   a  a
0 x1   a22  21 a12  x2   a23  21 a13  x3  b2  21 b1
 a11   a11  a11

Ta tiếp tục cách này để loại trừ x1 ra khỏi hàng thứ 3. Phương trình trở thành:

188
 a12
 a11     x1   b1 
a13
     

 0 a22     x2    b2 
a23
 0 a
 32
   x3   b3 
a33

Với a,11 = a11, a,12 = a12, a,13 = a13, a,13 = a13, b,1 = b1
a21 a21 a31
  a22 
a22 a12   a23 
a23 a13   a32 
a32 a12
a11 a11 a11

a31 a21 a31


  a33 
a33 a13 b2  b2  b1 b3  b3  b1
a11 a11 a11

Ta loại trừ số hạng chứa x3 trong dòng thứ 3 bằng cách tương tự. Ta nhân hàng
thứ 2 trong hệ A'X = B' với a,32/a,22 và đem trừ đi hàng thứ 3 trong hệ mới. Như vậy số
hạng chứa x3 biến mất và ta nhận được ma trận tam giác trên.
 a12
 a11     x1   b1 
a13
     
 0 a22     x2    b2 
a23
 0
 0    x3   b3 
a33

Với   a11
a11    a12
a12    a13
a13  b1  b1   a22
a22    a23
a23 


a32 
a33
b2  b2   a33
a33   a b3  b3  b
 23
a22  2
a22

Các phép tính này chỉ thực hiện được khi a11  0 và a,11  0.
Với một hệ có n phương trình, thuật tính hoàn toàn tương tự. Sau đây là chương
trình giải hệ phương trình n ẩn số bằng phương pháp khử Gauss.
Chương trình 5-9
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#define max 10

void main()
{
float b[max],x[max];
float a[max][max];
int i,j,k,n,t;
189
float c,s,d;
char tl;

clrscr();
printf("Cho so phuong trinh n = ");
scanf("%d",&n);
printf("Cho cac phan tu cua ma tran a :\n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
printf("Ma tran a ma ban da nhap\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
printf("\n");
t=1;
flushall();
while (t)
{
printf("Co sua ma tran a khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");

190
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
if (toupper(tl)=='K')
t=0;
}
printf("Ma tran a ban dau\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
printf("\n");
printf("Cho cac phan tu cua ma tran b : \n");
for (i=1;i<=n;i++)
{
printf("b[%d] = ",i);
scanf("%f",&b[i]);
}
printf("\n");
printf("Ma tran b ma ban da nhap\n");
printf("\n");
for (i=1;i<=n;i++)
printf("b[%d] = %15.5f\n",i,b[i]);
printf("\n");
flushall();
t=1;

191
while (t)
{
printf("Co sua ma tran b khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%f",&i);
printf("b[%d] = ",i);
scanf("%f",&b[i]);
}
if (toupper(tl)=='K')
t=0;
}
printf("\n");
printf("Ma tran b\n");
for (i=1;i<=n;i++)
printf("b[%d] = %15.5f\n",i,b[i]);
printf("\n");
for (k=1;k<=n-1;k++)
{
for (i=k+1;i<=n;i++)
{
b[i]=b[i]-b[k]*a[i][k]/a[k][k];
for (j=k+1;j<=n;j++)
a[i][j]=a[i][j]-a[k][j]*a[i][k]/a[k][k];
}
}

{
if (a[n][n]==0)
if (b[n]==0)

192
printf("He da cho vo nghiem");
else
{
printf("He da cho co vo so nghiem");
x[n]=c;
}
else
x[n]=b[n]/a[n][n];
for (i=n-1;i>=1;i--)
{
s=0;
for (k=i+1;k<=n;k++)
s=s+a[i][k]*x[k];
x[i]=(b[i]-s)/a[i][i];
}
printf("\n");
printf("Nghiem cua he da cho la\n");
printf("\n");
for (i=1;i<=n;i++)
printf("x[%d] = %15.5f\n",i,x[i]);
getch();
}
}
b. Phương pháp Gauss – Jordan
Xét hệ phương trình AX = B. Khi giải hệ bằng phương pháp Gauss ta đưa nó về
dạng ma trận tam giác sau một loạt biến đổi. Phương pháp khử Gauss-Jordan cải tiến
khử Gauss bằng cách đưa hệ về dạng:
EX = B*
Và khi đó nghiệm của hệ chính là B*. Trong phương pháp Gauss-Jordan mỗi
bước tính phải tính nhiều hơn phương pháp Gauss nhưng lại không phải tính nghiệm.
Để đưa ma trận A về dạng ma trận E tại bước thứ i ta phải có aii = 1 và aij = 0. Như vậy
tại lần khử thứ i ta biến đổi:

193
1.aij = aij/aii (j = i + 1, i + 2,..., n)
2.k = 1, 2,..., n
akj = akj - aijaki (j = i + 1, i + 2,..., n)
bk = bk - biaki
Ví dụ. Cho hệ phương trình
8 4 2 0   x1   24 
     
 4 10 5 4   x2   32 
 
 2 5 6.5 4   x3   26 
     
0 4 4 9   x4   21 

Biến đổi lần 1: Ta chia hàng 1 cho a11 = 8, nhân hàng 1 vừa nhận được với 4 và
lấy hàng 2 trừ đi, nhân hàng 1 vừa nhận được với 2 và lấy hàng 3 trừ đi, giữ nguyên
hàng 4 vì phần tử đầu tiên đã bằng 0 ta có:
 1 0.5 0.25 0   x1   3 
     
0 8 4 4   x2   20 
 
0 4 6 4   x3   20 
     
0 4 9   x4   21 
 4

Biến đổi lần 2: Ta chia hàng 2 cho a22 = 8, nhân hàng 2 vừa nhận được với 0.5
và lấy hàng 1 trừ đi, nhân hàng 2 vừa nhận được với 4 và lấy hàng 3 trừ đi, nhân hàng
2 vừa nhận được với 4 và lấy hàng 4 trừ đi ta có:
1 0 0 0.25   x1  1.75 
     
0 1 0.5 0.5   x2   2.5 
 
0 0 4 2   x3   10 
     
0 0 2 7   x4   11 

Biến đổi lần 3: Ta chia hàng 3 cho a33 = 4, giữ nguyên hàng 1, nhân hàng 3 vừa
nhận được với 0.5 và lấy hàng 2 trừ đi, nhân hàng 3 vừa nhận được với 2 và lấy hàng 4
trừ đi ta có:
1 0 0  0.25   x1  1.75 
     
0 1 0 0.25   x2  1.25 
 
0 0 1 0.5   x3   2.5 
     
0 6   x4   6 
 0 0

Biến đổi lần 4: Ta chia hàng 4 cho a44 = 6, nhân hàng 4 vừa nhận được với
- 0.25 và lấy hàng 1 trừ đi, nhân hàng 4 vừa nhận được với 0.25 và lấy hàng 2 trừ đi,
nhân hàng 4 vừa nhận được với 0.5 và lấy hàng 3 trừ đi ta có:
194
1 0 0 0   x1   2 
     
0 1 0 0   x2   1 
 
0 0 1 0   x3   2 
     
0 1   x4   1 
 0 0

Và ta có ngay vectơ nghiệm.

Chương trình 5-10


#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#define spt 10

void main()
{
float a[spt][2*spt];
float b[spt];
int i,j,k,n,m,t;
float max,c;
char tl;

clrscr();
printf("Cho so phuong trinh n = ");
scanf("%d",&n);
printf("Cho cac phan tu cua ma tran a :\n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
195
printf("Ma tran a ma ban da nhap");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
printf("\n");
t=1;
flushall();
while (t)
{
printf("Co sua ma tran a khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
if (toupper(tl)=='K')
t=0;
}
printf("Ma tran a\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)

196
printf("%15.5f",a[i][j]);
printf("\n");
}
printf("\n");
printf("Cho cac phan tu cua ma tran b : \n");
for (i=1;i<=n;i++)
{
printf("b[%d] = ",i);
scanf("%f",&b[i]);
}
printf("\n");
printf("Ma tran b ma ban da nhap\n");
printf("\n");
for (i=1;i<=n;i++)
printf("b[%d] = %15.5f\n",i,b[i]);
printf("\n");
t=1;
flushall();
while (t)
{
printf("Co sua ma tran b khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("b[%d] = ",i);
scanf("%f",&b[i]);
}
if (toupper(tl)=='K')
t=0;
}

197
printf("\n");
printf("Ma tran b\n");
printf("\n");
for (i=1;i<=n;i++)
printf("%15.5f\n",b[i]);
printf("\n");
t=1;
flushall();
i=1;
while (t)
{
if (a[i][i]==0)
{
max=0;
m=i;
for (k=i+1;k<=n;k++)
if (max<fabs(a[k][i]))
{
m=k;
max=fabs(a[i][i]);
}
if (m!=i)
{
for (j=i;j<=n;j++)
{
c=a[i][j];
a[i][j]=a[m][j];
a[m][j]=c;
}
c=b[i];
b[i]=b[m];
b[m]=c;

198
}
if (m==i)
{
t=0;
printf("MA TRAN SUY BIEN");
}
}
if (a[i][i]!=0)
{
c=1/a[i][i];
for (j=i;j<=n;j++)
a[i][j]=a[i][j]*c;
b[i]=b[i]*c;
for (k=1;k<=n;k++)
if (k!=i)
{
c=a[k][i];
for (j=i;j<=n;j++)
a[k][j]=a[k][j]-a[i][j]*c;
b[k]=b[k]-b[i]*c;
}
}
i=i+1;
if (i==(n+1))
t=0;
}
if (i==(n+1))
{
printf("NGHIEM CUA HE");
printf("\n");
for (i=1;i<=n;i++)
printf("x[%d] = %15.5f\n",i,b[i]);

199
}
getch();
}

c. Phân tích LU và phân tích Cholesky


Trong phép phân tích LU, ma trận A có thể phân tích: A = L.U
Với L là ma trận tam giác dưới, với các phần tử nằm trên đường chéo chính
bằng 1, U là ma trận tam giác trên. Phép phân tích LU này bao giờ cũng thực hiện
được nếu các trụ (các phần tử chính a11, a22, a33, ...) khác không.
Nó sẽ duy nhất nếu các phần tử trên đường chéo chính của ma trận L bằng 1.
Với phân tích LU việc giải hệ phương trình:
A.X = b
Trở thành giải lần lượt hai hệ phương trình:
LY = b
Và: UX = Y
Thuật giải của phép phân tích LU thường dùng là của Crout. Trong trường hợp
ma trận A là đối xứng, khi đó phép phân tích trở nên đơn giản hơn rất nhiều, không đòi
hỏi các phần tử trên đường chéo chính của ma trận L bằng 1 nữa.
Thay vào đó ta sử dụng điều kiện:
U = LT
A = L.LT
Lúc đó L và U có các phần tử trên đường chéo chính giống nhau, các phần tử
này có thể là thực hay phức và gọi phép này là phân tích Cholesky.
(i). Phương pháp phân tích Crout: Phân tích ma trận A thành tích của hai ma
trận L và U sao cho: A = L.U. Để phân tích được, ma trận A phải có các giá trị trụ
khác 0. Các ma trận L và U là các ma trận tam giác dưới (L) và tam giác trên (U). Ma
trận L có các hệ số lkk = 1. Ma trận L và U bậc 3 có dạng :
 a11 a12 a13  1 0 0  r11 r12 r13 
     
A   a21 a22 a23  L   l21 1 0  U   0 r22 r23 
a a33  l  0 0 r 
 31 a32  31 l321 1   33 

Chúng ta nhắc lại quy tắc nhân hai ma trận A.B :

200
 a11 a12 a13   b11 b12 b13   c11 c12 c13 
     
A   a21 a22 a23  B   b21 b22 b23  C   c21 c22 c23 
a a33  b  c c33 
 31 a32  31 b32 c33   31 c32
Với: c11 = a11b11 + a12b21 + a13b31
c12 = a11b12 + a12b22 + a13b32
c13 = a11b13 + a12b23 + a13b33
c21 = a21b11 + a22b21 + a23b31
Tổng quát :
n
c ij   a ik b kj
k 1

Dùng quy tắc này cho hai ma trận L và U và cho đồng nhất các hệ số của chúng
với ma trận A, ta có:
1 0 0   r11 r12 r13   a11 a12 a13 
     
 l21 1 0    0 r22 r23    a21 a22 a23 
l   r33  a a33 
 31 l321 1   0 0  31 a32
a11 = 1. r11 + 0.0 + 0.0 = r11
a12 = r12 ; a13 = r13
a21 = l21r11
a22 = l21r12 + r22 ; a23 = l31r11
a31 = l31r11 ; a32 = l31r12
a33 = l31r13 + l32r23 + r33
Một cách tổng quát ta có:
Với j > i : lij = rji = 0
Với i = 1 : r1j = a1j (j = 1 tới n)
lj1 = aj1/r11 (j = 1 tới n)
Với i = 2 tới n
i 1
rij  aij   lik rkj ( j = i tới n)
k 1

i 1
a ji   l jk rki
l ji  k 1
(j = i tới n)
rii

Chương trình phân tích ma trận thành 2 ma trận như sau :

201
Chương trình 5-11
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define max 6

void main()
{
float a[max][max],r[max][max],l[max][max];
int i,j,k,n;
float tr,tl;
clrscr();
printf("Cho bac cua ma tran n = ");
scanf("%d",&n);
printf("Cho cac phan tu cua ma tran can phan tich a\n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
l[i][j]=0.0;
r[i][j]=0.0;
}
for (i=1;i<=n;i++)
{
r[1][i]=a[1][i];
l[i][i]=1.0;

202
l[i][1]=a[i][1]/a[1][1];
}
for (k=2;k<=n;k++)
{
for (j=k;j<=n;j++)
{
tr=0.0;
for (i=1;i<=k;i++)
tr=tr+l[k][i]*r[i][j];
r[k][j]=a[k][j]-tr;
}
if (k!=n)
{
for (i=1;i<=n;i++)
{
tl=0.0;
for (j=1;j<=k-1;j++)
tl=tl+l[i][j]*r[j][k];
l[i][k]=(a[i][k]-tl)/r[k][k];
}
}
else
printf("\n");
}
printf("Ma tran l :\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",l[i][j]);
printf("\n");
}
printf("Ma tran r :\n");

203
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",r[i][j]);
printf("\n");
}
getch();
}
Áp dụng. Dùng chương trình này phân tích ma trận ta được:
 2 1  2  1 0 0 2 1  2
     
A   3 1 1  L   1.5 1 0  R   0  2.5 4 
 7 5  3  3.5  6 1  0 6.4 
     0

(ii). Phương pháp phân tích Cholesky: Phương pháp Cholesky dùng để phân
tích một ma trận đối xứng sao cho A = UTU với U là một ma trận tam giác trên. Cách
phân tích cũng tương tự như phương pháp Crout . Ta xét các ma trận A và U bậc 3 như
sau :
 a11 a12 a13   r11 r12 r13 
   
A   a21 a22 a23  U   0 r22 r23 
a a33  0 0 r 
 31 a32  33 

Tích hai ma trận UT và U là :


T
 r11 r12 r13   r11 r12 r13   a11 a12 a13 
     
 0 r22 r23    0 r22 r23    a21 a22 a23 
0 0 r33   0 0 r33   a31 a32 a33 

Ta tính được :
r112 = a11
r11r12 = a12
r11r13 = a13
r11r12 = a21
r122 + r22r12 = a22
r222 + r12r13 = a23
r11r13 = a31
r13r12+ r23r21 = a32
r332 + r22r23 + r132 = a23
204
Tổng quát ta có :
aij
r11  a11 ; sij 
a11
i 1
rii  aii   ski2 , 1 i  n
k 1

i 1
aij   rki rkj
rij  k 1
, i j
rii

rij = 0 (i > j )
Dưới đây là chương trình:
Chương trình 5-12
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define max 6

void main()
{
float a[max][max],r[max][max],b[max][max];
int i,j,k,n,l;

clrscr();
printf("Cho bac cua ma tran n : ");
scanf("%d",&n);
printf("Cho cac phan tu cua ma tran can phan tich a :\n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
for (i=1;i<=n;i++)
205
for (j=1;j<=n;j++)
r[i][j]=0.0;
for (i=1;i<=n;i++)
{
if (a[i][i]<0.0)
{
printf("Ma tran khong duong");
getch();
exit(1);
}
else
{
r[i][i]=sqrt(a[i][i]);
for (j=1+i;j<=n;j++)
r[i][j]=a[i][j]/r[i][i];
for (k=i+1;k<=n;k++)
for (l=k;l<=n;l++)
a[k][l]=a[k][l]-r[i][k]*r[i][l];
}
}
printf("\n");
printf("Ma tran chuyen vi cua r\n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
b[j][i]=r[i][j];
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",b[i][j]);
printf("\n");
}
printf("\n");

206
printf("Ma tran r\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",r[i][j]);
printf("\n");
}
getch();
}
Ví dụ 1. Dùng chương trình này để phân tích ma trận:
10 7 8 7 6
 
7 5 6 5 4
 8 6 10 9 6
 
 7 5 9 10 7
6 4 6 7 9 

Ta có :
 3.162278 2.213594 2.529822 2.213594 1.897367 
 
 0 0.316228 1.264911 0.316228  0.631456 
U  0 0 1.414214 2.121320 1.414214 
 
 0 0 0 0.707107 0 
 1.732052 
 0 0 0 0

Ví dụ 2. Phân tích LU để giải phương trình:

 3 0,1 0, 2   x1   7,85 


 0,1    
 7 0,3   x2   19,3
0,3 0, 2 10   x3   71, 4 

Phân tích ma trận A thành ma trận L và U :

 1 0 0 3 0,1 0, 2 
U  0, 0333333 1 0 , U  0 7, 00333 0, 293333
 0,100000 0, 0271300 1  0 0 10, 0120 

Phân tích LY = b

 1 0 0   y1   7,85 
0, 0333333   y   19,3
 1 0  2  
 0,100000 0, 0271300 1   y3   71, 4 

207
Khai triển ra ta có:
y1 = 7,85
0,0333333y1 + y2 = -19,3
0,100000y1 – 0,0271300y2 + y3 = -19,3
Giải ra ta được:

 7,85 
 
 Y  19,5617 
 70, 0843 
 
Áp dụng phương trình UX = Y
3 0,1 0, 2   x1   7,85 
0 7, 00333 0, 293333  x   19,5617 
  2  
0 0 10, 0120   x3   71, 0843 
  

 3 
 
Giải ra ta được: X   2,5 
7, 00003
 
Chương trình giải hệ đại tuyến theo thuật toán Crout

Chương trình 4-13


#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#define max 6

void main()
{
float b[max],x[max],y[max];
float a[max][max],r[max][max],l[max][max];
int i,j,k,n,t;
float c,tr,tl,s;
char tloi;

208
clrscr();
printf("Cho so phuong trinh n = ");
scanf("%d",&n);
printf("Cho cac phan tu cua ma tran a : \n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
printf("Ma tran a ma ban da nhap");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%10.5f",a[i][j]);
printf("\n");
}
printf("\n");
t=1;
flushall();
while (t)
{
printf("Co sua ma tran a khong(c/k)?");
scanf("%c",&tloi);
if (toupper(tloi)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);

209
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
flushall();
}
if (toupper(tloi)=='K')
t=0;
}
printf("Ma tran a\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%10.5f",a[i][j]);
printf("\n");
}
printf("\n");
printf("Cho cac phan tu cua ma tran b : \n");
for (i=1;i<=n;i++)
{
printf("b[%d] = ",i);
scanf("%f",&b[i]);
}
printf("\n");
printf("Ma tran b ma ban da nhap");
printf("\n");
for (i=1;i<=n;i++)
printf("b[%d] = %10.5f\n",i,b[i]);
printf("\n");
t=1;
flushall();
while (t)
{

210
printf("Co sua ma tran b khong(c/k)?");
scanf("%c",&tloi);
if (toupper(tloi)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("b[%d] = ",i);
scanf("%f",&b[i]);
flushall();
}
if (toupper(tloi)=='K')
t=0;
}
printf("\n");
printf("Ma tran b\n");
printf("\n");
for (i=1;i<=n;i++)
printf("b[%d] = %10.5f\n",i,b[i]);
printf("\n");
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
r[i][j]=0.0;
l[i][j]=0.0;
}
for (i=1;i<=n;i++)
{
r[1][i]=a[1][i];
l[i][i]=1.0;
l[i][1]=a[i][1]/a[1][1];
}
for (k=2;k<=n;k++)

211
{
for (j=k;j<=n;j++)
{
tr=0.0;
for (i=1;i<=k;i++)
tr=tr+l[k][i]*r[i][j];
r[k][j]=a[k][j]-tr;
}
if (k!=n)
{
for (i=1;i<=n;i++)
{
tl=0.0;
for (j=1;j<=k-1;j++)
tl=tl+l[i][j]*r[j][k];
l[i][k]=(a[i][k]-tl)/r[k][k];
}
}
else
printf("\n");
}
if (l[1][1]==0.0)
if (b[1]==0.0)
printf("He da cho vo nghiem\n");
else
{
printf("He da cho co vo so nghiem\n");
y[n]=c;
}
else
y[1]=b[1]/l[1][1];
for (i=2;i<=n;i++)

212
{
s=0.0;
for (k=1;k<=i-1;k++)
s=s+l[i][k]*y[k];
y[i]=(b[i]-s)/l[i][i];
}
if (r[n][n]==0.0)
if (y[n]==0.0)
printf("He da cho vo nghiem\n");
else
{
printf("He da cho co vo so nghiem\n");
x[n]=c;
}
else
x[n]=y[n]/r[n][n];
for (i=n-1;i>=1;i--)
{
s=0.0;
for (k=i+1;k<=n;k++)
s+=r[i][k]*x[k];
x[i]=(y[i]-s)/r[i][i];
}
printf("\n");
printf("Nghiem cua he da cho la\n");
printf("\n");
for (i=1;i<=n;i++)
printf("x[%d] = %15.5f\n",i,x[i]);
getch();
}

213
(iii) Chương trình giải hệ đại tuyến theo phương pháp Choleski
Trong phương pháp Cholesky một ma trận đối xứng A được phân tích thành
dạng A = UTU trong đó U là một ma trận tam giác trên. Hệ phương trình lúc đó
chuyển thành AX = UTUX = B. Như vậy trước hết ta phân tích ma trận A thành tích
hai ma trận. Sau đó giải hệ phương trình UTY = B và cuối cùng là hệ UX = Y. Chương
trình mô tả thuật toán này được cho dưới đây:

Chương trình 4-14


#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#define max 6

void main()
{
float a[max][max],r[max][max];
float b[max],x[max],y[max];
int i,j,k,l,n,t;
float s;
char tl;

clrscr();
printf("Cho so phuong trinh n = ");
scanf("%d",&n);
printf("Cho cac phan tu cua ma tran a : \n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);

214
}
printf("\n");
printf("Ma tran a ma ban da nhap\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
printf("\n");
flushall();
t=1;
while (t)
{
printf("Co sua ma tran a khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[",i,",",j,"] = ");
scanf("%f",&a[i][j]);
}
if (toupper(tl)=='K')
t=0;
}
printf("Ma tran a\n");
printf("\n");
for (i=1;i<=n;i++)

215
{
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
printf("\n");
printf("Cho cac phan tu cua ma tran b : \n");
for (i=1;i<=n;i++)
{
printf("b[%d] = ",i);
scanf("%f",&b[i]);
}
printf("\n");
printf("Ma tran b ma ban da nhap\n");
printf("\n");
for (i=1;i<=n;i++)
printf("b[%d] = %15.5f\n",i,b[i]);
printf("\n");
flushall();
t=1;
while (t)
{
printf("Co sua ma tran b khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("b[%d] = ",i);
scanf("%f",&b[i]);
}
if (toupper(tl)=='K')

216
t=0;
}
printf("\n");
printf("Ma tran b\n");
printf("\n");
for (i=1;i<=n;i++)
printf("b[%d] = %15.5f\n",i,b[i]);
printf("\n");
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
r[i][j]=0.0;
for (i=1;i<=n;i++)
{
if (a[i][i]>=0)
{
r[i][i]=sqrt(a[i][i]);
for (j=1+i;j<=n;j++)
r[i][j]=a[i][j]/r[i][i];
for (k=i+1;k<=n;k++)
for (l=k;l<=n;l++)
a[k][l]=a[k][l]-r[i][k]*r[i][l];
}
}
for (k=1;k<=n;k++)
{
s=b[k];
if (k!=1)
for (i=1;i<=k-1;i++)
s=s+r[i][k]*y[i];
y[k]=-s/r[k][k];
}
for (i=n;i>=1;i--)

217
{
s=-y[i];
if (i!=n)
for (k=i+1;k<=n;k++)
s=s-r[i][k]*x[k];
x[i]=s/r[i][i];
}
printf("Nghiem cua he phuong trinh la\n ");
for (i=1;i<=n;i++)
printf("x[%d] = %10.5f\n",i,x[i]);
getch();
}
5.2.2. Phương pháp lặp giải hệ phương trình
Phương pháp Gauss thuộc loại phương pháp đúng hay còn gọi là phương pháp
trực tiếp. Ngoài ra còn có 1 loại phương pháp khác là phương pháp lặp, trong mục này
ta lần lượt xét một số phương pháp lặp thông dụng.
a. Phương pháp lặp đơn giải hệ phương trình
Phương pháp lặp đơn, hệ phương trình cho ở dạng vector: Ax = f
Ta chuyển hệ này về dạng tương đương: x = Bx + g
b11 b12  b1n
b 21 b 22  b 2n
Giả sử: B=    
b n1 b n 2  b nn
Sau đó ta xây dựng công thức tính lặp:

x ( m )  Bx ( m1)  g
 ( 0) (5.13)
x
n

Trong đó: (Bx)i = b x


j1
ij j , x(0) cho trước.

Phương pháp tính theo (5.13) gọi là phương pháp lặp đơn.

218
Sự hội tụ:
Giả sử  = (1 , 2 , . . . . ., n)T là nghiệm của hệ x = Bx + g , nếu xi(m)  i
khi m  , với i = 1, 2, 3 , . . . , n thì ta nói phương pháp lặp (5.13) hội tụ.
Ta đưa vào các ký hiệu: z = ( z1 , z2 , . . . , zn )T thì mỗi đại lượng sau:

z0  max z i  

z1  z1  z 2    zn 
z2  z12  z 22    z 2n 

Gọi là độ dài mở rộng của vector z, người ta còn gọi nó là chuẩn của z.

 n

0 r  max
i
 b ij
 j1

 n

r1  max  b ij
Đối với ma trận B = ( bi j), ta đặt: 
j
i 1
 n n
r2   . b ij
 i 1 j1

Người ta chứng minh được định lý sau đây về điều kiện hội tụ:
- Nếu r0 < 1 hoặc r1 < 1 hoặc r2 < 1 thì phương pháp lặp (5.13) hội tụ với bất
kỳ xấp xỉ ban đầu x(0) nào, đồng thời ta có sai số đánh giá:

rPm 
x (m)
  x (1)  x ( 0) 
P 1  rP P


rPm 
x (m)
  x ( m )  x ( m 1)
1  rP P

P

Trong đó: p = 0 nếu r0 < 1, p = 1 nếu r1 < 1, p = 2 nếu r2 < 1.


Khi ma trận A có tính chéo trội, khi đó các hệ số aii ≠ 0 và chuẩn ro < 1, phương
pháp lặp đơn được gọi là phương pháp lặp Jacobi.

Ví dụ. Chúng ta có phương trình


10 x1  2 x2  x3  10

 x1  10 x2  2 x3  12
 x  x  10 x  8
 1 2 3

Chúng ta đưa phương trình về dạng :

219
 1 1
 x1   5 x2  10 x3  1

 1 1 6
 x2   x1  x3 
 10 5 5
 1 1 4
 x3   10 x1  10 x2  5

Như vậy :
 1 1   
 0  5  10  1 
   

B 
1
0
1  5
và G   
 10 5  6
  4
 1  1 0  
 10 10  5

Dễ thấy B 1  3 /10 ; B 2  3 /10 và B 3  12 /100 nên phép lặp hội tụ.

(i) Ứng dụng lập trình (dùng C++)


#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#define max 10

void main()
{
float a[max][max];
float f[max],x0[max],x1[max];
int i,j,k,n,l,t;
float s,c,epsi;
char tl;

clrscr();
printf("Cho so phuong trinh n = ");
scanf("%d",&n);

220
printf("Cho cac phan tu cua ma tran a : \n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
printf("Ma tran a ma ban da nhap");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
printf("\n");
t=1;
flushall();
while (t)
{
printf("Co sua ma tran a khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
flushall();

221
}
if (toupper(tl)=='K')
t=0;
}
printf("Ma tran a\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%10.5f",a[i][j]);
printf("\n");
}
printf("\n");
printf("Cho cac phan tu cua ma tran f : \n");
for (i=1;i<=n;i++)
{
printf("f[%d] = ",i);
scanf("%f",&f[i]);
}
printf("\n");
printf("Ma tran f ma ban da nhap");
printf("\n");
for (i=1;i<=n;i++)
printf("f[%d] = %10.5f\n",i,f[i]);
printf("\n");
t=1;
flushall();
while (t)
{
printf("Co sua ma tran f khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')

222
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("f[%d] = ",i);
scanf("%f",&f[i]);
flushall();
}
if (toupper(tl)=='K')
t=0;
}
printf("\n");
printf("Ma tran f");
printf("\n");
for (i=1;i<=n;i++)
printf("f[%d] = %10.5f\n",i,f[i]);
printf("\n");
for (i=1;i<=n;i++)
x0[i]=0.0;
x0[1]=1.0;
printf("Cho so lan lap l = ");
scanf("%d",&l);
epsi=1e-5;
for (i=1;i<=n;i++)
{
c=1.0/a[i][i];
for (j=1;j<=n;j++)
if (j!=i)
a[i][j]*=c;
f[i]*=c;
a[i][i]=0.0;
}
k=1;

223
t=0;
do
{
for (i=1;i<=n;i++)
{
x1[i]=f[i];
for (j=1;j<=n;j++)
x1[i]=x1[i]-a[i][j]*x0[j];
}
s=0.0;
for (i=1;i<=n;i++)
s=s+fabs(x1[i]-x0[i]);
if (s>=epsi)
for (i=1;i<=n;i++)
x0[i]=x1[i];
if (s<epsi)
{
t=1;
printf("\n");
printf("Phep lap hoi tu sau %d buoc tinh",k);
printf("\n");
printf("NGHIEM CUA HE");
printf("\n");
for (i=1;i<=n;i++)
printf("x[%d] = %10.5f\n",i,x1[i]);
}
k=k+1;
if (k>l)
{
t=1;
printf("Phep lap khong hoi tu sau %d buoc tinh",k-1);
}

224
}
while (t==0);
getch();
}

b. Phương pháp lặp Seidel (hay còn gọi là Gauss - Seidel)


Là phương pháp cải tiến phương pháp lặp đơn một chút khi tính xấp xỉ thứ
(k + 1) của ẩn xi ta sử dụng các xấp xỉ thứ (k + 1) đã tính của ẩn x1, . . . , xi -1 .
n
Giả sử cho hệ: Ax  b  xi = i + 
j 1
ij x j với i = 1, 2,. . . , n

Lấy xấp xỉ ban đầu là x1(0) , x2(0) , . . . , xn(0)


Tiếp theo, giả sử ta đã biết xấp xỉ thứ k là xi(k) theo Seiden, ta sẽ tìm xấp xỉ
thứ ( k + 1) của nghiệm theo công thức:
 ( k 1) n

 x1  1    1 j x (jk )
 j 1

 ( k 1) n

 x2   2   21x1( k 1)    2 j x (jk )


 j 2


 i 1 n
 xi( k 1)   i    ij x (jk 1)   x (jk )

ij
j 1 j i
 n 1
 x ( k 1)   n    ij x (jk 1)   nn xn( k )


n
j 1

(Thông thường lặp Seidel hội tụ nhanh hơn lặp đơn)


Ví dụ 1. Cho hệ phương trình:
10 x1  x2  x3  12

2 x1  10 x2  x3  13
2 x  2 x  10 x  14
 1 2 3

Biết nghiệm đúng của hệ là (1, 1, 1)


Ta đưa về dạng thuận tiện cho phép lặp:
 x1  1.2  0.1x2  0.1x3

 x2  1.3  0.2 x1  0.1x3
 x  1.4  0.2 x  0.2 x
 3 1 2

Chọn lớp nghiệm gần đúng ban đầu: x1(o) = 1.2, x2(o) = 0, x3(o) = 0.
Sử dụng phương pháp lặp Seidel, ta có:
225
Lần lặp thứ 1:
 x11  1.2  0.1 0  0.1 0  1.2
 1
 x2  1.3  0.2 1.2  0.1 0  1.06
 1
 x3  1.4  0.2 1.2  0.2 1.06  0.948
Lần lặp thứ 2:
 x12  1.2  0.11.06  0.1 0.948  0.9992
 2
 x2  1.3  0.2  0.9992  0.1 0.948  1.00536
 1
 x3  1.4  0.2  0.9992  0.2 1.00536  0.999098
Và cứ thế tiếp tục cho lần lặp thứ 3, 4,…cho đến khi thỏa mãn sai số cho phép.
Ví dụ 2. Tìm nghiệm gần đúng của hệ phương trình sau bằng phương pháp lặp đơn.
4 x1  0,24 x 2  0,08 x3  8

0,09 x1  3x 2  0,15 x3  9
0,04 x  0,08 x  4 x  20
 1 2 3

Giải:
Hệ phương trình đã cho có dạng đường chéo trội, dễ dàng đưa về dạng
X= X   . Trong đó:

0  0,06 0,02  2

   0,03 0 
0,05 ;   3 
 0,01 0,02 0  5 

 x
 0,08  1 quá trình lặp hội tụ.

Chọn xấp xỉ đầu X0 =  = (2, 3, 5)


K X1 X2 X3
0 2 3 5
1 1,92 3,1924 5,044648
2 1,9093489 3,194952 5,0448056
3 1,909199 3,1949643 5,0448073

(i) Ứng dụng lập trình


 Dùng C++
#include <conio.h>
#include <stdio.h>
#include <math.h>
226
#include <stdlib.h>
#include <ctype.h>
#define max 6

void main()
{
float b[max],x[max];
float a[max][max];
int i,j,k,n,dem,t1;
float t,s,d,w,epsi;
char tl;

clrscr();
printf("Cho so an so n = ");
scanf("%d",&n);
printf("Cho cac phan tu cua ma tran a : \n");
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
{
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
printf("Ma tran a ma ban da nhap\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%10.5f",a[i][j]);
printf("\n");
}
printf("\n");

227
t1=1;
flushall();
while (t1)
{
printf("Co sua ma tran a khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("Cho chi so cot can sua : ");
scanf("%d",&j);
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
flushall();
}
if (toupper(tl)=='K')
t1=0;
}
printf("Ma tran a\n");
printf("\n");
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
printf("%15.5f",a[i][j]);
printf("\n");
}
printf("\n");
printf("Cho cac phan tu cua ma tran b : \n");
for (i=1;i<=n;i++)
{
printf("b[%d] = ",i);

228
scanf("%f",&b[i]);
}
printf("\n");
printf("Ma tran b");
printf("\n");
for (i=1;i<=n;i++)
printf("b[%d] = %10.5f\n",i,b[i]);
printf("\n");
t1=1;
flushall();
while (t1)
{
printf("Co sua ma tran b khong(c/k)?");
scanf("%c",&tl);
if (toupper(tl)=='C')
{
printf("Cho chi so hang can sua : ");
scanf("%d",&i);
printf("b[%d] = ",i);
scanf("%f",&b[i]);
flushall();
}
if (toupper(tl)=='K')
t1=0;
}
printf("\n");
printf("Ma tran b");
printf("\n");
for (i=1;i<=n;i++)
printf("b[%d] = %10.5f\n",i,b[i]);
printf("\n");
printf("Cho so lan lap k : ");

229
scanf("%d",&k);
printf("\n");
w=1;
epsi=1e-8;

for (i=1;i<=n;i++)
x[i]=0.0;
dem = 0;
do
{
dem=dem+1;
for (i=1;i<=n;i++)
{
s=0.0;
for (j=1;j<=n;j++)
s=s+a[i][j]*x[j];
d=x[i];
x[i]=(1-w)*d+w*(-s+a[i][i]*d+b[i])/a[i][i];
t=fabs(d-x[i]);
}
}
while ((dem<=k)&&(t>epsi*fabs(x[n])));
if (t<epsi*fabs(x[n]))
{
printf("Nghiem sau %d lan lap la :\n",dem);
for (i=1;i<=n;i++)
printf("x[%d] = %12.8f\n",i,x[i]);
}
else
{
printf("Khong dat do chinh xac sau %d lan lap\n",k);
printf("Nghiem cua lan lap cuoi cung la : \n");

230
for (i=1;i<=n;i++)
printf("x[%d] = %12.8f\n",i,x[i]);
}
getch();
}
 Dùng Matlab
Xây dựng hàm:
function x = gausseidel(a, b, x0, kmax)
%Tim nghiem cua he AX = B bang cach lap Gauss–Seidel.
if nargin < 4
kmax = 100;
end
if nargin < 3
x0 = zeros(size(b));
kmax = 100;
end
na = size(a,1);
x = x0;
for k = 1: kmax
x(1, :) = (b(1, :) - a(1, 2:na)*x(2: na, :))/a(1,1);
for m = 2:na-1
tmp = b(m, :) - a(m, 1:m-1)*x(1: m - 1, :) - a(m, m + 1:na)*x(m + 1:na,:);
x(m, :) = tmp/a(m, m);
end
x(na, :) = (b(na,:) - a(na,1:na - 1)*x(1:na - 1,:))/a(na, na);
err = sqrt(x - x0)'*(x - x0);
if err < eps
break;
end
x0 = x;
end
if k == kmax

231
fprintf('Khong hoi tu sau %d lan lap',kmax);
else
fprintf('Hoi tu sau %d lan lap',k);
end
c. Phương pháp lặp với hệ số giảm dư SOR
Phương pháp SOR tương tự như các phương pháp Jacobi và Gauss-Seidel,
nhưng nó sử dụng hệ số tỉ lệ làm giảm nhanh chóng các sai số xấp xỉ. Ngược lại với
các phương pháp cổ điển đã được thảo luận trong phần trước, kỹ thuật SOR là một
sự cải tiến gần đây hơn.
Kỹ thuật SOR là một trong lớp các phương pháp giảm dư để tính toán xấp xỉ
x(k) theo công thức:
 i 1 i 
xi( k )  1    xi( k 1)  bi   aij x j   aij x j 
(k ) ( k 1)

aii  j 1 j i 1 
Với ω là hệ số tỷ lệ.
Khi ω = 1, chúng ta có phương pháp Gauss-Seidel. Khi 0 < ω < 1, kỹ thuật này
được gọi là phương pháp giảm dư dưới và có thể được sử dụng để nhận được hội tụ
của một số hệ thống khi chúng không hội tụ theo phương pháp Gauss-Seidel.
Khi 1 < ω, các kỹ thuật này được gọi là các phương pháp giảm dư trên, được sử
dụng để gia tăng sự hội tụ cho các hệ thống sử dụng kỹ thuật lặp Gauss-Seidel. Những
phương pháp này được viết tắt là SOR (Successive Over-Relaxation) và được sử dụng
để tìm lời giải số của hệ đại tuyến.
Để xác định dạng ma trận của phương pháp SOR, chúng ta viết lại phương trình
trước đó như sau:
i 1 i
aii xi( k )    aij x(jk )  1    aii xi( k 1)    aij x(jk 1)  bi
j 1 j i 1

Vì vậy ở dạng vector, chúng ta có:


D   L  x( k )  1    D  U  x( k 1)  b

Nếu (D − ωL)−1 tồn tại, thì:


x( k )  T x( k 1)  c

Với Tω = (D − ωL)−1[(1 − ω)D + ωU] và cω = ω(D − ωL)−1b .


Ví dụ 1. Cho hệ phương trình tuyến tính Ax = b như sau:
4x1 +3x2 = 24
232
3x1 +4x2 − x3 = 30
−x2 +4x3 = −24
Có lời giải đúng: (3, 4, -5) t. Phương pháp Gauss-Seidel và phương pháp SOR
với ω = 1.25 sẽ được sử dụng để giải hệ này, bằng cách sử dụng xấp xỉ ban đầu
x (0) = (1, 1, 1) t cho cả hai phương pháp.
Với mỗi k =1, 2,..., các phương trình của phương pháp Gauss-Seidel cho:
x1(k) = −0.75x2(k−1) + 6
x2(k) = −0.75x1(k) +0.25x3(k−1) +7.5
x3(k) = 0.25x2(k) – 6
Và các phương trình của phương pháp SOR với ω = 1.25 là:
x1(k) = −0.25x1(k−1) − 0.9375x2(k−1) +7.5
x2(k) = −0.9375x1(k) − 0.25x2(k−1) +0.3125x3(k−1) +9.375
x3(k) = 0.3125x2(k) − 0.25x3(k−1) − 7.5.
Bảy lần lặp đầu tiên cho từng phương pháp được liệt kê trong Bảng 5.1 để
có chính xác đến bảy chữ số thập phân, phương pháp Gauss-Seidel yêu cầu 34 lần lặp,
nhưng trái lại, chỉ có 14 lần lặp đối với phương pháp SOR với ω = 1.25.
Bảng 5.1: Phương pháp Gauss-Seidel
k 0 1 2 3 4 5 6 7
x1(k) 1 5.250000 3.1406250 3.0878906 3.0549316 3.0343323 3.0214577 3.0134110
(k)
x1 1 3.812500 3.8828125 3.9267578 3.9542236 3.9713898 3.9821186 3.9888241
(k)
x1 1 −5.046875 −5.0292969 −5.0183105 −5.0114441 −5.0071526 −5.0044703 −5.0027940

Phương pháp SOR với ω =1.25


k 0 1 2 3 4 5 6 7
x1(k) 1 6.312500 2.6223145 3.1333027 2.957051 3.0037211 2.996327 3.0000498
(k)
x1 1 3.5195313 3.9585266 4.0102646 4.0074838 4.0029250 4.0009262 4.0002586
(k)
x1 1 −6.6501465 −4.6004238 −5.0966863 −4.9734897 −5.0057135 −4.9982822 −5.0003486

Câu hỏi đặt ra là giá trị thích hợp của ω được chọn như thế nào. Mặc dù không
có câu trả lời đầy đủ cho câu hỏi này trong trường hợp tổng quát với hệ tuyến tính n×n,
kết quả sau đây có thể được sử dụng trong các tình huống nhất định.
Nếu A là một ma trận xác định dương và 0 < ω < 2, thì phương pháp SOR hội
tụ cho bất kỳ lựa chọn lời giải xấp xỉ ban đầu nào [vector x(0)].

233
Thêm vào, nếu A là ma trận 3 đường chéo, thì ρ(Tg) = [ρ(Tj )]2 < 1, và sự lựa
chọn tối ưu của ω cho phương pháp SOR là:
2

1  1  [ T j ]2

Với sự lựa chọn ω này, chúng ta có ρ(Tω) = ω − 1.


Ví dụ 2. Cho ma trận:
4 3 0 
 3 4 1
 
 0 1 4 

Đây là ma trận 3 đường chéo. Ta có:


1 
4 0 0
   0 3 0   0 0.75 0 
Tj = D (L + U) =  0
-1 1
0  3 0 1  =  0.75 0 0.25 
 4    
  0 1 0   0 0 
1 
0.25
0 0
 4 
Và:
det(Tj − λI) = −λ(λ2 − 0.625) và ρ(Tj ) = 0.625
Vậy lựa chọn tối ưu của ω là:
2 2
   1.24
1  1  [ T j ]2 1  1  0.625

Điều này giải thích sự hội tụ nhanh chóng thu được trong ví dụ 1 bằng cách sử
dụng ω = 1.25.
d. Phương pháp gradient liên hợp (Conjugate gradient method)
Phương pháp gradient liên hợp của Hestenes và Stiefel [HS] đã được phát triển
như là một phương pháp nhằm thiết kế để giải hệ đại tuyến xác định dương (n x n)
phương trình.
Phương pháp này thường kém hơn phương pháp ước lượng Gauss, từ chỗ cả
hai phương pháp đều yêu cầu n bước chính để xác định lời giải và các bước của
phương pháp gradient liên hợp đòi hỏi nhiều phép tính hơn so với phương pháp ước
lượng Gauss.
Tuy nhiên, phương pháp gradient liên hợp là rất hữu ích khi sử dụng như là
phương pháp xấp xỉ để giải hệ ma trận thưa lớn và nó càng hiệu quả hơn nữa, nếu bài

234
toán là không dừng. Những bài toán này thường gặp ở các bài toán giá trị biên, ví dụ:
bài toán dự báo ngập lũ ở một vùng nào đó, hay bài toán tính kết cấu chịu tải trọng
động...
Để giải hệ phương trình:  P(I, J)  F(J) = G(I)
Giá trị ban đầu ước lượng là: F0(J), gây ra phần dư U(I), ta biểu diễn:
U(I) = G(I) - P(I, J)  F
O (J) .

Đặt: V(I) = U(I)


UU = {U(I).U(I)}
Vòng lặp:
W(I) = {P(I, J).V(J)}
VW = {V(I).W(I)}
AA = UU/VW
F(I) = F(I) + AA.V(I)
U(I) = U(I) - AA.W(I)
WW = {U(I).U(I)}
BB = WW/UU
V(I) = U(I) + BB.V(I)
UU = WW
UU ≤  ?
Quá trình này được lặp lại mãi đến khi UU ≤  (sai số cho phép của bài toán)
thì dừng.
*
* * *
Theo khảo sát ở một bài toán của Doug Faires & Dick Burden, thì các phương
pháp lặp có hiệu quả nhất được sắp theo thứ tự như sau :
(i) Phương pháp lặp gradient liên hợp;
(ii) Phương pháp lặp có hệ số giảm dư (SOR);
(iii) Phương pháp lặp Gauss – Seidel;
(iv) Phương pháp lặp Jacobi.

235
5.2.3. Hệ phương trình số phức
Giả sử ta có một hệ phương trình số phức có dạng AX = B, trong đó A = C + jD
, B = E + jF và X = Y + jZ . Ta viết lại phương trình dưới dạng sau:
(C + jD)(Y + jZ) = (E + jF)
Nhân biểu thức vế trái và cân bằng phần thực với phần thực và phần ảo với
phần ảo ta nhận được hệ mới:
CY - DZ = E

DY  CZ = F
Như vậy chúng ta nhận được một hệ gồm 2n phương trình số thực. Giải hệ này
và kết hợp các phần thực và phần ảo ta nhận được nghiệm của hệ phương trình ban
đầu. Chương trình giải hệ phương trình số phức được xây dựng như sau:

Chương trình 4-15


#include <conio.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#define max 20

void main()
{
int i,j,k,l,n,m;
float s,t,a[max][max],b[max][max],x[max];

clrscr();
printf("Cho so an so cua phuong trinh n = ");
scanf("%d",&n);
printf("Cho phan thuc cua cac he so,ke ca ve phai\n");
for (i=1;i<=n;i++)
for (j=1;j<=n+1;j++)
{

236
printf("a[%d][%d] = ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n");
printf("Cho phan ao cua cac he so,ke ca ve phai\n");
for (i=1;i<=n;i++)
for (j=1;j<=n+1;j++)
{
printf("b[%d][%d] = ",i,j);
scanf("%f",&b[i][j]);
}
for (i=1;i<=n;i++)
a[i][2*n+1]=a[i][n+1];
for (i=n+1;i<=2*n;i++)
a[i][2*n+1]=b[i-n][n+1];
for (i=n+1;i<=2*n;i++)
for (j=1;j<=n;j++)
a[i][j]=b[i-n][j];
for (i=1;i<=n;i++)
for (j=n+1;j<=2*n;j++)
a[i][j]=-b[i][j-n];
for (i=n+1;i<=2*n;i++)
for (j=n+1;j<=2*n;j++)
a[i][j]=a[i-n][j-n];
m=2*n;
for (k=1;k<=m-1;k++)
{
s=0.0;
for (i=k;i<=m;i++)
{
t=fabs(a[i][k]);
if (s<=t)

237
{
s=t;
l=i;
}
}
for (j=k;j<=m+1;j++)
{
s=a[k][j];
a[k][j]=a[l][j];
a[l][j]=s;
}
if (fabs(a[k][k]/a[1][1])<=1e-08)
{
printf("Ma tran suy bien\n");
getch();
exit(1);
}
for (i=k+1;i<=m;i++)
{
s=a[i][k]/a[k][k];
a[i][k]=0.0;
for (j=k+1;j<=m+1;j++)
a[i][j]-=s*a[k][j];
}
}
x[m]=a[m][m+1]/a[m][m];
for (i=m-1;i>=1;i--)
{
s=a[i][m+1];
for (j=i+1;j<=m;j++)
s-=a[i][j]*x[j];
x[i]=s/a[i][i];

238
}
printf("\n");
printf("Nghiem phuc cua he\n");
for (i=1;i<=n;i++)
if (x[i+n]<0)
printf("%10.5f-%10.5fj\n",x[i],fabs(x[i+n]));
else
printf("%10.5f+%10.5fj\n",x[i],x[i+n]);
getch();
}
Áp dụng. Dùng chương trình này giải hệ phương trình:
(3  7 j ) x  (2  4 j ) y  (1  3 j ) z  (4  2 j )r 8  36 j
(5  6 j ) x  (2  5 j ) z  (3  j )r 4  10 j


(4  5 j ) x  (1  2 j ) y  (5  j ) z  6r 13  3 j
(2  4 j ) x  (1  j ) y  (2  3 j )r  10  6 j

Ta nhận được các nghiệm x = 2 + 3j, y = 1 - 2j, z = -1 + 4j và r = 1- j


Ngoài các phương pháp nêu trên ta thấy rằng từ hệ phương trình AX = B, ta có
thể tìm nghiệm X của hệ bằng cách viết lại phương trình dưới dạng X = B/A = A-1B
với A-1 là ma trận nghịch đảo của A. Do đó, trước hết ta cần tìm A-1 và sau đó tính tích
A-1B.

Câu hỏi:

1) Hãy cho ví dụ về bài toán nào đó trong thực tế kỹ thuật có ma trận thưa (dạng
BAND hay dạng bất kỳ) ?
2) Hãy trình bày một thuật toán lưu trữ tiết kiệm bộ nhớ trong máy tính và giải nó
khi ma trận thưa ?
3) Hãy cho một ví dụ cụ thể về ma trận A xác định dương ?
4) Hãy nêu ưu nhược điểm của các phương pháp giải hệ đại tuyến (trực tiếp và
lặp) ?

Bài tập:
1) Dùng phân tích LU để giải phương trình:
239
10 2 1  x1   27 
 3 6 2   x   61,5
  2  
 1 1 5   x3  21,5
  

2) Giải hệ phương trình:


 8 1 1  1 
1 
 5 1  X= 16

1 1  4 7 

a) Bằng phương pháp lặp đơn.


b) Bằng phương pháp lặp Seiden.
(Đối với mỗi phương pháp, tính đến X3 với X0 =  )

3) Giải hệ phương trình:


24,21x1  2,42 x 2  3,85 x3  30,24

2,31x1  31,49 x 2  1,52 x3  40,95
3,49 x  4,85 x  28,72 x  42,81
 1 2 3

Bằng phương pháp lặp đơn, tính cho tới khi:


X k  X k 1  10-4

4) Giải hệ phương trình sau bằng phương pháp lặp đơn sao cho :
X k  X k 1   là số đã cho trước.

1,02  0,25  0,30  0,515 


 0,41 
1,13  0,15  X= 1,555  ;   10 3

 0,25  0,14 1,21 2,780

5) Cho hệ phương trình:

10 x1  x2  x3  12

2 x1  10 x2  x3  13
2 x  2 x  10 x  14
 1 2 3

Giải hệ phương trình bằng phương pháp lặp Gauss-Seidel. Cho biết nghiệm
đúng của hệ là (1, 1, 1).
6) Cho hệ phương trình :

3x1  0,1x2  0, 2 x3  7,85



0,1x1  7 x2  0,3x3  19,3
0,3x  0, 2 x  10 x  71, 4
 1 2 3

240
Giải hệ phương trình bằng phương pháp lặp Gauss-Seidel. Cho biết nghiệm
đúng của hệ là (3, -2.5, 7).
7) Dùng phương pháp lặp Gauss-Seidel tìm nghiệm gần đúng của hệ phương
trình với sai số:      0, 05

10 x1  2 x2  1x3  27

3x1  6 x2  2 x3  6,15
 x  x  5 x  21,5
 1 2 3

8) Tìm hai lần lặp đầu tiên theo phương pháp SOR với ω = 1.1 cho những hệ
tuyến tính, bằng cách sử dụng x(0) = 0:
3x1  x2  x3  1

a. 3x1  6 x2  2 x3  0
3x  3x  7 x  4
 1 2 3

4 x1  x2  x3  x5  6
 x  3x  x  x  6
 1 2 3 4

b. 2 x1  x2  5 x3  x4  x5  6
 x  x  x  4 x  6
 1 2 3 4

2 x2  x3  x4  4 x5  6

9) Cho hệ phương trình:

4 x1  1x2  x3  12

1x1  4 x2  2 x3  1
x  2x  4x  5
 1 2 3

Giải hệ phương trình bằng phương pháp gradient liên hợp. Biết nghiệm đúng
của hệ là (3, 1, 1).

Đáp số:
 x1  0,9618359

2) a)  x 2  3,9448436
 x  2,9398827
 3

 x1  0,9922021

b)  x 2  3,9937418
 x  2,9964857
 3

241
 x1  0,9444

 x 2  1,1743 X k  X k 1  0,5.10
-4
3)
 x  1,1775
 3
4) X = (2.0, 2.5, 3)
 x1  0,9992

5)  x2  1, 00536
 x  0.999098
 3

 x1  2,99997

6)  x2  0,99999
 x  0.99999
 3

242
Chương 6 NGHIỆM GẦN ĐÚNG CỦA HỆ
PHƯƠNG TRÌNH VI PHÂN THƯỜNG
SOLVING THE ORDINARY DIFFERENTIAL EQUATIONS

6.1. Mở đầu
Nhiều bài toán khoa học kỹ thuật có phương trình chỉ đạo là (hệ) phương trình vi
phân thường cùng với điều kiện biên và điều kiện ban đầu. Nghiệm đúng của chúng
thường chỉ áp dụng cho một số lớp bài toán rất hạn chế; đa số các bài toán là phải tìm
nghiệm gần đúng.
Có hai loại bài toán là:
(i) Bài toán Cauchy hay còn gọi là bài toán giá trị ban đầu, bao gồm (hệ) phương
trình vi phân và điền kiện ban đầu của bài toán.
(ii) Bài toán biên, bao gồm (hệ) phương trình vi phân và điều kiện biên để giải gần
đúng các bài toán này có hai phương pháp là:
- Phương pháp giải tích: Tìm nghiệm gần đúng dưới dạng biểu thức như
phương pháp xấp xỉ liên tiếp Picard, phương pháp chuỗi nguyên, phương
pháp tham số bé,…
- Phương pháp số: Tìm nghiệm gần đúng bằng số tại các điểm rời rạc; nó còn
chia ra phương pháp một bước (như phương pháp Euler, Runghe-Kutta,…)
và phương pháp đa bước (Adams,…). Với phương pháp một bước tính
nghiệm gần đúng yi thông qua yi-1 còn với phương pháp đa bước yi tính được
thông qua nhiều bước trước đó: yi-1, yi-2, yi-3,…
6.2. Nghiệm gần đúng của bài toán Cauchy đối với phương trình vi phân thường
y '  f ( x, y ) 
Giả sử ta cần giải bài toán Cauchy:  (6.1)
y ( x0 )  y0 

Giả sử rằng trong miền ta xét, hàm f(x, y) có các đạo hàm riêng liên tục đến cấp n,
khi đó nghiệm cần tìm sẽ có các đạo hàm riêng liên tục đến cấp n + 1, và do đó ta có thể
viết:

243
y0  y ( x0 )  y0  ( x  x0 ) y ,o 
( x  x0 )2 ( x  x0 ) n 1 ( n 1) n 1
 y "0  ......  y0   ( x  x0 ) (6.2)
2! (n  1)!
Ký hiệu x - x0 = h, với h đủ bé ta có thể bỏ qua 0(x – x0n+1).
Từ (6.2) ta có:
 ( x  x0 ) n1

h2 h n 1 ( n 1)
y0 = y(x0+h) - y0 + hy’0 + y" ..........  y0 (6.3)
(n  1)!
0
2!
Để tính (6.3) ta lần lượt tính từ (6.1):
f 0 f
y’0 = f(x0, y0) = f0 , y”0 =  f0 0 ,
x y
m
   n
 mu
Nói chung ta có:   f  u   Cm f
K K

 x y  K 0 x m  K y K
n
hK
Vậy ta tính được: y(x)  y
K 0
(K )
( x0 )
K!
Trong thực tế cách tính này ít dùng vì cồng kềnh, ta sẽ xét các phương pháp giải
khác đơn giản hơn.

6.2.1. Phương pháp xấp xỉ liên tiếp Pica


Một trong những phương pháp giải tích giải gần đúng phương trình vi phân (6.1) là
phương pháp xấp xỉ liên tiếp Pica.
Mục đích của phương pháp này là xây dựng nghiệm cần tìm là y = y(x)
x x x

Từ (6.1) ta có:  dy   f (t , y)dt


x0 x0
 y ( x)  y ( x0 )   f (t, y)dt
x0

Hay: y( x )  y 0   f ( t, y)dt (6.4)


x0

f
Giả sử f(x, y) là hàm liên tục theo x, y và < K.
y
Để tìm xấp xỉ liên tiếp, trong (6.4) thay y bằng y0, ta có xấp xỉ thứ nhất:

244
x
y1  y0   f (t , y0 )dt ,
x0

Tương tự có xấp xỉ thứ hai: y2  y0   f (t , y1 )dt


x0

Tổng quát, ta có: yn  y0   f (t , yn 1 )dt , với n = 1,2,3,…


x0

Như vậy ta sẽ có: y( x)  yn ( x)  y0   f (t , yn 1 )dt


x0

lim y n ( x )  y( x )
n 

M ( KC ) n
Sai số: yn ( x)  y( x)  , trong đó f (x, y ) = M
K .n!

 b
Với: x  x 0 < a  , y  y 0 < b   , thì C = min  a , 
 M
Ta có:
f
(i) > 0 và f(x, y0) > 0 thì: y0 < y1 < y2 < . . . < yn < y(x)
y
f
(ii) > 0 và f(x, y0) < 0 thì: y0 > y1 > y2 > . . . > yn > y(x)
y
Trong hai trường hợp này ta có dãy xấp xỉ 1 phía.
f
(iii) < 0 các xấp xỉ Pica lập thành các xấp xỉ 2 phía.
y
Ứng dụng lập trình
Dùng Matlab
Xây dựng hàm:
function g = picard(f, y0, maxiter)
syms x y
g = subs(f, y0);
245
g = int(g, x);
for i = 1:maxiter
g = subs(f, g);
g = int(g, x);
end
g = sort(g);

Ví dụ. Tìm 2 nghiệm xấp xỉ liên tiếp theo phương pháp Pica của phương trình vi phân:
y’ = x 2 + y2 cho y(0) = 0
6.2.2. Phương pháp Euler

y
y=f(x)
A3

A2
A1
` Ao

x
O xo x1 x2 x3

Trước hết chia đọan [xo, X] thành n đoạn nhỏ:


xi = xo + ih, với i = 0, 1, 2,..., n
( X  xo )
h
n
Đi xây dựng công thức, dùng khai triển Taylor hàm y = f(x) tại xi ta có:

y(ci )
y(x)  y(xi )  y(x i ).(x - x i )  ( x  xi ) 2
2!
Với: ci = xi + (x - xi), 0 <  < 1
Thay x = xi+1 = xi + h, và y’(xi) = f(xi, y(xi))

y (ci )
Ta có: y(xi 1 )  y(xi )  h.f(x i , y(xi ))  h .
2

2!
246
Khi bước chia h khá bé, số hạng cuối  0, khi thay y(xi) bằng ui ta được:
ui+1 = ui + hi.f(xi,ui)
Biểu thức này cho phép tính ui+1 khi biết ui, với điều kiện ban đầu được cho là: uo = 
Đánh giá sai số:
f
Định lý: Giả sử  L và y ''  K , trong đó L, K là những hằng số, khi đó phương
y
pháp Euler hội tụ và sai số là ei = ui - y(xi) có đánh giá:

ei  ui  y ( xi )  M ( e0  h)
K
M  e L ( xi  x 0 ) ,  
2
Ứng dụng lập trình
(i) Dùng C++
//pp_Euler;
#include <conio.h>
#include <stdio.h>
#include <math.h>

float f(float x,float y)


{
float a=x+y;
return(a);
}

void main()
{
int i,n;
float a,b,t,z,h,x0,y0,c1,c2;
float x[100],y[100];

247
clrscr();
printf("Cho can duoi a = ");
scanf("%f",&a);
printf("Cho can tren b = ");
scanf("%f",&b);
printf("Cho so buoc tinh n = ");
scanf("%d",&n);
printf("Cho so kien x0 = ");
scanf("%f",&x0);
printf("Cho so kien y0 = ");
scanf("%f",&y0);
printf("\n");
printf("Bang ket qua\n");
printf("\n");
printf("Phuong phap Euler\n");
h=(b-a)/n;
x[1]=x0;
y[1]=y0;
printf(" x y");
printf("\n");
for (i=1;i<=n+1;i++)
{
x[i+1]=x[i]+h;
y[i+1]=y[i]+h*f(x[i],y[i]);
printf("%3.2f%16.3f",x[i],y[i]);
printf("\n");
}
printf("\n");
getch();
printf("Phuong phap Euler cai tien\n");
248
printf(" x y");
printf("\n");
for (i=1;i<=n+1;i++)
{
x[i+1]=x[i]+h;
c1=h*f(x[i],y[i]);
c2=h*f(x[i]+h,y[i]+c1);
y[i+1]=y[i]+(c1+c2)/2;
printf("%3.2f%15.5f",x[i],y[i]);
printf("\n");
}
getch();
}

(ii) Dùng Matlab


Xây dựng hàm:
function [X, Y] = euler(fxy, xo, xf, yo, n)
% %Giai phuong trinh y'(x) = f(x,y(x)) hay y’ = f(x)
if n < 2
n = 2;
end
h = (xf - xo)/n;
X = zeros(n+1, 1);
M = max(size(yo));% so phuong trinh (so cot cua ma tran Y)
Y = zeros(n+1, M);
%dat dieu kien dau
x = xo;
X(1) = x;
y = yo;
Y(1,:) = y';
249
for i = 1:n
if nargin(fxy) > 1
k1 = h*feval(fxy, x, y);
else
k1 = h*feval(fxy, x);
end
y = y + k1;
x = x + h;
X(i+1) = x;
Y(i+1, :) = y';
end

function dy = f1(t, y)
dy = zeros(3, 1);
dy(1) = y(2) * y(3);
dy(2) = -y(1) * y(3);
dy(3) = -0.51 * y(1) * y(2);

Ví dụ: Dùng phương pháp Euler giải phương trình vi phân:


xy
dy/dx = với 0  x  1 Cho y(0) = 1.
2
xy
Giải : Ta có : xi = i.h ; i = 1,…,5 ; f(x, y) =
2
Ta lập được bảng sau.
i xi yi f(xi,yi) h.f(xi,yi)
0 0.0 1.000 0.000 0.000
1 0.2 1.000 0.100 0.020
2 0.4 1.020 0.204 0.041
3 0.6 1.061 0.318 0.064
4 0.8 1.124 0.450 0.090
5 1.0 1.214

250
6.2.3. Phương pháp Runghe - Kutta bậc 4
Xét bài toán Cauchy (6.1). Giả sử ta đã tìm được giá trị gần đúng yi của y(xi) và
muốn tính yi+1 của y(xi+1). Trước hết ta viết công thức Taylor:
h2 hm ( m) hm 1 ( m 1)
y( xi 1 )  y( xi )  hy( xi )  y( xi )      y ( xi )  y (c ) (6.5)
2 m! m!
Với c (xi, xi+1) và:
y( xi )  f xi , y( xi )

d k 1
y ( k ) ( xi )  f xi , y ( xi )
dx k 1
Ta viết lại (6.5) dưới dạng:
h2 hm ( m) hm 1 ( m 1)
yi 1  yi  hy( xi )  y( xi )      y ( xi )  y (c ) (6.6)
2 m! m!
Ta đã kéo dài khai triển Taylor để kết quả chính xác hơn. Để tính yi, yi v.v… ta
có thể dùng phương pháp Runge-Kutta bằng cách đặt:
yi 1  yi  r1k1(i )  r2k2(i )  r3k3(i )  r4k4(i ) (6.7)
Trong đó:
k1(i )  hf ( xi , yi )
 (i )
k2  hf ( xi  ah, yi  k1 )
(i )

 (i ) (6.8)
k3  hf ( xi  bh, yi  k1  k2 )
(i ) (i )

.......

Và ta cần xác định các hệ số a, b,..; , , ,...; r1, r2,.. sao cho vế phải của (6.7) khác
với vế phải của (6.6) một vô cùng bé cấp cao nhất có thể có đối với h.
Khi dùng công thức Runge-Kutta bậc hai ta có:

k1  hf ( xi , yi )
(i )

 (i ) (6.9)
k2  hf ( xi  ah, yi  k1 )
 (i )

Và yi 1  yi  r1k1(i )  r2k2(i ) (6.10)


Ta có:
y(x) = f[x,y(x)]
y( x)  f xx, y( x)  f yx, y( x)

................
251
Do đó vế phải của (6.6) là:

hf ( xi , yi ) 
h2
2
 
f x( xi , yi )  f y( xi , yi ) y( x)     (6.11)

Mặt khác theo (6.9) và theo công thức Taylor ta có:


k1(i )  hf ( xi , yi )  hyi

k2(i )  h[ f ( xi , yi )  ahf x( xi , yi )  k1(i ) f y( xi , yi )    ]

Do đó vế phải của (6.10) là:


h(r1  r2 ) f ( xi , yi )  h2[ar2 f x( xi , yi )  r2 yi f y( xi , yi )]     (6.12)

Bây giờ cho (6.11) và (6.12) khác nhau một vô cùng bé cấp O(h3) ta tìm được các
hệ số chưa biết khi cân bằng các số hạng chứa h và chứa h2:
r1 + r2 = 1
a.r1 = 1/ 2
.r2 = 1
Như vậy:  = a, r1 = (2a - 1)/ 2a, r2 = 1/ 2a với a được chọn bất kì.
Nếu a = 1/2 thì r1 = 0 và r2 = 1. Lúc này ta nhận được công thức Euler. Nếu a = 1
thì r1 = 1/2 và r2 = 1/2. Lúc này ta nhận được công thức Euler cải tiến.
Một cách tương tự chúng ta nhận được công thức Runge-Kutta bậc 4. Công thức
này hay được dùng trong tính toán thực tế vì độ chính xác cao và thuật toán không phức
tạp:
k1 = h.f(xi, yi)
k2 = h.f(xi+h/ 2, yi + k1/ 2)
k3 = h.f(xi+h/ 2, yi + k2/ 2)
k4 = h.f(xi+h, yi + k3)
yi+1 = yi + (k1 + 2k2 + 2k3 + k4) / 6
Ví dụ 1. Cho phương trình vi phân
y
y’ =  y 2
x
y(1) = 1, h = 0.2. Tính trong khoảng [1, 1.4] Runge- Kuta.
y
f(x, y) =  y2
x

252
i x y k=hf(x,y) y

0 1 1 0 0
1,1 1 -0,018 -0,036
1,1 0,991 -0,0186 -0,162
1,2 0,984 -0,039 -0,079
1
y1 = y0 + (k1+2k2 +2k3+k4)
6
1
= 1+ (0+2(-0.018)+2(-0,081)-0,079 = 0,954
6
i x y k=hf(x,y) y

0 1,2 0,954 -0,058 -0,115


1,3 0,925 -0,02 -0.046
1,3 0,940 -0,032 -0,064
1,4 +0,938 -0,042 -0,042

1
y2 = y1 + (k1+2k2 +2k3+k4)
6
1
= 0,954+ (-0,058+2(-0,02)+2(-0,032)+(-0,042)
6
Ứng dụng lập trình
(i) Bằng C++
//Phuong phap Runge_Kutta;
#include <conio.h>
#include <stdio.h>
#include <math.h>
#define k 10

float f(float x,float y)


{
float a=x+y;
return(a);
253
}

void main()
{
float a,b,k1,k2,k3,k4;
int i,n;
float x0,y0,h,e;
float x[k],y[k];

clrscr();
printf("Phuong phap Runge - Kutta\n");
printf("Cho can duoi a = ");
scanf("%f",&a);
printf("Cho can tren b = ");
scanf("%f",&b);
printf("Cho so kien y0 = ");
scanf("%f",&y[0]);
printf("Cho buoc tinh h = ");
scanf("%f",&h);
n=(int)((b-a)/h);
printf(" x y\n");
for (i=0;i<=n+1;i++)
{
x[i]=a+i*h;
k1=h*f(x[i],y[i]);
k2=h*f((x[i]+h/2),(y[i]+k1/2));
k3=h*f((x[i]+h/2),(y[i]+k2/2));
k4=h*f((x[i]+h),(y[i]+k3));
y[i+1]=y[i]+(k1+2*k2+2*k3+k4)/6;
printf("%12.1f%16.4f\n",x[i],y[i]);
254
}
getch();
}

(ii) Bằng Matlab


Xây dựng hàm:
function [x, y] = rungekutta(f, a, b, y0, n)
%Phuong phap Runge-Kutta de giai phuong trinh y'(x) = f(x,y(x)) hay y’ = %f(x)
if nargin < 4 | n <= 0
n = 100;
end
if nargin < 3
y0 = 0;
end
y(1,:) = y0(:)'; %
h = (b - a)/n;
x = a + [0:n]'*h;
if nargin(f) >1
for k = 1:n
f1 = h*feval(f, x(k), y(k, :));
f1 = f1(:)';
f2 = h*feval(f, x(k) + h/2, y(k, :) + f1/2);
f2 = f2(:)';
f3 = h*feval(f, x(k) + h/2, y(k, :) + f2/2);
f3 = f3(:)';
f4 = h*feval(f, x(k) + h, y(k, :) + f3);
f4 = f4(:)';
y(k+1, :) = y(k, :) + (f1 + 2*(f2 + f3) + f4)/6;
end
else

255
for k = 1:n
f1 = h*feval(f, x(k));
f1 = f1(:)';
f2 = h*feval(f, x(k) + h/2);
f2 = f2(:)';
f3 = h*feval(f, x(k) + h/2);
f3 = f3(:)';
f4 = h*feval(f, x(k) + h);
f4 = f4(:)';
y(k+1, :) = y(k, :) + (f1 + 2*(f2 + f3) + f4)/6;
end
end
Áp dụng. Giải phương trình y’= x + y 0  x  1 , y(0) = 0.5, h = 0.1
Bằng phương pháp Runghe - Kutta
Ta dùng chương trình :
clear all, clc
a = 0;
b = 1;
y = inline('x + y');
ya = 0.5;
n = 10;%so lan tinh chi n = 10
[x, y] = rungekutta(y, a, b, ya, n)
plot(x, y);
6.2.4. Phương pháp Adam
Giả sử cần giải phương trình vi phân:
Y’ = f(x, y), với điều kiện ban đầu: y(x0) = y0
Cho biến số thay đổi bởi bước h nào đó, xuất phát từ điều kiện ban đầu Y(x0) = Y0
bằng phương pháp nào đó (ví dụ: phương pháp Runghe-Kutta bậc 4), ta tìm được 3 giá
trị tiếp theo của hàm cần tìm y(x): Y1 = Y(x1) = Y(x0+h), Y2 = Y(x0+2h), Y3 = Y(x0 + 3h).
Nhờ các giá trị x0, x1, x2, x3 và Y0, Y1, Y2, Y3 ta tính được q0, q1, q2, q3.
256
Trong đó: q0 = h.Y0’ = h.f(x0, y0), q1 = h.f(x1, y1), q2 = h.f(x2, y2), q3 = h.f(x3 , y3),
sau đó ta lập bảng sai phân hữu hạn của các đại lượng y và q

x y y q q 2q 3q -------


xo yo qo
yo q0
x1 y1 q1 2q0
y1 q1 3q0
x2 y2 q2 2q1 --------
y2 q2 --------
x3 y3 q3 -------
------------ ---------- ---------- ---------- ----------- ---------- --------- -------

Biết các số ở đường chéo dưới, ta tìm y3 theo công thức Adam như sau:
1 5 3
y3  q3  .q2  .2 q1  .3 .q0
2 12 8
Tiếp đó ta có:
Y4 = Y3 + Y3  q4 = h.f(x4, Y4)
Sau đó viết đường chéo tiếp theo như sau:
q3 = q4 - q3 , 2q2= q3 - q2 , 3q1 = 2.q2 - 2.q
Đường chéo mới cho phép ta tính Y4 :
Y4 = q4 + 1/2q3 + 5/122q2 + 3/83q1
Vì vậy ta có: Y5 = Y4 + Y4 . . . . .
Ví dụ. Giải lại ví dụ 1 bằng phương pháp Adam
. Tìm x4 = 1,8  y4 =?
x5 = 2,0  y5 = ?

257
x y y q q 2 q 3q
1 1 0
-0,016 -0,030
1,2 0,984 -0,030 0,016
-0,038 -0,014 -0,008
1,4 0,946 -0,044 0,008
-0,046 -0,006 -0,001
1,6 0,900 -0,05 0,007
-0,053 0,001 0,388
1,8 0,847 -0,049 0,395
-0,02 0,396
2 0,827 0,347

1 5 3
y3 =q3 + q2 + 2 q1 + 3q0 =-0,050+1/2.(-0,006)+5/12.(0,008)+3/8.(-0,008)
2 12 8
1 5 3
y4 =q4 + q3 + 2 q2 + 3q1 =-0,049+1/2.0,001+5/12.0,07+3/8.(-0,001)= -0,02
2 12 8

Câu hỏi:

1) Hãy cho ví dụ cụ thể về bài toán phương trình vi phân thường: Bài toán Cauchy
(hay còn gọi là bài toán giá trị ban đầu) và bài toán biên ?
2) Tại sao phương pháp Pica được gọi là phương pháp giải tích gần đúng ?
3) Tại sao phương pháp Euler cho sai số lớn, nhưng các sách về phương pháp tính
đều phải đưa phương pháp này vào ?
4) Tại sao các sách về phương pháp tính thường trình bày phương pháp Runghe –
Kutta bậc 4 để giải phương trình vi phân thường mà không trình bày phương pháp
này có bậc cao hơn hoặc thấp hơn (bậc 3, bậc 5… ) ?
5) Tại sao phương pháp Adam được gọi là phương pháp đa bước ?

258
Bài tập:

1) Tìm nghiệm gần đúng của phương trình y’ = x + y2 thỏa mãn điều kiện ban đầu
y(0) =1, bằng phương pháp xấp xỉ liên tiếp pica (đến xấp xỉ thứ hai)
2) Tìm nghiệm đúng của bài toán vi phân y’ = x + y, y(0) = 0 trên miền x  0 bằng
phương pháp dãy pica.
3) Tìm nghiệm gần đúng của phương trình y’ = 2xycos(x2) thỏa mãn điều kiện
y(0) = 1 bằng phương pháp dãy pica.
4) Bằng phương pháp ơle (công thức ơle), tìm nghiệm gần đúng của bài toán côsi
y’(y + x) = y – x, y’(0) =1, lấy h = 0.1 (tìm bốn giá trị đầu tiên của y).
5) Tìm nghiệm gần đúng của bài toán côsi
( x  y )(1  xy )
y’  y(0) =1 trên [0, 1] bằng công thức ơle, lấy h = 0.2.
x  2y

6) Tìm nghiệm gần đúng của bài toán côsi


y
y’=y2 + y(2) = 4, h = 0.1.
x
2x
7) Tìm các giá trị của hàm số y = y(x) là nghiệm của bài toán Côsi y’ = y- ,
y

y(0) =1 bằng công thức dạng Runghe-Kutta bậc 4 trên đoạn [0, 1] với h = 0.2 (Tính hai
giá trị y1 = y(0,2), y2 = y(0.4). So sánh với nghiệm đúng y = 2 x  1 .
8) Bằng phương pháp Runghe-Kutta bặc 4 tìm nghiệm gần đúng của bài toán côsi.
x
y’ = + 0.5y, y(0) = 1 lấy với h = 0.1; Tính y(0.5).
y

9) Cho bài toán côsi y’= x2+y2; y(0) = -1.


Tìm nghiệm gần đúng của y4 = y(0.4) bừng công thức nội suy Adam.
10) Tìm nghiệm gần đúng của bài toán côsi
y’ = x2 + y2; y(0) = 0
Theo công thức nội suy Adam, tại điểm x = 0.4 (lấy h = 0.1)

259
Đáp số:
1) Chọn xấp xỉ đầu y0 = y(0) = 1
x2
Xấp xỉ thứ nhất y1 = 1 + x +
2
3 2 2 3 1 4 1 5
Xấp xỉ thứ 2 y2 = 1 + x + x + x + x + x
2 3 4 20
2) Chọn xấp xỉ đầu y0 = y(0) = 0, được dãy pica. Dãy đó hội tụ tới nghiệm đúng
n
x k 1
của bài toán: y = ex – x - 1 và yn(x) = 
k 1 ( k  1)!

n
sin k ( x 2 )
3) yn(x) = 
2
; nghiệm đúng y(x) = e sin(x ) .
k 1 k!

4) x 0 0,1 0,2 0,3 0,4

y(x) 1 1,1 1,18 1,25 1,31


5) x 0 0,2 0,4 0,6 0,8 1,0

y(x) 1 1,1 1,18 1,24 1,27 1,27

6) x 2 2,1 2,2 2,3 2,4

y(x) 4 5,8 9,44 18,78 54,86

7) x 0 0,2 0,4

y(x) 1 1,1832 1,1346


8) x 0 0,1 0,2 0,3 0,4 0,5

y(x) 1 1,05 1,12 1,20 1,29 1,39


9) y4 = y(0.4)  0,69
10) y4 = y(0.4)  0,02

260
Chương 7 GIẢI GẦN ĐÚNG PHƯƠNG TRÌNH ĐẠO HÀM RIÊNG
BẰNG PHƯƠNG PHÁP SỐ
NUMERICAL METHOD FOR PARTIAL DIFFERENTIAL EQUATIONS

Các hiện tượng vật lý trong tự nhiên thường rất phức tạp, nên thường phải mô
tả bằng các phương trình đạo hàm riêng. Mỗi loại phương trình đạo hàm riêng (PDF)
thường đòi hỏi các điều kiện biên tương ứng để bài toán có nghiệm tốt, phù hợp với
hiện tượng vật lý quan sát.
7.1. Phân loại phương trình đạo hàm riêng bậc 2
Xét một phương trình đạo hàm riêng (PDE) bậc 2 với hai biến độc lập x, y
 2u  2u  2u u u
A 2 B C 2  D  E  Fu  g ( x, y)
x xy y x y

Chuyển tất cả các số hạng khác đạo hàm bậc hai về vế trái, ta có:
Au,xx + Bu,xy + Cu,yy = Ƒ (7.1)
Ở đây dấu ',' chỉ số dưới chỉ đạo hàm riêng. Dạng tuyến tính hoặc phi tuyến
của phương trình (7.1) phụ thuộc vào các hệ số A, B, C, và Ƒ.
Phương trình tuyến tính:
Nếu A, B, C là các hàm số chỉ của x và y, và Ƒ là một hàm tuyến tính theo u,
u, x, u,y, khi đó phương trình (7.1) được gọi là phương trình tuyến tính. Trong trường
hợp này, phương trình (7.1) có thể được viết như sau:
Au,xx + Bu,xy + Cu,yy = -Du,x - Eu,y - Fu + g (7.2)
Trong đó A, B, C, D, E, F và g là các hàm theo biến x và y
Phương trình phi tuyến: Tùy thuộc vào các dạng của A, B, C và Ƒ, Eq. (7.1)
có thể được phân loại thêm để chỉ ra bậc phi tuyến.
- Á tuyến tính: Nếu A, B và C là các hàm chỉ của x và y, và Ƒ là hàm (có thể
không phải là một hàm tuyến tính) của x, y, u, u,x, u,y như Ƒ = Ƒ (x, y, u , u,x , u y),
phương trình (7.1) được gọi là phương trình á tuyến tính hoặc phương trình nửa tuyến
tính.
- Tựa tuyến tính: Nếu A, B, C và d là các hàm của x, y, u, u,x, u,y, thì phương
trình (7.1) được gọi là phương trình tựa tuyến tính.
Phi tuyến (hoàn toàn): Nếu phương trình (7.1) khác hơn so với phương trình
tuyến tính, á tuyến tính hoặc tựa tuyến tính, nó được gọi là phương trình phi tuyến.

261
7.1.1. Phân loại phương trình đạo hàm riêng bậc 2 tuyến tính
Ở đây, chúng ta chỉ thảo luận việc phân loại phương trình đạo hàm riêng bậc 2
tuyến tính với hai biến độc lập. Chúng ta muốn nghiên cứu phân loại phương trình đạo
hàm riêng, bởi vì:
- Có một số khác biệt cơ bản trong các lời giải của từng loại khác nhau của các
phương trình.
- Tùy thuộc vào loại phương trình, chỉ có một số dạng bài toán (như loại có giá
trị ban đầu, các loại giá trị biên, hoặc các loại giá trị biên - ban đầu) có thể có các giải
pháp hay cách đặt bài toán tốt.
- Nó cũng giúp chuyển đổi một phương trình đạo hàm riêng tuyến tính bậc 2
(với hai biến độc lập) về các dạng chính tắc, điều này rất tiện lợi trong phương pháp
giải số.
Từ dạng tổng quát:
 2u  2u  2u u u
A  B  C D E  Fu  g ( x, y) (7.3)
x 2
xy y 2
x y

Phân loại với chú ý các đạo hàm bậc cao, khi đó (7.3) được viết lại:
 2u  2u  2u
A  B  C  f u x , u y , u, x, y  (7.4)
x 2 xy y 2

Đơn giản (7.4) bằng cách đổi biến số:  = (x, y) ,  = (x, y)
Đặt:  = x + y ,  = x + y
u u  u  u u
Hay:    x  x
x  x  x  y
Tương tự cho các đạo hàm khác ta được:
u  2u u
( A  C  B )  [2 A  2C  B(   )]
2 2
 ( A 2  C 2  B ) = f (7.5)
  
Một cách đơn giản để tìm lời giải của phương trình này, là chọn ,  sao cho số
hạng thứ nhất và thứ ba trong phương trình (7.5) triệt tiêu:

 A  B  C  0
 2 2

 2
 A  B  C  0
 2

Ta được dạng đơn giản:


 2u
[2 A  2C  B(    )]


262
Giả sử:   0,   0 ta có:
A(/)2 + B(/) + C = 0, A(/)2 + B(/) + C = 0 (7.6)
 1
   2 A ( B  B  4 AC )
2


   1 ( B  B 2  4 AC )
 2 A

KẾT LUẬN: B2 - 4AC > 0 : Phương trình Hyporbol


B2 - 4AC < 0 : Phương trình Ellip
B2 - 4AC = 0 : Phương trình Parabol
Chú ý: Ở đây không phân biệt biến không gian và thời gian x, y, z, t
a. Phương trình Hyperbol (B2 - 4AC > 0)
 2u 1  2u
Phương trình sóng 1 chiều  là 1 ví dụ của phương trình đạo hàm
x 2 c 2 t 2
riêng dạng hyperbol.
Từ chổ A, B và C có thể phụ thuộc vào x và y, việc phân loại này chỉ là một
đặc tính riêng của phương trình.
b. Phương trình Ellip (B2 - 4AC < 0)
 2u  2u
Phương trình Laplace hai chiều   0 là một ví dụ điển hình của
x 2 y 2

phương trình đạo hàm riêng dạng elliptic.


Loại bài toán này thường không được đặt tốt (not well-posed), cụ thể là một sự
thay đổi nhỏ về dữ liệu ban đầu sẽ tạo ra sự thay đổi rất lớn về lời giải.
Ví dụ. Hãy xem xét vấn đề về hai giá trị ban đầu sau đây:
- Trường hợp 1
  2u1  2u1
 x 2  y 2  0


u1  x, 0   0 y ≥ 0,−∞ < x < ∞ (7.7)
 u
 1  x, 0   0
 y

- Trường hợp 2

263
  2 u2  2 u2
 x 2  y 2  0


u2  x, 0   0 y ≥ 0,−∞ < x < ∞ (7.8)
 u
 2  x, 0   sin nx
 y x

Hai bài toán trên có u1 ≡ 0 và u2 = sin(nx) sinh (ny) / n2 là lời giải tương ứng.
Những lời giải này có thể dễ dàng được kiểm tra bởi một sự thay thế trực tiếp vào PDE
tương ứng và các điều kiện ban đầu. Với n rất lớn, các điều kiện ban đầu của bài toán
thứ hai chỉ khác chút ít so với điều kiện ban đầu của bài toán thứ nhất, nhưng các lời
giải của hai bài toán có sự khác nhau khá nhiều, nghĩa là các lời giải của hai bài toán
này là không tốt.
c. Phương trình Parabol (B2 - 4AC = 0)
 2u u
Phương trình nhiệt 1 chiều 2  (còn gọi là phương trình khuếch tán) là
x t
một ví dụ điển hình của PDE parabol.
7.1.2. Những lưu ý về phương trình đạo hàm riêng
Cần lưu ý, việc phân loại các PDE chỉ là một cách phân loại cục bộ. Chúng ta
xem xét, như là một ví dụ, phương trình Tricomi.
 2 u2  2 u2
 y 0 (7.9)
x 2 y 2

Theo định nghĩa về a, b, c ta có b2 - ac = -y, do đó đối với vùng y > 0 và y < 0


phương trình là elip và hyperbol, tương ứng. Trong khi dọc theo đường y = 0 phương
trình là parabol.
Lưu ý thêm về sự phân loại của PDE bậc 2 đơn trong một số biến:
- Không phải tất cả các PDE bậc 2 trong một số biến đã được phân loại.
- Phương trình PDE bậc hai tuyến tính có hệ số là hằng số trong loại
hyperbol, parabol và elliptic có thể luôn luôn được được đưa về dạng chính
tắc như sau:
u,11 − (u,22 + u,33 + · · · + u,nn) + (các số hạng bậc thấp hơn) = 0 hyperbol
u,1 − (u,22 + u,33 + · · · + u,nn) + (các số hạng bậc thấp hơn) = 0 parabol
u,11 + (u,22 + u,33 + · · · + u,nn) + (các số hạng bậc thấp hơn) = 0 ellip
7.2. Các bài toán biên thường gặp

264
Trong lĩnh vực kỹ thuật có ba bài toán biên: bài toán biên Dirichlet, bài toán biên
Neumann, bài toán biên hổn hợp.

7.2.1. Bài toán Dirichlet

Tìm hàm u thoả mãn phương trình:

a(u, v) = (f, v) trong miền ()

 và trên biên  của () cho trước giá trị của u

u = f(v)

n Nếu trên biên cho u = 0 thì ta có điều kiện biên


Dirichlet thuần nhất. Điều kiện biên Dirichlet được gọi
là điều kiện biên cốt yếu (essential boundary
conditions).

7.2.2. Bài toán Neumann

Tìm hàm u thoả mãn phương trình:


a(u, v) = (f, v) trong ()

Và điều kiện biên:

u
 f ( v)
n 

Nếu f(v) = 0 ta có bài toán Neumann thuần nhất. Để cho bài toán Neumann có
nghiệm duy nhất ta phải đặt thêm điều kiện g(1) nào đó. Điều kiện biên Neumann còn
gọi là điều kiện biên tự nhiên (natural boundary conditions).

7.2.3. Bài toán hổn hợp

0
Với bài toán hổn hợp (mixed boundary conditions)

 là bài toán mà biên  của nó gồm hai phần o và 1. Ví dụ

tìm hàm u thoả mãn phương trình:


1
n
a(u, v) = (f, v) trong ()

Với điều kiện biên:


265
u
 f1 ( v) ; uo = fo(v)
n 1

Trong thực tế kỹ thuật, người ta thường hay gặp điều kiện biên hỗn hợp này.

7.3. Tư tưởng cơ bản của các phương pháp gần đúng

Trên thực tế việc tìm nghiệm chính xác của các bài toán biên nói trên là vô cùng
khó khăn, toán học hiện nay chỉ cho phép giải các bài toán đó trong một số trường hợp
thật đơn giản, còn phần lớn là phải giải theo các phương pháp gần đúng khác nhau.

Tư tưởng của các phương pháp gần đúng (approximation methods) là xấp xỉ
không gian vô hạn chiều của nghiệm bằng một không gian con hữu hạn chiều.

a0 
u ( x)    (an cos nx  bn sin nx)
2 n 1

u ( x)   an .n ( x)
n 0

Nghiệm chính xác của bài toán có thể biểu diễn bằng các dạng sau:
u(x) = a0 + a1x + a2x2 + a3x3 +.. ..+ anxn +.. .. (7.10)

Rõ ràng nghiệm chính xác u(x) có thể xem như là một hàm của vô hạn các hệ số:

a0, a1, a2, .. ..,an,.. ..

Trong khi đó giải theo các phương pháp gần đúng ta chỉ có thể tìm được
nghiệm uh của nó như là hàm của một dãy hữu hạn các hệ số a0, a1, a2, .. ..,an nào đó
mà thôi.

Trong chương này ta sẽ nghiên cứu một số phương pháp số mạnh, thường sử
dụng để giải các bài toán cơ học:

+ Phương pháp đặc trưng (characteristic method)


+ Phương pháp sai phân (finite difference method)
+ Phương pháp phần tử hữu hạn (finite element method)
+ Phương pháp thể tích hữu hạn (finite volume method)
+ Phương pháp phần tử biên (Boundary element method)

266
7.4. Phương pháp đặc trưng
Nội dung của phương pháp đặc trưng là biến đổi phương trình vi phân đạo hàm
riêng về hệ phương trình vi phân thường, và tìm lời giải bài toán ở hệ phương trình vi
phân thường này, từ đó ta dễ dàng thấy được bản chất vật lý của hiện tượng nghiên
cứu.
 2u 1  2u
Ví dụ. Xét phương trình truyền sóng :  (7.11)
x 2 c 2 t 2
v u  2v  2u
Ta đặt hàm v(x, t) sao cho:    (7.12)
x t xt t 2
  v    u 
Vì :    
t  x  t  t 

1  2u  2u 1  2v  2u
Từ (7.11) ta có:  0  2  0
c 2 t 2 x 2 c tx x 2
1 v u
Và đặt:   f (t)
c 2 t x
Đi đến hệ thống:
 v u  v   v 
 x  t  0 1 0   x   0  1   0 
   u    1  t 
1 v u
 
      c 2 0   u   
   f (t)
0 1
    
 c 2 t x  x   t   f (t )

1 0  0  1
Đặt A=  , B= 1 
0 1  c 2 0

Phương trình đặc trưng được suy từ:
 1 1 1
det(A - B) = 0   1 
 0  2 = 2   
c2
c c

dx x  ct  a
Từ đó ta có đường cong đặc trưng:  c  
dt x  ct  b
7.5. Phương pháp sai phân
Dựa trên khai triển Taylor, một cách gần đúng ta thay các tỉ vi phân bằng tỉ sai
phân.

c
Ví dụ. Tìm đạo hàm
x x

267
 c  x 2   2 c 
Ta có: C(x + x) = C(x) + x       .....
2!  x 2  x
(7.13)
 x  x

C C( x  x )  C( x ) x   2 C 
      ......
x x x 2  x 2  x

 c  x   c 
2 2

Tương tự: Có C(x - x) = C(x) - x    


 x 2   ..... (7.14)

 x
x 2!  x
Lấy (7.13) - (7.14) suy ra sai phân trung tâm:

c C( x  x )  C( x  x ) x 3   3C 
     ......
x x 2x 3!  x 3  x
Có thể khai triển:

c x 2  C
2

C(x + 2x ) = C(x) + 2x + 4. . + ....... (7.15)


x x 2! x x
2

Lấy (7.13) nhân với 4 rồi trừ cho (7.15), ta có:

c  3C ( x)  4C ( x  x)  C ( x  2x) 4x 2  3C


 
x x 2x 3! x 3
Lấy (7.13) cộng (7.14) ta được:

 2C C ( x  x)  2C ( x)  C ( x  x)
  0(x 2 ) (7.16)
x x
2
x 2

 2  2
Áp dụng các sai phân này vào giải phương trình Laplace:  0
x 2 y 2

x i  X
Chọn :  (7.17)
y i  Y
Thay (7.16) vào (7.17), được:
i1, j  2ij  i1, j i , j1  2ij  1, j1
 0
X 2 Y 2

Đơn giản chọn x = y, ta được: i , j 


1
i1, j  i1, j  i, j1  i, j1 
4

268
t i,j+1 i+1,j+1

yj+
∆y
1
yj
yj-1
i,j ∆x i+1,j

xi-1 xi xi-1 x
7.5.1. Sơ đồ hiện – Sơ đồ ẩn
(Explicit - Implicit Scheme)

 2   2  S 
Time
Xét phương trình:  
x 2 y 2 T t

 K 1  K t+1  k 1i , j

Sai phân tiến: t t  t .K t

  
K K 1 t k i ,j

Sai phân lùi: t t  t .K t y
Ở đây (t)K = t = const t-1  k 1i , j
x
T=  (t ) j ,
K   t  K.t
K

- Sai phân tiến theo thời gian t của phương trình trên, ta được:

iK1, j  2iK, j  iK1, j iK, j1  2iK, j  iK, j1 S iK, j1  iK, j
 
(x )2 (y )2 T t

Từ phương trình này ta tìm được ngay iK, j1 khi biết các  iK1, j ,
 iK, j  iK j , j  iK, j 1  iK, j 1 nên gọi là sơ đồ hiện.

269
t

k+1

∆x ∆x x

- Sai phân lùi theo thời gian t ta có:

iK1,1j  2iK, j1  iK1,1j iK, j11  2iK, j1  iK, j11 S i , j  i , j
K 1 K

  .
(x)2 (y) 2 T t
Phương trình trên có 5 ẩn số trong 1 phương trình nên phải thiết lập các phương
trình cho tất cả các nút khác bên trong miền bài toán và giải đồng thời các hệ phương
trình này, thì mới tìm được các ẩn của bài toán ở bước thời gian (t + 1), nên ta gọi sơ
đồ này là sơ đồ ẩn.

k+1

∆x ∆x x

7.5.2. Sự ổn định của sơ đồ


Đối với sơ đồ ẩn luôn luôn ổn định với mọi khoảng thời gian t chọn, còn sơ đồ
hiện chỉ ổn định với khi:
t  t giới hạn
7.5.3. Tính nhất quán của lược đồ sai phân
z z
Xét phương trình vi phân:  0 (7.18)
t x
Thay các tỉ vi phân bằng các tỉ sai phân:
270
z z j  z j z z j  z j 1
n 1 n n n
t
 ;  : Thế vào (7.18) và đặt r =
t t x x x

Suy ra: znj1  (1 r )znj  r.znj1 (7.19)

Phương trình (còn gọi là lược đồ) (7.19) nhận được từ khai triển Taylor của
(7.18) hoặc bằng một lược đồ khác, ta thử xem lược đồ (7.19) có nhất quán với
phương trình vi phân (7.18) hay không ?
Từ khai triển Taylor ta được:

z  2 z t 2  3z t 3
z  z  t  2
n 1 n
  ...... t
t t 2! t 3 3!
j j
Đặt r 
z (x )  2 z x 2  3z x 3 x
z j 1  z j 
n n
 2  3  ......
x 1! x 2! x 3!
Thay tất cả vào (7.19), ta được:
z  2 z t 2  3 z t 3 z x  2 z x 2
z  t  2
n
  ...  (1  r ) z j  r ( z j 
n n
  ... (7.20)
t t 2! t 3 3! x 1! x 2 2!
j

x 1
Nhân 2 vế của (7.20) với rồi chuyển vế, rồi nhân tiếp 2 vế với ta được:
t t
z z  2z t  2z x
  2  ...... 2  ... (7.21)
t x t 2! x 2!
Khi x, t 0, vế phải của (7.21) 0, do đó ta thấy phương trình (7.21)
 (7.18)

Ta nói lược đồ (7.19) nhất quán với phương trình vi phân.


7.5.4. Sự ổn định của lược đồ.
Xét phương trình sai phân (còn gọi là lược đồ):

z nj1  (1  r)z nj  rz nj1 (7.22)

Ta nói: “Một lược đồ sai phân được gọi là ổn định, nếu tập hợp vô hạn các
nghiệm tính được là bị chặn đều, ngược lại gọi là không ổn định”.
Như vậy sự ổn định của lược đồ sai phân không liên quan đến phương trình vi
phân (chỉ là riêng của lược đồ).

Ví dụ. Lược đồ (7.22) có dạng: z j  Az j  Bz j1


n1 n n

Suy ra: z nj1  Az nj  Bznj 1

Gọi: z n  max z nj , trong tập j


j

271
Vậy thì: znj1  A zn  B zn  ( A  B). zn  znj

Tức là lớp: z j  z j ,.... z j  z0


n n1 1
mà z0 đã cho trước ở biên.

Vậy các zn bị chặn đều  Ta nói lược đồ ổn định.


Định lý Courant:
“Nếu lược đồ sai phân nhất quán với phương trình vi phân và bản thân lược đồ
đó là ổn định thì nghiệm của phương trình sai phân sẽ hội tụ đến nghiệm của phương
trình vi phân’’.

7.5.5. Các ứng dụng trong cơ học:


Phương trình vi phân dạng ellip: Ta sẽ gặp các phương trình này trong các bài
toán truyền nhiệt hoặc các bài toán thẩm thấu của cơ học chất lỏng với phương trình
mô tả Poisson.
Một dạng khác của phương trình vi phân đạo hàm riêng dạng hyperbol, ta có thể
gặp chúng trong các phương trình dao động của dây u = u(x, t) với x là tọa độ và t là
thời gian.
Ta còn có thể gặp các phương trình vi phân đạo hàm riêng ở dạng phức tạp hơn
như phương trình trong động lực học chất lưu: Phương trình Navier-Stocks, hay
phương trình dao động uốn của tấm hay dầm trên nền đàn hồi trong các bài toán sức
bền vật liệu.
Ví dụ 1. Giải gần đúng phương trình đạo hàm riêng dạng Elliptic.
Cho phương trình vi phân đạo hàm riêng u xx''  u 'yy'  xy2 trên hình chữ nhật

D = 0,0.6  0,0.3 biết giá trị của hàm u(x, y) trên biên là u(x, y) = x + 3y với bước

chia x = h = 0.2, y =  = 0.1.


Giải:
Ta có h = 0.2 suy ra n = (0.6 - 0)/h = 3, xi = ih = 0.2i
 = 0.1 suy ra m = (0.3-0)/ = 3
Cho các điểm (0, j), (i, 0), (3, j), (i, 3) là các điểm lưới. Giá trị của hàm trên các
điểm lưới là:
u00 = 0, u01 = 0.3, u02 = 0.6, u0,3 = 0.9, u10 = 0.2, u20 = 0.4, u30 = 0.6, u31 = 0.9,
u32 = 1.2, u33 = 1.5, u10 = 1.1, u20 = 1.3.

272
Ta cần tính giá trị của hàm u tại 4 điểm là (1, 1), (1, 2), (2, 1), (2, 2). Hàm
f(x, y) = xy2 nên f11 = 0.002, f12 = 0.008, f21=0.004, f22 = 0.016. Ta có hệ 4 phương
trình đại số tuyến tính là:
 u 21  2u11  u 01 u12  2u11  u10
   0,002
 0,2 2 0,12

 10u11  4u12  u21  1,099992



4u11  10u12  u22  4,99968

u11  10u21  4u22  2,499984
 u12  4u21  10u22  6,399936

Giải hệ phương trình ta được:


u11 = 0.499964132, u12 = 0.79994444, u21= 0.699994356, u22 = 0.999907868
Ví dụ 2. Giải gần đúng phương trình đạo hàm riêng dạng Parabolic.
u  2u

t x 2

Thỏa mãn điều kiện biên : u( x,0)  1,1( x 2  1) sin x; 0  x  1


u(0, t )  0 ; u(1, t )  0 ; 0  t  0,02

Sử dụng lưới chữ nhật có bước h = 0.1, l = 0.05


Giải:
Tại mỗi điểm trong (xi, tj) thay thế đạo hàm bằng tỷ sai phân:

  2u  u i 1, j  2u i , j  u i 1, j
 2  
 x  i , j h2

 u  ui , j 1  ui , j
   (Sai phân tiến)
 t  i , j l

Thế vào phương trình đạo hàm riêng ta áp dụng sai phân tiến sơ đồ hiện:
ui , j 1  ui , j ui1, j  2ui , j  ui1, j

l h2
Đặt   l / h 2 thế vào trên ta có phương trình:
ui , j 1  (1  2 )ui , j   (ui1, j  ui1, j )

1
(Điều kiện lược đồ sai phân ổn định khi 0    )
2
273
1
Với h = 0.1 và l = 0.005 thì ta có  
2

ui1, j  ui 1, j
Thế vào ta có ui , j 1 
2

Bảng kết quả nghiệm của phương trình

x
j 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1
t
0 0 0 0.343 0.672 0.970 1.214 1.375 1.423 1.326 1.060 0.615 0
1 0.005 0 0.336 0.657 0.943 1.173 1.318 1.350 1.242 0.971 0.530 0
2 0.01 0 0.328 0.640 0.915 1.131 1.261 1.280 1.161 0.886 0.485 0
3 0.015 0 0.320 0.621 0.885 1.088 1.205 1.211 1.083 0.823 0.443 0
4 0.02 0 0.311 0.602 0.855 1.045 1.150 1.144 1.017 0.763 0.411 0

Ví dụ 3. Giải gần đúng phương trình đạo hàm riêng dạng Hyperbolic.
 2u 2  u
2
 a
x 2 t 2

Thỏa mãn điều kiện biên : u(x, 0) = f(x) , a = 1


u’t(x, 0) = 0, u(0, t) = u(1, t) = 0
0  x  1, 0  t  0,5 ,

Với sử dụng lưới chữ nhật có bước h = 0.1, l = 0.05

x 0 0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9


f(x) 0 0.029 0.102 0.180 0.217 0.374 0.380 0.289 0.206 0.100

Thế đạo hàm phương trình đạo hàm riêng bằng tỷ sai phân:
ui 1, j  2ui , j  ui 1, j ui , j 1  2ui , j  ui , j 1
2
 a2
h l2

Đặt  = l/h ta được phương trình sai phân:

 
2

ui , j 1  2ui , j  ui , j 1    (ui 1, j  2ui , j  ui 1, j ) (7.23)


a

Với j = 0 phương trình trên có dạng

   2   
2

ui ,1  2ui ,0 1      ui ,1    (ui 1,0  ui 1,0 )


  a   a

Thay đạo hàm u’t(x, 0) bằng tỷ sai phân sau với j = -1


274
ui ,1  ui , 1
u 't ( x,0) 
2l

Thế ui ,1  ui ,1  2.l.u 't ( x,0)

   2  1  
2

ui ,1  ui ,0 1      l.u 't ( x, 0)    (ui 1,0  ui 1,0 ) (7.24)


  a   2 a 

Thế  = l/h =1/2 và a =1, u’t(x, 0) = 0 vào phương trình (7.24) ta được:
3 1
ui ,1  ui ,0  (ui 1,0  ui 1,0 ) (7.25)
4 8

Thế  = l/h =1/2 và a =1


ui , j 1  1,5ui , j  ui , j 1  0, 25ui 1, j  0, 25ui 1, j

Bảng kết quả nghiệm của phương trình


xi
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1
tj
0 0 0.0290 0.1022 0.1796 0.2172 0.3744 0.3804 0.2888 0.2056 0.1004 0.0
0.05 0 0.0345 0.0955 0.1491 0.1873 0.3012 0.2746 0.1947 0.1307 0.0496 0.0
0.1 0 0.0467 0.0869 0.1147 0.1762 0.1929 0.1555 0.1046 0.0515 0.0067 0.0
0.15 0 0.0572 0.0752 0.0888 0.1540 0.0710 0.0330 0.0139 -0.0256 -0.0267 0.0
0.2 0 0.0579 0.0624 0.0757 0.0947 -0.0395 -0.0847 -0.0819 -0.0931 -0.0532 0.0
0.25 0 0.0453 0.0518 0.0641 -0.0029 -0.1279 -0.1905 -0.1812 -0.1478 -0.0763 0.0
0.3 0 0.0230 0.0427 0.0327 -0.1150 -0.2006 -0.2782 -0.2745 -0.1930 -0.0982 0.0
0.35 0 -0.0001 0.0261 -0.0332 -0.2115 -0.2713 -0.3457 -0.3484 -0.2348 -0.1193 0.0
0.4 0 -0.0167 -0.0118 -0.1288 -0.2785 -0.3457 -0.3952 -0.3931 -0.2762 -0.1394 0.0
0.45 0 -0.0279 -0.0803 -0.2326 -0.3248 -0.4156 -0.4318 -0.4092 -0.3126 -0.1589 0.0
0.5 0 -0.0452 -0.1737 -0.3214 -0.3708 -0.4669 -0.4588 -0.4068 -0.3347 -0.1771 0.0

7.6. Phương pháp phần tử hữu hạn

Với phương pháp biến phân người ta tìm lời giải xấp xỉ trên toàn miền bài toán,
do đó hàm xấp xỉ trên toàn miền bài toán thường là rất khó xây dựng, phương pháp
phần tử hữu hạn (PTHH - The finite element method) khắc phục nhược điểm này là
chia miền bài toán thành nhiều miền con và tìm hàm xấp xỉ trên miền con, còn gọi là
phần tử (element) với thỏa mãn điều kiện cân bằng và liên tục giữa các phần tử. Trong
phương pháp PTHH thường dựa trên các phương pháp biến phân RAYLEIGH –
RITZ và GALERKIN.

275
7.6.1. Phương pháp biến phân RAYLEIGH - RITZ
Bài toán [phương trình đạo hàm riêng]  Bài toán [biến phân]

(x, y, Fx , Fy )  0  I(F)   (x, y, F , F )dxdy


x y (7.26)
D

Với cực tiểu phiếm hàm  và thoả mãn điều kiện trên biên F = G(s).
Giả sử ta có F(x, y)  đi tìm I(F) cực trị, ta biểu diển hàm F(x, y) như sau:
n

F(x, y)  F n(x, y) = C1.1(x,, y) + C2.2(x,, y) + . . . + Cn.n(x,,y) =


x
 C  ( x , y)
i 1
i i

Các Ci phải xác định sao cho I(Fn) đạt cực trị.
Hàm i (x, y) được chọn trước sao cho thỏa điều kiện biên. Như vậy:

I  ( F )     ( x, y, C1 , C2 ,..., Cn )dxdy  min (7.27)


D


Các hệ số Ci được xác định từ  0 , i = 1, 2, 3, . . ., n.
ci
7.6.2. Phương pháp biến phân GALERKIN
Nếu hàm  không tồn tại phiếm hàm, người ta sử dụng phương pháp biến phân
Galerkin như sau:

Cho phương trình: L(u)  M  f D (u, xi )  0 (7.28)


 n

Cần tìm nghiệm gần đúng: U   N P .U P trong miền D.


P 1

Với U P (P  1,2,..., n) là các hằng số phải xác định.

N P (P  1,2,..., n) là các hàm tọa độ tự chọn.


 
Ta có: L(U )  M  f D (U , xi )  R, R n  0 (7.29)

Có nghĩa phần dư R sẽ triệt tiêu khi n tiến tới vô cùng.



Đặt điều kiện L(U )  M phải trực giao với i trong miền xác định D với
j (j = 1, 2, . . . , n) là các hàm tọa độ tự chọn độc lập tuyến tính.
Như vậy ta có:

276
     n  
D L(U )  M   j dD  0 hay D   
L
P 1
N P .
U P 

 M   j dD  0

Trong trường hợp U p là hằng số, và  j  N p , ta được phương pháp

GALERKIN.
Tóm lại, phương pháp Galerkin được thiết lập có dạng:

  n  
D   
L
P 1
N p .
U P 

 M  N p dD  0

hay N
D
p .R.dD  0, với p=1,2,…,n (7.30)

7.6.3. Phương pháp phần tử hữu hạn


Chia miền D thành ne (hữu hạn) miền con De :
ne ne

D= D e , chọn hàm: N P   N eP (7.31)


e1 e1

Với N eP gọi là hàm tọa độ được chọn trong miền con De sao cho thoả mãn
một số tính chất nào đó (xem chương 8), ta có được Phương pháp phần tử hữu hạn.

7.7. Phương pháp thể tích hữu hạn


Xét phương trình vi phân:

q  F G k+1
  0 (7.32)
t x y
C
Áp dụng phương pháp miền con k

cho thể tích ABCD, ta có:


k-1
D
 q  F G  B
 1. 
ABCD 
t x

y
dxdy  0


(7.33)
n
Áp dụng định lý Green ta có: A j+1
d
j
dt 
qdv   H .n.dS  0 (7.34)
ABCD
j-1
 
Ở đây H = F, G cho trong tọa độ Descartes.

H.n.dS = Fdy  Gdx


Vì phương trình (7.34) dạng bảo toàn với thể tích tùy ý, nên ta có:

277
 
D
.q j ,k   F .y  Gx   0
d
(7.35)
dt A

Ở đây,  là diện tích của (ABCD), yAB = yB - yA, xAB = xB - xA , nên:

FAB =
1
Fj,k1  Fj,k , GAB = 1 G j,k1  G j,k 
2 2
Tương tự cho yBC, yCD, yDA, . . .

Nếu  không phụ thuộc thời gian t và xi = yi = const, ta được:
d F j 1,k  F j 1,k G j ,k 1  G j ,k 1
q j ,k  
dt 2x 2y
7.8. Phương pháp phần tử biên
Với phương pháp phần tử biên, như tên gọi của nó, 2
việc chia phần tử chỉ ở biên của bài toán.
Xét ví dụ bài toán mô tả dòng chảy thế hai chiều
(2 Dimensions): 1 
n
 2 = 0 (7.38)
Trong miền  ta có:

+ Điều kiện biên chủ yếu:    trên biên 1 (đk biên Dirichlet)

  
+ Điều kiện biên tự nhiên: q =   q trên biên 2 (điều kiện biên
n n
Neumann)
Với  = 1 + 2
Dạng biến phân trọng số dư
Định nghĩa:
Gọi các phần dư:
~
R=  
2


R1 =   

R2 = q - q

~ ~
 R. .d    R .q .d   R
~  .d
=> 1 2
 1 2

278
Dùng tích phân từng phần hai lần liên tiếp, ta có:

~ ~ ~
 (  ) .d    q . .d   q. .d   q~. .d   q~. . d
2

 2 2 2 1

Ta có lời giải cơ bản cho phương trình Poisson:

~
2    ( x  x )  0 (7.41)
Với  là hàm Dirac.

Lời giải cho bài toán 2D, khi x  x là:

~ 1 1
  . ln( ) , với r = x 2  y 2 (7.42)
2 r
Với những điểm x nằm bên trong  , cách thành lập theo phương pháp phần
tử biên cho bài toán biểu diễn bởi phương trình Laplace là:
~
 ( x )   . q~.d    .q.d
 

Với những điểm x nằm trên biên  , phương trình viết cho bài toán trở thành:

~
c. ( x )    . q~.d    .q.d (7.43)
 


với c = (thông thường c = 1/2)
2. 
Ta đi rời rạc hóa biên  của miền D, dùng phần tử bậc 2 ta được:
n n
~
(c. ) i     . q~.d     .q.d (7.43)
j 1 j j 1 j

1 
 
Hàm dạng  được biểu diễn:  ( )  [ N1 N 2 N 3 ] 2   [ N ] ,
 
 3

q(  )=[N]. q

279
3
0


  1
1 2

  1

1 1
N1(  ) = (  1) , N2 (  ) = (1  )(1  ) , N3(  ) = (  1)
2 2
Với  [ 1,1]
Thiết lập cho một phần tử trên biên, ta có:

1  1 
   
 . q .d   [ N1 N 2 N 3 ]. q .2 .d  [h1 h2 h3 ].2 
~ ~
3   
 3
j j

 q1   q1 
~ ~   
  . q.d   [ N1 N 2 N 3 ] .q2 .d  [ g1 g 2 g 3 ].q2 
 q3  q 
 3
j j

~
Ở đây:  ~
hk= N k q d
j

và gk = N k  d , k  1,2,3
j

Chú ý: Ta có Jacobicon biến đổi toạ độ như sau:

 dx   dy 
2 2 h2
d        , d  G .d
 d   d 
h2
1 j+
hk =  N k ( ). q
~.d 
 N K ( ) q~. G d ho 1
j
1

~
1
~ j
gk = 
j
N k ( ). .d   N K ( )  . G d
1
h1

Cuối cùng thế vào phương trình đã rời rạc hoá, ta có:
1 
   q1 
  
 2  
(c ) i  H i1 H i 2 ..... H in ]   [Gi1 Gi 2 .... Gi 2 N ] q 2  (7.44)
 ...  q 
   2N 
 n

280

Với H ij là tổng của số hạng h1 của phần tử j + 1 và h2 của phần tử j.

Nếu đặt:
 ˆ
 H ij , i  j N 2N
H ij  
 ˆ
 H ij  c, i  j thì ta viết lại: H
i 1
ij . j   Gij .q j
j 1

Hay ta có hệ phương trình: H.U = G.q (7.45)


Giải hệ phương trình này ta sẽ tìm được các ẩn của bài toán trên biên, từ đó ta
sẽ tìm được các ẩn trong miền D tại những nơi cần thiết.

Câu hỏi:
1) Trình bày ý nghĩa vật lý của các phương trình loại Hyperbol, Parabol, Ellip?
Trong thực tế có những phương trình lưỡng tính, nhất là trong cơ học lưu chất,
hãy cho vài ví dụ và giải thích ?
2) Từ sự mô tả bản chất vật lý của bài toán của mỗi loại phương trình mô tả, nên
số và loại điều kiện biên phải đáp ứng, hãy cho mỗi loại phương trình vài ví dụ?
3) Phương pháp đặc trưng đóng một vai trò quan trọng trong việc hiểu rõ bản chất
vật lý của bài toán, vì sao?
4) Phương pháp sai phân là phương pháp không bảo toàn, vì sao?
5) Nêu các điều kiện để sơ đồ sai phân được chấp nhận?
6) Ưu nhược điểm của sai phân hiện và sai phân ẩn?
7) Hãy nêu sự giống nhau và khác nhau của các phương pháp Sai phân, Phần tử
hữu hạn, Thể tích hữu hạn, Phần tử biên; ưu nhược điểm của chúng?

Bài tập :
Bằng phương pháp sai phân giải các phương trình sau:
  2u  2u
 2  2 , 0  x  2, u x,0  x  2 x
2

 t  x
1) 
u 0, t    u 2, t   sin t , u  1  0,1.k . 
. 2  x
 t t 0

Bước chia theo x là h = 0.5, theo t là k = 0.01.Tính u(x, 0.03)

281
 u  2 u
  2 , 0  x  1, t  0
 t x
2) u x,0   4  0,1.k 1  x 
u 0, t   u 1, t   0



Bước chia theo x là h = 0.25, theo t là k = 0.025.Tính u(x, 0.1)


u xx  u yy  1  0,1.k

3) x, y   G  0,1 0,1
u x, y   0, x, y 

Thuộc biên của G h = k = 0.25


4) Tìm nghiệm gần đúng của phương trình đạo hàm riêng sau bằng phương pháp
sai phân hữu hạn:
 2u 2  u
2
 a
x 2 t 2
Thỏa mãn điều kiện biên:
u(x, 0) = f(x) a=1
u’t(x, 0) = 0; u(0, t) = u(1, t) = 0
0  x  1, 0  t  0,5
Với sử dụng lưới chữ nhật có bước h = 0.1, l = 0.05
5) Giải gần đúng phương trình đạo hàm riêng dạng PARAPOLIC phương trình
u’t = u’’xx trên hình chữ nhật [0, 2]x[0, 0.3] với điều kiện biên u(0, t) = u(2, t) = 0,
u(x, 0) = x(2 - x), bước chia theo t là  = 0.1.
6) Tìm nghiệm của phương trình dạng Elliptic :
 2u  2u
 0
x 2 y 2
Với miền xác định G ={0  x  6, 0  x  6}

Thỏa mãn điều kiện biên:


u
  x y u 1
n 
7) Tính chuyển vị trên dầm chịu tải trọng tam giác hướng từ trên xuống dưới. Với
điều kiện biên M1 = M4 = 0

282
q0
0

Trong đó: q là cường độ tải trọng phân bố.


E là mô đun dàn hồi.
J là moomen quán tính của tiết diện ngang của dầm.
L là chiều dài của dầm.
8) Tìm chuyển vị và nội lực của tấm vuông, chu vi gối tựa đơn, cạnh a, chịu tải
trọng phân bố hình thang như hình vẽ. Biết chuyển vị của tấm thỏa mãn phương trình:
 4u  4u  4u q
 u  4 2 2 2  4 
2

x x y y D

Trong đó: q là cường độ tải trọng phân bố


D là độ cứng chống uốn của tấm
U là chuyển vị của tấm

q0/2 5q0/8 3q0/4 7q0/8 q0

283
Chương 8 PHƯƠNG PHÁP PHẦN TỬ HỮU HẠN

Như đã phân tích ở mục 7.6, chương 7, một bài toán có miền hình học phức tạp,
có thể xem như là tập hợp của nhiều dạng hình học đơn giản (gọi là miền con hay phần tử
–element), để việc xây dựng hàm xấp xỉ (hay còn gọi là hàm nội suy - interpolation
function) trên miền con này được dễ dàng, hàm xấp xỉ được xây dựng một cách hệ thống
cho hầu hết dạng hình học, hàm xấp xỉ này chỉ phụ thuộc vào phương trình vi phân, từ đó
hình thành phương pháp phần tử hữu hạn.
Với phương pháp phần tử hữu hạn, miền tính toán được xem như là tập hợp nhiều
miền con hữu hạn (finite element) có dạng hình học đơn giản (simple shape-element).
Trên mỗi miền con này, phương trình chủ đạo (governing equation) được thiết lập với sử
dụng một phương pháp biến phân nào đó. Các phần tử được liên kết với nhau và phải thoả
mãn điều kiện cân bằng và liên tục của các biến phụ thuộc qua biên của các phần tử.

8.1. Các loại phần tử


Miền tính toán được chia thành nhiều miền con (còn gọi là phần tử), nếu miền tính
toán là một chiều, ta có phần tử một chiều, miền tính toán là hai chiều ta có phần tử hai
chiều, miền tính toán là ba chiều ta có phần tử ba chiều.

Tuyến tính (2) Bậc hai (3) Bậc ba (4)

Các loại phần tử một chiều

Tuyến tính (3) Bậc hai (6) Bậc ba (9)

Các loại phần tử hai chiều

284
Tuyến tính (4) Bậc hai (8) Bậc ba (12)

Tuyến tính (4) Bậc hai (10) Bậc ba (16)

Tuyến tính (8) Bậc hai (20) Bậc ba (32)

8.2. Hàm nội suy


Lời giải xấp xỉ của ẩn số bài toán được cho bởi:
n
h  h
j 1
j .N j
(8.1)

Ở đây j là hàm nội suy (interpolation functions) và hj là ẩn của bài toán tại nút
của phần tử.
Ta cũng có thể mô tả hình dạng của phần tử bằng cách dùng các toạ độ của mỗi nút
trong phần tử (xem Hình 8.1).

285
n
x( p )  S
j 1
j ( p ).x j (8.2)

Tuyến tính (6) Bậc hai (16) Bậc ba (24)

n
y ( p)  S
j 1
j ( p ). y j (8.3)

n
z ( p)  S
j 1
j ( p ).z j (8.4)

Vì rằng hàm nội suy Sj được dùng xác định hình dạng của phần tử, nên thường
được gọi là hàm dạng (shape functions).

Hàm nội suy tuyến tính, hàm dạng tuyến tính

hj Hàm nội suy

h(e)(x)=Ni(e)(x)hi + Nj(e)(x)hj
h(e)(x)

x(P)=Si(e)(x)xi(e)+Sj(e)(x)xj(e)
hi
Hàm dạng
xi(e) xi(e)
x

286
Hàm nội suy bậc hai, hàm dạng tuyến tính

hk
h(e)(x)=Ni(e)(x)hi + Nj(e)(x)hj+ Nk(e)(x)hk

hj
Hàm nội suy
h(e)(x)
x(P)=Si(e)(x)xi(e)+Sj(e)(x)xk(e)
hi
Hàm dạng
xi(e) xj(e) xk(e)
x
Hình 8.1: Hàm nội suy và hàm dạng của phần tử một chiều
Bậc của đa thức dùng để nội suy và các hàm dạng bên trong phần tử có thể là khác
nhau, người ta phân ra ba loại như sau: Phần tử dưới tham số (subparametric elements)
khi bậc đa thức hàm dạng nhỏ hơn bậc đa thức nội suy. Phần tử đẳng tham số
(isoparametric elements) khi bậc đa thức hàm dạng bằng bậc đa thức nội suy. Phần tử trên
tham số (superparametric elements) khi bậc đa thức hàm dạng lớn hơn bậc đa thức nội
suy (xem Hình 8.2).
Đa số các bài toán trong thực tế dùng phần tử đẳng tham số và hàm dạng đồng nhất
với hàm nội suy.

Phần tử dưới tham số

hk
hj Hàm nội suy bậc hai(nút i, j, k)
h(x)
hi Hàm dạng tuyến tính (nút i và nút k)

xi(e) xj(e) x xk(e)

Phần tử đẳng tham số

hj
Hàm nội suy tuyến tính (nút i và j)
h(x)
Hàm dạng tuyến tính (nút i và j)
hi

xi(e) x xj(e)
287
Phần tử tham số Hàm dạng bậc 2(nút i, j,k)

(e) (e)
(xk(e) , yk(e))
hk (xj , yj )
h(x)
(xi(e) , yi(e))
hi
Hàm nội suy tuyến tính (nút i và j)

Si(e) Sj(e) Sk(e)


S
Hình 8.2: Minh hoạ về định nghĩa các loại phần tử một chiều dưới tham số, đẳng
tham số, và trên tham số.
Khi tại các nút chỉ chứa ẩn số h của bài toán, thường sử dụng hàm nội suy
Lagrange (phần lớn các hàm nội suy trong các bài toán chất lỏng được sử dụng bởi nội
suy Lagrange, do đó ở đây chỉ giới thiệu nội suy Lagrange), nếu tại các nút còn có ẩn số
là đạo hàm h / xi thường sử dụng hàm nội suy Hermite.
Hàm nội suy Lagrange được xây dựng từ đa thức như sau:

x  xm
N k ( x)   (8.5)
m 0 xk  xm
k m

Với: m là số nút.
xm là toạ độ nút thứ m.
Tính chất của hàm nội suy:
Hàm nội suy có các tính chất sau:
 Tính chất 1: Hàm nội suy có giá trị bằng 1 tại nút đó và bằng 0 tại các nút
khác.
 Tính chất 2: Các hàm nội suy thoả biểu thức sau:
n

 N ( ).P ( )  P ( ), j  1,2,....n
i 1
i j i j (8.6)

Với Pj (i) là đa thức cơ sở của hàm nội suy.


Hàm nội suy có thể được xây dựng trong hệ toạ độ tổng thể (global coordinates)
hoặc hệ toạ độ địa phương (local coordinates), thông thường với các bài toán phức tạp

288
(nội suy bậc cao ở các bài toán hai hoặc ba chiều) phải sử dụng hàm nội suy trong toạ độ
địa phương.
8.2.1. Hàm nội suy cho bài toán một chiều
a. Nội suy tuyến tính trong hệ toạ độ tổng thể:
N  N1 N2  (8.7)
xB  x x  xA
Với N1  N2 
xB  xA xB  xA

b. Nội suy dạng Lagrange bậc hai trong hệ toạ độ tổng thể:
N  N1 N 2 N 3  (8.8)

Trong đó: Ni(x)= ( với i = 1, 2, 3

 ie  xie x ke   x ke x ej 
2 2

 ie  x ej   x ke 
2 2
Trong đó:

 ie  x ej  x ke  ,
3
D e    ie
i 1

c. Nội suy tuyến tính trong hệ toạ độ địa phương


N  N1 N2  (8.9)

Ni 
 N 1  2 1   
1
N1 N2  (8.10)
1.0  N  1 1   
 2 2

-1 0 
1

d. Nội suy bậc hai dạng Lagrange trong hệ toạ độ địa phương: N  N1 N2 N3 

u1 u2 u3 u1 u2 u3
1 2 3 1 2 3

x1  x3 x
-1 0 1  x1 x2  x3
2
1    1
nd = 3 x1  x  x3
vr n=3
v er

289
e. Nội suy bậc ba dạng Lagrange trong hệ toạ độ địa phương:
N  N1 N2 N3 N4 

u1 u2 u3 u4 u1 u2 u3 u4
1
1 2 3 4 1 2 3 4

2 x1  x 4 2 x1  x 4
-1 1/ 3 0 1/ 3 1 x1 x2  x3  x2
3 3

1    1 x1  x  x2
nd = 4
vr n=4 v er

 9 1  1 
 N1   16 1     3    3   
   
 27 1 
 N 2   1   1       
 16 3 
 (8.11)
 N   27 1   1     1   
 3  
16 3 

 N   9  1    1    1  
 4    
16  3  3 
8.2.2. Hàm nội suy cho bài toán hai chiều
a. Nội suy tuyến tính trong hệ toạ độ tổng thể cho phần tử tam giác:
N  N1 N2 N3  (8.12)

Ở đây: N1 
1
2A

 ie   ie x   ie y  (8.13)

Với: i = 1, 2, 3 hoán vị vòng tròn


 i  x j y k  xk y j
 i  y j  yk
 i  x j  x k 

b. Nội suy tuyến tính trong hệ toạ độ địa phương cho phần tử tam giác:
N  N1 N 2 N 3  (8.14)

290

y
u3
3 2 u2
u3 3
t n
1

u1
1 2
u1 u2  x
vr ve
n 3 n3 nd  3

Với:
N1  1    , N 2   , N 3  

Nếu điểm gốc toạ độ địa phương được chọn khác như hình sau, thì hàm nội suy
cho phần tử tam giác cũng sẽ thay đổi theo:


1
1 N1   (   )
2
1
 N 2   (1   ) (8.15)
2
1
-1 N 3   (1   )
2
- 1
1
c. Nội suy bậc hai trong hệ toạ độ địa phương cho phần tử tam giác:


y
u5 n
t
5 u4
u5
5 4 u3
3
u4 u6 6 2
u6 6 4 u2
1
1 2 3 u1
u1 u2 u3  x
n6 nd  6
291
N 1   1  2 , N 4  4
N 2  4 , N 5   1  2 
(8.16)
N 3   1  2 , N 6  4

Với:   1  
d. Nội suy tuyến tính trong hệ toạ độ địa phương cho phần tử tứ giác:
Hàm dạng: N  N1 N 2 N 3 N 4  (8.17)

N1 
1
1   1   , N3 
1
1   1   
4 4
N 2  1   1   , N 4  1   1   
1 1
4 4

y

u4 u3 u3
4 3 3
u4
4
 2 u2
1
u1
1 2 ve
u1 u2
n4 x
v r n4 nd  4

e. Nội suy bậc hai trong hệ toạ độ địa phương cho phần tử tứ giác:

 5
x1  x3
1
6 4 x2 
3 2
7 6 5 7 9 etc
8 2
-1 8 4 1 …
9  1
1 2 3
-1 x
nd  9
e
v
r
v n 9
292
 3     1  1 ,  4     1  1
1 1
4 4

 5   1   2   1 ,  6     11   2 
1 1
2 2 (8.18)

 7   1   2   1 ,  8     11   2 
1 1
2 2
 9  1   2 1   2 

8.2.3. Hàm nội suy cho bài toán ba chiều


a. Nội suy tuyến tính trong hệ toạ độ địa phương cho phần tử hình chóp:

z
u4
 4
u4 1 3 u3
4 u1 2
u1 3 u2
1 u3  y
2
 u2 x ve
vr n4 nd  4

N1  1       , N3  
N2  , N4   (8.19)

b. Nội suy bậc hai trong hệ toạ độ địa phương cho phần tử hình chóp:

N 1   1  2 
1
70 N 2  4
9 N 3   1  2 
8 6 (8.20)
N 4  4
1
5  N 5   1  2 
2
4 N 6  4
3

293
N 7  4 , N 8  4
với:   1    
N 9  4 , N10   1  2 

c. Nội suy tuyến tính trong hệ toạ độ địa phương cho phần tử ba chiều hình trụ đáy tam
giác:

z
 6
 0
4 6 0 3
3
5 1   0 4
1    0
2
 1
  1 y
1
 3
ve
2 vr x
n6
nd  6

N1  a , N 4  b
N 2   a , N 5  b (8.21)
N 3  a , N 6  b
1 1
Với:   1    , a , b
2 2

d. Nội suy tuyến tính trong hệ toạ độ địa phương cho phần tử ba chiều hình trụ có đáy tứ
giác:

z 8
 1   1 7
6
5  1   1 5
 1   1 6
4 3
 1
4 2
1
3 y
2 
vr n8 n8 nd  8 ve
x

294
N1 
1
a2 b2 c2 , N 2  1 a1 b2 c2 , N 3  1 a1 b1 c2 
c c c

N4 
1
a2 b1 c1  , N 5  1 a2 b2 c1 , N 6  1 a1 b2 c1 
c c c

N7 
1
a1 b1 c1  , N8 
1
a2 b1 c1  (8.22)
c c
a1  1   , a 2  1  
Với : b1  1   , b2  1  
c1  1   , c 2  1  

8.3 . Tích phân số


Trong phương pháp phần tử hữu hạn, nhằm lợi dụng khả năng tính toán rất nhanh
của máy tính cũng như khi cần độ chính xác khá cao cho bài toán, do đó người ta thường
sử dụng tích phân số của Gauss (tham khảo mục 3.2.3.)
8.4. Các bước tính toán cơ bản và kỹ thuật lập trình cho máy tính số theo phương
pháp phần tử hữu hạn
Để áp dụng cách giải bài toán theo phương pháp phần tử hữu hạn người ta thực
hiện các bước sau:
Bước 1: Rời rạc hoá miền khảo sát.
Chia miền khảo sát V thành ne miền con V(e) hay các phần tử có dạng hình học
nhất định.
ne
Ta có: V  V (e) (8.23)
e 1

Với cách chia miền tính toán V bằng tổng các miền con V(e) , mô hình thực tế được
thay bằng mô hình tính toán với ne phần tử hữu hạn được liên kết với nhau bởi các điểm
nút và tại mỗi điểm nút tồn tại các đại lượng thể hiện sự tác động qua lại của các phần tử
kề nhau, như vậy bài toán hệ liên tục có bậc tự do vô hạn được thay bằng bài toán tính
hệ có bậc tự do hữu hạn đơn giản hơn nhiều.

Ví dụ với các bài toán thấm thường có các dạng sơ đồ sau:

295
 Một chiều:
Mưa

Nút
Lớp không thấm

Phần tử

 Hai chiều:
Mặt đất
Mực nước
ngầm
Phần tử

 Ba chiều:
Phần tử

Bước 2: Chọn hàm xấp xỉ thích hợp.

Phương pháp phần tử hữu hạn áp dụng ở đây thường là phương pháp Galerkin- gọi
tắt là phương pháp phần tử hữu hạn Galerkin.

Để tìm được nghiệm trên các miền con điều quan trọng là phải chọn hàm toạ độ
Np(e) (hay còn gọi là hàm nội suy, hàm dạng) đảm bảo sự liên tục của các đại lượng cần
tìm giữa các phần tử trong miền D.

Bước 3: Xây dựng phương trình phần tử.

296
Miền V được chia thành ne phần tử (miền con V(e)) bởi R điểm nút. Tại một nút có
s bậc tự do, thì số bậc tự do của cả hệ là: n = R.s
Gọi  q  là véc-tơ ẩn của toàn hệ,  q e là véc tơ ẩn của mỗi phần tử, giả sử mỗi
phần tử có r nút, thì số bậc tự do của mỗi phần tử là: r s
Ta có liên hệ :  q e = Le   q  (8.24)
(ne1) = (nen) x (n 1)
Với Le được gọi là ma trận định vị.
Ứng với mỗi phần tử, ta có phương trình ma trận:
Ke q e = Ce (8.25)
[K]e ma trận phần tử , {C}e vectơ vế phải phần tử.

{q}e là tập hợp các giá trị cần tìm tại các nút của phần tử.

Bước 4: Ghép nối các phần tử.

Tập hợp cho tất cả các phần tử trong miền V, ta có:


ne ne


e 1
Ke  q e = 
e 1
Ce

Viết lại:  K  q  =  C  (8.26)


ne ne
Trong đó: K  =  e 1
Ke = 
e 1
LeTKeLe

C    C
ne ne

e 1
e = 
e 1
LeTCe
K- Ma trận tổng thể.
q - Vectơ tập hợp tổng các ẩn cần tìm tại các nút (tổng bậc tự do tại các nút).
 C  Vectơ các số hạng tổng thể ở vế phải.
Như vậy việc sử dụng ma trận định vị Le để tính  K  và  C , thực chất là sắp
xếp các phần tử Ke , Ce vào vị trí của nó ở trong  K  và  C . Tuy nhiên trong thực
hành người ta không dùng cách này.
Sau đây, sẽ giới thiệu một cách ghép nối trực tiếp để thiết lập ma trận tổng thể và
vectơ vế phải tổng thể mà không cần xử dụng ma trận định vị Le .
Giả sử xét bài toán thấm có áp trong miền  (A B C D E F), miền được chia thành
8 phần tử tam giác (ne = 8), có 9 điểm nút (R = 9), tại mỗi điểm nút có s bậc tự do (số ẩn
297
số tại nút ), ở đây s =1 là cột nước thấm, mỗi phần tử tam giác có 3 điểm nút (r = 3), thì số
bậc tự do của mỗi phần tử là: r s = 31 = 3 (xem Hình 8.3).

y(m)
Vn = 0
F E D k
3 9
6
4 8
3 7 
2 8 i
2 5 6 j
1 4 5
1 7
A B C x(m)
Vn = 0

Hình 8.3: Ví dụ bài toán thấm có áp miền tính toán (ABCDEF)

Nếu cũng với phần tử tam giác có ba điểm nút này r = 3, tại mỗi nút có ba ẩn h, u,
v như bài toán dòng chảy hở hai chiều ngang s = 3, thì số bậc tự do của mỗi phần tử là r.
s = 3x3 = 9, ta sẽ được ma trận phần tử (9, 9). Để đơn giản ta xét phần tử tam giác tại mỗi
nút có một bậc tự do. Mỗi phần tử (ở đây là tam giác) được đánh số các nút (i, j, k) theo
chiều được qui ước (chẳng hạn ngược chiều kim đồng hồ) nút i được qui ước là nút ở bên
trái và thấp nhất. Với mỗi phần tử bất kỳ ne ta có ma trận phần tử Ke và véc tơ vế phải
Ce như sau:
 K iie K ije K ike  cie 
K e

  K eji K ejj K ejk 

, Ce
 
= c ej 
 K kie K kje K kke  c e 
  k
Với cách đánh số nút và phần tử như trên ta có 8 phần tử với các nút tương ứng (i,
j, k) như sau: e1(1, 4, 5), e2(1, 5, 2), e3(2, 5, 6), e4(2, 6, 3), e5(4, 7, 8), e6(4, 8, 5), e7(5, 8,
9), e8(5, 9, 6) .
Ví dụ phần tử: e4(i, j, k)  e4 (2, 6)
 K 22
4 4
K 26 4
K 23  c 24 
 4   
Ke=4 =  K 624 4
K 66 K 63  , và Ce=4 = c 64 
 K 32
4 4
K 36 4 
K 33 c 4 
   3

298
Mỗi hệ số Kije : e chỉ số trên, chỉ số này thuộc ma trận phần tử, i là hàng nào
trong ma trận tổng thể, j là cột nào trong ma trận tổng thể. Ví dụ đây là hệ số của ma
trận phần tử e = 4, nằm trong hàng 6 cột 2 của ma trận tổng thể. Và ma trận tổng thể:
ne 8
K  =  K 
e 1
e =  K  e
e 1
= [X]

 1 2 3 4 5 6 7 8 9 
1 1 2 
 k 11 +k 11 k 212 k 141 1
k 15 +k 152

 2 k 2 k 2 +k3 +k 4 k 423 k 225 +k 325 k 326 +k 426 
 21 22 22 22 
3 4
k 32 k 433 k 436 
 
 4 k1 k144 +k544 +k644 k145 +k 645 k547 k548 +k 648 
= 1 2 
41

[X] 5 k 51 +k 51 k 52 +k 52 k 59 +k 59  (8.27)
2 3
k154 +k 654 k155 +k 255 +k 355 +k 655 +k 755 +k 855 k 356 +k 856 k 658 +k758 7 8

 
6 k362 +k 462 k 463 k365 +k 865 k 366 +k 466 +k 866 k 869 
 
7 k574 k577 k578 
 
8 k584 +k684 k685 +k785 k587 k588 +k 688 +k 788 k 789 
9 
 k795 +k895 k896 k798 k799 +k 899 

Cộng một cách tương tự cho vectơ vế phải  C , với chú ý phép cộng này giống
cộng các số hạng trên đường chéo chính của ma trận tổng thể  K :
ne
C  =  e 1
Ce (8.28)

Ta thấy ở ma trận tổng thể các phần tử khác không có dạng đường chéo (hay còn
gọi là dạng Band). Để tiết kiệm bộ nhớ và thời gian tính của máy tính, người ta chỉ lưu
trữ các phần tử khác không này và thuật toán cũng chỉ tính toán với các phần tử khác
không.
Người ta phải lưu trữ cả ma trận dạng Band này khi ma trận Band có chiều rộng
Band hẹp (liên quan đến cách đánh số nút của các phần tử), không đối xứng (Hình 8.4).
Chỉ cần lưu trữ một nữa Band khi ma trận đối xứng. Khi chiều rộng Band lớn và trong các
hàng của Band còn nhiều phần tử bằng không, người ta có thể dồn ma trận lại thành ma
trận Band hẹp hơn, như vậy sẽ cần thêm ma trận định vị nữa. Tuy nhiên với cách lưu trữ
ma trận Band dù theo kiểu nào, thì trong Band vẫn còn một số hệ số phần tử bằng không,

299
do đó để loại bỏ các phần tử bằng không ở trong Band, người ta còn có cách lưu trữ các
phần tử khác không này ở dạng vectơ gọi là kỹ thuật frontal method.
Thiết lập ma trận tổng thể của bài toán ở dạng ma trận Band
Ở đây ma trận tổng thể được lưu trữ ở dạng Band, ví dụ ma trận tổng thể không đối
xứng, nên lưu trữ cả hai Band (KIJ  K J I).
b
b

[VK] KII

n
[K]= KII

n 2b+1
1111
Hình 8.4: Cách lưu trữ ma trận dạng Band

Ta có : KIJ = V Ki j (8.29)
Với : i = I
j = J - I + 1 + b
(Nếu ma trận đối xứng chỉ cần lưu trữ một Band, lúc đó j = J - I + 1)
Sau đây là thuật toán theo phương pháp khử Gauss, viết cho ma trận Band đối
xứng, chỉ lưu trữ một Band có chiều rộng b:
Ước lượng thuận Thế ngược

bn
Do k = 1, n = 1 bn 
an ,1
nbk = min(n-k+1, b)
do i = k+1, nbk+k+-1 Do ii = 1, n =1
i1 = i - k+1 i = n – ii
c = ak, i1/ak,1 nbi = min(n-1+1, b)
do j = I, nbk +k – 1 sum = 0
j1 = j-i+1 Do j = 2, nbi
j2 = j-k+1 Sum = sum + ai, jbi+j-1
ai, j1 = ai, j1 – cak, j2 bi  sum
bi 
bi = bi - cbk ai ,1

300
Bước 5: Áp đặt các điều kiện biên của bài toán ta sẽ nhận được hệ phương trình
để giải như sau:

Cách áp đặt điều kiện biên


Sau khi có được ma trận hệ thống ở dạng Band, để việc lập chương trình được đơn
giản, kích thước ma trận tổng thể của bài toán được cố định khi có số điều kiện biên là bất
kì.
Cách làm như sau:
- Dạng phương trình [ K ].{ q } = { c } (8.30)
- Nếu ẩn số thứ i = r được biết là i , tức là:
q r = i
Thì các hệ số của ma trận hệ thống được biến đổi như sau:
b

1
b

1
[VK] =

n
n

[K]=

n 2b+1

Hình 8.5: Cách áp đặt điều kiện biên

Krj = 0 nếu j  r
Kir = 0 nếu i  r (8.31)
Krr = 1
Vectơ vế phải của hệ thống sẽ là:
 c1  k1r   i 
c  k  
 2 2r  i 
  
C =   (8.32)
 i 
  
 
c n  k n r   i 

301
Cũng có thể đưa điều kiện biên vào bằng cách nhân hệ số trên đường chéo chính
của ma trận [VK] với một số rất lớn (từ 108 - 1015) khi ma trận [K] có tính chất trội hoặc
không xấu (các hệ số kii là không quá bé so với các hệ số khác).
Bước 6: Giải hệ phương trình đại số.

K q  C 
* * *
(8.33)

Cách giải hệ phương trình ở dạng ma trận (8.33) này tuỳ theo từng loại bài toán
(dừng hoặc không dừng) tính chất của ma trận lưu trữ, cách lưu trữ ma trận tổng thể mà
chọn cách giải thích hợp; chẳng hạn khử Gauss trực tiếp, phép tách LU hay Cholexski
hoặc giải lặp Gauss-seidel có hệ số giảm dư hay lặp theo phương pháp gradient liên
hợp,… (xem N.T. Hùng, 2000)
Ví dụ. Áp dụng phương pháp PTHH Galerkin
d 2T
Giải phương trình   f ( x) với chiều dài thanh l = 10cm với điều kiện biên
dx 2
T(0, t) = 50, T(10, t) = 100 và hàm phân bố nhiệt độ f(x) = 20, theo phương pháp phần tử
hữu hạn Galerkin.
Giải:
Bước 1: Rời rạc hoá miền khảo sát.
Rời rạc hóa thanh thành 5 phần tử tương ứng với 6 nút như hình vẽ

e1(1,2) e2(2,3) e3(3,4) e4(4,5) e5(5,6)

Đánh số nút và số tên phần tử như trên.


Bước 2: Chọn hàm xấp xỉ.

302
Chọn hàm xấp xỉ T  N1T1  N 2T2 , ở đây :

+ N1, N2 là hàm nội suy tuyến tính trong hệ toạ độ tổng thể :
N  N1 N 2 ,

x2  x x  x1
N1  ; N2 
x2  x1 x2  x1

+ T1, T2 là ẩn của bài toán tại nút của phần tử.


Áp dụng tích phân phần tử hữu hạn Galerkin.
x2  d 2T 
x1  dx 2  f ( x)N i dx  0
 

x2 d 2T x2
x1 dx 2
N i dx    f ( x)N i dx
x1
(8.34)

x2 d 2T
Ta tích phân từng phần vế trái : 
x1 dx 2
N i dx

 dN i ( x)
u  N i ( x)  du  dx
Với:  2   dx ta được
dv  d T dx v  dT
 dx 2  dx
x2
x2 d 2T dT x2 dT dN ( x)i
x1 dx 2
Ni dx  Ni ( x)
dx x1

x1 dx dx
dx

x2 d 2T dT ( x2 ) dT ( x1 ) x2 dT dN i
x1 dx 2
N i dx  N i ( x2 )
dx
 N i ( x1 )
dx

x1 dx dx
dx (8.35)

x2  x
Với: x = x2 thì N1(x2) = 0 ( N1  ).
x2  x1

x2  x
x = x1 thì N1(x1) = 1 ( N1  ).
x2  x1

Kết hợp phương trình (8.34) và (8.35):


Khi i = 1 (tại nút đầu của phần tử), ta có:
303
x2 dT dN1 dT ( x1 ) x2
x1 dx dx
dx  
dx
  f ( x) N1 ( x)dx
x1
(8.36)

Khi i = 2 (tại nút cuối của phần tử), ta có :


x2 dT dN 2 dT ( x2 ) x2
x1 dx dx
dx 
dx
  f ( x) N 2 ( x)dx
x1
(8.37)

x2  x
N2  suy ra N 2 ( x 2 )  1 , N2 ( x1)  0
x2  x1

dT dN1 dN 2
Với  T1  T2 (8.38)
dx dx dx

Và nội suy tuyến tính trong hệ toạ độ tổng thể : N  N1 N 2  với

dN1 1 x x dN 2 1 x  x1
 với ( N1  2 );  với ( N 2  )
dx x2  x1 x2  x1 dx x2  x1 x2  x1

Thế các giá trị trên vào (8.38) ta có:


dT (T2  T1 )

dx ( x2  x1 )

dT dN i
Cùng các giá trị : ; đã tính ở trên và
dx dx
Khi i = 1, ta có:
dT dN 1 x 2  (T  T ) T  T2

x2
dx   2 1
dx  1 (8.39)
x1 dx dx x1 ( x  x )
2 1
2
x 2  x1

Khi i = 2, ta có:
x2 dT dN 2 x2 T  T T T
x1 dx dx
dx   2 1
x1 ( x  x )
2 1
2
dx  1 2
x2  x1
(8.40)

Kết hợp các phương trình (8.36), (8.37), (8.39) và (8.40) biểu diễn ở dạng ma trận:
  dT ( x1 ) x2 
   f ( x) N1 ( x)dx 
1  1  1 T1   dx x1 
   
x2  x1  1 
1  T2   dT ( x ) x2

 dx   f ( x) N 2 ( x)dx 
2

 x1 

Trong đó :

304
x2  x
x2 x2 2


x1
f ( x) N 1 ( x)dx   20
x1
x 2  x1
dx   10(2  x)dx  20 , với x2 = 2, x1 = 0
0

x  x1
x2 x2 2


x1
f ( x) N 2 ( x)dx   20
x1
x2  x1
dx   10 xdx  20 , với x2 = 2, x1 = 0
0

Bước 3: Xây dựng phương trình phần tử


Ứng với mỗi phần tử, ta có phương trình ma trận:
K e T e  Ce
Trong đó :
[K]e ma trận phần tử
{C}e véc tơ vế phải phần tử
T e là tập hợp các giá trị cần tìm tại các nút của phần tử
Tập hợp cho tất cả các phần tử trong toàn miền V, ta có:
ne ne

 Ke  T e =  Ce
e 1 e 1

Các ma trận phần tử của toàn miền V gồm:

k 1 k 1  0,5  0,5
K 1
  111 121    
k 21 k 22   0,5 0,5 
e

k 222 k 232  0,5  0,5


K 2
 2 2 
 
k 32 k 33   0,5 0,5
e

k 333 k 343  0,5  0,5


K 3
 3 3 
 
k 43 k 44   0,5 0,5 
e

k 444 k 454  0,5  0,5


K 4
 4 4 
 
k 54 k 55   0,5 0,5 
e

k 555 k 562  0,5  0,5


K 5
 5 5 
 
k 65 k 66   0,5 0,5 
e

Bước 4: Nối ghép các phần tử

305
5
Đưa các ma trận phần tử vào ma trận tổng thể : K total   K 
1 e

k11
1 1
k12 
 1  0,5  0,5 
k 21
1
k 22  k 22
2 2
k 23    0,5 1  0,5 
   
2 2
 k 33
3 3
  0,5 1  0,5 
K    k 32 k 33 k 34 
  
3
k 43 3
k 33  k 44
4 4
k 45   0,5 1  0,5 
 
 5    0,5 1  0,5
4
k 54 4
k 55  k 55
5
k 56  
    0,5 0,5 

5
k 65 k 66 
5 

Các véc tơ vế phải tương ứng với từng phần tử như sau:
  dT ( x1 ) x2    dT ( x2 ) x3 
   f ( x) N1 ( x)dx     f ( x) N 2 ( x)dx 
 dx x1   dx x2 
C1   x2  C2   x3 
 dT ( x2 )   dT ( x3 ) 
 dx   f ( x) N 2 ( x)dx   dx   f ( x) N 3 ( x)dx 
 x1   x2 

  dT ( x3 ) x4    dT ( x4 ) x5 
   f ( x) N 3 ( x)dx     f ( x) N 4 ( x)dx 
 dx x3   dx x4 
C3   x4  C4   x5 
 dT ( x4 )   dT ( x5 ) 
 dx   f ( x) N 4 ( x)dx   dx   f ( x) N 5 ( x)dx 
 x3   x4 

  dT ( x5 ) x6 
   f ( x) N 5 ( x)dx 
 dx x5 
C5   x6 
 dT ( x6 ) 
 dx   f ( x) N 6 ( x)dx 
 x5 

306
  dT ( x1 ) x2 
   f ( x) N1 ( x)dx 
 dx x1 
 x2 x3 
 f ( x) N ( x)dx  f ( x) N ( x)dx 
 2  2
   dT ( x1 )  20
 x1 x2
  dx 
 x4 x4
  
  40 
5  x3
f ( x ) N 3 ( x ) dx  x f ( x ) N 3 ( x ) dx 
  40 
 Ce   x
3

x5   
40

   
5
e 1
  f ( x) N 4 ( x)dx   f ( x) N 4 ( x)dx   40 
 x4 x4
  
 x6 x3   dT ( x6 )  20 
  f ( x) N 5 ( x)dx   f ( x) N 5 ( x)dx   dx 
 x5 x2 
 
 dT ( x6 ) 6 
x

 dx   f ( x) N 6 ( x)dx 
 x5 

Thế vào ta có hệ phương trình ma trận :


0,5  0,5  T1   dT ( x1 ) / dx  20
 0,5 1  0,5  T   40 
  2   
  0,5 1  0,5  T3   40 
     
  0,5 1  0,5  T4   40 
  0,5 1  0,5 T5   40 
    
  0,5 0,5  T6  dT ( x6 ) / dx  20 

 dT
 0,5T1  0,5T2 
dx
( x)  20

 0,5T1  T2  0,5T3  40

  0,5T2  T3  0,5T4  40
 
  0,5T3  T4  0,5T5  40
  0,5T4  T5  0,5T6  40

  0,5T5  0,5T6 
dT
( x)  20

 dx

Bước 5: Áp đặt các điều kiện biên


Với điều kiện biên T1 = T(0, t) = 50, T2 = T(10, t) = 100 thế vào ta có:

307
 dT
 dx ( x)  0,5T2  5

 T2  0,5T3  65
  0,5T2  T3  0,5T4  40

  0,5T3  T4  0,5T5  40
  0,5T4  T5  90

  0,5T5 
dT
( x)  30
 dx

1  0,5  dT ( x1 ) / dx   5 
 1  0,5  T2   
    65 
   0,5 1  0,5  T3  
  40 

   
  0,5 1  0,5  T4   40 
  0,5 1  0,5   T5   90 
    
  0,5  1 
dT ( x6 ) / dx 
 30

Bước 6: Giải hệ phương trình


Giải hệ phương trình trên ta được kết quả :
dT ( x1 ) / dx  104.9999999 
 T2  219.9999998 
  
 T3  309.9999997 
T   
 T 4  319.9999998 
 T5  249.9999999 
   
dT ( x6 ) / dx   94.9999995

Giải bằng phương pháp giải tích


Phương trình bậc 2 có dạng:
T  ax 2  bx  c (8.41)
Ta có đạo hàm bậc 2: T” = 2a = 20  a = -10
Dùng điều kiện biên để xác định hệ số b và c, với điều kiện ban đầu x = 0 thì
T = 50:
50  10(0) 2  b(0)  c  c = 50

Với x = 10 thì T = 100 thế vào phương trình (8.41) :


100 = -10(10)2 + b(10) + 50  b = 105
308
Ta có phương trình T = -10x2 + 105x + 50
Ta biểu diễn các giá trị của hàm T được tính ra từ 2 phương pháp nêu trên trên
cùng một đồ thị để so sánh kết quả tính toán :

T
350
310 320
300

250 250
220
200

150

100 100

50 50

0
L
0 2 4 6 8 10

Nhận xét:
Qua đồ thị trên ta thấy :
+ Kết quả tính toán bằng phương pháp PTHH cho nghiệm gần đúng với nghiệm
của phương pháp giải tích.
+ Nếu miền tính toán của bài toán nêu trên được chia thành các phần tử có kích
thước càng nhỏ thì độ chính xác của nghiệm càng cao (càng tiến gần đến nghiệm giải
tích).
Phụ lục tính toán bằng phần mền Maple 9
> K:=array([[1,-0.5,0,0,0,0],[0,1,-0.5,0,0,0],[0,-0.5,1,-0.5,0,0],[0,0,-0.5,1,-0.5,0],[0,0,0,-
0.5,1,0],[0,0,0,0,-0.5,-1]]);

309
1 5 0 0 0 0 
0 1 5 0 0 0 
 
0 5 1 5 0 0 
K :  
 0 0 5 1 5 0 
0 0 0 5 1 0 
 
0 0 0 0 5 1
> F:=vector([-5,65,40,40,90,-30]);
F :  5, 65, 40, 40, 90, 30

> linsolve(K,F);
F  104.9999999, 219.9999998, 309.9999997, 319.9999998, 249.9999999, 95.000000
> A:=array([[1,-0.5,0,0,0,0],[0,1,-0.5,0,0,0],[0,-0.5,1,-0.5,0,0],[0,0,-0.5,1,-0.5,0],[0,0,0,-
0.5,1,0],[0,0,0,0,-0.5,-1]]);
1 5 0 0 0 0 
0 1 5 0 0 0 
 
0 5 1 5 0 0 
A :  
0 0 5 1 5 0 
0 0 0 5 1 0 
 
0 0 0 0 5 1
> F:=vector([-5,65,40,40,90,-30]);
F :  5, 65, 40, 40, 90, 30

> linsolve(K,F);
8.5. Phương pháp phần tử hữu hạn trong Cơ học vật rắn
Phương pháp PTHH là một phương pháp số có hiệu quả để giải các bài toán ứng
dụng có điều kiện biên.
Xấp xỉ ẩn trên miền con Ve (phần tử),  Ve = V (miền tính toán). Các phần tử nối
kết lại các điểm nút. Tại nút chứa ẩn bài toán (còn gọi là bậc tự do).
Phương pháp này là chủ đạo trong các bài toán cơ học vật rắn, đặc biệt thích hợp
cho bài toán có miền xác định phức tạp, điều kiện biên khác nhau. Lập trình, tự động,
tính toán dễ dàng và trở nên thông dụng nhờ sự phát triển của máy tính điện tử.
Với bài toán cơ học VẬT RẮN biến dạng & CƠ KẾT CẤU dùng 3 mô hình:
310
+ Mô hình tương thích : Xem chuyển vị là đại lượng cần tìm trước.
+ Mô hình cân bằng : Xấp xỉ ứng suất trên từng phần tử, đi tìm ứng suất.
+ Mô hình hỗn hợp : Xem chuyển vị & ứng suất là hai yếu tố độc lập.
Hàm xấp xỉ biểu diễn gần đúng dạng phân bố của chuyển vị và ứng suất.
Đối với các bài toán trong cơ học chất lỏng, thường thiết lập bài toán theo dạng
yếu Galerkin - trên từng phần tử (Xem sách chuyên khảo của cùng Tác giả).
Bài toán biên (Bài toán có điều kiện biên)
Trạng thái ban đầu G, biên của thể tích V là S.
Sau khi có ngoại lực tác dụng nó biến đổi thành trạng thái G’ .
Hãy tính tại mọi điểm I(x1, x2) những thông số trạng thái như: Chuyển vị u, biến
dạng , ứng suất ,...
u
Biết liên hệ: [] = [
x ] tại 1 điểm.
[] = [E] x [], với E: Tính chất của vật liệu.

x2
 = s

I
x2 u (S)
(V)

u=o G
G'
o x1 x1

a. Phương trình tích phân (Integral equation)


Muốn giải bài toán có điều kiện biên như trên, ngoài các liên hệ đã nói trên, ta còn
cần các phương trình cân bằng. Có 2 cách thiết lập phương trình cân bằng:
(i) Cách thứ nhất: “Phương trình vi phân + Điều kiện biên”

311
x2

(S)

(V)
 2+d  2
 12
dx2 1 I  1+d  1

2

O
dx1 x1

Xây dựng phương trình cân bằng cho một vi phân diện tích [dx1, dx2] bao quanh
điểm I bất kỳ.
D{[u], [E]} = 0: Gọi là phương trình vi phân.
Cộng thêm các điều kiện ràng buộc cho trước trên biên (u = 0,  = s).
Trong “Phương pháp sai phân”, sử dụng phương trình cân bằng theo cách này
(để giải người ta chuyển dạng VI PHÂN về dạng SAI PHÂN).
(ii) Cách thứ 2: “ Nguyên lý biến phân - cực tiểu phiếm hàm’’.
Dùng lý thuyết biến phân để xây dựng phương trình cân bằng cho cả vùng (V), kể
cả biên (S), gọi: Phương trình tích phân và tìm cực tiểu phiếm hàm ở dạng tích phân này
d = 0; đây chính là”Phương pháp cân bằng”. Giải phương trình này sẽ cho ta lời đáp số
của bài toán.
Trong kết cấu hàm  gọi thế năng và ở đây sử dụng biến phân về chuyển vị.
b. Các phương trình cơ bản
(i) Chuyển vị - biến dạng và ứng suất trong phần tử
Ma trận độ cứng phần tử và vectơ tải phần tử
Ta có: {u}e = [N]{q}e (8.42)
Với {q}e chuyển vị nút phần tử.
Từ liên hệ giữa chuyển vị {u}e và biến dạng {  }e ta có:
{  }e = [ ]{ u} e  [ ][ N]{ q} e  [ B]{ q} e (8.43)
Trong đó: [B] = [  ][N]
312
Khi vật liệu tuân theo định luật Hooke ta có:
{}e = [D]({  }e-{  0}e)+{0}e (8.44)
Trong đó: {0}e, {  o }e là ứng suất và biến dạng ban đầu của phần tử.
Mang (8.43) vào (8.44) được: {}e = [D][B]{q}e - [D]{  o }e+{0}e (8.45)
Hay: {}e = [T]{q }e - [D]{  o }e + {0}e (8.46)
Trong đó: [T] = [D][B] gọi là ma trận tính ứng suất phần tử.
Từ (8.42), (8.43), (8.45) cho ta biểu diễn chuyển vị, biến dạng và ứng suất
trong phần tử theo vectơ chuyển vị nút phần tử {q}e.
Thế năng toàn phần của phần tử:
1
 e ({ u} e )   2{ } .{ } e dV -  {g}T {u}e dV -  { P} .{ u} e dS
T T
e (8.47)
Ve Ve Se

Thế (8.42), (8.43), (8.46) vào (8.47) được:


1
 e ({q}e )  V 2{q}e ([ B] [ D][ B]).{q}e dV -
T T

1

1
-(  {g} {u}e dV +
T
{P}T .{u}e dS +  { o }Te .[ D][ B])dV -  { o }Te .B.dV ){q}e
Ve Se Ve
2 Ve
2

1
Hay:  e ({q}e ) = {q}e T [ K ]e {q}e  {q}e T .{P}e (8.48)
2

Trong đó: [K]e =  [B] [D][B]dV gọi là ma trận phần tử.


T
(8.49)
Ve

1 1
{P}e   [ N]T {g}e dV +  {N} {P}e dS +  [ B T ].[ D].{ o }e )dV -  [ B]T .{ o }e dV
T

Ve Se Ve
2 Ve
2

{P} gọi là vectơ tải phần tử.


Trong đó: {g} là lực khối, {P} là tải trọng bề mặt.
Ghép nối các phần tử - Ma trận độ cứng và véc tơ tải tổng thể

Miền V được chia thành ne phần tử (miền con Ve ) bởi R điểm nút. Tại 1 nút có S
bậc tự do, thì số bậc tự do cả hệ: n = R.S
Gọi { q } là vectơ chuyển vị nút tổng thể. Giả sử mỗi phần tử có r nút, thì số bậc
tự do của mỗi phần tử là: ne = r.S
313
Ta có liên hệ: {q}e = [L]e . { q } (8.50)
(ne.1) (ne.n ) (n.1)
Với [L]e gọi là ma trận định vị.
Sử dụng (8.50) và (8.48) ta có thế năng toàn phần của hệ:
ne ne
1
  
e1
 e   [ { q} T [ L ] Te .[K ] e[ L ] e{ q}  { P} Te .[L ] e{ q} T ]
e1 2
(8.51)

Áp dụng nguyên lý thế năng toàn phần dừng (nguyên lý Lagrange) ta sẽ có điều
kiện cân bằng của toàn hệ tại các điểm nút:

0
q1

0
q 2
  0  . 
hay ở dạng ma trận:  0
. {q }

0
q n
 ne ne

= [ [L ] e .[K ] e[ L ] e ].{ } -  [L ] e . {P}e = {0}


q
T T
Và ta có:
{ q} e1 e1



Viết lại: [ K ]. { q}  { P}  { 0} (8.52)
ne

Trong đó: [K ] =  [L]Te .[ K ]e .[ L]e ] gọi là ma trận cứng tổng thể.


e 1

ne
{ P}   [ L ] Te .{P} e gọi là vectơ tải tổng thể.
e1

 
Ghi chú: Việc sử dụng ma trận định vị [L]e để tính [ K ] và {P} , thực chất là sắp



xếp các phần tử [K ]e , {P}e vào vị trí của nó trong [ K ] và {P} . Tuy nhiên trong thực
hành ta không dùng cách này.

314
Phép chuyển trục tọa độ
Ở trên đây đã xây dựng [N], [Ke], {P}e trong hệ tọa độ thích hợp của mỗi phần tử,
gọi là hệ tọa độ địa phương (và do đó các bậc tự do của phần tử cũng lấy theo hệ tọa độ
này).
Tuy nhiên trong thực tế, thường gặp các kết cấu mà các phần tử khác nhau thì có
các hệ tọa độ địa phương khác nhau và do đó các bậc tự do của phần tử cũng khác nhau
về phương.
Do vậy cần thiết có hệ tọa độ chung cho toàn hệ.
Gọi (x, y, z) là hệ tọa độ địa phương tương ứng {q}e, {P}e, [K]e
(x’, y’, z’) là hệ tọa độ tổng thể tương ứng {q’}e, {P’}e, [K’]e
Ta có quan hệ: {q}e = [T]e{q’}e (8.53)
{P}e = [T]e.{P’}e (8.54)
[T]e là ma trận biến đổi tọa độ từ (x’, y’, z’) về ( x, y, z).
1
Mặt khác: ∏e = {q}Te[K]e {q}e - {P}Te{q’}e. Thế (8.53) vào đây ta được:
2
1
∏e = {q’}Te[T]Te[K]e[T]e {q’}e - {P}Te[T]e {q’}e (8.55)
2
1
Hay ∏e = {q’}Te[K’]e{q’}e - {P’}Te[T]e {q’}e
2
Trong đó: [K’]e = [T]Te[K]e[T]e và {P’}e = [T]e {P}e (8.56)
So sánh (8.54) và (8.56) ta thấy [T]Te [T]e = [E]: Ma trận đơn vị.
Khi Te là ma trận vuông thì TeT = Te-1, Te là ma trận trực giao.
Tương tự khi áp dụng nguyên lý thế năng toàn phần dùng cho toàn hệ ta được :

K q   P  , trong đó: K    K  trong hệ tọa độ ( x , y , z )


    ne
' ' ' ' ' ' ' '
e (8.57)
    e 1

 '
   
ne

P    P  P ' 
'
e (8.58)
  e1  n


Ở đây số hạng thứ 2:  P '  trong (8.58) là vectơ tải trọng tập trung đặt tại các nút
 n
tác dụng theo các phương tương ứng của các thành phần trong véc tơ chuyển vị nút kết
cấu {q’}e, gọi vectơ tải trọng nút.
315
Ghép nối phần tử hay sử dụng ma trận chỉ số để xây dựng
Ma trận độ cứng tổng thể và vectơ tải tổng thể.
Để xác định sự tương ứng của mỗi phần tử thuộc qe trong đó q (hoặc qe

trong q). Người ta lập ma trận chỉ số b (còn gọi là ma trận liên hệ Boolean) mà giá trị
của mỗi thành phần bij chính là chỉ số tổng thể tương ứng bậc tự do thứ j của phần tử thứ
i. Ma trận chỉ số b có số hàng bằng số phần tử của hệ, số cột bằng số bậc tự do của một
phần tử.
Ví dụ.

q1 q3 q5 q7

1 2 3
q2 q4 q6 q8

Chỉ số cục Nút I Nút j


bộ q1 q3
Phần tử 1 2 3 4

i j
1 1 2 3 4
e
q2 q4
2 3 4 5 6
3 5 6 7 8

K1,3(2) gộp thêm => K ( b21, b23 )  K 3,5

K2,4(3) gộp thêm => K ( b32, b34 )  K 6,8

Mỗi thành phần K eij của ma trận phần tử [K]e sẽ phải gộp thêm vào phần tử

K m,n của ma trận tổng thể [ K ] với m = bei, n = bej (nhớ là bei, bej là các giá trị của phần tử

hàng e, cột i và hàng e cột j) của ma trận [b].

316
[b] = e (hàng)

i j
(Cột)
Ví dụ. Tính toán hệ thanh:
+ Phần tử thanh chịu biến dạng dọc trục
Đi biểu diễn chuyển vị dọc thanh: y
U(x) = [N].{q}e
q1
q i  ui  q
Trong đó: {q}e =      1
q j  e u j  e L=a

Chọn hàm chuyển vị có dạng bậc nhất:


x x
[N] = [N1 N2] = [(1 - ) ],
L L
EF
Với biến dạng và ứng suất chỉ có theo q2
2
phương trục ox: L=a

 { }  {  x }

{ }  {  x }

d
Ký hiệu: [  ]  
 dx 
, q3
x

[D] = [E] => x = E.x


Với E - Modun đàn hồi Young của vật liệu.
D - Là ma trận liên hệ giữa ứng suất và biến dạng: [] = [D].{}
 d x x  1 1 1
Ta có: [B] = [  ].[N] =  .(1  )   [ 1 1]
 dx   L L   L L  L
L
1  1 1 EF 1  1
 [ B] .[D].[B].dV    .E. L [ 1 1].F.dx 
T
.
1
[K]e =
Ve 0 L  1  L  1
Trong trường hợp chỉ có lực phân bố dọc trục p(x) = q, vectơ tải được tính:

317
 x   x 
 (1  ) L (1  )
L .p(x ).dx   L .q.dx  q.L 1  q.a 1
L L

{Pe}   [ N] T .{p(x )}. dx    0  x  


o
x  2 1 2 1

0   
 L   L 
Ma trận tổng thể (có được khi cộng hai phần tử thanh):

1  1  1  1 
EF   EF  
[K]  (1  1)  1 2  1
a   a  
=
 sym 1   sym 1 

R 
  
Véc tơ tải trọng nút: P    0  ,
 n  
0

 qa 
 1  R   2  R 
qa      
Vectơ tải tổng thể: P 

1  1   0    qa 
  2     qa 
 1   0  
 2 

Ta có hệ phương trình: K  q   P được tính cụ thể như sau:
  

    

   qa 
 1  1 0   q1  ( 2  R )
EF 
  q    qa 
a 
2 1  2   
sym 
1  q   qa 
 3  2 
   

Điều kiện biên chuyển vị: q1  0

 2
q  3 . qa
 2 2 EF
Giải hệ này ta được: 
 4 qa 2
 3
q 
 2 EF

318
2qa
FEM
3qa/2
Chính xác Chính xác

FEM

3qa2/2EF u
N
2
4qa /2EF

qa/2

Xác định nội lực:  x  du / dx


x  E x  const,
Lực dọc: Nc = F.x = E.F.x

du  1 1  0 2  3qa
N1 = EF.  EF  . 3 qa  
dx 1  a a 
 2 EF 

2

 3qa2 
du  1 1   2EF  qa
 EF . 2
a   4 qa  2
N2 = EF.
dx 2  a
 2 EF 
+ Phần tử thanh trong dàn phẳng

y
vi' =q'2j
i

x
u2 =q2
y'
vi' =ri'
i i

uj' =q'2j-1
j
u1 =q1
e

q'2i-1 = ui'
o x'

319
Trong dàn phẳng xem mỗi mắt dàn là một đỉnh nút, mỗi thanh dàn là một phần tử
chiụ biến dạng dọc trục:
q1 = q’2i-1lij + q’2i-1mij
q2 = q’2j-1lij + q’2j-1mij
Trong đó: lij, mij là cosine chỉ phương của trục phần tử (trục x) đối với hệ trục tổng
thể x’o’y’.

 u1, u2e  q1, q2e


T T
Ta có: {q}e


{q’}e  u i , vi , u j , v j
' ' '
  q
' T '
2i 1 , q ' 2i , q ' 2 j 1 , q ' 2 j 
T

Nên: {q}e =[T]e.{q’}e trong đó ma trận chuyển trục.


l ij m ij 0 0 
[T]e=  
0 0 l ij m ij 

Vậy ma trận độ cứng trong hệ tọa độ tổng thể:


 l ij 0 
m 0 l ij mij 0 0 
[K ]e = [T] e .[K]e.[T] = 
’ T ij
  EF  1  1   
0 l ij  L  1 1  0 0 l ij mij 
 
0 m ij 
Cuối cùng:

l ij2 l ij m ij  l ij2  l ij m ij 
 
 m ij2  l ij m ij  m ij2 
EF
[K’]e =  l ij2 l ij m ij 
L
 
 sym y' m ij2 

Chú ý: y
x
x j  xi
' '

lij = cos(x, x ) =’ y'j e


L j
y'i 
y j  yi
' '

mij = cos(x, y ) = ’ i
L

Với: L = ( x ' j  x ' i ) 2  ( y ' j  y ' i ) 2


o x'i 320x'
x'j
Theo hình vẽ:
lij = cos (  ), mij = sin(  )
cos  sin  0 0 
Nên [T]e = 
0 0 cos  sin  

Nội lực thanh dàn:  x  [ B]{ q} e ,  x  E x , N = x.F = EF.[B].{q}e


' '
Nên Ne= EF [B][T]e {q ' }e = [Se ]{q ' }e với: [Se ] = EF[B][Te];

 1 1  l ij 0  EF
 m ij 
m ij 0
[Se ] = EF.   l ij  m ij
'
. = l ij
 L L  0 0 l ij m ij  L

'
[Se ] =
EF
 cos   sin  cos  sin 
L
+ Khung phẳng

y y
v2 ≡ q3 x

v1 ≡ q1 2 x
2 ≡ q4

1
1≡ q2 L,EJ o z

y
dv/dx

y dv/dx
A
B'
v
A
y
B x
u=-y.dv/dx
321
Ta có vectơ chuyển vị nút phần tử:

q  v1 1 v2 2 e  q1 q2 q3 q4 e


e T T

dv
Với góc xoay: 
dx
Quan hệ giữa chuyển vị dọc trục u và độ võng v là:
dv
U = -y.
dx
Trong đó: y là khoảng cách từ điểm xét tới trục trung hòa.
Khi đó biến dạng dọc trục:
du d2v
x    y. 2 , với v = [N].{q}e
dx dx
Với: [N] là ma trận hàm dạng
[N] = [N1 N2 N3 N4]
x2 x3 x x2
Với: N1(x) = 1-3 2  2 3 , N2(x) = x.(1-2  2 )
L L L L
x2 x3 x x2
N3(x) = 3.  2 , N4(x) = x.(   2)
L2 L3 L L
d2N d2
Viết lại:  x   y. 2 {q}e  [B]{q}e , trong đó [B] = -y 2 [ N]
dx dx
 6 x 4 x 6 12 x 2 6 x 
Hay: [B] = -y (  12 3 )(  6 2 )( 2  3 )(  2 ) 
 L L L 
2
L L L L L

Ứng suất tại mọi điểm của dầm chịu uốn:  x  E. x , biểu diễn dạng ma trận:
{} = [D].{  } , ở đây: [D] = [E]
Ma trận phần tử của dầm chịu uốn: [K]e =  [ B] T [ D][ B]dV  E [ B] T [ B]dF.dX
Ve LF

Tính cụ thể được:


 12 6 L  12 6 L 
 4 L2  6 L 2 L2 
EJ Z 
[K]e = 3
L  12  6 L 
 
 sym 4 L2 

322
Với Jz =  y 2 dF : Momen quán tính của mặt cắt ngang đối với trục z.
F

Vectơ tải {P}e tính theo công thức:


na nM
dN
{P}e =  [ N]T q( x )dx   [ N( x Qi )]T .Q i   [ ( x Mi )]T .M i
L i 1 i 1 dx
Với q(x): Tải trọng phân bố; Qi : Lực tập trung (có hoành độ xQi), Mi : Mômen tập
trung có hoành độ xMi, nQ, nM số lực tập trung và số mômen tập trung.
 3x 2 x3   qL 
1  2
 2 3   2 
L L
 P1   2x 2
x 3   qL2 
P  x  2   
{P}e =  2     12 
    3x 2 2 x 3 qdx   qL 
L L
P3  L   3 
  
   L2
L  2 
P4   x2 x3    qL 
2

    
 L L2   12  
 3a 2 2a3 
1   
 L2 L3 
P   
 1  2a 2 a3 
 a L  2 
{P}e =  2
P

   [ N ( a )] .Q  Q. 
T L 
P
 3  2 3 
   3a  2a 
P
 4  2 3 
 
L L

  a a3 
  
 L L2 

Mômen uốn: y
d2v d2
M = EJ.  EJ [ N]{ q} e
dx 2 dx 2 Lực phân bố P3
P1
q
i j P4 x
M  EJ [ N '' ]{q}e P2
L

Với: y
P1 Q P3

N   dx 2 [ N]
,, d2
o
N ,,   [ N ''1 N ''2 N ''3 N '' 4 ] P2 P4 x
a
L
Có lực tập trung Q
323
đặt ở toạ độ xQ = a
 M (tai nut 1)  M 1 
Gọi {M}e =   là mômen uốn tại đầu nút phần tử {M}e =  
M (tai nut 2) M 2 

 
M e  EJ. N '' ( x  0) .{q}e
''

 N ( x  L) 
M e  [ S ]e {q}e
[ N " (0)]  EJ  6L  4L2 6L  2L2 
Vậy: [S]e=EJ  "  3 
[ N (L )]  L  6L 2L
2
 6L 4L2 

8.6. Phương pháp phần tử hữu hạn trong Cơ học chất lỏng
Khác với chất rắn trong lưu chất các phân tử của nó chuyển động tương đối với
nhau.
Các phương trình cơ bản của cơ học chất lưu được suy diễn từ các định luật bảo
toàn khối lượng, động lượng và năng lượng. Với định luật bảo toàn khối lượng người ta
xây dựng phương trình liên tục, từ định luật bảo toàn động lượng xây dựng phương trình
chuyển động, định luật bảo toàn năng lượng chính là định luật thứ nhất của nhiệt động lực
học.
Người ta dùng khái niệm chất lỏng lý tưởng (ideal liquids) là chất lỏng không có
tính nhớt và không nén được; ngược lại mọi chất lưu thực (real fluids) đều có tính nhớt
hữu hạn và có thể nén được hoặc không nén được. Chất lưu không nhớt (non-viscous
fluids) là chất lưu không có tính nhớt, có thể nén được hoặc không thể nén được. Một chất
lưu nhớt (viscous fluids) được gọi là chất lưu Newton nếu hệ số nhớt của nó không phụ
thuộc vào gradient vận tốc; ngược lại chất lưu phi Newton (non- Newtonian fluids) là chất
lưu có hệ số nhớt của nó phụ thuộc vào gradient vận tốc.
Việc giải các bài toán trong cơ học lưu chất thường phức tạp hơn rất nhiều so với
bài toán trong cơ học vật rắn, bởi lẽ đa số các bài toán trong cơ học lưu chất thường
không thể tìm được phiếm hàm, bậc của các số hạng (terms) trong phương trình thường
có độ lớn khác nhau và phụ thuộc vào tốc độ dòng chảy. Đối với bài toán nhiều chiều,
không dừng, biên của bài toán thay đổi theo thời gian, nên bài toán thường phải biến đổi
hệ phương trình chỉ đạo, và lời giải thường phải ở dạng Galerkin không chuẩn, thậm chí
có trường hợp phải sử dụng các phép tách các phương trình (split) và phải sử dụng những

324
thuật toán có độ chính xác rất cao (CBS, Taylor – Galerkin) để có thể nhận được lời giải
số tốt.
Sau đây, giới thiệu lời giải số một bài toán đơn giản theo phương pháp PTHH
Galerkin cho bài toán một chiều của chất lỏng Newton.
Ví dụ: Xét dòng Poiseuille chảy giữa hai bản phẳng song song cho bởi phương trình:
d 2u 1 dp
y  (8.59)
dy 2  dx

Với u là vận tốc phân bố theo


o phương oy, giả sử ta có:
x
L dp
 a  const
dx
Hình 4.1: Dòng Poiseuille
Tích phân phương trình (8.59) ta nhận được sự phân bố vận tốc v theo trục oy có
dạng:
a 2
u y  by  c (8.60)
2
Với điều kiện biên u = 0 khi y =  L, thế vào (8.60) ta được:
aL2
b0 , c
2

aL2 y2
Vậy: u (1  2 )
2 L

aL2
Tại trục y = 0 thì: u 
2

Bây giờ ta đi tìm u bằng cách đi giải bài toán theo phương pháp PTHH Galerkin,
áp dụng vào phương trình (8.59):
L
 d 2u 1 dp 
 i . 
0  dy
2
 dy  0
 dx 
(8.61)
L
 d 2u a 
hay 0  i .  dy 2   dy  0
Với u xấp xỉ trong từng miền con là đoạn thẳng , ᴪj là hàm trọng số. Với bài toán
này, để đơn giản ta chia làm hai phần tử một chiều có chiều dài L theo phương oy:
325
3
uu  y    j e  y  u j e
j 1

Với  ( y) thường chọn là hàm nội suy Lagrange, ở đây ta chọn bậc của nó là hai:
e
j

 
 _

 _   y  2 y 
  y   1
e
1
   h  h 
1

  
_
 _

  _
y y
 2e  y   4 1  
  h h
 
_
 _

 _
 y  2 y 
 3  y    1
e

  h  h 
 

_
1
Với y  h và áp dụng tích phân từng phần ta có được phương trình dạng ma trận:
2

 K  U e    f e   Q
e e
(8.62)

d e d
e
 dp 
L L
Với : K    i . j dy
e
ij ; fi e      ie dy
0
0
dy dy dx 

 du   du 
Với : Q1e    .  ; Q3e   . 
dy  0  dy  h

Với h = 2L, ta có :
 7  8 1 u1  1  Q1 
1

   u   q0 L 4   0 
8 16  8  2    
6L    3    1
 1  8 7  u3  1  Q3 

Cho: u1 = u3 = 0 (điều kiện biên), ta có:


q0 L2
u2 
2

Ta thấy lời giải phù hợp với nghiệm chính xác của bài toán là:
q0 L2  y 2 
u( y)  1  
2  L2 

326
Câu hỏi:
1) Trong trường hợp nào hàm dạng đồng nhất với hàm nội suy?
2) Nêu đặc tính của hàm dạng?
3) Trong phương pháp PTHH bước quan trọng nhất là thiết lập phương trình phần tử
(hay còn gọi tính ma trận phần tử), vì sao?
4) Tại sao trong thực hành lập trình tính toán, người ta không sử dụng ma trận định vị để
thiết lập ma trận tổng thể?

Bài tập
1) Hãy trình bày phương pháp Phần tử hữu hạn Galerkin tổng quát và áp dụng cho bài
toán một chiều (one dimension 1D) nào đó, do em tự chọn, có số phần tử ne = 3 ÷ 7,
tự cho các phương trình ma trận phần tử (element matrix equations) [K]e.{X}={c}e .
Hãy thiết lập hệ phương trình ma trận cho toàn hệ:  [K]e.{X} =  {c}e
d 2T
2) Giải phương trình   f ( x) với chiều dài thanh l = 10cm với điều kiện biên
dx 2
T(0, t) = 50, T(10, t) = 100 và hàm phân bố nhiệt độ f(x) = 20, theo phương pháp
phần tử hữu hạn Galerkin.

327
PHẦN PHỤ LỤC

A. PHÉP TÍNH VÉC-TƠ


Cho vecto a ( x1 , y1 , z1 )

b ( x2 , y 2 , z 2 )
  
c  a b


  b
c b




aa
a

 Tích vô hướng : a.b  ab cos 

a.b  x1x2  y1 y2  z1z2

Tích vector : c  a  b  ab sin 


   
Có tính chất : b a   a  b
i j k
a  b  x1 y1 z1
x2 y2 z2

Ví dụ 1. Cho a   4, 0, 1 , b   2,1,3 . Tính a  b

i j k
a  b  4 0 1  i  10 j  4k  1, 10, 4
2 1 3

 Độ lớn của vector: a  x12  y12  z12 , b  x22  y22  z22

 Các tính chất của vector


ab  ba

328
u  v   w  u  v  w 
a0  0a

 
a  a  0

ca  cx1 , cy1 , cz1 

 
c a  b  ca  cb

 c  k  a  ca  ka
 
c ka   ck  a

1a  a

0a  0

1a  a

i . i = 1, j . j = 1, k . k = 1

i . j = 0, j . k = 1, i . k = 1

 Tích hỗn tạp:


x1 y1 z1
abc = (a  b) . c = a.(b  c) = bca = cab = x 2 y2 z2
x3 y3 z3

abc = - bac = - cba = - acb

1 1
V1 = abc, V2 = V1 = abc
6 6

V1 là thể tích hình hộp dựng trên các vector a, b, c

V2 là thể tích hình chóp dựng trên các vector a , b, c này.


Toán tử Haminton
U U U
gradU  i j k
x y z
Ax Ay Az
divA   
x y z
 Az Ay   Ax Az   Ay Ax 
rotA     i     j    k
 y z   z x   x y 
Công thức Ostrogradsky - Gauss:
329
 Ad   divAd 
 
z
(L)

r
x

Với : Mặt và : Thể tích


Công thức Stokes:

 Adr   rotAdsvới r  xi  y j  zk
(L ) ( S)

Phép toán với toán tử 


  
i  j k
x y z
U U U
U  i j k  gradU
x y z
     Ax Ay Az
  A   i  j  k   iAx  jAy  kAz     divA
 x y z  x y z

i j k
  
CurlA =  X A =
X Y z
AX AY AZ
AZ AY A A A A
CurlA = i( - ) + j( X - Z ) + k( Y - X ) = rotA
y z z x x y

      
A    (iA X  jA Y  kA Z )   i  j  k   A X  AY  AZ
 x y z  x y z

d  d (.) (.)
 u   hay  u  (.) 
dt t dt t

330
2 2 2  u  u  u 2 2 2

        2  2  2 , divgrad u =  u  u = 2  
2 2

x y z x y 2 z2
Ví dụ 2. Cho U = 2x + yz – 3y2. Tính U
U = 2i + (z - 6y)j + yk
Ví dụ 3. Cho A = 3xzi + 2xyj – yz2k. Tính   A
  A = 3z + 2x – 2yz
Ví dụ 4. Cho A = yzi + 3zxj + zk.
CurlA =  X A = -3xi + yj + 2zk
Ví dụ 5. Chiếu phương trình Navier- Stocks lên hệ trục tọa độ tự nhiên:

dv  1 
 F  gradp  v
dt 
 
Trong đó: F  g

v : Trường vận tốc dòng chảy.

 : Khối lượng riêng.

p: Áp suất (vô hướng).

 : Hệ số nhớt chất lỏng.

v
Hướng d n: VT=  v.v
t

à v  iv x  jv y  kv z

v v v
v  i  j k
x y z

1 p p p  2v  2v  2v
VP= iFx  jFy  k Fz  (i j  k )  ( 2  2  2 )
 x y z x y z

C n ng hai vế r i chiếu lên o , oy, oz

B. PHÉP TÍNH TEN-XƠ (Tensor analysis)


Hạng của Tensor là số chỉ số của Tensor đó.
Ví dụ : ai có một chỉ số, nên là tensor hạng nhất

331
aij có hai chỉ số, nên là Tensor hạng hai
Qui tắc chỉ số
Khi có hai chỉ số giống nhau, iểu thị một tổng:
3
aibi = a1b1+ a2b2+ a3b3 =  ai bi
i 1

Hệ thống đối ứng khi aij = aji, phản đối ứng khi aij = -aji
Ví dụ 6.

1 khi i= j
 ij  
0 khi i j
là một Tensor hạng hai đối ứng.
 Tổng các Tensor cùng hạng là một Tensor cùng hạng:
Cijk = aijk  bijk (hạng a)
 Nh n Tensor: Cijklm= aijk.blm
(mọi tích có thể có của từng thành phần Tensor)
Vô hướng được em như Tensor hạng zero.
 Phép cuộn Tensor:
Được thực hiện khi có hai chỉ số ất kỳ trùng nhau:
3
aijkk =  aijkk = aij11+ aij22+ aij33 = Cij
k 1

Phép nh n trong: Cijm = aijkbkm


Là phép nh n và cuộn đ ng thời các Tensor , cho ta tìm được vết của Tensor.
Phép nh n trong cho ta điểm uất phát quan trọng để nhận được các ất iến
của các đối tượng hình học và vật lý.
Ví dụ 7. Vết của Tensor aij = xiyj
Khi cho i = j => aii = xiyi = x1y1 + x2y2 + x3y3 = vô hướng
C. CÁC PHƯƠNG PHÁP BIẾN ĐỔI
1. Phép biến đổi tọa độ
y
y y'
M
*M y
x1
y1 x1
b
O1 x’
y1 α
o a x
332
o x x
+ Phép tịnh tiến:

x  x 'a , y  y' b

x '  x  a , y'  y  b
+ Phép quay:

x  x ' cos  y' sin , y  x ' sin  y' cos



x '  x cos  y sin , y'  x sin  y cos

2. Phép biến hình bảo giác

B B’
W = f(z)

A C A’ C’
y v

o O’ u
x

γ l l’
y g h γ’ g’
v
h’

x0, yo u0, vo
Ϭ

ϕ’
λ ϕ '
λ
'
o
o x u

Cho W = f(z) giải tích trong miền D, số phức z = + yi và W = u + vi


Phép iến đổi điểm: A(x, y)  A’(u, v),
333
AB BC CA
Các cạnh tỉ lệ với nhau: ' '
 ' '  ' ' và các góc tương ứng ng
A B BC CA
nhau: góc  = ’ ( ảo giác)
3. Phép biến đổi Laplace
U(x i , t )
Xét phương trình vi ph n : U(x i , t )  , với t > 0
t
Nh n 2 vế của phương trình trên với e-pt (với p > 0), lấy tích ph n theo t từ
 
U(x i , t ) Pt
0   , ta được :   U(x i , t )e dt  
 Pt
e dt
0 0 t

Đặt U(x i , P)   U(x i , P)e dt , hàm U(x i , P) được gọi là phép iến đổi
 Pt

Laplace của hàm U( i, t) đối với t .

Biểu thức trên được viết lại theo U(x i , P) :

. U  PU  U(x i , P) ,

Giải dễ dàng hơn và tìm được U , có U dùng ảng tra tìm U.

U(x i , t ) Pt
 

Chú ý:  e dt  U(x i , P).e   P U(x i , t )ePtdt


 Pt

0 t 0

4. Phép biến đổi Sigma 


x z=   =1 tại mặt thoáng
y z = - h(x,y)   = - 1 tại đáy
2(z   )
=  1 =>   [ 1,1]
h(x, y )  
t’=t

z

mặt nước
mặt nước 1
(x,y,t)
O
0 , 
h(x,y) đáy
đáy x,y -1
Tọa độ 
Tọa độ z
334
D. MỘT VÀI ỨNG DỤNG CỦA GIẢI TÍCH HÀM
1. Không gian mêtrix
Định nghĩa: ột tập hợp X được gọi là một không gian etri , nếu ứng với
mỗi cặp phần tử , y X có một số thực  (x, y)  0, gọi là khoảng cách giữa & y,
thỏa điều kiện sau:
(x, y) = 0 khi và chỉ khi x = y, (x, y) = (y, x)
(x, y)  (x, z) + (z, y), x, y, z  X ( ất đẳng thức tam giác).
2. Không gian tuyến tính định chuẩn
Tập hợp X được gọi là không gian tuyến tính nếu trên tập hợp đó ác định hai
phép tính: Cộng các phần tử và nh n phần tử với một số đ ng thời thỏa các tiên đề:
x+y =y+x , (x + y) + z = x + (y + z ),
(x + y) = x + y , ( + )x = x + x ,  (x) = ()x
T n tại phần tử   X, gọi là phần tử không, sao cho 0. = , x  X
Không gian tuyến tính được gọi là định chuẩn, nếu ứng với mỗi  X ta ác

định được một số thực gọi là chuẩn của và ký hiệu x đ ng thời số thực đó thỏa

điều kiện sau:

x  0 , x = 0, khi và chỉ khi =

x   . x , R, xX

x  y < x + y ,  x,y  X ( ất đẳng thức tam giác).


3. Không gian EUCLIC- Không gian HILBERT
Cho một không gian tuyến tính X (trên trường số thực hoặc phức). Giả sử ứng
với mỗi cặp phần tử , y  X, ác định được một số thực hoặc phức ( , y) thỏa các
điều kiện sau :

(x, y) = (y, x) , trong trường số phức thì ( , y) = ( y, x )


(x + y,z) = (x, z) + (y, z),  x, y, z  X
(x, y) = (x, y)
(x, x)  0, trong đó ( , ) = 0 khi và chỉ khi = 
Số ( , y) như vậy được gọi là tích vô hướng của hai phần tử , y.

335
Không gian tuyến tính mà trong đó có ác định tích vô hướng được gọi là
không gian Euclic.
Không gian Euclic đủ, vô hạn chiều được gọi là không gian Hil ert.
4. Toán Tử Tuyến Tính - Phiếm Hàm Tuyến Tính
Giả sử X, Y là hai không gian Topo tuyến tính
Toán tử (hay ánh ạ):
A: X  Y (y = Ax , x  X , y  Y) được gọi là tuyến tính nếu ta có:
A(x1 + x2 ) = Ax1 + Ax2
Tập hợp tất cả các gía trị  X mà tại đó A ác định, được gọi là miền ác
định của toán tử A và ký hiệu D(A). iền giá trị của A được ký hiệu R(A)  Y.
Trong trường hợp Y = R1 (trường số thực), thì toán tử tuyến tính A được gọi là
phiếm hàm tuyến tính.

Câu hỏi:
1) Nêu ý nghĩa vật lý và trình ày công thức tính của các toán tử Haminton
(GradU, DivA, RotA)? Sự ích lợi của nó ?
2) Hãy nêu những ưu nhược điểm của phép tính toán tử so với phép tính tensor ?
3) Hãy nêu vài ứng dụng của công thức Stockes và công thức O trograski–Gauss?
4) Hãy nêu vài ứng dụng của các phép iến đổi (Laplace, iến hình ảo giác,
Sigma) ?

Bài tập :
1) Chứng minh: divgradu  2u
rot(u.a)  gradu  a  urota với: a là vectơ, u = u( , y, z)

2) .    2   divgrad

3) Chứng minh đẳng thức sau:


rot(.a)  grad  a  .rota
Trong đó : a là véctơ và  là hàm
1 u u
4) Từ phương trình vectơ: F  gradp   grad ( )  rotU
 t 2

Hãy viết nó ở dạng chiếu lên các trục tọa độ o , oy, oz.

336
5) Viết các thành phần hình chiếu lên các trục o , oy, oz của các phương trình sau:
ui
 div (kT )   ij
de
.
dt x j
Với:
 u u 
 ij   p ij    i  j    ij divV
 x 
 j xi 

337
TÀI LIỆU THAM KHẢO

1. Phạm Kỳ Anh, Giải tích số, Nhà xuất bản Đại học Quốc Gia, Hà Nội 1996
2. Đào Huy Bích - Nguyễn Đăng Bích, Cơ học môi trường liên tục, Nhà xuất bản
Xây Dựng, Hà Nội 2002
3. Phan Đăng Cầu & Phan Thị Hà, Giáo trình phương pháp số, Nhà xuất bản
Bưu Điện 2007
4. Tạ Văn Đĩnh, Phương pháp tính, Nhà xuất bản giáo dục, 1997

5. Phạm Hồng Giang, Phương pháp phần tử biên, NXB Khoa học và kỹ thuật,
Hà Nội 2002.
6. Phan Văn Hạp và các tác giả khác, Cơ sở phương pháp tính, Nhà xuất bản Đại
học - Trung học chuyên nghiệp, Hà Nội 1970
7. Nguyễn Thế Hùng, Giáo trình Phương pháp số, Đại học Đà Nẵng 1996
8. Nguyễn Thế Hùng, Phương pháp phần tử hữu hạn trong chất lỏng, Nhà xuất
bản Xây Dựng, Hà Nội 2004
9. Đặng Quốc Lương, Phương pháp tính trong kỹ thuật, Nhà xuất bản Xây Dựng,
Hà Nội 2001
10. Đinh Văn Phong, Phương pháp số trong cơ học, Nhà xuất bản Khoa học và Kỹ
thuật, Hà Nội 1999
11. Lê Đình Thịnh, Phương pháp tính, Nhà xuất bản Khoa học và Kỹ thuật, Hà
Nội 1995
12. Lê Trọng Vinh, Giải tích số, Nhà xuất bản Khoa học và Kỹ thuật, Hà Nội 2000

13. Abbott M. B. and Basco D. R., Computation fluid dynamics an introduction


for engineers, John Wiley & Sons, Inc, New York 1989.
14. Aslak Tveito, Ragnar Winther, Introduction to Partial Differential Equations:
A Computational A pproach, Springer Verlag 1993

15. Brebbia, C. A. et al., Boundary Element Techniques. Theory and applications


in Engineering, Springer Verlag, Berlin, Heidelberg, Newyork, Tokyo 1984.

16. Brebbia C. A. and Ferrante A. J., Computational hydraulics, Butterworths &


co (Publishers) Ltd 1983.
17. Burden, RL, - Faires, JD, Numerical Analysis, 5th ed, PWS Publishing, Boston
1993
18. Chapra S.C, Numerical Methods for Engineers, McGraw Hill, 1998
19. Douglas Faires - Richard L. Burden, Numerical methods, Brooks Cole 2002
20. Gurmund & all, Numerical Methods, Dover Publications, 2003
21. Hoffman, J, Numerical Methods for Engineers scientists, McGrawHill,
Newyork 1992
22. Jaan Kiusaalas, Numerical Methods in Engineering with Matlab, Cambridge
University Press, 2005
23. Owen T. et al., Computational methods in chemical engineering, Prentice Hall,
1995
24. Roland W. Lewis et al., Fundamentals of the Finite Element Method for Heat
and Fluid Flow, John Wiley and Son Ltd 2004
25. Steven T. Karris, Numerical Analysis, Using Matlab and Excel, Orchard
Publications, 2007
26. J. Stoer, R. Bulirsch, Introduction to Numerical Analysis, Springer Verlag
1993

Website tham khảo


http://ocw.mit.edu/index.html
http://gigapedia.org
http://ebookee.com.cn
http://db.vista.gov.vn
http://dspace.mit.edu
http://www.info.sciencedirect.com/books
http://ecourses.ou.edu
http://www.dbebooks.com

You might also like