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

Dependencies:   mbed

Committer:
MikamiUitOpen
Date:
Thu Feb 04 09:45:09 2021 +0000
Revision:
1:2b596eab04de
Parent:
0:4037028ba61a
2

Who changed what in which revision?

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