1 /* ----------------------------------------------------------------------
2 * Project: CMSIS DSP Library
3 * Title: arm_absmin_no_idx_f32.c
4 * Description: Minimum value of absolute values of a floating-point vector
5 *
6 * $Date: 16 November 2021
7 * $Revision: V1.10.0
8 *
9 * Target Processor: Cortex-M and Cortex-A cores
10 * -------------------------------------------------------------------- */
11 /*
12 * Copyright (C) 2010-2021 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/statistics_functions.h"
30
31 #if (defined(ARM_MATH_NEON) || defined(ARM_MATH_MVEF)) && !defined(ARM_MATH_AUTOVECTORIZE)
32 #include <limits.h>
33 #endif
34
35
36 /**
37 @ingroup groupStats
38 */
39
40
41 /**
42 @addtogroup AbsMin
43 @{
44 */
45
46 /**
47 @brief Minimum value of absolute values of a floating-point vector.
48 @param[in] pSrc points to the input vector
49 @param[in] blockSize number of samples in input vector
50 @param[out] pResult minimum value returned here
51 */
52
53 #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
54
55 #include "arm_helium_utils.h"
arm_absmin_no_idx_f32(const float32_t * pSrc,uint32_t blockSize,float32_t * pResult)56 ARM_DSP_ATTRIBUTE void arm_absmin_no_idx_f32(
57 const float32_t * pSrc,
58 uint32_t blockSize,
59 float32_t * pResult)
60 {
61 int32_t blkCnt; /* loop counters */
62 f32x4_t vecSrc;
63 float32_t const *pSrcVec;
64 f32x4_t curExtremValVec = vdupq_n_f32(F32_ABSMAX);
65 float32_t minValue = F32_ABSMAX;
66 mve_pred16_t p0;
67
68
69 pSrcVec = (float32_t const *) pSrc;
70 blkCnt = blockSize >> 2;
71 while (blkCnt > 0)
72 {
73 vecSrc = vldrwq_f32(pSrcVec);
74 pSrcVec += 4;
75 /*
76 * update per-lane min.
77 */
78 curExtremValVec = vminnmaq(vecSrc, curExtremValVec);
79 /*
80 * Decrement the blockSize loop counter
81 */
82 blkCnt--;
83 }
84 /*
85 * tail
86 * (will be merged thru tail predication)
87 */
88 blkCnt = blockSize & 3;
89 if (blkCnt > 0)
90 {
91 vecSrc = vldrwq_f32(pSrcVec);
92 pSrcVec += 4;
93 p0 = vctp32q(blkCnt);
94 /*
95 * Get current min per lane and current index per lane
96 * when a min is selected
97 */
98 curExtremValVec = vminnmaq_m(curExtremValVec, vecSrc, p0);
99 }
100 /*
101 * Get min value across the vector
102 */
103 minValue = vminnmavq(minValue, curExtremValVec);
104 *pResult = minValue;
105 }
106
107 #else
108 #if defined(ARM_MATH_LOOPUNROLL)
arm_absmin_no_idx_f32(const float32_t * pSrc,uint32_t blockSize,float32_t * pResult)109 ARM_DSP_ATTRIBUTE void arm_absmin_no_idx_f32(
110 const float32_t * pSrc,
111 uint32_t blockSize,
112 float32_t * pResult)
113 {
114 float32_t cur_absmin, out; /* Temporary variables to store the output value. */\
115 uint32_t blkCnt; /* Loop counter */ \
116 \
117 \
118 /* Load first input value that act as reference value for comparision */ \
119 out = *pSrc++; \
120 out = (out > 0.0f) ? out : -out; \
121 \
122 \
123 /* Loop unrolling: Compute 4 outputs at a time */ \
124 blkCnt = (blockSize - 1U) >> 2U; \
125 \
126 while (blkCnt > 0U) \
127 { \
128 /* Initialize cur_absmin to next consecutive values one by one */ \
129 cur_absmin = *pSrc++; \
130 cur_absmin = (cur_absmin > 0.0f) ? cur_absmin : -cur_absmin; \
131 /* compare for the extrema value */ \
132 if (cur_absmin < out) \
133 { \
134 /* Update the extrema value and it's index */ \
135 out = cur_absmin; \
136 } \
137 \
138 cur_absmin = *pSrc++; \
139 cur_absmin = (cur_absmin > 0.0f) ? cur_absmin : -cur_absmin; \
140 if (cur_absmin < out) \
141 { \
142 out = cur_absmin; \
143 } \
144 \
145 cur_absmin = *pSrc++; \
146 cur_absmin = (cur_absmin > 0.0f) ? cur_absmin : -cur_absmin; \
147 if (cur_absmin < out) \
148 { \
149 out = cur_absmin; \
150 } \
151 \
152 cur_absmin = *pSrc++; \
153 cur_absmin = (cur_absmin > 0.0f) ? cur_absmin : -cur_absmin; \
154 if (cur_absmin < out) \
155 { \
156 out = cur_absmin; \
157 } \
158 \
159 \
160 /* Decrement loop counter */ \
161 blkCnt--; \
162 } \
163 \
164 /* Loop unrolling: Compute remaining outputs */ \
165 blkCnt = (blockSize - 1U) % 4U; \
166 \
167 \
168 while (blkCnt > 0U) \
169 { \
170 cur_absmin = *pSrc++; \
171 cur_absmin = (cur_absmin > 0.0f) ? cur_absmin : -cur_absmin; \
172 if (cur_absmin < out) \
173 { \
174 out = cur_absmin; \
175 } \
176 \
177 /* Decrement loop counter */ \
178 blkCnt--; \
179 } \
180 \
181 /* Store the extrema value and it's index into destination pointers */ \
182 *pResult = out; \
183 }
184 #else
arm_absmin_no_idx_f32(const float32_t * pSrc,uint32_t blockSize,float32_t * pResult)185 ARM_DSP_ATTRIBUTE void arm_absmin_no_idx_f32(
186 const float32_t * pSrc,
187 uint32_t blockSize,
188 float32_t * pResult)
189 {
190 float32_t minVal, out; /* Temporary variables to store the output value. */
191 uint32_t blkCnt; /* Loop counter */
192
193
194
195 /* Load first input value that act as reference value for comparision */
196 out = fabsf(*pSrc++);
197
198 /* Initialize blkCnt with number of samples */
199 blkCnt = (blockSize - 1U);
200
201 while (blkCnt > 0U)
202 {
203 /* Initialize minVal to the next consecutive values one by one */
204 minVal = fabsf(*pSrc++);
205
206 /* compare for the minimum value */
207 if (out > minVal)
208 {
209 /* Update the minimum value and it's index */
210 out = minVal;
211 }
212
213 /* Decrement loop counter */
214 blkCnt--;
215 }
216
217 /* Store the minimum value and it's index into destination pointers */
218 *pResult = out;
219 }
220
221 #endif /* defined(ARM_MATH_LOOPUNROLL) */
222 #endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
223 /**
224 @} end of AbsMin group
225 */
226