AM中波放送用SDR.CICフィルタのみを使用.CQ出版社「トランジスタ技術」誌,2021年5月号に掲載

Dependencies:   mbed

SDR_Library/FastATan.hpp

Committer:
MikamiUitOpen
Date:
2021-03-03
Revision:
1:32d6e3f7df30
Parent:
0:7a653530c8ce

File content as of revision 1:32d6e3f7df30:

//--------------------------------------------------------------
//  高速低精度 arctan 計算
//      係数はミニマックス近似で求めたもの
//      ただし,誤差は絶対誤差で評価した
//
//  2020/08/12, Copyright (c) 2020 MIKAMI, Naoki
//--------------------------------------------------------------

#include "mbed.h"

#ifndef FAST_ARCTAN_LOW_PRECISION_HPP
#define FAST_ARCTAN_LOW_PRECISION_HPP

namespace Mikami
{
    inline float ATanPoly(float x);
    
    // 引数の与え方は,atan2() と同じ
    float FastATan(float y, float x)
    {
        static const float PI    = 3.1415926536f;  // π
        static const float PI_4  = PI/4.0f;        // π/4
        static const float PI3_4 = 3.0f*PI/4.0f;   // 3π/4
        static const float PI_2  = PI/2.0f;        // π/2

        if ( (x == 0.0f) && (y == 0.0f) ) return 0.0f;
        if (y == 0.0f) return (x > 0.0f) ? 0.0f : PI;

        float abs_x = fabsf(x);
        float abs_y = fabsf(y);

        if (abs_x == abs_y)
        {
            if (x > 0.0f) return (y > 0.0f) ?  PI_4 : -PI_4;
            else          return (y > 0.0f) ? PI3_4 : -PI3_4;
        }

        if (abs_x > abs_y)  // |θ|< π/4,3π/4<|θ|<π
        {
            float u = ATanPoly(y/x);
            if (x > 0.0f) return u;
            else          return (y > 0.0f) ? u + PI : u - PI;
        }
        else                // π/4 <|θ|<3π/4
        {
            float u = ATanPoly(x/y);
            return (y > 0.0f) ? -u + PI_2 : -u - PI_2;
        }
    }

    inline float ATanPoly(float x)
    {
        static const float A1 =  0.9992138f;    // a1
        static const float A3 = -0.3211750f;    // a3
        static const float A5 =  0.1462645f;    // a5
        static const float A7 = -0.03898651f;   // a7
        
        float x2 = x*x;
        float atanx = (((A7*x2 + A5)*x2 + A3)*x2 + A1)*x;
        
        return atanx;
    }
}
#endif  // FAST_ARCTAN_LOW_PRECISION_HPP