Camera_driver: initialize project and libraries

This commit is contained in:
Petr Malanik
2022-08-15 18:21:50 +02:00
parent 4da5aefb5a
commit 34b9eaafc2
1280 changed files with 1099270 additions and 0 deletions

View File

@ -0,0 +1,16 @@
cmake_minimum_required (VERSION 3.6)
project(CMSISDSPStatistics)
file(GLOB SRC "./*_*.c")
add_library(CMSISDSPStatistics STATIC ${SRC})
configdsp(CMSISDSPStatistics ..)
### Includes
target_include_directories(CMSISDSPStatistics PUBLIC "${DSP}/../../Include")

View File

@ -0,0 +1,53 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: StatisticsFunctions.c
* Description: Combination of all statistics function source files.
*
* $Date: 18. March 2019
* $Revision: V1.0.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2019 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 "arm_max_f32.c"
#include "arm_max_q15.c"
#include "arm_max_q31.c"
#include "arm_max_q7.c"
#include "arm_mean_f32.c"
#include "arm_mean_q15.c"
#include "arm_mean_q31.c"
#include "arm_mean_q7.c"
#include "arm_min_f32.c"
#include "arm_min_q15.c"
#include "arm_min_q31.c"
#include "arm_min_q7.c"
#include "arm_power_f32.c"
#include "arm_power_q15.c"
#include "arm_power_q31.c"
#include "arm_power_q7.c"
#include "arm_rms_f32.c"
#include "arm_rms_q15.c"
#include "arm_rms_q31.c"
#include "arm_std_f32.c"
#include "arm_std_q15.c"
#include "arm_std_q31.c"
#include "arm_var_f32.c"
#include "arm_var_q15.c"
#include "arm_var_q31.c"

View File

@ -0,0 +1,271 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_max_f32.c
* Description: Maximum value of a floating-point vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
#if defined(ARM_MATH_NEON)
#include <limits.h>
#endif
/**
@ingroup groupStats
*/
/**
@defgroup Max Maximum
Computes the maximum value 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 Max
@{
*/
/**
@brief Maximum value 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_NEON)
void arm_max_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult,
uint32_t * pIndex)
{
float32_t maxVal1, maxVal2, out; /* Temporary variables to store the output value. */
uint32_t blkCnt, outIndex, count; /* loop counter */
float32x4_t outV, srcV;
float32x2_t outV2;
uint32x4_t idxV;
uint32x4_t maxIdx={ULONG_MAX,ULONG_MAX,ULONG_MAX,ULONG_MAX};
uint32x4_t index={4,5,6,7};
uint32x4_t delta={4,4,4,4};
uint32x4_t countV={0,1,2,3};
uint32x2_t countV2;
/* Initialise the count value. */
count = 0U;
/* Initialise the index value to zero. */
outIndex = 0U;
/* Load first input value that act as reference value for comparison */
if (blockSize <= 3)
{
out = *pSrc++;
blkCnt = blockSize - 1;
while (blkCnt > 0U)
{
/* Initialize maxVal to the next consecutive values one by one */
maxVal1 = *pSrc++;
/* compare for the maximum value */
if (out < maxVal1)
{
/* Update the maximum value and it's index */
out = maxVal1;
outIndex = blockSize - blkCnt;
}
/* Decrement the loop counter */
blkCnt--;
}
}
else
{
outV = vld1q_f32(pSrc);
pSrc += 4;
/* Compute 4 outputs at a time */
blkCnt = (blockSize - 4 ) >> 2U;
while (blkCnt > 0U)
{
srcV = vld1q_f32(pSrc);
pSrc += 4;
idxV = vcgtq_f32(srcV, outV);
outV = vbslq_f32(idxV, srcV, outV );
countV = vbslq_u32(idxV, index,countV );
index = vaddq_u32(index,delta);
/* Decrement the loop counter */
blkCnt--;
}
outV2 = vpmax_f32(vget_low_f32(outV),vget_high_f32(outV));
outV2 = vpmax_f32(outV2,outV2);
out = outV2[0];
idxV = vceqq_f32(outV, vdupq_n_f32(out));
countV = vbslq_u32(idxV, countV,maxIdx);
countV2 = vpmin_u32(vget_low_u32(countV),vget_high_u32(countV));
countV2 = vpmin_u32(countV2,countV2);
outIndex = countV2[0];
/* if (blockSize - 1U) is not multiple of 4 */
blkCnt = (blockSize - 4 ) % 4U;
while (blkCnt > 0U)
{
/* Initialize maxVal to the next consecutive values one by one */
maxVal1 = *pSrc++;
/* compare for the maximum value */
if (out < maxVal1)
{
/* Update the maximum value and it's index */
out = maxVal1;
outIndex = blockSize - blkCnt ;
}
/* Decrement the loop counter */
blkCnt--;
}
}
/* Store the maximum value and it's index into destination pointers */
*pResult = out;
*pIndex = outIndex;
}
#else
void arm_max_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 */
#if defined (ARM_MATH_LOOPUNROLL)
uint32_t index; /* index of maximum value */
#endif
/* Initialise index value to zero. */
outIndex = 0U;
/* Load first input value that act as reference value for comparision */
out = *pSrc++;
#if defined (ARM_MATH_LOOPUNROLL)
/* Initialise index of maximum value. */
index = 0U;
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = (blockSize - 1U) >> 2U;
while (blkCnt > 0U)
{
/* Initialize maxVal to next consecutive values one by one */
maxVal = *pSrc++;
/* compare for the maximum value */
if (out < maxVal)
{
/* Update the maximum value and it's index */
out = maxVal;
outIndex = index + 1U;
}
maxVal = *pSrc++;
if (out < maxVal)
{
out = maxVal;
outIndex = index + 2U;
}
maxVal = *pSrc++;
if (out < maxVal)
{
out = maxVal;
outIndex = index + 3U;
}
maxVal = *pSrc++;
if (out < maxVal)
{
out = maxVal;
outIndex = index + 4U;
}
index += 4U;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = (blockSize - 1U) % 4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = (blockSize - 1U);
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* Initialize maxVal to the next consecutive values one by one */
maxVal = *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 /* #if defined(ARM_MATH_NEON) */
/**
@} end of Max group
*/

View File

@ -0,0 +1,148 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_max_q15.c
* Description: Maximum value of a Q15 vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup Max
@{
*/
/**
@brief Maximum value of a Q15 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
*/
void arm_max_q15(
const q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult,
uint32_t * pIndex)
{
q15_t maxVal, out; /* Temporary variables to store the output value. */
uint32_t blkCnt, outIndex; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
uint32_t index; /* index of maximum value */
#endif
/* Initialise index value to zero. */
outIndex = 0U;
/* Load first input value that act as reference value for comparision */
out = *pSrc++;
#if defined (ARM_MATH_LOOPUNROLL)
/* Initialise index of maximum value. */
index = 0U;
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = (blockSize - 1U) >> 2U;
while (blkCnt > 0U)
{
/* Initialize maxVal to next consecutive values one by one */
maxVal = *pSrc++;
/* compare for the maximum value */
if (out < maxVal)
{
/* Update the maximum value and it's index */
out = maxVal;
outIndex = index + 1U;
}
maxVal = *pSrc++;
if (out < maxVal)
{
out = maxVal;
outIndex = index + 2U;
}
maxVal = *pSrc++;
if (out < maxVal)
{
out = maxVal;
outIndex = index + 3U;
}
maxVal = *pSrc++;
if (out < maxVal)
{
out = maxVal;
outIndex = index + 4U;
}
index += 4U;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = (blockSize - 1U) % 4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = (blockSize - 1U);
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* Initialize maxVal to the next consecutive values one by one */
maxVal = *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;
}
/**
@} end of Max group
*/

View File

@ -0,0 +1,148 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_max_q31.c
* Description: Maximum value of a Q31 vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup Max
@{
*/
/**
@brief Maximum value of a Q31 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
*/
void arm_max_q31(
const q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult,
uint32_t * pIndex)
{
q31_t maxVal, out; /* Temporary variables to store the output value. */
uint32_t blkCnt, outIndex; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
uint32_t index; /* index of maximum value */
#endif
/* Initialise index value to zero. */
outIndex = 0U;
/* Load first input value that act as reference value for comparision */
out = *pSrc++;
#if defined (ARM_MATH_LOOPUNROLL)
/* Initialise index of maximum value. */
index = 0U;
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = (blockSize - 1U) >> 2U;
while (blkCnt > 0U)
{
/* Initialize maxVal to next consecutive values one by one */
maxVal = *pSrc++;
/* compare for the maximum value */
if (out < maxVal)
{
/* Update the maximum value and it's index */
out = maxVal;
outIndex = index + 1U;
}
maxVal = *pSrc++;
if (out < maxVal)
{
out = maxVal;
outIndex = index + 2U;
}
maxVal = *pSrc++;
if (out < maxVal)
{
out = maxVal;
outIndex = index + 3U;
}
maxVal = *pSrc++;
if (out < maxVal)
{
out = maxVal;
outIndex = index + 4U;
}
index += 4U;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = (blockSize - 1U) % 4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = (blockSize - 1U);
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* Initialize maxVal to the next consecutive values one by one */
maxVal = *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;
}
/**
@} end of Max group
*/

View File

@ -0,0 +1,148 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_max_q7.c
* Description: Maximum value of a Q7 vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup Max
@{
*/
/**
@brief Maximum value of a Q7 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
*/
void arm_max_q7(
const q7_t * pSrc,
uint32_t blockSize,
q7_t * pResult,
uint32_t * pIndex)
{
q7_t maxVal, out; /* Temporary variables to store the output value. */
uint32_t blkCnt, outIndex; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
uint32_t index; /* index of maximum value */
#endif
/* Initialise index value to zero. */
outIndex = 0U;
/* Load first input value that act as reference value for comparision */
out = *pSrc++;
#if defined (ARM_MATH_LOOPUNROLL)
/* Initialise index of maximum value. */
index = 0U;
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = (blockSize - 1U) >> 2U;
while (blkCnt > 0U)
{
/* Initialize maxVal to next consecutive values one by one */
maxVal = *pSrc++;
/* compare for the maximum value */
if (out < maxVal)
{
/* Update the maximum value and it's index */
out = maxVal;
outIndex = index + 1U;
}
maxVal = *pSrc++;
if (out < maxVal)
{
out = maxVal;
outIndex = index + 2U;
}
maxVal = *pSrc++;
if (out < maxVal)
{
out = maxVal;
outIndex = index + 3U;
}
maxVal = *pSrc++;
if (out < maxVal)
{
out = maxVal;
outIndex = index + 4U;
}
index += 4U;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = (blockSize - 1U) % 4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = (blockSize - 1U);
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* Initialize maxVal to the next consecutive values one by one */
maxVal = *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;
}
/**
@} end of Max group
*/

View File

@ -0,0 +1,166 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_mean_f32.c
* Description: Mean value of a floating-point vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@defgroup mean Mean
Calculates the mean of the input vector. Mean is defined as the average of the elements in the vector.
The underlying algorithm is used:
<pre>
Result = (pSrc[0] + pSrc[1] + pSrc[2] + ... + pSrc[blockSize-1]) / blockSize;
</pre>
There are separate functions for floating-point, Q31, Q15, and Q7 data types.
*/
/**
@addtogroup mean
@{
*/
/**
@brief Mean value 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 mean value returned here.
@return none
*/
#if defined(ARM_MATH_NEON_EXPERIMENTAL)
void arm_mean_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult)
{
float32_t sum = 0.0f; /* Temporary result storage */
float32x4_t sumV = vdupq_n_f32(0.0f); /* Temporary result storage */
float32x2_t sumV2;
uint32_t blkCnt; /* Loop counter */
float32_t in1, in2, in3, in4;
float32x4_t inV;
blkCnt = blockSize >> 2U;
/* Compute 4 outputs at a time.
** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
inV = vld1q_f32(pSrc);
sumV = vaddq_f32(sumV, inV);
pSrc += 4;
/* Decrement the loop counter */
blkCnt--;
}
sumV2 = vpadd_f32(vget_low_f32(sumV),vget_high_f32(sumV));
sum = sumV2[0] + sumV2[1];
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
** No loop unrolling is used. */
blkCnt = blockSize & 3;
while (blkCnt > 0U)
{
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
sum += *pSrc++;
/* Decrement the loop counter */
blkCnt--;
}
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */
/* Store the result to the destination */
*pResult = sum / (float32_t) blockSize;
}
#else
void arm_mean_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
float32_t sum = 0.0f; /* Temporary result storage */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
sum += *pSrc++;
sum += *pSrc++;
sum += *pSrc++;
sum += *pSrc++;
/* Decrement the loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
sum += *pSrc++;
/* Decrement loop counter */
blkCnt--;
}
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */
/* Store result to destination */
*pResult = (sum / blockSize);
}
#endif /* #if defined(ARM_MATH_NEON) */
/**
@} end of mean group
*/

View File

@ -0,0 +1,114 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_mean_q15.c
* Description: Mean value of a Q15 vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup mean
@{
*/
/**
@brief Mean value of a Q15 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult mean value returned here
@return none
@par Scaling and Overflow Behavior
The function is implemented using a 32-bit internal accumulator.
The input is represented in 1.15 format and is accumulated in a 32-bit
accumulator in 17.15 format.
There is no risk of internal overflow with this approach, and the
full precision of intermediate result is preserved.
Finally, the accumulator is truncated to yield a result of 1.15 format.
*/
void arm_mean_q15(
const q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
q31_t sum = 0; /* Temporary result storage */
#if defined (ARM_MATH_LOOPUNROLL)
q31_t in;
#endif
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
in = read_q15x2_ia ((q15_t **) &pSrc);
sum += ((in << 16U) >> 16U);
sum += (in >> 16U);
in = read_q15x2_ia ((q15_t **) &pSrc);
sum += ((in << 16U) >> 16U);
sum += (in >> 16U);
/* Decrement the loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
sum += *pSrc++;
/* Decrement loop counter */
blkCnt--;
}
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */
/* Store result to destination */
*pResult = (q15_t) (sum / (int32_t) blockSize);
}
/**
@} end of mean group
*/

View File

@ -0,0 +1,110 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_mean_q31.c
* Description: Mean value of a Q31 vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup mean
@{
*/
/**
@brief Mean value of a Q31 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult mean value returned here
@return none
@par Scaling and Overflow Behavior
The function is implemented using a 64-bit internal accumulator.
The input is represented in 1.31 format and is accumulated in a 64-bit
accumulator in 33.31 format.
There is no risk of internal overflow with this approach, and the
full precision of intermediate result is preserved.
Finally, the accumulator is truncated to yield a result of 1.31 format.
*/
void arm_mean_q31(
const q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
q63_t sum = 0; /* Temporary result storage */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
sum += *pSrc++;
sum += *pSrc++;
sum += *pSrc++;
sum += *pSrc++;
/* Decrement the loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
sum += *pSrc++;
/* Decrement loop counter */
blkCnt--;
}
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */
/* Store result to destination */
*pResult = (q31_t) (sum / blockSize);
}
/**
@} end of mean group
*/

View File

@ -0,0 +1,112 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_mean_q7.c
* Description: Mean value of a Q7 vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup mean
@{
*/
/**
@brief Mean value of a Q7 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult mean value returned here
@return none
@par Scaling and Overflow Behavior
The function is implemented using a 32-bit internal accumulator.
The input is represented in 1.7 format and is accumulated in a 32-bit
accumulator in 25.7 format.
There is no risk of internal overflow with this approach, and the
full precision of intermediate result is preserved.
Finally, the accumulator is truncated to yield a result of 1.7 format.
*/
void arm_mean_q7(
const q7_t * pSrc,
uint32_t blockSize,
q7_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
q31_t sum = 0; /* Temporary result storage */
#if defined (ARM_MATH_LOOPUNROLL)
q31_t in;
#endif
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
in = read_q7x4_ia ((q7_t **) &pSrc);
sum += ((in << 24U) >> 24U);
sum += ((in << 16U) >> 24U);
sum += ((in << 8U) >> 24U);
sum += (in >> 24U);
/* Decrement the loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
sum += *pSrc++;
/* Decrement loop counter */
blkCnt--;
}
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */
/* Store result to destination */
*pResult = (q7_t) (sum / (int32_t) blockSize);
}
/**
@} end of mean group
*/

View File

@ -0,0 +1,268 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_min_f32.c
* Description: Minimum value of a floating-point vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
#include <limits.h>
/**
@ingroup groupStats
*/
/**
@defgroup Min Minimum
Computes the minimum value of an array of data.
The function returns both the minimum value and its position within the array.
There are separate functions for floating-point, Q31, Q15, and Q7 data types.
*/
/**
@addtogroup Min
@{
*/
/**
@brief Minimum value 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 minimum value returned here
@param[out] pIndex index of minimum value returned here
@return none
*/
#if defined(ARM_MATH_NEON)
void arm_min_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult,
uint32_t * pIndex)
{
float32_t maxVal1, maxVal2, out; /* Temporary variables to store the output value. */
uint32_t blkCnt, outIndex, count; /* loop counter */
float32x4_t outV, srcV;
float32x2_t outV2;
uint32x4_t idxV;
uint32x4_t maxIdx={ULONG_MAX,ULONG_MAX,ULONG_MAX,ULONG_MAX};
uint32x4_t index={4,5,6,7};
uint32x4_t delta={4,4,4,4};
uint32x4_t countV={0,1,2,3};
uint32x2_t countV2;
/* Initialise the count value. */
count = 0U;
/* Initialise the index value to zero. */
outIndex = 0U;
/* Load first input value that act as reference value for comparison */
if (blockSize <= 3)
{
out = *pSrc++;
blkCnt = blockSize - 1;
while (blkCnt > 0U)
{
/* Initialize maxVal to the next consecutive values one by one */
maxVal1 = *pSrc++;
/* compare for the maximum value */
if (out > maxVal1)
{
/* Update the maximum value and it's index */
out = maxVal1;
outIndex = blockSize - blkCnt;
}
/* Decrement the loop counter */
blkCnt--;
}
}
else
{
outV = vld1q_f32(pSrc);
pSrc += 4;
/* Compute 4 outputs at a time */
blkCnt = (blockSize - 4 ) >> 2U;
while (blkCnt > 0U)
{
srcV = vld1q_f32(pSrc);
pSrc += 4;
idxV = vcltq_f32(srcV, outV);
outV = vbslq_f32(idxV, srcV, outV );
countV = vbslq_u32(idxV, index,countV );
index = vaddq_u32(index,delta);
/* Decrement the loop counter */
blkCnt--;
}
outV2 = vpmin_f32(vget_low_f32(outV),vget_high_f32(outV));
outV2 = vpmin_f32(outV2,outV2);
out = outV2[0];
idxV = vceqq_f32(outV, vdupq_n_f32(out));
countV = vbslq_u32(idxV, countV,maxIdx);
countV2 = vpmin_u32(vget_low_u32(countV),vget_high_u32(countV));
countV2 = vpmin_u32(countV2,countV2);
outIndex = countV2[0];
/* if (blockSize - 1U) is not multiple of 4 */
blkCnt = (blockSize - 4 ) % 4U;
while (blkCnt > 0U)
{
/* Initialize maxVal to the next consecutive values one by one */
maxVal1 = *pSrc++;
/* compare for the maximum value */
if (out > maxVal1)
{
/* Update the maximum value and it's index */
out = maxVal1;
outIndex = blockSize - blkCnt ;
}
/* Decrement the loop counter */
blkCnt--;
}
}
/* Store the maximum value and it's index into destination pointers */
*pResult = out;
*pIndex = outIndex;
}
#else
void arm_min_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult,
uint32_t * pIndex)
{
float32_t minVal, out; /* Temporary variables to store the output value. */
uint32_t blkCnt, outIndex; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
uint32_t index; /* index of maximum value */
#endif
/* Initialise index value to zero. */
outIndex = 0U;
/* Load first input value that act as reference value for comparision */
out = *pSrc++;
#if defined (ARM_MATH_LOOPUNROLL)
/* Initialise index of maximum value. */
index = 0U;
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = (blockSize - 1U) >> 2U;
while (blkCnt > 0U)
{
/* Initialize minVal to next consecutive values one by one */
minVal = *pSrc++;
/* compare for the minimum value */
if (out > minVal)
{
/* Update the minimum value and it's index */
out = minVal;
outIndex = index + 1U;
}
minVal = *pSrc++;
if (out > minVal)
{
out = minVal;
outIndex = index + 2U;
}
minVal = *pSrc++;
if (out > minVal)
{
out = minVal;
outIndex = index + 3U;
}
minVal = *pSrc++;
if (out > minVal)
{
out = minVal;
outIndex = index + 4U;
}
index += 4U;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = (blockSize - 1U) % 4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = (blockSize - 1U);
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* Initialize minVal to the next consecutive values one by one */
minVal = *pSrc++;
/* compare for the minimum value */
if (out > minVal)
{
/* Update the minimum value and it's index */
out = minVal;
outIndex = blockSize - blkCnt;
}
/* Decrement loop counter */
blkCnt--;
}
/* Store the minimum value and it's index into destination pointers */
*pResult = out;
*pIndex = outIndex;
}
#endif /* #if defined(ARM_MATH_NEON) */
/**
@} end of Min group
*/

View File

@ -0,0 +1,149 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_min_q15.c
* Description: Minimum value of a Q15 vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup Min
@{
*/
/**
@brief Minimum value of a Q15 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult minimum value returned here
@param[out] pIndex index of minimum value returned here
@return none
*/
void arm_min_q15(
const q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult,
uint32_t * pIndex)
{
q15_t minVal, out; /* Temporary variables to store the output value. */
uint32_t blkCnt, outIndex; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
uint32_t index; /* index of maximum value */
#endif
/* Initialise index value to zero. */
outIndex = 0U;
/* Load first input value that act as reference value for comparision */
out = *pSrc++;
#if defined (ARM_MATH_LOOPUNROLL)
/* Initialise index of maximum value. */
index = 0U;
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = (blockSize - 1U) >> 2U;
while (blkCnt > 0U)
{
/* Initialize minVal to next consecutive values one by one */
minVal = *pSrc++;
/* compare for the minimum value */
if (out > minVal)
{
/* Update the minimum value and it's index */
out = minVal;
outIndex = index + 1U;
}
minVal = *pSrc++;
if (out > minVal)
{
out = minVal;
outIndex = index + 2U;
}
minVal = *pSrc++;
if (out > minVal)
{
out = minVal;
outIndex = index + 3U;
}
minVal = *pSrc++;
if (out > minVal)
{
out = minVal;
outIndex = index + 4U;
}
index += 4U;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = (blockSize - 1U) % 4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = (blockSize - 1U);
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* Initialize minVal to the next consecutive values one by one */
minVal = *pSrc++;
/* compare for the minimum value */
if (out > minVal)
{
/* Update the minimum value and it's index */
out = minVal;
outIndex = blockSize - blkCnt;
}
/* Decrement loop counter */
blkCnt--;
}
/* Store the minimum value and it's index into destination pointers */
*pResult = out;
*pIndex = outIndex;
}
/**
@} end of Min group
*/

View File

@ -0,0 +1,149 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_min_q31.c
* Description: Minimum value of a Q31 vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup Min
@{
*/
/**
@brief Minimum value of a Q31 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult minimum value returned here
@param[out] pIndex index of minimum value returned here
@return none
*/
void arm_min_q31(
const q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult,
uint32_t * pIndex)
{
q31_t minVal, out; /* Temporary variables to store the output value. */
uint32_t blkCnt, outIndex; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
uint32_t index; /* index of maximum value */
#endif
/* Initialise index value to zero. */
outIndex = 0U;
/* Load first input value that act as reference value for comparision */
out = *pSrc++;
#if defined (ARM_MATH_LOOPUNROLL)
/* Initialise index of maximum value. */
index = 0U;
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = (blockSize - 1U) >> 2U;
while (blkCnt > 0U)
{
/* Initialize minVal to next consecutive values one by one */
minVal = *pSrc++;
/* compare for the minimum value */
if (out > minVal)
{
/* Update the minimum value and it's index */
out = minVal;
outIndex = index + 1U;
}
minVal = *pSrc++;
if (out > minVal)
{
out = minVal;
outIndex = index + 2U;
}
minVal = *pSrc++;
if (out > minVal)
{
out = minVal;
outIndex = index + 3U;
}
minVal = *pSrc++;
if (out > minVal)
{
out = minVal;
outIndex = index + 4U;
}
index += 4U;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = (blockSize - 1U) % 4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = (blockSize - 1U);
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* Initialize minVal to the next consecutive values one by one */
minVal = *pSrc++;
/* compare for the minimum value */
if (out > minVal)
{
/* Update the minimum value and it's index */
out = minVal;
outIndex = blockSize - blkCnt;
}
/* Decrement loop counter */
blkCnt--;
}
/* Store the minimum value and it's index into destination pointers */
*pResult = out;
*pIndex = outIndex;
}
/**
@} end of Min group
*/

View File

@ -0,0 +1,149 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_min_q7.c
* Description: Minimum value of a Q7 vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup Min
@{
*/
/**
@brief Minimum value of a Q7 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult minimum value returned here
@param[out] pIndex index of minimum value returned here
@return none
*/
void arm_min_q7(
const q7_t * pSrc,
uint32_t blockSize,
q7_t * pResult,
uint32_t * pIndex)
{
q7_t minVal, out; /* Temporary variables to store the output value. */
uint32_t blkCnt, outIndex; /* Loop counter */
#if defined (ARM_MATH_LOOPUNROLL)
uint32_t index; /* index of maximum value */
#endif
/* Initialise index value to zero. */
outIndex = 0U;
/* Load first input value that act as reference value for comparision */
out = *pSrc++;
#if defined (ARM_MATH_LOOPUNROLL)
/* Initialise index of maximum value. */
index = 0U;
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = (blockSize - 1U) >> 2U;
while (blkCnt > 0U)
{
/* Initialize minVal to next consecutive values one by one */
minVal = *pSrc++;
/* compare for the minimum value */
if (out > minVal)
{
/* Update the minimum value and it's index */
out = minVal;
outIndex = index + 1U;
}
minVal = *pSrc++;
if (out > minVal)
{
out = minVal;
outIndex = index + 2U;
}
minVal = *pSrc++;
if (out > minVal)
{
out = minVal;
outIndex = index + 3U;
}
minVal = *pSrc++;
if (out > minVal)
{
out = minVal;
outIndex = index + 4U;
}
index += 4U;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = (blockSize - 1U) % 4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = (blockSize - 1U);
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* Initialize minVal to the next consecutive values one by one */
minVal = *pSrc++;
/* compare for the minimum value */
if (out > minVal)
{
/* Update the minimum value and it's index */
out = minVal;
outIndex = blockSize - blkCnt;
}
/* Decrement loop counter */
blkCnt--;
}
/* Store the minimum value and it's index into destination pointers */
*pResult = out;
*pIndex = outIndex;
}
/**
@} end of Min group
*/

View File

@ -0,0 +1,175 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_power_f32.c
* Description: Sum of the squares of the elements of a floating-point vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@defgroup power Power
Calculates the sum of the squares of the elements in the input vector.
The underlying algorithm is used:
<pre>
Result = pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + pSrc[2] * pSrc[2] + ... + pSrc[blockSize-1] * pSrc[blockSize-1];
</pre>
There are separate functions for floating point, Q31, Q15, and Q7 data types.
*/
/**
@addtogroup power
@{
*/
/**
@brief Sum of the squares of the elements 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 sum of the squares value returned here
@return none
*/
#if defined(ARM_MATH_NEON)
void arm_power_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult)
{
float32_t sum = 0.0f; /* accumulator */
float32_t in; /* Temporary variable to store input value */
uint32_t blkCnt; /* loop counter */
float32x4_t sumV = vdupq_n_f32(0.0f); /* Temporary result storage */
float32x2_t sumV2;
float32x4_t inV;
blkCnt = blockSize >> 2U;
/* Compute 4 outputs at a time.
** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
/* Compute Power and then store the result in a temporary variable, sum. */
inV = vld1q_f32(pSrc);
sumV = vmlaq_f32(sumV, inV, inV);
pSrc += 4;
/* Decrement the loop counter */
blkCnt--;
}
sumV2 = vpadd_f32(vget_low_f32(sumV),vget_high_f32(sumV));
sum = sumV2[0] + sumV2[1];
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
** No loop unrolling is used. */
blkCnt = blockSize % 0x4U;
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
/* compute power and then store the result in a temporary variable, sum. */
in = *pSrc++;
sum += in * in;
/* Decrement the loop counter */
blkCnt--;
}
/* Store the result to the destination */
*pResult = sum;
}
#else
void arm_power_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
float32_t sum = 0.0f; /* Temporary result storage */
float32_t in; /* Temporary variable to store input value */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* Compute Power and store result in a temporary variable, sum. */
in = *pSrc++;
sum += in * in;
in = *pSrc++;
sum += in * in;
in = *pSrc++;
sum += in * in;
in = *pSrc++;
sum += in * in;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* Compute Power and store result in a temporary variable, sum. */
in = *pSrc++;
sum += in * in;
/* Decrement loop counter */
blkCnt--;
}
/* Store result to destination */
*pResult = sum;
}
#endif /* #if defined(ARM_MATH_NEON) */
/**
@} end of power group
*/

View File

@ -0,0 +1,132 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_power_q15.c
* Description: Sum of the squares of the elements of a Q15 vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup power
@{
*/
/**
@brief Sum of the squares of the elements of a Q15 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult sum of the squares value returned here
@return none
@par Scaling and Overflow Behavior
The function is implemented using a 64-bit internal accumulator.
The input is represented in 1.15 format.
Intermediate multiplication yields a 2.30 format, and this
result is added without saturation to a 64-bit accumulator in 34.30 format.
With 33 guard bits in the accumulator, there is no risk of overflow, and the
full precision of the intermediate multiplication is preserved.
Finally, the return result is in 34.30 format.
*/
void arm_power_q15(
const q15_t * pSrc,
uint32_t blockSize,
q63_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
q63_t sum = 0; /* Temporary result storage */
q15_t in; /* Temporary variable to store input value */
#if defined (ARM_MATH_LOOPUNROLL) && defined (ARM_MATH_DSP)
q31_t in32; /* Temporary variable to store packed input value */
#endif
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* Compute Power and store result in a temporary variable, sum. */
#if defined (ARM_MATH_DSP)
in32 = read_q15x2_ia ((q15_t **) &pSrc);
sum = __SMLALD(in32, in32, sum);
in32 = read_q15x2_ia ((q15_t **) &pSrc);
sum = __SMLALD(in32, in32, sum);
#else
in = *pSrc++;
sum += ((q31_t) in * in);
in = *pSrc++;
sum += ((q31_t) in * in);
in = *pSrc++;
sum += ((q31_t) in * in);
in = *pSrc++;
sum += ((q31_t) in * in);
#endif /* #if defined (ARM_MATH_DSP) */
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* Compute Power and store result in a temporary variable, sum. */
in = *pSrc++;
sum += ((q31_t) in * in);
/* Decrement loop counter */
blkCnt--;
}
/* Store result in 34.30 format */
*pResult = sum;
}
/**
@} end of power group
*/

View File

@ -0,0 +1,121 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_power_q31.c
* Description: Sum of the squares of the elements of a Q31 vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup power
@{
*/
/**
@brief Sum of the squares of the elements of a Q31 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult sum of the squares value returned here
@return none
@par Scaling and Overflow Behavior
The function is implemented using a 64-bit internal accumulator.
The input is represented in 1.31 format.
Intermediate multiplication yields a 2.62 format, and this
result is truncated to 2.48 format by discarding the lower 14 bits.
The 2.48 result is then added without saturation to a 64-bit accumulator in 16.48 format.
With 15 guard bits in the accumulator, there is no risk of overflow, and the
full precision of the intermediate multiplication is preserved.
Finally, the return result is in 16.48 format.
*/
void arm_power_q31(
const q31_t * pSrc,
uint32_t blockSize,
q63_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
q63_t sum = 0; /* Temporary result storage */
q31_t in; /* Temporary variable to store input value */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* Compute Power then shift intermediate results by 14 bits to maintain 16.48 format and store result in a temporary variable sum, providing 15 guard bits. */
in = *pSrc++;
sum += ((q63_t) in * in) >> 14U;
in = *pSrc++;
sum += ((q63_t) in * in) >> 14U;
in = *pSrc++;
sum += ((q63_t) in * in) >> 14U;
in = *pSrc++;
sum += ((q63_t) in * in) >> 14U;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* Compute Power and store result in a temporary variable, sum. */
in = *pSrc++;
sum += ((q63_t) in * in) >> 14U;
/* Decrement loop counter */
blkCnt--;
}
/* Store results in 16.48 format */
*pResult = sum;
}
/**
@} end of power group
*/

View File

@ -0,0 +1,136 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_power_q7.c
* Description: Sum of the squares of the elements of a Q7 vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup power
@{
*/
/**
@brief Sum of the squares of the elements of a Q7 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult sum of the squares value returned here
@return none
@par Scaling and Overflow Behavior
The function is implemented using a 32-bit internal accumulator.
The input is represented in 1.7 format.
Intermediate multiplication yields a 2.14 format, and this
result is added without saturation to an accumulator in 18.14 format.
With 17 guard bits in the accumulator, there is no risk of overflow, and the
full precision of the intermediate multiplication is preserved.
Finally, the return result is in 18.14 format.
*/
void arm_power_q7(
const q7_t * pSrc,
uint32_t blockSize,
q31_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
q31_t sum = 0; /* Temporary result storage */
q7_t in; /* Temporary variable to store input value */
#if defined (ARM_MATH_LOOPUNROLL) && defined (ARM_MATH_DSP)
q31_t in32; /* Temporary variable to store packed input value */
q31_t in1, in2; /* Temporary variables to store input value */
#endif
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* Compute Power and store result in a temporary variable, sum. */
#if defined (ARM_MATH_DSP)
in32 = read_q7x4_ia ((q7_t **) &pSrc);
in1 = __SXTB16(__ROR(in32, 8));
in2 = __SXTB16(in32);
/* calculate power and accumulate to accumulator */
sum = __SMLAD(in1, in1, sum);
sum = __SMLAD(in2, in2, sum);
#else
in = *pSrc++;
sum += ((q15_t) in * in);
in = *pSrc++;
sum += ((q15_t) in * in);
in = *pSrc++;
sum += ((q15_t) in * in);
in = *pSrc++;
sum += ((q15_t) in * in);
#endif /* #if defined (ARM_MATH_DSP) */
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* Compute Power and store result in a temporary variable, sum. */
in = *pSrc++;
sum += ((q15_t) in * in);
/* Decrement loop counter */
blkCnt--;
}
/* Store result in 18.14 format */
*pResult = sum;
}
/**
@} end of power group
*/

View File

@ -0,0 +1,176 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_rms_f32.c
* Description: Root mean square value of the elements of a floating-point vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@defgroup RMS Root mean square (RMS)
Calculates the Root Mean Square of the elements in the input vector.
The underlying algorithm is used:
<pre>
Result = sqrt(((pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] * pSrc[blockSize-1]) / blockSize));
</pre>
There are separate functions for floating point, Q31, and Q15 data types.
*/
/**
@addtogroup RMS
@{
*/
/**
@brief Root Mean Square of the elements 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 root mean square value returned here
@return none
*/
#if defined(ARM_MATH_NEON)
void arm_rms_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult)
{
float32_t sum = 0.0f; /* accumulator */
float32_t in; /* Temporary variable to store input value */
uint32_t blkCnt; /* loop counter */
float32x4_t sumV = vdupq_n_f32(0.0f); /* Temporary result storage */
float32x2_t sumV2;
float32x4_t inV;
blkCnt = blockSize >> 2U;
/* Compute 4 outputs at a time.
** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
/* Compute Power and then store the result in a temporary variable, sum. */
inV = vld1q_f32(pSrc);
sumV = vmlaq_f32(sumV, inV, inV);
pSrc += 4;
/* Decrement the loop counter */
blkCnt--;
}
sumV2 = vpadd_f32(vget_low_f32(sumV),vget_high_f32(sumV));
sum = sumV2[0] + sumV2[1];
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
** No loop unrolling is used. */
blkCnt = blockSize % 0x4U;
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
/* compute power and then store the result in a temporary variable, sum. */
in = *pSrc++;
sum += in * in;
/* Decrement the loop counter */
blkCnt--;
}
/* Compute Rms and store the result in the destination */
arm_sqrt_f32(sum / (float32_t) blockSize, pResult);
}
#else
void arm_rms_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
float32_t sum = 0.0f; /* Temporary result storage */
float32_t in; /* Temporary variable to store input value */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
in = *pSrc++;
/* Compute sum of squares and store result in a temporary variable, sum. */
sum += in * in;
in = *pSrc++;
sum += in * in;
in = *pSrc++;
sum += in * in;
in = *pSrc++;
sum += in * in;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
in = *pSrc++;
/* Compute sum of squares and store result in a temporary variable. */
sum += ( in * in);
/* Decrement loop counter */
blkCnt--;
}
/* Compute Rms and store result in destination */
arm_sqrt_f32(sum / (float32_t) blockSize, pResult);
}
#endif /* #if defined(ARM_MATH_NEON) */
/**
@} end of RMS group
*/

View File

@ -0,0 +1,134 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_rms_q15.c
* Description: Root Mean Square of the elements of a Q15 vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup RMS
@{
*/
/**
@brief Root Mean Square of the elements of a Q15 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult root mean square value returned here
@return none
@par Scaling and Overflow Behavior
The function is implemented using a 64-bit internal accumulator.
The input is represented in 1.15 format.
Intermediate multiplication yields a 2.30 format, and this
result is added without saturation to a 64-bit accumulator in 34.30 format.
With 33 guard bits in the accumulator, there is no risk of overflow, and the
full precision of the intermediate multiplication is preserved.
Finally, the 34.30 result is truncated to 34.15 format by discarding the lower
15 bits, and then saturated to yield a result in 1.15 format.
*/
void arm_rms_q15(
const q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
q63_t sum = 0; /* Temporary result storage */
q15_t in; /* Temporary variable to store input value */
#if defined (ARM_MATH_LOOPUNROLL) && defined (ARM_MATH_DSP)
q31_t in32; /* Temporary variable to store input value */
#endif
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* Compute sum of squares and store result in a temporary variable. */
#if defined (ARM_MATH_DSP)
in32 = read_q15x2_ia ((q15_t **) &pSrc);
sum = __SMLALD(in32, in32, sum);
in32 = read_q15x2_ia ((q15_t **) &pSrc);
sum = __SMLALD(in32, in32, sum);
#else
in = *pSrc++;
sum += ((q31_t) in * in);
in = *pSrc++;
sum += ((q31_t) in * in);
in = *pSrc++;
sum += ((q31_t) in * in);
in = *pSrc++;
sum += ((q31_t) in * in);
#endif /* #if defined (ARM_MATH_DSP) */
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
in = *pSrc++;
/* Compute sum of squares and store result in a temporary variable. */
sum += ((q31_t) in * in);
/* Decrement loop counter */
blkCnt--;
}
/* Truncating and saturating the accumulator to 1.15 format */
/* Store result in destination */
arm_sqrt_q15(__SSAT((sum / (q63_t)blockSize) >> 15, 16), pResult);
}
/**
@} end of RMS group
*/

View File

@ -0,0 +1,124 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_rms_q31.c
* Description: Root Mean Square of the elements of a Q31 vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup RMS
@{
*/
/**
@brief Root Mean Square of the elements of a Q31 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult root mean square value returned here
@return none
@par Scaling and Overflow Behavior
The function is implemented using an internal 64-bit accumulator.
The input is represented in 1.31 format, and intermediate multiplication
yields a 2.62 format.
The accumulator maintains full precision of the intermediate multiplication results,
but provides only a single guard bit.
There is no saturation on intermediate additions.
If the accumulator overflows, it wraps around and distorts the result.
In order to avoid overflows completely, the input signal must be scaled down by
log2(blockSize) bits, as a total of blockSize additions are performed internally.
Finally, the 2.62 accumulator is right shifted by 31 bits to yield a 1.31 format value.
*/
void arm_rms_q31(
const q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
uint64_t sum = 0; /* Temporary result storage (can get never negative. changed type from q63 to uint64 */
q31_t in; /* Temporary variable to store input value */
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
in = *pSrc++;
/* Compute sum of squares and store result in a temporary variable, sum. */
sum += ((q63_t) in * in);
in = *pSrc++;
sum += ((q63_t) in * in);
in = *pSrc++;
sum += ((q63_t) in * in);
in = *pSrc++;
sum += ((q63_t) in * in);
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
in = *pSrc++;
/* Compute sum of squares and store result in a temporary variable. */
sum += ((q63_t) in * in);
/* Decrement loop counter */
blkCnt--;
}
/* Convert data in 2.62 to 1.31 by 31 right shifts and saturate */
/* Compute Rms and store result in destination vector */
arm_sqrt_q31(clip_q63_to_q31((sum / (q63_t) blockSize) >> 31), pResult);
}
/**
@} end of RMS group
*/

View File

@ -0,0 +1,188 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_std_f32.c
* Description: Standard deviation of the elements of a floating-point vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@defgroup STD Standard deviation
Calculates the standard deviation of the elements in the input vector.
The underlying algorithm is used:
<pre>
Result = sqrt((sumOfSquares - sum<sup>2</sup> / blockSize) / (blockSize - 1))
sumOfSquares = pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] * pSrc[blockSize-1]
sum = pSrc[0] + pSrc[1] + pSrc[2] + ... + pSrc[blockSize-1]
</pre>
There are separate functions for floating point, Q31, and Q15 data types.
*/
/**
@addtogroup STD
@{
*/
/**
@brief Standard deviation of the elements 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 standard deviation value returned here
@return none
*/
#if defined(ARM_MATH_NEON_EXPERIMENTAL)
void arm_std_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult)
{
float32_t var;
arm_var_f32(pSrc,blockSize,&var);
arm_sqrt_f32(var, pResult);
}
#else
void arm_std_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
float32_t sum = 0.0f; /* Temporary result storage */
float32_t sumOfSquares = 0.0f; /* Sum of squares */
float32_t in; /* Temporary variable to store input value */
#ifndef ARM_MATH_CM0_FAMILY
float32_t meanOfSquares, mean, squareOfMean; /* Temporary variables */
#else
float32_t squareOfSum; /* Square of Sum */
float32_t var; /* Temporary varaince storage */
#endif
if (blockSize <= 1U)
{
*pResult = 0;
return;
}
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* C = A[0] + A[1] + ... + A[blockSize-1] */
in = *pSrc++;
/* Compute sum of squares and store result in a temporary variable, sumOfSquares. */
sumOfSquares += in * in;
/* Compute sum and store result in a temporary variable, sum. */
sum += in;
in = *pSrc++;
sumOfSquares += in * in;
sum += in;
in = *pSrc++;
sumOfSquares += in * in;
sum += in;
in = *pSrc++;
sumOfSquares += in * in;
sum += in;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* C = A[0] + A[1] + ... + A[blockSize-1] */
in = *pSrc++;
/* Compute sum of squares and store result in a temporary variable, sumOfSquares. */
sumOfSquares += ( in * in);
/* Compute sum and store result in a temporary variable, sum. */
sum += in;
/* Decrement loop counter */
blkCnt--;
}
#ifndef ARM_MATH_CM0_FAMILY
/* Compute Mean of squares and store result in a temporary variable, meanOfSquares. */
meanOfSquares = sumOfSquares / ((float32_t) blockSize - 1.0f);
/* Compute mean of all input values */
mean = sum / (float32_t) blockSize;
/* Compute square of mean */
squareOfMean = (mean * mean) * (((float32_t) blockSize) /
((float32_t) blockSize - 1.0f));
/* Compute standard deviation and store result to destination */
arm_sqrt_f32((meanOfSquares - squareOfMean), pResult);
#else
/* Run the below code for Cortex-M0 */
/* Compute square of sum */
squareOfSum = ((sum * sum) / (float32_t) blockSize);
/* Compute variance */
var = ((sumOfSquares - squareOfSum) / (float32_t) (blockSize - 1.0f));
/* Compute standard deviation and store result in destination */
arm_sqrt_f32(var, pResult);
#endif /* #ifndef ARM_MATH_CM0_FAMILY */
}
#endif /* #if defined(ARM_MATH_NEON) */
/**
@} end of STD group
*/

View File

@ -0,0 +1,161 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_std_q15.c
* Description: Standard deviation of an array of Q15 vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup STD
@{
*/
/**
@brief Standard deviation of the elements of a Q15 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult standard deviation value returned here
@return none
@par Scaling and Overflow Behavior
The function is implemented using a 64-bit internal accumulator.
The input is represented in 1.15 format.
Intermediate multiplication yields a 2.30 format, and this
result is added without saturation to a 64-bit accumulator in 34.30 format.
With 33 guard bits in the accumulator, there is no risk of overflow, and the
full precision of the intermediate multiplication is preserved.
Finally, the 34.30 result is truncated to 34.15 format by discarding the lower
15 bits, and then saturated to yield a result in 1.15 format.
*/
void arm_std_q15(
const q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
q31_t sum = 0; /* Accumulator */
q31_t meanOfSquares, squareOfMean; /* Square of mean and mean of square */
q63_t sumOfSquares = 0; /* Sum of squares */
q15_t in; /* Temporary variable to store input value */
#if defined (ARM_MATH_LOOPUNROLL) && defined (ARM_MATH_DSP)
q31_t in32; /* Temporary variable to store input value */
#endif
if (blockSize <= 1U)
{
*pResult = 0;
return;
}
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* C = A[0] + A[1] + ... + A[blockSize-1] */
/* Compute sum of squares and store result in a temporary variable, sumOfSquares. */
/* Compute sum and store result in a temporary variable, sum. */
#if defined (ARM_MATH_DSP)
in32 = read_q15x2_ia ((q15_t **) &pSrc);
sumOfSquares = __SMLALD(in32, in32, sumOfSquares);
sum += ((in32 << 16U) >> 16U);
sum += (in32 >> 16U);
in32 = read_q15x2_ia ((q15_t **) &pSrc);
sumOfSquares = __SMLALD(in32, in32, sumOfSquares);
sum += ((in32 << 16U) >> 16U);
sum += (in32 >> 16U);
#else
in = *pSrc++;
sumOfSquares += (in * in);
sum += in;
in = *pSrc++;
sumOfSquares += (in * in);
sum += in;
in = *pSrc++;
sumOfSquares += (in * in);
sum += in;
in = *pSrc++;
sumOfSquares += (in * in);
sum += in;
#endif /* #if defined (ARM_MATH_DSP) */
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* C = A[0] + A[1] + ... + A[blockSize-1] */
in = *pSrc++;
/* Compute sum of squares and store result in a temporary variable, sumOfSquares. */
sumOfSquares += (in * in);
/* Compute sum and store result in a temporary variable, sum. */
sum += in;
/* Decrement loop counter */
blkCnt--;
}
/* Compute Mean of squares and store result in a temporary variable, meanOfSquares. */
meanOfSquares = (q31_t) (sumOfSquares / (q63_t)(blockSize - 1U));
/* Compute square of mean */
squareOfMean = (q31_t) ((q63_t) sum * sum / (q63_t)(blockSize * (blockSize - 1U)));
/* mean of squares minus the square of mean. */
/* Compute standard deviation and store result in destination */
arm_sqrt_q15(__SSAT((meanOfSquares - squareOfMean) >> 15U, 16U), pResult);
}
/**
@} end of STD group
*/

View File

@ -0,0 +1,147 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_std_q31.c
* Description: Standard deviation of the elements of a Q31 vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup STD
@{
*/
/**
@brief Standard deviation of the elements of a Q31 vector.
@param[in] pSrc points to the input vector.
@param[in] blockSize number of samples in input vector.
@param[out] pResult standard deviation value returned here.
@return none
@par Scaling and Overflow Behavior
The function is implemented using an internal 64-bit accumulator.
The input is represented in 1.31 format, which is then downshifted by 8 bits
which yields 1.23, and intermediate multiplication yields a 2.46 format.
The accumulator maintains full precision of the intermediate multiplication results,
but provides only a 16 guard bits.
There is no saturation on intermediate additions.
If the accumulator overflows it wraps around and distorts the result.
In order to avoid overflows completely the input signal must be scaled down by
log2(blockSize)-8 bits, as a total of blockSize additions are performed internally.
After division, internal variables should be Q18.46
Finally, the 18.46 accumulator is right shifted by 15 bits to yield a 1.31 format value.
*/
void arm_std_q31(
const q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
q63_t sum = 0; /* Accumulator */
q63_t meanOfSquares, squareOfMean; /* Square of mean and mean of square */
q63_t sumOfSquares = 0; /* Sum of squares */
q31_t in; /* Temporary variable to store input value */
if (blockSize <= 1U)
{
*pResult = 0;
return;
}
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* C = A[0] + A[1] + ... + A[blockSize-1] */
in = *pSrc++ >> 8U;
/* Compute sum of squares and store result in a temporary variable, sumOfSquares. */
sumOfSquares += ((q63_t) (in) * (in));
/* Compute sum and store result in a temporary variable, sum. */
sum += in;
in = *pSrc++ >> 8U;
sumOfSquares += ((q63_t) (in) * (in));
sum += in;
in = *pSrc++ >> 8U;
sumOfSquares += ((q63_t) (in) * (in));
sum += in;
in = *pSrc++ >> 8U;
sumOfSquares += ((q63_t) (in) * (in));
sum += in;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* C = A[0] + A[1] + ... + A[blockSize-1] */
in = *pSrc++ >> 8U;
/* Compute sum of squares and store result in a temporary variable, sumOfSquares. */
sumOfSquares += ((q63_t) (in) * (in));
/* Compute sum and store result in a temporary variable, sum. */
sum += in;
/* Decrement loop counter */
blkCnt--;
}
/* Compute Mean of squares and store result in a temporary variable, meanOfSquares. */
meanOfSquares = (sumOfSquares / (q63_t)(blockSize - 1U));
/* Compute square of mean */
squareOfMean = ( sum * sum / (q63_t)(blockSize * (blockSize - 1U)));
/* Compute standard deviation and store result in destination */
arm_sqrt_q31((meanOfSquares - squareOfMean) >> 15U, pResult);
}
/**
@} end of STD group
*/

View File

@ -0,0 +1,234 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_var_f32.c
* Description: Variance of the elements of a floating-point vector
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@defgroup variance Variance
Calculates the variance of the elements in the input vector.
The underlying algorithm used is the direct method sometimes referred to as the two-pass method:
<pre>
Result = sum(element - meanOfElements)^2) / numElement - 1
meanOfElements = ( pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] ) / blockSize
</pre>
There are separate functions for floating point, Q31, and Q15 data types.
*/
/**
@addtogroup variance
@{
*/
/**
@brief Variance of the elements 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 variance value returned here
@return none
*/
#if defined(ARM_MATH_NEON_EXPERIMENTAL)
void arm_var_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult)
{
float32_t mean;
float32_t sum = 0.0f; /* accumulator */
float32_t in; /* Temporary variable to store input value */
uint32_t blkCnt; /* loop counter */
float32x4_t sumV = vdupq_n_f32(0.0f); /* Temporary result storage */
float32x2_t sumV2;
float32x4_t inV;
float32x4_t avg;
arm_mean_f32(pSrc,blockSize,&mean);
avg = vdupq_n_f32(mean);
blkCnt = blockSize >> 2U;
/* Compute 4 outputs at a time.
** a second loop below computes the remaining 1 to 3 samples. */
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
/* Compute Power and then store the result in a temporary variable, sum. */
inV = vld1q_f32(pSrc);
inV = vsubq_f32(inV, avg);
sumV = vmlaq_f32(sumV, inV, inV);
pSrc += 4;
/* Decrement the loop counter */
blkCnt--;
}
sumV2 = vpadd_f32(vget_low_f32(sumV),vget_high_f32(sumV));
sum = sumV2[0] + sumV2[1];
/* If the blockSize is not a multiple of 4, compute any remaining output samples here.
** No loop unrolling is used. */
blkCnt = blockSize % 0x4U;
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + A[2] * A[2] + ... + A[blockSize-1] * A[blockSize-1] */
/* compute power and then store the result in a temporary variable, sum. */
in = *pSrc++;
in = in - mean;
sum += in * in;
/* Decrement the loop counter */
blkCnt--;
}
/* Variance */
*pResult = sum / (float32_t)(blockSize - 1.0f);
}
#else
void arm_var_f32(
const float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
float32_t sum = 0.0f; /* Temporary result storage */
float32_t fSum = 0.0f;
float32_t fMean, fValue;
const float32_t * pInput = pSrc;
if (blockSize <= 1U)
{
*pResult = 0;
return;
}
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
sum += *pInput++;
sum += *pInput++;
sum += *pInput++;
sum += *pInput++;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
sum += *pInput++;
/* Decrement loop counter */
blkCnt--;
}
/* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) / blockSize */
fMean = sum / (float32_t) blockSize;
pInput = pSrc;
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
fValue = *pInput++ - fMean;
fSum += fValue * fValue;
fValue = *pInput++ - fMean;
fSum += fValue * fValue;
fValue = *pInput++ - fMean;
fSum += fValue * fValue;
fValue = *pInput++ - fMean;
fSum += fValue * fValue;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
fValue = *pInput++ - fMean;
fSum += fValue * fValue;
/* Decrement loop counter */
blkCnt--;
}
/* Variance */
*pResult = fSum / (float32_t)(blockSize - 1.0f);
}
#endif /* #if defined(ARM_MATH_NEON) */
/**
@} end of variance group
*/

View File

@ -0,0 +1,164 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_var_q15.c
* Description: Variance of an array of Q15 type
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup variance
@{
*/
/**
@brief Variance of the elements of a Q15 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult variance value returned here
@return none
@par Scaling and Overflow Behavior
The function is implemented using a 64-bit internal accumulator.
The input is represented in 1.15 format.
Intermediate multiplication yields a 2.30 format, and this
result is added without saturation to a 64-bit accumulator in 34.30 format.
With 33 guard bits in the accumulator, there is no risk of overflow, and the
full precision of the intermediate multiplication is preserved.
Finally, the 34.30 result is truncated to 34.15 format by discarding the lower
15 bits, and then saturated to yield a result in 1.15 format.
*/
void arm_var_q15(
const q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
q31_t sum = 0; /* Accumulator */
q31_t meanOfSquares, squareOfMean; /* Square of mean and mean of square */
q63_t sumOfSquares = 0; /* Sum of squares */
q15_t in; /* Temporary variable to store input value */
#if defined (ARM_MATH_LOOPUNROLL) && defined (ARM_MATH_DSP)
q31_t in32; /* Temporary variable to store input value */
#endif
if (blockSize <= 1U)
{
*pResult = 0;
return;
}
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* C = A[0] + A[1] + ... + A[blockSize-1] */
/* Compute sum of squares and store result in a temporary variable, sumOfSquares. */
/* Compute sum and store result in a temporary variable, sum. */
#if defined (ARM_MATH_DSP)
in32 = read_q15x2_ia ((q15_t **) &pSrc);
sumOfSquares = __SMLALD(in32, in32, sumOfSquares);
sum += ((in32 << 16U) >> 16U);
sum += (in32 >> 16U);
in32 = read_q15x2_ia ((q15_t **) &pSrc);
sumOfSquares = __SMLALD(in32, in32, sumOfSquares);
sum += ((in32 << 16U) >> 16U);
sum += (in32 >> 16U);
#else
in = *pSrc++;
sumOfSquares += (in * in);
sum += in;
in = *pSrc++;
sumOfSquares += (in * in);
sum += in;
in = *pSrc++;
sumOfSquares += (in * in);
sum += in;
in = *pSrc++;
sumOfSquares += (in * in);
sum += in;
#endif /* #if defined (ARM_MATH_DSP) */
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* C = A[0] + A[1] + ... + A[blockSize-1] */
in = *pSrc++;
/* Compute sum of squares and store result in a temporary variable, sumOfSquares. */
#if defined (ARM_MATH_DSP)
sumOfSquares = __SMLALD(in, in, sumOfSquares);
#else
sumOfSquares += (in * in);
#endif /* #if defined (ARM_MATH_DSP) */
/* Compute sum and store result in a temporary variable, sum. */
sum += in;
/* Decrement loop counter */
blkCnt--;
}
/* Compute Mean of squares and store result in a temporary variable, meanOfSquares. */
meanOfSquares = (q31_t) (sumOfSquares / (q63_t)(blockSize - 1U));
/* Compute square of mean */
squareOfMean = (q31_t) ((q63_t) sum * sum / (q63_t)(blockSize * (blockSize - 1U)));
/* mean of squares minus the square of mean. */
*pResult = (meanOfSquares - squareOfMean) >> 15U;
}
/**
@} end of variance group
*/

View File

@ -0,0 +1,147 @@
/* ----------------------------------------------------------------------
* Project: CMSIS DSP Library
* Title: arm_var_q31.c
* Description: Variance of an array of Q31 type
*
* $Date: 18. March 2019
* $Revision: V1.6.0
*
* Target Processor: Cortex-M cores
* -------------------------------------------------------------------- */
/*
* Copyright (C) 2010-2019 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 "arm_math.h"
/**
@ingroup groupStats
*/
/**
@addtogroup variance
@{
*/
/**
@brief Variance of the elements of a Q31 vector.
@param[in] pSrc points to the input vector
@param[in] blockSize number of samples in input vector
@param[out] pResult variance value returned here
@return none
@par Scaling and Overflow Behavior
The function is implemented using an internal 64-bit accumulator.
The input is represented in 1.31 format, which is then downshifted by 8 bits
which yields 1.23, and intermediate multiplication yields a 2.46 format.
The accumulator maintains full precision of the intermediate multiplication results,
but provides only a 16 guard bits.
There is no saturation on intermediate additions.
If the accumulator overflows it wraps around and distorts the result.
In order to avoid overflows completely the input signal must be scaled down by
log2(blockSize)-8 bits, as a total of blockSize additions are performed internally.
After division, internal variables should be Q18.46
Finally, the 18.46 accumulator is right shifted by 15 bits to yield a 1.31 format value.
*/
void arm_var_q31(
const q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult)
{
uint32_t blkCnt; /* Loop counter */
q63_t sum = 0; /* Temporary result storage */
q63_t meanOfSquares, squareOfMean; /* Square of mean and mean of square */
q63_t sumOfSquares = 0; /* Sum of squares */
q31_t in; /* Temporary variable to store input value */
if (blockSize <= 1U)
{
*pResult = 0;
return;
}
#if defined (ARM_MATH_LOOPUNROLL)
/* Loop unrolling: Compute 4 outputs at a time */
blkCnt = blockSize >> 2U;
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* C = A[0] + A[1] + ... + A[blockSize-1] */
in = *pSrc++ >> 8U;
/* Compute sum of squares and store result in a temporary variable, sumOfSquares. */
sumOfSquares += ((q63_t) (in) * (in));
/* Compute sum and store result in a temporary variable, sum. */
sum += in;
in = *pSrc++ >> 8U;
sumOfSquares += ((q63_t) (in) * (in));
sum += in;
in = *pSrc++ >> 8U;
sumOfSquares += ((q63_t) (in) * (in));
sum += in;
in = *pSrc++ >> 8U;
sumOfSquares += ((q63_t) (in) * (in));
sum += in;
/* Decrement loop counter */
blkCnt--;
}
/* Loop unrolling: Compute remaining outputs */
blkCnt = blockSize % 0x4U;
#else
/* Initialize blkCnt with number of samples */
blkCnt = blockSize;
#endif /* #if defined (ARM_MATH_LOOPUNROLL) */
while (blkCnt > 0U)
{
/* C = A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1] */
/* C = A[0] + A[1] + ... + A[blockSize-1] */
in = *pSrc++ >> 8U;
/* Compute sum of squares and store result in a temporary variable, sumOfSquares. */
sumOfSquares += ((q63_t) (in) * (in));
/* Compute sum and store result in a temporary variable, sum. */
sum += in;
/* Decrement loop counter */
blkCnt--;
}
/* Compute Mean of squares and store result in a temporary variable, meanOfSquares. */
meanOfSquares = (sumOfSquares / (q63_t)(blockSize - 1U));
/* Compute square of mean */
squareOfMean = ( sum * sum / (q63_t)(blockSize * (blockSize - 1U)));
/* Compute variance and store result in destination */
*pResult = (meanOfSquares - squareOfMean) >> 15U;
}
/**
@} end of variance group
*/