
375
printf("\n %d derivative=%f error=%f ",
k,der,delta);
if(fabs(delta)>=500.0)
{
printf("\n A numerical problem was
encountered.");
printf("\n Restart problem with a different
choice.");
exit(1);
}
r[0]-delta/der;
}
gotoxy(70,25);
textattr(WHITE+(BLACK<<4));
cputs(" ");
gotoxy(xt,yt+2);
switch(ch)
{
case '1':
case '3':
printf("\n\n -%c %9.6f ",(char)236,r[0]);
break;
case '2':
printf("\n\n %9.6f %9.6f ",d[0],r[0]);
}
for(i=1;i<N;i++)
printf("\n %9.6f %9.6f ",d[i],r[i]);
switch(ch)
{
case '1':
case '3':
printf("\n +%c",(char)236);
break;
case '2':
printf("\n %9.6f ",-d[0]);
}
printf("\nEnter file name for storing
quantizer-->");
scanf("%s",file_name);
fptr=fopen(file_name,"w");
for(i=0;i<N;i++)
fprintf(fptr,"%f %f \n",d[i],r[i]);
fclose(fptr);

376
}
double p(double x)
{
double prob;
switch(ch)
{
case '1':
prob=exp(-x*x*0.5);
break;
case '2':
prob=1.0;
break;
case '3':
prob=exp(-1.4142136*fabs(x));
break;
}
return prob;
}
#define EPS 1.0e-6
/*----------------------------------
Calculating the next decision level,
given values for d[i-11 and r[i-1].
--------------------------------- */
double decision_level(double di_1, double ri_1)
{
double delta,di,fun,dfun,ff,area1,area2;
int i;
if(fabs(di_1)>10.0) delta=2.0;
else delta=0.1;
di=ri_1+delta;
i=0;
/* Using Newton-Raphson's method for root finding.
*/
while(fabs(delta)>=EPS)
{
i++;
if(i>=1000)
{
printf("\n no convergence.\n");
return di;
}
area1=Romberg(di-1,di,f1);
area2=Romberg(di-1,di,f2);

377
ff=area1/area2;
fun=(ri_1)-ff;
if(fabs(area2)<=1.0e-10)
{
printf("\n A numerical problem was
encountered.");
printf("\n Restart problem with a different
choice.");
exit(1);
}
dfun=-p(di)*(di-ff)/area2;
if(fabs(dfun)<=1.0e-10)
{
gotoxy(1,20);
printf("\n derivative=%f",dfun);
printf("\n A numerical problem was
encountered.");
printf("\n Restart problem with a different
choice.");
exit(1);
}
delta=-fun/dfun;
di+=delta;
}
return di;
}
/*-------------------------
functions used by numerical integration routine.
-------------------------------- */
double f1(double y)
{
return (y*(p(y)));
}
double f2(double y)
{
return p(y);
}
/* -----------------------------
Numerical integration using
Romberg method.
---------------------------- */
double Romberg(double di_1,double di,double
(*f)(double))
{

378
double T[10][10],h,x,Area;
int N,k,kk,i,j;
N=9;
k=1 ;
h=di- di_1;
T[0][0]=h*((*f)(di_1)+(*f)(di))/2.0;
for(i=1;i<=N;i++)
{
k<<=1;
h/=2.0;
x=di_1 - h;
Area=0.0;
T[0][i]=(T[0][i-1])/2.0;
for(j=0;j<(k-1);j+=2)
{
x+=2.0*h ;
Area+=(*f)(x);
}
T[0][i]+=Area*h;
kk=1;
for(j=1;j<=i;j++)
{
kk<<=2;
T[j][i]=(kk*T[j-1][i]-T[j-1][i-1])/(float)(kk-
1);
}
}
return T[N][N];
}
Bài tập 13.8
1. Chạy chương trình 13.9 dùng các lựa chọn sau:
3 bit, 4 bit, 5 bit, 6 bit.
2. Với mỗi lựa chọn số bit ta chọn:
Gauss.
Đồng đều.
Laplace.
3. Các mức lượng tử có thể dùng cho thiết kế có trên đĩa, ví dụ dùng
Q3G.DAT cho lượng tử 3 bit dùng lượng tử Gauss, Q4L.DAT cho 4 bit lượng
tử Laplace.
Phương pháp Lloyd Lloyd cũng đưa ra một phương pháp thứ hai cho
phép xác định các mức lượng tử mà ông gọi là phương pháp Lloyd I. Phương

379
pháp này có nhiều ưu điểm hơn phương pháp II (giải thuật Lloyd-Max), vì nó
dễ dàng cho tính toán và các vector lượng tử hoá có thể mở rộng. Chú ý là vấn
đề mà chúng ta quan tâm ở đây là khoảng cách lượng tử hoá, lượng tử hoá của
hàm một biến đã biết được phân tán. Vector lượng tử hoá là một vector của
nhiều biến mà với các biến này ta đã biết được phân tán.
Thuật toán Lloyd theo các bước sau:
1. Rút ra ước lượng cho phạm vi của các biến
di {i = 0, 1, 2, ..., N}
(Một ước lượng có thể rút ra bằng cách dùng các giá trị từ lượng tử hoá
đồng đều hoặc từ các mức lượng tử trước mà ta cần một kết quả tốt hơn).
2. Đặt một biến D1= 0. D1 dùng để lưu lại tình trạng không chính xác lúc
trước.
3. Tính
1
1
)(
)(
i
i
i
i
d
d
d
d
idyyp
dyyyp
r
i = 0, 1, ..., N - 1.
4. Tính
dr r
i
i i
1
2
i = 0, 1, ..., N - 1
5. Tính tình trạng không chính xác
1
0
2
2
1)()(
N
k
d
d
k
k
k
dyypryD
Có thể dễ dàng mở rộng biểu thức trạng thái không chính xác theo
1
0
22 111 )()(2)(
N
k
d
d
d
dk
d
dkk
k
k
k
k
kdyyprdyyyprypyD (13.58)
6. Nếu
D D
D
2 1
1
thì một giải pháp đã được tìm ra. Lưu lại kết quả và thoát khỏi chương
trình.
7. Đặt D1 = D2
8. Quay lại bước 3.
Một chương trình C cho giải thuật trên được đề cập đến ở dưới đây.