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