Задача: Подсчет среднего значения и дисперсии числового ряда

Эта задача имеет очень большое практическое применение: в статистической обработке данных, обработке временных рядов, в цифровой обработке сигналов применительно к цифровым отсчётам сигнала. Постановка задачи такая:

— вводится последовательность (вещественных) чисел …
— нужно просчитать, в итоге, среднее значение и дисперсию (или СКО: средне-квадратичное отклонение) числового ряда.

Напоминание для тех, кто не дружит с математикой:
— для последовательности N чисел a1, a2, … aN
— среднее значение вычисляем как M = 1 / N * SUM( i=1, N, ai )
— дисперсию вычисляем как D = 1 / N * SUM( i=1, N, ( ai — M ) ** 2 )
— СКО вычисляем как S = SQRT( D )

Фишка здесь в том, что для вычисления дисперсии прежде нужно вычислить среднее значение M. Но такое прямое вычисление потребует 2-х проходов по последовательности: сначала для вычисления M, а затем снова для вычисления D. Это непозволительная роскошь, если нужно делать вычисления для ряда в 10 000, 100 000 или 1 000 000 значений. Вычисления нужно произвести в один проход, без хранения всей последовательности: после ввода очередного числа все предыдущие теряются…

Подсказка: прежде программирования попробуйте преобразовать выражение для D так, чтобы входящее значение M вынести из-под операции суммирования.

Решение:

Прежде, чем писать код, займёмся преобразованием формулы для вычисления дисперсии (раскроем квадрат разности под суммой):

D = 1 / N * SUM( i=1, N, ( ai — M ) ** 2 ) =

= 1 / N * SUM( i=1, N, ai ** 2 ) 2 * 1 / N * SUM( i=1, N, ai ** 2 ) * M + 1 / N * N * M ** 2 =

= 1 / N * SUM( i=1, N, ai ** 2 ) — 2 * M ** 2 + M ** 2 =

= 1 / N * SUM( i=1, N, ai ** 2 ) — M ** 2

Или, если выразить это словами: усреднённая (делённая на N) сумма квадратов чисел, минус квадрат их среднего. Теперь мы можем по ходу поступления чисел ряда накапливать их сумму (s1 — для последующего вычисления среднего) и сумму квадратов (s2 — для последующего вычисления дисперсии), а вычисление итоговых характеристик отложить до завершения поступления числового ряда.

А теперь спокойно пишем реализующий это код:

Всего то! (код сильно упрощён: весь числовой ряд вводится в одной строке, заканчивающейся Enter, не включена обработка ошибочного ввода и др.).

А теперь — как это работает:

задача с решением, практика программирования на с++, Подсчет среднего значения и десперсии числового ряда

На ваши вопросы ответим в комментариях.

Рассылка новых уроков по программированию:

Дата
Страница
Задача: Подсчет среднего значения и дисперсии числового ряда
Рейтинг
51star1star1star1star1star
Olej

Об авторе Olej

Стаж практических программных разработок около 40 лет. Преподаватель международной софтверной компании Global Logic. Постоянный автор публикаций IBM Developer Works. Научный редактор книжного издательства компьютерной литературы "Символ-Плюс", Санкт-Петербург.

Добавить комментарий

Код размещайте в тегах: <pre class="lang:c++ decode:true ">YOUR CODE</pre>