Averages/Arithmetic mean: Difference between revisions
(added php) |
|||
Line 175: | Line 175: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
This function works if the element type is an instance of Fractional: |
|||
mean :: (Fractional a) => [a] -> a |
|||
mean [] = 0 |
mean [] = 0 |
||
mean xs = sum xs / Data.List.genericLength xs |
mean xs = sum xs / Data.List.genericLength xs |
||
But some types, e.g. integers, are not Fractional; the following function works for all Real types: |
|||
meanReals :: (Real a, Fractional b) => [a] -> b |
|||
meanReals = mean . map realToFrac |
|||
=={{header|IDL}}== |
=={{header|IDL}}== |
Revision as of 02:18, 13 January 2009
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.
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
APL
X←3 1 4 1 5 9 (+/X)÷⍴X 3.833333333
BASIC
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
C
This implementation uses a plain old static array of doubles for the numeric vector.
<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;}</c>
C++
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(); }
Common Lisp
(defun mean (sequence) (let ((length (length sequence))) (if (zerop length) 0 (/ (reduce #'+ sequence) length))))
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()) ; }
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
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)
Haskell
This function works if the element type is an instance of Fractional:
mean :: (Fractional a) => [a] -> a mean [] = 0 mean xs = sum xs / Data.List.genericLength xs
But some types, e.g. integers, are not Fractional; the following function works for all Real types:
meanReals :: (Real a, Fractional b) => [a] -> b meanReals = mean . map realToFrac
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>.
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
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)); ...
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
function mean(a) { return a.length ? Functional.reduce('+', 0, a) / a.length : 0; }
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
Lucid
avg(x) where sum = first(x) fby sum + next(x); n = 1 fby n + 1; avg = sum / n; end
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))
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
OCaml
These functions return a float:
<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)</ocaml>
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.
<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)
- </ocaml>
Perl
<perl>sub avg {
@_ or return 0; my $sum = 0; $sum += $_ foreach @_; return $sum/@_;
}
print avg(qw(3 1 4 1 5 9)), "\n";</perl>
With module Data::Average. (For zero-length arrays, returns the empty list.) <perl>use Data::Average;
my $d = Data::Average->new; $d->add($_) foreach qw(3 1 4 1 5 9); print $d->avg, "\n";</perl>
PHP
<php>$nums = array(3, 1, 4, 1, 5, 9); if ($nums)
echo array_sum($nums) / count($nums), "\n";
else
echo "0\n";</php>
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
<python>def average(x):
return sum(x)/float(len(x)) if x else 0
print average([3,1,4,1,5,9])</python>
Output:
<python>3.83333333333333</python>
<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])</python>
Output:
<python>3.83333333333333</python>
Ruby
nums = [3, 1, 4, 1, 5, 9] nums.empty? ? 0 : nums.inject(:+) / Float(nums.size)
Scheme
<scheme>(define (mean l)
(if (null? l) 0 (/ (apply + l) (length l))))</scheme>
> (mean (list 3 1 4 1 5 9)) 3 5/6
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
V
[mean [sum 0 [+] fold]. dup sum swap size [[1 <] [1]] when / ].