Task[edit]
Write a stateful function, class, generator or co-routine that takes a series of floating point numbers, one at a time, and returns the running standard deviation of the series.

The task implementation should use the most natural programming style of those listed for the function in the implementation language; the task must state which is being used.

Do not apply Bessel's correction; the returned standard deviation should always be computed as if the sample seen so far is the entire population.



Test case

Use this to compute the standard deviation of this demonstration set, 



{
2
,
4
,
4
,
4
,
5
,
5
,
7
,
9
}


{\displaystyle \{2,4,4,4,5,5,7,9\}}

, which is 



2


{\displaystyle 2}

.



Related tasks

 Random numbers


Tasks for calculating statistical measures



in one go
moving (sliding window)
moving (cumulative)

Mean
Arithmetic

Statistics/Basic
Averages/Arithmetic mean
Averages/Pythagorean means


Averages/Simple moving average




Geometric

Averages/Pythagorean means




Harmonic

Averages/Pythagorean means




Quadratic

Averages/Root mean square




Circular

Averages/Mean angle
Averages/Mean time of day




Median

Averages/Median




Mode

Averages/Mode




Standard deviation

Statistics/Basic



Cumulative standard deviation




 
program standard_deviation
  implicit none
  integer(kind=4), parameter :: dp = kind(0.0d0)
 
  real(kind=dp), dimension(:), allocatable :: vals
  integer(kind=4) :: i
 
  real(kind=dp), dimension(8) :: sample_data = (/ 2, 4, 4, 4, 5, 5, 7, 9 /)
 
  do i = lbound(sample_data, 1), ubound(sample_data, 1)
    call sample_add(vals, sample_data(i))
    write(*, fmt='(''#'',I1,1X,''value = '',F3.1,1X,''stddev ='',1X,F10.8)') &
      i, sample_data(i), stddev(vals)
  end do
 
  if (allocated(vals)) deallocate(vals)
contains
  ! Adds value :val: to array :population: dynamically resizing array
  subroutine sample_add(population, val)
    real(kind=dp), dimension(:), allocatable, intent (inout) :: population
    real(kind=dp), intent (in) :: val
 
    real(kind=dp), dimension(:), allocatable :: tmp
    integer(kind=4) :: n
 
    if (.not. allocated(population)) then
      allocate(population(1))
      population(1) = val
    else
      n = size(population)
      call move_alloc(population, tmp)
 
      allocate(population(n + 1))
      population(1:n) = tmp
      population(n + 1) = val
    endif
  end subroutine sample_add
 
  ! Calculates standard deviation for given set of values
  real(kind=dp) function stddev(vals)
    real(kind=dp), dimension(:), intent(in) :: vals
    real(kind=dp) :: mean
    integer(kind=4) :: n
 
    n = size(vals)
    mean = sum(vals)/n
    stddev = sqrt(sum((vals - mean)**2)/n)
  end function stddev
end program standard_deviation
 