Math 'atan'函数在不动点上的逼近

Math 'atan'函数在不动点上的逼近,math,microcontroller,trigonometry,atmega,approximation,Math,Microcontroller,Trigonometry,Atmega,Approximation,我必须做一些需要使用三角函数的计算,特别是atanone。代码将在Atmega328p上运行,为了提高效率,我不能使用floats:我使用的是定点数字。因此,我不能使用标准的atan函数 我需要一个函数,该函数以定点格式s16_10(有符号,16位宽度,第10位的点)获取值,并返回s16_6格式。输入将在0和1之间(so 0和210),因此输出(以度为单位)将在-45和45之间(so-45*26和45*26) 假设Y是不动点,Y的s16_6表示,弧的实际角度,x如atan(x)=Y,x是x的s1

我必须做一些需要使用三角函数的计算,特别是
atan
one。代码将在Atmega328p上运行,为了提高效率,我不能使用
float
s:我使用的是定点数字。因此,我不能使用标准的
atan
函数

我需要一个函数,该函数以定点格式s16_10(有符号,16位宽度,第10位的点)获取值,并返回s16_6格式。输入将在0和1之间(so 0和210),因此输出(以度为单位)将在-45和45之间(so-45*26和45*26)

假设Y是不动点,Y的s16_6表示,弧的实际角度,x如
atan(x)=Y
,x是x的s16_10表示。我首先用四次多项式将
atan
函数从(0,1)近似到(-45,45),发现我们可以使用:

y ~= 8.11 * x^4 - 19.67 * x^3 - 0.93 * x^2 + 57.52 * x + 0.0096
这导致:

Y ~= (8.11 * X^4)/2^34 - (19.62* X^3)/2^24 - (0.93 * X^2)/2^14 + (57.52*X)/2^4 + 0.0069 * 2^6

我被困在这里。。。一方面,计算
X^4
将导致定义间隔的五分之一为0,另一方面,{3,2,1}中的2n4n通常也将导致零值。。。我该怎么办?

有些术语被截断为零并不一定是一场灾难;这并不会严重恶化您的近似值。我在Matlab中模拟了固定精度设置,将多项式的每个项舍入为最接近的整数:

q4 = @(X) round((8.11 * X.^4)/2^34);
q3 = @(X) -round((19.62* X.^3)/2^24);
q2 = @(X) -round((0.93 * X.^2)/2^14);
q1 = @(X) round((57.52*X)/2^4);
q0 = @(X) round(0.0069 * 2^6);
诚然,在区间[0210]的前五分之一处,第四季度、第三季度、第二季度的数据看起来相当波动,而第四季度基本上不存在

但是这些舍入效应的大小与多项式逼近atan的理论误差大致相同。下图中,红色表示不舍入为整数计算的差值(多项式atan),绿色表示差值(q4+q3+q2+q1+q0 atan):

正如您所看到的,舍入并不会使近似值变得更糟;在大多数情况下,它实际上通过一次愉快的意外减少了错误


我注意到你的多项式系统地高估了atan。当我用Matlab将一个四次多项式拟合到[0,1]上的atan时,系数略有不同:

8.0927  -19.6568   -0.9257   57.5106   -0.0083
即使将它们截断为两个有效数字,正如您所做的,我也得到了一个更好的近似值:

(8.09 * X^4)/2^34 - (19.66* X^3)/2^24 - (0.93 * X^2)/2^14 + (57.52*X)/2^4 - 0.0083 * 2^6


这一次,对整数的截断确实使情况恶化。但可以预期,如果将多个中间结果四舍五入为整数,则计算结果将减少+-2左右。该多项式所示的+-0.5的理论精度无法用给定的算术工具实现

最后一句中可能有拼写错误(“另一方面,2n4通常也会导致错误”)-请澄清。另外,当某个中间结果为0时,为什么这是一个问题?还有,你必须使用泰勒级数吗?没有哪一种可能更有效;我从未听说过Atmega328p,因此无法确定哪种算法更好。@Anatolig为了清晰起见,我编辑了答案!这是一个问题,因为前三名成员始终为零。。。我找不到一个不使变量为零的近似值。我不知道这是泰勒系列,但我会看看CORDIC算法你用的是
\u Accum
还是自定义类型?我用的是
typedef int16\u fixed 16\u p
其中p是点的位置