This problem is of great practical use: in statistical data processing, time series processing, digital signal processing with respect to the digital reference signal. Statement of the problem, such:
– introduced sequence (real) numbers …
– you need to calculate, eventually, mean and variance (or SKO: secondary deviation) numerical series.
Reminder for those, who are not friends with math:
– for a sequence of N numbers a1, a2, … aN
– the average value is calculated as M = 1 / N * SUM( i=1, N, to )
– We compute a dispersion D = 1 / N * SUM( i=1, N, ( to – M ) ** 2 )
– Standard deviation is calculated as S = SQRT( D )
The trick here is, that for the calculation of dispersion must first calculate the average value M. But such a direct calculation will require 2 passes in sequence: first to calculate M, and then again to calculate D. This is an inadmissible luxury., if you want to do the calculations for a number in 10 000, 100 000 or 1 000 000 values. Calculations need to be done in one pass., without storing the entire sequence: after entering the next number all previous ones are lost…
Tip: programming first try to transform the expression for D so, to remove the input value of M from the summation operation.
Decision:
before, than to write code, zaymёmsya conversion formulas for calculating variance (reveal a sum of squared difference):
D = 1 / N * SUM( i=1, N, ( to – M ) ** 2 ) =
= 1 / N * SUM( i=1, N, to ** 2 ) – 2 * 1 / N * SUM( i=1, N, to ** 2 ) * M + 1 / N * N * M ** 2 =
= 1 / N * SUM( i=1, N, to ** 2 ) – 2 * M ** 2 + M ** 2 =
= 1 / N * SUM( i=1, N, to ** 2 ) – M ** 2
Or, if you put it into words: averaged (делённая на N) sum of squares numbers, minus square their average. Now we can during numbers of the series proceeds to accumulate their sum (s1 – for the subsequent calculation of the mean) and the sum of squares (s2 – for the subsequent calculation of variance), and the calculation of the final characteristics to postpone the Incoming number series.
Now, quietly writing implements this code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include <iostream> #include <sstream> using namespace std; int main() { setlocale(LC_ALL, "rus"); string e; int n; // счётчик чисел double d, s1, s2; while (true) { s1 = s2 = 0.0; n = 0; cout << "Вводите последовательность чисел: "; getline(cin, e); istringstream ist(e); while (ist >> d) { n++; s1 += d; s2 += d * d; } s1 /= n; s2 = s2 / n - s1 * s1; cout << "Введено чисел " << n << ", среднее = " << s1 << ", дисперсия = " << s2 << endl; } } |
Just! (greatly simplified code: all numerical number entered in one line, Enter ending, not including the handling of erroneous input, and others.).
And now – how it works: