您的位置:首页 > 其它

一种复数求模的实用方法

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,也能得到很不错的结果。



=====================================================================

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);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: