PageRenderTime 44ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/CMSIS/DSP_Lib/Source/StatisticsFunctions/arm_std_q15.c

https://gitlab.com/locsonpham/demeter_weatherstation
C | 197 lines | 66 code | 35 blank | 96 comment | 0 complexity | 9e66dd741f2c0669930561393bd1fcbd MD5 | raw file
  1. /* ----------------------------------------------------------------------
  2. * Copyright (C) 2010 ARM Limited. All rights reserved.
  3. *
  4. * $Date: 15. February 2012
  5. * $Revision: V1.1.0
  6. *
  7. * Project: CMSIS DSP Library
  8. * Title: arm_std_q15.c
  9. *
  10. * Description: Standard deviation of an array of Q15 type.
  11. *
  12. * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
  13. *
  14. * Version 1.1.0 2012/02/15
  15. * Updated with more optimizations, bug fixes and minor API changes.
  16. *
  17. * Version 1.0.10 2011/7/15
  18. * Big Endian support added and Merged M0 and M3/M4 Source code.
  19. *
  20. * Version 1.0.3 2010/11/29
  21. * Re-organized the CMSIS folders and updated documentation.
  22. *
  23. * Version 1.0.2 2010/11/11
  24. * Documentation updated.
  25. *
  26. * Version 1.0.1 2010/10/05
  27. * Production release and review comments incorporated.
  28. *
  29. * Version 1.0.0 2010/09/20
  30. * Production release and review comments incorporated.
  31. * -------------------------------------------------------------------- */
  32. #include "arm_math.h"
  33. /**
  34. * @ingroup groupStats
  35. */
  36. /**
  37. * @addtogroup STD
  38. * @{
  39. */
  40. /**
  41. * @brief Standard deviation of the elements of a Q15 vector.
  42. * @param[in] *pSrc points to the input vector
  43. * @param[in] blockSize length of the input vector
  44. * @param[out] *pResult standard deviation value returned here
  45. * @return none.
  46. *
  47. * @details
  48. * <b>Scaling and Overflow Behavior:</b>
  49. *
  50. * \par
  51. * The function is implemented using a 64-bit internal accumulator.
  52. * The input is represented in 1.15 format.
  53. * Intermediate multiplication yields a 2.30 format, and this
  54. * result is added without saturation to a 64-bit accumulator in 34.30 format.
  55. * With 33 guard bits in the accumulator, there is no risk of overflow, and the
  56. * full precision of the intermediate multiplication is preserved.
  57. * Finally, the 34.30 result is truncated to 34.15 format by discarding the lower
  58. * 15 bits, and then saturated to yield a result in 1.15 format.
  59. */
  60. void arm_std_q15(
  61. q15_t * pSrc,
  62. uint32_t blockSize,
  63. q15_t * pResult)
  64. {
  65. q31_t sum = 0; /* Accumulator */
  66. q31_t meanOfSquares, squareOfMean; /* square of mean and mean of square */
  67. q15_t mean; /* mean */
  68. uint32_t blkCnt; /* loop counter */
  69. q15_t t; /* Temporary variable */
  70. q63_t sumOfSquares = 0; /* Accumulator */
  71. #ifndef ARM_MATH_CM0
  72. /* Run the below code for Cortex-M4 and Cortex-M3 */
  73. q31_t in; /* input value */
  74. q15_t in1; /* input value */
  75. /*loop Unrolling */
  76. blkCnt = blockSize >> 2u;
  77. /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
  78. ** a second loop below computes the remaining 1 to 3 samples. */
  79. while(blkCnt > 0u)
  80. {
  81. /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
  82. /* Compute Sum of squares of the input samples
  83. * and then store the result in a temporary variable, sum. */
  84. in = *__SIMD32(pSrc)++;
  85. sum += ((in << 16) >> 16);
  86. sum += (in >> 16);
  87. sumOfSquares = __SMLALD(in, in, sumOfSquares);
  88. in = *__SIMD32(pSrc)++;
  89. sum += ((in << 16) >> 16);
  90. sum += (in >> 16);
  91. sumOfSquares = __SMLALD(in, in, sumOfSquares);
  92. /* Decrement the loop counter */
  93. blkCnt--;
  94. }
  95. /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
  96. ** No loop unrolling is used. */
  97. blkCnt = blockSize % 0x4u;
  98. while(blkCnt > 0u)
  99. {
  100. /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
  101. /* Compute Sum of squares of the input samples
  102. * and then store the result in a temporary variable, sum. */
  103. in1 = *pSrc++;
  104. sumOfSquares = __SMLALD(in1, in1, sumOfSquares);
  105. sum += in1;
  106. /* Decrement the loop counter */
  107. blkCnt--;
  108. }
  109. /* Compute Mean of squares of the input samples
  110. * and then store the result in a temporary variable, meanOfSquares. */
  111. t = (q15_t) ((1.0 / (blockSize - 1)) * 16384LL);
  112. sumOfSquares = __SSAT((sumOfSquares >> 15u), 16u);
  113. meanOfSquares = (q31_t) ((sumOfSquares * t) >> 14u);
  114. /* Compute mean of all input values */
  115. t = (q15_t) ((1.0 / (blockSize * (blockSize - 1))) * 32768LL);
  116. mean = (q15_t) __SSAT(sum, 16u);
  117. /* Compute square of mean */
  118. squareOfMean = ((q31_t) mean * mean) >> 15;
  119. squareOfMean = (q31_t) (((q63_t) squareOfMean * t) >> 15);
  120. /* mean of the squares minus the square of the mean. */
  121. in1 = (q15_t) (meanOfSquares - squareOfMean);
  122. /* Compute standard deviation and store the result to the destination */
  123. arm_sqrt_q15(in1, pResult);
  124. #else
  125. /* Run the below code for Cortex-M0 */
  126. q15_t in; /* input value */
  127. /* Loop over blockSize number of values */
  128. blkCnt = blockSize;
  129. while(blkCnt > 0u)
  130. {
  131. /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
  132. /* Compute Sum of squares of the input samples
  133. * and then store the result in a temporary variable, sumOfSquares. */
  134. in = *pSrc++;
  135. sumOfSquares += (in * in);
  136. /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
  137. /* Compute sum of all input values and then store the result in a temporary variable, sum. */
  138. sum += in;
  139. /* Decrement the loop counter */
  140. blkCnt--;
  141. }
  142. /* Compute Mean of squares of the input samples
  143. * and then store the result in a temporary variable, meanOfSquares. */
  144. t = (q15_t) ((1.0 / (blockSize - 1)) * 16384LL);
  145. sumOfSquares = __SSAT((sumOfSquares >> 15u), 16u);
  146. meanOfSquares = (q31_t) ((sumOfSquares * t) >> 14u);
  147. /* Compute mean of all input values */
  148. mean = (q15_t) __SSAT(sum, 16u);
  149. /* Compute square of mean of the input samples
  150. * and then store the result in a temporary variable, squareOfMean.*/
  151. t = (q15_t) ((1.0 / (blockSize * (blockSize - 1))) * 32768LL);
  152. squareOfMean = ((q31_t) mean * mean) >> 15;
  153. squareOfMean = (q31_t) (((q63_t) squareOfMean * t) >> 15);
  154. /* mean of the squares minus the square of the mean. */
  155. in = (q15_t) (meanOfSquares - squareOfMean);
  156. /* Compute standard deviation and store the result to the destination */
  157. arm_sqrt_q15(in, pResult);
  158. #endif /* #ifndef ARM_MATH_CM0 */
  159. }
  160. /**
  161. * @} end of STD group
  162. */