用MATLAB找出三角函数的Minimax多项式逼近

我试图用MATLAB中的remez交换算法找到正弦和余弦的最小多项式近似。 由于我正在为IEEE-754浮点实现正弦和余弦函数,因此需要精确到23位。

在这里使用这个链接(参考第8页到第15页),给出了使用Mathematica和Maple查找多项式的说明,但是我不确定如何推断这些MATLAB的方法。

根据表3,我需要使用5或6阶多项式来获得〜23位(小数点后)的精度。

我打算首先将所有进入的theta的范围缩小到-pi / 4到+ pi / 4之间,然后根据需要执行正弦或余弦函数(最终目标是实现exp(i * x)= cos x)+ i * sin(x)。

我可能会自己按照本文的说明操作,但我不知道如何在这里使用remez函数来达到我的目的。 另外,我没有关注为什么作者使用方程(6)(第9页),也不知道k的方程(第11页)是如何确定的(2796201是从哪里来的?),为什么定义形式的多项式,我们希望最终变化为sin9x)= x + kx ^ 3 + x ^ 5 * P(x ^ 2)。

使用firpm函数会更好吗(因为remez已被弃用)?

非常感谢您的帮助和指导,以及对我的问题进行编辑以确保可能的最佳答案。


我不打算试图开发你自己的近似值。 更简单的是拿起一份“计算机近似”,Hart等人。 一个好的大学图书馆应该有它。 23位是大约7位十进制数字,所以只需选择一个近似值即可获得所需的精度。 你可以选择一个简单的多项式近似,或者使用一个有理多项式,通常稍微好一点,只要你可以容忍除法。

减少范围确实有意义,事实上,我在我自己的工具中选择了相同的范围(+/- pi / 4),因为此范围选择特别容易处理。

编辑:(使用Hart可以找到的近似值的例子)

在这里,我会找到sin(x)的近似值,其中x位于区间[0,pi / 4]中。 我的目标是在该区间内选择绝对精度至少为1.e-7的近似值。 当然,如果你对x有负值,我们知道sin(x)是一个奇函数,所以这是微不足道的。

我注意到Hart中的近似值倾向于sin(alphapix),其中x位于区间[0,1]中。 如果我然后选择α= 1/2的近似值,我会得到一个在选定区间内有效的近似值。 因此,对于区间[0,pi / 4]的近似值,我们寻找alpha = 1/4。

接下来,我寻找一个近似值,表明绝对精度至少为7位数,我宁愿使用有理多项式近似值,因为它们往往更有效一些。 扫描第118页的表格(我的Hart的副本是从1978年开始的),我找到了一个近似值,alpha = 1/4,符合法案:索引3060。

这种近似将是形式

sin(alpha*pi*x) = x*P(x^2)/Q(x^2)

因此,现在我选择页面,给出SIN 3060的系数。在我的副本中,它位于199-200页。 有5个系数,P00,P01,P02,Q00,Q01。 (注意这里使用的有些非标准的科学记数法。)因此,P(分子多项式)有3项,而Q(分母有2项)。 写出来,我得到这个:

sin(alpha*pi*x) = (52.81860134812 -4.644800481954*x^3 + 0.0867545069521*x^5)/ ...
    (67.250731777791 + x^2)

让我们现在在MATLAB中尝试它。

x = linspace(0,pi/4,10001);
xt = x*4/pi; % transform to [0,1]
sine = @(x) (52.81860134812*x -4.644800481954*x.^3 + ...
     0.0867545069521*x.^5)./(67.250731777791 + x.^2);

max(abs(sin(x) -sine(xt)))
ans =
   1.6424e-09

plot(x,sin(x)- sine(xt),'-')

[0,pi / 4]上的sin近似的误差

请注意附加到y轴的1e-9。

看起来这是在特定的时间间隔内对sin(x)进行近似的最合理的选择,尽管这给出了大约29位的精确度,而不是你要求的23位。 如果你愿意选择一个不同的范围缩减间隔,有几个选择可以节省一个术语,可能需要几个比特的费用,而你不需要。

log2(max(abs(sin(x) -sine(xt))))
ans =
      -29.182
链接地址: http://www.djcxy.com/p/85591.html

上一篇: Using MATLAB to find Minimax Polynomial Approximation of Trigonometric Functions

下一篇: point math consistent in C#? Can it be?