Averages/Pythagorean means

From Rosetta Code
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>

Ada

pythagorean_means.ads: <lang Ada>package Pythagorean_Means is

  type Set is array (Positive range <>) of Float;
  function Arithmetic_Mean (Data : Set) return Float;
  function Geometric_Mean  (Data : Set) return Float;
  function Harmonic_Mean   (Data : Set) return Float;

end Pythagorean_Means;</lang>

pythagorean_means.adb: <lang Ada>with Ada.Numerics.Generic_Elementary_Functions; package body Pythagorean_Means is

  package Math is new Ada.Numerics.Generic_Elementary_Functions (Float);
  function "**" (Left, Right : Float) return Float renames Math."**";
  function Arithmetic_Mean (Data : Set) return Float is
     Sum : Float := 0.0;
  begin
     for I in Data'Range loop
        Sum := Sum + Data (I);
     end loop;
     return Sum / Float (Data'Length);
  end Arithmetic_Mean;
  function Geometric_Mean (Data : Set) return Float is
     Product : Float := 1.0;
  begin
     for I in Data'Range loop
        Product := Product * Data (I);
     end loop;
     return Product**(1.0/Float(Data'Length));
  end Geometric_Mean;
  function Harmonic_Mean (Data : Set) return Float is
     Reciprocal_Sum : Float := 0.0;
  begin
     for I in Data'Range loop
        Reciprocal_Sum := Reciprocal_Sum + Data (I)**(-1);
     end loop;
     return Float (Data'Length) / Reciprocal_Sum;
  end Harmonic_Mean;

end Pythagorean_Means;</lang>

example main.adb: <lang Ada>with Ada.Text_IO; with Pythagorean_Means; procedure Main is

  My_Set : Pythagorean_Means.Set := (1.0, 2.0, 3.0, 4.0,  5.0,
                                     6.0, 7.0, 8.0, 9.0, 10.0);
  Arithmetic_Mean : Float := Pythagorean_Means.Arithmetic_Mean (My_Set);
  Geometric_Mean  : Float := Pythagorean_Means.Geometric_Mean  (My_Set);
  Harmonic_Mean   : Float := Pythagorean_Means.Harmonic_Mean   (My_Set);

begin

  Ada.Text_IO.Put_Line (Float'Image (Arithmetic_Mean) & " >= " &
                        Float'Image (Geometric_Mean)  & " >= " &
                        Float'Image (Harmonic_Mean));

end Main;</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)$; # preferred 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> Lunix command:

a68g Averages_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 = 4.5287
Harmonic mean = 3.4142

APL

<lang APL>

arithmetic←{(+/⍵)÷⍴⍵}
geometric←{(×/⍵)*÷⍴⍵}
harmonic←{(⍴⍵)÷(+/÷⍵)}


x←⍳10
arithmetic x

5.5

geometric x

4.528728688

harmonic x

3.414171521 </lang>


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>

C++

<lang cpp>#include <vector>

  1. include <iostream>
  2. include <numeric>
  3. include <cmath>
  4. include <algorithm>

double toInverse ( int i ) {

  return  1.0 / i  ;

}

int main( ) {

  std::vector<int> numbers ;
  for ( int i = 1 ; i < 11 ; i++ ) 
     numbers.push_back( i ) ;
  double arithmetic_mean = std::accumulate( numbers.begin( ) , numbers.end( ) , 0 ) / 10.0 ;
  double geometric_mean =
     pow( std::accumulate( numbers.begin( ) , numbers.end( ) , 1 , std::multiplies<int>( ) ), 0.1 ) ;
  std::vector<double> inverses ;
  inverses.resize( numbers.size( ) ) ;
  std::transform( numbers.begin( ) , numbers.end( ) , inverses.begin( ) , toInverse ) ;  
  double harmonic_mean = 10 / std::accumulate( inverses.begin( ) , inverses.end( ) , 0.0 ); //initial value of accumulate must be a double!
  std::cout << "The arithmetic mean is " << arithmetic_mean << " , the geometric mean " 
     << geometric_mean << " and the harmonic mean " << harmonic_mean << " !\n" ;
  return 0 ;

}</lang> Output:

The arithmetic mean is 5.5 , the geometric mean 4.52873 and the harmonic mean 3.41417 !

C#

The standard Linq extension method Average provides arithmetic mean. This example adds two more extension methods for the geometric and harmonic means.

Works with: C# version 3

<lang csharp>using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq;

namespace PythMean {

   static class Program
   {
       static void Main(string[] args) {
           var nums = from n in Enumerable.Range(1, 10) select (double)n;
           var a = nums.Average();
           var g = nums.Gmean();
           var h = nums.Hmean();
           Console.WriteLine("Arithmetic mean {0}", a);
           Console.WriteLine("Geometric mean  {0}", g);
           Console.WriteLine("Harmonic mean   {0}", h);
           Debug.Assert(a >= g && g >= h);
       }
       // Geometric mean extension method.
       static double Gmean(this IEnumerable<double> n) {
           return Math.Pow(n.Aggregate((s, i) => s * i), 1.0 / n.Count());
       }
       // Harmonic mean extension method.
       static double Hmean(this IEnumerable<double> n) {
           return n.Count() / n.Sum(i => 1 / i);
       }
   }

}</lang>

Output:

Arithmetic mean 5.5
Geometric mean  4.52872868811677
Harmonic mean   3.41417152147406

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]

 (/ (apply + coll) (count coll)))

(defn g-mean [coll]

 (expt (apply * coll) (/ (count coll))))

(defn h-mean [coll]

 (/ (count coll) (apply + (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>

D

<lang d>import std.stdio, std.algorithm, std.range, std.functional;

auto amean(T)(T data) {

   return reduce!q{a + b}(data) / data.length;

}

auto gmean(T)(T data) {

   return reduce!q{a * b}(data) ^^ (1.0 / data.length);

}

auto hmean(T)(T data) {

   return data.length / reduce!q{1.0/a + b}(data);

}

void main() {

   auto m = adjoin!(hmean, gmean, amean)(iota(1.L, 11.L));
   writefln("%.19f %.19f %.19f", m.tupleof);
   assert(isSorted([m.tupleof]));

}</lang> Output:

0.9891573712076470036 4.5287286881167647619 5.5000000000000000000

Delphi

This example is incomplete. There seems to be no check on the relative sizes of the means of the integers 1..10. Please ensure that it meets all task requirements and remove this message.

<lang Delphi>program AveragesPythagoreanMeans;

{$APPTYPE CONSOLE}

uses Types, Math;

function ArithmeticMean(aArray: TDoubleDynArray): Double; var

 lValue: Double;

begin

 Result := 0;
 for lValue in aArray do
   Result := Result + lValue;
 if Result > 0 then
   Result := Result / Length(aArray);

end;

function GeometricMean(aArray: TDoubleDynArray): Double; var

 lValue: Double;

begin

 Result := 1;
 for lValue in aArray do
   Result := Result * lValue;
 Result := Power(Result, 1 / Length(aArray));

end;

function HarmonicMean(aArray: TDoubleDynArray): Double; var

 lValue: Double;

begin

 Result := 0;
 for lValue in aArray do
   Result := Result + 1 / lValue;
 Result := Length(aArray) / Result;

end;

var

 lSourceArray: TDoubleDynArray;

begin

 lSourceArray := TDoubleDynArray.Create(1,2,3,4,5,6,7,8,9,10);
 Writeln(ArithmeticMean(lSourceArray));
 Writeln(GeometricMean(lSourceArray));
 Writeln(HarmonicMean(lSourceArray));

end.</lang>

E

Given that we're defining all three together, it makes sense to express their regularities:

<lang e>def makeMean(base, include, finish) {

   return def mean(numbers) {
       var count := 0
       var acc := base
       for x in numbers {
           acc := include(acc, x)
           count += 1
       }
       return finish(acc, count)
   }

}

def A := makeMean(0, fn b,x { b+x }, fn acc,n { acc / n }) def G := makeMean(1, fn b,x { b*x }, fn acc,n { acc ** (1/n) }) def H := makeMean(0, fn b,x { b+1/x }, fn acc,n { n / acc })</lang>

<lang e>? A(1..10)

  1. value: 5.5

? G(1..10)

  1. value: 4.528728688116765

? H(1..10)

  1. value: 3.414171521474055</lang>

Euphoria

<lang euphoria>function arithmetic_mean(sequence s)

   atom sum
   if length(s) = 0 then
       return 0
   else
       sum = 0
       for i = 1 to length(s) do   
           sum += s[i]
       end for
       return sum/length(s)
   end if

end function

function geometric_mean(sequence s)

   atom p
   p = 1
   for i = 1 to length(s) do
       p *= s[i]
   end for
   return power(p,1/length(s))

end function

function harmonic_mean(sequence s)

   atom sum
   if length(s) = 0 then
       return 0
   else
       sum = 0
       for i = 1 to length(s) do
           sum += 1/s[i]
       end for
       return length(s) / sum
   end if

end function

function true_or_false(atom x)

   if x then
       return "true"
   else
       return "false"
   end if

end function

constant s = {1,2,3,4,5,6,7,8,9,10} constant arithmetic = arithmetic_mean(s),

   geometric = geometric_mean(s),
   harmonic = harmonic_mean(s)

printf(1,"Arithmetic: %g\n", arithmetic) printf(1,"Geometric: %g\n", geometric) printf(1,"Harmonic: %g\n", harmonic) printf(1,"Arithmetic>=Geometric>=Harmonic: %s\n",

   {true_or_false(arithmetic>=geometric and geometric>=harmonic)})</lang>

Output:

Arithmetic: 5.5
Geometric: 4.52873
Harmonic: 3.41417
Arithmetic>=Geometric>=Harmonic: true

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

Fantom

<lang fantom> class Main {

 static Float arithmeticMean (Int[] nums)
 {
   if (nums.size == 0) return 0.0f
   sum := 0
   nums.each |n| { sum += n }
   return sum.toFloat / nums.size
 }
 static Float geometricMean (Int[] nums)
 {
   if (nums.size == 0) return 0.0f
   product := 1
   nums.each |n| { product *= n }
   return product.toFloat.pow(1f/nums.size)
 }
 static Float harmonicMean (Int[] nums)
 {
   if (nums.size == 0) return 0.0f 
   reciprocals := 0f
   nums.each |n| { reciprocals += 1f / n }
   return nums.size.toFloat / reciprocals
 }
 public static Void main ()
 {
   items := (1..10).toList
   // display results
   echo (arithmeticMean (items))
   echo (geometricMean (items))
   echo (harmonicMean (items))
   // check given relation
   if ((arithmeticMean (items) >= geometricMean (items)) &&
       (geometricMean (items) >= harmonicMean (items)))
     echo ("relation holds")
   else
     echo ("relation failed")
 }

} </lang>

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>

GAP

<lang gap># The first two work with rationals or with floats

  1. (but bear in mind that support of floating point is very poor in GAP)

mean := v -> Sum(v) / Length(v); harmean := v -> Length(v) / Sum(v, Inverse); geomean := v -> EXP_FLOAT(Sum(v, LOG_FLOAT) / Length(v));

mean([1 .. 10]);

  1. 11/2

harmean([1 .. 10]);

  1. 25200/7381

v := List([1..10], FLOAT_INT);; mean(v);

  1. 5.5

harmean(v);

  1. 3.41417

geomean(v);

  1. 4.52873</lang>

Go

<lang go>package main

import (

   "fmt"
   "math"

)

func main() {

   sum, sumr, prod := 0., 0., 1.
   for n := 1.; n <= 10; n++ {
       sum += n
       sumr += 1 / n
       prod *= n
   }
   a, g, h := sum/10, math.Pow(prod, .1), 10/sumr
   fmt.Println("A:", a, "G:", g, "H:", h)
   fmt.Println("A >= G >= H:", a >= g && g >= h)

}</lang>

Groovy

Solution: <lang groovy>def arithMean = { list ->

   list == null \
       ? null \
       : list.empty \
           ? 0 \
           : list.sum() / list.size()

}

def geomMean = { list ->

   list == null \
       ? null \
       : list.empty \
           ? 1 \
           : list.inject(1) { prod, item -> prod*item } ** (1 / list.size())

}

def harmMean = { list ->

   list == null \
       ? null \
       : list.empty \
           ? 0 \
           : list.size() / list.collect { 1.0/it }.sum()

}</lang>

Test: <lang groovy>def list = 1..10 def A = arithMean(list) def G = geomMean(list) assert A >= G def H = harmMean(list) assert G >= H println """ list: ${list}

  A: ${A}
  G: ${G}
  H: ${H}

"""</lang>

Output:

list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
   A: 5.5
   G: 4.528728688116765
   H: 3.4141715214

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

 let ms = zipWith ((. flip mean [1..10]). (,)) "agh" [1, 0, -1]
 mapM_ (\(t,m) -> putStrLn $ t : ": " ++ show m) ms
 putStrLn $ " a >= g >= h is " ++  show ((\(_,[a,g,h])-> a>=g && g>=h) (unzip ms))</lang>

HicEst

<lang HicEst>AGH = ALIAS( A, G, H ) ! named vector elements AGH = (0, 1, 0) DO i = 1, 10

  A = A + i
  G = G * i
  H = H + 1/i

ENDDO AGH = (A/10, G^0.1, 10/H)

WRITE(ClipBoard, Name) AGH, "Result = " // (A>=G) * (G>=H)</lang> ! A=5.5; G=4.528728688; H=3.414171521; Result = 1;

Icon and Unicon

<lang Icon>link numbers # for a/g/h means

procedure main() every put(x := [], 1 to 10) writes("x := [ "); every writes(!x," "); write("]")

write("Arithmetic mean:", a := amean!x) write("Geometric mean:",g := gmean!x) write("Harmonic mean:", h := hmean!x) write(" a >= g >= h is ", if a >= g >= h then "true" else "false") end </lang>

numbers:amean, numbers:gmean, and numbers:hmean are shown below: <lang Icon>procedure amean(L[]) #: arithmetic mean

  local m
  if *L = 0 then fail
  m := 0.0
  every m +:= !L
  return m / *L

end

procedure gmean(L[]) #: geometric mean

  local m
  if *L = 0 then fail
  m := 1.0
  every m *:= !L
  m := abs(m)
  if m > 0.0 then
     return exp (log(m) / *L)
  else
     fail

end

procedure hmean(L[]) #: harmonic mean

  local m, r
  if *L = 0 then fail
  m := 0.0
  every r := !L do {
     if r = 0.0 then fail
     else m +:= 1.0 / r
     }
  return *L / m

end</lang>

Sample output:

#means.exe
x := [ 1 2 3 4 5 6 7 8 9 10 ]
Arithmetic mean:5.5
Geometric mean:4.528728688116765
Harmonic mean:3.414171521474055
 a >= g >= h is true

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>

Note that gmean could have instead been defined as mean under logarithm, for example:

<lang j>gmean=:amean&.:^.</lang>

Java

<lang java>import java.util.Arrays; import java.util.List;

public class PythagoreanMeans {

   public static double arithmeticMean(List<Double> numbers) {
       if (numbers.isEmpty()) return Double.NaN;
       double mean = 0.0;
       for (Double number : numbers) {
           mean += number;
       }
       return mean / numbers.size();
   }
   public static double geometricMean(List<Double> numbers) {
       if (numbers.isEmpty()) return Double.NaN;
       double mean = 1.0;
       for (Double number : numbers) {
           mean *= number;
       }
       return Math.pow(mean, 1.0 / numbers.size());
   }
   public static double harmonicMean(List<Double> numbers) {
       if (numbers.isEmpty() || numbers.contains(0.0)) return Double.NaN;
       double mean = 0.0;
       for (Double number : numbers) {
           mean += (1.0 / number);
       }
       return numbers.size() / mean;
   }
   public static void main(String[] args) {
       Double[] array = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0};
       List<Double> list = Arrays.asList(array);
       double arithmetic = arithmeticMean(list);
       double geometric = geometricMean(list);
       double harmonic = harmonicMean(list);
       System.out.format("A = %f  G = %f  H = %f%n", arithmetic, geometric, harmonic);
       System.out.format("A >= G is %b, G >= H is %b%n", (arithmetic >= geometric), (geometric >= harmonic));
   }

}</lang> Output:

A = 5.500000  G = 4.528729  H = 3.414172
A >= G is true, G >= H is true

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>

Liberty BASIC

<lang lb>for i = 1 to 10

   a = a + i

next ArithmeticMean = a/10

b = 1 for i = 1 to 10

   b = b * i

next GeometricMean = b ^ (1/10)

for i = 1 to 10

   c = c + (1/i)

next HarmonicMean = 10/c

print "ArithmeticMean: ";ArithmeticMean print "Geometric Mean: ";GeometricMean print "Harmonic Mean: ";HarmonicMean

if (ArithmeticMean>=GeometricMean) and (GeometricMean>=HarmonicMean) then print "True" else print "False" end if

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

Mathematica

<lang Mathematica>Print["{Arithmetic Mean, Geometric Mean, Harmonic Mean} = ",

N@Through[{Mean, GeometricMean, HarmonicMean}[Range@10]]]</lang>

Solution:

{Arithmetic Mean, Geometric Mean, Harmonic Mean} = {5.5,4.52873,3.41417}

MATLAB

<lang MATLAB>function [A,G,H] = pythagoreanMeans(list)

   function GMean = geometricMean(list)
       GMean = nthroot(prod(list),numel(list));
   end
   function HMean = harmonicMean(list)
       HMean = numel(list) / sum(1./list);
   end
   A = mean(list);
   G = geometricMean(list);
   H = harmonicMean(list);
   

end</lang> Solution: <lang MATLAB>>> [A,G,H]=pythagoreanMeans((1:10))

A =

  5.500000000000000


G =

  4.528728688116765


H =

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

PARI/GP

General implementations: <lang parigp>arithmetic(v)={

 sum(i=1,#v,v[i])/#v

}; geometric(v)={

 prod(i=1,#v,v[i])^(1/#v)

}; harmonic(v)={

 #v/sum(i=1,#v,1/v[i])

};

v=vector(10,i,i); [arithmetic(v),geometric(v),harmonic(v)]</lang>

Specific to the first n positive integers: <lang parigp>arithmetic_first(n)={

 (n+1)/2

}; geometric_first(n)={

 n!^(1/n)

}; harmonic_first(n)={

 n/if(n>1000,
   log(n)+Euler+1/(n+n)+1/(12*n^2)-1/(120*n^4)+1/(252*n^6)-1/(240*n^8)+1/(132*n^10)
 ,
   n/sum(k=1,n,1/k)
 )

};

[arithmetic_first(10),geometric_first(10),harmonic_first(10)] %[1]>=%[2] && %[2] >= %[3]</lang>

These are, asymptotically, n/2, n/e, and n/log n.

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>

Perl 6

<lang Perl6>sub A(@x) { ([+] @x) / @x.elems; } sub G(@x) { ([*] @x) ** (1 / @x.elems); } sub H(@x) { @x.elems / [+] @x.map: 1/*; }

say "A(1,...,10) = ", A(1..10); say "G(1,...,10) = ", G(1..10); say "H(1,...,10) = ", H(1..10); </lang>

Output:

A(1,...,10) = 5.5
G(1,...,10) = 4.52872868811677
H(1,...,10) = 3.41417152147406

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>

PicoLisp

<lang PicoLisp>(load "@lib/math.l")

(let (Lst (1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0) Len (length Lst))

  (prinl "Arithmetic mean: "
     (format
        (/ (apply + Lst) Len)
        *Scl ) )
  (prinl "Geometric mean: "
     (format
        (pow (*/ (apply * Lst) (** 1.0 (dec Len))) (/ 1.0 Len))
        *Scl ) )
  (prinl "Harmonic mean: "
     (format
        (*/ (* 1.0 Len) 1.0 (sum '((N) (*/ 1.0 1.0 N)) Lst))
        *Scl ) ) )</lang>

Output:

Arithmetic mean: 5.500000
Geometric mean: 4.528729
Harmonic mean: 3.414172

PostScript

<lang> /pythamean{ /x exch def /sum 0 def /prod 1 def /invsum 0 def /i 1 def

x{ /sum sum i add def /prod prod i mul def /invsum invsum i -1 exp add def /i i 1 add def }repeat (Arithmetic Mean : ) print sum x div = (Geometric Mean : ) print prod x -1 exp exp = (Harmonic Mean : ) print x invsum div = }def

10 pythamean </lang>

Output :

<lang> Arithmetic Mean : 5.5 Geometric Mean : 4.52873 Harmonic Mean : 3.41417 </lang>

Library: initlib

<lang postscript> /numbers {[1 10] 1 range}. /recip {1 exch div}.

% Arithmetic mean numbers dup 0 {+} fold exch length div % Geometric mean numbers dup 1 {*} fold exch length recip exp % Harmonic mean numbers dup 0 {recip +} fold exch length exch div </lang>

PowerShell

This example is incomplete. There seems to be no check on the relative sizes of the means of the integers 1..10. Please ensure that it meets all task requirements and remove this message.

<lang PowerShell>1..10 | ForEach-Object { $sum = 0; $product = 1; $invsum = 0; $count = 0 } { $count += 1; $sum += $_; $product *= $_; $invsum += 1 / $_ } { @{ "Arithmetic Mean" = $sum / $count; "Geometric Mean" = [math]::pow( $product, 1 / $count ); "Harmonic Mean" = $count / $invsum } }</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 version 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

These are the same in Python 2 apart from requiring explicit float division (either through float() casts or float literals such as 1./n); or better, do a from __future__ import division, which works on Python 2.2+ as well as Python 3, and makes division work consistently like it does in Python 3.

R

Initialise x <lang R>

x <- 1:10

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

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

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

The harmonic mean (no error checking that ) <lang R> h <- length(x)/sum(1/x) </lang>

Then:

<lang R> a > g </lang>

and

<lang R> g > h </lang>

give both

[1] TRUE

REXX

REXX doesn't have a POW function, so an IROOT (integer root) function is included here. <lang rexx> /*REXX program to compute/show Pythagorean means [Amean, Gmean, Hmean].*/

arg n . /*get an arguement (possibly). */ if n== then n=10 /*None specified? Assume default*/

 do j=1 for n
 @.j=j                                /*build population of array.     */
 end


/*─────────────────────────────────────compute Amean [Arithmetic mean]. */ sum=0

 do j=1 for n
 sum=sum+@.j                          /*compute the sum of all elements*/
 end

Amean=sum/n /*calculate the Amean. */ say 'Amean =' Amean /*show and tell Amean. */


/*─────────────────────────────────────compute Gmean [Geometric mean]. */ prod=1

 do j=1 for n
 prod=prod*@.j                        /*comp. product of all elements. */
 end

Gmean=iroot(prod,n) /*calculate the Gmean. */ say 'Gmean =' Gmean /*show and tell Gmean. */


/*─────────────────────────────────────compute Hmean [Harmonic mean]. */ rsum=0

 do j=1 for n
 rsum=rsum+1/@.j                      /*compute the sum of reciprocals.*/
 end

Hmean=n/rsum /*calculate the Hmean. */ say 'Hmean =' Hmean /*show and tell Hmean. */

exit


/*─────────────────────────────────────IROOT subroutine─────────────────*/ iroot: procedure; arg x 1 ox,y 1 oy /*get both args, and also a copy.*/ if x=0 then return 0 /*handle special case of zero. */ if x=1 then return 1 /*handle special case of unity. */ if y=0 then return 1 /*handle special case of root 0. */ if y=1 then return x /*handle special case of root 1. */

if x<0 & y//2==0 then do /*check for illegal combination. */

                     say
                     say '*** error! *** (from IROOT):'
                     say
                     say 'root' y "can't be even if 1st argument is < 0."
                     say
                     return '[n/a]'   /*return a   not applicable.     */
                     end

x=abs(x) /*use the absolute value for X. */ y=abs(y) /*use the absolute value for root*/ digo=digits() /*save original accuracy (digits)*/ a=digo+5 /*use an extra 5 digs (accuracy).*/ g=(x+1)/y**y /*use this as the 1st guesstimate*/ m=y-1 /*use this as a fast root- 1 */ numeric fuzz 3 /*3 fuzz digits for comparisons. */ d=5 /*start with five digits accuracy*/

                                      /*this is done because when digs */
                                      /*is large, excessive CPU time is*/
                                      /*wasted on large accuracies even*/
                                      /*when the guess isn't close to  */
                                      /*the final answer.  Best to take*/
                                      /*baby steps before going full   */
                                      /*trottle & putting the pedal to */
                                      /*metal, putting it in high gear,*/
                                      /*and turning the volume way up. */
 do forever                           /*keep plugging as digs increases*/
 d=min(d+d,a)                         /*limit the digits to orig digs+5*/
 numeric digits d                     /*keep increasing the accuracy.  */
 old=0                                /*define  old (guess).           */
   do forever                         /*keep plugging at the  Yth root.*/
   _=(m*g**y+x)/y/g**m                /*this is the nitty-gritty stuff.*/
   if _=g | _=old then leave          /*are we close enough yet ?      */
   old=g                              /*save guess in old (guess).     */
   g=_                                /*set Guess to what's been calc. */
   end
 if d==a then leave                   /*are we at the desired accuracy?*/
 end

_=g*sign(ox) /*adjust for the sign of orig X. */ if oy<0 then _=1/_ /*adjust for negative root. */ numeric digits digo /*restore the original digits. */ return _/1 /*normalize result to orig digits*/ </lang> Output:

Amean = 5.5
Gmean = 4.52872869
Hmean = 3.41417153

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

Scala

Works with: Scala version 2.8+

<lang scala>def arithmeticMean(n: Seq[Int]) = n.sum / n.size.toDouble def geometricMean(n: Seq[Int]) = math.pow(n.foldLeft(1.0)(_*_), 1.0 / n.size.toDouble) def harmonicMean(n: Seq[Int]) = n.size / n.map(1.0 / _).sum

var nums = 1 to 10

var a = arithmeticMean(nums) var g = geometricMean(nums) var h = harmonicMean(nums)

println("Arithmetic mean " + a) println("Geometric mean " + g) println("Harmonic mean " + h)

assert(a >= g && g >= h)</lang>

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>

Seed7

<lang seed7>$ include "seed7_05.s7i";

 include "float.s7i";

const array float: numbers is [] (1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);

const func proc: main is func

 local
   var float: number is 0.0;
   var float: sum is 0.0;
   var float: product is 1.0;
   var float: reciprocalSum is 0.0;
 begin
   for number range numbers do
     sum +:= number;
     product *:= number;
     reciprocalSum +:= 1.0 / number;
   end for;
   writeln("Arithmetic mean: " <& sum / flt(length(numbers)));
   writeln("Geometric mean:  " <& product ** (1.0 / flt(length(numbers))));
   writeln("Harmonic mean:   " <& flt(length(numbers)) / reciprocalSum);
 end func;</lang>

Output:

Arithmetic mean: 5.5
Geometric mean:  4.528728961944580078125
Harmonic mean:   3.4141712188720703125

Smalltalk

Works with: GNU Smalltalk

This extends the class Collection, so these three methods can be called over any kind of collection, it is enough the the objects of the collection understand +, *, raisedTo, reciprocal and /.

<lang smalltalk>Collection extend [

   arithmeticMean
   [

^ (self fold: [:a :b| a + b ]) / (self size)

   ]
   geometricMean
   [

^ (self fold: [:a :b| a * b]) raisedTo: (self size reciprocal)

   ]
   harmonicMean
   [

^ (self size) / ((self collect: [:x|x reciprocal]) fold: [:a :b| a + b ] )

   ]

]

|a| a := #(1 2 3 4 5 6 7 8 9 10).

a arithmeticMean asFloat displayNl. a geometricMean asFloat displayNl. a harmonicMean asFloat displayNl.

((a arithmeticMean) >= (a geometricMean)) displayNl. ((a geometricMean) >= (a harmonicMean)) displayNl.</lang>

Output:

5.5
4.528728688116765
3.414171521474055
true
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

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)