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

📄 特征提取.htm

📁 有关语音特征提取的C++程序
💻 HTM
📖 第 1 页 / 共 2 页
字号:
}

template<typename T>
inline CPolynomial<T> poly_divide(const CPolynomial<T>& a, const double b)
{
	CPolynomial<T> q,r;
	PolynomialDivision(a,CPolynomial<T>((T)b),q,r);
	return q;
}

template<typename T>
inline CPolynomial<T> poly_divide(const double a, const CPolynomial<T>& b)
{
	CPolynomial<T> q,r;
	PolynomialDivision(CPolynomial<T>((T)a),b,q,r);
	return q;
}

template<typename T>
inline CPolynomial<T> poly_modulo(const CPolynomial<T>& a, const CPolynomial<T>& b)
{
	CPolynomial<T> q,r;
	PolynomialDivision(a,b,q,r);
	return r;
}

template<typename T>
inline CPolynomial<T> poly_modulo(const CPolynomial<T>& a, const double b)
{
	CPolynomial<T> q,r;
	PolynomialDivision(a,CPolynomial<T>((T)b),q,r);
	return r;
}

template<typename T>
inline CPolynomial<T> poly_modulo(const double a, const CPolynomial<T>& b)
{
	CPolynomial<T> q,r;
	PolynomialDivision(CPolynomial<T>((T)a),b,q,r);
	return r;
}

/*

#if 0
template<typename T> inline CPolynomial<T> poly_plus(const CPolynomial<Complex<T> >& a, const CPolynomial<Complex<T> >& b)
{
	CPolynomial<T> c = a; c += b; return c;
}

template<typename T> inline CPolynomial<T> poly_minus(const CPolynomial<Complex<T> >& a, const CPolynomial<Complex<T> >& b)
{
	CPolynomial<T> c = a; c -= b; return c;
}

template<typename T> inline CPolynomial<T> poly_times(const CPolynomial<Complex<T> >& a, const CPolynomial<Complex<T> >& b)
{
	CPolynomial<T> c = a; c *= b; return c;
}

template<typename T> inline CPolynomial<T> poly_divide(const CPolynomial<Complex<T> >& a, const CPolynomial<Complex<T> >& b)
{
	CPolynomial<T> c = a; c /= b; return c;
}
#endif
*/

template<typename T>
CPolynomial<T>::CPolynomial(int m, const T* a)
{
	for(int i=0; i<=m; i++){
		v.push_back(a[i]);
	}
}
/*

#if 0
// do not use <cstdarg> and <typeinfo> because they are very fragile
// and depend on compilers
template<typename T>
CPolynomial<T>::CPolynomial(int m, const T v0, ...)
{
	va_list args;
	va_start (args, m); // Although GNU compiler warns here, we can ignore it.
	const type_info& a = typeid(v0);
	if(strcmp(a.name(),"float")==0 || strcmp(a.name(),"double")==0){
		for(int i=1; i<=m; i++){
			v.push_back((T)va_arg(args, double));
		}
	}
	else{
		printf("Unsupported Polynomial type (%s)!\n", a.name());
		exit(1);
	}
    va_end (args);
}
#endif
*/


template<typename T>
CPolynomial<T>::CPolynomial(const char* a)
{
	char *t = strdup(a);
	char *p = strtok(t, " \t\r\n");
	v.push_back((T)atof(p));
	while((p = strtok(NULL, " \t\r\n"))){
		v.push_back((T)atof(p));
	}
	free(t);
}

template<typename T>
CPolynomial<T>::CPolynomial()
{
	v.push_back((T)0);
}

template<typename T>
CPolynomial<T>::~CPolynomial()
{
}

#define EPS 2.0e-6
#define MAXM 100

/* Roots() yields n roots into roots[1]...roots[n] */
template<typename T>
void CPolynomial<T>::Roots(CComplex* roots) const
{
	int n = v.size()-1;
	vector<CComplex> a(n+1);
	for(int i=0;i<=n;i++) a[i] = CComplex(v[i],0);
	zroots(&a[0], n, roots, 1);
}

#define EPSS 1.0e-7
#define MR 8
#define MT 10
#define MAXIT (MT*MR)

#ifndef my_max
#define my_max(a, b) (((a) > (b)) ? (a) : (b)) 
#endif
#ifndef my_min
#define my_min(a, b) (((a) < (b)) ? (a) : (b)) 
#endif


template<typename T>
void CPolynomial<T>::zroots(CComplex* a, int m, CComplex* roots, int polish) const
{
	int i,its,j,jj;
	CComplex x,b,c,ad[MAXM];

	for(j=0;j<=m;j++) ad[j] = a[j];
	for(j=m;j>=1;j--){
		//x = 0;
		x = roots[j];
		laguer(ad,j,&x,&its);
		if(fabs(imag(x)) <= 2.0*EPS*fabs(real(x))) x=CComplex(real(x), 0);
		roots[j] = x;
		b = ad[j];
		for(jj=j-1;jj>=0;jj--){
			c = ad[jj];
			ad[jj] = b;
			b = x*b+c;
		}
	}
	if(polish)
		for(j=1;j<=m;j++)
			laguer(a,m,&roots[j],&its);
	for(j=2;j<=m;j++){
		x = roots[j];
		for(i=j-1;i>=1;i--){
			if(real(roots[i]) <= real(x)) break;
			roots[i+1] = roots[i];
		}
		roots[i+1] = x;
	}
}

