当前位置: 主页 > 程序 >

atan函数优化

时间:2021-10-09  作者:haden   点击:
【摘要】有没有考虑过C/C++函数中三角函数是如何计算出来的呢? 三角函数原理: 数学书告诉我们任何函数都可以通过泰勒展开找到近似解。常见三角函数的泰勒展开如下: 实现代码为: //以

有没有考虑过C/C++函数中三角函数是如何计算出来的呢?

三角函数原理:

数学书告诉我们任何函数都可以通过泰勒展开找到近似解。常见三角函数的泰勒展开如下:

实现代码为:

//以sin()为例
int main (void)
{
        int n;
        float x, term ,sum;
        n=1;
        printf("Enter a number x : ");
        scanf("%f",&x);    //输入值
        term = sum = x;
        do {
                n+=2;
                term *=(-x * x)/((float)(n)-1)/(float)(n);  //阶乘过程存储
                sum +=term; //计算多项式值
        } while ( fabs(term)>=1e-8); //满足精度跳出循环
        printf("sin(%f) = %f",x,sum); //结果输出,单位弧度
        return 0;
}

atan优化:

为了加速计算过程,可以使用多项式逼近的方法进行优化。
根据,可以将计算范围缩小到[0, pi/2]。即区3的值可以通过区2和区1值经过变换得到。
根据,可以将计算范围缩小到[0, pi/4]。即区2值可以通过区1值经过变换得到。

根据多项式近似
根据Remez算法或者切比雪夫近似可以得到pn的参数值。这里不在具体介绍,可以参考https://en.wikipedia.org/wiki/Remez_algorithm
根据Remez算法得到的程序实例:

a := min (|x|, |y|) / max (|x|, |y|)
s := a * a
r := ((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a
if |y| > |x| then r := 1.57079637 - r
if x < 0 then r := 3.14159274 - r
if y < 0 then r := -r

以下是OpenCV的计算源码,位置在 opencv/sources/modules/core/src/mathfuncs.cpp 文件中。

static const float atan2_p1 = 0.9997878412794807f*(float)(180/CV_PI);
static const float atan2_p3 = -0.3258083974640975f*(float)(180/CV_PI);
static const float atan2_p5 = 0.1555786518463281f*(float)(180/CV_PI);
static const float atan2_p7 = -0.04432655554792128f*(float)(180/CV_PI);

float fastAtan2( float y, float x )
{
    float ax = std::abs(x), ay = std::abs(y);  //区域3转为区2和区1
    float a, c, c2;
    if( ax >= ay )
    {
        //区1计算方法
        c = ay/(ax + (float)DBL_EPSILON);
        c2 = c*c;
        a = (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c;
    }
    else
    {
        //区2计算方法
        c = ax/(ay + (float)DBL_EPSILON);
        c2 = c*c;
        a = 90.f - (((atan2_p7*c2 + atan2_p5)*c2 + atan2_p3)*c2 + atan2_p1)*c;
    }
    if( x < 0 )
        a = 180.f - a;
    if( y < 0 )
        a = 360.f - a;
    return a;
}

可以看到稍微是有点区别的,两种方法和标准方法的误差图如下,红色是第一种方法误差图,蓝色线是OpenCV使用的误差结果,可以看出,OpenCV的拟合效果略优。

顶一下
(3)
100%
踩一下
(0)
0%
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
验证码: 点击我更换图片

推荐内容