Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dsp by
arm_var_q31.c
00001 /* ---------------------------------------------------------------------- 00002 * Copyright (C) 2010-2013 ARM Limited. All rights reserved. 00003 * 00004 * $Date: 17. January 2013 00005 * $Revision: V1.4.1 00006 * 00007 * Project: CMSIS DSP Library 00008 * Title: arm_var_q31.c 00009 * 00010 * Description: Variance of an array of Q31 type. 00011 * 00012 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0 00013 * 00014 * Redistribution and use in source and binary forms, with or without 00015 * modification, are permitted provided that the following conditions 00016 * are met: 00017 * - Redistributions of source code must retain the above copyright 00018 * notice, this list of conditions and the following disclaimer. 00019 * - Redistributions in binary form must reproduce the above copyright 00020 * notice, this list of conditions and the following disclaimer in 00021 * the documentation and/or other materials provided with the 00022 * distribution. 00023 * - Neither the name of ARM LIMITED nor the names of its contributors 00024 * may be used to endorse or promote products derived from this 00025 * software without specific prior written permission. 00026 * 00027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00028 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00029 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00030 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00031 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00032 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00033 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00034 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00035 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00036 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00037 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00038 * POSSIBILITY OF SUCH DAMAGE. 00039 * -------------------------------------------------------------------- */ 00040 00041 #include "arm_math.h" 00042 00043 /** 00044 * @ingroup groupStats 00045 */ 00046 00047 /** 00048 * @addtogroup variance 00049 * @{ 00050 */ 00051 00052 /** 00053 * @brief Variance of the elements of a Q31 vector. 00054 * @param[in] *pSrc points to the input vector 00055 * @param[in] blockSize length of the input vector 00056 * @param[out] *pResult variance value returned here 00057 * @return none. 00058 * 00059 * @details 00060 * <b>Scaling and Overflow Behavior:</b> 00061 * 00062 *\par 00063 * The function is implemented using an internal 64-bit accumulator. 00064 * The input is represented in 1.31 format, and intermediate multiplication 00065 * yields a 2.62 format. 00066 * The accumulator maintains full precision of the intermediate multiplication results, 00067 * but provides only a single guard bit. 00068 * There is no saturation on intermediate additions. 00069 * If the accumulator overflows it wraps around and distorts the result. 00070 * In order to avoid overflows completely the input signal must be scaled down by 00071 * log2(blockSize) bits, as a total of blockSize additions are performed internally. 00072 * Finally, the 2.62 accumulator is right shifted by 31 bits to yield a 1.31 format value. 00073 * 00074 */ 00075 00076 00077 void arm_var_q31( 00078 q31_t * pSrc, 00079 uint32_t blockSize, 00080 q63_t * pResult) 00081 { 00082 q63_t sum = 0, sumSquare = 0; /* Accumulator */ 00083 q31_t meanOfSquares, squareOfMean; /* square of mean and mean of square */ 00084 q31_t mean; /* mean */ 00085 q31_t in; /* input value */ 00086 q31_t t; /* Temporary variable */ 00087 uint32_t blkCnt; /* loop counter */ 00088 00089 #ifndef ARM_MATH_CM0_FAMILY 00090 00091 /* Run the below code for Cortex-M4 and Cortex-M3 */ 00092 q63_t sumSquare1 = 0; /* Accumulator */ 00093 q31_t in1, in2, in3, in4; /* Temporary input variables */ 00094 00095 /*loop Unrolling */ 00096 blkCnt = blockSize >> 2u; 00097 00098 /* First part of the processing with loop unrolling. Compute 4 outputs at a time. 00099 ** a second loop below computes the remaining 1 to 3 samples. */ 00100 while(blkCnt > 0u) 00101 { 00102 /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */ 00103 /* Compute Sum of squares of the input samples 00104 * and then store the result in a temporary variable, sum. */ 00105 /* read input samples from source buffer */ 00106 in1 = pSrc[0]; 00107 in2 = pSrc[1]; 00108 00109 /* calculate sum of inputs */ 00110 sum += in1; 00111 /* calculate sum of squares */ 00112 sumSquare += ((q63_t) (in1) * (in1)); 00113 in3 = pSrc[2]; 00114 sum += in2; 00115 sumSquare1 += ((q63_t) (in2) * (in2)); 00116 in4 = pSrc[3]; 00117 sum += in3; 00118 sumSquare += ((q63_t) (in3) * (in3)); 00119 sum += in4; 00120 sumSquare1 += ((q63_t) (in4) * (in4)); 00121 00122 /* update input pointer to process next samples */ 00123 pSrc += 4u; 00124 00125 /* Decrement the loop counter */ 00126 blkCnt--; 00127 } 00128 00129 /* add two accumulators */ 00130 sumSquare = sumSquare + sumSquare1; 00131 00132 /* If the blockSize is not a multiple of 4, compute any remaining output samples here. 00133 ** No loop unrolling is used. */ 00134 blkCnt = blockSize % 0x4u; 00135 00136 #else 00137 00138 /* Run the below code for Cortex-M0 */ 00139 blkCnt = blockSize; 00140 00141 #endif /* #ifndef ARM_MATH_CM0_FAMILY */ 00142 00143 while(blkCnt > 0u) 00144 { 00145 /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */ 00146 /* Compute Sum of squares of the input samples 00147 * and then store the result in a temporary variable, sum. */ 00148 in = *pSrc++; 00149 sumSquare += ((q63_t) (in) * (in)); 00150 sum += in; 00151 00152 /* Decrement the loop counter */ 00153 blkCnt--; 00154 } 00155 00156 t = (q31_t) ((1.0f / (float32_t) (blockSize - 1u)) * 1073741824.0f); 00157 00158 /* Compute Mean of squares of the input samples 00159 * and then store the result in a temporary variable, meanOfSquares. */ 00160 sumSquare = (sumSquare >> 31); 00161 meanOfSquares = (q31_t) ((sumSquare * t) >> 30); 00162 00163 /* Compute mean of all input values */ 00164 t = (q31_t) ((1.0f / (blockSize * (blockSize - 1u))) * 2147483648.0f); 00165 mean = (q31_t) (sum); 00166 00167 /* Compute square of mean */ 00168 squareOfMean = (q31_t) (((q63_t) mean * mean) >> 31); 00169 squareOfMean = (q31_t) (((q63_t) squareOfMean * t) >> 31); 00170 00171 /* Compute variance and then store the result to the destination */ 00172 *pResult = (q63_t) meanOfSquares - squareOfMean; 00173 00174 } 00175 00176 /** 00177 * @} end of variance group 00178 */
Generated on Tue Jul 12 2022 18:44:10 by
1.7.2
