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

