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