一种复数求模的实用方法
2012-05-31 19:05
197 查看
一种复数求模的实用方法
在DSP中,经常遇到复数求模的问题。对于复数X
X=R+j*I(1)
其幅度magX为:
magX=sqrt(R^2+I^2)(2)
由上式可知,复数求模的问题可看做是一个实数求根的问题。对这个问题有一些成熟算法,如博文所述:/article/1961454.html
这里,针对复数求模这种特殊情况,在精度要求不太高的情况下,可用如下近似方法计算:
MagX=Alpha*max(|R|,|I|)+Beta*min(|R|,|I|)(3)
其中Alpha和Beta为系数,根据不同的准则,如均方根误差最小,峰值误差最小等,这两个系数的取值有所不同。具体数值参见下表。最简单的情况,选取Alpha=1,Beta=0.25,也能得到很不错的结果。
附录:C实现代码
/*(代码来源于网络,版权归原作者所有)*/
在DSP中,经常遇到复数求模的问题。对于复数X
X=R+j*I(1)
其幅度magX为:
magX=sqrt(R^2+I^2)(2)
由上式可知,复数求模的问题可看做是一个实数求根的问题。对这个问题有一些成熟算法,如博文所述:
这里,针对复数求模这种特殊情况,在精度要求不太高的情况下,可用如下近似方法计算:
MagX=Alpha*max(|R|,|I|)+Beta*min(|R|,|I|)(3)
其中Alpha和Beta为系数,根据不同的准则,如均方根误差最小,峰值误差最小等,这两个系数的取值有所不同。具体数值参见下表。最简单的情况,选取Alpha=1,Beta=0.25,也能得到很不错的结果。
=====================================================================
Alpha*Max+Beta*MinMagnitudeEstimator
NameAlphaBetaAvgErrRMSPeak
(linear)(dB)(dB)
---------------------------------------------------------------------
MinRMSErr0.9475436362910.3924854250920.000547-32.6-25.6
MinPeakErr0.9604338701030.397824734759-0.013049-31.4-28.1
MinRMSw/Avg=00.9480594489690.3926990816990.000003-32.6-25.7
1,MinRMSErr1.0000000000000.323260990000-0.020865-28.7-23.8
1,MinPeakErr1.0000000000000.335982538000-0.025609-28.3-25.1
1,1/21.0000000000000.500000000000-0.086775-20.7-18.6
1,1/41.0000000000000.2500000000000.006456-27.6-18.7
Frerking1.0000000000000.400000000000-0.049482-25.1-22.3
1,11/321.0000000000000.343750000000-0.028505-28.0-24.8
1,3/81.0000000000000.375000000000-0.040159-26.4-23.4
15/16,15/320.9375000000000.468750000000-0.018851-29.2-24.1
15/16,1/20.9375000000000.500000000000-0.030505-26.9-24.1
31/32,11/320.9687500000000.343750000000-0.000371-31.6-22.9
31/32,3/80.9687500000000.375000000000-0.012024-31.4-26.1
61/64,3/80.9531250000000.3750000000000.002043-32.5-24.3
61/64,13/320.9531250000000.406250000000-0.009611-31.8-26.6
=====================================================================
附录:C实现代码
/*(代码来源于网络,版权归原作者所有)*/
#include<math.h>
#include<stdio.h>
/*********************************************************************
*
*
*Name:mag_est.c
*
*Synopsis:
*
*Demonstratesandteststhe"Alpha*Min+Beta*Max"magnitude
*estimationalgorithm.
*
*Description:
*
*Thisprogramdemonstratesthe"Alpha,Beta"algorithmfor
*estimatingthemagnitudeofacomplexnumber.Comparedto
*calculatingthemagnitudedirectlyusingsqrt(I^2+Q^2),this
*estimationisveryquick.
*
*VariousvaluesofAlphaandBetacanbeusedtotradeamongRMS
*error,peakerror,andcoefficientcomplexity.Thisprogram
*includesatableofthemostusefulvalues,anditprintsoutthe
*resultingRMSandpeakerrors.
*
*Copyright1999GrantR.Griffin
*
*********************************************************************/
/********************************************************************/
doublealpha_beta_mag(doublealpha,doublebeta,doubleinphase,
doublequadrature)
{
/*magnitude~=alpha*max(|I|,|Q|)+beta*min(|I|,|Q|)*/
doubleabs_inphase=fabs(inphase);
doubleabs_quadrature=fabs(quadrature);
if(abs_inphase>abs_quadrature){
returnalpha*abs_inphase+beta*abs_quadrature;
}else{
returnalpha*abs_quadrature+beta*abs_inphase;
}
}
/*********************************************************************/
doubledecibels(doublelinear)
{
#defineSMALL1e-20
if(linear<=SMALL){
linear=SMALL;
}
return20.0*log10(linear);
}
/*********************************************************************/
voidtest_alpha_beta(char*name,doublealpha,doublebeta,
intnum_points)
{
#definePI3.141592653589793
intii;
doublephase,real,imag,err,avg_err,rms_err;
doublepeak_err=0.0;
doublesum_err=0.0;
doublesum_err_sqrd=0.0;
doubledelta_phase=(2.0*PI)/num_points;
for(ii=0;ii<num_points;ii++){
phase=delta_phase*ii;
real=cos(phase);
imag=sin(phase);
err=sqrt(real*real+imag*imag)
-alpha_beta_mag(alpha,beta,real,imag);
sum_err+=err;
sum_err_sqrd+=err*err;
err=fabs(err);
if(err>peak_err){
peak_err=err;
}
}
avg_err=sum_err/num_points;
rms_err=sqrt(sum_err_sqrd/num_points);
printf("%-16s%14.12lf%14.12lf%9.6lf%4.1lf%4.1lf\n",
name,alpha,beta,avg_err,decibels(rms_err),
decibels(peak_err));
}
/*********************************************************************/
voidmain(void)
{
#defineNUM_CHECK_POINTS100000
typedefstructtagALPHA_BETA{
char*name;
doublealpha;
doublebeta;
}ALPHA_BETA;
#defineNUM_ALPHA_BETA16
constALPHA_BETAcoeff[NUM_ALPHA_BETA]={
{"MinRMSErr",0.947543636291,0.3924854250920},
{"MinPeakErr",0.960433870103,0.3978247347593},
{"MinRMSw/Avg=0",0.948059448969,0.3926990816987},
{"1,MinRMSErr",1.0,0.323260990},
{"1,MinPeakErr",1.0,0.335982538},
{"1,1/2",1.0,1.0/2.0},
{"1,1/4",1.0,1.0/4.0},
{"Frerking",1.0,0.4},
{"1,11/32",1.0,11.0/32.0},
{"1,3/8",1.0,3.0/8.0},
{"15/16,15/32",15.0/16.0,15.0/32.0},
{"15/16,1/2",15.0/16.0,1.0/2.0},
{"31/32,11/32",31.0/32.0,11.0/32.0},
{"31/32,3/8",31.0/32.0,3.0/8.0},
{"61/64,3/8",61.0/64.0,3.0/8.0},
{"61/64,13/32",61.0/64.0,13.0/32.0}
};
intii;
printf("\nAlpha*Max+Beta*MinMagnitude
Estimator\n\n");
printf("NameAlphaBetaAvgErr
RMSPeak\n");
printf("(linear)
(dB)(dB)\n");
printf("---------------------------------------------------------------------\n");
for(ii=0;ii<NUM_ALPHA_BETA;ii++){
test_alpha_beta(coeff[ii].name,coeff[ii].alpha,coeff[ii].beta,
1024);
}
}
相关文章推荐
- 一种高精度复数求模近似算法的设计及实现
- 一种实用的笑脸检测方法
- WinEdt7的一种实用的破解方法
- 一种简单实用的全屏方法
- 关于日间夜间模式切换的一种实用方法
- 一种简单实用的全屏方法
- WinEdt7的一种实用的破解方法
- 本文给出了一种方便实用的解决大文件的读取、存储等处理的方法,并结合相关程序代码对具体的实现过程进行了介绍
- 一种简单实用的全屏方法
- 一种简单实用的全屏方法
- python--selenium一种实用的自动生成测试HTML报告方法--HTMLTestRunner
- 一种简单实用的错误码构建方法
- 实用计算机视觉 -- 一种基于直方图的最优阈值计算方法
- 一种简单实用的全屏方法
- union:一种实用的共用体用法
- 一种上下拉动的实用下拉框
- 开发DSP硬件驱动程序的一种方法
- 一种使用QThread线程的新方法QObject::moveToThread
- 手工添加datagridview数据的一种方法
- 一种不能进行gpu加速的折中方法