template<typename T>
void CPolynomial<T>::laguer(CComplex* a, int m, CComplex* x, int *its) const
{
	int iter,j;
	T abx,abp,abm,err;
	CComplex dx,x1,b,d,f,g,h,sq,gp,gm,g2;
	static T frac[MR+1]={
		(T)0.00,(T)0.50,(T)0.25,
		(T)0.75,(T)0.13,(T)0.38,
		(T)0.62,(T)0.88,(T)1.00
	};

	for(iter=1;iter<=MAXIT;iter++){
		*its = iter;
		b = a[m];
		err = (T)abs(b);
		d = f = 0;
		abx = (T)abs(*x);
		for(j=m-1;j>=0;j--){
			f = (*x)*f+d;
			d = (*x)*d+b;
			b = (*x)*b+a[j];
			err = (T)abs(b)+abx*err;
		}
		err *= (T)EPSS;
		if(abs(b) <= err) return;
		g = d/b;
		g2 = g*g;
		h = g2 - (T)2*(f/b);
		sq = sqrt((T)(m-1)*(((T)m*h)-g2));
		gp = g+sq;
		gm = g-sq;
		abp = (T)abs(gp);
		abm = (T)abs(gm);
		if(abp < abm) gp = gm;
		dx = ((my_max(abp,abm) > 0.0 ? CComplex(m,0)/gp
			: ((T)exp(log(1+abx))*CComplex(cos(iter),sin(iter)))));
		x1 = (*x)-dx;
		if(real(*x) == real(x1) && imag(*x) == imag(x1)) return;
		if(iter%MT) *x = x1;
		else *x = (*x)-frac[iter/MT]*dx;
	}
	printf("too many iteration in laguer");
	return;
}

template<typename T>
T CPolynomial<T>::Eval(T x, T* pd, int nd) const
{
	int nnd, j, i;
	T cnst = 1;
	T ftmp;

	if(!pd){
		nd = 0;
	}
	int n = v.size()-1;
	ftmp = v[n];
	if(pd) pd[0] = v[n];
	for(j=1;j<=nd;j++) pd[j] = 0;
	for(i=n-1;i>=0;i--){
		nnd = (nd < (n-i) ? nd : n-i);
		for(j=nnd;j>=1;j--)
			pd[j] = (T)(pd[j]*x+pd[j-1]);
		ftmp = (T)(ftmp*x+v[i]);
		if(pd) pd[0] = (T)(pd[0]*x+v[i]);
	}
	for(i=2;i<=nd;i++){
		cnst *= i;
		pd[i] *= cnst;
	}
	return ftmp;
}

template<typename T>
void CPolynomial<T>::Print() const
{
	int n=v.size()-1;
	int bAllZero = 1;
	for(int i=n;i>=0;i--){
		if(fabs(v[i]) < 1e-37){
			if(i==0 && bAllZero) printf("0");
			continue;
		}
		bAllZero = 0;
		if(v[i] > 0 && i != n) printf(" + ");
		else if(v[i] < 0) printf(" - ");

		if(fabs(fabs(v[i])-1) > 1e-37){
			printf("%gx(%d)",fabs(v[i]),i);
		}
		else{
			printf("x(%d)",i);	
		}
	}
	printf("\n");
}

template<typename T>
CPolynomial<T>& CPolynomial<T>::operator=(const CPolynomial<T>& a)
{
	int an = a.v.size()-1;
	int n = an;
	v.resize(n+1);
	int m = 0;
	for(int i=0; i<=n; i++){
		v[i] = a.v[i];
		if(v[i] != 0.0) 
			m = i;
	}
	if(m != n) v.resize(m+1);
	return *this;
}

template<typename T>
CPolynomial<T>& CPolynomial<T>::operator+=(const CPolynomial<T>& a)
{
	int m = v.size()-1;
	int an = a.v.size()-1;	
	int n = my_max(m,an);
	v.resize(n+1);
	for(int i=0; i<=n; i++)
		v[i] = ((i<=m)? v[i]: 0) + ((i<=an)? a.v[i]: 0);
	return *this;
}

template<typename T>
CPolynomial<T>& CPolynomial<T>::operator-=(const CPolynomial<T>& a)
{
	int m = v.size()-1;
	int an = a.v.size()-1;	
	int n = my_max(m,an);
	v.resize(n+1);
	for(int i=0; i<=n; i++)
		v[i] = ((i<=m)? v[i]: 0) - ((i<=an)? a.v[i]: 0);
	return *this;
}

template<typename T>
CPolynomial<T>& CPolynomial<T>::operator*=(const CPolynomial<T>& a)
{
	int p,i;
	int m = v.size()-1;
	int an = a.v.size()-1;
	int n = m + an;
	v.resize(n+1);
	for(p=n;p>m;p--) v[p] = 0;
	for(p=n; p>=0; p--){
		T sum = 0;
		for(i=my_min(p,m); i>=0 && p-i<=an; i--){
			sum += v[i] * a.v[p-i];
		}
		v[p] = sum;
	}
	return *this;
}

template<typename T>
CPolynomial<T>& CPolynomial<T>::operator/=(const CPolynomial<T>& a)
{
	CPolynomial<T> q,r;
	PolynomialDivision(*this,a,q,r);
	return q;
}

#endif
</PRE></BODY></HTML>

⌨️ 快捷键说明

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