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

Dependencies:   mbed

Committer:
MikamiUitOpen
Date:
Wed Dec 01 00:53:09 2021 +0000
Revision:
2:63fbcf115b88
Parent:
0:9c28f5905a1a
3

Who changed what in which revision?

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