|
- /* ----------------------------------------------------------------------
- * Project: CMSIS DSP Library
- * Title: arm_absmax_f32.c
- * Description: Maximum value of absolute values of a floating-point vector
- *
- * $Date: 23 April 2021
- * $Revision: V1.9.0
- *
- * Target Processor: Cortex-M and Cortex-A cores
- * -------------------------------------------------------------------- */
- /*
- * Copyright (C) 2010-2021 ARM Limited or its affiliates. All rights reserved.
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the License); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- #include "dsp/statistics_functions.h"
- #if (defined(ARM_MATH_NEON) || defined(ARM_MATH_MVEF)) && !defined(ARM_MATH_AUTOVECTORIZE)
- #include <limits.h>
- #endif
-
- /**
- @ingroup groupStats
- */
-
- /**
- @defgroup AbsMax Absolute Maximum
-
- Computes the maximum value of absolute values of an array of data.
- The function returns both the maximum value and its position within the array.
- There are separate functions for floating-point, Q31, Q15, and Q7 data types.
- */
-
- /**
- @addtogroup AbsMax
- @{
- */
-
- /**
- @brief Maximum value of absolute values of a floating-point vector.
- @param[in] pSrc points to the input vector
- @param[in] blockSize number of samples in input vector
- @param[out] pResult maximum value returned here
- @param[out] pIndex index of maximum value returned here
- @return none
- */
- #if defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE)
-
- #include "arm_helium_utils.h"
-
- void arm_absmax_f32(
- const float32_t * pSrc,
- uint32_t blockSize,
- float32_t * pResult,
- uint32_t * pIndex)
- {
- int32_t blkSize = blockSize;
- f32x4_t vecSrc;
- f32x4_t curExtremValVec = vdupq_n_f32(F32_ABSMIN);
- float32_t maxValue = F32_ABSMIN;
- uint32_t idx = blockSize;
- uint32x4_t indexVec;
- uint32x4_t curExtremIdxVec;
- uint32_t curIdx = 0;
- mve_pred16_t p0;
-
-
- indexVec = vidupq_wb_u32(&curIdx, 1);
- curExtremIdxVec = vdupq_n_u32(0);
-
- do {
- mve_pred16_t p = vctp32q(blkSize);
-
- vecSrc = vldrwq_z_f32((float32_t const *) pSrc, p);
- vecSrc = vabsq_m(vuninitializedq_f32(), vecSrc, p);
- /*
- * Get current max per lane and current index per lane
- * when a max is selected
- */
- p0 = vcmpgeq_m(vecSrc, curExtremValVec, p);
- curExtremValVec = vpselq(vecSrc, curExtremValVec, p0);
- curExtremIdxVec = vpselq(indexVec, curExtremIdxVec, p0);
-
- /* Does TP detection works here ?? */
- indexVec = vidupq_wb_u32(&curIdx, 1);
-
- blkSize -= 4;
- pSrc += 4;
- }
- while (blkSize > 0);
-
- /*
- * Get max value across the vector
- */
- maxValue = vmaxnmvq(maxValue, curExtremValVec);
- /*
- * set index for lower values to max possible index
- */
- p0 = vcmpgeq(curExtremValVec, maxValue);
- indexVec = vpselq(curExtremIdxVec, vdupq_n_u32(blockSize), p0);
- /*
- * Get min index which is thus for a max value
- */
- idx = vminvq(idx, indexVec);
- /*
- * Save result
- */
- *pIndex = idx;
- *pResult = maxValue;
- }
-
-
- #else
- #if defined(ARM_MATH_LOOPUNROLL)
- void arm_absmax_f32(
- const float32_t * pSrc,
- uint32_t blockSize,
- float32_t * pResult,
- uint32_t * pIndex)
- {
- float32_t cur_absmax, out; /* Temporary variables to store the output value. */\
- uint32_t blkCnt, outIndex; /* Loop counter */ \
- uint32_t index; /* index of maximum value */ \
- \
- /* Initialize index value to zero. */ \
- outIndex = 0U; \
- /* Load first input value that act as reference value for comparision */ \
- out = *pSrc++; \
- out = (out > 0.0f) ? out : -out; \
- /* Initialize index of extrema value. */ \
- index = 0U; \
- \
- /* Loop unrolling: Compute 4 outputs at a time */ \
- blkCnt = (blockSize - 1U) >> 2U; \
- \
- while (blkCnt > 0U) \
- { \
- /* Initialize cur_absmax to next consecutive values one by one */ \
- cur_absmax = *pSrc++; \
- cur_absmax = (cur_absmax > 0.0f) ? cur_absmax : -cur_absmax; \
- /* compare for the extrema value */ \
- if (cur_absmax > out) \
- { \
- /* Update the extrema value and it's index */ \
- out = cur_absmax; \
- outIndex = index + 1U; \
- } \
- \
- cur_absmax = *pSrc++; \
- cur_absmax = (cur_absmax > 0.0f) ? cur_absmax : -cur_absmax; \
- if (cur_absmax > out) \
- { \
- out = cur_absmax; \
- outIndex = index + 2U; \
- } \
- \
- cur_absmax = *pSrc++; \
- cur_absmax = (cur_absmax > 0.0f) ? cur_absmax : -cur_absmax; \
- if (cur_absmax > out) \
- { \
- out = cur_absmax; \
- outIndex = index + 3U; \
- } \
- \
- cur_absmax = *pSrc++; \
- cur_absmax = (cur_absmax > 0.0f) ? cur_absmax : -cur_absmax; \
- if (cur_absmax > out) \
- { \
- out = cur_absmax; \
- outIndex = index + 4U; \
- } \
- \
- index += 4U; \
- \
- /* Decrement loop counter */ \
- blkCnt--; \
- } \
- \
- /* Loop unrolling: Compute remaining outputs */ \
- blkCnt = (blockSize - 1U) % 4U; \
- \
- \
- while (blkCnt > 0U) \
- { \
- cur_absmax = *pSrc++; \
- cur_absmax = (cur_absmax > 0.0f) ? cur_absmax : -cur_absmax; \
- if (cur_absmax > out) \
- { \
- out = cur_absmax; \
- outIndex = blockSize - blkCnt; \
- } \
- \
- /* Decrement loop counter */ \
- blkCnt--; \
- } \
- \
- /* Store the extrema value and it's index into destination pointers */ \
- *pResult = out; \
- *pIndex = outIndex;
- }
- #else
- void arm_absmax_f32(
- const float32_t * pSrc,
- uint32_t blockSize,
- float32_t * pResult,
- uint32_t * pIndex)
- {
- float32_t maxVal, out; /* Temporary variables to store the output value. */
- uint32_t blkCnt, outIndex; /* Loop counter */
-
-
-
- /* Initialise index value to zero. */
- outIndex = 0U;
-
- /* Load first input value that act as reference value for comparision */
- out = fabsf(*pSrc++);
-
- /* Initialize blkCnt with number of samples */
- blkCnt = (blockSize - 1U);
-
-
- while (blkCnt > 0U)
- {
- /* Initialize maxVal to the next consecutive values one by one */
- maxVal = fabsf(*pSrc++);
-
- /* compare for the maximum value */
- if (out < maxVal)
- {
- /* Update the maximum value and it's index */
- out = maxVal;
- outIndex = blockSize - blkCnt;
- }
-
- /* Decrement loop counter */
- blkCnt--;
- }
-
- /* Store the maximum value and it's index into destination pointers */
- *pResult = out;
- *pIndex = outIndex;
- }
- #endif /* defined(ARM_MATH_LOOPUNROLL) */
- #endif /* defined(ARM_MATH_MVEF) && !defined(ARM_MATH_AUTOVECTORIZE) */
- /**
- @} end of AbsMax group
- */
|