Averages/Arithmetic mean: Difference between revisions
m Add cross link |
corrected categorization of task |
||
Line 1:
{{task|
See also: [[Median]], [[Mode]]
|
Revision as of 13:25, 13 June 2009
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
Write a program to find the mean (arithmetic average) of a numeric vector. The program should work on a zero-length vector (with an answer of 0).
Ada
This example shows how to pass a zero length vector as well as a larger vector. <lang ada>with Ada.Float_Text_Io; use Ada.Float_Text_Io; with Ada.Text_IO; use Ada.Text_IO;
procedure Mean_Main is
type Vector is array(Positive range <>) of Float; function Mean(Item : Vector) return Float is Sum : Float := 0.0; Result : Float := 0.0; begin for I in Item'range loop Sum := Sum + Item(I); end loop; if Item'Length > 0 then Result := Sum / Float(Item'Length); end if; return Result; end Mean; A : Vector := (3.0, 1.0, 4.0, 1.0, 5.0, 9.0);
begin
Put(Item => Mean(A), Fore => 1, Exp => 0); New_Line; -- test for zero length vector Put(Item => Mean(A(1..0)), Fore => 1, Exp => 0); New_Line;
end Mean_Main;</lang> Output:
3.83333 0.00000
ALGOL 68
<lang algol68> PROC mean = (REF[]REAL p)REAL:
- Calculates the mean of qty REALs beginning at p. #
IF LWB p > UPB p THEN 0.0 ELSE REAL total := 0.0; FOR i FROM LWB p TO UPB p DO total +:= p[i] OD; total / (UPB p - LWB p + 1) FI;
main:(
[6]REAL test := (1.0, 2.0, 5.0, -5.0, 9.5, 3.14159); print((mean(test),new line))
) </lang>
AmigaE
Because of the way Amiga E handles floating point numbers, the passed list/vector must contain all explicitly floating point values (e.g., you need to write "1.0", not "1") <lang amigae>PROC mean(l:PTR TO LONG)
DEF m, i, ll ll := ListLen(l) IF ll = 0 THEN RETURN 0.0 m := 0.0 FOR i := 0 TO ll-1 DO m := !m + l[i] m := !m / (ll!)
ENDPROC m
PROC main()
DEF s[20] : STRING WriteF('mean \s\n', RealF(s,mean([1.0, 2.0, 3.0, 4.0, 5.0]), 2))
ENDPROC</lang>
AutoHotkey
<lang autohotkey>i = 10 Loop,% i {
Random, v, -3.141592, 3.141592 list .= v "`n" sum += v
} MsgBox,% i ? list "`nmean: " sum/i:0</lang>
AWK
<lang awk># work around a gawk bug in the length extended use:
- so this is a more non-gawk compliant way to get
- how many elements are in an array
function elength(v) {
l=0 for(el in v) l++ return l
}
function mean(v) {
if (elength(v) < 1) { return 0 } sum = 0 for(i=0; i < elength(v); i++) { sum += v[i] } return sum/elength(v)
}
BEGIN {
# fill a vector with random numbers for(i=0; i < 10; i++) { vett[i] = rand()*10 } print mean(vett)
}</lang>
APL
<lang apl> X←3 1 4 1 5 9
(+/X)÷⍴X
3.833333333</lang>
BASIC
Assume the numbers are in a DIM named nums. <lang qbasic>mean = 0 sum = 0; FOR i = LBOUND(nums) TO UBOUND(nums)
sum = sum + nums(i);
NEXT i size = UBOUND(nums) - LBOUND(nums) + 1 PRINT "The mean is: "; IF size <> 0 THEN
PRINT (sum / size)
ELSE
PRINT 0
END IF</lang>
C
This implementation uses a plain old static array of doubles for the numeric vector.
<lang c>#include <stdio.h>
double mean(double *p, unsigned qty) /* Calculates the mean of qty doubles beginning at p. */
{if (qty == 0) return 0; double total = 0; for (int i = 0 ; i < qty ; ++i) total += p[i]; return total / qty;}
int main(void)
{double test[6] = {1.0, 2.0, 5.0, -5.0, 9.5, 3.14159}; printf("%lg\n", mean(test, 6)); return 0;}</lang>
C++
<lang cpp>#include <vector>
double mean(const std::vector<double>& numbers) {
if (numbers.size() == 0) return 0;
double sum = 0; for (std::vector<double>::iterator i = numbers.begin(); i != numbers.end(); i++) sum += *i; return sum / numbers.size();
}</lang>
Shorter (and more idiomatic) version:
<lang cpp>#include <vector>
- include <algorithm>
double mean(const std::vector<double>& numbers) {
if (numbers.empty()) return 0; return std::accumulate(numbers.begin(), numbers.end(), 0.0) / numbers.size();
}</lang>
C#
<lang csharp>using System.Linq;
static double avg(ICollection<int> i) {
if (i == null || i.Count == 0) return 0; return i.Sum() / (double)i.Count;
}
static void Main(string[] args) {
int[] numbers = new int[] {1, 2, 3, 4, 5, 6, 7, 8}; Console.WriteLine(avg(numbers));
}</lang>
C# already has a builtin Average function.
<lang csharp>static void Main(string[] args) {
int[] numbers = new int[] {1, 2, 3, 4, 5, 6, 7, 8}; Console.WriteLine(numbers.Average());
}</lang>
Clojure
<lang clojure> (defn mean [sq]
(let [length (count sq)] (if (zero? length) 0 (/ (reduce + sq) length)))
) </lang>
Common Lisp
<lang lisp>(defun mean (sequence)
(let ((length (length sequence))) (if (zerop length) 0 (/ (reduce #'+ sequence) length))))</lang>
D
Using template to make the mean function work for higher-rank array. <lang d>module mean ; import std.stdio ;
real mean(T)(T[] a) {
static if(is(T U : U[])) { // recursively unfold the multi-array T u ; foreach(e ; a) u ~= e ; return u.mean() ;
} else { // do the math if(a.length == 0) return 0.0 ; real sum = 0.0 ; foreach(e ; a) sum += e ; return sum / a.length ; }
} void main() {
int[] array = [3,1,4,1,5,9]; real[][][] multi = [[[1,2,2],[2,3,4],[4,5,7]], [[4,1,3],[0,3,1],[4,4,6]], [[1,3,3],[2,7,8],[9,1,5]]] ; writefln("array : ", array.mean()) ; writefln("multi : ", multi.mean()) ;
}</lang>
E
Slightly generalized to support any object that allows iteration.
<lang e>def meanOrZero(numbers) {
var count := 0 var sum := 0 for x in numbers { sum += x count += 1 } return sum / 1.max(count)
}</lang>
Forth
<lang forth> : fmean ( addr n -- f )
0e dup 0= if 2drop exit then tuck floats bounds do i f@ f+ 1 floats +loop 0 d>f f/ ; create test 3e f, 1e f, 4e f, 1e f, 5e f, 9e f, test 6 fmean f. \ 3.83333333333333</lang>
Fortran
In ISO Fortran 90 or later, use the SUM intrinsic, the SIZE intrinsic and the MAX intrinsic (to avoid divide by zero): <lang fortran> real, target, dimension(100) :: a = (/ (i, i=1, 100) /)
real, dimension(5,20) :: b = reshape( a, (/ 5,20 /) ) real, pointer, dimension(:) :: p => a(2:1) ! pointer to zero-length array real :: mean, zmean, bmean real, dimension(20) :: colmeans real, dimension(5) :: rowmeans mean = sum(a)/size(a) ! SUM of A's elements divided by SIZE of A mean = sum(a)/max(size(a),1) ! Same result, but safer code ! MAX of SIZE and 1 prevents divide by zero if SIZE == 0 (zero-length array) zmean = sum(p)/max(size(p),1) ! Here the safety check pays off. Since P is a zero-length array, ! expression becomes "0 / MAX( 0, 1 ) -> 0 / 1 -> 0", rather than "0 / 0 -> NaN" bmean = sum(b)/max(size(b),1) ! multidimensional SUM over multidimensional SIZE rowmeans = sum(b,1)/max(size(b,2),1) ! SUM elements in each row (dimension 1) ! dividing by the length of the row, which is the number of columns (SIZE of dimension 2) colmeans = sum(b,2)/max(size(b,1),1) ! SUM elements in each column (dimension 2) ! dividing by the length of the column, which is the number of rows (SIZE of dimension 1)</lang>
F#
The following computes the running mean using a tail-recursive approach. If we just sum all the values then divide by the number of values then we will suffer from overflow problems for large lists. See wikipedia about the moving average computation. <lang fsharp>let avg (a:float) (v:float) n =
a + (1. / ((float n) + 1.)) * (v - a)
let mean_series list =
let rec f a n list = match list with | [] -> a | h :: t -> f (avg a (float h) n) (n + 1) t f 0. 0 list</lang>
Checking this:
> mean_series [1; 8; 2; 8; 1; 7; 1; 8; 2; 7; 3; 6; 1; 8; 100] ;; val it : float = 10.86666667 > mean_series [] ;; val it : float = 0.0
We can also make do with the built-in List.average function
List.average [4;1;7;5;8;4;5;2;1;5;2;5]
Groovy
<lang groovy>def avg = { list -> list == [] ? 0 : list.sum() / list.size() }</lang>
Test Program: <lang groovy>println avg(0..9) println avg([2,2,2,4,2]) println avg ([])</lang>
Output:
4.5 2.4 0
Haskell
This function works if the element type is an instance of Fractional: <lang haskell>mean :: (Fractional a) => [a] -> a mean [] = 0 mean xs = sum xs / Data.List.genericLength xs</lang>
But some types, e.g. integers, are not Fractional; the following function works for all Real types: <lang haskell>meanReals :: (Real a, Fractional b) => [a] -> b meanReals = mean . map realToFrac</lang>
IDL
If truly only the mean is wanted, one could use
<lang idl> x = [3,1,4,1,5,9]
print,mean(x)</lang>
But mean() is just a thin wrapper returning the zeroth element of moment() :
<lang idl>print,moment(x)
- ==>
3.83333 8.96667 0.580037 -1.25081</lang>
which are mean, variance, skewness and kurtosis.
There are no zero-length vectors in IDL. Every variable has at least one value or otherwise it is <Undefined>.
J
<lang j>mean=: +/ % #</lang>
That is, sum divided by the number of items. The verb also works on higher-ranked arrays. For example:
<lang j> mean 3 1 4 1 5 9 3.83333
mean $0 NB. $0 is a zero-length vector
0
x=: 20 4 ?@$ 0 NB. a 20-by-4 table of random (0,1) numbers mean x
0.58243 0.402948 0.477066 0.511155</lang>
The computation can also be written as a loop. It is shown here for comparison only and is highly non-preferred compared to the version above.
<lang j>mean1=: 3 : 0
z=. 0 for_i. i.#y do. z=. z+i{y end. z % #y
)
mean1 3 1 4 1 5 9
3.83333
mean1 $0
0
mean1 x
0.58243 0.402948 0.477066 0.511155</lang>
Java
Assume the numbers are in a double array called "nums". <lang java5>... double mean = 0; double sum = 0; for(double i : nums){
sum += i;
} System.out.println("The mean is: " + ((nums.length != 0) ? (sum / nums.length) : 0)); ...</lang>
JavaScript
<lang javascript>function mean(array) {
var sum = 0; for(var i in array) sum += array[i]; return array.length ? sum / array.length : 0;
}
alert( mean( [1,2,3,4,5] ) ); // 3</lang>
<lang javascript>function mean(a) {
return a.length ? Functional.reduce('+', 0, a) / a.length : 0;
}</lang>
Logo
<lang logo>to average :l
if empty? :l [output 0] output quotient apply "sum :l count :l
end print average [1 2 3 4] ; 2.5</lang>
Lucid
<lang lucid>avg(x)
where sum = first(x) fby sum + next(x); n = 1 fby n + 1; avg = sum / n; end</lang>
M4
M4 handle only integers, so in order to have a slightly better math for the mean, we must pass to the mean macro integers multiplied by 100. The macro rmean could embed the macro fmean and extractdec directly, but it is a little bit clearer to keep them separated.
<lang m4>define(`extractdec', `ifelse(eval(`$1%100 < 10'),1,`0',`')eval($1%100)')dnl define(`fmean', `eval(`($2/$1)/100').extractdec(eval(`$2/$1'))')dnl define(`mean', `rmean(`$#', $@)')dnl define(`rmean', `ifelse(`$3', `', `fmean($1,$2)',dnl `rmean($1, eval($2+$3), shift(shift(shift($@))))')')dnl</lang> <lang m4>mean(0,100,200,300,400,500,600,700,800,900,1000)</lang>
MAXScript
<lang maxscript>fn mean data = (
total = 0 for i in data do ( total += i ) if data.count == 0 then 0 else total as float/data.count
)
print (mean #(3, 1, 4, 1, 5, 9))</lang>
Nial
in the standard way, mean is <lang nial>mean is / [sum, tally]
mean 6 2 4 = 4</lang> but it fails with 0 length vectors. so using a tally with a minimum value 1
<lang nial>dtally is recur [ empty rest, 1 first, 1 first, plus, rest ] mean is / [sum, dtally]
mean [] =0</lang>
OCaml
These functions return a float:
<lang ocaml>let mean_floats xs =
if xs = [] then 0. else List.fold_left (+.) 0. xs /. float_of_int (List.length xs)
let mean_ints xs = mean_floats (List.map float_of_int xs)</lang>
the previous code is easier to read and understand, though if you which the fastest implementation to use in production code notice several points: it is possible to save a call to List.length computing the length through the List.fold_left, and for mean_ints it is possible to save calling float_of_int on every numbers, converting only the result of the addition. (also when using List.map and the order is not important, you can use List.rev_map instead to save an internal List.rev.) Also the task asks to return 0 on empty lists, but in OCaml this case would rather be handled by an exception.
<lang ocaml>let mean_floats xs =
if xs = [] then invalid_arg "empty list" else let total, length = List.fold_left (fun (tot,len) x -> (x +. tot), len +. 1.) (0., 0.) xs in (total /. length)
let mean_ints xs =
if xs = [] then invalid_arg "empty list" else let total, length = List.fold_left (fun (tot,len) x -> (x + tot), len +. 1.) (0, 0.) xs in (float total /. length)
- </lang>
Octave
GNU Octave has a mean function (from statistics package), but it does not handle an empty vector; an implementation that allows that is:
<lang octave>function m = omean(l)
if ( numel(l) == 0 ) m = 0; else m = mean(l); endif
endfunction
disp(omean([])); disp(omean([1,2,3]));</lang>
Perl
<lang perl>sub avg {
@_ or return 0; my $sum = 0; $sum += $_ foreach @_; return $sum/@_;
}
print avg(qw(3 1 4 1 5 9)), "\n";</lang>
With module Data::Average. (For zero-length arrays, returns the empty list.) <lang perl>use Data::Average;
my $d = Data::Average->new; $d->add($_) foreach qw(3 1 4 1 5 9); print $d->avg, "\n";</lang>
PHP
<lang php>$nums = array(3, 1, 4, 1, 5, 9); if ($nums)
echo array_sum($nums) / count($nums), "\n";
else
echo "0\n";</lang>
Pop11
define mean(v); lvars n = length(v), i, s = 0; if n = 0 then return(0); else for i from 1 to n do s + v(i) -> s; endfor; endif; return(s/n); enddefine;
Python
.
Uses fsum which tracks multiple partial sums to avoid losing precision <lang python>from math import fsum def average(x):
return fsum(x)/float(len(x)) if x else 0
print (average([3,1,4,1,5,9])) print (average([1e20,3,1,4,1,5,9,-1e20]))</lang>
Output:
<lang python>3.83333333333333
2.875</lang>
<lang python>def average(x):
return sum(x)/float(len(x)) if x else 0
print average([3,1,4,1,5,9]) print average([1e20,3,1,4,1,5,9,-1e20])</lang>
Output
(Notice how the second call gave the wrong result)
<lang python>3.83333333333333
0.0 </lang>
<lang python>def avg(data): if len(data)==0: return 0 else: return sum(data)/float(len(data)) print avg([3,1,4,1,5,9])</lang>
Output:
<lang python>3.83333333333333</lang>
Ruby
<lang ruby>nums = [3, 1, 4, 1, 5, 9] nums.empty? ? 0 : nums.inject(:+) / Float(nums.size)</lang>
Scheme
<lang scheme>(define (mean l)
(if (null? l) 0 (/ (apply + l) (length l))))</lang>
> (mean (list 3 1 4 1 5 9)) 3 5/6
Slate
<lang slate> [|:list| (list reduce: #+ `er ifEmpty: [0]) / (list isEmpty ifTrue: [1] ifFalse: [list size])] applyWith: #(3 1 4 1 5 9). [|:list| (list reduce: #+ `er ifEmpty: [0]) / (list isEmpty ifTrue: [1] ifFalse: [list size])] applyWith: {}. </lang>
Smalltalk
<lang smalltalk>| numbers | numbers := #(1 2 3 4 5 6 7 8). (numbers isEmpty ifTrue:[0]
ifFalse: [ (numbers inject: 0 into: [:sum :aNumber | sum + aNumber]) / numbers size ]
) displayNl.</lang>
Standard ML
These functions return a real:
<lang sml>fun mean_reals [] = 0.0
| mean_reals xs = foldl op+ 0.0 xs / real (length xs);
val mean_ints = mean_reals o (map real);</lang>
the previous code is easier to read and understand, though if you which
the fastest implementation to use in production code notice several points:
it is possible to save a call to length
computing the length through
the foldl
, and for mean_ints it is possible to save calling
real
on every numbers, converting only the result of the addition.
Also the task asks to return 0 on empty lists, but in Standard ML this case
would rather be handled by an exception.
<lang sml>fun mean_reals [] = raise Empty
| mean_reals xs = let val (total, length) = foldl (fn (x, (tot,len)) => (x + tot, len + 1.0)) (0.0, 0.0) xs in (total / length) end;
fun mean_ints [] = raise Empty
| mean_ints xs = let val (total, length) = foldl (fn (x, (tot,len)) => (x + tot, len + 1.0)) (0, 0.0) xs in (real total / length) end;
</lang>
Tcl
<lang tcl>package require Tcl 8.5 proc mean args {
if {[set num [llength $args]] == 0} {return 0} expr {[tcl::mathop::+ {*}$args] / double($num)}
} mean 3 1 4 1 5 9 ;# ==> 3.8333333333333335</lang>
UnixPipes
<lang bash>term() {
b=$1;res=$2 echo "scale=5;$res+$b" | bc
}</lang>
<lang bash>sum() {
(read B; res=$1; test -n "$B" && (term $B $res) || (term 0 $res))
}</lang>
<lang bash>fold() {
func=$1 (while read a ; do fold $func | $func $a done)
}</lang>
<lang bash>mean() {
tee >(wc -l > count) | fold sum | xargs echo "scale=5;(1/" $(cat count) ") * " | bc
}</lang>
<lang bash>(echo 3; echo 1; echo 4) | mean</lang>
V
<lang v>[mean
[sum 0 [+] fold]. dup sum swap size [[1 <] [1]] when /
].</lang>