Movatterモバイル変換


[0]ホーム

URL:


Jump to content
Rosetta Code
Search

Cumulative standard deviation

From Rosetta Code
Task
Cumulative standard deviation
You are encouraged tosolve this task according to the task description, using any language you may know.
Task

Write a stateful function, class, generator or co-routine that takes a series of floating point numbers,one at a time, and returns the runningstandard 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 taskmust state which is being used.

Do not applyBessel'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 {\displaystyle \{2,4,4,4,5,5,7,9\}}}, which is2{\displaystyle {\displaystyle 2}}.


Related tasks


Tasks for calculating statistical measures

11l

Translation of:Python:_Callable_class
T SD   sum = 0.0   sum2 = 0.0   n = 0.0   F ()(x)      .sum += x      .sum2 += x ^ 2      .n += 1.0      R sqrt(.sum2 / .n - (.sum / .n) ^ 2)V sd_inst = SD()L(value) [2, 4, 4, 4, 5, 5, 7, 9]   print(value‘ ’sd_inst(value))
Output:
2 04 14 0.9428090424 0.8660254045 0.9797958975 17 1.3997084249 2

360 Assembly

For maximum compatibility, this program uses only the basic instruction set. Part of the code length is due to the square root algorithm and to the nice output.

******** Standard deviation of a populationSTDDEV   CSECT         USING  STDDEV,R13SAVEAREA B      STM-SAVEAREA(R15)         DC     17F'0'         DC     CL8'STDDEV'STM      STM    R14,R12,12(R13)         ST     R13,4(R15)         ST     R15,8(R13)         LR     R13,R15         SR     R8,R8           s=0         SR     R9,R9           ss=0         SR     R4,R4           i=0         LA     R6,1         LH     R7,NLOOPI    BXH    R4,R6,ENDLOOPI         LR     R1,R4           i         BCTR   R1,0         SLA    R1,1         LH     R5,T(R1)         ST     R5,WW           ww=t(i)         MH     R5,=H'1000'     w=ww*1000         AR     R8,R5           s=s+w         LR     R15,R5         MR     R14,R5          w*w         AR     R9,R15          ss=ss+w*w         LR     R14,R8          s         SRDA   R14,32         DR     R14,R4          /i         ST     R15,AVG         avg=s/i         LR     R14,R9          ss         SRDA   R14,32         DR     R14,R4          ss/i         LR     R2,R15          ss/i         LR     R15,R8          s         MR     R14,R8          s*s         LR     R3,R15         LR     R15,R4          i         MR     R14,R4          i*i         LR     R1,R15         LA     R14,0         LR     R15,R3         DR     R14,R1          (s*s)/(i*i)         SR     R2,R15         LR     R10,R2          std=ss/i-(s*s)/(i*i)         LR     R11,R10         std         SRA    R11,1           x=std/2         LR     R12,R10         px=stdLOOPWHIL EQU    *         CR     R12,R11         while px<>=x         BE     ENDWHILE         LR     R12,R11         px=x         LR     R15,R10         std         LA     R14,0         DR     R14,R12         /px         LR     R1,R12          px         AR     R1,R15          px+std/px         SRA    R1,1            /2         LR     R11,R1          x=(px+std/px)/2         B      LOOPWHILENDWHILE EQU    *         LR     R10,R11         CVD    R4,P8           i         MVC    C17,MASK17         ED     C17,P8         MVC    BUF+2(1),C17+15         L      R1,WW         CVD    R1,P8         MVC    C17,MASK17         ED     C17,P8         MVC    BUF+10(1),C17+15         L      R1,AVG         CVD    R1,P8         MVC    C18,MASK18         ED     C18,P8         MVC    BUF+17(5),C18+12         CVD    R10,P8          std         MVC    C18,MASK18         ED     C18,P8         MVC    BUF+31(5),C18+12         WTO    MF=(E,WTOMSG)           B      LOOPIENDLOOPI EQU    *         L      R13,4(0,R13)         LM     R14,R12,12(R13)         XR     R15,R15         BR     R14         DS     0DN        DC     H'8'T        DC     H'2',H'4',H'4',H'4',H'5',H'5',H'7',H'9'WW       DS     FAVG      DS     FP8       DS     PL8MASK17   DC     C' ',13X'20',X'2120',C'-'              MASK18   DC     C' ',10X'20',X'2120',C'.',3X'20',C'-' C17      DS     CL17C18      DS     CL18WTOMSG   DS     0F         DC     H'80',XL2'0000'BUF      DC     CL80'N=1  ITEM=1  AVG=1.234  STDDEV=1.234 '         YREGS           END    STDDEV
Output:
N=1  ITEM=2  AVG=2.000  STDDEV=0.000N=2  ITEM=4  AVG=3.000  STDDEV=1.000N=3  ITEM=4  AVG=3.333  STDDEV=0.942N=4  ITEM=4  AVG=3.500  STDDEV=0.866N=5  ITEM=5  AVG=3.800  STDDEV=0.979N=6  ITEM=5  AVG=4.000  STDDEV=1.000N=7  ITEM=7  AVG=4.428  STDDEV=1.399N=8  ITEM=9  AVG=5.000  STDDEV=2.000

Action!

Library:Action! Tool Kit
Library:Action! Real Math
INCLUDE "H6:REALMATH.ACT"REAL sum,sum2INT countPROC Calc(REAL POINTER x,sd)  REAL tmp1,tmp2,tmp3  RealAdd(sum,x,tmp1)       ;tmp1=sum+x  RealAssign(tmp1,sum)      ;sum=sum+x  RealMult(x,x,tmp1)        ;tmp1=x*x  RealAdd(sum2,tmp1,tmp2)   ;tmp2=sum2+x*x  RealAssign(tmp2,sum2)     ;sum2=sum2+x*x  count==+1  IF count=0 THEN    IntToReal(0,sd)         ;sd=0  ELSE    IntToReal(count,tmp1)    RealMult(sum,sum,tmp2)  ;tmp2=sum*sum    RealDiv(tmp2,tmp1,tmp3) ;tmp3=sum*sum/count    RealDiv(tmp3,tmp1,tmp2) ;tmp2=sum*sum/count/count    RealDiv(sum2,tmp1,tmp3) ;tmp3=sum2/count    RealSub(tmp3,tmp2,tmp1) ;tmp1=sum2/count-sum*sum/count/count    Sqrt(tmp1,sd)           ;sd=sqrt(sum2/count-sum*sum/count/count)  FIRETURNPROC Main()  INT ARRAY values=[2 4 4 4 5 5 7 9]  INT i  REAL x,sd  Put(125) PutE() ;clear screen  MathInit()  IntToReal(0,sum)  IntToReal(0,sum2)  count=0  FOR i=0 TO 7  DO    IntToReal(values(i),x)    Calc(x,sd)    Print("x=") PrintR(x)    Print(" sum=") PrintR(sum)    Print(" sd=") PrintRE(sd)  ODRETURN
Output:

Screenshot from Atari 8-bit computer

x=2 sum=2 sd=0x=4 sum=6 sd=1x=4 sum=10 sd=.942809052x=4 sum=14 sd=.86602541x=5 sum=19 sd=.979795903x=5 sum=24 sd=1x=7 sum=31 sd=1.39970843x=9 sum=40 sd=1.99999999

Ada

withAda.Numerics.Elementary_Functions;useAda.Numerics.Elementary_Functions;withAda.Numerics.Elementary_Functions;useAda.Numerics.Elementary_Functions;withAda.Text_IO;useAda.Text_IO;withAda.Float_Text_IO;useAda.Float_Text_IO;withAda.Integer_Text_IO;useAda.Integer_Text_IO;procedureTest_DeviationistypeSampleisrecordN:Natural:=0;Sum:Float:=0.0;SumOfSquares:Float:=0.0;end record;procedureAdd(Data:inoutSample;Point:Float)isbeginData.N:=Data.N+1;Data.Sum:=Data.Sum+Point;Data.SumOfSquares:=Data.SumOfSquares+Point**2;endAdd;functionDeviation(Data:Sample)returnFloatisbeginreturnSqrt(Data.SumOfSquares/Float(Data.N)-(Data.Sum/Float(Data.N))**2);endDeviation;Data:Sample;Test:array(1..8)ofInteger:=(2,4,4,4,5,5,7,9);beginforIndexinTest'RangeloopAdd(Data,Float(Test(Index)));Put("N=");Put(Item=>Index,Width=>1);Put(" ITEM=");Put(Item=>Test(Index),Width=>1);Put(" AVG=");Put(Item=>Float(Data.Sum)/Float(Index),Fore=>1,Aft=>3,Exp=>0);Put("  STDDEV=");Put(Item=>Deviation(Data),Fore=>1,Aft=>3,Exp=>0);New_line;endloop;endTest_Deviation;
Output:
N=1 ITEM=2 AVG=2.000  STDDEV=0.000N=2 ITEM=4 AVG=3.000  STDDEV=1.000N=3 ITEM=4 AVG=3.333  STDDEV=0.943N=4 ITEM=4 AVG=3.500  STDDEV=0.866N=5 ITEM=5 AVG=3.800  STDDEV=0.980N=6 ITEM=5 AVG=4.000  STDDEV=1.000N=7 ITEM=7 AVG=4.429  STDDEV=1.400N=8 ITEM=9 AVG=5.000  STDDEV=2.000

ALGOL 60

Rogalgol

Translation of:ANSI BASIC
COMMENT Cumulative standard deviation;BEGINPROCEDURE init(n, sum, sumofsquares);  INTEGER n; REAL sum, sumofsquares;BEGIN  n := 0;  sum := 0.0;  sumofsquares := 0.0END;PROCEDURE add(n, sum, sumofsquares, p);  VALUE p; INTEGER n; REAL sum, sumofsquares, p;BEGIN  n := n + 1;  sum := sum + p;  sumofsquares := sumofsquares + p * pEND;REAL PROCEDURE deviation(n, sum, sumofsquares);  VALUE n, sum, sumofsquares; INTEGER n; REAL sum, sumofsquares;BEGIN  REAL sumdivn;  sumdivn := sum / n;  deviation := sqrt(sumofsquares / n - sumdivn * sumdivn)END;REAL ARRAY testdata[1 : 8];INTEGER n, i;REAL sum, sumofsquares;testdata[1] := 2;testdata[2] := 4;testdata[3] := 4;testdata[4] := 4;testdata[5] := 5;testdata[6] := 5;testdata[7] := 7;testdata[8] := 9;init(n, sum, sumofsquares);text(1, " N ITEM  AVG   STDDEV");skip(1);FOR i := 1 STEP 1 UNTIL 8 DOBEGIN  add(n, sum, sumofsquares, testdata[i]);  rwrite(1, i, 2, 0);  rwrite(1, testdata[i], 4, 0);  rwrite(1, sum / i, 6, 3);  rwrite(1, deviation(n, sum, sumofsquares), 6, 3);  skip(1)END;END FINISH
Output:
 N ITEM  AVG   STDDEV 1    2  2.000  0.000 2    4  3.000  1.000 3    4  3.333  0.943 4    4  3.500  0.866 5    5  3.800  0.980 6    5  4.000  1.000 7    7  4.429  1.400 8    9  5.000  2.000

ALGOL 68

Translation of:C
Works with:ALGOL 68 version Standard - no extensions to language used
Works with:ALGOL 68G version Any - tested with release 2.8-win32

Note: the use of a UNION to mimic C's enumerated types is "experimental" and probably not typical of "production code". However it is a example ofALGOL 68sconformity CASE clause useful for classroom dissection.

MODE VALUE = STRUCT(CHAR value),     STDDEV = STRUCT(CHAR stddev),     MEAN = STRUCT(CHAR mean),     VAR = STRUCT(CHAR var),     COUNT = STRUCT(CHAR count),     RESET = STRUCT(CHAR reset); MODE ACTION = UNION ( VALUE, STDDEV, MEAN, VAR, COUNT, RESET ); LONG REAL sum := 0;LONG REAL sum2 := 0;INT num := 0; PROC stat object = (LONG REAL v, ACTION action)LONG REAL:(   LONG REAL m;   CASE action IN  (VALUE):(    num +:= 1;    sum +:= v;    sum2 +:= v*v;    stat object(0, LOC STDDEV)  ),  (STDDEV):    long sqrt(stat object(0, LOC VAR)),  (MEAN):    IF num>0 THEN sum/LONG REAL(num) ELSE 0 FI,  (VAR):(    m := stat object(0, LOC MEAN);    IF num>0 THEN sum2/LONG REAL(num)-m*m ELSE 0 FI  ),  (COUNT):    num,  (RESET):    sum := sum2 := num := 0  ESAC); # main # (  []LONG REAL v = ( 2,4,4,4,5,5,7,9 );  LONG REAL sd;   FOR i FROM LWB v TO UPB v DO    sd := stat object(v[i], LOC VALUE);    printf(($"value: "g(0,6)," standard dev := "g(0,6)l$, v[i], sd))  OD )
Output:
value: 2.000000 standard dev := .000000value: 4.000000 standard dev := 1.000000value: 4.000000 standard dev := .942809value: 4.000000 standard dev := .866025value: 5.000000 standard dev := .979796value: 5.000000 standard dev := 1.000000value: 7.000000 standard dev := 1.399708value: 9.000000 standard dev := 2.000000
Translation of:Python
Works with:ALGOL 68 version Standard - no extensions to language used
Works with:ALGOL 68G version Any - tested with release 2.8-win32

A code sample in an object oriented style:

