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
arm_atan_limited_f16(float16_t x)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
arm_atan_f16(float16_t x)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 */
arm_atan2_f16(float16_t y,float16_t x,float16_t * result)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 */
172