[ 1.0 ] [ { 1 1 1 } geometric-mean ] unit-test
[ 1/3 ] [ { 1 1 1 } harmonic-mean ] unit-test
[ 5+1/4 ] [ { 1 3 5 7 } contraharmonic-mean ] unit-test
-[ 18 ] [ { 4 8 15 16 23 42 } 0 trim-mean ] unit-test
-[ 15+1/2 ] [ { 4 8 15 16 23 42 } 0.2 trim-mean ] unit-test
+[ 18 ] [ { 4 8 15 16 23 42 } 0 trimmed-mean ] unit-test
+[ 15+1/2 ] [ { 4 8 15 16 23 42 } 0.2 trimmed-mean ] unit-test
+[ 3 ] [ { 1 3 3 3 3 5 } 0.2 winsorized-mean ] unit-test
[ 0 ] [ { 1 } range ] unit-test
[ 89 ] [ { 1 2 30 90 } range ] unit-test
: contraharmonic-mean ( seq -- x )
[ sum-of-squares ] [ sum ] bi / ; inline
-: trim-mean ( seq p -- x )
- swap [ length [ * >integer ] keep over - ] keep <slice> mean ;
+<PRIVATE
+
+: trim-points ( p seq -- from to seq )
+ [ length [ * >integer ] keep over - ] keep ;
+
+PRIVATE>
+
+: trimmed-mean ( seq p -- x )
+ swap natural-sort trim-points <slice> mean ;
+
+: winsorized-mean ( seq p -- x )
+ swap natural-sort trim-points
+ [ <slice> ]
+ [ nip dupd nth <array> ]
+ [ [ 1 - ] dip nth <array> ] 3tri
+ surround mean ;
<PRIVATE