Giáo trình C - Chương 11: Nội suy và xấp xỉ hàm
Trong thực tế nhiều khi phải phục hồi một hàm y = f(x) tại mọi giá trị x trong một
đoạn [ a,b ] nào đó mà chỉ biết một số nhất định các giá trị của hàm tại một số điểm cho
tr-ớc.Các giá trị này đ-ợc cung cấp qua thực nghiệm hay tính toán.Vì vậy nảy sinh vấn đề
toán học là trên đoạn a =x =b cho một loạt các điểm xi( i= 0,1,2.) và tại các điểm xinày giá trị của hàm là yi= f(xi) đã biết.
f("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; while (t) { printf("Co sua so lieu khong(c/k): "); scanf("%c",&ok); if (toupper(ok)=='C') { 195 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]; 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])); } 196 getch(); } Với các giá trị x,y đo đ−ợc theo bảng x 0 2 4 6 8 10 12 y 128 0 635 324 162 76 43 19 ta có n = 7 và tính đ−ợc theo ch−ơng trình các hệ số : A = 1285.44 va c = -0.3476 và hàm xấp xỉ sẽ là : f(x) = 1285.44 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 Theo điều kiện đạo hàm triệt tiêu ta có hệ ph−ơng trình : ⎪⎪⎩ ⎪⎪⎨ ⎧ =+ =+ ∑ ∑∑ ∑ ∑ = == = = n 1i n 1i ii n 1i ii 2 n 1i n 1i ii ylnxlnxlnAlnxlnq ylnAlnnxlnq Giải hệ ph−ơng trình này ta có các hệ số A và q : Ch−ơng trình 11-6 //xap_xi_x_mu; #include #include #include #include #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]); 197 } 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; } 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]); 198 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); 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(); } Với các giá trị x,y đo đ−ợc theo bảng x 1 2 4 5 6 y 7.1 27.8 62.1 110 161 ta có n = 5 và tính đ−ợc theo ch−ơng trình các hệ số : A = 7.1641 và q = 1.9531 và hàm xấp xỉ sẽ là : f(x) = 1285.44x1.9531 4.Hàm l−ợng giác : Khi quan hệ y=f(x) có dạng tuần hoàn ta dùng hàm xấp xỉ là tổ hợp tuyến tính của các hàm sin và cosin dạng : ∑ ∑ = = ω+ω+= n 1i n 1i ii0 )xisin(b)xicos(aa)x(f Để đơn giản tr−ớc hết ta xét hàm chỉ có một số hạng sin-cos,nghĩa là : xsinbxcosaa)x(f 110 ω+ω+= Hàm S sẽ có dạng : [ ]∑ = ω+ω+−= n 1i 2 110i )xsinbxcosaa(yS Theo điều kiện đạo hàm triệt tiêu ta có hệ ph−ơng trình đối với các hệ số dạng : ⎥⎥ ⎥ ⎦ ⎤ ⎢⎢ ⎢ ⎣ ⎡ ω ω=⎥⎥⎦ ⎤ ⎢⎢⎣ ⎡ ⎥⎥ ⎥ ⎦ ⎤ ⎢⎢ ⎢ ⎣ ⎡ ωωωω ωωωω ωω ∑∑ ∑ ∑∑∑ ∑∑∑ ∑∑ xsiny xcosy y b a a xsinxsinxcosxsin xsinxcosxcosxcos xsinxcosn 1 1 0 2 2 Do : 0 n xsinxcos 2 1 n xcos 2 1 n xsin 0 n xcos 0 n xsin 22 =ωω =ω=ω =ω=ω ∑ ∑∑ ∑∑ nên hệ ph−ơng trình có dạng đơn giản : 199 ⎥⎥ ⎥ ⎦ ⎤ ⎢⎢ ⎢ ⎣ ⎡ ω ω=⎥⎥⎦ ⎤ ⎢⎢⎣ ⎡ ⎥⎥⎦ ⎤ ⎢⎢⎣ ⎡ ∑∑ ∑ xsiny xcosy y b a a 2n00 02n0 00n 1 1 0 Giải hệ ta có : ∑∑∑ ω=ω== xsinyn2bxcosyn2an y a 110 Trong tr−ờng hợp tổng quát,một cách t−ơng tự ta có : ∑∑∑ ω=ω== xisinyn2bxicosyn2an y a ii0 Ch−ơng trình tìm các hệ số ai và bi đ−ợc thể hiện nh− sau : Ch−ơng trình 11-7 //xap_xi_sin_cos; #include #include #include #include #define max 11 #define pi 3.15159 void main() { int i,j,m,n,t; 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++) 200 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("\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; } 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); 201 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(); } Với hàm cho bằng bảng số : x 0 0.15 0.3 0.45 0.6 0.75 0.9 1.05 1.2 1.3 y 2.200 1.595 1.03 1 0.72 2 0.78 6 1.20 0 1.80 5 2.36 9 2.67 8 2.614 Chọn số hệ số sin-cos m = 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) 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 : xb ax y += Lấy nghịch đảo của nó ta có : a 1 x 1 a b y 1 += Đặ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 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 1i n 1i ii 2 i n 1i i n 1i n 1i ii yx 1 x 1 B x 1 A y 1 x 1 BnA và từ đó tính đ−ợc a và b.Ch−ơng trình sau mô tả thuật toán trên Ch−ơng trình 11-.8 //xap xi huu_ty; #include #include #include #include #define k 11 void main() { float x[k],y[k]; float a,b,a1,b1,c,d,e; int i,n,t; 202 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++) { 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"); 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; 203 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(); } Với dãy số liệu đã cho : x 1 2 3 4 5 y 0.333333 3 0.5 0.6 0.66666 0.7142857 ta nhận đ−ợc từ ch−ơng trình trị số a = 1 và b = 2
File đính kèm:
- Giao_Trinh_C_Chuong11.pdf