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 */