Giáo trình Turbo C nâng cao và C++ - Chương 9: Các vấn đề về ma trận

//phuong phap Bairstow #include #include #include #include #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--) {145 printf("a[%d] = ",n-i); scanf("%f",&a[i]); } 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

pdf35 trang | Chia sẻ: hachi492 | Ngày: 07/01/2022 | Lượt xem: 342 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Giáo trình Turbo C nâng cao và C++ - Chương 9: Các vấn đề về ma trận, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
116 Ch−ơng 9 : Các vấn đề về ma trận Đ1.Định thức của ma trận Cho một ma trận vuông cấp n.Ta cần tìm định thức của nó.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 - đị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ụ: ⎟⎟ ⎟⎟ ⎠ ⎞ ⎜⎜ ⎜⎜ ⎝ ⎛ = 44434241 34333231 24232221 14131211 aaaa aaaa aaaa aaaa A 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à: ⎟⎟ ⎟⎟ ⎠ ⎞ ⎜⎜ ⎜⎜ ⎝ ⎛ ′′′ 44434241 34333231 24232221 141312 aaaa aaaa aaaa aaa1 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à: ⎟⎟ ⎟⎟ ⎠ ⎞ ⎜⎜ ⎜⎜ ⎝ ⎛ ′′′ ′′′ ′′′ ′′′ 444342 343332 242322 141312 aaa0 aaa0 aaa0 aaa1 Lấy giá trị trụ là 222 ap ′= .Ta chia các phần tử của hàng thứ hai cho p2 thì định thức sẽ là D/(p1p2) và ma trận còn lại là: ⎟⎟ ⎟⎟ ⎠ ⎞ ⎜⎜ ⎜⎜ ⎝ ⎛ ′′′ ′′′ ′′′′ ′′′ 444342 343332 2423 141312 aaa0 aaa0 aa10 aaa1 Lấy hàng 1 trừ đi hàng 2 đã nhân với 12a′ ,lấy hàng 3 trừ đi hàng 2 đã nhân với 32a′ và lấy hàng 4 trừ đi hàng 2 đã nhân với 42a′ thì định thức vẫn là D/p1 và ma trận là: thì định thức vẫn là D/(p1p2) và ma trận là: 117 ⎟⎟ ⎟⎟ ⎠ ⎞ ⎜⎜ ⎜⎜ ⎝ ⎛ ′′′′ ′′′′ ′′′′ ′′′′ 4443 3433 2423 1413 aa00 aa00 aa10 aa01 Tiếp tục lấy hàng 3 rồi hàng 4 làm trụ thì ma trận sẽ là: ⎟⎟ ⎟ ⎠ ⎞ ⎜⎜ ⎜ ⎝ ⎛ 1000 0100 0010 0001 Định thức của ma trận này là D/(p1p2p3p4)= D/( 44332211 aaaa ′′′′′′ ) =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 9-1 //tinh dinh thuc #include #include #include #include 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++) { 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++) 118 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') 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; 119 ok1=0; } 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); } getch(); } Đ2.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à: ⎟⎟ ⎟ ⎠ ⎞ ⎜⎜ ⎜ ⎝ ⎛ = 1000 0100 0010 0001 E 120 Ph−ơng pháp loại trừ để 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 ⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛= 211 121 112 A Ta viết lại ma trận A và ma trận đơn vị t−ơng ứng với nó ⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛=⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛= 100 010 001 E 211 121 112 A 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 ⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ =⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ = 100 010 0021 E 211 121 21211 A 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. ⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ − −=⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ = 1021 0121 0021 E 23210 21230 21211 A 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 ⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ − −=⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ = 1021 03231 0021 E 23210 3110 21211 A 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 ⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ −− − − =⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ = 13131 03231 03132 E 3400 3110 3101 A 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 ⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ −− − − =⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ = 434141 03231 03132 E 100 3110 3101 A 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 ⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ −− −− −− =⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛= 434141 414341 414143 E 100 010 001 A Nh− vậy A-1 là: 121 ⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ −− −− −− =− 434141 414341 414143 A 1 áp dụng ph−ơng pháp này chúng ta có ch−ơng trình sau: Ch−ơng trình 9-2 #include #include #include #include #include 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; 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"); 122 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; 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++) 123 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(); } Dùng ch−ơng trình tính nghịch đảo của ma trận: ⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ 678 789 899 cho ta kết quả ⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ −− − −− 991 9102 121 Đ3.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 trong đó mỗi phần tử của Cmp là: ∑ = = n 1k kjikij bac Ch−ơng trình d−ới đây thực hiện nhân hai ma trận với nhau. Ch−ơng trình 9-3 #include #include #include #include #include #define max 50 void main() 124 { 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"); } 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++) 125 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); 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++) { 126 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(); } Dùng ch−ơng trình tính tính hai ma trận ta nhận đ−ợc kết quả ⎟⎟ ⎟ ⎠ ⎞ ⎜⎜ ⎜ ⎝ ⎛ −− − − −=⎟⎠ ⎞⎜⎝ ⎛ − −ì⎟⎟ ⎟ ⎠ ⎞ ⎜⎜ ⎜ ⎝ ⎛− 1214 221 11148 105 343 221 35 01 31 12 Đ4.Giá trị riêng và vec tơ riêng của ma trận 1.Khái niệm chung: Trong nghiên lí thuyết và ứng dụng,ta gặp bài toán về ma trận cấp n.Cho một ma trận A cấp n,giá trị λ đ−ợc gọi là giá trị riêng và vectơ X đ−ợc gọi là vectơ riêng của ma trận A nếu: AX = λX (1) Vectơ riêng phải là vectơ khác không.T−ơng ứng với một giá trị riêng có vô số vectơ riêng.Nếu X là một véc tơ riêng t−ơng ứng với giá trị riêng λ thì cX cũng là vec t− riênh ứng với λ.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 (1) ta có: (A-λE)X = 0 (2) và (A - λE) là ma trận có dạng: ⎟⎟ ⎟⎟ ⎟ ⎠ ⎞ ⎜⎜ ⎜⎜ ⎜ ⎝ ⎛ − − − λ λλ aaa ....... aaa aaa nn2n1n n22221 n11211 .... .... .... (3) Nh− vậy do (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 (4) Ph−ơng trình (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 PA(λ) của ma trận trên đ−ợ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: ⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ − − − 022 113 313 Tr−ớc hết ta tính đa thức đặc tr−ng của ma trận A: 127 )4()4( 22 113 313 )(P 2 A + ⎟⎟ ⎟⎟ ⎠ ⎞ ⎜⎜ ⎜⎜ ⎝ ⎛ λλ−=λ−− −λ− −λ−=λ 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ệ 0 22 113 313 3 2 1 = ⎟⎟ ⎟⎟ ⎠ ⎞ ⎜⎜ ⎜⎜ ⎝ ⎛ ⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ ξ ξ ξ ì λ−− −λ− −λ− 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 tính này ta dùng ph−ơng pháp Fadeev-Leverrier.Ta xét ma trận A: ⎟⎟ ⎟⎟ ⎠ ⎞ ⎜⎜ ⎜⎜ ⎝ ⎛ ⋅⋅⋅ ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ ⋅⋅⋅ ⋅⋅⋅ = nn2n1n n22221 n11211 aaa aaa aaa A 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 cá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: Ch−ơng trình 9-4 // Faddeev_Leverrier; #include #include #include #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"); 128 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++) { 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"); } 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; 129 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"); printf("\n"); d=1.0; printf("%6.2f",d); for (i=1;i<=n;i++) { c1=-p[i]; printf("%5c%6.2f",' ',c1); } getch(); } 2.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à 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 1i iinn2211 XvXvXvXvV (5) Trong đó X1,X2,..,Xn là các vec 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. Vậy nên: AV = v1λ1X1 + v2λ2X2 +...+ vnλnXn 130 XvXAvAV ii n 1i iii n 1i i λ∑∑ == == Lại nhân biểu thức trên với A ta có: A2V = v1λ1 AX1 + v2λ2 AX2 +...+ vnλn AXn = v1λ21X1 + v2λ22 X2 +...+ vnλn2 Xn và tiếp đến lần thứ p ta có: XvXvXvXvVA n p nn2 p 211 p 11i p i n 1i i p λλλλ∑ +⋅⋅++== = Lấy λp1 làm thừa số chung ta có: ⎥⎥⎦ ⎤ ⎢⎢⎣ ⎡ ⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ λ λ+⋅⋅⋅+⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ λ λ+⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ λ λ+λ= n p 1 n n3 p 1 3 32 p 1 2 211 p 1 p XvXvXvXvVA T−ơng tự ta có: ⎥⎥⎦ ⎤ ⎢⎢⎣ ⎡ ⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ λ λ+⋅⋅⋅+⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ λ λ+⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ λ λ+λ= +++ ++ n 1p 1 n n3 1p 1 3 32 1p 1 2 211 1p 1 1p XvXvXvXvVA Khi p rất lớn,vì λ1 > λ2 > λ3 >,...,λn nên: ∞→→⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ λ λ pkhi0 1 i Do đó: 11 p 1 p p XvVAlim λ=∞→ (6) 11 1p 1 1p p XvVAlim ++∞→ λ= nghĩa là khi p đủ lớn thì: 11 p 1 p XvVA λ= 11 1p 1 1p XvVA ++ λ= do đó: VAVA p1 1p λ=+ hay: ( ) VAVAA p1p λ= Nh− vậy VA p là véc tơ riêng của A ứng với λ1 còn giá trị riêng λ1 sẽ là: 1p 1p p VA VA lim λ= + ∞→ 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 p1p VAV ′=+ với vp+1,j là phần tử thứ j của Vp+1.Ta có: ⎪⎩ ⎪⎨ ⎧ λ= =′ +∞→ ∞→ 1j,1p p 1p p vlim XVlim 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: 131 ⎟⎟ ⎟ ⎠ ⎞ ⎜⎜ ⎜ ⎝ ⎛ −−−− = 26544323 68102 720138 17302417 A Chọn V= {1,1,1,1}T ta tính đ−ợc V V1 = AV V’1 V2 = AV’1 V’2 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 = AV’2 V’3 V4 = AV’3 V’4 V5 = 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 Dùng thuật toán trên ta có ch−ơng trình sau: Ch−ơng trình 9-5 #include #include #include #include #include #define max 50void 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++) 132 { 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++) { 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"); for (i=1;i<=n;i++) x0[i]=1; k=1; t=0; t1=0; do { t0=t1; for (i=1;i<=n;i++) 133 { 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]); 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(); } Dùng ch−ơng trình này tính gía trị riêng và vec tơ riêng của ma trận: ⎟⎟⎠ ⎞ ⎜⎜⎝ ⎛ −− − 308 649 012 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à vec tơ 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 >...> λn.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: 134 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: WX XW AA T 11 1 T 1 1 1 λ−= (7) Ta chú ý là X1W1 T là một ma trận còn W1 TX1 là một con số.Khi nhân hai vế của biểu thức (7) với X1 và chý ý đến tính kết hợp của tích các ma trận ta có: 0 XAX XW XWXAX XWX XW AXXA 111 1 T 1 1 T 1 111 1 T 11 1 T 1 1 111 = −= −= −= λ λ λ (8) 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ó: XW XWXAX XWX XW AXXA 1 T 1 2 T 1 112 2 T 11 1 T 1 1 221 λ λ −= −= (9) Theo định nghĩa vì W1 là vectơ riêng của A T nên: λ1W1 =ATW1 (10) Mặt khác do: (AX)T =XTAT và (AT)T = A Nên khi chuyển vị (10) ta nhận đ−ợc: (ATW1) T = λ1WT1 Hay: W1 TA = λ1W1T (11) Khi nhân (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) W1TX2 = 0 khi λ1 ≠ λ2 thì: W1 TX2 = 0 (12) Cuối cùng thay (12) vào (9) ta có: 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 (7). - tìm giá trị riêng và vec tơ riêng của A1 bằng cách lặp công suất 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: 135 ⎟⎟ ⎟ ⎠ ⎞ ⎜⎜ ⎜ ⎝ ⎛ −−−− = 26544323 68102 720138 17302417 A 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: ⎟⎟ ⎟ ⎠ ⎞ ⎜⎜ ⎜ ⎝ ⎛ −− −−= 266717 5482030 43101324 232817 A T 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 (7): ⎟⎟ ⎟ ⎠ ⎞ ⎜⎜ ⎜ ⎝ ⎛ −−−− =λ 86814921390586 0000 434746695293 434746695293 120 7 XW WX 1 T 1 T 11 1 và: ⎟⎟ ⎟ ⎠ ⎞ ⎜⎜ ⎜ ⎝ ⎛ −−−− −−−−= 6333.240333.330833.381833.11 68102 3167.185167.235417.270917.9 3167.85167.135417.160917.0 A1 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: Ch−ơng trình 9-6 #include #include #include #include #include #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++) 136 { 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++) { 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++) { 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++) 137 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]; 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(); 138 exit(1); } if (fabs(va-v1)>3*epsi) { printf("Co loi\n"); 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]; } } 139 Do (6) đú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 (1) , gần đúng nh- một cấp số nhân có công sai q . Nh- vậy : 1q yx yx n 1n <=− −+ (7) hay : )yx(qyx n1n −=−+ (8) T-ơng tự ta có : )yx(qyx 1n2n −=− ++ (9) Từ (8) và (9) ta có : n1n 1n2n xx xx q − −= + ++ (10) Thay giá trị của q vừa tính ở (10) vào biểu thức của q ở trên ta có : ( ) 1n1nn 2 1nn n xx2x xx xy ++ + +− −−= (11) Công thức (11) đ-ợc gọi là công thức ngoại suy Adam.Nh- vậy theo (11) 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 (11) 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 : 3)xln(x += 3xlnx2 1 )x(f +=′ 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 trình 8-9 //phuong phap Aitken #include #include #include #define m 5 void main() { 140 float x[m]; float epsi,n,y; int i,z; float f(float); clrscr(); printf("Cho tri so ban dau x[1] = "); 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); } Với giá trị ban đầu là 1 và sai số là 1e-8,ch-ơng trình cho kết quả y = 1.9096975944 Đ10.Ph−ơng pháp Bairstow 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 141 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 (1) b1 = a1 + sbo b2 = a2 + sb1 - pbo .................. bk = ak + sbk-1 - pbk-2 α = an-1 + sbn-2 - pbn-3 β = an - pbn-2 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 + β = bn-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: ⎩⎨ ⎧ ==0)p,s(g 0)p,s(f 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: 142 J(Xi)(Xi+1 - Xi) = -F(Xi) với Xi = { si,pi}T và Xi+1 = { si+1,pi+1}T )p,s(g )p,s(f )X(F ii ii i = iJ X f s f p g s g 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 : ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ f s s f p p f s p g s s g p p g s p i i i i ∆ ∆ ∆ ∆ + = + = ⎧ ⎨ ⎪⎪⎪ ⎩ ⎪⎪⎪ − − ( ) ( ) , , Theo công thức Cramer ta có : ∆s f g p g f p= − +∂∂ ∂ ∂ δ ∆p g f s f g s= − +∂∂ ∂ ∂ δ δ ∂∂ ∂ ∂ ∂ ∂ ∂ ∂= − f s g p f p g s Để dùng đ-ợc công thức này ta cần tính đ-ợc các đạo hàm ∂∂ f s , ∂∂ f p , ∂∂ g s , ∂∂ g p .Các đạo hàm này đ-ợc tính theo công thức truy hồi. Do bo = ao nên ob s ∂ ∂ =0 ob p ∂ ∂ =0 b1 = a1 + sbo nên 1∂∂ b s bo = 1 0∂∂ b p = b2 = a2 + sb1- pbo nên 2 2 1∂∂ ∂ ∂ ∂ ∂ ∂ ∂ b s a s sb s pb s o= + − ( ) ( ) Mặt khác : 2 0∂∂ a s = 1 1 1 ∂ ∂ ∂ ∂ ( )sb s s b s b= + opb s ∂ ∂ ( ) =0 nên : 2 1 ∂ ∂ b s b sbo = + b3 = a3 + sb2- pb1 nên 3 2 2 1∂∂ ∂ ∂ ∂ ∂ b s b s b s p b s = + − Nếu chúng ta đặt : k k b s c ∂ ∂ = −1 143 thì : co = bo (2) 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: 2n1n3n2n cs f c s f c s f c s f −−−− =∂ ∂=∂ ∂=∂ ∂=∂ ∂ 2 2n3n1n 3nn2n1n ccc cbcb s −−− −−− − −=∆ (3) 2 2n3n1n 2nn1n1n ccc cbcb p −−− −−− − −=∆ (4) 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 (1) - Tính các giá trị co,...,cn theo (2) - Tính ∆so và ∆po theo (3) và (4) - 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 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 11.0 5.52.3 1.35.5 5.57.0 1.38.0 s = − − − − =∆ 06.0 5.52.3 1.35.5 7.02.3 8.05.5 p = − − −=∆ 144 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 01.0 51.403.1 88.251.4 5.57.0 88.207.0 s −= − − − − =∆ 04.0 51.403.1 88.251.4 17.003.1 07.051.4 p = − − −−=∆ 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 8-10 //phuong phap Bairstow #include #include #include #include #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--) { 145 printf("a[%d] = ",n-i); scanf("%f",&a[i]); } 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; 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"); 146 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)); 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(); } 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 Đ11.Hệ ph−ơng trình phi tuyến Ph-ơng pháp Newton có thể đ-ợc tổng quát hoá để giải hệ ph-ơng trình phi tuyến dạng : 147 ⎪⎪ ⎪ ⎩ ⎪⎪ ⎪ ⎨ ⎧ = = = = 0)x,...,x,x,x(f ............................... 0)x,...,x,x,x(f 0)x,...,x,x,x(f 0)x,...,x,x,x(f 2321n 23213 23212 23211 hay viết gọn hơn d-ới dạng : F(X) = 0 Trong đó : X = (x1,x2,x3,.....,xn) Với một ph-ơng trình một biến,công thức Newton là : i i i i x x f x f x+ = −1 ( ) '( ) hay : f'(xi).∆x = -f(xi) với ∆x = xi+1 - xi Đối với hệ,công thức lặp là : J(Xi)∆x = -F(Xi) Trong đó J(Xi) là toán tử Jacobi.Nó là một ma trận bậc n ( n - t-ơng ứng với số thành phần trong vectơ X) có dạng : i n n n n n n n J x f x f x f x f x f x f x f x f x f x f x f x f x ( ) . . .............. .............. .............. = 1 1 1 2 1 3 1 2 1 2 2 2 3 2 1 2 3 ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ ∂ và ∆X = Xi+1 - Xi Ph-ơng pháp Newton tuyến tính hoá hệ và nh- vậy với mỗi b-ớc lặp cần giải một hệ ph-ơng trình tuyến tính (mà biến là ∆xi) xác định bởi công thức lặp cho tới khi vectơ X(x1,x2,x3,.....,xn) gần với nghiệm. D-ới đây là ch-ơng trình giải hệ ph-ơng trình phi tuyến 1 3 2 3 1 2 4 1 2 3 4 1 2 3 1 2 3 4 3 8 0 5 0 25 8 4 0 2 8 0 x x x x x x x x x x x x x x x − − = + + + − = − + + = − + = −⎧ ⎨ ⎪⎪⎪ ⎩ ⎪⎪⎪ Ma trận đạo hàm riêng J(xi)là : 1 2 2 4 2 2 1 4 1 2 1 2 3 2 3 2 3 3 3 3 3 0 3 1 1 1 1 25 0 8 0 2 2 2 1 1 2 x x x x x x x x x x x x x x x x − − − − − − −⎛ ⎝ ⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜ ⎞ ⎠ ⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟ 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. 148 Ch−ơng trình 8-11 //giai he pt phi tuyen #include #include #include #include #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 ; 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) { 149 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) { 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"); } 150 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]); 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; }

Các file đính kèm theo tài liệu này:

  • pdfgiao_trinh_turbo_c_nang_cao_va_c_chuong_9_cac_van_de_ve_ma_t.pdf