

 This page uses content from Wikipedia. The original article was at Arithmetic-geometric mean. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance)



Task

Write a function to compute the arithmetic-geometric mean of two numbers.



The arithmetic-geometric mean of two numbers can be (usefully) denoted as 




a
g
m

(
a
,
g
)


{\displaystyle \mathrm {agm} (a,g)}

, and is equal to the limit of the sequence:

 




a

0


=
a
;


g

0


=
g


{\displaystyle a_{0}=a;\qquad g_{0}=g}


 




a

n
+
1


=



1
2



(

a

n


+

g

n


)
;


g

n
+
1


=



a

n



g

n




.


{\displaystyle a_{n+1}={\tfrac {1}{2}}(a_{n}+g_{n});\quad g_{n+1}={\sqrt {a_{n}g_{n}}}.}


Since the limit of 




a

n


−

g

n




{\displaystyle a_{n}-g_{n}}

 tends (rapidly) to zero with iterations, this is an efficient method.

Demonstrate the function by calculating:






a
g
m

(
1
,
1

/



2


)


{\displaystyle \mathrm {agm} (1,1/{\sqrt {2}})}




Also see

   mathworld.wolfram.com/Arithmetic-Geometric Mean


$ include "seed7_05.s7i";
  include "float.s7i";
  include "math.s7i";
 
const func float: agm (in var float: a, in var float: g) is func
  result
    var float: agm is 0.0;
  local
    const float: iota is 1.0E-7;
    var float: a1 is 0.0;
    var float: g1 is 0.0;
  begin
    if a * g < 0.0 then
      raise RANGE_ERROR;
    else
      while abs(a - g) > iota do
        a1 := (a + g) / 2.0;
        g1 := sqrt(a * g);
        a := a1;
        g := g1;
      end while;
      agm := a;
    end if;
  end func;
 
const proc: main is func
  begin
    writeln(agm(1.0, 2.0) digits 6);
    writeln(agm(1.0, 1.0 / sqrt(2.0)) digits 6);
  end func;