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

Dependencies:   mbed

Committer:
MikamiUitOpen
Date:
Sat Aug 29 11:19:03 2020 +0000
Revision:
2:4bec6b2be809
Parent:
1:30d9fb51dec1
3

Who changed what in which revision?

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