Giáo trình Turbo C nâng cao và C++ - Chương 12: Tính gần đúng đạo hàm và tích phân xác định

//Phuong phap Simpson; #include #include #include 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 = "); 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++) {210 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(); } Dùng chương trình này tính tích phân của hàm trong function trong đoạn [0,1] với 20 khoảng chia cho ta kết quả J = 3.14159265.

pdf7 trang | Chia sẻ: hachi492 | Ngày: 07/01/2022 | Lượt xem: 413 | Lượt tải: 0download
Bạn đang xem nội dung tài liệu Giáo trình Turbo C nâng cao và C++ - Chương 12: Tính gần đúng đạo hàm và tích phân xác định, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
204 Ch−ơng 12 : Tính gần đúng đạo hàm và tích phân xác định Đ1. Đạo hàm Romberg Đạo hàm theo ph−ơng pháp Romberg là một ph−ơng pháp ngoại suy để xác định đạo hàm với một độ chính xác cao . Ta xét khai triển Taylor của hàm f(x) tại (x+h) và (x-h) : ⋅⋅⋅++′′′+′′+′+=+ )x(f !4 h )x(f !3 h )x(f 2 h )x(fh)x(f)hx(f )4( 432 (1) ⋅⋅⋅−+′′′−′′+′−=− )x(f !4 h )x(f !3 h )x(f 2 h )x(fh)x(f)hx(f )4( 432 (2) Trừ (1) cho (2) ta có : ⋅⋅⋅++′′′+′=−−+ )x(f !5 h2 )x(f !3 h2 )x(fh2)hx(f)hx(f )5( 53 (3) Nh− vậy rút ra : ⋅⋅⋅−−′′′−−−+=′ )x(f !5 h )x(f !3 h h2 )hx(f)hx(f )x(f )5( 42 (4) hay ta có thể viết lại : [ ] ⋅⋅⋅++++−−+=′ 664422 hahaha)hx(f)hx(fh21)x(f (5) trong đó các hệ số ai phụ thuộc f và x . Ta đặt : )]hx(f)hx(f[ h2 1)h( −−+ϕ = (6) Nh− vậy từ (5) và (6) ta có : ⋅⋅⋅−−−−′=ϕ= 664422 hahaha)x(f)h()1,1(D (7) ⋅⋅⋅−−−−′=⎟⎠ ⎞⎜⎝ ⎛ϕ= 64 h a 16 h a 4 h a)x(f 2 h )1,2(D 6 6 4 4 2 2 (8) và tổng quát với hi = h/2 i-1 ta có : ⋅⋅⋅−−−−′=ϕ= 6i64i42i2i hahaha)x(f)h()1,i(D (9) Ta tạo ra sai phân D(1,1) - 4D(2,1) và có : ⋅⋅⋅−−−′−=⎟⎠ ⎞⎜⎝ ⎛ϕ−ϕ 6644 ha16 15 ha 4 3 )x(f3 2 h 4)h( (10) Chia hai vế của (10) cho -3 ta nhận đ−ợc : ⋅⋅⋅+++′=−= 6644 ha16 5 ha 4 1 )x(f 4 )1,1(D)1,2(D4 )2,2(D (11) Trong khi D(1,1) và D(2,1) sai khác f′(x) phụ thuộc vào h2 thì D(2,2) sai khác f′(x) phụ thuộc vào h4 . Bây giờ ta lại chia đôi b−ớc h và nhận đ−ợc : D f x a h a h(2, ) ( ) ( / ) ( / ) ...2 1 4 2 5 16 24 4 6 6= + + +′ (12) và khử số hạng có h4 bằng cách tạo ra : D D f x a h(2, ) ( , ) ( ) ( ) ...2 16 32 15 15 64 6 6− − ′= + + + (13) Chia hai vế của (13) cho -15 ta có : D D D f x a h(3, ) (3, ) (2, ) ( ) . ...3 16 2 2 15 1 64 6 6= = − − − ′ (14) 205 Với lần tính này sai số của đạo hàm chỉ còn phụ thuộc vào h6 . Lại tiếp tục chia đôi b−ớc h và tính D(4,4) thì sai số phụ thuộc h8 . Sơ đồ tính đạo hàm theo ph−ơng pháp Romberg là : 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) . . . . . . . . . . . . trong đó mỗi giá trị sau là giá trị ngoại suy của giá trị tr−ớc đó ở hàng trên . Với 2 ≤ j ≤ i ≤ n ta có : D j D j D jj j(i, ) (i, ) (i , ) = − − − − − − − 1 1 4 1 1 1 4 1 và giá trị khởi đầu là : D h h f x h f x hi i i i (i, ) ( ) [ ( ) ( )]1 12= = + − −ϕ với hi = h/2 i-1 . Chúng ta ngừng lại khi hiệu giữa hai lần ngoại suy đạt độ chính xác yêu cầu. 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 201843569.4)]75.1(f)25.2(f[ 25.02 1 )1,2(D 207496266.4)]5.1(f)5.2(f[ 5.02 1 )1,1(D =−ì= =−ì= 200458976.4)]875.1(f)125.2(f[ 125.02 1 )1,3(D =−ì= 200492284.4 14 )2,2(D)2,3(D4 )3,3(D 200458976.4 14 )1,2(D)1,3(D4 )2,3(D 19995935.4 14 )1,1(D)1,2(D4 )2,2(D 21 2 1 1 1 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. Ch−ơng trình12-.1 //Daoham_Romberg; #include #include #include #define max 11 float h; void main() { float d[max]; int j,k,n; float x,p; float y(float),dy(float); 206 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; 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); } Đ2. Khái niệm về tích phân số Mục đích của tính tích phân xác định là đánh giá định l−ợng biểu thức : J f x a b = ∫ ( )dx trong đó f(x) là hàm liên tục trong khoảng [a,b] và có thể biểu diễn bởi đ−ờng cong y= f(x). Nh− vậy tích phân xác định J là diện tích SABba , giới hạn bởi đ−ờng cong f(x) , trục hoành , các đ−ờng thẳng x = a và x = b . Nếu ta chia đoạn [a,b] thành n phần bởi các điểm xi thì J là gới hạn của tổng diện tích các hình chữ nhật f(xi).(xi+1 - xi) khi số điểm chia tiến tới ∝, nghĩa là : a a b A B y x 207 J f x x x n i i n i i = − →∞ = + ∑lim ( )( ) 0 1 Nếu các điểm chia xi cách đều , thì ( xi+1- xi ) = h . Khi đặt f(xo) = fo , f(x1) = f1 ,... ta có tổng : n i i n S h f= = ∑ 0 Khi n rất lớn , Sn tiến tới J . Tuy nhiên sai số làm tròn lại đ−ợc tích luỹ . Do vậy cần phải tìm ph−ơng pháp tính chính xác hơn . Do đó ng−ời ta ít khi dùng ph−ơng pháp hình chữ nhật nh− vừa nêu . Đ3. Ph−ơng pháp hình thang Trong ph−ơng pháp hình thang , thay vì chia diện tích SABba thành các hình chữ nhật , ta lại dùng hình thang . Ví dụ nếu chia thành 3 đoạn nh− hình vẽ thì : S3 = t1 + t2 + t3 trong đó ti là các diện tích nguyên tố . Mỗi diện tích này là một hình thang : ti = [f(xi) + f(xi-1)]/ (2h) = h(fi - fi-1) / 2 Nh− vậy : S3 = h[(fo+f1)+(f1+f2)+(f2+f3)] / 2 = h[fo+2f1+2f2+f3] / 2 Một cách tổng quát chúng ta có : )f2f2f2f(n ab S n1n1on ++⋅⋅⋅++= − − hay : }f2ff{n ab S n 1i ion n ∑++− == Một cách khác ta có thể viết : f x dx f x hf a kh f a k h a b a kh a k h k n k n ( ) ( )dx { ( ) / [ ( ) ] / } ( ) ∫ ∫∑ ∑= ≈ + + + + + + + = − = −1 1 1 0 1 2 1 2 hay : f x h f a f a h f a n h f b a b ( )dx { ( ) / ( ) [ ( ) ] ( ) / }= + + + ⋅ ⋅ ⋅ + + − +∫ 2 1 2 Ch−ơng trình tính tích phân theo ph−ơng pháp hình thang nh− sau : Ch−ơng trình 12-2 //tinh tich phan bang phuong phap hinh_thang; #include #include #include float f(float x) { float a=exp(-x)*sin(x); return(a); }; 208 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; s=s+f(x); } tp=s*h; printf("Gia tri cua tich phan la : %10.6f\n",tp); getch(); } Dùng ch−ơng trình này tính tích phân của hàm cho trong function trong khoảng [0 , 1] với 20 điểm chia ta có J = 0.261084. Đ4. Công thức Simpson Khác với ph−ơng pháp hình thang , ta chia đoạn [a,b] thành 2n phần đều nhau bởi các điểm chia xi : a = xo < x1 < x2 < ....< x2n = b xi = a+ih ; h = (b - a)/ 2n với i =0 , . . , 2n Do yi = f(xi) nên ta có : ∫∫∫ ∫ − +++= x x fdx... x x fdx b a x x fdxdx)x(f n2 2n2 4 2 2 0 Để tính tích phân này ta thay hàm f(x) ở vế phải bằng đa thức nội suy Newton tiến bậc 2 : y t2 )1t(t yty)x(P 0 2 002 ∆−∆ ++= và với tích phân thứ nhất ta có : dx)x(Pdx)x(f x x x x 2 0 2 0 2∫∫ = Đổi biến x = x0+th thì dx = hdt , với x0 thì t =0 và với x2 thì t = 2 nên : 209 |]y) 2 t 3 t( 2 1y 2 tty[h dt)y 2 )1t(1 yty(hdx)x(P 2t 0t0 2 23 0 2 0 0 2 0 2 0 02 x x 2 0 = =∆∆ ∆−∆∫∫ −++= ++= ]yy4y[ 3 h ]y) 2 4 3 8( 2 1y2y2[h 210 0 2 00 ++= −++= ∆∆ Đối với các tích phân sau ta cũng có kết quả t−ơng tự : ]yy4y[ 3 hdx)x(f 2i21i2i2 x x 2i2 i2 ++ ++=∫ + Cộng các tích phân trên ta có : ]y)yyy(2)yyy(4y[ 3 hdx)x(f n22n2421n231o b a ++⋅⋅⋅++++⋅⋅⋅+++= −−∫ Ch−ơng trình dùng thuật toán Simpson nh− sau : Ch−ơng trình 12-3 //Phuong phap Simpson; #include #include #include 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 = "); 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++) { 210 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(); } Dùng ch−ơng trình này tính tích phân của hàm trong function trong đoạn [0,1] với 20 khoảng chia cho ta kết quả J = 3.14159265.

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

  • pdfgiao_trinh_turbo_c_nang_cao_va_c_chuong_12_tinh_gan_dung_dao.pdf