在微控制器上逼近两个平方和的平方根

时间:2011-04-03 05:30:40

标签: assembly signal-processing microcontroller numerical-methods

我正在努力在8位微控制器(HCS08)上组装FFT算法。一旦算法完成,我将有一个8位实/虚对的数组,我想找到每个值的大小。也就是说,如果 x 很复杂,我想找到

|x| = sqrt(Re{x}^2 + Im{x}^2)  

现在我可以使用16位寄存器和8位寄存器。我想到只是对它们进行平方,添加它们,并取结果的平方根,但这会产生一个问题:两个8位数的平方和的最大可能值为~130k,大于16位寄存器可以容纳的最大值(65.5k)。

我想出了一个子程序,它计算一个16位数的整数平方根,这似乎运行良好,但显然我不能保证使用适合16位的值。我现在的想法是,有一种算法能够直接逼近我需要的算法,但我似乎找不到任何东西。任何想法将不胜感激。

总结一下:假设我有一个带有两个8位分量的向量,我想找到向量的长度。如何在不实际计算平方和平方根的情况下对其进行近似计算?

谢谢!

6 个答案:

答案 0 :(得分:6)

有一个描述Fast Magnitude Estimator的网页。基本思想是使方程符合最小二乘(或其他高质量):

Mag ~= Alpha * max(|I|, |Q|) + Beta * min(|I|, |Q|)

表示系数Alpha和Beta。列出了几个系数对,其中包括均方误差,最大误差等,包括适用于整数ALU的系数。

答案 1 :(得分:3)

如果总和大于65535,则将其除以4(右移2位),取平方根,然后乘以2.您将失去一位精度,当然结果不能保证适合8位。

答案 2 :(得分:0)

好吧,你可以写极性形式的x:

x = r[cos(w) + i sin(w)]

其中w = arctan(Im(x)/Re(x)),所以

|x| = r = Re(x)/cos(w)

这里没有大数字,但也许你会失去三角函数的精确度(也就是说,如果你可以访问三角函数: - /)

答案 3 :(得分:0)

一种廉价而肮脏的方法,可能适用也可能不适合使用

|x| ~ max(|Re{x}|,|Im{x}|) + min(|Re{x}|,|Im{x})/2;

这往往会高估| x |在0到12%之间。

答案 4 :(得分:0)

如果您随后要将幅度转换为dB,那么您将完全取消sqrt操作。即如果你的计算是:

magnitude = sqrt(re*re+im*im); // calculate magnitude of complex FFT output value
magnitude_dB = 20*log10(magnitude); // convert magnitude to dB

您可以将其重写为:

magnitude_sq = re*re+im*im; // calculate squared magnitude of complex FFT output value
magnitude_dB = 10*log10(magnitude_sq);  // convert squared magnitude to dB

答案 5 :(得分:0)

您可能只受限于2个寄存器,但您可以在http://www.realitypixels.com/turk/opensource/index.html查看此代码 固定点平方根 使用CORDIC的定点三角函数