Merge branch 'jnosky/master'
[fw/stlink] / exampleF4 / CMSIS / DSP_Lib / Source / StatisticsFunctions / arm_var_f32.c
1 /* ----------------------------------------------------------------------   
2 * Copyright (C) 2010 ARM Limited. All rights reserved.   
3 *   
4 * $Date:        15. July 2011  
5 * $Revision:    V1.0.10  
6 *   
7 * Project:          CMSIS DSP Library   
8 * Title:                arm_var_f32.c   
9 *   
10 * Description:  Variance of the elements of a floating-point vector.   
11 *   
12 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
13 *  
14 * Version 1.0.10 2011/7/15 
15 *    Big Endian support added and Merged M0 and M3/M4 Source code.  
16 *   
17 * Version 1.0.3 2010/11/29  
18 *    Re-organized the CMSIS folders and updated documentation.   
19 *    
20 * Version 1.0.2 2010/11/11   
21 *    Documentation updated.    
22 *   
23 * Version 1.0.1 2010/10/05    
24 *    Production release and review comments incorporated.   
25 *   
26 * Version 1.0.0 2010/09/20    
27 *    Production release and review comments incorporated.   
28 * ---------------------------------------------------------------------------- */
29
30 #include "arm_math.h"
31
32 /**   
33  * @ingroup groupStats   
34  */
35
36 /**   
37  * @defgroup variance  Variance   
38  *   
39  * Calculates the variance of the elements in the input vector.   
40  * The underlying algorithm is used:   
41  *   
42  * <pre>   
43  *      Result = (sumOfSquares - sum<sup>2</sup> / blockSize) / (blockSize - 1)  
44  *  
45  *         where, sumOfSquares = pSrc[0] * pSrc[0] + pSrc[1] * pSrc[1] + ... + pSrc[blockSize-1] * pSrc[blockSize-1]  
46  *  
47  *                         sum = pSrc[0] + pSrc[1] + pSrc[2] + ... + pSrc[blockSize-1]  
48  * </pre>  
49  *   
50  * There are separate functions for floating point, Q31, and Q15 data types.   
51  */
52
53 /**   
54  * @addtogroup variance   
55  * @{   
56  */
57
58
59 /**   
60  * @brief Variance of the elements of a floating-point vector.   
61  * @param[in]       *pSrc points to the input vector   
62  * @param[in]       blockSize length of the input vector   
63  * @param[out]      *pResult variance value returned here   
64  * @return none.   
65  *   
66  */
67
68
69 void arm_var_f32(
70   float32_t * pSrc,
71   uint32_t blockSize,
72   float32_t * pResult)
73 {
74
75 #ifndef ARM_MATH_CM0
76
77   /* Run the below code for Cortex-M4 and Cortex-M3 */
78
79   float32_t sum = (float32_t) 0.0;               /* Accumulator */
80   float32_t meanOfSquares, mean, in, squareOfMean;      /* Temporary variables */
81   uint32_t blkCnt;                               /* loop counter */
82   float32_t *pIn;                                /* Temporary pointer */
83
84   /* updating temporary pointer */
85   pIn = pSrc;
86
87   /*loop Unrolling */
88   blkCnt = blockSize >> 2u;
89
90   /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.   
91    ** a second loop below computes the remaining 1 to 3 samples. */
92   while(blkCnt > 0u)
93   {
94     /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1])  */
95     /* Compute Sum of squares of the input samples   
96      * and then store the result in a temporary variable, sum. */
97     in = *pSrc++;
98     sum += in * in;
99     in = *pSrc++;
100     sum += in * in;
101     in = *pSrc++;
102     sum += in * in;
103     in = *pSrc++;
104     sum += in * in;
105
106     /* Decrement the loop counter */
107     blkCnt--;
108   }
109
110   /* If the blockSize is not a multiple of 4, compute any remaining output samples here.   
111    ** No loop unrolling is used. */
112   blkCnt = blockSize % 0x4u;
113
114   while(blkCnt > 0u)
115   {
116     /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
117     /* Compute Sum of squares of the input samples   
118      * and then store the result in a temporary variable, sum. */
119     in = *pSrc++;
120     sum += in * in;
121
122     /* Decrement the loop counter */
123     blkCnt--;
124   }
125
126   /* Compute Mean of squares of the input samples   
127    * and then store the result in a temporary variable, meanOfSquares. */
128   meanOfSquares = sum / ((float32_t) blockSize - 1.0f);
129
130   /* Reset the accumulator */
131   sum = 0.0f;
132
133   /*loop Unrolling */
134   blkCnt = blockSize >> 2u;
135
136   /* Reset the input working pointer */
137   pSrc = pIn;
138
139   /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.   
140    ** a second loop below computes the remaining 1 to 3 samples. */
141   while(blkCnt > 0u)
142   {
143     /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
144     /* Compute sum of all input values and then store the result in a temporary variable, sum. */
145     sum += *pSrc++;
146     sum += *pSrc++;
147     sum += *pSrc++;
148     sum += *pSrc++;
149
150     /* Decrement the loop counter */
151     blkCnt--;
152   }
153
154   /* If the blockSize is not a multiple of 4, compute any remaining output samples here.   
155    ** No loop unrolling is used. */
156   blkCnt = blockSize % 0x4u;
157
158   while(blkCnt > 0u)
159   {
160     /* C = (A[0] + A[1] + A[2] + ... + A[blockSize-1]) */
161     /* Compute sum of all input values and then store the result in a temporary variable, sum. */
162     sum += *pSrc++;
163
164     /* Decrement the loop counter */
165     blkCnt--;
166   }
167   /* Compute mean of all input values */
168   mean = sum / (float32_t) blockSize;
169
170   /* Compute square of mean */
171   squareOfMean = (mean * mean) * (((float32_t) blockSize) /
172                                   ((float32_t) blockSize - 1.0f));
173
174   /* Compute variance and then store the result to the destination */
175   *pResult = meanOfSquares - squareOfMean;
176
177 #else
178
179   /* Run the below code for Cortex-M0 */
180
181   float32_t sum = 0.0f;                          /* Temporary result storage */
182   float32_t sumOfSquares = 0.0f;                 /* Sum of squares */
183   float32_t squareOfSum;                         /* Square of Sum */
184   float32_t in;                                  /* input value */
185   uint32_t blkCnt;                               /* loop counter */
186
187   /* Loop over blockSize number of values */
188   blkCnt = blockSize;
189
190   while(blkCnt > 0u)
191   {
192     /* C = (A[0] * A[0] + A[1] * A[1] + ... + A[blockSize-1] * A[blockSize-1]) */
193     /* Compute Sum of squares of the input samples    
194      * and then store the result in a temporary variable, sumOfSquares. */
195     in = *pSrc++;
196     sumOfSquares += in * in;
197
198     /* C = (A[0] + A[1] + ... + A[blockSize-1]) */
199     /* Compute Sum of the input samples    
200      * and then store the result in a temporary variable, sum. */
201     sum += in;
202
203     /* Decrement the loop counter */
204     blkCnt--;
205   }
206
207   /* Compute the square of sum */
208   squareOfSum = ((sum * sum) / (float32_t) blockSize);
209
210   /* Compute the variance */
211   *pResult = ((sumOfSquares - squareOfSum) / (float32_t) (blockSize - 1.0f));
212
213 #endif /* #ifndef ARM_MATH_CM0 */
214
215 }
216
217 /**   
218  * @} end of variance group   
219  */