Averages/Arithmetic mean: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎[[Mean#ALGOL 68]]: clarify what ELLA ALGOL 68 is missing.)
No edit summary
Line 79: Line 79:
This implementation uses a plain old static array of <tt>double</tt>s for the numeric vector.
This implementation uses a plain old static array of <tt>double</tt>s for the numeric vector.


<c>#include <stdio.h>
<lang c>#include <stdio.h>


double mean(double *p, unsigned qty)
double mean(double *p, unsigned qty)
Line 91: Line 91:
{double test[6] = {1.0, 2.0, 5.0, -5.0, 9.5, 3.14159};
{double test[6] = {1.0, 2.0, 5.0, -5.0, 9.5, 3.14159};
printf("%lg\n", mean(test, 6));
printf("%lg\n", mean(test, 6));
return 0;}</c>
return 0;}</lang>


=={{header|C++}}==
=={{header|C++}}==
Line 322: Line 322:
These functions return a float:
These functions return a float:


<ocaml>let mean_floats xs =
<lang ocaml>let mean_floats xs =
if xs = [] then
if xs = [] then
0.
0.
Line 328: Line 328:
List.fold_left (+.) 0. xs /. float_of_int (List.length xs)
List.fold_left (+.) 0. xs /. float_of_int (List.length xs)


let mean_ints xs = mean_floats (List.map float_of_int xs)</ocaml>
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 previous code is easier to read and understand, though if you which
Line 340: Line 340:
would rather be handled by an exception.
would rather be handled by an exception.


<ocaml>let mean_floats xs =
<lang ocaml>let mean_floats xs =
if xs = [] then
if xs = [] then
invalid_arg "empty list"
invalid_arg "empty list"
Line 363: Line 363:
in
in
(float total /. length)
(float total /. length)
;;</ocaml>
;;</lang>


=={{header|Perl}}==
=={{header|Perl}}==
<perl>sub avg {
<lang perl>sub avg {
@_ or return 0;
@_ or return 0;
my $sum = 0;
my $sum = 0;
Line 373: Line 373:
}
}
print avg(qw(3 1 4 1 5 9)), "\n";</perl>
print avg(qw(3 1 4 1 5 9)), "\n";</lang>
{{libheader|Data::Average}}
{{libheader|Data::Average}}
With module Data::Average.
With module Data::Average.
(For zero-length arrays, returns the empty list.)
(For zero-length arrays, returns the empty list.)
<perl>use Data::Average;
<lang perl>use Data::Average;


my $d = Data::Average->new;
my $d = Data::Average->new;
$d->add($_) foreach qw(3 1 4 1 5 9);
$d->add($_) foreach qw(3 1 4 1 5 9);
print $d->avg, "\n";</perl>
print $d->avg, "\n";</lang>


=={{header|PHP}}==
=={{header|PHP}}==
<php>$nums = array(3, 1, 4, 1, 5, 9);
<lang php>$nums = array(3, 1, 4, 1, 5, 9);
if ($nums)
if ($nums)
echo array_sum($nums) / count($nums), "\n";
echo array_sum($nums) / count($nums), "\n";
else
else
echo "0\n";</php>
echo "0\n";</lang>


=={{header|Pop11}}==
=={{header|Pop11}}==
Line 408: Line 408:
=={{header|Python}}==
=={{header|Python}}==
{{works with|Python|2.5}}
{{works with|Python|2.5}}
<python>def average(x):
<lang python>def average(x):
return sum(x)/float(len(x)) if x else 0
return sum(x)/float(len(x)) if x else 0
print average([3,1,4,1,5,9])</python>
print average([3,1,4,1,5,9])</lang>


Output:
Output:
<python>3.83333333333333</python>
<lang python>3.83333333333333</lang>




{{works with|Python|2.4}}
{{works with|Python|2.4}}
<python>def avg(data):
<lang python>def avg(data):
if len(data)==0:
if len(data)==0:
return 0
return 0
else:
else:
return sum(data)/float(len(data))
return sum(data)/float(len(data))
print avg([3,1,4,1,5,9])</python>
print avg([3,1,4,1,5,9])</lang>


Output:
Output:
<python>3.83333333333333</python>
<lang python>3.83333333333333</lang>


=={{header|Ruby}}==
=={{header|Ruby}}==
<ruby>nums = [3, 1, 4, 1, 5, 9]
<lang ruby>nums = [3, 1, 4, 1, 5, 9]
nums.empty? ? 0 : nums.inject(:+) / Float(nums.size)</ruby>
nums.empty? ? 0 : nums.inject(:+) / Float(nums.size)</lang>


=={{header|Scheme}}==
=={{header|Scheme}}==
<scheme>(define (mean l)
<lang scheme>(define (mean l)
(if (null? l)
(if (null? l)
0
0
(/ (apply + l) (length l))))</scheme>
(/ (apply + l) (length l))))</lang>


> (mean (list 3 1 4 1 5 9))
> (mean (list 3 1 4 1 5 9))

Revision as of 15:41, 3 February 2009

Task
Averages/Arithmetic mean
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

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 mk15-0.8b.fc9.i386
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386 - note that some necessary LONG REAL operators are missing from ELLA's library.
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))
)

APL

Works with: APL2
      X←3 1 4 1 5 9
      (+/X)÷⍴X
3.833333333

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

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++

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();
}

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
Library: Functional
function mean(a) {
  return a.length ? Functional.reduce('+', 0, a) / a.length : 0;
}

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

[1]

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:

<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>

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

Works with: Python version 2.5

<lang python>def average(x):

   return sum(x)/float(len(x)) if x else 0

print average([3,1,4,1,5,9])</lang>

Output:

<lang python>3.83333333333333</lang>


Works with: Python version 2.4
<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

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 /
].