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

Dependencies:   mbed

Committer:
MikamiUitOpen
Date:
Sat Aug 29 11:26:29 2020 +0000
Revision:
0:7a653530c8ce
1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:7a653530c8ce 1 //--------------------------------------------------------------
MikamiUitOpen 0:7a653530c8ce 2 // 高速低精度 arctan 計算
MikamiUitOpen 0:7a653530c8ce 3 // 係数はミニマックス近似で求めたもの
MikamiUitOpen 0:7a653530c8ce 4 // ただし,誤差は絶対誤差で評価した
MikamiUitOpen 0:7a653530c8ce 5 //
MikamiUitOpen 0:7a653530c8ce 6 // 2020/08/12, Copyright (c) 2020 MIKAMI, Naoki
MikamiUitOpen 0:7a653530c8ce 7 //--------------------------------------------------------------
MikamiUitOpen 0:7a653530c8ce 8
MikamiUitOpen 0:7a653530c8ce 9 #include "mbed.h"
MikamiUitOpen 0:7a653530c8ce 10
MikamiUitOpen 0:7a653530c8ce 11 #ifndef FAST_ARCTAN_LOW_PRECISION_HPP
MikamiUitOpen 0:7a653530c8ce 12 #define FAST_ARCTAN_LOW_PRECISION_HPP
MikamiUitOpen 0:7a653530c8ce 13
MikamiUitOpen 0:7a653530c8ce 14 namespace Mikami
MikamiUitOpen 0:7a653530c8ce 15 {
MikamiUitOpen 0:7a653530c8ce 16 inline float ATanPoly(float x);
MikamiUitOpen 0:7a653530c8ce 17
MikamiUitOpen 0:7a653530c8ce 18 // 引数の与え方は,atan2() と同じ
MikamiUitOpen 0:7a653530c8ce 19 float FastATan(float y, float x)
MikamiUitOpen 0:7a653530c8ce 20 {
MikamiUitOpen 0:7a653530c8ce 21 static const float PI = 3.1415926536f; // π
MikamiUitOpen 0:7a653530c8ce 22 static const float PI_4 = PI/4.0f; // π/4
MikamiUitOpen 0:7a653530c8ce 23 static const float PI3_4 = 3.0f*PI/4.0f; // 3π/4
MikamiUitOpen 0:7a653530c8ce 24 static const float PI_2 = PI/2.0f; // π/2
MikamiUitOpen 0:7a653530c8ce 25
MikamiUitOpen 0:7a653530c8ce 26 if ( (x == 0.0f) && (y == 0.0f) ) return 0.0f;
MikamiUitOpen 0:7a653530c8ce 27 if (y == 0.0f) return (x > 0.0f) ? 0.0f : PI;
MikamiUitOpen 0:7a653530c8ce 28
MikamiUitOpen 0:7a653530c8ce 29 float abs_x = fabsf(x);
MikamiUitOpen 0:7a653530c8ce 30 float abs_y = fabsf(y);
MikamiUitOpen 0:7a653530c8ce 31
MikamiUitOpen 0:7a653530c8ce 32 if (abs_x == abs_y)
MikamiUitOpen 0:7a653530c8ce 33 {
MikamiUitOpen 0:7a653530c8ce 34 if (x > 0.0f) return (y > 0.0f) ? PI_4 : -PI_4;
MikamiUitOpen 0:7a653530c8ce 35 else return (y > 0.0f) ? PI3_4 : -PI3_4;
MikamiUitOpen 0:7a653530c8ce 36 }
MikamiUitOpen 0:7a653530c8ce 37
MikamiUitOpen 0:7a653530c8ce 38 if (abs_x > abs_y) // |θ|< π/4,3π/4<|θ|<π
MikamiUitOpen 0:7a653530c8ce 39 {
MikamiUitOpen 0:7a653530c8ce 40 float u = ATanPoly(y/x);
MikamiUitOpen 0:7a653530c8ce 41 if (x > 0.0f) return u;
MikamiUitOpen 0:7a653530c8ce 42 else return (y > 0.0f) ? u + PI : u - PI;
MikamiUitOpen 0:7a653530c8ce 43 }
MikamiUitOpen 0:7a653530c8ce 44 else // π/4 <|θ|<3π/4
MikamiUitOpen 0:7a653530c8ce 45 {
MikamiUitOpen 0:7a653530c8ce 46 float u = ATanPoly(x/y);
MikamiUitOpen 0:7a653530c8ce 47 return (y > 0.0f) ? -u + PI_2 : -u - PI_2;
MikamiUitOpen 0:7a653530c8ce 48 }
MikamiUitOpen 0:7a653530c8ce 49 }
MikamiUitOpen 0:7a653530c8ce 50
MikamiUitOpen 0:7a653530c8ce 51 inline float ATanPoly(float x)
MikamiUitOpen 0:7a653530c8ce 52 {
MikamiUitOpen 0:7a653530c8ce 53 static const float A1 = 0.9992138f; // a1
MikamiUitOpen 0:7a653530c8ce 54 static const float A3 = -0.3211750f; // a3
MikamiUitOpen 0:7a653530c8ce 55 static const float A5 = 0.1462645f; // a5
MikamiUitOpen 0:7a653530c8ce 56 static const float A7 = -0.03898651f; // a7
MikamiUitOpen 0:7a653530c8ce 57
MikamiUitOpen 0:7a653530c8ce 58 float x2 = x*x;
MikamiUitOpen 0:7a653530c8ce 59 float atanx = (((A7*x2 + A5)*x2 + A3)*x2 + A1)*x;
MikamiUitOpen 0:7a653530c8ce 60
MikamiUitOpen 0:7a653530c8ce 61 return atanx;
MikamiUitOpen 0:7a653530c8ce 62 }
MikamiUitOpen 0:7a653530c8ce 63 }
MikamiUitOpen 0:7a653530c8ce 64 #endif // FAST_ARCTAN_LOW_PRECISION_HPP