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

Dependencies:   mbed

Revision:
1:30d9fb51dec1
Child:
2:4bec6b2be809
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDR_Library/FastATan.hpp	Mon Sep 23 07:32:10 2019 +0000
@@ -0,0 +1,77 @@
+//--------------------------------------------------------------
+//  高速低精度 arctan 計算
+//      係数はミニマックス近似で求めたもの
+//      ただし,誤差は絶対誤差で評価した
+//
+//  2019/09/18, Copyright (c) 2019 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)
+        {
+            if (x > 0.0f) return 0.0f;      // 0
+            else          return PI;        // π
+        }
+        float abs_x = fabsf(x);
+        float abs_y = fabsf(y);
+
+        if (abs_x == abs_y)
+        {
+            if (x > 0.0f)
+            {
+                if (y > 0.0f) return PI_4;  // π/4
+                else          return -PI_4; // -π/4
+            }
+            else
+            {
+                if (y > 0.0f) return PI3_4;  // 3π/4
+                else          return -PI3_4; // -3π/4
+            }
+        }
+
+        if (abs_x > abs_y)  // |θ|< π/4,3π/4<|θ|<π
+        {
+            float u = ATanPoly(y/x);
+            if (x > 0.0f) return u;
+            if (y > 0.0f) return u + PI;
+            else          return u - PI;
+        }
+        else                // π/4 <|θ|<3π/4
+        {
+            float u = ATanPoly(x/y);
+            if (y > 0.0f) return -u + PI_2;
+            else          return -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