MODE STAT = STRUCT(  LONG REAL sum,  LONG REAL sum2,  INT num); OP INIT = (REF STAT new)REF STAT:  (init OF class stat)(new); MODE CLASSSTAT = STRUCT(  PROC (REF STAT, LONG REAL #value#)VOID plusab,  PROC (REF STAT)LONG REAL stddev, mean, variance, count,  PROC (REF STAT)REF STAT init); CLASSSTAT class stat; plusab OF class stat := (REF STAT self, LONG REAL value)VOID:(    num OF self +:= 1;    sum OF self +:= value;    sum2 OF self +:= value*value  ); OP +:= = (REF STAT lhs, LONG REAL rhs)VOID: # some syntatic sugar #  (plusab OF class stat)(lhs, rhs); stddev OF class stat := (REF STAT self)LONG REAL:    long sqrt((variance OF class stat)(self));# could define STDDEV as an operator for more syntatic sugar  OP STDDEV = ([]LONG REAL value)LONG REAL: (     REF STAT stat = INIT LOC STAT;    FOR i FROM LWB value TO UPB value DO      stat +:= value[i]    OD;    (stddev OF class stat)(stat)  );#mean OF class stat := (REF STAT self)LONG REAL:    sum OF self/LONG REAL(num OF self); variance OF class stat := (REF STAT self)LONG REAL:(    LONG REAL m = (mean OF class stat)(self);    sum2 OF self/LONG REAL(num OF self)-m*m  ); count OF class stat := (REF STAT self)LONG REAL:    num OF self; init OF class stat := (REF STAT self)REF STAT:(    sum OF self := sum2 OF self := num OF self := 0;    self  ); # main # (  []LONG REAL value = ( 2,4,4,4,5,5,7,9 );#  printf(($"standard deviation operator = "g(0,6)l$, STDDEV value));#  REF STAT stat = INIT LOC STAT;  FOR i FROM LWB value TO UPB value DO    stat +:= value[i];    printf(($"value: "g(0,6)," standard dev := "g(0,6)l$, value[i], (stddev OF class stat)(stat)))  OD;#  printf(($"standard deviation = "g(0,6)l$, (stddev OF class stat)(stat)));  printf(($"mean = "g(0,6)l$, (mean OF class stat)(stat)));  printf(($"variance = "g(0,6)l$, (variance OF class stat)(stat)));  printf(($"count = "g(0,6)l$, (count OF class stat)(stat)));#  SKIP)
Output:
value: 2.000000 standard dev := .000000value: 4.000000 standard dev := 1.000000value: 4.000000 standard dev := .942809value: 4.000000 standard dev := .866025value: 5.000000 standard dev := .979796value: 5.000000 standard dev := 1.000000value: 7.000000 standard dev := 1.399708value: 9.000000 standard dev := 2.000000
Translation of:Python
Works with:ALGOL 68 version Standard - no extensions to language used
Works with:ALGOL 68G version Any - tested with release1.18.0-9h.tiny

A simple - but "unpackaged" - code example, useful if the standard deviation is required on only one set of concurrent data:

LONG REAL sum, sum2;INT n;PROC sd = (LONG REAL x)LONG REAL:(    sum  +:= x;    sum2 +:= x*x;    n    +:= 1;    IF n = 0 THEN 0 ELSE long sqrt(sum2/n - sum*sum/n/n) FI); sum := sum2 := n := 0;[]LONG REAL values = (2,4,4,4,5,5,7,9);FOR i TO UPB values DO    LONG REAL value = values[i];    printf(($2(xg(0,6))l$, value, sd(value)))OD
Output:
 2.000000 .000000 4.000000 1.000000 4.000000 .942809 4.000000 .866025 5.000000 .979796 5.000000 1.000000 7.000000 1.399708 9.000000 2.000000

ALGOL W

Translation of:Python – viaOberon-07

This is an Algol W version of Oberon-07 sample which was based on the third, "unpackaged" Algol 68 sample, which was itself translated from Python.

begin    record CSD ( long real sumof, sum2of, sdof; integer countof );     long real procedure sample ( reference(CSD) value sdv; long real value x) ;    begin        long real sum, sum2;        integer   n;        countof(sdv) := countof(sdv) + 1;        sum          := sumof(sdv);        sum2         := sum2of(sdv);        n            := countof(sdv);        sum          := sum   + x;        sum2         := sum2  + (x*x);        sdof(sdv)    := if n = 0 then 0 else longsqrt(sum2/n - sum*sum/n/n);        sumof(sdv)   := sum;        sum2of(sdv)  := sum2;        sdof(sdv)    end sample;     reference(CSD) procedure NewCSD; CSD( 0, 0, 0, 0 );    begin        reference(CSD) sd;        sd := NewCSD;        r_format := "A"; r_w := 14; r_d := 6; % set output to fixed point format %        i_w := 6; s_w := 0;              % also set integer and separator format %        for i := 2,4,4,4,5,5,7,9 do begin            long real val, newSd;            val := i;            newSd := sample( sd, val );            write( countof(sd), ": ", val, " -> ", newSd )        end for_i    endend.
Output:
     1:       2.000000 ->       0.000000     2:       4.000000 ->       1.000000     3:       4.000000 ->       0.942809     4:       4.000000 ->       0.866025     5:       5.000000 ->       0.979796     6:       5.000000 ->       1.000000     7:       7.000000 ->       1.399708     8:       9.000000 ->       2.000000

AppleScript

Accumulation over a fold:

-------------- CUMULATIVE STANDARD DEVIATION --------------- stdDevInc :: Accumulator -> Num -> Index -> Accumulator-- stdDevInc :: {sum:, squaresSum:, stages:} -> Real -> Integer--                -> {sum:, squaresSum:, stages:}onstdDevInc(a,n,i)setsumto(sumofa)+nsetsquaresSumto(squaresSumofa)+(n^2)setstagesto(stagesofa)&¬((squaresSum/i)-((sum/i)^2))^0.5{sum:(sumofa)+n,squaresSum:squaresSum,stages:stages}endstdDevInc--------------------------- TEST -------------------------onrunsetxsto[2,4,4,4,5,5,7,9]stagesoffoldl(stdDevInc,¬{sum:0,squaresSum:0,stages:[]},xs)--> {0.0, 1.0, 0.942809041582, 0.866025403784, 0.979795897113, 1.0, 1.399708424448, 2.0}endrun-------------------- GENERIC FUNCTIONS --------------------- foldl :: (a -> b -> a) -> a -> [b] -> aonfoldl(f,startValue,xs)tellmReturn(f)setvtostartValuesetlngtolengthofxsrepeatwithifrom1tolngsetvto|λ|(v,itemiofxs,i,xs)endrepeatreturnvendtellendfoldl-- mReturn :: First-class m => (a -> b) -> m (a -> b)onmReturn(f)-- 2nd class handler function lifted into 1st class script wrapper.ifscriptisclassoffthenfelsescriptproperty|λ|:fendscriptendifendmReturn
Output:
{0.0, 1.0, 0.942809041582, 0.866025403784, 0.979795897113, 1.0, 1.399708424448, 2.0}


Or as a map-accumulation:

-------------- CUMULATIVE STANDARD DEVIATION --------------- cumulativeStdDevns :: [Float] -> [Float]oncumulativeStdDevns(xs)scriptgoon|λ|(sq,x,i)set{s,q}tosqset_stox+sset_qtoq+(x^2){{_s,_q},((_q/i)-((_s/i)^2))^0.5}end|λ|endscriptitem2ofmapAccumL(go,{0,0},xs)endcumulativeStdDevns--------------------------- TEST -------------------------onruncumulativeStdDevns({2,4,4,4,5,5,7,9})endrun------------------------- GENERIC -------------------------- foldl :: (a -> b -> a) -> a -> [b] -> aonfoldl(f,startValue,xs)tellmReturn(f)setvtostartValuesetlngtolengthofxsrepeatwithifrom1tolngsetvto|λ|(v,itemiofxs,i,xs)endrepeatreturnvendtellendfoldl-- mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])onmapAccumL(f,acc,xs)-- 'The mapAccumL function behaves like a combination of map and foldl;-- it applies a function to each element of a list, passing an-- accumulating parameter from |Left| to |Right|, and returning a final-- value of this accumulator together with the new list.' (see Hoogle)scripton|λ|(a,x,i)tellmReturn(f)tosetpairto|λ|(item1ofa,x,i){item1ofpair,(item2ofa)&{item2ofpair}}end|λ|endscriptfoldl(result,{acc,[]},xs)endmapAccumL-- mReturn :: First-class m => (a -> b) -> m (a -> b)onmReturn(f)-- 2nd class handler function lifted into 1st class script wrapper.ifscriptisclassoffthenfelsescriptproperty|λ|:fendscriptendifendmReturn
Output:
{0.0, 1.0, 0.942809041582, 0.866025403784, 0.979795897113, 1.0, 1.399708424448, 2.0}

Arturo

arr:[]loop[24445579]'value['arr++valueprint[value"->"deviationarr]]
Output:
2 -> 0.0 4 -> 1.0 4 -> 0.9428090415820634 4 -> 0.8660254037844386 5 -> 0.9797958971132711 5 -> 0.9999999999999999 7 -> 1.39970842444753 9 -> 2.0

AutoHotkey

Data:=[2,4,4,4,5,5,7,9]fork,vinData{FileAppend,%"#"a_index" value = "v" stddev = "stddev(v)"`n",* ; send to stdout}returnstddev(x){staticn,sum,sum2n++sum+=xsum2+=x*xreturnsqrt((sum2/n)-(((sum*sum)/n)/n))}
Output:
#1 value = 2 stddev 0 0.000000#2 value = 4 stddev 0 1.000000#3 value = 4 stddev 0 0.942809#4 value = 4 stddev 0 0.866025#5 value = 5 stddev 0 0.979796#6 value = 5 stddev 0 1.000000#7 value = 7 stddev 0 1.399708#8 value = 9 stddev 0 2.000000

AWK

# syntax: GAWK -f STANDARD_DEVIATION.AWKBEGIN{n=split("2,4,4,4,5,5,7,9",arr,",")for(i=1;i<=n;i++){temp[i]=arr[i]printf("%g %g\n",arr[i],stdev(temp))}exit(0)}functionstdev(arr,i,n,s1,s2,variance,x){for(iinarr){n++x=arr[i]s1+=x^2s2+=x}variance=((n*s1)-(s2^2))/(n^2)return(sqrt(variance))}
Output:
2 04 14 0.9428094 0.8660255 0.9797965 17 1.399719 2

Axiom

This example isincorrect. Please fix the code and remove this message.

Details: It does not return therunning standard deviation of the series.

We implement a domain with dependent type T with the operation + and identity 0:

)abbrev package TESTD TestDomainTestDomain(T : Join(Field,RadicalCategory)): Exports == Implementation where  R ==> Record(n : Integer, sum : T, ssq : T)  Exports == AbelianMonoid with    _+ : (%,T) -> %    _+ : (T,%) -> %    sd : % -> T  Implementation == R add    Rep := R   -- similar representation and implementation    obj : %    0 == [0,0,0]    obj + (obj2:%) == [obj.n + obj2.n, obj.sum + obj2.sum, obj.ssq + obj2.ssq]    obj + (x:T) == obj + [1, x, x*x]    (x:T) + obj == obj + x    sd obj ==       mean : T := obj.sum / (obj.n::T)      sqrt(obj.ssq / (obj.n::T) - mean*mean)

This can be called using:

T ==> Expression IntegerD ==> TestDomain(T)items := [2,4,4,4,5,5,7,9+x] :: List T;map(sd, scan(+, items, 0$D))                                        +---------------+                +-+  +-+   +-+     +-+  |  2              2\|2  \|3  2\|6    4\|6  \|7x  + 64x + 256    (1)  [0,1,-----,----,-----,1,-----,------------------]                3     2    5       7            8                                              Type: List(Expression(Integer))eval subst(last %,x=0)    (2)  2                                                    Type: Expression(Integer)

BASIC

See alsoVisual Basic.

ANSI BASIC

Translation of:Ada – Output format changed.
Works with:Decimal BASIC
100REM Cumulative standard deviation110DECLAREEXTERNALSUBInit120DECLAREEXTERNALSUBAdd130DECLAREEXTERNALFUNCTIONDeviation140DIMTestData(1TO8)150FORI=1TO8160READTestData(I)170NEXTI180DATA2,4,4,4,5,5,7,9190CALLInit(N,Sum,SumOfSquares)200PRINT"N ITEM AVG   STDDEV"210FORI=LBOUND(TestData)TOUBOUND(TestData)220CALLAdd(N,Sum,SumOfSquares,TestData(I))230PRINTUSING"# ":I;240PRINTUSING"   # ":TestData(I);250PRINTUSING"#.### ":Sum/I;260PRINTUSING" #.###":Deviation(N,Sum,SumOfSquares)270NEXTI280END290!300EXTERNALSUBInit(N,Sum,SumOfSquares)310REM The parameters N, Sum, SumOfSquares are passed by reference. So, the arguments must be variables.320LETN=0330LETSum=0.0340LETSumOfSquares=0.0350ENDSUB360!370EXTERNALSUBAdd(N,Sum,SumOfSquares,P)380REM The parameters N, Sum, SumOfSquares are passed by reference. So, the arguments must be variables.390LETN=N+1400LETSum=Sum+P410LETSumOfSquares=SumOfSquares+P^2420ENDSUB430!440EXTERNALFUNCTIONDeviation(N,Sum,SumOfSquares)450LETDeviation=SQR(SumOfSquares/N-(Sum/N)^2)460ENDFUNCTION
Output:
N ITEM AVG   STDDEV1    2 2.000   .0002    4 3.000  1.0003    4 3.333   .9434    4 3.500   .8665    5 3.800   .9806    5 4.000  1.0007    7 4.429  1.4008    9 5.000  2.000

BBC BASIC

Works with:BBC BASIC for Windows

Uses theMOD(array()) andSUM(array()) functions.

MAXITEMS=100FORi%=1TO8READnPRINT"Value = ";n", running SD = "FNrunningsd(n)NEXTENDDATA2,4,4,4,5,5,7,9DEFFNrunningsd(n)PRIVATElist(),i%DIMlist(MAXITEMS)i%+=1list(i%)=n=SQR(MOD(list())^2/i%-(SUM(list())/i%)^2)
Output:
Value = 2, running SD = 0Value = 4, running SD = 1Value = 4, running SD = 0.942809043Value = 4, running SD = 0.866025404Value = 5, running SD = 0.979795901Value = 5, running SD = 1Value = 7, running SD = 1.39970842Value = 9, running SD = 2

FreeBASIC

' FB 1.05.0 Win64FunctioncalcStandardDeviation(numberAsDouble)AsDoubleStatica()AsDoubleRedimPreservea(0ToUBound(a)+1)DimubAsUInteger=UBound(a)a(ub)=numberDimsumAsDouble=0.0ForiAsUInteger=0Toubsum+=a(i)NextDimmeanAsDouble=sum/(ub+1)DimdiffAsDoublesum=0.0ForiAsUInteger=0Toubdiff=a(i)-meansum+=diff*diffNextReturnSqr(sum/(ub+1))EndFunctionDima(0To7)AsDouble={2,4,4,4,5,5,7,9}ForiAsUInteger=0To7Print"Added";a(i);" SD now : ";calcStandardDeviation(a(i))NextPrintPrint"Press any key to quit"Sleep
Output:
Added 2 SD now :  0Added 4 SD now :  1Added 4 SD now :  0.9428090415820634Added 4 SD now :  0.8660254037844386Added 5 SD now :  0.9797958971132712Added 5 SD now :  1Added 7 SD now :  1.39970842444753Added 9 SD now :  2

IS-BASIC

100 PROGRAM "StDev.bas"110 LET N=8120 NUMERIC ARR(1 TO N)130 FOR I=1 TO N140   READ ARR(I)150 NEXT 160 DEF STDEV(N)170   LET S1,S2=0180   FOR I=1 TO N190     LET S1=S1+ARR(I)^2:LET S2=S2+ARR(I)200   NEXT 210   LET STDEV=SQR((N*S1-S2^2)/N^2)220 END DEF 230 FOR J=1 TO N240   PRINT J;"item =";ARR(J),"standard dev =";STDEV(J)250 NEXT 260 DATA 2,4,4,4,5,5,7,9

Liberty BASIC

Works with:Just BASIC

Using a global array to maintain the state. Implements definition explicitly.

    dim SD.storage$( 100)   '   can call up to 100 versions, using ID to identify.. arrays are global.                            '   holds (space-separated) number of data items so far, current sum.of.values and current sum.of.squares    for i =1 to 8        read x        print "New data "; x; " so S.D. now = "; using( "###.######", standard.deviation( 1, x))    next i    endfunction standard.deviation( ID, in)  if SD.storage$( ID) ="" then SD.storage$( ID) ="0 0 0"  num.so.far =val( word$( SD.storage$( ID), 1))  sum.vals   =val( word$( SD.storage$( ID), 2))  sum.sqs    =val( word$( SD.storage$( ID), 3))  num.so.far =num.so.far +1  sum.vals   =sum.vals   +in  sum.sqs    =sum.sqs    +in^2  ' standard deviation = square root of (the average of the squares less the square of the average)  standard.deviation   =(               ( sum.sqs /num.so.far)      -    ( sum.vals /num.so.far)^2)^0.5  SD.storage$( ID) =str$( num.so.far) +" " +str$( sum.vals) +" " +str$( sum.sqs)end function    Data 2, 4, 4, 4, 5, 5, 7, 9
New data 2 so S.D. now =   0.000000New data 4 so S.D. now =   1.000000New data 4 so S.D. now =   0.942809New data 4 so S.D. now =   0.866025New data 5 so S.D. now =   0.979796New data 5 so S.D. now =   1.000000New data 7 so S.D. now =   1.399708New data 9 so S.D. now =   2.000000

PureBasic

;DefineourStandarddeviationfunctionDeclare.dStandard_deviation(x);MainprogramIfOpenConsole()Definei,xRestoreMyListFori=1To8Read.ixPrintN(StrD(Standard_deviation(x)))NextiPrint(#CRLF$+"Press ENTER to exit"):Input()EndIf;Calculationprocedure,withmemoryProcedure.dStandard_deviation(In)Staticin_summa,antalStaticin_kvadrater.qin_summa+inin_kvadrater+in*inantal+1ProcedureReturnPow((in_kvadrater/antal)-Pow(in_summa/antal,2),0.50)EndProcedure;datasectionDataSectionMyList:Data.i2,4,4,4,5,5,7,9EndDataSection
Output:
 0.0000000000 1.0000000000 0.9428090416 0.8660254038 0.9797958971 1.0000000000 1.3997084244 2.0000000000

QuickBASIC

Translation of:Ada – Output format changed.
' Cumulative standard deviationTYPESampleNASINTEGERSumASSINGLESumOfSquaresASSINGLEENDTYPEDECLARESUBInit(SASSample)DECLARESUBAdd(SASSample,BYVALPASSINGLE)DECLAREFUNCTIONDeviation!(SASSample)DIMTest(1TO8)ASSINGLEDIMSASSampleFORI=1TO8READTest(I)NEXTIDATA2,4,4,4,5,5,7,9CALLInit(S)PRINT"N ITEM AVG   STDDEV"FORI=LBOUND(Test)TOUBOUND(Test)CALLAdd(S,Test(I))PRINTUSING"# ";I;PRINTUSING"   # ";Test(I);PRINTUSING"#.### ";S.Sum/I;PRINTUSING" #.###";Deviation!(S)NEXTIENDSUBAdd(SASSample,BYVALPASSINGLE)S.N=S.N+1S.Sum=S.Sum+PS.SumOfSquares=S.SumOfSquares+P^2ENDSUBFUNCTIONDeviation!(SASSample)Deviation!=SQR(S.SumOfSquares/S.N-(S.Sum/S.N)^2)ENDFUNCTIONSUBInit(SASSample)S.N=0S.Sum=0!S.SumOfSquares=0!ENDSUB
Output:
N ITEM AVG   STDDEV1    2 2.000  0.0002    4 3.000  1.0003    4 3.333  0.9434    4 3.500  0.8665    5 3.800  0.9806    5 4.000  1.0007    7 4.429  1.4008    9 5.000  2.000

Run BASIC

Works with:Just BASIC
dim sdSave$(100) 'can call up to 100 versions                  'holds (space-separated) number of data , sum of values and sum of squaressd$ = "2,4,4,4,5,5,7,9"for num = 1 to 8  stdData = val(word$(sd$,num,","))  sumVal = sumVal + stdData  sumSqs = sumSqs + stdData^2   ' standard deviation = square root of (the average of the squares less the square of the average)  standDev   =((sumSqs / num) - (sumVal /num) ^ 2) ^ 0.5  sdSave$(num) = str$(num);" ";str$(sumVal);" ";str$(sumSqs)  print num;" value in = ";stdData; " Stand Dev = "; using("###.######", standDev)next num
1 value in = 2 Stand Dev =   0.0000002 value in = 4 Stand Dev =   1.0000003 value in = 4 Stand Dev =   0.9428094 value in = 4 Stand Dev =   0.8660255 value in = 5 Stand Dev =   0.9797966 value in = 5 Stand Dev =   1.0000007 value in = 7 Stand Dev =   1.3997088 value in = 9 Stand Dev =   2.000000

TI-83 BASIC

On the TI-83 family, standard deviation of a population is a builtin function (σx):

• Press [STAT] select [EDIT] followed by [ENTER]• then enter for list L1 in the table : 2, 4, 4, 4, 5, 5, 7, 9• Or enter {2,4,4,4,5,5,7,9}→L1• Press [STAT] select [CALC] then [1-Var Stats] select list L1 followed by [ENTER]• Then σx (=2) gives the standard deviation of the population

C

#include<stdio.h>#include<stdlib.h>#include<math.h>typedefenumAction{STDDEV,MEAN,VAR,COUNT}Action;typedefstructstat_obj_struct{doublesum,sum2;size_tnum;Actionaction;}sStatObject,*StatObject;StatObjectNewStatObject(Actionaction){StatObjectso;so=malloc(sizeof(sStatObject));so->sum=0.0;so->sum2=0.0;so->num=0;so->action=action;returnso;}#define FREE_STAT_OBJECT(so) \   free(so); so = NULLdoublestat_obj_value(StatObjectso,Actionaction){doublenum,mean,var,stddev;if(so->num==0.0)return0.0;num=so->num;if(action==COUNT)returnnum;mean=so->sum/num;if(action==MEAN)returnmean;var=so->sum2/num-mean*mean;if(action==VAR)returnvar;stddev=sqrt(var);if(action==STDDEV)returnstddev;return0;}doublestat_object_add(StatObjectso,doublev){so->num++;so->sum+=v;so->sum2+=v*v;returnstat_obj_value(so,so->action);}
doublev[]={2,4,4,4,5,5,7,9};intmain(){inti;StatObjectso=NewStatObject(STDDEV);for(i=0;i<sizeof(v)/sizeof(double);i++)printf("val: %lf  std dev: %lf\n",v[i],stat_object_add(so,v[i]));FREE_STAT_OBJECT(so);return0;}

C#

usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;namespacestandardDeviation{classProgram{staticvoidMain(string[]args){List<double>nums=newList<double>{2,4,4,4,5,5,7,9};for(inti=1;i<=nums.Count;i++)Console.WriteLine(sdev(nums.GetRange(0,i)));}staticdoublesdev(List<double>nums){List<double>store=newList<double>();foreach(doubleninnums)store.Add((n-nums.Average())*(n-nums.Average()));returnMath.Sqrt(store.Sum()/store.Count);}}}
010,9428090415820630,8660254037844390,97979589711327111,399708424447532

C++

No attempt to handle different types -- standard deviation is intrinsically a real number.

#include<cassert>#include<cmath>#include<vector>#include<iostream>template<intN>structMomentsAccumulator_{std::vector<double>m_;MomentsAccumulator_():m_(N+1,0.0){}voidoperator()(doublev){doubleinc=1.0;for(auto&mi:m_){mi+=inc;inc*=v;}}};doubleStdev(conststd::vector<double>&moments){assert(moments.size()>2);assert(moments[0]>0.0);constdoublemean=moments[1]/moments[0];constdoublemeanSquare=moments[2]/moments[0];returnsqrt(meanSquare-mean*mean);}intmain(void){std::vector<int>data({2,4,4,4,5,5,7,9});MomentsAccumulator_<2>accum;for(autod:data){accum(d);std::cout<<"Running stdev:  "<<Stdev(accum.m_)<<"\n";}}

Clojure

(defnstateful-std-deviation[x](letfn[(std-dev[x](let[v(deref(find-var(symbol(str*ns*"/v"))))](swap!vconjx)(let[m(/(reduce+@v)(count@v))](Math/sqrt(/(reduce+(map#(*(-m%)(-m%))@v))(count@v))))))](when(nil?(resolve'v))(intern*ns*'v(atom[])))(std-devx)))

COBOL

Works with:OpenCOBOL version 1.1
IDENTIFICATIONDIVISION.PROGRAM-ID.run-stddev.environmentdivision.input-outputsection.file-control.  selectinput-fileassignto"input.txt"    organizationislinesequential.data division.file section.fd input-file.  01inp-record.    03inp-fldpic 9(03).working-storagesection.01  fillerpic 9(01)value0.  88 no-more-inputvalue1.01  ws-tb-data.  03ws-tb-sizepic 9(03).  03ws-tb-table.    05ws-tb-fldpic s9(05)v9999comp-3occurs0to100timesdependingonws-tb-size.01 ws-stddevpic s9(05)v9999comp-3.PROCEDUREDIVISION.  move0tows-tb-size  openinputinput-file    readinput-file    atendsetno-more-inputtotrueend-readperformtestafteruntilno-more-inputadd1tows-tb-sizemoveinp-fldtows-tb-fld(ws-tb-size)call'stddev'usingbyreferencews-tb-dataws-stddevdisplay'inp='inp-fld' stddev='ws-stddevreadinput-fileatendsetno-more-inputtotrueend-readend-performcloseinput-file  stoprun.end programrun-stddev.IDENTIFICATIONDIVISION.PROGRAM-ID.stddev.data division.working-storagesection.01 ws-tbxpic s9(03)comp.01 ws-tb-work.  03ws-sumpic s9(05)v9999comp-3value+0.  03ws-sumsqpic s9(05)v9999comp-3value+0.  03ws-avgpic s9(05)v9999comp-3value+0.linkagesection.01  ws-tb-data.  03ws-tb-sizepic 9(03).  03ws-tb-table.    05ws-tb-fldpic s9(05)v9999comp-3occurs0to100timesdependingonws-tb-size.01  ws-stddevpic s9(05)v9999comp-3.PROCEDUREDIVISIONusingws-tb-dataws-stddev.    computews-sum=0performtestbeforevaryingws-tbxfrom1by+1untilws-tbx>ws-tb-sizecomputews-sum=ws-sum+ws-tb-fld(ws-tbx)    end-perform    computews-avgrounded=ws-sum/ws-tb-size    computews-sumsq=0performtestbeforevaryingws-tbxfrom1by+1untilws-tbx>ws-tb-sizecomputews-sumsq=ws-sumsq+(ws-tb-fld(ws-tbx)-ws-avg)**2.0end-performcomputews-stddev=(ws-sumsq/ws-tb-size)**0.5goback.end programstddev.
sampleoutput:inp=002stddev=+00000.0000inp=004stddev=+00001.0000inp=004stddev=+00000.9427inp=004stddev=+00000.8660inp=005stddev=+00000.9797inp=005stddev=+00001.0000inp=007stddev=+00001.3996inp=009stddev=+00002.0000

CoffeeScript

Uses a class instance to maintain state.

classStandardDeviationconstructor:->@sum=0@sumOfSquares=0@values=0@deviation=0include:( n ) ->@values+=1@sum+=n@sumOfSquares+=n*nmean=@sum/@valuesmean*=mean@deviation=Math.sqrt@sumOfSquares/@values-meandev=newStandardDeviationvalues=[2,4,4,4,5,5,7,9]tmp=[]forvalueinvaluestmp.pushvaluedev.includevalueconsole.log"""        Values:#{tmp}        Standard deviation:#{dev.deviation}    """
Output:
Values: 2Standard deviation: 0Values: 2,4Standard deviation: 1Values: 2,4,4Standard deviation: 0.9428090415820626Values: 2,4,4,4Standard deviation: 0.8660254037844386Values: 2,4,4,4,5Standard deviation: 0.9797958971132716Values: 2,4,4,4,5,5Standard deviation: 1Values: 2,4,4,4,5,5,7Standard deviation: 1.3997084244475297Values: 2,4,4,4,5,5,7,9Standard deviation: 2

Common Lisp

Since we don't care about the sample values once std dev is computed, we only need to keep track of their sum and square sums, hence:

(defunrunning-stddev()(let((sum0)(sq0)(n0))(lambda(x)(incfsumx)(incfsq(*xx))(incfn)(/(sqrt(-(*nsq)(*sumsum)))n))))CL-USER>(loopwithf=(running-stddev)foriin'(24445579)do(formatt"~a ~a~%"i(funcallfi)))NIL20.041.040.9428090540.866025450.9797959351.071.399708592.0

In the REPL, one step at a time:

CL-USER>(setffn(running-stddev))#<InterpretedClosure(:INTERNALRUNNING-STDDEV)@#x21b9a492>CL-USER>(funcallfn2)0.0CL-USER>(funcallfn4)1.0CL-USER>(funcallfn4)0.94280905CL-USER>(funcallfn4)0.8660254CL-USER>(funcallfn5)0.97979593CL-USER>(funcallfn5)1.0CL-USER>(funcallfn7)1.3997085CL-USER>(funcallfn9)2.0

Component Pascal

This example isincorrect. Please fix the code and remove this message.

Details: Function does not take numbers individually.

BlackBox Component Builder

MODULEStandardDeviation;IMPORTStdLog,Args,Strings,Math;PROCEDUREMean(x:ARRAYOFREAL;n:INTEGER;OUTmean:REAL);VARi:INTEGER;total:REAL;BEGINtotal:=0.0;FORi:=0TOn-1DOtotal:=total+x[i]END;mean:=total/nENDMean;PROCEDURESDeviation(x:ARRAYOFREAL;n:INTEGER):REAL;VARi:INTEGER;mean,sum:REAL;BEGINMean(x,n,mean);sum:=0.0;FORi:=0TOn-1DOsum:=sum+((x[i]-mean)*(x[i]-mean));END;RETURNMath.Sqrt(sum/n);ENDSDeviation;PROCEDUREDo*;VARp:Args.Params;x:POINTERTOARRAYOFREAL;i,done:INTEGER;BEGINArgs.Get(p);IFp.argc>0THENNEW(x,p.argc);FORi:=0TOp.argc-1DOx[i]:=0.0END;FORi:=0TOp.argc-1DOStrings.StringToReal(p.args[i],x[i],done);StdLog.Int(i+1);StdLog.String(" :> ");StdLog.Real(SDeviation(x,i+1));StdLog.LnENDENDENDDo;ENDStandardDeviation.

Execute: ^Q StandardDeviation.Do 2 4 4 4 5 5 7 9 ~

Output:
 1 :>  0.0 2 :>  1.0 3 :>  0.9428090415820634 4 :>  0.8660254037844386 5 :>  0.9797958971132712 6 :>  1.0 7 :>  1.39970842444753 8 :>  2.0

Crystal

Object

Use an object to keep state.

Translation of:Ruby
classStdDevAccumulatordefinitialize@n,@sum,@sum2=0,0.0,0.0enddef<<(num)@n+=1@sum+=num@sum2+=num**2Math.sqrt(@sum2*@n-@sum**2)/@n**2endendsd=StdDevAccumulator.newi=0[2,4,4,4,5,5,7,9].each{|n|puts"adding#{n}: stddev of#{i+=1} samples is#{sd<<n}"}
Output:
adding 2: stddev of 1 samples is 0.0adding 4: stddev of 2 samples is 1.0adding 4: stddev of 3 samples is 0.9428090415820634adding 4: stddev of 4 samples is 0.8660254037844386adding 5: stddev of 5 samples is 0.9797958971132712adding 5: stddev of 6 samples is 1.0adding 7: stddev of 7 samples is 1.3997084244475304adding 9: stddev of 8 samples is 2.0

Closure

Translation of:Ruby
defsdaccumn,sum,sum2=0,0.0,0.0->(num:Int32)don+=1sum+=numsum2+=num**2Math.sqrt((sum2*n-sum**2)/n**2)endendsd=sdaccum[2,4,4,4,5,5,7,9].each{|n|printsd.call(n),", "}
Output:
0.0, 1.0, 0.9428090415820634, 0.8660254037844386, 0.9797958971132712, 1.0, 1.3997084244475304, 2.0

D

importstd.stdio,std.math;structStdDev{realsum=0.0,sqSum=0.0;longnvalues;voidaddNumber(inrealinput)purenothrow{nvalues++;sum+=input;sqSum+=input^^2;}realgetStdDev()constpurenothrow{if(nvalues==0)return0.0;immutablerealmean=sum/nvalues;returnsqrt(sqSum/nvalues-mean^^2);}}voidmain(){StdDevstdev;foreach(el;[2.0,4,4,4,5,5,7,9]){stdev.addNumber(el);writefln("%e",stdev.getStdDev());}}
Output:
0.000000e+001.000000e+009.428090e-018.660254e-019.797959e-011.000000e+001.399708e+002.000000e+00

Delphi

See:#Pascal

DuckDB

Works with:DuckDB version v1.0

This entry is premised on the existence of a table, t, containing thenumbers (column x) in the required order, as specified by a columnof increasing values. The standard deviations are thencomputed on a rolling basis using DuckDB's support forincrementally growing "windows".

#CreateatablewiththedatatogetherwithasequencenumberCREATEORREPLACETABLEtASSELECTgenerate_subscripts(l,1)asid,unnest(l)::DOUBLEasx,from(values([2,4,4,4,5,5,7,9]))tbl(l);#ComputetherollingstandarddeviationswithouttheBesseladjustment:SELECT*,stddev_pop(x)OVER(ORDERBYid)as'cumulative stddev'FROMt;
Output:
┌───────┬────────┬────────────────────┐│  id   │   x    │ cumulative stddev  ││ int64 │ double │       double       │├───────┼────────┼────────────────────┤│     1 │    2.0 │                0.0 ││     2 │    4.0 │                1.0 ││     3 │    4.0 │ 0.9428090415820634 ││     4 │    4.0 │ 0.8660254037844386 ││     5 │    5.0 │ 0.9797958971132713 ││     6 │    5.0 │                1.0 ││     7 │    7.0 │ 1.3997084244475304 ││     8 │    9.0 │                2.0 │└───────┴────────┴────────────────────┘

E

This implementation produces two (function) objects sharing state. It is idiomatic in E to separate input from output (read from write) rather than combining them into one object.

The algorithm is

Translation of:Perl

and the results were checked against#Python.

def makeRunningStdDev() {    var sum := 0.0    var sumSquares := 0.0    var count := 0.0        def insert(v) {        sum += v        sumSquares += v ** 2        count += 1    }        /** Returns the standard deviation of the inputs so far, or null if there        have been no inputs. */    def stddev() {        if (count > 0) {            def meanSquares := sumSquares/count            def mean := sum/count            def variance := meanSquares - mean**2            return variance.sqrt()        }    }        return [insert, stddev]}
? def [insert, stddev] := makeRunningStdDev()# value: <insert>, <stddev>? [stddev()]# value: [null]? for value in [2,4,4,4,5,5,7,9] {>     insert(value)>     println(stddev())> }0.01.00.94280904158206260.86602540378443860.97979589711327161.01.39970842444752972.0

EasyLang

Translation of:Pascal
global sum sum2 n .func sd x .   sum += x   sum2 += x * x   n += 1   return sqrt (sum2 / n - sum * sum / n / n).v[] = [ 2 4 4 4 5 5 7 9 ]for v in v[]   print v & " " & sd v.
Output:
2 04 14 0.944 0.875 0.985 17 1.409 2

Elixir

Translation of:Erlang
defmoduleStandard_deviationdodefadd_sample(pid,n),do:send(pid,{:add,n})defcreate,do:spawn_link(fn->loop([])end)defdestroy(pid),do:send(pid,:stop)defget(pid)dosend(pid,{:get,self()})receivedo{:get,value,_pid}->valueendenddeftaskdopid=create()forx<-[2,4,4,4,5,5,7,9],do:add_print(pid,x,add_sample(pid,x))destroy(pid)enddefpadd_print(pid,n,_add)doIO.puts"Standard deviation#{get(pid)} when adding#{n}"enddefploop(ns)doreceivedo{:add,n}->loop([n|ns]){:get,pid}->send(pid,{:get,loop_calculate(ns),self()})loop(ns):stop->:okendenddefploop_calculate(ns)doaverage=loop_calculate_average(ns):math.sqrt(loop_calculate_average(forx<-ns,do::math.pow(x-average,2)))enddefploop_calculate_average(ns),do:Enum.sum(ns)/length(ns)endStandard_deviation.task
Output:
Standard deviation 0.0 when adding 2Standard deviation 1.0 when adding 4Standard deviation 0.9428090415820634 when adding 4Standard deviation 0.8660254037844386 when adding 4Standard deviation 0.9797958971132712 when adding 5Standard deviation 1.0 when adding 5Standard deviation 1.3997084244475302 when adding 7Standard deviation 2.0 when adding 9

Emacs Lisp

(defunrunning-std(items)(let((running-sum0)(running-len0)(running-squared-sum0)(result0))(dolist(itemitems)(setqrunning-sum(+running-sumitem))(setqrunning-len(1+running-len))(setqrunning-squared-sum(+running-squared-sum(*itemitem)))(setqresult(sqrt(-(/running-squared-sum(floatrunning-len))(/(*running-sumrunning-sum)(float(*running-lenrunning-len))))))(message"%f"result))result))(running-std'(24445579))
Output:
0.0000001.0000000.9428090.8660250.9797961.0000001.3997082.0000002.0
Library:Calc
(let((x'(24445579)))(string-to-number(calc-eval"sqrt(vpvar($1))"nil(append'(vec)x))))
Library:generator.el
;; lexical-binding: t(require'generator)(iter-defunstd-dev-gen(lst)(let((sum0)(avg0)(tmp'())(std0))(dolist(ilst)(setqi(floati))(pushitmp)(setqsum(+sumi))(setqavg(/sum(lengthtmp)))(setqstd0)(dolist(jtmp)(setqstd(+std(expt(-javg)2))))(setqstd(/std(lengthtmp)))(setqstd(sqrtstd))(iter-yieldstd))))(let*((test-data'(24445579))(generator(std-dev-gentest-data)))(dolist(itest-data)(message"with %d: %f"i(iter-nextgenerator))))

Erlang

-module(standard_deviation).-export([add_sample/2,create/0,destroy/1,get/1,task/0]).-compile({no_auto_import,[get/1]}).add_sample(Pid,N)->Pid!{add,N}.create()->erlang:spawn_link(fun()->loop([])end).destroy(Pid)->Pid!stop.get(Pid)->Pid!{get,erlang:self()},receive{get,Value,Pid}->Valueend.task()->Pid=create(),[add_print(Pid,X,add_sample(Pid,X))||X<-[2,4,4,4,5,5,7,9]],destroy(Pid).add_print(Pid,N,_Add)->io:fwrite("Standard deviation~p when adding~p~n",[get(Pid),N]).loop(Ns)->receive{add,N}->loop([N|Ns]);{get,Pid}->Pid!{get,loop_calculate(Ns),erlang:self()},loop(Ns);stop->okend.loop_calculate(Ns)->Average=loop_calculate_average(Ns),math:sqrt(loop_calculate_average([math:pow(X-Average,2)||X<-Ns])).loop_calculate_average(Ns)->lists:sum(Ns)/erlang:length(Ns).
Output:
9> standard_deviation:task().Standard deviation 0.0 when adding 2Standard deviation 1.0 when adding 4Standard deviation 0.9428090415820634 when adding 4Standard deviation 0.8660254037844386 when adding 4Standard deviation 0.9797958971132712 when adding 5Standard deviation 1.0 when adding 5Standard deviation 1.3997084244475302 when adding 7Standard deviation 2.0 when adding 9

Factor

USING:accessorsiokernelmathmath.functionsmath.parsersequences;IN:standard-deviatorTUPLE:standard-deviatorsumsum^2n;:<standard-deviator>(--standard-deviator)0.0 0.0 0standard-deviatorboa;:current-std(standard-deviator--std)[[sum^2>>][n>>]bi/][[sum>>][n>>]bi/sq]bi-sqrt;:add-value(valuestandard-deviator--)[nip[1+]change-ndrop][[+]change-sumdrop][[[sq]dip+]change-sum^2drop]2tri;:main(--){2 4 4 4 5 5 7 9}<standard-deviator>[[add-value]curryeach]keepcurrent-stdnumber>stringprint;

FOCAL

01.01 C-- TEST SET01.10 S T(1)=2;S T(2)=4;S T(3)=4;S T(4)=401.20 S T(5)=5;S T(6)=5;S T(7)=7;S T(8)=901.30 D 2.101.35 T %6.4001.40 F I=1,8;S A=T(I);D 2.2;T "VAL",A;D 2.3;T " SD",A,!01.50 Q02.01 C-- RUNNING STDDEV02.02 C-- 2.1: INITIALIZE02.03 C-- 2.2: INSERT VALUE A02.04 C-- 2.3: A = CURRENT STDDEV02.10 S XN=0;S XS=0;S XQ=002.20 S XN=XN+1;S XS=XS+A;S XQ=XQ+A*A02.30 S A=FSQT(XQ/XN - (XS/XN)^2)
Output:
VAL= 2.00000 SD= 0.00000VAL= 4.00000 SD= 1.00000VAL= 4.00000 SD= 0.94281VAL= 4.00000 SD= 0.86603VAL= 5.00000 SD= 0.97980VAL= 5.00000 SD= 1.00000VAL= 7.00000 SD= 1.39971VAL= 9.00000 SD= 2.00000


Forth

:f+!( x addr -- )dupf@f+f!;:st-count( stats -- n )f@;:st-sum( stats -- sum )float+f@;:st-sumsq( stats -- sum*sum )2floats+f@;:st-mean( stats -- mean )dupst-sumst-countf/;:st-variance( stats -- var )dupst-sumsqdupst-meanfdupf*dupst-countf*f-st-countf/;:st-stddev( stats -- stddev )st-variancefsqrt;:st-add( fnum stats -- )dup1edupf+!float+fdupdupf+!float+fdupf*f+!std-stddev;

This variation is more numerically stable when there are large numbers of samples or large sample ranges.

:st-count( stats -- n )f@;:st-mean( stats -- mean )float+f@;:st-nvar( stats -- n*var )2floats+f@;:st-variance( stats -- var )dupst-nvarst-countf/;:st-stddev( stats -- stddev )st-variancefsqrt;:st-add( x stats -- )dup1edupf+!\ update countfdupdupst-meanf-fswap( delta x )foverdupst-countf/( delta x delta/n )float+dupf+!\ update mean( delta x )dupf@f-f*float+f+!\ update nvarst-stddev;

Usage example:

createstats0ef,0ef,0ef,2estatsst-addf.\ 0.4estatsst-addf.\ 1.4estatsst-addf.\ 0.9428090415820634estatsst-addf.\ 0.8660254037844395estatsst-addf.\ 0.9797958971132715estatsst-addf.\ 1.7estatsst-addf.\ 1.399708424447539estatsst-addf.\ 2.

Fortran

Works with:Fortran version 2003 and later
programstandard_deviationimplicit noneinteger(kind=4),parameter::dp=kind(0.0d0)real(kind=dp),dimension(:),allocatable::valsinteger(kind=4)::ireal(kind=dp),dimension(8)::sample_data=(/2,4,4,4,5,5,7,9/)doi=lbound(sample_data,1),ubound(sample_data,1)callsample_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 arraysubroutinesample_add(population,val)real(kind=dp),dimension(:),allocatable,intent(inout)::populationreal(kind=dp),intent(in)::valreal(kind=dp),dimension(:),allocatable::tmpinteger(kind=4)::nif(.not.allocated(population))then      allocate(population(1))population(1)=valelsen=size(population)callmove_alloc(population,tmp)allocate(population(n+1))population(1:n)=tmppopulation(n+1)=valendif  end subroutinesample_add! Calculates standard deviation for given set of valuesreal(kind=dp)functionstddev(vals)real(kind=dp),dimension(:),intent(in)::valsreal(kind=dp)::meaninteger(kind=4)::nn=size(vals)mean=sum(vals)/nstddev=sqrt(sum((vals-mean)**2)/n)end functionstddevend programstandard_deviation
Output:
#1 value = 2.0 stddev = 0.00000000#2 value = 4.0 stddev = 1.00000000#3 value = 4.0 stddev = 0.94280904#4 value = 4.0 stddev = 0.86602540#5 value = 5.0 stddev = 0.97979590#6 value = 5.0 stddev = 1.00000000#7 value = 7.0 stddev = 1.39970842#8 value = 9.0 stddev = 2.00000000

Old style, four ways

Early computers loaded the entire programme and its working storage into memory and left it there throughout the run. Uninitialised variables would start with whatever had been left in memory at their address by whatever last used those addresses, though some systems would clear all of memory to zero or possibly some other value before each load. Either way, if a routine was invoked a second time, its variables would have the values left in them by their previous invocation. The DATA statement allows initial values to be specified, and allows repeat counts when specifying such values as well. It is not an executable statement: it is not re-executed on second and subsequent invocations of the containing routine. Thus, it is easy to have a routine employ counters and the like, visible only within themselves and initialised to zero or whatever suited.

With more complex operating systems, routines that relied on retaining values across invocations might no longer work - perhaps a fresh version of the routine would be loaded to memory (perhaps at odd intervals), or, on exit, the working storage would be discarded. There was a half-way scheme, whereby variables that had appeared in DATA statements would be retained while the others would be discarded. This subtle indication has been discarded in favour of the explicit SAVE statement, naming those variables whose values are to be retained between invocations, though compilers might also offer an option such as "automatic" (for each invocation always allocate then discard working memory) and "static" (retain values), possibly introducing non-standard keywords as well. Otherwise, the routines would have to use storage global to them such as additional parameters, or, COMMON storage and in later Fortran, the MODULE arrangements for shared items. The persistence of such storage can still be limited, but by naming them in the main line can be ensured for the life of the run. The other routines with access to such storage could enable re-initialisation, additional reports, or multiple accumulations, etc.

Since the standard deviation can be calculated in a single pass through the data, producing values for the standard deviation of all values so far supplied is easily done without re-calculation. Accuracy is quite another matter. Calculations using deviances from a working mean are much better, and capturing the first X as the working mean would be easy, just test on N = 0. The sum and sum-of-squares method is quite capable of generating a negative variance, but the second method cannot, because the terms being added in to V are never negative. This is demonstrated by comparing the results computed from StdDev(A), StdDev(A + 10), StdDev(A + 100), StdDev(A + 1000), etc.

Incidentally, Fortran implementations rarely enable re-entrancy for the WRITE statement, so, since here the functions are invoked in a WRITE statement, the functions cannot themselves use WRITE statements, say for debugging.

REALFUNCTIONSTDDEV(X)!Standard deviation for successive values.REALX!The latest value.REALV!Scratchpad.INTEGERN!Ongoing: count of the values.REALEX,EX2!Ongoing: sum of X and X**2.SAVEN,EX,EX2!Retain values from one invocation to the next.DATAN,EX,EX2/0,0.0,0.0/!Initial values.N=N+1!Another value arrives.EX=X+EX!Augment the total.EX2=X**2+EX2!Augment the sum of squares.V=EX2/N-(EX/N)**2!The variance, but, it might come out negative!STDDEV=SIGN(SQRT(ABS(V)),V)!Protect the SQRT, but produce a negative result if so.END FUNCTIONSTDDEV!For the sequence of received X values.REALFUNCTIONSTDDEVP(X)!Standard deviation for successive values.REALX!The latest value.INTEGERN!Ongoing: count of the values.REALA,V!Ongoing: average, and sum of squared deviations.SAVEN,A,V!Retain values from one invocation to the next.DATAN,A,V/0,0.0,0.0/!Initial values.N=N+1!Another value arrives.V=(N-1)*(X-A)**2/N+V!First, as it requires the existing average.A=(X-A)/N+A!= [x + (n - 1).A)]/n: recover the total from the average.STDDEVP=SQRT(V/N)!V can never be negative, even with limited precision.END FUNCTIONSTDDEVP!For the sequence of received X values.REALFUNCTIONSTDDEVW(X)!Standard deviation for successive values.REALX!The latest value.REALV,D!Scratchpads.INTEGERN!Ongoing: count of the values.REALEX,EX2!Ongoing: sum of X and X**2.REALW!Ongoing: working mean.SAVEN,EX,EX2,W!Retain values from one invocation to the next.DATAN,EX,EX2/0,0.0,0.0/!Initial values.IF(N.LE.0)W=X!Take the first value as the working mean.N=N+1!Another value arrives.D=X-W!Its deviation from the working mean.EX=D+EX!Augment the total.EX2=D**2+EX2!Augment the sum of squares.V=EX2/N-(EX/N)**2!The variance, but, it might come out negative!STDDEVW=SIGN(SQRT(ABS(V)),V)!Protect the SQRT, but produce a negative result if so.END FUNCTIONSTDDEVW!For the sequence of received X values.REALFUNCTIONSTDDEVPW(X)!Standard deviation for successive values.REALX!The latest value.INTEGERN!Ongoing: count of the values.REALA,V!Ongoing: average, and sum of squared deviations.REALW!Ongoing: working mean.SAVEN,A,V,W!Retain values from one invocation to the next.DATAN,A,V/0,0.0,0.0/!Initial values.IF(N.LE.0)W=X!Oh for self-modifying code!N=N+1!Another value arrives.D=X-W!Its deviation from the working mean.V=(N-1)*(D-A)**2/N+V!First, as it requires the existing average.A=(D-A)/N+A!= [x + (n - 1).A)]/n: recover the total from the average.STDDEVPW=SQRT(V/N)!V can never be negative, even with limited precision.END FUNCTIONSTDDEVPW!For the sequence of received X values.PROGRAMTESTINTEGERI!A stepper.REALA(8)!The example data.DATAA/2.0,3*4.0,2*5.0,7.0,9.0/!Alas, another opportunity to use @ passed over.REALB!An offsetting base.WRITE(6,1)1FORMAT("Progressive calculation of the standard deviation."/1" I",7X,"A(I)       EX EX2      Av V*N      Ed Ed2     wAv V*N")B=1000000!Provoke truncation error.DOI=1,8!Step along the data series,WRITE(6,2)I,INT(A(I)+B),!No fractional part, so I don't want F11.0.1STDDEV(A(I)+B),STDDEVP(A(I)+B),!Showing progressive values.2STDDEVW(A(I)+B),STDDEVPW(A(I)+B)!These with a working mean.2FORMAT(I2,I11,1X,4F12.6)!Should do for the example.END DO!On to the next value.END

Output: the second pair of columns have the calculations done with a working mean and thus accumulate deviations from that.

       Progressive calculation of the standard deviation.I       A(I)       EX EX2      Av V*N      Ed Ed2     wAv V*N1          2     0.000000    0.000000    0.000000    0.0000002          4     1.000000    1.000000    1.000000    1.0000003          4     0.942809    0.942809    0.942809    0.9428094          4     0.866025    0.866025    0.866025    0.8660255          5     0.979796    0.979796    0.979796    0.9797966          5     1.000000    1.000000    1.000000    1.0000007          7     1.399708    1.399708    1.399708    1.3997088          9     2.000000    2.000000    2.000000    2.000000
I       A(I)       EX EX2      Av V*N      Ed Ed2     wAv V*N1         12     0.000000    0.000000    0.000000    0.0000002         14     1.000000    1.000000    1.000000    1.0000003         14     0.942809    0.942809    0.942809    0.9428094         14     0.866025    0.866025    0.866025    0.8660255         15     0.979796    0.979796    0.979796    0.9797966         15     1.000000    1.000000    1.000000    1.0000007         17     1.399708    1.399708    1.399708    1.3997088         19     2.000000    2.000000    2.000000    2.000000
I       A(I)       EX EX2      Av V*N      Ed Ed2     wAv V*N1        102     0.000000    0.000000    0.000000    0.0000002        104     1.000000    1.000000    1.000000    1.0000003        104     0.942809    0.942809    0.942809    0.9428094        104     0.866025    0.866025    0.866025    0.8660255        105     0.979796    0.979796    0.979796    0.9797966        105     1.000000    0.999999    1.000000    1.0000007        107     1.399708    1.399708    1.399708    1.3997088        109     2.000000    1.999999    2.000000    2.000000
I       A(I)       EX EX2      Av V*N      Ed Ed2     wAv V*N1       1002     0.000000    0.000000    0.000000    0.0000002       1004     1.000000    1.000000    1.000000    1.0000003       1004     0.942809    0.942809    0.942809    0.9428094       1004     0.866025    0.866028    0.866025    0.8660255       1005     0.979796    0.979798    0.979796    0.9797966       1005     1.000000    1.000004    1.000000    1.0000007       1007     1.399708    1.399711    1.399708    1.3997088       1009     2.000000    1.999997    2.000000    2.000000
I       A(I)       EX EX2      Av V*N      Ed Ed2     wAv V*N1      10002    -2.000000    0.000000    0.000000    0.0000002      10004    -1.000000    1.000000    1.000000    1.0000003      10004    -0.666667    0.942809    0.942809    0.9428094      10004     1.936492    0.866072    0.866025    0.8660255      10005     2.181742    0.979829    0.979796    0.9797966      10005     2.309401    1.000060    1.000000    1.0000007      10007     1.801360    1.399745    1.399708    1.3997088      10009     2.645751    1.999987    2.000000    2.000000
I       A(I)       EX EX2      Av V*N      Ed Ed2     wAv V*N1     100002    19.493589    0.000000    0.000000    0.0000002     100004     7.416198    1.000000    1.000000    1.0000003     100004    -7.333333    0.942809    0.942809    0.9428094     100004    20.093531    0.865650    0.866025    0.8660255     100005    -1.280625    0.979531    0.979796    0.9797966     100005   -16.492422    1.000305    1.000000    1.0000007     100007    17.851427    1.399895    1.399708    1.3997088     100009    20.566963    1.999835    2.000000    2.000000
I       A(I)       EX EX2      Av V*N      Ed Ed2     wAv V*N1    1000002   -80.024994    0.000000    0.000000    0.0000002    1000004   158.767120    1.000000    1.000000    1.0000003    1000004   -89.146576    0.942809    0.942809    0.9428094    1000004    90.795097    0.869074    0.866025    0.8660255    1000005   193.357590    0.981953    0.979796    0.9797966    1000005   238.361069    0.999691    1.000000    1.0000007    1000007   153.462296    1.399519    1.399708    1.3997088    1000009   151.284500    1.997653    2.000000    2.000000

Speaking loosely, to square a number of d digits accurately requires the ability to represent 2d digits accurately, with more digits needed if many such squares are to be added together accurately. In this example, 1000 when squared, is pushing at the limits of single precision. The average&variance method is resistant to this problem (and does not generate negative variances either!) because it manipulates differences from the running average, but it is still better to use a working mean.

In other words, a two-pass method will be more accurate (where the second pass calculates the variance by accumulating deviations from the actual average, itself calculated with a working mean) but at the cost of that second pass and the saving of all the values. Higher precision variables for the accumulations are the easiest way towards accurate results.

FutureBasic

Translation of:Swift
double local fn CalcSD( x as double )  static double n, sum, sum2  n++  sum += x  sum2 += x * xend fn = sqr( sum2 / n - sum * sum / n / n )void local fn DoIt  double testData(7) = {2,4,4,4,5,5,7,9}  for int i = 0 to 7    double x = testData(i)    double a = fn CalcSD( x )    printf @"value %.0f SD = %f", x, a  nextend fnfn DoItHandleEvents
Output:
value 2 SD = 0.000000value 4 SD = 1.000000value 4 SD = 0.942809value 4 SD = 0.866025value 5 SD = 0.979796value 5 SD = 1.000000value 7 SD = 1.399708value 9 SD = 2.000000

Go

Algorithm to reduce rounding errors from WP article.

State maintained with a closure.

packagemainimport("fmt""math")funcnewRsdv()func(float64)float64{varn,a,qfloat64returnfunc(xfloat64)float64{n++a1:=a+(x-a)/nq,a=q+(x-a)*(x-a1),a1returnmath.Sqrt(q/n)}}funcmain(){r:=newRsdv()for_,x:=range[]float64{2,4,4,4,5,5,7,9}{fmt.Println(r(x))}}
Output:
010.94280904158206340.86602540378443860.979795897113271311.39970842444753042

Groovy

Solution:

Listsamples=[]defstdDev={defsample->samples<<sampledefsum=samples.sum()defsumSq=samples.sum{it*it}defcount=samples.size()(sumSq/count - (sum/count)**2)**0.5}[2,4,4,4,5,5,7,9].each{println"${stdDev(it)}"}
Output:
010.94280904169991450.86602540378443860.979795897113271211.39970842434692622

Haskell

We store the state in theST monad using anSTRef.

{-# LANGUAGE BangPatterns #-}importData.List(foldl')-- 'importData.STRefimportControl.Monad.STdataPairab=Pair!a!bsumLen::[Double]->PairDoubleDoublesumLen=fiof2.foldl'(\(Pairsl)x->Pair(s+x)(l+1))(Pair0.00)--'wherefiof2(Pairsl)=Pairs(fromIntegrall)divl::PairDoubleDouble->Doubledivl(Pair_0.0)=0.0divl(Pairsl)=s/lsd::[Double]->Doublesdxs=sqrt$foldl'(\ax->a+(x-m)^2)0xs/l--'wherep@(Pairsl)=sumLenxsm=divlpmkSD::STs(Double->STsDouble)mkSD=go<$>newSTRef[]wheregoaccx=modifySTRefacc(x:)>>(sd<$>readSTRefacc)main=mapM_print$runST$mkSD>>=forM[2.0,4.0,4.0,4.0,5.0,5.0,7.0,9.0]


Or, perhaps more simply, as a map-accumulation over an indexed list:

importData.List(mapAccumL)-------------- CUMULATIVE STANDARD DEVIATION -------------cumulativeStdDevns::[Float]->[Float]cumulativeStdDevns=snd.mapAccumLgo(0,0).zip[1.0..]wherego(s,q)(i,x)=let_s=s+x_q=q+(x^2)in((_s,_q),sqrt((_q/i)-((_s/i)^2)))--------------------------- TEST -------------------------main::IO()main=mapM_print$cumulativeStdDevns[2,4,4,4,5,5,7,9]
Output:
0.01.00.94280930.86602540.979795931.01.39970872.0

Haxe

usingLambda;classMain{staticfunctionmain():Void{varnums=[2,4,4,4,5,5,7,9];for(iin1...nums.length+1)Sys.println(sdev(nums.slice(0,i)));}staticfunctionaverage<T:Float>(nums:Array<T>):Float{returnnums.fold(function(n,t)returnn+t,0)/nums.length;}staticfunctionsdev<T:Float>(nums:Array<T>):Float{varstore=[];varavg=average(nums);for(ninnums){store.push((n-avg)*(n-avg));}returnMath.sqrt(average(store));}}
010.9428090415820630.8660254037844390.97979589711327111.399708424447532

HicEst

REAL :: n=8, set(n), sum=0, sum2=0set = (2,4,4,4,5,5,7,9)DO k = 1, n   WRITE() 'Adding ' // set(k) // 'stdev = ' // stdev(set(k))ENDDOEND ! end of "main"FUNCTION stdev(x)   USE : sum, sum2, k   sum = sum + x   sum2 = sum2 + x*x   stdev = ( sum2/k - (sum/k)^2) ^ 0.5 END
Adding 2 stdev = 0Adding 4 stdev = 1Adding 4 stdev = 0.9428090416Adding 4 stdev = 0.8660254038Adding 5 stdev = 0.9797958971Adding 5 stdev = 1Adding 7 stdev = 1.399708424Adding 9 stdev = 2

Icon andUnicon

proceduremain()stddev()# reset state / emptyeverys:=stddev(![2,4,4,4,5,5,7,9])dowrite("stddev (so far) := ",s)endprocedurestddev(x)# running standard deviationstaticX,sumX,sum2Xif/xthen{# reset stateX:=[]sumX:=sum2X:=0.}else{# accumulateput(X,x)sumX+:=xsum2X+:=x^2returnsqrt((sum2X/*X)-(sumX/*X)^2)}end
Output:
stddev (so far) := 0.0stddev (so far) := 1.0stddev (so far) := 0.9428090415820626stddev (so far) := 0.8660254037844386stddev (so far) := 0.9797958971132716stddev (so far) := 1.0stddev (so far) := 1.39970842444753stddev (so far) := 2.0

J

J is block-oriented; it expresses algorithms with the semantics of all the data being available at once. It does not have native lexical closure or coroutine semantics. It is possible to implement these semantics in J; seeMoving Average for an example. We will not reprise that here.

mean=:+/%#dev=:-meanstddevP=:[:%:@mean*:@devNB. A) 3 equivalent defs for stddevPstddevP=:[:mean&.:*:devNB. B) uses Under (&.:) to apply inverse of *: after meanstddevP=:%:@(mean@:*:-*:@mean)NB. C) sqrt of ((mean of squares) - (square of mean))stddevP\24445579010.9428090.8660250.97979611.399712

Alternatives:
Using verbose names for J primitives.

of=:@:sqrt=:%:sum=:+/squares=:*:data=:]mean=:sum%#stddevP=:sqrtofmeanofsquaresof(data-mean)stddevP\24445579010.9428090.8660250.97979611.399712
Translation of:R


Or we could take a cue from theR implementation and reverse the Bessel correction to stddev:

require'stats'(%:@:(%~<:)@:#*stddev)\24445579010.9428090.8660250.97979611.399712

Java

publicclassStdDev{intn=0;doublesum=0;doublesum2=0;publicdoublesd(doublex){n++;sum+=x;sum2+=x*x;returnMath.sqrt(sum2/n-sum*sum/n/n);}publicstaticvoidmain(String[]args){double[]testData={2,4,4,4,5,5,7,9};StdDevsd=newStdDev();for(doublex:testData){System.out.println(sd.sd(x));}}}

JavaScript

Imperative

Uses a closure.

functionrunning_stddev(){varn=0;varsum=0.0;varsum_sq=0.0;returnfunction(num){n++;sum+=num;sum_sq+=num*num;returnMath.sqrt((sum_sq/n)-Math.pow(sum/n,2));}}varsd=running_stddev();varnums=[2,4,4,4,5,5,7,9];varstddev=[];for(variinnums)stddev.push(sd(nums[i]));// using WSHWScript.Echo(stddev.join(', ');
Output:
0, 1, 0.942809041582063, 0.866025403784439, 0.979795897113273, 1, 1.39970842444753, 2

Functional

ES5

Accumulating across a fold

(function(xs){returnxs.reduce(function(a,x,i){varn=i+1,sum_=a.sum+x,squaresSum_=a.squaresSum+(x*x);return{sum:sum_,squaresSum:squaresSum_,stages:a.stages.concat(Math.sqrt((squaresSum_/n)-Math.pow((sum_/n),2)))};},{sum:0,squaresSum:0,stages:[]}).stages})([2,4,4,4,5,5,7,9]);
Output:
[0,1,0.9428090415820626,0.8660254037844386,0.9797958971132716,1,1.3997084244475297,2]

ES6

As a map-accumulation:

(()=>{'use strict';// ---------- CUMULATIVE STANDARD DEVIATION ----------// cumulativeStdDevns :: [Float] -> [Float]constcumulativeStdDevns=ns=>{constgo=([s,q])=>([i,x])=>{const_s=s+x,_q=q+(x*x),j=1+i;return[[_s,_q],Math.sqrt((_q/j)-Math.pow(_s/j,2))];};returnmapAccumL(go)([0,0])(ns)[1];};// ---------------------- TEST -----------------------constmain=()=>showLog(cumulativeStdDevns([2,4,4,4,5,5,7,9]));// --------------------- GENERIC ---------------------// mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])constmapAccumL=f=>// A tuple of an accumulation and a list// obtained by a combined map and fold,// with accumulation from left to right.acc=>xs=>[...xs].reduce((a,x,i)=>{constpair=f(a[0])([i,x]);return[pair[0],a[1].concat(pair[1])];},[acc,[]]);// showLog :: a -> IO ()constshowLog=(...args)=>console.log(args.map(x=>JSON.stringify(x,null,2)).join(' -> '));// MAIN ---returnmain();})();
Output:
[  0,  1,  0.9428090415820626,  0.8660254037844386,  0.9797958971132716,  1,  1.3997084244475297,  2]

jq

Observations from a file or array

We first define a filter, "simulate", that, if given a file ofobservations, will emit the standard deviations of the observationsseen so far. The current state is stored in a JSON object, with this structure:

{ "n": _, "ssd": _, "mean": _ }

where "n" is the number of observations seen, "mean" is their average, and "ssd" is the sum of squared deviations about that mean.

The challenge here is to ensure accuracy for very large n, without sacrificing efficiency. The key idea in that regard is that if m is the mean of a series of n observations, x, we then have for any a:

SIGMA( (x - a)^2 ) == SIGMA( (x-m)^2 ) + n * (a-m)^2 == SSD + n*(a-m)^2where SSD is the sum of squared deviations about the mean.
# Compute the standard deviation of the observations # seen so far, given the current state as input:def standard_deviation: .ssd / .n | sqrt;def update_state(observation):   def sq: .*.;  ((.mean * .n + observation) / (.n + 1)) as $newmean  | (.ssd + .n * ((.mean - $newmean) | sq)) as $ssd  | { "n": (.n + 1),      "ssd":  ($ssd + ((observation - $newmean) | sq)),      "mean": $newmean };def initial_state: { "n": 0, "ssd": 0, "mean": 0 };# Given an array of observations presented as input:def simulate:  def _simulate(i; observations):    if (observations|length) <= i then empty    else update_state(observations[i])       | standard_deviation, _simulate(i+1; observations)    end ;  . as $in | initial_state | _simulate(0; $in);# Begin:simulate

Example 1

# observations.txt24445579
Output:
$jq-s-fDynamic_standard_deviation.jqobservations.txt010.94280904158206340.86602540378443860.97979589711327110.99999999999999991.39970842444753021.9999999999999998

Observations from a stream

Recent versions of jq (after 1.4) support retention of state while processing a stream. This means that any generator (including generators that produce items indefinitely) can be used as the source of observations, without first having to capture all the observations, e.g. in a file or array.

# requires jq version > 1.4def simulate(stream):   foreach stream as $observation    (initial_state;     update_state($observation);     standard_deviation);

Example 2:

simulate( range(0;10) )
Output:
00.50.8164965809277261.1180339887498951.41421356237309511.70782512765993322.291287847477922.5819888974716112.8722813232690143

Observations from an external stream

The following illustrates how jq can be used to process observations from an external (potentially unbounded) stream, one at a time. Here we usebash to manage the calls to jq.

The definitions of the filters update_state/1 and initial_state/0 are as above but are repeated so that this script is self-contained.

#!/bin/bash# jq is assumed to be on PATHPROGRAM='def standard_deviation: .ssd / .n | sqrt;def update_state(observation):  def sq: .*.;  ((.mean * .n + observation) / (.n + 1)) as $newmean  | (.ssd + .n * ((.mean - $newmean) | sq)) as $ssd  | { "n": (.n + 1),      "ssd":  ($ssd + ((observation - $newmean) | sq)),      "mean": $newmean };def initial_state: { "n": 0, "ssd": 0, "mean": 0 };# Input should be [observation, null] or [observation, state]def standard_deviations:  . as $in  | if type == "array" then      (if .[1] == null then initial_state else .[1] end) as $state      | $state | update_state($in[0])      | standard_deviation, .    else empty    end;standard_deviations'state=nullwhileread-p"Next observation: "observationdoresult=$(echo"[$observation,$state ]"|jq-c"$PROGRAM")sed-n1p<<<"$result"state=$(sed-n2p<<<"$result")done

Example 3

$./standard_deviation_server.shNextobservation:100Nextobservation:205Nextobservation:08.16496580927726

Julia

Use a closure to create a running standard deviation function.

functionmakerunningstd(::Type{T}=Float64)whereT∑x=∑x²=zero(T)n=0functionrunningstd(x)∑x+=x∑x²+=x^2n+=1s=∑x²/n-(∑x/n)^2returnsendreturnrunningstdendtest=Float64[2,4,4,4,5,5,7,9]rstd=makerunningstd()println("Perform a running standard deviation of ",test)foriintestprintln(" - add$i → ",rstd(i))end
Output:
Perform a running standard deviation of [2.0, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0] - add 2.0 → 0.0 - add 4.0 → 1.0 - add 4.0 → 0.8888888888888875 - add 4.0 → 0.75 - add 5.0 → 0.9600000000000009 - add 5.0 → 1.0 - add 7.0 → 1.9591836734693864 - add 9.0 → 4.0

Kotlin

Translation of:Java

Using a class to keep the running sum, sum of squares and number of elements added so far:

// version 1.0.5-2classCumStdDev{privatevarn=0privatevarsum=0.0privatevarsum2=0.0funsd(x:Double):Double{n++sum+=xsum2+=x*xreturnMath.sqrt(sum2/n-sum*sum/n/n)}}funmain(args:Array<String>){valtestData=doubleArrayOf(2.0,4.0,4.0,4.0,5.0,5.0,7.0,9.0)valcsd=CumStdDev()for(dintestData)println("Add $d => ${csd.sd(d)}")}
Output:
Add 2.0 => 0.0Add 4.0 => 1.0Add 4.0 => 0.9428090415820626Add 4.0 => 0.8660254037844386Add 5.0 => 0.9797958971132708Add 5.0 => 1.0Add 7.0 => 1.399708424447531Add 9.0 => 2.0

Lobster

// Stats computes a running mean and variance // See Knuth TAOCP vol 2, 3rd edition, page 232class Stats:    M = 0.0    S = 0.0    n = 0    def incl(x):        n += 1        if n == 1:            M = x        else:            let mm = (x - M)            M += mm / n            S += mm * (x - M)    def mean(): return M    //def variance(): return (if n > 1.0: S / (n - 1.0) else: 0.0) // Bessel's correction    def variance(): return (if n > 0.0: S / n else: 0.0)    def stddev(): return sqrt(variance())    def count(): return n def test_stdv() -> float:    let v = [2,4,4,4,5,5,7,9]    let s = Stats {}    for(v) x: s.incl(x+0.0)    print concat_string(["Mean: ", string(s.mean()), ", Std.Deviation: ", string(s.stddev())], "")test_stdv()
Output:
Mean: 5.0, Std.Deviation: 2.0

Lua

Uses a closure. Translation of JavaScript.

functionstdev()localsum,sumsq,k=0,0,0returnfunction(n)sum,sumsq,k=sum+n,sumsq+n^2,k+1returnmath.sqrt((sumsq/k)-(sum/k)^2)endendldev=stdev()fori,vinipairs{2,4,4,4,5,5,7,9}doprint(ldev(v))end

Mathematica /Wolfram Language

runningSTDDev[n_]:=(If[Not[ValueQ[$Data]],$Data={}];StandardDeviation[AppendTo[$Data,n]])

MATLAB /Octave

The simple form is, computing only the standand deviation of the whole data set:

x=[2,4,4,4,5,5,7,9];n=length(x);m=mean(x);x2=mean(x.*x);dev=sqrt(x2-m*m)dev=2

When the intermediate results are also needed, one can use this vectorized form:

m=cumsum(x)./[1:n];% running meanx2=cumsum(x.^2)./[1:n];% running squaresdev=sqrt(x2-m.*m)dev=0.000001.000000.942810.866030.979801.000001.399712.00000

Here is a vectorized one line solution as a function

functionstdDevEval(n)disp(sqrt(sum((n-sum(n)/length(n)).^2)/length(n)));end

MiniScript

StdDeviator={}StdDeviator.count=0StdDeviator.sum=0StdDeviator.sumOfSquares=0StdDeviator.add=function(x)self.count=self.count+1self.sum=self.sum+xself.sumOfSquares=self.sumOfSquares+x*xendfunctionStdDeviator.stddev=function()m=self.sum/self.countreturnsqrt(self.sumOfSquares/self.count-m*m)endfunctionsd=newStdDeviatorforxin[2,4,4,4,5,5,7,9]sd.addxendforprintsd.stddev
Output:
2

МК-61/52

0П4П5П6С/ПП0ИП5+П5ИП0x^2ИП6+П6КИП4ИП6ИП4/ИП5ИП4/x^2-КвКорБП04

Instruction: В/О С/Пnumber С/Пnumber С/П ...

Nanoquery

Translation of:Java
class StdDevdeclare ndeclare sumdeclare sum2def StdDev()n = 0sum = 0sum2 = 0enddef sd(x)this.n += 1this.sum += xthis.sum2 += x*xreturn sqrt(sum2/n - sum*sum/n/n)endendtestData = {2,4,4,4,5,5,7,9}sd = new(StdDev)for x in testDataprintln sd.sd(x)end
Output:
0.01.00.94280904158206340.86602540378443860.97979589711327121.01.39970842444753042.0

Nim

Using global variables

importmath,strutilsvarsdSum,sdSum2,sdN=0.0procsd(x:float):float=sdN+=1sdSum+=xsdSum2+=x*xsqrt(sdSum2/sdN-sdSum*sdSum/(sdN*sdN))forvaluein[float2,4,4,4,5,5,7,9]:echovalue," ",formatFloat(sd(value),precision=-1)
Output:
2 04 14 0.9428094 0.8660255 0.9797965 17 1.399719 2

Using an accumulator object

importmath,strutilstypeSDAccum=objectsdN,sdSum,sdSum2:floatvaraccum:SDAccumprocadd(accum:varSDAccum;value:float):float=# Add a value to the accumulator. Return the standard deviation.accum.sdN+=1accum.sdSum+=valueaccum.sdSum2+=value*valueresult=sqrt(accum.sdSum2/accum.sdN-accum.sdSum*accum.sdSum/(accum.sdN*accum.sdN))forvaluein[float2,4,4,4,5,5,7,9]:echovalue," ",formatFloat(accum.add(value),precision=-1)
Output:

Same output.

Using a closure

importmath,strutilsfuncaccumBuilder():auto=varsdSum,sdSum2,sdN=0.0result=func(value:float):float=sdN+=1sdSum+=valuesdSum2+=value*valueresult=sqrt(sdSum2/sdN-sdSum*sdSum/(sdN*sdN))letstd=accumBuilder()forvaluein[float2,4,4,4,5,5,7,9]:echovalue," ",formatFloat(std(value),precision=-1)
Output:

Same output.

Oberon-07

Translation of:Python – started as a translation of the Algol 68 "unpackaged" sample and evolved from there
MODULECumulativeStandardDeviation;IMPORTMath,Out;TYPECSD*=POINTERTOCSDStruct;CSDStruct=RECORDsum,sum2,sd:REAL;n:INTEGEREND;PROCEDUREsample*(sd:CSD;x:REAL):REAL;VARr,sum,sum2:REAL;BEGINsum:=sd.sum+x;sum2:=sd.sum2+(x*x);;INC(sd.n);r:=FLT(sd.n);IFsd.n=0THENsd.sd:=0.0ELSEsd.sd:=Math.sqrt(sum2/r-sum*sum/r/r)END;sd.sum:=sum;sd.sum2:=sum2RETURNsd.sdENDsample;PROCEDURENewCSD*():CSD;VARsd:CSD;BEGINNEW(sd);sd.n:=0;sd.sum:=0.0;sd.sum2:=0.0;sd.sd:=0.0RETURNsdENDNewCSD;PROCEDUREshowSampleEffect(sd:CSD;x:REAL);VARdev:REAL;BEGINdev:=sample(sd,x);Out.Int(sd.n,6);Out.String(": ");Out.Real(x,10);Out.String(" -> ");Out.Real(dev,10);Out.LnENDshowSampleEffect;PROCEDUREtest;VARsd:CSD;BEGINsd:=NewCSD();showSampleEffect(sd,2.0);showSampleEffect(sd,4.0);showSampleEffect(sd,4.0);showSampleEffect(sd,4.0);showSampleEffect(sd,5.0);showSampleEffect(sd,5.0);showSampleEffect(sd,7.0);showSampleEffect(sd,9.0)ENDtest;BEGINtest;ENDCumulativeStandardDeviation.
Output:

Showing the output fromoberonc, the real number format may be different with other compilers.

     1:   2.000000 ->   0.000000     2:   4.000000 ->   1.000000     3:   4.000000 ->   0.942809     4:   4.000000 ->   0.866025     5:   5.000000 ->   0.979796     6:   5.000000 ->   1.000000     7:   7.000000 ->   1.399708     8:   9.000000 ->   2.000000

Oberon-2

Translation of:Oberon-07

Oberon-2 has type bound procedures, allowing us to writesd.sample( x ) instead ofsample( sd, x ).

MODULECumulativeStandardDeviation;IMPORTMath,Out;TYPECSD*=POINTERTOCSDStruct;CSDStruct*=RECORDsum,sum2,sd:REAL;n:INTEGER;END;PROCEDURE(sd:CSD)sample*(x:REAL):REAL;VARr,sum,sum2:REAL;BEGINsum:=sd.sum+x;sum2:=sd.sum2+(x*x);;INC(sd.n);r:=sd.n;IFsd.n=0THENsd.sd:=0.0ELSEsd.sd:=Math.sqrt(sum2/r-sum*sum/r/r)END;sd.sum:=sum;sd.sum2:=sum2;RETURNsd.sdENDsample;PROCEDURENewCSD*():CSD;VARsd:CSD;BEGINNEW(sd);sd.n:=0;sd.sum:=0.0;sd.sum2:=0.0;sd.sd:=0.0;RETURNsdENDNewCSD;PROCEDURE(sd:CSD)showSampleEffect(x:REAL);VARdev:REAL;BEGINdev:=sd.sample(x);Out.Int(sd.n,6);Out.String(": ");Out.Real(x,15);Out.String(" -> ");Out.Real(dev,15);Out.LnENDshowSampleEffect;PROCEDUREtest;VARsd:CSD;BEGINsd:=NewCSD();sd.showSampleEffect(2.0);sd.showSampleEffect(4.0);sd.showSampleEffect(4.0);sd.showSampleEffect(4.0);sd.showSampleEffect(5.0);sd.showSampleEffect(5.0);sd.showSampleEffect(7.0);sd.showSampleEffect(9.0)ENDtest;BEGINtest;ENDCumulativeStandardDeviation.
Output:

Similar to theOberon-07 sample, except for differences in real number formatting.

Objeck

Translation of:Java
use Structure;bundle Default {  class StdDev {    nums : FloatVector;        New() {      nums := FloatVector->New();    }        function : Main(args : String[]) ~ Nil {      sd := StdDev->New();      test_data := [2.0, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0];      each(i : test_data) {        sd->AddNum(test_data[i]);        sd->GetSD()->PrintLine();      };    }        method : public : AddNum(num : Float) ~ Nil {      nums->AddBack(num);    }        method : public : native : GetSD() ~ Float {      sq_diffs := 0.0;      avg := nums->Average();      each(i : nums) {        num := nums->Get(i);        sq_diffs += (num - avg) * (num - avg);      };            return (sq_diffs / nums->Size())->SquareRoot();    }  }}

Objective-C

#import <Foundation/Foundation.h>@interfaceSDAccum :NSObject{doublesum,sum2;unsignedintnum;}-(double)value:(double)v;-(unsignedint)count;-(double)mean;-(double)variance;-(double)stddev;@end@implementationSDAccum-(double)value:(double)v{sum+=v;sum2+=v*v;num++;return[selfstddev];}-(unsignedint)count{returnnum;}-(double)mean{return(num>0)?sum/(double)num:0.0;}-(double)variance{doublem=[selfmean];return(num>0)?(sum2/(double)num-m*m):0.0;}-(double)stddev{returnsqrt([selfvariance]);}@endintmain(){@autoreleasepool{doublev[]={2,4,4,4,5,5,7,9};SDAccum*sdacc=[[SDAccumalloc]init];for(inti=0;i<sizeof(v)/sizeof(*v);i++)printf("adding %f\tstddev = %f\n",v[i],[sdaccvalue:v[i]]);}return0;}

Blocks

Works with:Mac OS X version 10.6+
Works with:iOS version 4+
#import <Foundation/Foundation.h>typedefdouble(^Func)(double);// a block that takes a double and returns a doubleFuncsdCreator(){__blockintn=0;__blockdoublesum=0;__blockdoublesum2=0;return^(doublex){sum+=x;sum2+=x*x;n++;returnsqrt(sum2/n-sum*sum/n/n);};}intmain(){@autoreleasepool{doublev[]={2,4,4,4,5,5,7,9};Funcsdacc=sdCreator();for(inti=0;i<sizeof(v)/sizeof(*v);i++)printf("adding %f\tstddev = %f\n",v[i],sdacc(v[i]));}return0;}

OCaml

letsqrx=x*.xletstddevl=letn,sx,sx2=List.fold_left(fun(n,sx,sx2)x->succn,sx+.x,sx2+.sqrx)(0,0.,0.)linsqrt((sx2-.sqrsx/.floatn)/.floatn)let_=letl=[2.;4.;4.;4.;5.;5.;7.;9.]inPrintf.printf"List: ";List.iter(Printf.printf"%g  ")l;Printf.printf"\nStandard deviation: %g\n"(stddevl)
Output:
List: 2  4  4  4  5  5  7  9Standard deviation: 2

Oforth

Oforth does not have global variables that can be used to create statefull functions.

Here, we create a channel to hold current list of numbers. Constraint is that this channel can't hold mutable objects. On the other hand, stddev function is thread safe and can be called by tasks running in parallel.

Channel new [ ] over send drop const: StdValues: stddev(x)| l |   StdValues receive x + dup ->l StdValues send drop   #qs l map sum l size asFloat / l avg sq - sqrt ;
Output:
>[ 2, 4, 4, 4, 5, 5, 7, 9 ] apply(#[ stddev println ])010.9428090415820630.8660254037844390.97979589711327211.399708424447532ok>

ooRexx

Works with:oorexx
sdacc=.SDAccum~newx=.array~of(2,4,4,4,5,5,7,9)sd=0doi=1tox~sizesd=sdacc~value(x[i])Say'#'i'value ='x[i]'stdev ='sdend::classSDAccum::methodsumattribute::methodsum2attribute::methodcountattribute::methodinitself~sum=0.0self~sum2=0.0self~count=0::methodvalueexposesumsum2countparseargxsum=sum+xsum2=sum2+x*xcount=count+1returnself~stddev::methodmeanexposesumcountreturnsum/count::methodvarianceexposesum2countm=self~meanreturnsum2/count-m*m::methodstddevreturnself~sqrt(self~variance)::methodsqrtargnifn=0thenreturn0ans=n/2prev=ndountilprev=ansprev=ansans=(prev+(n/prev))/2endreturnans
Output:
#1 value = 2 stdev = 0#2 value = 4 stdev = 1#3 value = 4 stdev = 0.94280905#4 value = 4 stdev = 0.866025405#5 value = 5 stdev = 0.979795895#6 value = 5 stdev = 1#7 value = 7 stdev = 1.39970844#8 value = 9 stdev = 2

PARI/GP

Uses the Cramer-Young updating algorithm. For demonstration it displays the mean and variance at each step.

newpoint(x)={  myT=x;  myS=0;  myN=1;  [myT,myS]/myN};addpoint(x)={  myT+=x;  myN++;  myS+=(myN*x-myT)^2/myN/(myN-1);  [myT,myS]/myN};addpoints(v)={  print(newpoint(v[1]));  for(i=2,#v,print(addpoint(v[i])));  print("Mean: ",myT/myN);  print("Standard deviation: ",sqrt(myS/myN))};addpoints([2,4,4,4,5,5,7,9])

Pascal

Std.Pascal

Translation of:AWK
programstddev;usesmath;constn=8;vararr:array[1..n]ofreal=(2,4,4,4,5,5,7,9);functionstddev(n:integer):real;vari:integer;s1,s2,variance,x:real;beginfori:=1tondobeginx:=arr[i];s1:=s1+power(x,2);s2:=s2+xend;variance:=((n*s1)-(power(s2,2)))/(power(n,2));stddev:=sqrt(variance)end;vari:integer;beginfori:=1tondobeginwriteln(i,' item=',arr[i]:2:0,' stddev=',stddev(i):18:15)endend.
Output:
1 item= 2 stddev= 0.0000000000000002 item= 4 stddev= 1.0000000000000003 item= 4 stddev= 0.9428090415820644 item= 4 stddev= 0.8660254037844395 item= 5 stddev= 0.9797958971132716 item= 5 stddev= 1.0000000000000007 item= 7 stddev= 1.3997084244475308 item= 9 stddev= 2.000000000000000

Delphi

programprj_CalcStdDerv;{$APPTYPE CONSOLE}usesMath;varSeries:ArrayofExtended;UserString:String;functionAppendAndCalc(NewVal:Extended):Extended;beginsetlength(Series,high(Series)+2);Series[high(Series)]:=NewVal;result:=PopnStdDev(Series);end;constdata:array[0..7]ofExtended=(2,4,4,4,5,5,7,9);varrr:Extended;beginsetlength(Series,0);forrrindatadobeginwriteln(rr,' -> ',AppendAndCalc(rr));end;Readln;end.
Output:
 2.0000000000000000E+0000 ->  0.0000000000000000E+0000 4.0000000000000000E+0000 ->  1.0000000000000000E+0000 4.0000000000000000E+0000 ->  9.4280904158206337E-0001 4.0000000000000000E+0000 ->  8.6602540378443865E-0001 5.0000000000000000E+0000 ->  9.7979589711327124E-0001 5.0000000000000000E+0000 ->  1.0000000000000000E+0000 7.0000000000000000E+0000 ->  1.3997084244475303E+0000 9.0000000000000000E+0000 ->  2.0000000000000000E+0000

PascalABC.NET

With a Closure

##functionsdcreator():real->real;beginvarSum:=0.0;varSum2:=0.0;varN:=0;result:=function(x:real):real->beginN+=1;Sum+=x;Sum2+=x*x;result:=sqrt(Sum2/N-Sum*Sum/(N*N));end;end;varsd:=sdcreator();foreachvarvaluein|2,4,4,4,5,5,7,9|doprintln(value,sd(value));
Output:
2 04 14 0.9428090415820644 0.8660254037844395 0.9797958971132725 17 1.399708424447539 2

Perl

{packageSDAccum;subnew{my$class=shift;my$self={};$self->{sum}=0.0;$self->{sum2}=0.0;$self->{num}=0;bless$self,$class;return$self;}subcount{my$self=shift;return$self->{num};}submean{my$self=shift;return($self->{num}>0)?$self->{sum}/$self->{num}:0.0;}subvariance{my$self=shift;my$m=$self->mean;return($self->{num}>0)?$self->{sum2}/$self->{num}-$m*$m:0.0;}substddev{my$self=shift;returnsqrt($self->variance);}subvalue{my$self=shift;my$v=shift;$self->{sum}+=$v;$self->{sum2}+=$v*$v;$self->{num}++;return$self->stddev;}}
my$sdacc=SDAccum->new;my$sd;foreachmy$v(2,4,4,4,5,5,7,9){$sd=$sdacc->value($v);}print"std dev = $sd\n";

A much shorter version using a closure and a property of the variance:

# <(x - <x>)²> = <x²> - <x>²{my$num,$sum,$sum2;substddev{my$x=shift;$num++;returnsqrt(($sum2+=$x**2)/$num-(($sum+=$x)/$num)**2);}}printstddev($_),"\n"forqw(2 4 4 4 5 5 7 9);
Output:
010.9428090415820630.8660254037844390.97979589711327211.399708424447532

one-liner:

perl-MMath::StdDev-e'$d=new Math::StdDev;foreach my $v ( 2,4,4,4,5,5,7,9 ) {$d->Update($v); print $d->variance(),"\n"}'

small script:

useMath::StdDev;$d=newMath::StdDev;foreachmy$v(2,4,4,4,5,5,7,9){$d->Update($v);print$d->variance(),"\n"}
Output:
010.9428090415820630.8660254037844390.97979589711327111.399708424447532

Phix

demo\rosetta\Standard_deviation.exw contains a copy of this code and a version that could be the basis for a library version that can handle multiple active data sets concurrently.

withjavascript_semanticsatomsdn=0,sdsum=0,sdsumsq=0proceduresdadd(atomn)sdn+=1sdsum+=nsdsumsq+=n*nendprocedurefunctionsdavg()returnsdsum/sdnendfunctionfunctionsddev()returnsqrt(sdsumsq/sdn-power(sdsum/sdn,2))endfunction--test code:constanttestset={2,4,4,4,5,5,7,9}integertifori=1tolength(testset)doti=testset[i]sdadd(ti)printf(1,"N=%d Item=%d Avg=%5.3f StdDev=%5.3f\n",{i,ti,sdavg(),sddev()})endfor
Output:
N=1 Item=2 Avg=2.000 StdDev=0.000N=2 Item=4 Avg=3.000 StdDev=1.000N=3 Item=4 Avg=3.333 StdDev=0.943N=4 Item=4 Avg=3.500 StdDev=0.866N=5 Item=5 Avg=3.800 StdDev=0.980N=6 Item=5 Avg=4.000 StdDev=1.000N=7 Item=7 Avg=4.429 StdDev=1.400N=8 Item=9 Avg=5.000 StdDev=2.000

As of 1.0.6 there is a builtin std_dev(), the following produces the same output as above, albeit w/o any running totals:

withjavascript_semanticsconstanttestset={2,4,4,4,5,5,7,9}fori,tintestsetdosequencetest=testset[1..i]printf(1,"N=%d Item=%d Avg=%5.3f StdDev=%5.3f\n",{i,t,average(test),std_dev(test)})endfor

PHP

This is just straight PHP class usage, respecting the specifications "stateful" and "one at a time":

<?phpclasssdcalc{private$cnt,$sumup,$square;function__construct(){$this->reset();}# callable on an instancefunctionreset(){$this->cnt=0;$this->sumup=0;$this->square=0;}functionadd($f){$this->cnt++;$this->sumup+=$f;$this->square+=pow($f,2);return$this->calc();}functioncalc(){if($this->cnt==0||$this->sumup==0){return0;}else{returnsqrt($this->square/$this->cnt-pow(($this->sumup/$this->cnt),2));}}}# start test, adding test data one by one$c=newsdcalc();foreach([2,4,4,4,5,5,7,9]as$v){printf('Adding %g: result %g%s',$v,$c->add($v),PHP_EOL);}

This will produce the output:

Adding 2: result 0Adding 4: result 1Adding 4: result 0.942809Adding 4: result 0.866025Adding 5: result 0.979796Adding 5: result 1Adding 7: result 1.39971Adding 9: result 2

PicoLisp

(scl 2)(de stdDev ()   (curry ((Data)) (N)      (push 'Data N)      (let (Len (length Data)  M (*/ (apply + Data) Len))         (sqrt            (*/               (sum                  '((N) (*/ (- N M) (- N M) 1.0))                  Data )               1.0               Len )            T ) ) ) )(let Fun (stdDev)   (for N (2.0 4.0 4.0 4.0 5.0 5.0 7.0 9.0)      (prinl (format N *Scl) " -> " (format (Fun N) *Scl)) ) )
Output:
2.00 -> 0.004.00 -> 1.004.00 -> 0.944.00 -> 0.875.00 -> 0.985.00 -> 1.007.00 -> 1.409.00 -> 2.00

PL/I

*process source attributes xref; stddev: proc options(main);   declare a(10) float init(1,2,3,4,5,6,7,8,9,10);   declare stdev float;   declare i fixed binary;        stdev=std_dev(a);   put skip list('Standard deviation', stdev);        std_dev: procedure(a) returns(float);     declare a(*) float, n fixed binary;     n=hbound(a,1);     begin;       declare b(n) float, average float;       declare i fixed binary;       do i=1 to n;         b(i)=a(i);       end;       average=sum(a)/n;       put skip data(average);       return( sqrt(sum(b**2)/n - average**2) );     end;   end std_dev;  end;
Output:
AVERAGE= 5.50000E+0000;Standard deviation       2.87228E+0000

Pluto

Translation of:Wren
Library:Pluto-table2
Library:Pluto-fmt
require"table2"localfmt=require"fmt"localfunctioncum_std_dev(a)fori=1,#adolocalb=a:slice(1,i)fmt.print("Values  : %,s",b)coroutine.yield(b:stddev())endendlocala={2,4,4,4,5,5,7,9}localco=coroutine.create(cum_std_dev)whiletruedolocal_,sd=coroutine.resume(co,a)if!sdthenbreakendfmt.print("Std Dev : %10.8f\n",sd)end
Output:
Values  : {2}Std Dev : 0.00000000Values  : {2, 4}Std Dev : 1.00000000Values  : {2, 4, 4}Std Dev : 0.94280904Values  : {2, 4, 4, 4}Std Dev : 0.86602540Values  : {2, 4, 4, 4, 5}Std Dev : 0.97979590Values  : {2, 4, 4, 4, 5, 5}Std Dev : 1.00000000Values  : {2, 4, 4, 4, 5, 5, 7}Std Dev : 1.39970842Values  : {2, 4, 4, 4, 5, 5, 7, 9}Std Dev : 2.00000000

PowerShell

This implementation takes the form of an advanced function which can act like a cmdlet and receive input from the pipeline.

functionGet-StandardDeviation{begin{$avg=0$nums=@()}process{$nums+=$_$avg=($nums|Measure-Object-Average).Average$sum=0;$nums|ForEach-Object{$sum+=($avg-$_)*($avg-$_)}[Math]::Sqrt($sum/$nums.Length)}}

Usage as follows:

PS> 2,4,4,4,5,5,7,9 | Get-StandardDeviation010.9428090415820630.8660254037844390.97979589711327111.399708424447532

Python

Python: Using a function with attached properties

The program should work with Python 2.x and 3.x, although the output would not be a tuple in 3.x

>>>frommathimportsqrt>>>defsd(x):sd.sum+=xsd.sum2+=x*xsd.n+=1.0sum,sum2,n=sd.sum,sd.sum2,sd.nreturnsqrt(sum2/n-sum*sum/n/n)>>>sd.sum=sd.sum2=sd.n=0>>>forvaluein(2,4,4,4,5,5,7,9):print(value,sd(value))(2,0.0)(4,1.0)(4,0.94280904158206258)(4,0.8660254037844386)(5,0.97979589711327075)(5,1.0)(7,1.3997084244475311)(9,2.0)>>>

Python: Using a class instance

>>>classSD(object):# Plain () for python 3.xdef__init__(self):self.sum,self.sum2,self.n=(0,0,0)defsd(self,x):self.sum+=xself.sum2+=x*xself.n+=1.0sum,sum2,n=self.sum,self.sum2,self.nreturnsqrt(sum2/n-sum*sum/n/n)>>>sd_inst=SD()>>>forvaluein(2,4,4,4,5,5,7,9):print(value,sd_inst.sd(value))

Python: Callable class

You could rename the methodsd to__call__ this would make the class instance callable like a function so instead of usingsd_inst.sd(value) it would change tosd_inst(value) for the same results.

Python: Using a Closure

Works with:Python version 3.x
>>>frommathimportsqrt>>>defsdcreator():sum=sum2=n=0defsd(x):nonlocalsum,sum2,nsum+=xsum2+=x*xn+=1.0returnsqrt(sum2/n-sum*sum/n/n)returnsd>>>sd=sdcreator()>>>forvaluein(2,4,4,4,5,5,7,9):print(value,sd(value))20.041.040.94280904158240.86602540378450.97979589711351.071.3997084244592.0

Python: Using an extended generator

Works with:Python version 2.5+
>>>frommathimportsqrt>>>defsdcreator():sum=sum2=n=0whileTrue:x=yieldsqrt(sum2/n-sum*sum/n/n)ifnelseNonesum+=xsum2+=x*xn+=1.0>>>sd=sdcreator()>>>sd.send(None)>>>forvaluein(2,4,4,4,5,5,7,9):print(value,sd.send(value))20.041.040.94280904158240.86602540378450.97979589711351.071.3997084244592.0

Python: In a couple of 'functional' lines

>>>myMean=lambdaMyList:reduce(lambdax,y:x+y,MyList)/float(len(MyList))>>>myStd=lambdaMyList:(reduce(lambdax,y:x+y,map(lambdax:(x-myMean(MyList))**2,MyList))/float(len(MyList)))**.5>>>printmyStd([2,4,4,4,5,5,7,9])2.0

R

To compute the running sum, one must keep track of the number of items, the sum of values, and the sum of squares.

If the goal is to get a vector of running standard deviations, the simplest is to do it with cumsum:

cumsd<-function(x){n<-seq_along(x)sqrt(cumsum(x^2)/n-(cumsum(x)/n)^2)}set.seed(12345L)x<-rnorm(10)cumsd(x)# [1] 0.0000000 0.3380816 0.8752973 1.1783628 1.2345538 1.3757142 1.2867220 1.2229056 1.1665168 1.1096814# Compare to the naive implementation, i.e. compute sd on each sublist:Vectorize(function(k)sd(x[1:k])*sqrt((k-1)/k))(seq_along(x))# [1]        NA 0.3380816 0.8752973 1.1783628 1.2345538 1.3757142 1.2867220 1.2229056 1.1665168 1.1096814# Note that the first is NA because sd is unbiased formula, hence there is a division by n-1, which is 0 for n=1.

The task requires an accumulator solution:

accumsd<-function(){n<-0m<-0s<-0function(x){n<<-n+1m<<-m+xs<<-s+x*xsqrt(s/n-(m/n)^2)}}f<-accumsd()sapply(x,f)# [1] 0.0000000 0.3380816 0.8752973 1.1783628 1.2345538 1.3757142 1.2867220 1.2229056 1.1665168 1.1096814

Racket

#langracket(requiremath)(definerunning-stddev(let([ns'()])(λ(n)(set!ns(consnns))(stddevns))));; run it on each number, return the last result(last(maprunning-stddev'(24445579)))

Raku

(formerly Perl 6)

Using a closure:

subsd (@a) {my$mean =@aR/ [+]@a;sqrt@aR/ [+]map (* -$mean)²,@a;}subsdaccum {my@a;return {push@a,$^x;sd@a; };}my&f =sdaccum;sayf$_for2,4,4,4,5,5,7,9;

Using a state variable (remember that<(x-<x>)²> = <x²> - <x>²):

substddev($x) {sqrt        ( .[2] +=$x²) / ++.[0]      - ((.[1] +=$x ) /   .[0])²givenstate @;}say .&stddevfor<2 4 4 4 5 5 7 9>;
Output:
010.9428090415820630.8660254037844390.97979589711327111.399708424447532

REXX

These REXX versions use  running sums.

show running sums

/*REXX program calculates and displays the standard deviation of a given set of numbers.*/parsearg#/*obtain optional arguments from the CL*/if#=''then#=24445579/*None specified?  Then use the default*/n=words(#);$=0;$$=0;L=length(n)/*N:  # items; $,$$:  sums to be zeroed*//* [↓]  process each number in the list*/doj=1forn_=word(#,j);$=$+_$$=$$+_**2say'   item'right(j,L)":"right(_,4)'  average='left($/j,12),'   standard deviation='sqrt($$/j-($/j)**2)end/*j*//* [↑]  prettify output with whitespace*/say'standard deviation: 'sqrt($$/n-($/n)**2)/*calculate & display the std deviation*/exit0/*stick a fork in it,  we're all done. *//*──────────────────────────────────────────────────────────────────────────────────────*/sqrt:procedure;parseargx;ifx=0thenreturn0;d=digits();h=d+6;m.=9;numericformnumericdigits;parsevalueformat(x,2,1,,0)'E0'withg'E'_.;g=g*.5'e'_%2doj=0whileh>9;m.j=h;h=h%2+1;end/*j*/dok=j+5to0by-1;numericdigitsm.k;g=(g+x/g)*.5;end/*k*/numericdigitsd;returng/1
output  when using the default input of:     2   4   4   4   5   5   7   9
   item 1:    2    average= 2               standard deviation= 0   item 2:    4    average= 3               standard deviation= 1   item 3:    4    average= 3.33333333      standard deviation= 0.942809047   item 4:    4    average= 3.5             standard deviation= 0.866025404   item 5:    5    average= 3.8             standard deviation= 0.979795897   item 6:    5    average= 4               standard deviation= 1   item 7:    7    average= 4.42857143      standard deviation= 1.39970843   item 8:    9    average= 5               standard deviation= 2standard deviation:  2

only show standard deviation

/*REXX program calculates and displays the standard deviation of a given set of numbers.*/parsearg#/*obtain optional arguments from the CL*/if#=''then#=24445579/*None specified?  Then use the default*/n=words(#);$=0;$$=0/*N:  # items; $,$$:  sums to be zeroed*//* [↓]  process each number in the list*/doj=1forn/*perform summation on two sets of #'s.*/_=word(#,j);$=$+_$$=$$+_**2end/*j*/say'standard deviation: 'sqrt($$/n-($/n)**2)/*calculate&display the std, deviation.*/exit0/*stick a fork in it,  we're all done. *//*──────────────────────────────────────────────────────────────────────────────────────*/sqrt:procedure;parseargx;ifx=0thenreturn0;d=digits();h=d+6;m.=9;numericformnumericdigits;parsevalueformat(x,2,1,,0)'E0'withg'E'_.;g=g*.5'e'_%2doj=0whileh>9;m.j=h;h=h%2+1;end/*j*/dok=j+5to0by-1;numericdigitsm.k;g=(g+x/g)*.5;end/*k*/numericdigitsd;returng/1
output  when using the default input of:     2   4   4   4   5   5   7   9
standard deviation:  2

Ring

# Project : Cumulative standard deviationdecimals(6)sdsave = list(100) sd = "2,4,4,4,5,5,7,9"sumval = 0sumsqs = 0for num = 1 to 8     sd = substr(sd, ",", "")     stddata = number(sd[num])     sumval = sumval + stddata     sumsqs = sumsqs + pow(stddata,2)      standdev = pow(((sumsqs / num) - pow((sumval /num),2)),0.5)      sdsave[num] = string(num) + " " + string(sumval) +" " + string(sumsqs)     see "" + num + " value in = " + stddata + " Stand Dev = " + standdev + nlnext

Output:

1 value in = 2 Stand Dev = 02 value in = 4 Stand Dev = 13 value in = 4 Stand Dev = 0.9428094 value in = 4 Stand Dev = 0.8660255 value in = 5 Stand Dev = 0.9797966 value in = 5 Stand Dev = 17 value in = 7 Stand Dev = 1.3997088 value in = 9 Stand Dev = 2

RPL

Basic RPL

≪ CL∑ { } SWAP   1 OVER SIZEFOR j      DUP j GET ∑+IF j 1 >THEN         SDEV ∑DAT SIZE 1 GET DUP 1 - SWAP / √ *          ROT SWAP + SWAPENDNEXT   DROP CL∑ ≫ 'CSDEV' STO

RPL 1993

≪ CL∑    1 ≪ ∑+ PSDEV ≫ DOSUBS CL∑≫ 'CSDEV' STO
Output:
1: { 0 1 0.942809041582 0.866025403784 0.979795897113 1 1.39970842445 2 }

Ruby

Object

Uses an object to keep state.

"Simplification of the formula [...] for standard deviation [...] can be memorized as taking the square root of (the average of the squares less the square of the average)."c.f. wikipedia.

classStdDevAccumulatordefinitialize@n,@sum,@sumofsquares=0,0.0,0.0enddef<<(num)# return self to make this possible:  sd << 1 << 2 << 3 # => 0.816496580927726@n+=1@sum+=num@sumofsquares+=num**2selfenddefstddevMath.sqrt((@sumofsquares/@n)-(@sum/@n)**2)enddefto_sstddev.to_sendendsd=StdDevAccumulator.newi=0[2,4,4,4,5,5,7,9].each{|n|puts"adding#{n}: stddev of#{i+=1} samples is#{sd<<n}"}
adding 2: stddev of 1 samples is 0.0adding 4: stddev of 2 samples is 1.0adding 4: stddev of 3 samples is 0.942809041582063adding 4: stddev of 4 samples is 0.866025403784439adding 5: stddev of 5 samples is 0.979795897113272adding 5: stddev of 6 samples is 1.0adding 7: stddev of 7 samples is 1.39970842444753adding 9: stddev of 8 samples is 2.0

Closure

defsdaccumn,sum,sum2=0,0.0,0.0lambdado|num|n+=1sum+=numsum2+=num**2Math.sqrt((sum2/n)-(sum/n)**2)endendsd=sdaccum[2,4,4,4,5,5,7,9].each{|n|printsd.call(n),", "}
0.0, 1.0, 0.942809041582063, 0.866025403784439, 0.979795897113272, 1.0, 1.39970842444753, 2.0,

Rust

Using a struct:

Translation of:Java
pub struct CumulativeStandardDeviation {    n: f64,    sum: f64,    sum_sq: f64}impl CumulativeStandardDeviation {    pub fn new() -> Self {        CumulativeStandardDeviation {            n: 0.,            sum: 0.,            sum_sq: 0.        }    }    fn push(&mut self, x: f64) -> f64 {        self.n += 1.;        self.sum += x;        self.sum_sq += x * x;        (self.sum_sq / self.n - self.sum * self.sum / self.n / self.n).sqrt()    }}fn main() {    let nums = [2, 4, 4, 4, 5, 5, 7, 9];    let mut cum_stdev = CumulativeStandardDeviation::new();    for num in nums.iter() {        println!("{}", cum_stdev.push(*num as f64));    }}
Output:
010.94280904158206260.86602540378443860.979795897113270811.3997084244475312

Using a closure:

fn sd_creator() -> impl FnMut(f64) -> f64 {    let mut n = 0.0;    let mut sum = 0.0;    let mut sum_sq = 0.0;    move |x| {        sum += x;        sum_sq += x*x;        n += 1.0;        (sum_sq / n - sum * sum / n / n).sqrt()    }}fn main() {    let nums = [2, 4, 4, 4, 5, 5, 7, 9];    let mut sd_acc = sd_creator();    for num in nums.iter() {        println!("{}", sd_acc(*num as f64));    }}
Output:
010.94280904158206260.86602540378443860.979795897113270811.3997084244475312

SAS

*--Load the test data;data test1;   input x @@;   obs=_n_;datalines;2 4 4 4 5 5 7 9;run;*--Create a dataset with the cummulative data for each set of data for which the SD should be calculated;data test2 (drop=i obs);   set test1;   y=x;   do i=1 to n;      set test1 (rename=(obs=setid)) nobs=n point=i;      if obs<=setid then output;   end;proc sort;   by setid;run;*--Calulate the standards deviation (and mean) using PROC MEANS;proc means data=test2 vardef=n noprint; *--use vardef=n option to calculate the population SD;   by setid;   var y;   output out=stat1 n=n mean=mean std=sd;run;*--Output the calculated standard deviations;proc print data=stat1 noobs;   var n sd /*mean*/;run;
Output:
N       SD1    0.000002    1.000003    0.942814    0.866035    0.979806    1.000007    1.399718    2.00000

Scala

Generic for any numeric type

Library:Scala
import scala.math.sqrtobject StddevCalc extends App {  def calcAvgAndStddev[T](ts: Iterable[T])(implicit num: Fractional[T]): (T, Double) = {    def avg(ts: Iterable[T])(implicit num: Fractional[T]): T =      num.div(ts.sum, num.fromInt(ts.size)) // Leaving with type of function T    val mean: T = avg(ts) // Leave val type of T    // Root of mean diffs    val stdDev = sqrt(ts.map { x =>      val diff = num.toDouble(num.minus(x, mean))      diff * diff    }.sum / ts.size)    (mean, stdDev)  }  println(calcAvgAndStddev(List(2.0E0, 4.0, 4, 4, 5, 5, 7, 9)))  println(calcAvgAndStddev(Set(1.0, 2, 3, 4)))  println(calcAvgAndStddev(0.1 to 1.1 by 0.05))  println(calcAvgAndStddev(List(BigDecimal(120), BigDecimal(1200))))  println(s"Successfully completed without errors. [total ${scala.compat.Platform.currentTime - executionStart}ms]")}

Scheme

(define (standart-deviation-generator)  (let ((nums '()))    (lambda (x)       (set! nums (cons x nums))      (let* ((mean (/ (apply + nums) (length nums)))      (mean-sqr (lambda (y) (expt (- y mean) 2)))      (variance (/ (apply + (map mean-sqr nums)) (length nums))))    (sqrt variance)))))(let loop ((f (standart-deviation-generator))           (input '(2 4 4 4 5 5 7 9)))  (unless (null? input)      (display (f (car input)))      (newline)      (loop f (cdr input))))

Scilab

Scilab has the built-in functionstdev to compute the standard deviation of a sample so it is straightforward to have the standard deviation of a sample with a correction of the bias.

T=[2,4,4,4,5,5,7,9];stdev(T)*sqrt((length(T)-1)/length(T))
Output:
-->T=[2,4,4,4,5,5,7,9];-->stdev(T)*sqrt((length(T)-1)/length(T))   ans  =     2.

Sidef

Using an object to keep state:

class StdDevAccumulator(n=0, sum=0, sumofsquares=0) {  method <<(num) {    n += 1    sum += num    sumofsquares += num**2    self  }   method stddev {    sqrt(sumofsquares/n - pow(sum/n, 2))  }   method to_s {    self.stddev.to_s  }} var i = 0var sd = StdDevAccumulator()[2,4,4,4,5,5,7,9].each {|n|    say "adding #{n}: stddev of #{i+=1} samples is #{sd << n}"}
Output:
adding 2: stddev of 1 samples is 0adding 4: stddev of 2 samples is 1adding 4: stddev of 3 samples is 0.942809041582063365867792482806465385713114583585adding 4: stddev of 4 samples is 0.866025403784438646763723170752936183471402626905adding 5: stddev of 5 samples is 0.979795897113271239278913629882356556786378992263adding 5: stddev of 6 samples is 1adding 7: stddev of 7 samples is 1.39970842444753034182701947126050936683768427466adding 9: stddev of 8 samples is 2

Usingstatic variables:

func stddev(x) {    static(num=0, sum=0, sum2=0)    num++    sqrt(        (sum2 += x**2) / num -        (((sum += x) / num)**2)    )} %n(2 4 4 4 5 5 7 9).each { say stddev(_) }
Output:
010.9428090415820633658677924828064653857131145835850.8660254037844386467637231707529361834714026269050.97979589711327123927891362988235655678637899226311.399708424447530341827019471260509366837684274662

Smalltalk

Works with:GNU Smalltalk
Object subclass: SDAccum [    |sum sum2 num|    SDAccum class >> new [  |o|         o := super basicNew.        ^ o init.    ]    init [ sum := 0. sum2 := 0. num := 0 ]    value: aValue [       sum := sum + aValue.      sum2 := sum2 + ( aValue * aValue ).      num := num + 1.      ^ self stddev    ]    count [ ^ num ]    mean [ num>0 ifTrue: [^ sum / num] ifFalse: [ ^ 0.0 ] ]    variance [ |m| m := self mean.               num>0 ifTrue: [^ (sum2/num) - (m*m) ] ifFalse: [ ^ 0.0 ]             ]    stddev [ ^ (self variance) sqrt ] ].
|sdacc sd|sdacc := SDAccum new.#( 2 4 4 4 5 5 7 9 ) do: [ :v | sd := sdacc value: v ].('std dev = %1' % { sd }) displayNl.

SQL

Works with:Postgresql
-- the minimal tablecreate table if not exists teststd (n double precision not null);-- code modularity with view, we could have used a common table expression insteadcreate view  vteststd as  select count(n) as cnt,  sum(n) as tsum,  sum(power(n,2)) as tsqrfrom teststd;-- you can of course put this code into every querycreate or replace function std_dev() returns double precision as $$ select sqrt(tsqr/cnt - (tsum/cnt)^2) from vteststd;$$ language sql;-- test data is: 2,4,4,4,5,5,7,9insert into teststd values (2);select std_dev() as std_deviation;insert into teststd values (4);select std_dev() as std_deviation;insert into teststd values (4);select std_dev() as std_deviation;insert into teststd values (4);select std_dev() as std_deviation;insert into teststd values (5);select std_dev() as std_deviation;insert into teststd values (5);select std_dev() as std_deviation;insert into teststd values (7);select std_dev() as std_deviation;insert into teststd values (9);select std_dev() as std_deviation;-- cleanup test datadelete from teststd;

With a command likepsql <rosetta-std-dev.sql you will get an output like this: (duplicate lines generously deleted, locale is DE)

CREATE TABLEFEHLER:  Relation »vteststd« existiert bereitsCREATE FUNCTIONINSERT 0 1 std_deviation ---------------             0(1 Zeile)INSERT 0 1 std_deviation ---------------             1 0.942809041582063 0.866025403784439 0.979795897113272             1 1.39970842444753             2DELETE 8

Swift

import Darwinclass stdDev{        var n:Double = 0.0    var sum:Double = 0.0    var sum2:Double = 0.0        init(){                let testData:[Double] = [2,4,4,4,5,5,7,9];        for x in testData{                        var a:Double = calcSd(x)            println("value \(Int(x)) SD = \(a)");        }            }        func calcSd(x:Double)->Double{                n += 1        sum += x        sum2 += x*x        return sqrt( sum2 / n - sum*sum / n / n)    }    }var aa = stdDev()
Output:
value 2 SD = 0.0value 4 SD = 1.0value 4 SD = 0.942809041582063value 4 SD = 0.866025403784439value 5 SD = 0.979795897113271value 5 SD = 1.0value 7 SD = 1.39970842444753value 9 SD = 2.0

Functional:

func standardDeviation(arr : [Double]) -> Double{    let length = Double(arr.count)    let avg = arr.reduce(0, { $0 + $1 }) / length    let sumOfSquaredAvgDiff = arr.map { pow($0 - avg, 2.0)}.reduce(0, {$0 + $1})    return sqrt(sumOfSquaredAvgDiff / length)} let responseTimes = [ 18.0, 21.0, 41.0, 42.0, 48.0, 50.0, 55.0, 90.0 ] standardDeviation(responseTimes) // 20.8742514835862standardDeviation([2,4,4,4,5,5,7,9]) // 2.0

Tcl

With a Class

Works with:Tcl version 8.6

or

Library:TclOO
oo::class create SDAccum {    variable sum sum2 num    constructor {} {        set sum 0.0        set sum2 0.0        set num 0    }    method value {x} {        set sum2 [expr {$sum2 + $x**2}]        set sum [expr {$sum + $x}]        incr num        return [my stddev]    }    method count {} {        return $num    }    method mean {} {        expr {$sum / $num}    }    method variance {} {        expr {$sum2/$num - [my mean]**2}    }    method stddev {} {        expr {sqrt([my variance])}    }}# Demonstrationset sdacc [SDAccum new]foreach val {2 4 4 4 5 5 7 9} {    set sd [$sdacc value $val]}puts "the standard deviation is: $sd"
Output:
the standard deviation is: 2.0

With a Coroutine

Works with:Tcl version 8.6
# Make a coroutine out of a lambda applicationcoroutine sd apply {{} {    set sum 0.0    set sum2 0.0    set sd {}    # Keep processing argument values until told not to...    while {[set val [yield $sd]] ne "stop"} {        incr n        set sum [expr {$sum + $val}]        set sum2 [expr {$sum2 + $val**2}]        set sd [expr {sqrt($sum2/$n - ($sum/$n)**2)}]    }}}# Demonstrationforeach val {2 4 4 4 5 5 7 9} {    set sd [sd $val]}sd stopputs "the standard deviation is: $sd"

Visual Basic

NOTE. The helper functionavg is not namedaverage to avoid a name conflict withWorksheetFunction.Average in MS Excel.

Function avg(what() As Variant) As Variant    'treats non-numeric strings as zero    Dim L0 As Variant, total As Variant    For L0 = LBound(what) To UBound(what)        If IsNumeric(what(L0)) Then total = total + what(L0)    Next    avg = total / (1 + UBound(what) - LBound(what))End FunctionFunction standardDeviation(fp As Variant) As Variant    Static list() As Variant    Dim av As Variant, tmp As Variant, L0 As Variant    'add to sequence if numeric    If IsNumeric(fp) Then        On Error GoTo makeArr   'catch undimensioned list        ReDim Preserve list(UBound(list) + 1)        On Error GoTo 0        list(UBound(list)) = fp    End If    'get average    av = avg(list())    'the actual work    For L0 = 0 To UBound(list)        tmp = tmp + ((list(L0) - av) ^ 2)    Next    tmp = Sqr(tmp / (UBound(list) + 1))    standardDeviation = tmp    Exit FunctionmakeArr:    If 9 = Err.Number Then        ReDim list(0)    Else        'something's wrong        Err.Raise Err.Number    End If    Resume NextEnd FunctionSub tester()    Dim x As Variant    x = Array(2, 4, 4, 4, 5, 5, 7, 9)    For L0 = 0 To UBound(x)        Debug.Print standardDeviation(x(L0))    NextEnd Sub
Output:
 0 1 0.942809041582063 0.866025403784439 0.979795897113271 1 1.39970842444753 2

VBScript

data = Array(2,4,4,4,5,5,7,9)For i = 0 To UBound(data)WScript.StdOut.Write "value = " & data(i) &_" running sd = " & sd(data,i)WScript.StdOut.WriteLineNextFunction sd(arr,n)mean = 0variance = 0For j = 0 To nmean = mean + arr(j)Nextmean = mean/(n+1)For k = 0 To nvariance = variance + ((arr(k)-mean)^2)Nextvariance = variance/(n+1)sd = FormatNumber(Sqr(variance),6)End Function
Output:
value = 2 running sd = 0.000000value = 4 running sd = 1.000000value = 4 running sd = 0.942809value = 4 running sd = 0.866025value = 5 running sd = 0.979796value = 5 running sd = 1.000000value = 7 running sd = 1.399708value = 9 running sd = 2.000000

Wren

Library:Wren-fmt
Library:Wren-math
import "./fmt" for Fmtimport "./math" for Numsvar cumStdDev = Fiber.new { |a|    for (i in 0...a.count) {        var b = a[0..i]        System.print("Values  : %(b)")        Fiber.yield(Nums.popStdDev(b))    }}var a = [2, 4, 4, 4, 5,  5, 7, 9]while (true) {    var sd = cumStdDev.call(a)    if (cumStdDev.isDone) return    Fmt.print("Std Dev : $10.8f\n", sd)}
Output:
Values  : [2]Std Dev : 0.00000000Values  : [2, 4]Std Dev : 1.00000000Values  : [2, 4, 4]Std Dev : 0.94280904Values  : [2, 4, 4, 4]Std Dev : 0.86602540Values  : [2, 4, 4, 4, 5]Std Dev : 0.97979590Values  : [2, 4, 4, 4, 5, 5]Std Dev : 1.00000000Values  : [2, 4, 4, 4, 5, 5, 7]Std Dev : 1.39970842Values  : [2, 4, 4, 4, 5, 5, 7, 9]Std Dev : 2.00000000

XPL0

include c:\cxpl\codes;          \intrinsic 'code' declarationsint  A, I;real N, S, S2;[A:= [2,4,4,4,5,5,7,9];N:= 0.0;  S:= 0.0;  S2:= 0.0;for I:= 0 to 8-1 do        [N:= N + 1.0;        S:= S + float(A(I));        S2:= S2 + float(sq(A(I)));        RlOut(0, sqrt((S2/N) - sq(S/N)));        ];CrLf(0);]
Output:
    0.00000    1.00000    0.94281    0.86603    0.97980    1.00000    1.39971    2.00000

Zig

Works with: 0.14.x, 0.15.0-dev.849+36499c251

const std = @import("std");pub fn main() !void {    const stdout = std.io.getStdOut().writer();    const arr = [_]f32{ 2, 4, 4, 4, 5, 5, 7, 9 };    var sum: f32 = 0;    var sum2: f32 = 0;    var count: f32 = 0;    for (arr) |n| {        sum += n;        sum2 += std.math.pow(f32, n, 2);        count += 1;        const cumulative: f32 = count * sum2 - std.math.pow(f32, sum, 2);        const running_sd: f32 = std.math.sqrt(cumulative) / count;        try stdout.print("{d} {d}\n", .{n, running_sd});    }}
Output:
2 04 14 0.942809054 0.86602545 0.979795935 17 1.39970859 2

zkl

fcn sdf{ fcn(x,xs){       m:=xs.append(x.toFloat()).sum(0.0)/xs.len();       (xs.reduce('wrap(p,x){(x-m)*(x-m) +p},0.0)/xs.len()).sqrt()     }.fp1(L())}
Output:
zkl: T(2,4,4,4,5,5,7,9).pump(Void,sdf())2zkl: sd:=sdf(); sd(2);sd(4);sd(4);sd(4);sd(5);sd(5);sd(7);sd(9)2
Retrieved from "https://rosettacode.org/wiki/Cumulative_standard_deviation?oldid=395869"
Categories:
Hidden category:
Cookies help us deliver our services. By using our services, you agree to our use of cookies.

[8]ページ先頭

©2009-2026 Movatter.jp