summaryrefslogtreecommitdiff
path: root/DSP/Source/ComplexMathFunctions/arm_cmplx_mag_f32.c
diff options
context:
space:
mode:
authorrihab kouki <rihab.kouki@st.com>2020-07-28 11:24:49 +0100
committerrihab kouki <rihab.kouki@st.com>2020-07-28 11:24:49 +0100
commit96d6da4e252b06dcfdc041e7df23e86161c33007 (patch)
treea262f59bb1db7ec7819acae435f5049cbe5e2354 /DSP/Source/ComplexMathFunctions/arm_cmplx_mag_f32.c
parent9f95ff5b6ba01db09552b84a0ab79607060a2666 (diff)
downloadst-cmsis-core-lowfat-master.tar.gz
st-cmsis-core-lowfat-master.tar.bz2
st-cmsis-core-lowfat-master.zip
Official ARM version: v5.6.0HEADmaster
Diffstat (limited to 'DSP/Source/ComplexMathFunctions/arm_cmplx_mag_f32.c')
-rw-r--r--DSP/Source/ComplexMathFunctions/arm_cmplx_mag_f32.c191
1 files changed, 113 insertions, 78 deletions
diff --git a/DSP/Source/ComplexMathFunctions/arm_cmplx_mag_f32.c b/DSP/Source/ComplexMathFunctions/arm_cmplx_mag_f32.c
index 95aaf1e..84812dc 100644
--- a/DSP/Source/ComplexMathFunctions/arm_cmplx_mag_f32.c
+++ b/DSP/Source/ComplexMathFunctions/arm_cmplx_mag_f32.c
@@ -3,13 +3,13 @@
* Title: arm_cmplx_mag_f32.c
* Description: Floating-point complex magnitude
*
- * $Date: 27. January 2017
- * $Revision: V.1.5.1
+ * $Date: 18. March 2019
+ * $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
- * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
+ * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -29,125 +29,160 @@
#include "arm_math.h"
/**
- * @ingroup groupCmplxMath
+ @ingroup groupCmplxMath
*/
/**
- * @defgroup cmplx_mag Complex Magnitude
- *
- * Computes the magnitude of the elements of a complex data vector.
- *
- * The <code>pSrc</code> points to the source data and
- * <code>pDst</code> points to the where the result should be written.
- * <code>numSamples</code> specifies the number of complex samples
- * in the input array and the data is stored in an interleaved fashion
- * (real, imag, real, imag, ...).
- * The input array has a total of <code>2*numSamples</code> values;
- * the output array has a total of <code>numSamples</code> values.
- * The underlying algorithm is used:
- *
- * <pre>
- * for(n=0; n<numSamples; n++) {
- * pDst[n] = sqrt(pSrc[(2*n)+0]^2 + pSrc[(2*n)+1]^2);
- * }
- * </pre>
- *
- * There are separate functions for floating-point, Q15, and Q31 data types.
+ @defgroup cmplx_mag Complex Magnitude
+
+ Computes the magnitude of the elements of a complex data vector.
+
+ The <code>pSrc</code> points to the source data and
+ <code>pDst</code> points to the where the result should be written.
+ <code>numSamples</code> specifies the number of complex samples
+ in the input array and the data is stored in an interleaved fashion
+ (real, imag, real, imag, ...).
+ The input array has a total of <code>2*numSamples</code> values;
+ the output array has a total of <code>numSamples</code> values.
+
+ The underlying algorithm is used:
+
+ <pre>
+ for (n = 0; n < numSamples; n++) {
+ pDst[n] = sqrt(pSrc[(2*n)+0]^2 + pSrc[(2*n)+1]^2);
+ }
+ </pre>
+
+ There are separate functions for floating-point, Q15, and Q31 data types.
*/
/**
- * @addtogroup cmplx_mag
- * @{
+ @addtogroup cmplx_mag
+ @{
*/
+
/**
- * @brief Floating-point complex magnitude.
- * @param[in] *pSrc points to complex input buffer
- * @param[out] *pDst points to real output buffer
- * @param[in] numSamples number of complex samples in the input vector
- * @return none.
- *
+ @brief Floating-point complex magnitude.
+ @param[in] pSrc points to input vector
+ @param[out] pDst points to output vector
+ @param[in] numSamples number of samples in each vector
+ @return none
*/
-
void arm_cmplx_mag_f32(
- float32_t * pSrc,
- float32_t * pDst,
- uint32_t numSamples)
+ const float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t numSamples)
{
- float32_t realIn, imagIn; /* Temporary variables to hold input values */
+ uint32_t blkCnt; /* loop counter */
+ float32_t real, imag; /* Temporary variables to hold input values */
-#if defined (ARM_MATH_DSP)
+#if defined(ARM_MATH_NEON)
- /* Run the below code for Cortex-M4 and Cortex-M3 */
- uint32_t blkCnt; /* loop counter */
+ float32x4x2_t vecA;
+ float32x4_t vRealA;
+ float32x4_t vImagA;
+ float32x4_t vMagSqA;
- /*loop Unrolling */
- blkCnt = numSamples >> 2U;
+ float32x4x2_t vecB;
+ float32x4_t vRealB;
+ float32x4_t vImagB;
+ float32x4_t vMagSqB;
+
+ /* Loop unrolling: Compute 8 outputs at a time */
+ blkCnt = numSamples >> 3;
- /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
- ** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
+ /* out = sqrt((real * real) + (imag * imag)) */
- /* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */
- realIn = *pSrc++;
- imagIn = *pSrc++;
- /* store the result in the destination buffer. */
- arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);
+ vecA = vld2q_f32(pSrc);
+ pSrc += 8;
+
+ vecB = vld2q_f32(pSrc);
+ pSrc += 8;
- realIn = *pSrc++;
- imagIn = *pSrc++;
- arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);
+ vRealA = vmulq_f32(vecA.val[0], vecA.val[0]);
+ vImagA = vmulq_f32(vecA.val[1], vecA.val[1]);
+ vMagSqA = vaddq_f32(vRealA, vImagA);
- realIn = *pSrc++;
- imagIn = *pSrc++;
- arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);
+ vRealB = vmulq_f32(vecB.val[0], vecB.val[0]);
+ vImagB = vmulq_f32(vecB.val[1], vecB.val[1]);
+ vMagSqB = vaddq_f32(vRealB, vImagB);
- realIn = *pSrc++;
- imagIn = *pSrc++;
- arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);
+ /* Store the result in the destination buffer. */
+ vst1q_f32(pDst, __arm_vec_sqrt_f32_neon(vMagSqA));
+ pDst += 4;
+ vst1q_f32(pDst, __arm_vec_sqrt_f32_neon(vMagSqB));
+ pDst += 4;
/* Decrement the loop counter */
blkCnt--;
}
- /* If the numSamples is not a multiple of 4, compute any remaining output samples here.
- ** No loop unrolling is used. */
- blkCnt = numSamples % 0x4U;
+ blkCnt = numSamples & 7;
+
+#else
+
+#if defined (ARM_MATH_LOOPUNROLL)
+
+ /* Loop unrolling: Compute 4 outputs at a time */
+ blkCnt = numSamples >> 2U;
while (blkCnt > 0U)
{
/* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */
- realIn = *pSrc++;
- imagIn = *pSrc++;
- /* store the result in the destination buffer. */
- arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);
- /* Decrement the loop counter */
+ real = *pSrc++;
+ imag = *pSrc++;
+
+ /* store result in destination buffer. */
+ arm_sqrt_f32((real * real) + (imag * imag), pDst++);
+
+ real = *pSrc++;
+ imag = *pSrc++;
+ arm_sqrt_f32((real * real) + (imag * imag), pDst++);
+
+ real = *pSrc++;
+ imag = *pSrc++;
+ arm_sqrt_f32((real * real) + (imag * imag), pDst++);
+
+ real = *pSrc++;
+ imag = *pSrc++;
+ arm_sqrt_f32((real * real) + (imag * imag), pDst++);
+
+ /* Decrement loop counter */
blkCnt--;
}
+ /* Loop unrolling: Compute remaining outputs */
+ blkCnt = numSamples % 0x4U;
+
#else
- /* Run the below code for Cortex-M0 */
+ /* Initialize blkCnt with number of samples */
+ blkCnt = numSamples;
+
+#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
+#endif /* #if defined(ARM_MATH_NEON) */
- while (numSamples > 0U)
+ while (blkCnt > 0U)
{
- /* out = sqrt((real * real) + (imag * imag)) */
- realIn = *pSrc++;
- imagIn = *pSrc++;
- /* store the result in the destination buffer. */
- arm_sqrt_f32((realIn * realIn) + (imagIn * imagIn), pDst++);
+ /* C[0] = sqrt(A[0] * A[0] + A[1] * A[1]) */
- /* Decrement the loop counter */
- numSamples--;
- }
+ real = *pSrc++;
+ imag = *pSrc++;
+
+ /* store result in destination buffer. */
+ arm_sqrt_f32((real * real) + (imag * imag), pDst++);
-#endif /* #if defined (ARM_MATH_DSP) */
+ /* Decrement loop counter */
+ blkCnt--;
+ }
}
/**
- * @} end of cmplx_mag group
+ @} end of cmplx_mag group
*/