/ Drivers / CMSIS / DSP / Source / FastMathFunctions / arm_atan2_f16.c
arm_atan2_f16.c
  1  /* ----------------------------------------------------------------------
  2   * Project:      CMSIS DSP Library
  3   * Title:        arm_atan2_f16.c
  4   * Description:  float16 Arc tangent of y/x
  5   *
  6   * $Date:        22 April 2022
  7   * $Revision:    V1.10.0
  8   *
  9   * Target Processor: Cortex-M and Cortex-A cores
 10   * -------------------------------------------------------------------- */
 11  /*
 12   * Copyright (C) 2010-2022 ARM Limited or its affiliates. All rights reserved.
 13   *
 14   * SPDX-License-Identifier: Apache-2.0
 15   *
 16   * Licensed under the Apache License, Version 2.0 (the License); you may
 17   * not use this file except in compliance with the License.
 18   * You may obtain a copy of the License at
 19   *
 20   * www.apache.org/licenses/LICENSE-2.0
 21   *
 22   * Unless required by applicable law or agreed to in writing, software
 23   * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 24   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 25   * See the License for the specific language governing permissions and
 26   * limitations under the License.
 27   */
 28  
 29  #include "dsp/fast_math_functions_f16.h"        
 30  
 31  #if defined(ARM_FLOAT16_SUPPORTED)
 32  
 33  /*
 34  
 35  atan for argument between in [0, 1.0]
 36  
 37  
 38  */
 39  
 40  #define PIF16 3.14f16
 41  #define PI16HALF 1.571f16
 42  
 43  #define ATANHALFF16 0.463648f16
 44  
 45  #define ATAN2_NB_COEFS_F16 5
 46  
 47  static const float16_t atan2_coefs_f16[ATAN2_NB_COEFS_F16]={0.f16
 48  ,1.f16
 49  ,0.f16
 50  ,-0.367f16
 51  ,0.152f16
 52  };
 53  
 54  __STATIC_FORCEINLINE float16_t arm_atan_limited_f16(float16_t x)
 55  {
 56      float16_t res=atan2_coefs_f16[ATAN2_NB_COEFS_F16-1];
 57      int i=1;
 58      for(i=1;i<ATAN2_NB_COEFS_F16;i++)
 59      {
 60          res = (_Float16)x*(_Float16)res + (_Float16)atan2_coefs_f16[ATAN2_NB_COEFS_F16-1-i];
 61      }
 62  
 63  
 64      return(res);
 65  }
 66  
 67  __STATIC_FORCEINLINE float16_t arm_atan_f16(float16_t x)
 68  {
 69     int sign=0;
 70     float16_t res=0.0f16;
 71  
 72     if ((_Float16)x < 0.0f16)
 73     {
 74        sign=1;
 75        x=-(_Float16)x;
 76     }
 77  
 78     if ((_Float16)x > 1.0f16)
 79     {
 80        x = 1.0f16 / (_Float16)x;
 81        res = (_Float16)PI16HALF - (_Float16)arm_atan_limited_f16(x);
 82     }
 83     else
 84     {
 85       res += (_Float16)arm_atan_limited_f16(x);
 86     }
 87  
 88  
 89     if (sign)
 90     {
 91       res = -(_Float16)res;
 92     }
 93  
 94     return(res);
 95  }
 96  
 97  /**
 98    @ingroup groupFastMath
 99   */
100  
101  
102  /**
103    @addtogroup atan2
104    @{
105   */
106  
107  /**
108    @brief       Arc Tangent of y/x using sign of y and x to get right quadrant
109    @param[in]   y  y coordinate
110    @param[in]   x  x coordinate
111    @param[out]  result  Result
112    @return  error status.
113   
114    @par         Compute the Arc tangent of y/x:
115                     The sign of y and x are used to determine the right quadrant
116                     and compute the right angle.
117  
118  */
119  arm_status arm_atan2_f16(float16_t y,float16_t x,float16_t *result)
120  {
121      if ((_Float16)x > 0.0f16)
122      {
123          *result=arm_atan_f16((_Float16)y/(_Float16)x);
124          return(ARM_MATH_SUCCESS);
125      }
126      if ((_Float16)x < 0.0f16)
127      {
128          if ((_Float16)y > 0.0f16)
129          {
130             *result=(_Float16)arm_atan_f16((_Float16)y/(_Float16)x) + (_Float16)PIF16;
131          }
132          else if ((_Float16)y < 0.0f16)
133          {
134             *result=(_Float16)arm_atan_f16((_Float16)y/(_Float16)x) - (_Float16)PIF16;
135          }
136          else
137          {
138              if (signbit(y))
139              {
140                 *result= -(_Float16)PIF16;
141              }
142              else
143              {
144                 *result= PIF16;
145              }
146          }
147          return(ARM_MATH_SUCCESS);
148      }
149      if ((_Float16)x == 0.0f16)
150      {
151          if ((_Float16)y > 0.0f16)
152          {
153              *result=PI16HALF;
154              return(ARM_MATH_SUCCESS);
155          }
156          if ((_Float16)y < 0.0f16)
157          {
158              *result=-(_Float16)PI16HALF;
159              return(ARM_MATH_SUCCESS);
160          }
161      }
162      
163  
164      return(ARM_MATH_NANINF);
165  
166  }
167  
168  #endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
169  /**
170    @} end of atan2 group
171   */