Averages/Pythagorean means: Difference between revisions

From Rosetta Code
Content added Content deleted
(Undo revision 80437 Hi, The note is because there seems to be no check on the relationship between the means for some input.)
(added Ursala and improved the order)
Line 476: Line 476:
if Geometric < Harmonic then put skip list ('Error');
if Geometric < Harmonic then put skip list ('Error');
</lang>
</lang>



=={{header|PureBasic}}==
=={{header|PureBasic}}==
Line 528: Line 529:


<pre>5.5 4.52872868812 3.41417152147</pre>
<pre>5.5 4.52872868812 3.41417152147</pre>
=={{header|R}}==
Initialise x
<lang R>
x<-1:10
</lang>
Arithmetic mean
<lang R>
sum(x)/length(x)

</lang>
or
<lang R>
mean(x)
</lang>

The geometric mean
<lang R>
prod(x)^(1/length(x))
</lang>

The harmonic mean (no error checking that <math>x_i\ne 0,\text{ } \forall \text{ }i=1\ldots n</math>)
<lang R>
length(x)/sum(1/x)
</lang>




=={{header|Ruby}}==
=={{header|Ruby}}==
Line 565: Line 592:
3.41417152147406
3.41417152147406
true</pre>
true</pre>

=={{header|Scheme}}==
=={{header|Scheme}}==
{{Works with|Scheme|R<math>^5</math>RS}}
{{Works with|Scheme|R<math>^5</math>RS}}
Line 593: Line 621:
<lang>11/2 >= 4.528728688116765 >= 25200/7381
<lang>11/2 >= 4.528728688116765 >= 25200/7381
#t</lang>
#t</lang>

