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_var_q31.c
- Revision:
- 5:3762170b6d4d
- Parent:
- 3:7a284390b0ce
--- a/cmsis_dsp/StatisticsFunctions/arm_var_q31.c Mon Jun 23 09:30:09 2014 +0100 +++ b/cmsis_dsp/StatisticsFunctions/arm_var_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_var_q31.c @@ -61,15 +61,16 @@ * *\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 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 single guard bit. + * 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) 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. + * 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. * */ @@ -77,20 +78,23 @@ void arm_var_q31( q31_t * pSrc, uint32_t blockSize, - q63_t * pResult) + q31_t * pResult) { - q63_t sum = 0, sumSquare = 0; /* Accumulator */ - q31_t meanOfSquares, squareOfMean; /* square of mean and mean of square */ - q31_t mean; /* mean */ + q63_t sum = 0; /* Accumulator */ + 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 */ - q63_t sumSquare1 = 0; /* Accumulator */ - q31_t in1, in2, in3, in4; /* Temporary input variables */ /*loop Unrolling */ blkCnt = blockSize >> 2u; @@ -100,76 +104,81 @@ while(blkCnt > 0u) { /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */ - /* Compute Sum of squares of the input samples + /* Compute Sum of squares of the input samples * and then store the result in a temporary variable, sum. */ - /* read input samples from source buffer */ - in1 = pSrc[0]; - in2 = pSrc[1]; - - /* calculate sum of inputs */ - sum += in1; - /* calculate sum of squares */ - sumSquare += ((q63_t) (in1) * (in1)); - in3 = pSrc[2]; - sum += in2; - sumSquare1 += ((q63_t) (in2) * (in2)); - in4 = pSrc[3]; - sum += in3; - sumSquare += ((q63_t) (in3) * (in3)); - sum += in4; - sumSquare1 += ((q63_t) (in4) * (in4)); - - /* update input pointer to process next samples */ - pSrc += 4u; + in = *pSrc++ >> 8; + sum += in; + sumOfSquares += ((q63_t) (in) * (in)); + in = *pSrc++ >> 8; + sum += in; + sumOfSquares += ((q63_t) (in) * (in)); + in = *pSrc++ >> 8; + sum += in; + sumOfSquares += ((q63_t) (in) * (in)); + in = *pSrc++ >> 8; + sum += in; + sumOfSquares += ((q63_t) (in) * (in)); /* Decrement the loop counter */ blkCnt--; } - /* add two accumulators */ - sumSquare = sumSquare + sumSquare1; - /* 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[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++ >> 8; + sum += in; + sumOfSquares += ((q63_t) (in) * (in)); + + /* Decrement the loop counter */ + blkCnt--; + } + + /* Compute Mean of squares of the input samples + * and then store the result in a temporary variable, meanOfSquares. */ + meanOfSquares = sumOfSquares / (q63_t)(blockSize - 1); + #else /* Run the below code for Cortex-M0 */ + + /* Loop over blockSize number of values */ blkCnt = blockSize; -#endif /* #ifndef ARM_MATH_CM0_FAMILY */ - while(blkCnt > 0u) { /* 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++; - sumSquare += ((q63_t) (in) * (in)); + /* Compute Sum of squares of the input samples + * and then store the result in a temporary variable, sumOfSquares. */ + in = *pSrc++ >> 8; + sumOfSquares += ((q63_t) (in) * (in)); + + /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */ + /* Compute sum of all input values and then store the result in a temporary variable, sum. */ sum += in; /* Decrement the loop counter */ blkCnt--; } - t = (q31_t) ((1.0f / (float32_t) (blockSize - 1u)) * 1073741824.0f); - - /* Compute Mean of squares of the input samples + /* Compute Mean of squares of the input samples * and then store the result in a temporary variable, meanOfSquares. */ - sumSquare = (sumSquare >> 31); - meanOfSquares = (q31_t) ((sumSquare * t) >> 30); + meanOfSquares = sumOfSquares / (q63_t)(blockSize - 1); - /* Compute mean of all input values */ - t = (q31_t) ((1.0f / (blockSize * (blockSize - 1u))) * 2147483648.0f); - mean = (q31_t) (sum); +#endif /* #ifndef ARM_MATH_CM0_FAMILY */ /* 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 variance and then store the result to the destination */ - *pResult = (q63_t) meanOfSquares - squareOfMean; + /* Compute standard deviation and then store the result to the destination */ + *pResult = (meanOfSquares - squareOfMean) >> 15; }