arm_atan2_f16.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  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. #include "dsp/fast_math_functions_f16.h"
  29. #if defined(ARM_FLOAT16_SUPPORTED)
  30. /*
  31. atan for argument between in [0, 1.0]
  32. */
  33. #define PIF16 3.14f16
  34. #define PI16HALF 1.571f16
  35. #define ATANHALFF16 0.463648f16
  36. #define ATAN2_NB_COEFS_F16 5
  37. static const float16_t atan2_coefs_f16[ATAN2_NB_COEFS_F16]={0.f16
  38. ,1.f16
  39. ,0.f16
  40. ,-0.367f16
  41. ,0.152f16
  42. };
  43. __STATIC_FORCEINLINE float16_t arm_atan_limited_f16(float16_t x)
  44. {
  45. float16_t res=atan2_coefs_f16[ATAN2_NB_COEFS_F16-1];
  46. int i=1;
  47. for(i=1;i<ATAN2_NB_COEFS_F16;i++)
  48. {
  49. res = (_Float16)x*(_Float16)res + (_Float16)atan2_coefs_f16[ATAN2_NB_COEFS_F16-1-i];
  50. }
  51. return(res);
  52. }
  53. __STATIC_FORCEINLINE float16_t arm_atan_f16(float16_t x)
  54. {
  55. int sign=0;
  56. float16_t res=0.0f16;
  57. if ((_Float16)x < 0.0f16)
  58. {
  59. sign=1;
  60. x=-(_Float16)x;
  61. }
  62. if ((_Float16)x > 1.0f16)
  63. {
  64. x = 1.0f16 / (_Float16)x;
  65. res = (_Float16)PI16HALF - (_Float16)arm_atan_limited_f16(x);
  66. }
  67. else
  68. {
  69. res += (_Float16)arm_atan_limited_f16(x);
  70. }
  71. if (sign)
  72. {
  73. res = -(_Float16)res;
  74. }
  75. return(res);
  76. }
  77. /**
  78. @ingroup groupFastMath
  79. */
  80. /**
  81. @addtogroup atan2
  82. @{
  83. */
  84. /**
  85. @brief Arc Tangent of y/x using sign of y and x to get right quadrant
  86. @param[in] y y coordinate
  87. @param[in] x x coordinate
  88. @param[out] result Result
  89. @return error status.
  90. @par Compute the Arc tangent of y/x:
  91. The sign of y and x are used to determine the right quadrant
  92. and compute the right angle.
  93. */
  94. arm_status arm_atan2_f16(float16_t y,float16_t x,float16_t *result)
  95. {
  96. if ((_Float16)x > 0.0f16)
  97. {
  98. *result=arm_atan_f16((_Float16)y/(_Float16)x);
  99. return(ARM_MATH_SUCCESS);
  100. }
  101. if ((_Float16)x < 0.0f16)
  102. {
  103. if ((_Float16)y > 0.0f16)
  104. {
  105. *result=(_Float16)arm_atan_f16((_Float16)y/(_Float16)x) + (_Float16)PIF16;
  106. }
  107. else if ((_Float16)y < 0.0f16)
  108. {
  109. *result=(_Float16)arm_atan_f16((_Float16)y/(_Float16)x) - (_Float16)PIF16;
  110. }
  111. else
  112. {
  113. if (signbit(y))
  114. {
  115. *result= -(_Float16)PIF16;
  116. }
  117. else
  118. {
  119. *result= PIF16;
  120. }
  121. }
  122. return(ARM_MATH_SUCCESS);
  123. }
  124. if ((_Float16)x == 0.0f16)
  125. {
  126. if ((_Float16)y > 0.0f16)
  127. {
  128. *result=PI16HALF;
  129. return(ARM_MATH_SUCCESS);
  130. }
  131. if ((_Float16)y < 0.0f16)
  132. {
  133. *result=-(_Float16)PI16HALF;
  134. return(ARM_MATH_SUCCESS);
  135. }
  136. }
  137. return(ARM_MATH_NANINF);
  138. }
  139. #endif /* #if defined(ARM_FLOAT16_SUPPORTED) */
  140. /**
  141. @} end of atan2 group
  142. */