Mean
From Rosetta Code
Programming Task
This is a programming task. It lays out a problem which Rosetta Code users are encouraged to solve, using languages they know.
Contents |
[edit] Ada
This example shows how to pass a zero length vector as well as a larger vector.
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;
Output:
3.83333 0.00000
[edit] APL
Works with: APL2
X←3 1 4 1 5 9
(+/X)÷⍴X
3.833333333
[edit] BASIC
Works with: QuickBasic version 4.5
Assume the numbers are in a DIM named nums.
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
[edit] C
This implementation uses a plain old static array of doubles for the numeric vector.
#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;}
[edit] C++
Library: STL
double mean(std::vector<double> const& vNumbers)
{
double sum = 0;
for( std::vector<double>::iterator i = vNumbers.begin(); vNumbers.end() != i; ++i )
sum += *i;
if( 0 == vNumbers.size() )
return 0;
else
return sum / vNumbers.size();
}
Shorter (and more idiomatic) version:
#include <vector>
#include <algorithm>
double mean(std::vector<double> const& numbers)
{
if (numbers.empty())
return 0;
return std::accumulate(numbers.begin(), numbers.end(), 0.0) / numbers.size();
}
[edit] Common Lisp
(defun mean (sequence)
(let ((length (length sequence)))
(if (zerop length)
0
(/ (reduce #'+ sequence) length))))
[edit] D
Using template to make the mean function work for higher-rank array.
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()) ;
}
[edit] 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
[edit] Fortran
In ISO Fortran 90 or later, use the SUM intrinsic, the SIZE intrinsic and the MAX intrinsic (to avoid divide by zero):
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)
[edit] Haskell
mean [] = 0 mean xs = sum xs / Data.List.genericLength xs
[edit] IDL
If truly only the mean is wanted, one could use
x = [3,1,4,1,5,9] print,mean(x)
But mean() is just a thin wrapper returning the zeroth element of moment() :
print,moment(x) ; ==> 3.83333 8.96667 0.580037 -1.25081
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>.
[edit] J
mean=: +/ % #
That is, sum divided by the number of items. The verb also works on higher-ranked arrays. For example:
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
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.
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
[edit] Java
Assume the numbers are in a double array called "nums".
...
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));
...
[edit] 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
Library: Functional
function mean(a) {
return a.length ? Functional.reduce('+', 0, a) / a.length : 0;
}
[edit] 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
[edit] Lucid
avg(x)
where
sum = first(x) fby sum + next(x);
n = 1 fby n + 1;
avg = sum / n;
end
[edit] 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))
[edit] Nial
in the standard way, mean is
mean is / [sum, tally]
mean 6 2 4 = 4
but it fails with 0 length vectors. so using a tally with a minimum value 1
dtally is recur [ empty rest, 1 first, 1 first, plus, rest ] mean is / [sum, dtally]
mean [] =0
[edit] OCaml
These functions return a float:
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)
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.
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) ;;
[edit] Perl
sub avg { @_ or return 0; my $sum = 0; $sum += $_ foreach @_; return $sum/@_; } print avg(qw(3 1 4 1 5 9)), "\n";
Library: Data::Average
With module Data::Average. (For zero-length arrays, returns the empty list.)
use Data::Average; my $d = Data::Average->new; $d->add($_) foreach qw(3 1 4 1 5 9); print $d->avg, "\n";
[edit] 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;
[edit] Python
Works with: Python version 2.5
def average(x): return sum(x)/float(len(x)) if x else 0 print average([3,1,4,1,5,9])
Output:
3.83333333333333
Works with: Python version 2.4
def avg(data): if len(data)==0: return 0 else: return sum(data)/float(len(data)) print avg([3,1,4,1,5,9])
Output:
3.83333333333333
[edit] Ruby
nums = [3, 1, 4, 1, 5, 9] nums.empty? ? 0 : nums.inject(:+) / Float(nums.size)
[edit] Scheme
(define (mean l)
(if (null? l)
0
(/ (apply + l) (length l))))
> (mean (list 3 1 4 1 5 9)) 3 5/6
[edit] UnixPipes
term() {
b=$1;res=$2
echo "scale=5;$res+$b" | bc
}
sum() {
(read B; res=$1;
test -n "$B" && (term $B $res) || (term 0 $res))
}
fold() {
func=$1
(while read a ; do
fold $func | $func $a
done)
}
mean() {
tee >(wc -l > count) | fold sum | xargs echo "scale=5;(1/" $(cat count) ") * " | bc
}
(echo 3; echo 1; echo 4) | mean
[edit] V
[mean [sum 0 [+] fold]. dup sum swap size [[1 <] [1]] when / ].
Categories: Programming Tasks | Arithmetic operations | Ada | APL | BASIC | C | C++ | STL | Common Lisp | D | Forth | Fortran | Haskell | IDL | J | Java | JavaScript | Functional | Logo | Lucid | MAXScript | Nial | OCaml | Perl | Data::Average | Pop11 | Python | Ruby | Scheme | UnixPipes | V

