Averages/Pythagorean means
![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.
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
C
<lang c>#include <stdio.h>
- include <stdlib.h> // atoi()
- 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>
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
<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
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>
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) *)
(* Simpler implementation *) 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
<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
Ruby
<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
- is h < g < a ??
p g.between?(h, a)</lang>
outputs
5.5 4.52872868811677 3.41417152147406 true
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
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>