=={{header|Tcl}}==
=={{header|Tcl}}==
<lang tcl>proc arithmeticMean list {
<lang tcl>proc arithmeticMean list {
Line 626: Line 655:




=={{header|Ursala}}==


<lang Ursala>#import std
#import flo


data = ari10(1.,10.) # arithmetic progression, length 10 with endpoints 1 and 10
=={{header|R}}==
Initialise x
<lang R>
x<-1:10
</lang>
Arithmetic mean
<lang R>
sum(x)/length(x)


a = mean data
</lang>
g = exp mean ln* data
or
h = div/1. mean div/*1. data
<lang R>
mean(x)
</lang>


#cast %eLbX
The geometric mean
<lang R>
prod(x)^(1/length(x))
</lang>


main = ^(~&,ordered not fleq) <a,g,h></lang>
The harmonic mean (no error checking that <math>x_i\ne 0,\text{ } \forall \text{ }i=1\ldots n</math>)
output:
<lang R>
<pre>(
length(x)/sum(1/x)
<5.500000e+00,4.528729e+00,3.414172e+00>,
</lang>
true)</pre>

Revision as of 12:42, 5 May 2010

Task
Averages/Pythagorean means
You are encouraged to solve this task according to the task description, using any language you may know.

Compute all three of the Pythagorean means of the set of integers 1 through 10.

Show that for this set of positive integers.

  • The most common of the three means, the arithmetic mean, is the sum of the list divided by its length:
  • The geometric mean is the th root of the product of the list:
  • The harmonic mean is divided by the sum of the reciprocal of each item in the list:

C.f. Averages/Root mean square

ActionScript

<lang ActionScript>function arithmeticMean(v:Vector.<Number>):Number { var sum:Number = 0; for(var i: uint = 0; i < v.length; i++) sum += v[i]; return sum/v.length; } function geometricMean(v:Vector.<Number>):Number { var product:Number = 1; for(var i: uint = 0; i < v.length; i++) product *= v[i]; return Math.pow(product, 1/v.length); } function harmonicMean(v:Vector.<Number>):Number { var sum:Number = 0; for(var i: uint = 0; i < v.length; i++) sum += 1/v[i]; return v.length/sum; } var list:Vector.<Number> = Vector.<Number>([1,2,3,4,5,6,7,8,9,10]); trace("Arithmetic: ", arithmeticMean(list)); trace("Geometric: ", geometricMean(list)); trace("Harmonic: ", harmonicMean(list)); </lang>

ALGOL 68

Translation of: C
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny

<lang algol68>main: (

 INT count:=0;
 LONG REAL f, sum:=0, prod:=1, resum:=0;
 FORMAT real = $g(0,4)$; # prefered real format #
 FILE fbuf; STRING sbuf; associate(fbuf,sbuf);
 BOOL opts := TRUE;
 FOR i TO argc DO
   IF opts THEN # skip args up to the -- token #
     opts := argv(i) NE "--"
   ELSE
     rewind(fbuf); sbuf := argv(i); get(fbuf,f);
     count +:= 1;
     sum +:= f;
     prod *:= f;
     resum +:= 1/f
   FI
 OD;
 printf(($"c: "f(real)l"s: "f(real)l"p: "f(real)l"r: "f(real)l$,count,sum,prod,resum));
 printf(($"Arithmetic mean = "f(real)l$,sum/count));
 printf(($"Geometric mean = "f(real)l$,prod**1/count));
 printf(($"Harmonic mean = "f(real)l$,count/resum))

)</lang>

Run command with arguments

a68g Pythagorean_means.a68 -- 1 2 3 4 5 6 7 8 9 10

Output:

c: 10.0000
s: 55.0000
p: 3628800.0000
r: 2.9290
Arithmetic mean = 5.5000
Geometric mean = 362880.0000
Harmonic mean = 3.4142

AutoHotkey

<lang autohotkey>A := ArithmeticMean(1, 10) G := GeometricMean(1, 10) H := HarmonicMean(1, 10)

If G Between %H% And %A%

   Result := "True"

Else

   Result := "False"

MsgBox, %A%`n%G%`n%H%`n%Result%


---------------------------------------------------------------------------

ArithmeticMean(a, b) { ; of integers a through b

---------------------------------------------------------------------------
   n := b - a + 1
   Loop, %n%
       Sum += (a + A_Index - 1)
   Return, Sum / n

}


---------------------------------------------------------------------------

GeometricMean(a, b) { ; of integers a through b

---------------------------------------------------------------------------
   n := b - a + 1
   Prod := 1
   Loop, %n%
       Prod *= (a + A_Index - 1)
   Return, Prod ** (1 / n)

}


---------------------------------------------------------------------------

HarmonicMean(a, b) { ; of integers a through b

---------------------------------------------------------------------------
   n := b - a + 1
   Loop, %n%
       Sum += 1 / (a + A_Index - 1)
   Return, n / Sum

}</lang> Message box shows:

5.500000
4.528729
3.414172
True

C

<lang c>#include <stdio.h>

  1. include <stdlib.h> // atoi()
  2. include <math.h> // pow()

int main(int argc, char* argv[]) {

 int i, count=0;
 double f, sum=0.0, prod=1.0, resum=0.0;
 for (i=1; i<argc; ++i) {
   f = atof(argv[i]);
   count++;
   sum += f;
   prod *= f;
   resum += (1.0/f);
 }
 //printf(" c:%d\n s:%f\n p:%f\n r:%f\n",count,sum,prod,resum);
 printf("Arithmetic mean = %f\n",sum/count);
 printf("Geometric mean = %f\n",pow(prod,(1.0/count)));
 printf("Harmonic mean = %f\n",count/resum);
 return 0;

} </lang>

Common Lisp

<lang lisp> (defun generic-mean (nums reduce-op final-op)

 (funcall final-op (reduce reduce-op nums)))

(defun a-mean (nums)

 (generic-mean nums #'+ (lambda (x) (/ x (length nums)))))

(defun g-mean (nums)

 (generic-mean nums #'* (lambda (x) (expt x (/ 1 (length nums))))))

(defun h-mean (nums)

 (generic-mean nums 
               (lambda (x y) (+ x
                                (/ 1 y)))
               (lambda (x) (/ (length nums) x))))

(let ((numbers (loop for i from 1 to 10 collect i)))

 (let ((a-mean (a-mean numbers))
       (g-mean (g-mean numbers))
       (h-mean (h-mean numbers)))
   (assert (> a-mean g-mean h-mean))
   (format t "a-mean ~a~%" a-mean)
   (format t "g-mean ~a~%" g-mean)
   (format t "h-mean ~a~%" h-mean)))</lang>

Clojure

<lang lisp>(use '[clojure.contrib.math :only (expt)])

(defn a-mean [coll]

 (/ (reduce + coll) (count coll)))

(defn g-mean [coll]

 (expt (reduce * coll) (/ (count coll))))

(defn h-mean [coll]

 (/ (count coll) (reduce + (map / coll))))

(let [numbers (range 1 11)

     a (a-mean numbers) g (g-mean numbers) h (h-mean numbers)]
 (println a ">=" g ">=" h)
 (>= a g h))</lang>

Factor

<lang factor>: a-mean ( seq -- mean )

   [ sum ] [ length ] bi / ;
g-mean ( seq -- mean )
   [ product ] [ length recip ] bi ^ ;
h-mean ( seq -- mean )
   [ length ] [ [ recip ] map-sum ] bi / ;</lang>
( scratchpad ) 10 [1,b] [ a-mean ] [ g-mean ] [ h-mean ] tri
               "%f >= %f >= %f\n" printf
5.500000 >= 4.528729 >= 3.414172

Forth

<lang forth>: famean ( faddr n -- f )

 0e
 tuck floats bounds do
   i f@ f+
 float +loop
 0 d>f f/ ;
fgmean ( faddr n -- f )
 1e
 tuck floats bounds do
   i f@ f*
 float +loop
 0 d>f 1/f f** ;
fhmean ( faddr n -- f )
 dup 0 d>f  0e
 floats bounds do
   i f@ 1/f f+
 float +loop
 f/ ;

create test 1e f, 2e f, 3e f, 4e f, 5e f, 6e f, 7e f, 8e f, 9e f, 10e f, test 10 famean fdup f. test 10 fgmean fdup fdup f. test 10 fhmean fdup f. ( A G G H ) f>= . f>= . \ -1 -1</lang>

Fortran

Works with: Fortran version 90

<lang fortran>program Mean

 real :: a(10) = (/ (i, i=1,10) /)
 real :: amean, gmean, hmean
 amean = sum(a) / size(a)
 gmean = product(a)**(1.0/size(a))
 hmean = size(a) / sum(1.0/a)
 if ((amean < gmean) .or. (gmean < hmean)) then
   print*, "Error!" 
 else
   print*, amean, gmean, hmean
 end if

end program Mean</lang>

Haskell

This example is incorrect. Please fix the code and remove this message.

Details: Need to show the relationship between A,G and H

The general function given here yields an arithmetic mean when its first argument is 1, a geometric mean when its first argument is 0, and a harmonic mean when its first argument is -1.

<lang haskell>import Data.List (genericLength) import Control.Monad (zipWithM_)

mean :: Double -> [Double] -> Double mean 0 xs = product xs ** (1 / genericLength xs) mean p xs = (1 / genericLength xs * sum (map (** p) xs)) ** (1/p)

main = zipWithM_ f "agh" (map (flip mean [1 .. 10]) [1, 0, -1])

where f c n = putStrLn $ c : ": " ++ show n</lang>

J

Solution: <lang j>amean=: +/ % # gmean=: # %: */ hmean=: amean&.:%</lang>

Example Usage: <lang j> (amean , gmean , hmean) >: i. 10 5.5 4.528729 3.414172

  assert 2 >:/\ (amean , gmean , hmean) >: i. 10    NB. check amean >= gmean and gmean >= hmean</lang>

JavaScript

Works with: JavaScript version 1.8

,

Works with: Firefox version 3.0

<lang javascript>function arithmetic_mean(ary) {

   var sum = ary.reduce(function(s,x) {return (s+x)}, 0);
   return (sum / ary.length);

}

function geometic_mean(ary) {

   var product = ary.reduce(function(s,x) {return (s*x)}, 1);
   return Math.pow(product, 1/ary.length);

}

function harmonic_mean(ary) {

   var sum_of_inv = ary.reduce(function(s,x) {return (s + 1/x)}, 0);
   return (ary.length / sum_of_inv);

}

var ary = [1,2,3,4,5,6,7,8,9,10]; var A = arithmetic_mean(ary); var G = geometic_mean(ary); var H = harmonic_mean(ary);

print("is A >= G >= H ? " + (A >= G && G >= H ? "yes" : "no"));</lang>

Lua

<lang lua>function fsum(f, a, ...) return a and f(a) + fsum(f, ...) or 0 end function pymean(t, f, finv) return finv(fsum(f, unpack(t)) / #t) end nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

--arithmetic a = pymean(nums, function(n) return n end, function(n) return n end) --geometric g = pymean(nums, math.log, math.exp) --harmonic h = pymean(nums, function(n) return 1/n end, function(n) return 1/n end) print(a, g, h) assert(a >= g and g >= h)</lang>


MUMPS

<lang MUMPS>Pyth(n) New a,ii,g,h,x For ii=1:1:n set x(ii)=ii ; ; Average Set a=0 For ii=1:1:n Set a=a+x(ii) Set a=a/n ; ; Geometric Set g=1 For ii=1:1:n Set g=g*x(ii) Set g=g**(1/n) ; ; Harmonic Set h=0 For ii=1:1:n Set h=1/x(ii)+h Set h=n/h ; Write !,"Pythagorean means for 1..",n,":",! Write "Average = ",a," >= Geometric ",g," >= harmonic ",h,! Quit Do Pyth(10)

Pythagorean means for 1..10: Average = 5.5 >= Geometric 4.528728688116178495 >= harmonic 3.414171521474055006</lang>


OCaml

The three means in one function

<lang ocaml>let means v =

 let n = Array.length v
 and a = ref 0.0
 and b = ref 1.0
 and c = ref 0.0 in
 for i=0 to n-1 do
   a := !a +. v.(i);
   b := !b *. v.(i);
   c := !c +. 1.0/.v.(i);
 done;
 let nn = float_of_int n in
 (!a /. nn, !b ** (1.0/.nn), nn /. !c)
</lang>

Sample output: <lang ocaml>means (Array.init 10 (function i -> (float_of_int (i+1)))) ;; (* (5.5, 4.5287286881167654, 3.4141715214740551) *)</lang>

Another implementation using Array.fold_left instead of a for loop:

<lang ocaml>let means v =

 let (a, b, c) =
   Array.fold_left
     (fun (a, b, c) x -> (a+.x, b*.x, c+.1./.x))
     (0.,1.,0.) v
 in
 let n = float_of_int (Array.length v) in
 (a /. n, b ** (1./.n), n /. c)
</lang>

Oz

<lang oz>declare

 %% helpers
 fun {Sum Xs} {FoldL Xs Number.'+' 0.0} end
 fun {Product Xs} {FoldL Xs Number.'*' 1.0} end
 fun {Len Xs} {Int.toFloat {Length Xs}} end
 fun {AMean Xs}
    {Sum Xs}
    /
    {Len Xs}
 end
 fun {GMean Xs}
    {Pow
     {Product Xs}
     1.0/{Len Xs}}
 end
 fun {HMean Xs}
    {Len Xs}
    /
    {Sum {Map Xs fun {$ X} 1.0 / X end}}
 end
 Numbers = {Map {List.number 1 10 1} Int.toFloat}
 [A G H] = [{AMean Numbers} {GMean Numbers} {HMean Numbers}]

in

 {Show [A G H]}
 A >= G = true
 G >= H = true</lang>

Perl

<lang perl>sub A {

       my $a = 0;
       $a += $_ for @_;
       return $a / @_;

} sub G {

       my $p = 1;
       $p *= $_ for @_;
       return  $p**(1/@_); # power of 1/n == root of n

} sub H {

       my $h = 0;
       $h += 1/$_ for @_;
       return @_/$h;

} my @ints = (1..10);

my $a = A(@ints); my $g = G(@ints); my $h = H(@ints);

print "A=$a\nG=$g\nH=$h\n"; die "Error" unless $a >= $g and $g >= $h;</lang>

PL/I

<lang PL/I> declare n fixed binary,

       (Average, Geometric, Harmonic) float;

declare A(10) float static initial (1,2,3,4,5,6,7,8,9,10);

n = hbound(A,1);

/* compute the average */ Average = sum(A)/n;

/* Compute the geometric mean: */ Geometric = prod(A)**(1/n);

/* Compute the Harmonic mean: */ Harmonic = n / sum(1/A);

put skip data (Average); put skip data (Geometric); put skip data (Harmonic);

if Average < Geometric then put skip list ('Error'); if Geometric < Harmonic then put skip list ('Error'); </lang>


PureBasic

<lang PureBasic>Procedure.d ArithmeticMean()

 For a = 1 To 10
   mean + a
 Next
 ProcedureReturn mean / 10

EndProcedure Procedure.d GeometricMean()

 mean = 1
 For a = 1 To 10
   mean * a
 Next
 ProcedureReturn Pow(mean, 1 / 10)

EndProcedure Procedure.d HarmonicMean()

 For a = 1 To 10
   mean.d + 1 / a
 Next
 ProcedureReturn 10 / mean

EndProcedure

If HarmonicMean() <= GeometricMean() And GeometricMean() <= ArithmeticMean()

 Debug "true"

EndIf Debug ArithmeticMean() Debug GeometricMean() Debug HarmonicMean()</lang>

Python

Works with: Python 3

<lang Python>from operator import mul from functools import reduce

def amean(num): return sum(num)/len(num)

def gmean(num): return reduce(mul, num, 1)**(1/len(num))

def hmean(num): return len(num)/sum(1/n for n in num)

numbers = range(1,11) # 1..10 a, g, h = amean(numbers), gmean(numbers), hmean(numbers) print(a, g, h) assert( a >= g >= h ) </lang>

Output:

5.5 4.52872868812 3.41417152147

R

Initialise x <lang R>

x<-1:10

</lang> Arithmetic mean <lang R> sum(x)/length(x)

</lang> or <lang R>

mean(x)

</lang>

The geometric mean <lang R> prod(x)^(1/length(x)) </lang>

The harmonic mean (no error checking that ) <lang R>

length(x)/sum(1/x)

</lang>


Ruby

Works with: Ruby version 1.9+

<lang ruby>class Array

 def arithmetic_mean
   inject(:+).to_f / length
 end
 def geometric_mean
   inject(:*) ** (1.0 / length)
 end
 def harmonic_mean
   length.to_f / inject(0) {|s, m| s += 1.0/m}
 end

end

class Range

 def method_missing(m, *args)
   case m
   when /_mean$/ then to_a.send(m)
   else super
   end
 end

end

p a = (1..10).arithmetic_mean p g = (1..10).geometric_mean p h = (1..10).harmonic_mean

  1. is h < g < a ??

p g.between?(h, a)</lang>

outputs

5.5
4.52872868811677
3.41417152147406
true

Scheme

Works with: Scheme version RRS

<lang scheme>(define (a-mean l)

 (/ (apply + l) (length l)))

(define (g-mean l)

 (expt (apply * l) (/ (length l))))

(define (h-mean l)

 (/ (length l) (apply + (map / l))))

(define (iota start stop)

 (if (> start stop)
     (list)
     (cons start (iota (+ start 1) stop))))

(let* ((l (iota 1 10)) (a (a-mean l)) (g (g-mean l)) (h (h-mean l)))

 (display a)
 (display " >= ")
 (display g)
 (display " >= ")
 (display h)
 (newline)
 (display (>= a g h))
 (newline))</lang>

Output: <lang>11/2 >= 4.528728688116765 >= 25200/7381

  1. t</lang>

Tcl

<lang tcl>proc arithmeticMean list {

   set sum 0.0
   foreach value $list { set sum [expr {$sum + $value}] }
   return [expr {$sum / [llength $list]}]

} proc geometricMean list {

   set product 1.0
   foreach value $list { set product [expr {$product * $value}] }
   return [expr {$product ** (1.0/[llength $list])}]

} proc harmonicMean list {

   set sum 0.0
   foreach value $list { set sum [expr {$sum + 1.0/$value}] }
   return [expr {[llength $list] / $sum}]

}

set nums {1 2 3 4 5 6 7 8 9 10} set A10 [arithmeticMean $nums] set G10 [geometricMean $nums] set H10 [harmonicMean $nums] puts "A10=$A10, G10=$G10, H10=$H10" if {$A10 >= $G10} { puts "A10 >= G10" } if {$G10 >= $H10} { puts "G10 >= H10" }</lang>

Output:

A10=5.5, G10=4.528728688116765, H10=3.414171521474055
A10 >= G10
G10 >= H10


Ursala

<lang Ursala>#import std

  1. import flo

data = ari10(1.,10.) # arithmetic progression, length 10 with endpoints 1 and 10

a = mean data g = exp mean ln* data h = div/1. mean div/*1. data

  1. cast %eLbX

main = ^(~&,ordered not fleq) <a,g,h></lang> output:

(
   <5.500000e+00,4.528729e+00,3.414172e+00>,
   true)