Основы программирования на С++ для начинающих

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

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

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

Напоминание для тех, кто не дружит с математикой:
– для последовательности 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, не включена обработка ошибочного ввода и др.).

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

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

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *