⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wilson.c

📁 speech signal process tools
💻 C
字号:
/*	 This material contains proprietary software of Entropic Processing, Inc. Any reproduction, distribution, or publication without the the prior	    written permission of Entropic Processing, Inc. is strictly prohibited. Any public distribution of copies of this work authorized in writing by Entropic Processing, Inc. must bear the notice			       	Copyright 1986, Entropic Proccessing, Inc	(C) 1985, Entropic Processing, Inc.         */#ifdef SCCSstatic char *sccsid = "@(#)wilson.c	1.2 4/28/86";#endif	/*			WILSON				*//*		John's improved version			*//*	C subroutine that corresponds to newils.f	*/#include <stdio.h>#define MAXSIZ 800#define FILTSZ ((MAXSIZ*(MAXSIZ+1))/2)#define ZERO 0.0#define ONE 1.0e0extern debug_level;wilson(c,size,th_init,init_siz,theta,rfl_coef,eps)double *c,*th_init,*theta,*rfl_coef,eps;int size,init_siz;/*    FACTORIZATION OF THE COVARIANCE OF A PURE MOVING AVERAGE PROCESS(new algorithm modified by John P. Burg that avoids      the matrix inversion)Ref : " Factorization of the covariance generating function	of a pure moving average process "	G. Wilson ; SIAM J. Numerical Analysis	Vol 6, No 1, March 1969The c vector represents the coefficients of the covariance 	generating function of a pure M.A process.The	polynomial is symmetric : c(k)=c(-k) 0<=k<=MThe Theta vector represents the coefficients of the moving 	average process        Find theta , knowing c  such that c(Z)=theta(Z)*theta(1/Z)M is the order of the filterq is the previous estimation of theta and is used to compute	theta: the new estimationfilt is the vector containing the coeffients of all the prediction error filters of order less than or equal to M.rlf_coef[0] returns with the value of gain of the inverse filter*//*  WARNING 1 :the c vector is assumed to correspond to actual correlationvalues and is thus not being tested here in this respect.*//*  WARNING 2 :The resulting polynomial has all its zeros OUTSIDE the unitcircle and is thus a minimum phase filter if oneconsiders it as a polynomial in Z.Otherwise one just has to flip the coefficients around : i.e.	theta(k)<->theta(M-k)the iteration stops when the normalized standard deviation  between q and theta as given by the stddev subroutine is 	  less than epsilon.*/{    double  tmp, q[MAXSIZ], stdv, R[MAXSIZ + MAXSIZ], S[MAXSIZ];    double  filt[FILTSZ];    int     iter, M, tM, sigM, i;    double  sqrt (), stddev ();/*       INITIALIZATION    */    if (size > MAXSIZ)	faterr ("wilson", "the dimension of the filter is too big", 1002);    else if (size <= 0)	faterr ("wilson", "the dimension of the filter is negative", 1003);    else if (size == 1) {	/* trivial case */	fprintf (stderr, " wilson : trivial case; size = 1");	if (c[0] <= 0.0)	    faterr ("wilson", " c[0] is negative ", 1004);	else {	    theta[0] = sqrt (c[0]);	    rfl_coef[0] = ONE / c[0];	}	return (0);    }    M = size-1;			/* M is the order of the polynomial */    tM = M + M;    sigM = M * (M + 1) / 2;    if (init_siz == 0) {	/*  use default initialization  */    /* printf("default initialization      "); */	for (i = 1, tmp = ZERO; i <= M; i++) {	    tmp += c[i];	    q[i] = ZERO;	}	q[0] = c[0] + tmp + tmp;	if (q[0] <= ZERO) {	    fprintf (stderr, "GASP : q[0]<0   q[0] = %lg \n", q[0]);	    fprintf (stderr, " try again ! \n");	    return (4);	}	q[0] = sqrt (q[0]);    /* printf(" q[0] = %lg \n",q[0]); *//*     this is an optimal initial value for theta according to Wilson */    }    else			/* use the array th_init of size init_siz 				*/	shiftar (q, th_init, init_siz);/*printf(" wilson alg initial guess\n");for(i=0 ; i<=M ; i++)	printf(" q[%d] = %lg \n",i,q[i]);*//*       MAIN LOOP    */    stdv = 0.0;    for (iter = 1;; iter++) {	/*	if (debug_level >= 2)	    printf("wilson: iteration %d   stdv= %g\n",iter,stdv);	*/	if (q[0] <= ZERO) {	    fprintf (stderr, "GASP : q[0]<0   q[0] = %lg \n", q[0]);	    fprintf (stderr, " try again ! \n");	    return (2);	}	if (baclev (q, rfl_coef, M, R, tM, filt, sigM) != 0)	    return (1);	compuS (R, tM, c, S, M);	mkthta (S, q, theta, M);	stdv = stddev (theta, q, M);	if (stdv < eps)	    break;	shiftar (q, theta, size);    }/*printf("last standard deviation on theta : %g   after %d iterations\n",stdv,iter);*/    check_wils (q, theta, M);    stdv = stddev (c, q, M);/*printf(" standard deviation on check : %g\n",stdv);*/    return (0);}/*      -------------------------------------------------------    */baclev(q,rflcof,m,r,tm,fil,sm)double  q[],rflcof[],r[],fil[];int  m,tm,sm;/*"Backwards" Levinson algorithm :             	Given a minimum phase filter q of order m, compute        	the autocorrelation values R out to        	lag tm(=2m)corresponding to the inverse filter.        	fil contains all the coefficients of the prediction error         	filters in increasing order.    At the same time, get the reflection coefficients rflcof;The gain of the filter is returned as r[0]=rflcof[0]*/{register int  k,km1,find,ff,fb,j;double  gain,cof,oocsq,temp;/*the coefficients of the successive prediction error filters are     	stored, in the array fil, in the following way :     	- in increasing order of 'order of the filter'        	- for each filter, in increasing order of 'coefficient order'    	  the coefficient of order 0 is never stored since it is        		always equal to 1.        	  i.e. fil(1) is the coefficient of the filter of order 1        		the second order prediction error filter is equal to       		1+ fil(2).Z + fil(3).Z        	find is the running indice for fil.    *//*        INITIALIZATION    *//*  printf("baclev\n");  */if (tm != m+m)	faterr("baclev","tm != 2m",1101);if (sm != m*(m+1)/2)	faterr("baclev","sm != m*(m+1)/2",1102);/* normalize the filter so that the coefficient of order 0		is equal to 1 */if (q[0] == 0.0)	{		fprintf(stderr," baclev init -> q[0] = 0.0  \n");		fprintf(stderr," try again ! ");		return(3);	}gain =  ONE / q[0];for ( k=1,find=sm-m+1 ; k<=m ; k++,find++)	fil[find]=q[k]*gain;gain = gain*gain;/*       MAIN LOOP    */for ( k=m,fb=sm,find=sm-m ; k>=2 ; k--)	{	km1=k-1;	ff=find+1;	cof=fil[fb];	if (cof >= 1.0 || cof <= -1.0)		{		fprintf(stderr," | refl coeff(%d) = %g | >= 1.0 \n",k,cof);		fprintf(stderr," try again ! \n");		return(1);		}	fb=fb-1;	rflcof[k]=cof;	oocsq=ONE/(ONE-cof*cof);	gain *= oocsq;	/*	if (fb != k*(k+1)/2-1 || fb != find+km1) 		printf("tu t''es plante dans ff mon gars\n");	if (ff  !=  k*km1/2+1 || ff != fb-km1+1) 		printf("tu t''es plante dans fb mon gars\n");	*//*     - We are here computing the filter of order (k-1). The coefficients    	are computed in decreasing order, i.e. from j=k-1 to 1    	find is the indice of the coefficient of order j in the	filter of order k    	fb coefficient j , filter of order k    	ff coefficient k-j, filter of order k    */	for (j=km1 ; j>=1 ; j--,find--,fb--,ff++)		fil[find]= oocsq*(fil[fb]-cof*fil[ff]);	}cof=fil[1];if (cof >= 1.0 || cof <= -1.0)	{		fprintf(stderr," | refl coeff(1) = %g | >= 1.0 \n",cof);		fprintf(stderr," try again ! \n");		return(1);	}fb--;rflcof[1]=cof;oocsq=ONE/(ONE-cof*cof);gain *= oocsq;r[0]=gain;rflcof[0] = gain;for (k=1,find=1 ; k<=m ; k++)	{	for (j=k-1,temp=ZERO ; j>=0 ; j--,find++)		temp -= fil[find]*r[j];	r[k]=temp;	}for (k=m+1 ; k<=tm ; k++)	{	for (j=k-m,temp=ZERO,find=sm ; j<=k-1 ; j++,find--)		temp -= fil[find]*r[j];	r[k]=temp;	}/*for k>M r(k) is the convolution of r(j) k-m<=j<=k-1 with the    	  Mth order filter since the process is considered to be of    	  order M.*/return(0);}/*     -----------------------------------------------------------    */compuS(r,tm,c,s,m)double  r[],c[],s[];register int  m;/*s represents the product of the 2 polynomials c and r the 3 polynomials are symmetric (i.e. the coefficients    	  of the negative powers of Z are identical to those of    	  the positive powers)       r is an infinite polynomial, but since c is of order m, we    	only need the powers of r up to order 2m(tm)           we then take the positive powers of s(Z)+1 => we take        	(s(0)+1)/2 instead of s(0)    */{    register int    k, j, kpj, kmj;    double  tmp;/*  printf("compuS\n");  *//*    	tmp=ONE;    */    tmp = 0.5e0 * (ONE + c[0] * r[0]);    for (j = 1; j <= m; j++)	tmp += c[j] * r[j];/*    	s[0]=0.5e0*tmp;    */    s[0] = tmp;    for (k = 1; k <= m; k++) {	tmp = c[0] * r[k];	for (j = 1, kmj = k - 1, kpj = k + 1; j <= m; j++, kmj--, kpj++)	    tmp += c[j] * (r[abs (kmj)] + r[kpj]);	s[k] = tmp;    }}/*      ------------------------------------------------------------  */mkthta(s,q,t,m)double  s[],q[],t[];register int  m;/*      s,q,t are 3 polynomials of order m t=s*q    */{register int  k,j;double  tmp;/* printf("mkthta\n");  */for (k=0 ; k<=m ; k++)	{	for (j=0,tmp=ZERO ; j<=k ; j++)		tmp += s[j]*q[k-j];	t[k]=tmp;	}}/*      ---------------------------------------------------------   */check_wils(c,theta,m)double *theta,*c;int m;/*Check the result of the wilson algorithmc(Z) = theta(Z) * theta(1/Z)both polynomials are of order m*/{register int j,k,p;register double tmp;/* printf(" check_wils \n");  */for(k=0 ; k<=m ; k++)	{	p= m-k;	tmp=0.0;	for(j=0 ; j<=p ; j++)		tmp+=theta[j]*theta[k+j];	c[k]=tmp;	}return(0);}/*    -------------------------------------------------------------   */#include <stdio.h>faterr(sub,messag,n)char *sub,*messag;int n;{/*    Subroutine for fatal error messages */fprintf(stderr,"			FATAL ERROR in : %s \n",sub);fprintf(stderr,"%s\n",messag);exit(n);}/*    ---------------------------------------------------------    */shiftar(u,v,n)double *u,*v;int n;/*SHIFT ARRAY v into array u  (elements 0 to (n-1) included)*/{while(n-- > 0)	*(u++) = *(v++);return(0);}/*     -----------------------------------------------------------    */double stddev(u,v,n)double *u,*v;int n;{register int  i;double tmp,e,denom,w,sqrt();/*printf("\n");printf(" stddev \n");*/for (i=0,tmp=0.0,denom=0.0; i<=n ; i++)	{	w=u[i];	e=w - v[i];	tmp += e*e;	denom += w*w;	}denom *= n;tmp /= denom;return(sqrt(tmp));}/*     -----------------------------------------------------------    */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -