CMSIS DSP library
Dependents: performance_timer Surfboard_ gps2rtty Capstone ... more
Legacy Warning
This is an mbed 2 library. To learn more about mbed OS 5, visit the docs.
Diff: cmsis_dsp/StatisticsFunctions/arm_std_q31.c
- Revision:
- 5:3762170b6d4d
- Parent:
- 3:7a284390b0ce
--- a/cmsis_dsp/StatisticsFunctions/arm_std_q31.c Mon Jun 23 09:30:09 2014 +0100 +++ b/cmsis_dsp/StatisticsFunctions/arm_std_q31.c Fri Nov 20 08:45:18 2015 +0000 @@ -1,8 +1,8 @@ /* ---------------------------------------------------------------------- -* Copyright (C) 2010-2013 ARM Limited. All rights reserved. +* Copyright (C) 2010-2014 ARM Limited. All rights reserved. * -* $Date: 17. January 2013 -* $Revision: V1.4.1 +* $Date: 19. March 2015 +* $Revision: V.1.4.5 * * Project: CMSIS DSP Library * Title: arm_std_q31.c @@ -60,16 +60,17 @@ * <b>Scaling and Overflow Behavior:</b> * *\par - * 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. + * 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. * */ @@ -80,13 +81,17 @@ q31_t * pResult) { q63_t sum = 0; /* Accumulator */ - q31_t meanOfSquares, squareOfMean; /* square of mean and mean of square */ - q31_t mean; /* mean */ + q63_t meanOfSquares, squareOfMean; /* square of mean and mean of square */ q31_t in; /* input value */ - q31_t t; /* Temporary variable */ uint32_t blkCnt; /* loop counter */ q63_t sumOfSquares = 0; /* Accumulator */ + if(blockSize == 1) + { + *pResult = 0; + return; + } + #ifndef ARM_MATH_CM0_FAMILY /* Run the below code for Cortex-M4 and Cortex-M3 */ @@ -101,16 +106,16 @@ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */ /* Compute Sum of squares of the input samples * and then store the result in a temporary variable, sum. */ - in = *pSrc++; + in = *pSrc++ >> 8; sum += in; sumOfSquares += ((q63_t) (in) * (in)); - in = *pSrc++; + in = *pSrc++ >> 8; sum += in; sumOfSquares += ((q63_t) (in) * (in)); - in = *pSrc++; + in = *pSrc++ >> 8; sum += in; sumOfSquares += ((q63_t) (in) * (in)); - in = *pSrc++; + in = *pSrc++ >> 8; sum += in; sumOfSquares += ((q63_t) (in) * (in)); @@ -127,7 +132,7 @@ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */ /* Compute Sum of squares of the input samples * and then store the result in a temporary variable, sum. */ - in = *pSrc++; + in = *pSrc++ >> 8; sum += in; sumOfSquares += ((q63_t) (in) * (in)); @@ -135,12 +140,9 @@ blkCnt--; } - t = (q31_t) ((1.0f / (float32_t) (blockSize - 1u)) * 1073741824.0f); - /* Compute Mean of squares of the input samples * and then store the result in a temporary variable, meanOfSquares. */ - sumOfSquares = (sumOfSquares >> 31); - meanOfSquares = (q31_t) ((sumOfSquares * t) >> 30); + meanOfSquares = sumOfSquares / (q63_t)(blockSize - 1); #else @@ -154,7 +156,7 @@ /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */ /* Compute Sum of squares of the input samples * and then store the result in a temporary variable, sumOfSquares. */ - in = *pSrc++; + in = *pSrc++ >> 8; sumOfSquares += ((q63_t) (in) * (in)); /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */ @@ -167,23 +169,15 @@ /* Compute Mean of squares of the input samples * and then store the result in a temporary variable, meanOfSquares. */ - t = (q31_t) ((1.0f / (float32_t) (blockSize - 1u)) * 1073741824.0f); - sumOfSquares = (sumOfSquares >> 31); - meanOfSquares = (q31_t) ((sumOfSquares * t) >> 30); + meanOfSquares = sumOfSquares / (q63_t)(blockSize - 1); #endif /* #ifndef ARM_MATH_CM0_FAMILY */ - /* Compute mean of all input values */ - t = (q31_t) ((1.0f / (blockSize * (blockSize - 1u))) * 2147483648.0f); - mean = (q31_t) (sum); - /* Compute square of mean */ - squareOfMean = (q31_t) (((q63_t) mean * mean) >> 31); - squareOfMean = (q31_t) (((q63_t) squareOfMean * t) >> 31); - + squareOfMean = sum * sum / (q63_t)(blockSize * (blockSize - 1u)); /* Compute standard deviation and then store the result to the destination */ - arm_sqrt_q31(meanOfSquares - squareOfMean, pResult); + arm_sqrt_q31((meanOfSquares - squareOfMean) >> 15, pResult); }