Arithmetic-geometric mean: Difference between revisions
No edit summary |
imported>Lacika7 No edit summary |
||
(266 intermediate revisions by more than 100 users not shown) | |||
Line 1: | Line 1: | ||
{{task}} |
|||
{{task}}{{wikipedia|Arithmetic-geometric mean}} |
|||
{{wikipedia|Arithmetic-geometric mean}} |
|||
;Task: |
|||
Write a function to compute the [[wp:Arithmetic-geometric mean|arithmetic-geometric mean]] of two numbers. |
Write a function to compute the [[wp:Arithmetic-geometric mean|arithmetic-geometric mean]] of two numbers. |
||
[http://mathworld.wolfram.com/Arithmetic-GeometricMean.html] |
|||
The arithmetic-geometric mean of two numbers can be (usefully) denoted as <math>\mathrm{agm}(a,g)</math>, and is equal to the limit of the sequence: |
The arithmetic-geometric mean of two numbers can be (usefully) denoted as <math>\mathrm{agm}(a,g)</math>, and is equal to the limit of the sequence: |
||
: <math>a_0 = a; \qquad g_0 = g</math> |
: <math>a_0 = a; \qquad g_0 = g</math> |
||
Line 9: | Line 14: | ||
Demonstrate the function by calculating: |
Demonstrate the function by calculating: |
||
:<math>\mathrm{agm}(1,1/\sqrt{2})</math> |
:<math>\mathrm{agm}(1,1/\sqrt{2})</math> |
||
;Also see: |
|||
* [http://mathworld.wolfram.com/Arithmetic-GeometricMean.html mathworld.wolfram.com/Arithmetic-Geometric Mean] |
|||
<br><br> |
|||
=={{header|11l}}== |
|||
{{trans|Python}} |
|||
<syntaxhighlight lang="11l">F agm(a0, g0, tolerance = 1e-10) |
|||
V an = (a0 + g0) / 2.0 |
|||
V gn = sqrt(a0 * g0) |
|||
L abs(an - gn) > tolerance |
|||
(an, gn) = ((an + gn) / 2.0, sqrt(an * gn)) |
|||
R an |
|||
print(agm(1, 1 / sqrt(2)))</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.847213</pre> |
|||
=={{header|360 Assembly}}== |
|||
For maximum compatibility, this program uses only the basic instruction set. |
|||
<syntaxhighlight lang="360asm">AGM CSECT |
|||
USING AGM,R13 |
|||
SAVEAREA B STM-SAVEAREA(R15) |
|||
DC 17F'0' |
|||
DC CL8'AGM' |
|||
STM STM R14,R12,12(R13) |
|||
ST R13,4(R15) |
|||
ST R15,8(R13) |
|||
LR R13,R15 |
|||
ZAP A,K a=1 |
|||
ZAP PWL8,K |
|||
MP PWL8,K |
|||
DP PWL8,=P'2' |
|||
ZAP PWL8,PWL8(7) |
|||
BAL R14,SQRT |
|||
ZAP G,PWL8 g=sqrt(1/2) |
|||
WHILE1 EQU * while a!=g |
|||
ZAP PWL8,A |
|||
SP PWL8,G |
|||
CP PWL8,=P'0' (a-g)!=0 |
|||
BE EWHILE1 |
|||
ZAP PWL8,A |
|||
AP PWL8,G |
|||
DP PWL8,=P'2' |
|||
ZAP AN,PWL8(7) an=(a+g)/2 |
|||
ZAP PWL8,A |
|||
MP PWL8,G |
|||
BAL R14,SQRT |
|||
ZAP G,PWL8 g=sqrt(a*g) |
|||
ZAP A,AN a=an |
|||
B WHILE1 |
|||
EWHILE1 EQU * |
|||
ZAP PWL8,A |
|||
UNPK ZWL16,PWL8 |
|||
MVC CWL16,ZWL16 |
|||
OI CWL16+15,X'F0' |
|||
MVI CWL16,C'+' |
|||
CP PWL8,=P'0' |
|||
BNM *+8 |
|||
MVI CWL16,C'-' |
|||
MVC CWL80+0(15),CWL16 |
|||
MVC CWL80+9(1),=C'.' /k (15-6=9) |
|||
XPRNT CWL80,80 display a |
|||
L R13,4(0,R13) |
|||
LM R14,R12,12(R13) |
|||
XR R15,R15 |
|||
BR R14 |
|||
DS 0F |
|||
K DC PL8'1000000' 10^6 |
|||
A DS PL8 |
|||
G DS PL8 |
|||
AN DS PL8 |
|||
* ****** SQRT ******************* |
|||
SQRT CNOP 0,4 function sqrt(x) |
|||
ZAP X,PWL8 |
|||
ZAP X0,=P'0' x0=0 |
|||
ZAP X1,=P'1' x1=1 |
|||
WHILE2 EQU * while x0!=x1 |
|||
ZAP PWL8,X0 |
|||
SP PWL8,X1 |
|||
CP PWL8,=P'0' (x0-x1)!=0 |
|||
BE EWHILE2 |
|||
ZAP X0,X1 x0=x1 |
|||
ZAP PWL16,X |
|||
DP PWL16,X1 |
|||
ZAP XW,PWL16(8) xw=x/x1 |
|||
ZAP PWL8,X1 |
|||
AP PWL8,XW |
|||
DP PWL8,=P'2' |
|||
ZAP PWL8,PWL8(7) |
|||
ZAP X2,PWL8 x2=(x1+xw)/2 |
|||
ZAP X1,X2 x1=x2 |
|||
B WHILE2 |
|||
EWHILE2 EQU * |
|||
ZAP PWL8,X1 return x1 |
|||
BR R14 |
|||
DS 0F |
|||
X DS PL8 |
|||
X0 DS PL8 |
|||
X1 DS PL8 |
|||
X2 DS PL8 |
|||
XW DS PL8 |
|||
* end SQRT |
|||
PWL8 DC PL8'0' |
|||
PWL16 DC PL16'0' |
|||
CWL80 DC CL80' ' |
|||
CWL16 DS CL16 |
|||
ZWL16 DS ZL16 |
|||
LTORG |
|||
YREGS |
|||
END AGM</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
+00000000.84721 |
|||
</pre> |
|||
=={{header|8th}}== |
|||
<syntaxhighlight lang="8th">: epsilon 1.0e-12 ; |
|||
with: n |
|||
: iter \ n1 n2 -- n1 n2 |
|||
2dup * sqrt >r + 2 / r> ; |
|||
: agn \ n1 n2 -- n |
|||
repeat iter 2dup epsilon ~= not while! drop ; |
|||
"agn(1, 1/sqrt(2)) = " . 1 1 2 sqrt / agn "%.10f" s:strfmt . cr |
|||
;with |
|||
bye |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
agn(1, 1/sqrt(2)) = 0.8472130848 |
|||
</pre> |
|||
=={{header|Action!}}== |
|||
{{libheader|Action! Tool Kit}} |
|||
{{libheader|Action! Real Math}} |
|||
<syntaxhighlight lang="action!">INCLUDE "H6:REALMATH.ACT" |
|||
PROC Agm(REAL POINTER a0,g0,result) |
|||
REAL a,g,prevA,tmp,r2 |
|||
RealAssign(a0,a) |
|||
RealAssign(g0,g) |
|||
IntToReal(2,r2) |
|||
DO |
|||
RealAssign(a,prevA) |
|||
RealAdd(a,g,tmp) |
|||
RealDiv(tmp,r2,a) |
|||
RealMult(prevA,g,tmp) |
|||
Sqrt(tmp,g) |
|||
IF RealGreaterOrEqual(a,prevA) THEN |
|||
EXIT |
|||
FI |
|||
OD |
|||
RealAssign(a,result) |
|||
RETURN |
|||
PROC Main() |
|||
REAL r1,r2,tmp,g,res |
|||
Put(125) PutE() ;clear screen |
|||
MathInit() |
|||
IntToReal(1,r1) |
|||
IntToReal(2,r2) |
|||
Sqrt(r2,tmp) |
|||
RealDiv(r1,tmp,g) |
|||
Agm(r1,g,res) |
|||
Print("agm(") PrintR(r1) |
|||
Print(",") PrintR(g) |
|||
Print(")=") PrintRE(res) |
|||
RETURN</syntaxhighlight> |
|||
{{out}} |
|||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Arithmetic-geometric_mean.png Screenshot from Atari 8-bit computer] |
|||
<pre> |
|||
agm(1,.7071067873)=.847213085 |
|||
</pre> |
|||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO, Ada.Numerics.Generic_Elementary_Functions; |
||
procedure Arith_Geom_Mean is |
procedure Arith_Geom_Mean is |
||
Line 36: | Line 224: | ||
begin |
begin |
||
N_IO.Put(AGM(1.0, 1.0/Math.Sqrt(2.0)), Fore => 1, Aft => 17, Exp => 0); |
N_IO.Put(AGM(1.0, 1.0/Math.Sqrt(2.0)), Fore => 1, Aft => 17, Exp => 0); |
||
end Arith_Geom_Mean;</ |
end Arith_Geom_Mean;</syntaxhighlight> |
||
Output:<pre>0.84721308479397909</pre> |
Output:<pre>0.84721308479397909</pre> |
||
=={{header| |
=={{header|ALGOL 68}}== |
||
Algol 68 Genie gives IEEE double precision for REAL quantities, 28 decimal digits for LONG REALs and, by default, 63 decimal digits for LONG LONG REAL though this can be made arbitrarily greater with a pragmat. |
|||
<lang cpp>/*Arithmetic Geometric Mean of 1 and 1/sqrt(2) |
|||
Printing out the difference between the means at each iteration nicely demonstrates the quadratic convergence. |
|||
<syntaxhighlight lang="algol68"> |
|||
BEGIN |
|||
PROC agm = (LONG REAL x, y) LONG REAL : |
|||
BEGIN |
|||
IF x < LONG 0.0 OR y < LONG 0.0 THEN -LONG 1.0 |
|||
ELIF x + y = LONG 0.0 THEN LONG 0.0 CO Edge cases CO |
|||
ELSE |
|||
LONG REAL a := x, g := y; |
|||
LONG REAL epsilon := a + g; |
|||
LONG REAL next a := (a + g) / LONG 2.0, next g := long sqrt (a * g); |
|||
LONG REAL next epsilon := ABS (a - g); |
|||
WHILE next epsilon < epsilon |
|||
DO |
|||
print ((epsilon, " ", next epsilon, newline)); |
|||
epsilon := next epsilon; |
|||
a := next a; g := next g; |
|||
next a := (a + g) / LONG 2.0; next g := long sqrt (a * g); |
|||
next epsilon := ABS (a - g) |
|||
OD; |
|||
a |
|||
FI |
|||
END; |
|||
printf (($l(-35,33)l$, agm (LONG 1.0, LONG 1.0 / long sqrt (LONG 2.0)))) |
|||
END |
|||
</syntaxhighlight> |
|||
Output:<pre>+1.707106781186547524400844362e +0 +2.928932188134524755991556379e -1 |
|||
+2.928932188134524755991556379e -1 +1.265697533955921916929670477e -2 |
|||
+1.265697533955921916929670477e -2 +2.363617660269221214237489508e -5 |
|||
+2.363617660269221214237489508e -5 +8.242743980540458935740117000e -11 |
|||
+8.242743980540458935740117000e -11 +1.002445937606580000000000000e -21 |
|||
+1.002445937606580000000000000e -21 +4.595001000000000000000000000e -29 |
|||
+4.595001000000000000000000000e -29 +4.595000000000000000000000000e -29 |
|||
0.847213084793979086606499123550000 |
|||
</pre> |
|||
=={{header|APL}}== |
|||
<syntaxhighlight lang="apl"> |
|||
agd←{(⍺-⍵)<10*¯8:⍺⋄((⍺+⍵)÷2)∇(⍺×⍵)*÷2} |
|||
1 agd ÷2*÷2 |
|||
</syntaxhighlight> |
|||
Output: <pre>0.8472130848</pre> |
|||
=={{header|AppleScript}}== |
|||
By functional composition: |
|||
<syntaxhighlight lang="applescript">-- ARITHMETIC GEOMETRIC MEAN ------------------------------------------------- |
|||
property tolerance : 1.0E-5 |
|||
-- agm :: Num a => a -> a -> a |
|||
on agm(a, g) |
|||
script withinTolerance |
|||
on |λ|(m) |
|||
tell m to ((its an) - (its gn)) < tolerance |
|||
end |λ| |
|||
end script |
|||
script nextRefinement |
|||
on |λ|(m) |
|||
tell m |
|||
set {an, gn} to {its an, its gn} |
|||
{an:(an + gn) / 2, gn:(an * gn) ^ 0.5} |
|||
end tell |
|||
end |λ| |
|||
end script |
|||
an of |until|(withinTolerance, ¬ |
|||
nextRefinement, {an:(a + g) / 2, gn:(a * g) ^ 0.5}) |
|||
end agm |
|||
-- TEST ---------------------------------------------------------------------- |
|||
on run |
|||
agm(1, 1 / (2 ^ 0.5)) |
|||
--> 0.847213084835 |
|||
end run |
|||
-- GENERIC FUNCTIONS --------------------------------------------------------- |
|||
-- until :: (a -> Bool) -> (a -> a) -> a -> a |
|||
on |until|(p, f, x) |
|||
set mp to mReturn(p) |
|||
set v to x |
|||
tell mReturn(f) |
|||
repeat until mp's |λ|(v) |
|||
set v to |λ|(v) |
|||
end repeat |
|||
end tell |
|||
return v |
|||
end |until| |
|||
-- Lift 2nd class handler function into 1st class script wrapper |
|||
-- mReturn :: Handler -> Script |
|||
on mReturn(f) |
|||
if class of f is script then |
|||
f |
|||
else |
|||
script |
|||
property |λ| : f |
|||
end script |
|||
end if |
|||
end mReturn</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>0.847213084835</pre> |
|||
=={{header|Arturo}}== |
|||
<syntaxhighlight lang="arturo">agm: function [a,g][ |
|||
delta: 1e-15 |
|||
[aNew, aOld, gOld]: @[0, a, g] |
|||
while [delta < abs aOld - gOld][ |
|||
aNew: 0.5 * aOld + gOld |
|||
gOld: sqrt aOld * gOld |
|||
aOld: aNew |
|||
] |
|||
return aOld |
|||
] |
|||
print agm 1.0 1.0/sqrt 2.0</lang> |
|||
{{out}} |
|||
<pre>0.8472130847939792</pre> |
|||
=={{header|AutoHotkey}}== |
|||
<syntaxhighlight lang="ahk">agm(a, g, tolerance=1.0e-15){ |
|||
While abs(a-g) > tolerance |
|||
{ |
|||
an := .5 * (a + g) |
|||
g := sqrt(a*g) |
|||
a := an |
|||
} |
|||
return a |
|||
} |
|||
SetFormat, FloatFast, 0.15 |
|||
MsgBox % agm(1, 1/sqrt(2))</syntaxhighlight> |
|||
Output: |
|||
<pre>0.847213084793979</pre> |
|||
=={{header|AWK}}== |
|||
<syntaxhighlight lang="awk">#!/usr/bin/awk -f |
|||
BEGIN { |
|||
printf "%.16g\n", agm(1.0,sqrt(0.5)) |
|||
} |
|||
function agm(a,g) { |
|||
while (1) { |
|||
a0=a |
|||
a=(a0+g)/2 |
|||
g=sqrt(a0*g) |
|||
if (abs(a0-a) < abs(a)*1e-15) break |
|||
} |
|||
return a |
|||
} |
|||
function abs(x) { |
|||
return (x<0 ? -x : x) |
|||
} |
|||
</syntaxhighlight> |
|||
Output |
|||
<pre>0.8472130847939792</pre> |
|||
=={{header|BASIC}}== |
|||
==={{header|ANSI BASIC}}=== |
|||
{{works with|Decimal BASIC}} |
|||
<syntaxhighlight lang="basic">100 PROGRAM ArithmeticGeometricMean |
|||
110 FUNCTION AGM (A, G) |
|||
120 DO |
|||
130 LET TA = (A + G) / 2 |
|||
140 LET G = SQR(A * G) |
|||
150 LET Tmp = A |
|||
160 LET A = TA |
|||
170 LET TA = Tmp |
|||
180 LOOP UNTIL A = TA |
|||
190 LET AGM = A |
|||
200 END FUNCTION |
|||
210 REM ******************** |
|||
220 PRINT AGM(1, 1 / SQR(2)) |
|||
230 END</syntaxhighlight> |
|||
{{out}} |
|||
<pre> .84721308479398 </pre> |
|||
==={{header|Applesoft BASIC}}=== |
|||
Same code as [[#Commodore_BASIC|Commodore BASIC]] |
|||
The [[#BASIC|BASIC]] solution works without any changes. |
|||
==={{header|BASIC256}}=== |
|||
<syntaxhighlight lang="basic256">print AGM(1, 1 / sqr(2)) |
|||
end |
|||
function AGM(a, g) |
|||
Do |
|||
ta = (a + g) / 2 |
|||
g = sqr(a * g) |
|||
x = a |
|||
a = ta |
|||
ta = x |
|||
until a = ta |
|||
return a |
|||
end function</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.84721308479</pre> |
|||
==={{header|BBC BASIC}}=== |
|||
{{works with|BBC BASIC for Windows}} |
|||
<syntaxhighlight lang="bbcbasic"> *FLOAT 64 |
|||
@% = &1010 |
|||
PRINT FNagm(1, 1/SQR(2)) |
|||
END |
|||
DEF FNagm(a,g) |
|||
LOCAL ta |
|||
REPEAT |
|||
ta = a |
|||
a = (a+g)/2 |
|||
g = SQR(ta*g) |
|||
UNTIL a = ta |
|||
= a |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.8472130847939792</pre> |
|||
==={{header|Chipmunk Basic}}=== |
|||
{{works with|Chipmunk Basic|3.6.4}} |
|||
<syntaxhighlight lang="qbasic">10 print agm(1,1/sqr(2)) |
|||
20 end |
|||
100 sub agm(a,g) |
|||
110 do |
|||
120 let ta = (a+g)/2 |
|||
130 let g = sqr(a*g) |
|||
140 let x = a |
|||
150 let a = ta |
|||
160 let ta = x |
|||
170 loop until a = ta |
|||
180 agm = a |
|||
190 end sub</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.847213</pre> |
|||
==={{header|Commodore BASIC}}=== |
|||
<syntaxhighlight lang="commodorebasic">10 A = 1 |
|||
20 G = 1/SQR(2) |
|||
30 GOSUB 100 |
|||
40 PRINT A |
|||
50 END |
|||
100 TA = A |
|||
110 A = (A+G)/2 |
|||
120 G = SQR(TA*G) |
|||
130 IF A<TA THEN 100 |
|||
140 RETURN</syntaxhighlight> |
|||
==={{header|Craft Basic}}=== |
|||
<syntaxhighlight lang="basic">let a = 1 |
|||
let g = 1 / sqrt(2) |
|||
do |
|||
let t = (a + g) / 2 |
|||
let g = sqrt(a * g) |
|||
let x = a |
|||
let a = t |
|||
let t = x |
|||
loopuntil a = t |
|||
print a</syntaxhighlight> |
|||
{{out| Output}} |
|||
<pre>0.85</pre> |
|||
==={{header|FreeBASIC}}=== |
|||
<syntaxhighlight lang="freebasic">' version 16-09-2015 |
|||
' compile with: fbc -s console |
|||
Function agm(a As Double, g As Double) As Double |
|||
Dim As Double t_a |
|||
Do |
|||
t_a = (a + g) / 2 |
|||
g = Sqr(a * g) |
|||
Swap a, t_a |
|||
Loop Until a = t_a |
|||
Return a |
|||
End Function |
|||
' ------=< MAIN >=------ |
|||
Print agm(1, 1 / Sqr(2) ) |
|||
' empty keyboard buffer |
|||
While InKey <> "" : Wend |
|||
Print : Print "hit any key to end program" |
|||
Sleep |
|||
End</syntaxhighlight> |
|||
{{out}} |
|||
<pre> 0.8472130847939792</pre> |
|||
==={{header|Gambas}}=== |
|||
{{trans|FreeBASIC}} |
|||
<syntaxhighlight lang="vbnet">Public Sub Main() |
|||
Print AGM(1, 1 / Sqr(2)) |
|||
End |
|||
Function AGM(a As Float, g As Float) As Float |
|||
Dim t_a As Float |
|||
Do |
|||
t_a = (a + g) / 2 |
|||
g = Sqr(a * g) |
|||
Swap a, t_a |
|||
Loop Until a = t_a |
|||
Return a |
|||
End Function</syntaxhighlight> |
|||
==={{header|GW-BASIC}}=== |
|||
<syntaxhighlight lang="gwbasic">10 A = 1 |
|||
20 G = 1!/SQR(2!) |
|||
30 FOR I=1 TO 20 'twenty iterations is plenty |
|||
40 B = (A+G)/2 |
|||
50 G = SQR(A*G) |
|||
60 A = B |
|||
70 NEXT I |
|||
80 PRINT A</syntaxhighlight> |
|||
==={{header|IS-BASIC}}=== |
|||
<syntaxhighlight lang="is-basic">100 PRINT AGM(1,1/SQR(2)) |
|||
110 DEF AGM(A,G) |
|||
120 DO |
|||
130 LET TA=A |
|||
140 LET A=(A+G)/2:LET G=SQR(TA*G) |
|||
150 LOOP UNTIL A=TA |
|||
160 LET AGM=A |
|||
170 END DEF</syntaxhighlight> |
|||
==={{header|Liberty BASIC}}=== |
|||
{{works with|Just BASIC}} |
|||
<syntaxhighlight lang="lb"> |
|||
print agm(1, 1/sqr(2)) |
|||
print using("#.#################",agm(1, 1/sqr(2))) |
|||
end |
|||
function agm(a,g) |
|||
do |
|||
absdiff = abs(a-g) |
|||
an=(a+g)/2 |
|||
gn=sqr(a*g) |
|||
a=an |
|||
g=gn |
|||
loop while abs(an-gn)< absdiff |
|||
agm = a |
|||
end function |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.84721308 |
|||
0.84721308479397904</pre> |
|||
==={{header|Minimal BASIC}}=== |
|||
{{trans|Commodore BASIC}} |
|||
{{works with|IS-BASIC}} |
|||
<syntaxhighlight lang="qbasic">10 LET A = 1 |
|||
20 LET G = 1 / SQR(2) |
|||
30 GOSUB 60 |
|||
40 PRINT A |
|||
50 STOP |
|||
60 LET T = A |
|||
70 LET A = (A + G) / 2 |
|||
80 LET G = SQR(T * G) |
|||
90 IF A < T THEN 60 |
|||
100 RETURN |
|||
110 END</syntaxhighlight> |
|||
{{out}} |
|||
<pre> .84721308</pre> |
|||
==={{header|MSX Basic}}=== |
|||
{{works with|MSX BASIC|any}} |
|||
The [[#Commodore BASIC|Commodore BASIC]] solution works without any changes. |
|||
The [[#GW-BASIC|GW-BASIC]] solution works without any changes. |
|||
==={{header|PureBasic}}=== |
|||
<syntaxhighlight lang="purebasic">Procedure.d AGM(a.d, g.d, ErrLim.d=1e-15) |
|||
Protected.d ta=a+1, tg |
|||
While ta <> a |
|||
ta=a: tg=g |
|||
a=(ta+tg)*0.5 |
|||
g=Sqr(ta*tg) |
|||
Wend |
|||
ProcedureReturn a |
|||
EndProcedure |
|||
If OpenConsole() |
|||
PrintN(StrD(AGM(1, 1/Sqr(2)), 16)) |
|||
Input() |
|||
CloseConsole() |
|||
EndIf</syntaxhighlight> |
|||
{{out}} |
|||
<pre> 0.8472130847939792</pre> |
|||
==={{header|QuickBASIC}}=== |
|||
{{works with|QBasic}} |
|||
<syntaxhighlight lang="qbasic">PRINT AGM(1, 1 / SQR(2)) |
|||
END |
|||
FUNCTION AGM (a, g) |
|||
DO |
|||
ta = (a + g) / 2 |
|||
g = SQR(a * g) |
|||
SWAP a, ta |
|||
LOOP UNTIL a = ta |
|||
AGM = a |
|||
END FUNCTION</syntaxhighlight> |
|||
{{out}} |
|||
<pre>.8472131</pre> |
|||
==={{header|Quite BASIC}}=== |
|||
{{trans|Commodore BASIC}} |
|||
<syntaxhighlight lang="qbasic">10 LET A = 1 |
|||
20 LET G = 1 / SQR(2) |
|||
30 GOSUB 100 |
|||
40 PRINT A |
|||
50 END |
|||
100 LET T = A |
|||
110 LET A = (A + G) / 2 |
|||
120 LET G = SQR(T * G) |
|||
130 IF A < T THEN 100 |
|||
140 RETURN</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.8472130847939792</pre> |
|||
==={{header|Run BASIC}}=== |
|||
<syntaxhighlight lang="runbasic">print agm(1, 1/sqr(2)) |
|||
print agm(1,1/2^.5) |
|||
print using("#.############################",agm(1, 1/sqr(2))) |
|||
function agm(agm,g) |
|||
while agm |
|||
an = (agm + g)/2 |
|||
gn = sqr(agm*g) |
|||
if abs(agm-g) <= abs(an-gn) then exit while |
|||
agm = an |
|||
g = gn |
|||
wend |
|||
end function</syntaxhighlight>{{out}} |
|||
<pre>0.847213085 |
|||
0.847213085 |
|||
0.8472130847939791165772005376</pre> |
|||
==={{header|Sinclair ZX81 BASIC}}=== |
|||
{{trans|COBOL}} |
|||
Works with 1k of RAM. |
|||
The specification calls for a function. Sadly that is not available to us, so this program uses a subroutine: pass the arguments in the global variables <tt>A</tt> and <tt>G</tt>, and the result will be returned in <tt>AGM</tt>. The performance is quite acceptable. Note that the subroutine clobbers <tt>A</tt> and <tt>G</tt>, so you should save them if you want to use them again. |
|||
Better precision than this is not easily obtainable on the ZX81, unfortunately. |
|||
<syntaxhighlight lang="basic"> 10 LET A=1 |
|||
20 LET G=1/SQR 2 |
|||
30 GOSUB 100 |
|||
40 PRINT AGM |
|||
50 STOP |
|||
100 LET A0=A |
|||
110 LET A=(A+G)/2 |
|||
120 LET G=SQR (A0*G) |
|||
130 IF ABS(A-G)>.00000001 THEN GOTO 100 |
|||
140 LET AGM=A |
|||
150 RETURN</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.84721309</pre> |
|||
==={{header|TI-83 BASIC}}=== |
|||
<syntaxhighlight lang="ti83b">1→A:1/sqrt(2)→G |
|||
While abs(A-G)>e-15 |
|||
(A+G)/2→B |
|||
sqrt(AG)→G:B→A |
|||
End |
|||
A</syntaxhighlight> |
|||
{{out}} |
|||
<pre>.8472130848</pre> |
|||
==={{header|True BASIC}}=== |
|||
{{works with|QBasic}} |
|||
<syntaxhighlight lang="qbasic">FUNCTION AGM (a, g) |
|||
DO |
|||
LET ta = (a + g) / 2 |
|||
LET g = SQR(a * g) |
|||
LET x = a |
|||
LET a = ta |
|||
LET ta = x |
|||
LOOP UNTIL a = ta |
|||
LET AGM = a |
|||
END FUNCTION |
|||
PRINT AGM(1, 1 / SQR(2)) |
|||
END</syntaxhighlight> |
|||
{{out}} |
|||
<pre>.84721308</pre> |
|||
==={{header|VBA}}=== |
|||
<syntaxhighlight lang="vb">Private Function agm(a As Double, g As Double, Optional tolerance As Double = 0.000000000000001) As Double |
|||
Do While Abs(a - g) > tolerance |
|||
tmp = a |
|||
a = (a + g) / 2 |
|||
g = Sqr(tmp * g) |
|||
Debug.Print a |
|||
Loop |
|||
agm = a |
|||
End Function |
|||
Public Sub main() |
|||
Debug.Print agm(1, 1 / Sqr(2)) |
|||
End Sub</syntaxhighlight>{{out}} |
|||
<pre> 0,853553390593274 |
|||
0,847224902923494 |
|||
0,847213084835193 |
|||
0,847213084793979 |
|||
0,847213084793979 </pre> |
|||
==={{header|VBScript}}=== |
|||
{{trans|BBC BASIC}} |
|||
<syntaxhighlight lang="vb">Function agm(a,g) |
|||
Do Until a = tmp_a |
|||
tmp_a = a |
|||
a = (a + g)/2 |
|||
g = Sqr(tmp_a * g) |
|||
Loop |
|||
agm = a |
|||
End Function |
|||
WScript.Echo agm(1,1/Sqr(2))</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>0.847213084793979</pre> |
|||
==={{header|Yabasic}}=== |
|||
<syntaxhighlight lang="vb">print AGM(1, 1 / sqrt(2)) |
|||
end |
|||
sub AGM(a, g) |
|||
repeat |
|||
ta = (a + g) / 2 |
|||
g = sqrt(a * g) |
|||
x = a |
|||
a = ta |
|||
ta = x |
|||
until a = ta |
|||
return a |
|||
end sub</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.847213</pre> |
|||
==={{header|Visual Basic .NET}}=== |
|||
{{trans|C#}} |
|||
====Double, Decimal Versions==== |
|||
<syntaxhighlight lang="vbnet">Imports System.Math |
|||
Imports System.Console |
|||
Module Module1 |
|||
Function CalcAGM(ByVal a As Double, ByVal b As Double) As Double |
|||
Dim c As Double, d As Double = 0, ld As Double = 1 |
|||
While ld <> d : c = a : a = (a + b) / 2 : b = Sqrt(c * b) |
|||
ld = d : d = a - b : End While : Return b |
|||
End Function |
|||
Function DecSqRoot(ByVal v As Decimal) As Decimal |
|||
Dim r As Decimal = CDec(Sqrt(CDbl(v))), t As Decimal = 0, d As Decimal = 0, ld As Decimal = 1 |
|||
While ld <> d : t = v / r : r = (r + t) / 2 |
|||
ld = d : d = t - r : End While : Return t |
|||
End Function |
|||
Function CalcAGM(ByVal a As Decimal, ByVal b As Decimal) As Decimal |
|||
Dim c As Decimal, d As Decimal = 0, ld As Decimal = 1 |
|||
While ld <> d : c = a : a = (a + b) / 2 : b = DecSqRoot(c * b) |
|||
ld = d : d = a - b : End While : Return b |
|||
End Function |
|||
Sub Main(ByVal args As String()) |
|||
WriteLine("Double result: {0}", CalcAGM(1.0, DecSqRoot(0.5))) |
|||
WriteLine("Decimal result: {0}", CalcAGM(1D, DecSqRoot(0.5D))) |
|||
If System.Diagnostics.Debugger.IsAttached Then ReadKey() |
|||
End Sub |
|||
End Module</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Double result: 0.847213084793979 |
|||
Decimal result: 0.8472130847939790866064991235</pre> |
|||
====System.Numerics==== |
|||
{{trans|C#}} |
|||
{{Libheader|System.Numerics}} |
|||
<syntaxhighlight lang="vbnet">Imports System.Math |
|||
Imports System.Console |
|||
Imports BI = System.Numerics.BigInteger |
|||
Module Module1 |
|||
Function BIP(ByVal leadDig As Char, ByVal numDigs As Integer) As BI |
|||
BIP = BI.Parse(leadDig & New String("0"c, numDigs)) |
|||
End Function |
|||
Function IntSqRoot(ByVal v As BI, ByVal res As BI) As BI ' res is the initial guess of the square root |
|||
Dim d As BI = 0, dl As BI = 1 |
|||
While dl <> d : IntSqRoot = v / res : res = (res + IntSqRoot) / 2 |
|||
dl = d : d = IntSqRoot - res : End While |
|||
End Function |
|||
Function CalcByAGM(ByVal digits As Integer) As BI |
|||
Dim a As BI = BIP("1"c, digits), ' value is 1, extended to required number of digits |
|||
c as BI, ' a temporary variable for swapping a and b |
|||
diff As BI = 0, ldiff As BI = 1 ' difference of a and b, last difference |
|||
CalcByAGM = BI.Parse(String.Format("{0:0.00000000000000000}", ' initial value of square root of 0.5 |
|||
Sqrt(0.5)).Substring(2) & New String("0"c, digits - 17)) |
|||
CalcByAGM = IntSqRoot(BIP("5"c, (digits << 1) - 1), CalcByAGM) ' value is now the square root of 0.5 |
|||
While ldiff <> diff : c = a : a = (a + CalcByAGM) >> 1 : CalcByAGM = IntSqRoot(c * CalcByAGM, a) |
|||
ldiff = diff : diff = a - CalcByAGM : End While |
|||
End Function |
|||
Sub Main(ByVal args As String()) |
|||
Dim digits As Integer = 25000 |
|||
If args.Length > 0 Then Integer.TryParse(args(0), digits) : _ |
|||
If digits < 1 OrElse digits > 999999 Then digits = 25000 |
|||
WriteLine("0.{0}", CalcByAGM(digits)) |
|||
If System.Diagnostics.Debugger.IsAttached Then ReadKey() |
|||
End Sub |
|||
End Module</syntaxhighlight> |
|||
{{out}} |
|||
<pre style="height:64ex; overflow:scroll; white-space: pre-wrap;">0.8472130847939790866064991234821916364814459103269421850605793726597340048341347597232002939946112299421222856252334109630979626658308710596997136359833842511763268142890603897067686016166500482811887218977133094117674620199443929629021672891944995072316778973468639476066710579805578521731403493983042004221192160398395535950981936412937163406460295999679705994343516020318426487569502421748638554059819545816017424178878541927588041627190120855876856483268341404312184008040358092045594943138778151209265222545743971242868207663409547336745996217926655353486256861185433086262872872875630108355631935706687147856390889821151088363521476969796126218329432284178681137684451700181460219136940270209459966835135963278808042743454817445873632200251539529362658066141983656164916262596074347237066169023530800173753128478525584306319074542749341526857906552694060031475910203327467196861247963255105546489028208552974396512499400966255286606758044873538921857014011677169765350140849524768489932573213370289846689391946658618737529663875622660459147770442046810892565844083803204091061900315370673411959410100747433105990550582052432600995169279241747821697678106168369771411073927334392155014302200708736736596227214925877619285105238036702689046390962190766364423553808590294523406519001334234510583834171218051425500392370111132541114461262890625413355052664365359582455215629339751825147065013464104705697935568130660632937334503871097709729487591717901581732028157828848714993134081549334236779704471278593761859508514667736455467920161593422399714298407078888227903265675159652843581779572728480835648996350440414073422611018338354697596266333042208499985230074270393027724347497971797326455254654301983169496846109869074390506801376611925291977093844129970701588949316666116199459226501131118396635250253056164643158720845452298877547517727274765672164898291823923889520720764283971088470596035692199292183190154814128076659269829446445714923966632997307581390495762243896242317520950731901842446244237098642728114951118082282605386248461767518014098312749725765198375649235690280021617490553142720815343954059556357637112728165705973733744297003905604015638866307222570038923015911237696012158008177907786335124086243107357158376592650454665278733787444483440631024475703968125545398226643035341641303561380163416557526558975294452116687345122019122746673319157124076375382110696814107692639007483317574339675231966033086497357138387419609898383220288269488219130281936694995442224069727616862136951165783888501219909616065545461154325314816424933269479700415949147632311292059351651899794335004597628821729262591808940550843146639378254833513955019065337087206206402407705607584879649984365159272826453442863661541914258577710675618501727803328717519518930503180550524542602233552290077141812879865435118791800635627959362476826778641224946033812608262825409889531252767753465624327921451122955551603181843313369296172304178385515712556740498341666592696958000895372457305769454227537216020968719147039887846636724326270619112707171659082464004167994112040565710364083000241929439855307399465653967781049270105541035951333943219992506667620207839469555376055179640100974921885631130101781388857879381317209594806253920130098365028791769582798590527994772194179799702494306215841946888532811549772157996019440962347768614408507573928429882375939682322367058033413477462311289762585932437663177897491107726190970448952220450963072551559009382490402136480779203476721504856844602255440999282616317431264228578762898338065072202301037175314926350463106018857377256700661838129058063895450812703131137104371613583348806583395543121790134839883321641305763524471251153947206667033010134871651632411382881763983962952612114126321979596509865678675525076076042409590751752302194610453256433324961490125353332922372386894812788502013596630537605584935892839163046940388785496002747148719780145765957904958580226006609952496736432496683346176010660815670697514238186650361083885220976165500251607311499216129477579019972924868963822060380876027628167237016681910663358577515465038133423672234764202655856558846416010210540489855618711473588497637840648642679818650448631907747038228671143515112300360708657429886477146674733750114345818852797006056211724692174847180694866251199472893444270378304620707354938052872720621560630718828685805645211106967080285699069825769177220998671959968507790681443494932804976811543680463259938693076235070999518295129581121235707245383354826190752395158273098248180549665897909168867984071707793705959045775840910473413109604194111357756620727337797833203797301137672658535747710279781409721309612142393854737462769615041307952837372882050658719152259765084027796991761175393006725492491229845082362975568722711065849435533850494532638736489804606655979954360169503092790092450057856477235876198848986034412195340795369002996411974549060741600978859537660722905160772428590070901156639138364299041220826769629797867649032356499981990765997439870548648769091024911927099968275697011368762244046402960383700066212734577664709711326374656811502985863032260337383421358423937896114617192083071953915643782093641496780334152464507396683173198363362743392555311712019454146844880895622417898031894341231284027858378289009624209541345002101072736323285272576209646851994468240550629391742053301706461917215178844296705314335503772310709716080285145314144106105023117310877779933248932087727229897821330120834074305604998159963202687793307156940302439156118926767517249511766526248547096041991473113657920697330996088897286789780735587578500623575157123771653042063631002703129296694025421967877168846655727580898306467662007014679585693082220620905330827782226503112520278733512519159918893900284319218166686548434879621972211763904959895793607330943697457628943200384117552941594754747183936381144125610351023459581080768558985657007445308909428669251190101718122826689349269528261052518556736045877702288147821446968500918347219741420546128072347950059811766364526150190788545471193803557145930744635656260752787518824386409506964649815131170591457990619376560858650175616864501924098327235724333688813080022186368700209641119724303603558649793773314916749593151188673535025505982303047060284740458456676849620934506396302909441632516408692889814507247877727673378033828929504978384342943766566737297587430575141036417476861639624198941904730996100228428079444920026904845254139188246001559089131943255610365769362364161784646693141456109984038312265504115251494445380042090428718182468431624610552637677520970104063944687837375017436089751693486887651283453677552786547090231542029453873076141196649767521919808902105772633472397958968722923357769041244458682297806209887089816018179521454920370956252850733023255060096611329479148443416687429872654204083552056456404421174124065041932362831296643126330768715450444950733554418200793669701331244638824360062439816712409346806322169771701563590417609841261977801052586956634654144702511135382841010278579543061802357275500930513955637771043922799597114118278203358118398952338720119626666828781215343331193353019800652511924103594315072427251589774226901431325149775220621148653209528291784172678852791825950189428306645453380829438548491390660090152646315666940813051689857738445716110134773528439558663918031477128997248977232695083095920860316390860179422146804892537147135669490647597566350405076105930300153453613446834614136284840473063909580064862482211399539962122107992774053203059756987131501429238941821989218445861496845306346078287058864262560349767113385390753047360747520569725532663517964059488138127648519130232826129551720747594498863925111049785977410104647258831744969489273332281068408949475978706769012216951869658194406136694310323411619613160554381608728305543504819071159752742665917363693001980988797627218662628543311906086034280619151845297823703639898449414417889008602782220998390227472837967411429578924346545640402855167478372538831386154780508035236893583332887355879794886804980971406868936719416711504307402575102269081707385928535837390976424975922421061832372517021428320986753744507133218963666908565634963306077455683011837149400258404997766113525532847665618870592978212729899729592794781820428719807102278646183807006401083138975677112754136221127444534535584959769252575758312999039536959893249951324106784265611556743660088737484274038234811784911002123537108015334407708175281579422928548731689863980071896268684985779061942582000173178473797975815609269087287850270024414741281953578873964745859459899535543412801653553049058528794674398220606230386688852700505218904927782197514115595435549125326115087432280435609563176116321811794164884206928474315699133677787956913705592704959893911100786224112449931719539890308215307126971807352814294437374058180589784287101566325873726600012296180403780429093175160473979931236882466314524590792512088916974765430245705320638670468411054034201437664442213212750799846299157010147106552946146746392249574530619682203425444816247545977269653430250686824205288099692448923652171403817749282935917315481284919621433304080904306867233682060716291289398517406255904282247558159509102324206160816363511440953267967974466214658121897383725705201831800678505181233270743236051760236565304605919728246762046497950757124332306210615236617229324468286251110577832854712371857906482302429199129753477340618812393224405123793229248698239302094605799468502209356458018864737205798950819968285087908120645175464792846657029993496146354533816989879012073959534299458051884682918835631136138879631316173442207506218212945047503433730640140356614106403320867621443183928438969994268286836082535591242751488383392264668222963323657488981599104902374571278077062853236895690028469742954774248422335523859049299225453318270693966088603518491166875108552006265340966412611220069290556369052744064893640087015171662929356529921474420793873710647399136453402185931518201576110059405556600166318190916348212818643068418256991194316266715898588673650488980580832972145195811525832974358064432698289209364284959616975339927502383832695801109608954786457256109785378297307074918168744735731189049849490781632210127110919398357638892753131749978321368280932894349330930087868884127092076359007648065118301317440813138170776478562086983456849957696333241556699085937149528437303782174166781012624737754844959408277598042857813775448446192929537153359741871355556678028606484917974827559022377376189703770332489774349235376523557139076431488967144133099539679871046284747721772185865851985971282165739148574494328320308464163956096301047370473988450307936956928683464113764226308568695688152053749196294562881085987015910764955019272667378276517237450013662421051146709184898952269727656206976263055094938932099216377529415335060027109430018977339221845390337351007942764665232509045377940478212355620488638969640291029182673024368888013982750049655688955540362739754118359277009094291839958396298535952123465573707751680432023872401008786292362558484920221296055948232317635214207117650427699747801290249150914873347204981208353486521246233538858471700470120592394582541522312967601307268280232044633644234100026474341568399123881048049819491200940244895720301881220640996997340843736095812449945913231793359333819197360248853375641030435643732302001328359990615298394916710687997693926699033522064083729586994304357670917169796698442332656830732550000321312902706719106342428311390049478179307304556219943912072209495471916547109605404919944186051724981471812994063119290173738101176617356976495636675620278895592099504686163440305250658681735840269428736633431167832903837475658050990783985384926064721246565130660487673608585790218386643241627198210378772796337736742692945663985470529377745854692207002046330357343505517537014050310355526578082729897049230547545589009275410944504014157125357682801074915174627928533783099570631952876838237806368177841661186334747789420166190186143388804514884174361681454810362321037643274595653364629397295294049952661691181657740018116146497654407589150912557599100855273107733703213603505619407350405223414533224306604743600257212590127202517146952605462439215815151732661454812243619860357386922465403688559787750083268386930674253759349376972691382532780570135683441862315010318955128705494038594760949278590520009881447715839714713971813720554960331191642239195313230213875992717401904622413925914800620171561815889352945121978193704745708538695427900233080410588007250947512318930796844637224171170594606197614751977323896101315556406372309310279476973938229476346893933755946893665094049910252612163538072005644241026471164639800490998535570282059396054554479255558624918709232180130454102936332893619326596350851413637207293142767763267817840066780089558654877782630822818446508158509625695020697797889664140551101421185533444015948880284701657904464926309216120238068566472631611326995533585414320547442896728173291714010643730593960222482733969720865809194288803963344344876467583385597351333330628439786357062196382217705500672607607570202305548328439335937369624085404957344415141889143812206076832329063384332685935928226648361622876815670931303789678327741487845287838232474038340893449427806045589018183673133602271167285304427194507315740913600066356089181219040305019319028163972135790696025211929562455952835850442627787993214468221041325612271290302469610374855134599106662606082143546126463790846952338680559237822828610361386416013753920426888371192602742087474507782730180882648297991489233434653363930327991816476995529468892904060335470265188317825821391915073117022336839564945335630414192442838503954209073337511117053790819768061378846157004292392264788138228486672543415580694421193506836000488465561599083339184724263183698928130695654949153165010313216361224018298711517222401523368101476246169896417259748838727189598765602350324828709741468793415378708814573190327920453219231685852735108372055942456601545647944675449566859142997988233179819059574125368681032194798082603876241044848730208905065871934264174092007936669883601462309762759844113071525758916288010581709353072588887654386253201848624931923638568216562603110434528313030704972291334873033240933736956347974889824930017415805659182123288343858101250171537305398462043432455721482088547523494730467761429282915391485852688505423074450548192619166975975031503447208211845313907683486006908772752077246485706597636740936173143436990399498908375710246545650814962015988805204483379491707040848303909417512426275869868668644293498242419667403627076032399201407183071270759837132000712447159523642782162488472933913713634046138974088894178399320090051543608421618891328957740354384456107645016010462709579098652495342014766016330458293537653454523438667413798731255017029554582809547897542497367109038598264606895622241257303208140890607025206140457815282368504505765710043804228592032720729190222134651835930255942940875306994701101153416476785623543575023993736414532895773499876167502240919794121893188059017977444329403624038551082491954751841177014150820554999148803286500065069030165028455616533514890711974194172310029663247936640825364542104897640445108081123906368188594908660418340025631562661211506365309297219580687177632051461355581309500814563826112416521487163593643553646268872746276680368630680088231249970572706496265335285424273723449757482776061300818063419639083097882249478922949525891665782610044424440110326748539620120023397129834624242363283711074267309902126029110038109050751840523266273905031934856015485510632624318778970878895198168073096354223096005536267735905099473408744371024816727970009494589707630185344952680106730984246828848883760016695887137355969244555238536396178788134209309376484848406842940499731494663578455826688245825356635393289729316700066238128368519670627697889769929009597838069557440769080950069594659578325366066060213000525012998145215099629307110700615796004759918829827472751877492472674770755413679265775060149528336859838085353420874215682758801259992855903410097963019943741001394975591822918846705741010634931594527954742032057295356596869586863097328488381174243827058441735659667485315202886191192125286398739560928127513223214119754229343092375569339614672740517569529376699061052365448344078610425576694541873486379356070861240473688356773437140126350120823765176390562050604076894729400293162079760342896846897639867830553941515230713725560502914671175123451932131962571791940911728951123948113598860588062424037835751996487088330150679210175429060531418836978611027896830689666851868410470182364780700615529883149883111601949965815038674390467105247175993726709203381051984777006122752302698038537619917731907133105816779008651480172440446403764720673784583395382889380902941273987910475254258486561698048543296782281040453997661165123290729161619992628751086519341731116513305659182981762584769428708454819029344222186027977405519291266188948708010515922860149238393490889782166965109499761673179583522105791358724355029782111425280584380959770472177893827382916471882671437865821461326011263516554280516418422188264141890686619186492751718984735037496602686033671961304915922609442146773092074476794711917820209913226872184947548378003848726148872742881265579174794634151444545105599464567614478293387968015412886418098284885525959617399177657635267081989985408930744564199296902459275405143647525648661932959903068323866757518479741015342911416508753572892479684280248440220211898390243430190746592470563991910024225814399068391457857458095344096826158489731615822039837691005171654390590093326827586419753439483771905973079465029210363641972615923872187876095687197681934481955852567024141433671590889694204781798936556351775101591005026585947279448642317311892727153525046034081896227383114600546852406398855471859684088277722162250586368419379964112646321070639818773794369650252104438622320671517228411475433482803041707675438555447584321271846396281391925884972509051040944134450429845346071848875654240709690138592611645519676563708429710676494635766201285381926791204110977805857352062737510466943591592074904378966129808716274322385039032007477854211063899544954185997641428116395197239708078986048758264126544825149923227286176571389697334537835963603962709038002668921324389159009375225033651171937770657226295341257068980907793198879997076783263303670667342657925395849950582363998610492878479976185891384024744790742355981796013254960652684988733518397287191251899388324341602608356164496670902390042273216221931567939944001215159910054381084520081133103207553492484487369268314444466610780275891777468369344585045949963237156043800258227618908603074550819931892899703285549507330240121766349515315827830897786432254556221744305752825143708087184314470811004510108612122699931396969361066523608721126359012344828262284427191281973187269761974740398071778378188160519801862257232970224762494767912932684020188061795236229174601398576604233579094407723017353015337974435643738584248250538061547193075224429309117207447677149522141919390974201716026970557825836923707297811545552570788004955666915477901830719591663516687057984336951611189153751912396714116378197000784953115386326766369269172016978409040396969804861828436417776804088449208439901095951205751340861060375353408155737087188313898337656322533650946010308686111901241541794900659835366926383515058402026098259570385429145865025692157987309807064597082326377138235585737704225628144262793497769429358804020882742028263786443615935817930817858306265712263479452174065216410798029333573961137404301928294367884626832432449078812684787281988676202931062510264948586549463964789154366240635570346688477784815271412470430646040615614277320107003575855033995279377529716156628381118518085523414187577256025217995103662771477552291036839539792329375184700131215428652464111526297830742328651189481978920924682746392250346179819781021313400022272303222234731521016033826145645816472110340883197207109422849637006090510260943044730126801795349152894613046101033061811314821366141874985466628809585678299308824993966655499624380015821082410781190328189506855057581990908848597095494573176672201417764187253816862426293852974092626551536758155537683368451820154793964862810533857810979434793077956125541240828563089647076354827276586047900779183041806574320855302776686899978897939486987950729652971448050889517660684386673056662911929857913206598752762097197279390208473846210277152094212386266930256260451209117402079233658157593274696841906354187366092529138116574357045728290417433832596884391356956442617823006949118156994294295529170211353842468704890572313005646106202029653246628477843902025194715815133791174898257040115532858624973690714844800747184719290671002133191274834310662201874141841328708920709275866745037664169280121112867057832132585948539987132879098472640550013972043153470930436509718084070853723316111111611632600262171748813737621046013600544051850633175245231989785291065646466038278748870331134307620041356514295482843502245454400571392386492526283423907951705366640483826875013469850263767974528926285288366544314868036628329638912254207094687335597669512007687507292940623176435604796651807847095408991068514998003358735387989422028901542800717906482276185298683079286137204396993726503610285463352157718364571843381950031926272352293654343387522809514152498052577486366048613580539162662183475105825647260311633442002377527140625112075332294909525522330744664115572260242435895269482927435844022622001466247093866533879048392320516224276433339282642640953964341822416705658461244760448817737705782669080880834418822622611342632727419248415651121035047131961583094994438779439078380664656207143187309895280874153167621657602227990850199615587578332393883365169478142077533262283694526612005465820771400826060398839255150948861553177333447506822679211849690448880479070102043288205874672361672971246062341973369704807867768609989464712379097525706498042381815865399434983035941162258347729020489356838477197804973214911448748749915616679253857438010864500220134843719609727912761136925035123155282535741655826107266099467657016111855684257826878422197833994329148734893923892153298966294232703135845615804723993624827409373966761563257981994036006655039613941881183164267144485664874468348587099434743710128859267552473831462181434321232124758618476925803128913233878664527525204324484796532776273320171351979849530142473805976430318655810403609897537469226336015596525652284888167037460054235043655813438329870872734142062859147847007274999414885129441657918212383876056572545671794085637289277002790218604788423519924573051811976377731594412994393860534559159658127123862955315918182841923881357245009246238507097741891437575676886206936433608263660374355173185026954239766173038826275043838965247160428689739548061640664606565379050539422795708801840829664956978192406737307076253014257542221763860230431809477056758905681723033326311408802886092880151777469082375063137750925275331638009836786645991949881018108222446858443984865972449621097999331605268587810061927125889694400669979755648800940895626242917531834388920035663113368763931463847812763130237825562198311791061780856687903309789539747505239545316630638169559777653347655949908779202359718666623572487055558216484036084925217803431104356647417600193631613474196113126657206064282217690428541246560204561459484317744683213906021267727411189443675804442911583757423572500214191467493342871160840582639470485636370375679604797073490813681083838562113841391587052553615073991983125473434527404596547926972539542447555990332809716643578039646945749813368621152410490288581779206318208255069166455507840899628333174744873951607229399258854694188637978240144635295264982572856632103053550891057171748674115218494774077589151115819489068851971959768129214023511454382738867557288320426608338030759515727545577639726238470674634011626346953231815229549718996906470438903536574430644436472716449550868519871817092814068746449470806856174570885105064766494332205391085097539987897980672278869943134632799032372604933150163386774039430519493297142505321117669011820293604482694166301309801111227443654953271242388534939973277749999335296667138307969441135719079969506099821923206878892624416110175909254904610286553512032488285673735148429324009831633211264460376172046209384270528903772251057643968938983722779640468452705694321085455273829462711022737243290606294601651732654594463569861350966095209962038508010899673666470073918705760679801337058347046567503369379598928154437380765511031719081985901371088639600700705631873099251480947989238619052479230983309717938226245725600119571130722386790431255742179135633111146646083268382596762356018472772209198013121983224179079476134977421748168833934278876403014334318798493417716613256506422668264638388429786875443810986754386459491846082078633346046469418429778813833857755519670005669840456587642130852057050148314568259387702428619224671173187370822224627538313365937868201435535126600146246249435880806572693573084485615073901842761167215162204840459913839674251648</pre> |
|||
==={{header|ZX Spectrum Basic}}=== |
|||
{{trans|ERRE}} |
|||
<syntaxhighlight lang="zxbasic">10 LET a=1: LET g=1/SQR 2 |
|||
20 LET ta=a |
|||
30 LET a=(a+g)/2 |
|||
40 LET g=SQR (ta*g) |
|||
50 IF a<ta THEN GO TO 20 |
|||
60 PRINT a |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.84721309</pre> |
|||
=={{header|bc}}== |
|||
<syntaxhighlight lang="bc">/* Calculate the arithmethic-geometric mean of two positive |
|||
* numbers x and y. |
|||
* Result will have d digits after the decimal point. |
|||
*/ |
|||
define m(x, y, d) { |
|||
auto a, g, o |
|||
o = scale |
|||
scale = d |
|||
d = 1 / 10 ^ d |
|||
a = (x + y) / 2 |
|||
g = sqrt(x * y) |
|||
while ((a - g) > d) { |
|||
x = (a + g) / 2 |
|||
g = sqrt(a * g) |
|||
a = x |
|||
} |
|||
scale = o |
|||
return(a) |
|||
} |
|||
scale = 20 |
|||
m(1, 1 / sqrt(2), 20)</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>.84721308479397908659</pre> |
|||
=={{header|BQN}}== |
|||
<syntaxhighlight lang="bqn">AGM ← { |
|||
(|𝕨-𝕩) ≤ 1e¯15? 𝕨; |
|||
(0.5×𝕨+𝕩) 𝕊 √𝕨×𝕩 |
|||
} |
|||
1 AGM 1÷√2</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.8472130847939792</pre> |
|||
=={{header|C}}== |
|||
===Basic=== |
|||
<syntaxhighlight lang="c">#include<math.h> |
|||
#include<stdio.h> |
|||
#include<stdlib.h> |
|||
double agm( double a, double g ) { |
|||
/* arithmetic-geometric mean */ |
|||
double iota = 1.0E-16; |
|||
double a1, g1; |
|||
if( a*g < 0.0 ) { |
|||
printf( "arithmetic-geometric mean undefined when x*y<0\n" ); |
|||
exit(1); |
|||
} |
|||
while( fabs(a-g)>iota ) { |
|||
a1 = (a + g) / 2.0; |
|||
g1 = sqrt(a * g); |
|||
a = a1; |
|||
g = g1; |
|||
} |
|||
return a; |
|||
} |
|||
int main( void ) { |
|||
double x, y; |
|||
printf( "Enter two numbers: " ); |
|||
scanf( "%lf%lf", &x, &y ); |
|||
printf( "The arithmetic-geometric mean is %lf\n", agm(x, y) ); |
|||
return 0; |
|||
} |
|||
</syntaxhighlight> |
|||
Original output: |
|||
<pre> |
|||
Enter two numbers: 1.0 2.0 |
|||
The arithmetic-geometric mean is 1.456791 |
|||
</pre> |
|||
Task output, the second input (0.707) is 1/sqrt(2) correct to 3 decimal places: |
|||
<pre> |
|||
Enter two numbers: 1 0.707 |
|||
The arithmetic-geometric mean is 0.847155 |
|||
</pre> |
|||
===GMP=== |
|||
<syntaxhighlight lang="cpp">/*Arithmetic Geometric Mean of 1 and 1/sqrt(2) |
|||
Nigel_Galloway |
Nigel_Galloway |
||
Line 74: | Line 1,005: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
The first couple of iterations produces: |
The first couple of iterations produces: |
||
Line 88: | Line 1,019: | ||
The limit (19,740) is imposed by the accuracy (65568). Using 6 iterations would produce a less accurate result. At 7 iterations increasing the 65568 would mean we already have 38,000 or so digits accurate. |
The limit (19,740) is imposed by the accuracy (65568). Using 6 iterations would produce a less accurate result. At 7 iterations increasing the 65568 would mean we already have 38,000 or so digits accurate. |
||
=={{header|C sharp|C#}}== |
|||
<syntaxhighlight lang="csharp">namespace RosettaCode.ArithmeticGeometricMean |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Globalization; |
|||
internal static class Program |
|||
{ |
|||
private static double ArithmeticGeometricMean(double number, |
|||
double otherNumber, |
|||
IEqualityComparer<double> |
|||
comparer) |
|||
{ |
|||
return comparer.Equals(number, otherNumber) |
|||
? number |
|||
: ArithmeticGeometricMean( |
|||
ArithmeticMean(number, otherNumber), |
|||
GeometricMean(number, otherNumber), comparer); |
|||
} |
|||
private static double ArithmeticMean(double number, double otherNumber) |
|||
{ |
|||
return 0.5 * (number + otherNumber); |
|||
} |
|||
private static double GeometricMean(double number, double otherNumber) |
|||
{ |
|||
return Math.Sqrt(number * otherNumber); |
|||
} |
|||
private static void Main() |
|||
{ |
|||
Console.WriteLine( |
|||
ArithmeticGeometricMean(1, 0.5 * Math.Sqrt(2), |
|||
new RelativeDifferenceComparer(1e-5)). |
|||
ToString(CultureInfo.InvariantCulture)); |
|||
} |
|||
private class RelativeDifferenceComparer : IEqualityComparer<double> |
|||
{ |
|||
private readonly double _maximumRelativeDifference; |
|||
internal RelativeDifferenceComparer(double maximumRelativeDifference) |
|||
{ |
|||
_maximumRelativeDifference = maximumRelativeDifference; |
|||
} |
|||
public bool Equals(double number, double otherNumber) |
|||
{ |
|||
return RelativeDifference(number, otherNumber) <= |
|||
_maximumRelativeDifference; |
|||
} |
|||
public int GetHashCode(double number) |
|||
{ |
|||
return number.GetHashCode(); |
|||
} |
|||
private static double RelativeDifference(double number, |
|||
double otherNumber) |
|||
{ |
|||
return AbsoluteDifference(number, otherNumber) / |
|||
Norm(number, otherNumber); |
|||
} |
|||
private static double AbsoluteDifference(double number, |
|||
double otherNumber) |
|||
{ |
|||
return Math.Abs(number - otherNumber); |
|||
} |
|||
private static double Norm(double number, double otherNumber) |
|||
{ |
|||
return 0.5 * (Math.Abs(number) + Math.Abs(otherNumber)); |
|||
} |
|||
} |
|||
} |
|||
}</syntaxhighlight> |
|||
Output: |
|||
<pre>0.847213084835193</pre> |
|||
Note that the last 5 digits are spurious, as ''maximumRelativeDifference'' was only specified to be 1e-5. Using 1e-11 instead will give the result 0.847213084793979, which is as far as ''double'' can take it. |
|||
===Using Decimal Type=== |
|||
<syntaxhighlight lang="csharp">using System; |
|||
class Program { |
|||
static Decimal DecSqRoot(Decimal v) { |
|||
Decimal r = (Decimal)Math.Sqrt((double)v), t = 0, d = 0, ld = 1; |
|||
while (ld != d) { t = v / r; r = (r + t) / 2; |
|||
ld = d; d = t - r; } return t; } |
|||
static Decimal CalcAGM(Decimal a, Decimal b) { |
|||
Decimal c, d = 0, ld = 1; while (ld != d) { ld = d; c = a; |
|||
d = (a = (a + b) / 2) - (b = DecSqRoot(c * b)); } return b; } |
|||
static void Main(string[] args) { |
|||
Console.WriteLine(CalcAGM(1M, DecSqRoot(0.5M))); |
|||
if (System.Diagnostics.Debugger.IsAttached) Console.ReadKey(); |
|||
} |
|||
}</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>0.8472130847939790866064991235</pre> |
|||
===C# with System.Numerics=== |
|||
{{Libheader|System.Numerics}} |
|||
Even though the System.Numerics library directly supports only '''BigInteger''' (and not big rationals or big floating point numbers), it can be coerced into making this calculation. One just has to keep track of the decimal place and multiply by a very large constant. |
|||
<syntaxhighlight lang="csharp">using static System.Math; |
|||
using static System.Console; |
|||
using BI = System.Numerics.BigInteger; |
|||
class Program { |
|||
static BI BIP(char leadDig, int numDigs) { // makes big constant |
|||
return BI.Parse(leadDig + new string('0', numDigs)); } |
|||
static BI IntSqRoot(BI v, BI res) { // res is the initial guess |
|||
BI term = 0, d = 0, dl = 1; while (dl != d) { term = v / res; res = (res + term) >> 1; |
|||
dl = d; d = term - res; } return term; } |
|||
static BI CalcByAGM(int digs) { // note: a and b are hard-coded for this RC task |
|||
BI a = BIP('1', digs), // value of 1, extended to required number of digits |
|||
b = BI.Parse(string.Format("{0:0.00000000000000000}", Sqrt(0.5)).Substring(2) + |
|||
new string('0', digs - 17)), // initial guess for square root of 0.5 |
|||
c, // temporary variable to swap a and b |
|||
diff = 0, ldiff = 1; // difference of a and b, last difference |
|||
b = IntSqRoot(BIP('5', (digs << 1) - 1), b); // value of square root of 0.5 |
|||
while (ldiff != diff) { ldiff = diff; c = a; a = (a + b) >> 1; |
|||
diff = a - (b = IntSqRoot(c * b, a)); } return b; } |
|||
static void Main(string[] args) { |
|||
int digits = 25000; if (args.Length > 0) { |
|||
int.TryParse(args[0], out digits); |
|||
if (digits < 1 || digits > 999999) digits = 25000; } |
|||
WriteLine("0.{0}", CalcByAGM(digits)); |
|||
if (System.Diagnostics.Debugger.IsAttached) ReadKey(); } |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre style="height:64ex; overflow:scroll; white-space:pre-wrap;">0.8472130847939790866064991234821916364814459103269421850605793726597340048341347597232002939946112299421222856252334109630979626658308710596997136359833842511763268142890603897067686016166500482811887218977133094117674620199443929629021672891944995072316778973468639476066710579805578521731403493983042004221192160398395535950981936412937163406460295999679705994343516020318426487569502421748638554059819545816017424178878541927588041627190120855876856483268341404312184008040358092045594943138778151209265222545743971242868207663409547336745996217926655353486256861185433086262872872875630108355631935706687147856390889821151088363521476969796126218329432284178681137684451700181460219136940270209459966835135963278808042743454817445873632200251539529362658066141983656164916262596074347237066169023530800173753128478525584306319074542749341526857906552694060031475910203327467196861247963255105546489028208552974396512499400966255286606758044873538921857014011677169765350140849524768489932573213370289846689391946658618737529663875622660459147770442046810892565844083803204091061900315370673411959410100747433105990550582052432600995169279241747821697678106168369771411073927334392155014302200708736736596227214925877619285105238036702689046390962190766364423553808590294523406519001334234510583834171218051425500392370111132541114461262890625413355052664365359582455215629339751825147065013464104705697935568130660632937334503871097709729487591717901581732028157828848714993134081549334236779704471278593761859508514667736455467920161593422399714298407078888227903265675159652843581779572728480835648996350440414073422611018338354697596266333042208499985230074270393027724347497971797326455254654301983169496846109869074390506801376611925291977093844129970701588949316666116199459226501131118396635250253056164643158720845452298877547517727274765672164898291823923889520720764283971088470596035692199292183190154814128076659269829446445714923966632997307581390495762243896242317520950731901842446244237098642728114951118082282605386248461767518014098312749725765198375649235690280021617490553142720815343954059556357637112728165705973733744297003905604015638866307222570038923015911237696012158008177907786335124086243107357158376592650454665278733787444483440631024475703968125545398226643035341641303561380163416557526558975294452116687345122019122746673319157124076375382110696814107692639007483317574339675231966033086497357138387419609898383220288269488219130281936694995442224069727616862136951165783888501219909616065545461154325314816424933269479700415949147632311292059351651899794335004597628821729262591808940550843146639378254833513955019065337087206206402407705607584879649984365159272826453442863661541914258577710675618501727803328717519518930503180550524542602233552290077141812879865435118791800635627959362476826778641224946033812608262825409889531252767753465624327921451122955551603181843313369296172304178385515712556740498341666592696958000895372457305769454227537216020968719147039887846636724326270619112707171659082464004167994112040565710364083000241929439855307399465653967781049270105541035951333943219992506667620207839469555376055179640100974921885631130101781388857879381317209594806253920130098365028791769582798590527994772194179799702494306215841946888532811549772157996019440962347768614408507573928429882375939682322367058033413477462311289762585932437663177897491107726190970448952220450963072551559009382490402136480779203476721504856844602255440999282616317431264228578762898338065072202301037175314926350463106018857377256700661838129058063895450812703131137104371613583348806583395543121790134839883321641305763524471251153947206667033010134871651632411382881763983962952612114126321979596509865678675525076076042409590751752302194610453256433324961490125353332922372386894812788502013596630537605584935892839163046940388785496002747148719780145765957904958580226006609952496736432496683346176010660815670697514238186650361083885220976165500251607311499216129477579019972924868963822060380876027628167237016681910663358577515465038133423672234764202655856558846416010210540489855618711473588497637840648642679818650448631907747038228671143515112300360708657429886477146674733750114345818852797006056211724692174847180694866251199472893444270378304620707354938052872720621560630718828685805645211106967080285699069825769177220998671959968507790681443494932804976811543680463259938693076235070999518295129581121235707245383354826190752395158273098248180549665897909168867984071707793705959045775840910473413109604194111357756620727337797833203797301137672658535747710279781409721309612142393854737462769615041307952837372882050658719152259765084027796991761175393006725492491229845082362975568722711065849435533850494532638736489804606655979954360169503092790092450057856477235876198848986034412195340795369002996411974549060741600978859537660722905160772428590070901156639138364299041220826769629797867649032356499981990765997439870548648769091024911927099968275697011368762244046402960383700066212734577664709711326374656811502985863032260337383421358423937896114617192083071953915643782093641496780334152464507396683173198363362743392555311712019454146844880895622417898031894341231284027858378289009624209541345002101072736323285272576209646851994468240550629391742053301706461917215178844296705314335503772310709716080285145314144106105023117310877779933248932087727229897821330120834074305604998159963202687793307156940302439156118926767517249511766526248547096041991473113657920697330996088897286789780735587578500623575157123771653042063631002703129296694025421967877168846655727580898306467662007014679585693082220620905330827782226503112520278733512519159918893900284319218166686548434879621972211763904959895793607330943697457628943200384117552941594754747183936381144125610351023459581080768558985657007445308909428669251190101718122826689349269528261052518556736045877702288147821446968500918347219741420546128072347950059811766364526150190788545471193803557145930744635656260752787518824386409506964649815131170591457990619376560858650175616864501924098327235724333688813080022186368700209641119724303603558649793773314916749593151188673535025505982303047060284740458456676849620934506396302909441632516408692889814507247877727673378033828929504978384342943766566737297587430575141036417476861639624198941904730996100228428079444920026904845254139188246001559089131943255610365769362364161784646693141456109984038312265504115251494445380042090428718182468431624610552637677520970104063944687837375017436089751693486887651283453677552786547090231542029453873076141196649767521919808902105772633472397958968722923357769041244458682297806209887089816018179521454920370956252850733023255060096611329479148443416687429872654204083552056456404421174124065041932362831296643126330768715450444950733554418200793669701331244638824360062439816712409346806322169771701563590417609841261977801052586956634654144702511135382841010278579543061802357275500930513955637771043922799597114118278203358118398952338720119626666828781215343331193353019800652511924103594315072427251589774226901431325149775220621148653209528291784172678852791825950189428306645453380829438548491390660090152646315666940813051689857738445716110134773528439558663918031477128997248977232695083095920860316390860179422146804892537147135669490647597566350405076105930300153453613446834614136284840473063909580064862482211399539962122107992774053203059756987131501429238941821989218445861496845306346078287058864262560349767113385390753047360747520569725532663517964059488138127648519130232826129551720747594498863925111049785977410104647258831744969489273332281068408949475978706769012216951869658194406136694310323411619613160554381608728305543504819071159752742665917363693001980988797627218662628543311906086034280619151845297823703639898449414417889008602782220998390227472837967411429578924346545640402855167478372538831386154780508035236893583332887355879794886804980971406868936719416711504307402575102269081707385928535837390976424975922421061832372517021428320986753744507133218963666908565634963306077455683011837149400258404997766113525532847665618870592978212729899729592794781820428719807102278646183807006401083138975677112754136221127444534535584959769252575758312999039536959893249951324106784265611556743660088737484274038234811784911002123537108015334407708175281579422928548731689863980071896268684985779061942582000173178473797975815609269087287850270024414741281953578873964745859459899535543412801653553049058528794674398220606230386688852700505218904927782197514115595435549125326115087432280435609563176116321811794164884206928474315699133677787956913705592704959893911100786224112449931719539890308215307126971807352814294437374058180589784287101566325873726600012296180403780429093175160473979931236882466314524590792512088916974765430245705320638670468411054034201437664442213212750799846299157010147106552946146746392249574530619682203425444816247545977269653430250686824205288099692448923652171403817749282935917315481284919621433304080904306867233682060716291289398517406255904282247558159509102324206160816363511440953267967974466214658121897383725705201831800678505181233270743236051760236565304605919728246762046497950757124332306210615236617229324468286251110577832854712371857906482302429199129753477340618812393224405123793229248698239302094605799468502209356458018864737205798950819968285087908120645175464792846657029993496146354533816989879012073959534299458051884682918835631136138879631316173442207506218212945047503433730640140356614106403320867621443183928438969994268286836082535591242751488383392264668222963323657488981599104902374571278077062853236895690028469742954774248422335523859049299225453318270693966088603518491166875108552006265340966412611220069290556369052744064893640087015171662929356529921474420793873710647399136453402185931518201576110059405556600166318190916348212818643068418256991194316266715898588673650488980580832972145195811525832974358064432698289209364284959616975339927502383832695801109608954786457256109785378297307074918168744735731189049849490781632210127110919398357638892753131749978321368280932894349330930087868884127092076359007648065118301317440813138170776478562086983456849957696333241556699085937149528437303782174166781012624737754844959408277598042857813775448446192929537153359741871355556678028606484917974827559022377376189703770332489774349235376523557139076431488967144133099539679871046284747721772185865851985971282165739148574494328320308464163956096301047370473988450307936956928683464113764226308568695688152053749196294562881085987015910764955019272667378276517237450013662421051146709184898952269727656206976263055094938932099216377529415335060027109430018977339221845390337351007942764665232509045377940478212355620488638969640291029182673024368888013982750049655688955540362739754118359277009094291839958396298535952123465573707751680432023872401008786292362558484920221296055948232317635214207117650427699747801290249150914873347204981208353486521246233538858471700470120592394582541522312967601307268280232044633644234100026474341568399123881048049819491200940244895720301881220640996997340843736095812449945913231793359333819197360248853375641030435643732302001328359990615298394916710687997693926699033522064083729586994304357670917169796698442332656830732550000321312902706719106342428311390049478179307304556219943912072209495471916547109605404919944186051724981471812994063119290173738101176617356976495636675620278895592099504686163440305250658681735840269428736633431167832903837475658050990783985384926064721246565130660487673608585790218386643241627198210378772796337736742692945663985470529377745854692207002046330357343505517537014050310355526578082729897049230547545589009275410944504014157125357682801074915174627928533783099570631952876838237806368177841661186334747789420166190186143388804514884174361681454810362321037643274595653364629397295294049952661691181657740018116146497654407589150912557599100855273107733703213603505619407350405223414533224306604743600257212590127202517146952605462439215815151732661454812243619860357386922465403688559787750083268386930674253759349376972691382532780570135683441862315010318955128705494038594760949278590520009881447715839714713971813720554960331191642239195313230213875992717401904622413925914800620171561815889352945121978193704745708538695427900233080410588007250947512318930796844637224171170594606197614751977323896101315556406372309310279476973938229476346893933755946893665094049910252612163538072005644241026471164639800490998535570282059396054554479255558624918709232180130454102936332893619326596350851413637207293142767763267817840066780089558654877782630822818446508158509625695020697797889664140551101421185533444015948880284701657904464926309216120238068566472631611326995533585414320547442896728173291714010643730593960222482733969720865809194288803963344344876467583385597351333330628439786357062196382217705500672607607570202305548328439335937369624085404957344415141889143812206076832329063384332685935928226648361622876815670931303789678327741487845287838232474038340893449427806045589018183673133602271167285304427194507315740913600066356089181219040305019319028163972135790696025211929562455952835850442627787993214468221041325612271290302469610374855134599106662606082143546126463790846952338680559237822828610361386416013753920426888371192602742087474507782730180882648297991489233434653363930327991816476995529468892904060335470265188317825821391915073117022336839564945335630414192442838503954209073337511117053790819768061378846157004292392264788138228486672543415580694421193506836000488465561599083339184724263183698928130695654949153165010313216361224018298711517222401523368101476246169896417259748838727189598765602350324828709741468793415378708814573190327920453219231685852735108372055942456601545647944675449566859142997988233179819059574125368681032194798082603876241044848730208905065871934264174092007936669883601462309762759844113071525758916288010581709353072588887654386253201848624931923638568216562603110434528313030704972291334873033240933736956347974889824930017415805659182123288343858101250171537305398462043432455721482088547523494730467761429282915391485852688505423074450548192619166975975031503447208211845313907683486006908772752077246485706597636740936173143436990399498908375710246545650814962015988805204483379491707040848303909417512426275869868668644293498242419667403627076032399201407183071270759837132000712447159523642782162488472933913713634046138974088894178399320090051543608421618891328957740354384456107645016010462709579098652495342014766016330458293537653454523438667413798731255017029554582809547897542497367109038598264606895622241257303208140890607025206140457815282368504505765710043804228592032720729190222134651835930255942940875306994701101153416476785623543575023993736414532895773499876167502240919794121893188059017977444329403624038551082491954751841177014150820554999148803286500065069030165028455616533514890711974194172310029663247936640825364542104897640445108081123906368188594908660418340025631562661211506365309297219580687177632051461355581309500814563826112416521487163593643553646268872746276680368630680088231249970572706496265335285424273723449757482776061300818063419639083097882249478922949525891665782610044424440110326748539620120023397129834624242363283711074267309902126029110038109050751840523266273905031934856015485510632624318778970878895198168073096354223096005536267735905099473408744371024816727970009494589707630185344952680106730984246828848883760016695887137355969244555238536396178788134209309376484848406842940499731494663578455826688245825356635393289729316700066238128368519670627697889769929009597838069557440769080950069594659578325366066060213000525012998145215099629307110700615796004759918829827472751877492472674770755413679265775060149528336859838085353420874215682758801259992855903410097963019943741001394975591822918846705741010634931594527954742032057295356596869586863097328488381174243827058441735659667485315202886191192125286398739560928127513223214119754229343092375569339614672740517569529376699061052365448344078610425576694541873486379356070861240473688356773437140126350120823765176390562050604076894729400293162079760342896846897639867830553941515230713725560502914671175123451932131962571791940911728951123948113598860588062424037835751996487088330150679210175429060531418836978611027896830689666851868410470182364780700615529883149883111601949965815038674390467105247175993726709203381051984777006122752302698038537619917731907133105816779008651480172440446403764720673784583395382889380902941273987910475254258486561698048543296782281040453997661165123290729161619992628751086519341731116513305659182981762584769428708454819029344222186027977405519291266188948708010515922860149238393490889782166965109499761673179583522105791358724355029782111425280584380959770472177893827382916471882671437865821461326011263516554280516418422188264141890686619186492751718984735037496602686033671961304915922609442146773092074476794711917820209913226872184947548378003848726148872742881265579174794634151444545105599464567614478293387968015412886418098284885525959617399177657635267081989985408930744564199296902459275405143647525648661932959903068323866757518479741015342911416508753572892479684280248440220211898390243430190746592470563991910024225814399068391457857458095344096826158489731615822039837691005171654390590093326827586419753439483771905973079465029210363641972615923872187876095687197681934481955852567024141433671590889694204781798936556351775101591005026585947279448642317311892727153525046034081896227383114600546852406398855471859684088277722162250586368419379964112646321070639818773794369650252104438622320671517228411475433482803041707675438555447584321271846396281391925884972509051040944134450429845346071848875654240709690138592611645519676563708429710676494635766201285381926791204110977805857352062737510466943591592074904378966129808716274322385039032007477854211063899544954185997641428116395197239708078986048758264126544825149923227286176571389697334537835963603962709038002668921324389159009375225033651171937770657226295341257068980907793198879997076783263303670667342657925395849950582363998610492878479976185891384024744790742355981796013254960652684988733518397287191251899388324341602608356164496670902390042273216221931567939944001215159910054381084520081133103207553492484487369268314444466610780275891777468369344585045949963237156043800258227618908603074550819931892899703285549507330240121766349515315827830897786432254556221744305752825143708087184314470811004510108612122699931396969361066523608721126359012344828262284427191281973187269761974740398071778378188160519801862257232970224762494767912932684020188061795236229174601398576604233579094407723017353015337974435643738584248250538061547193075224429309117207447677149522141919390974201716026970557825836923707297811545552570788004955666915477901830719591663516687057984336951611189153751912396714116378197000784953115386326766369269172016978409040396969804861828436417776804088449208439901095951205751340861060375353408155737087188313898337656322533650946010308686111901241541794900659835366926383515058402026098259570385429145865025692157987309807064597082326377138235585737704225628144262793497769429358804020882742028263786443615935817930817858306265712263479452174065216410798029333573961137404301928294367884626832432449078812684787281988676202931062510264948586549463964789154366240635570346688477784815271412470430646040615614277320107003575855033995279377529716156628381118518085523414187577256025217995103662771477552291036839539792329375184700131215428652464111526297830742328651189481978920924682746392250346179819781021313400022272303222234731521016033826145645816472110340883197207109422849637006090510260943044730126801795349152894613046101033061811314821366141874985466628809585678299308824993966655499624380015821082410781190328189506855057581990908848597095494573176672201417764187253816862426293852974092626551536758155537683368451820154793964862810533857810979434793077956125541240828563089647076354827276586047900779183041806574320855302776686899978897939486987950729652971448050889517660684386673056662911929857913206598752762097197279390208473846210277152094212386266930256260451209117402079233658157593274696841906354187366092529138116574357045728290417433832596884391356956442617823006949118156994294295529170211353842468704890572313005646106202029653246628477843902025194715815133791174898257040115532858624973690714844800747184719290671002133191274834310662201874141841328708920709275866745037664169280121112867057832132585948539987132879098472640550013972043153470930436509718084070853723316111111611632600262171748813737621046013600544051850633175245231989785291065646466038278748870331134307620041356514295482843502245454400571392386492526283423907951705366640483826875013469850263767974528926285288366544314868036628329638912254207094687335597669512007687507292940623176435604796651807847095408991068514998003358735387989422028901542800717906482276185298683079286137204396993726503610285463352157718364571843381950031926272352293654343387522809514152498052577486366048613580539162662183475105825647260311633442002377527140625112075332294909525522330744664115572260242435895269482927435844022622001466247093866533879048392320516224276433339282642640953964341822416705658461244760448817737705782669080880834418822622611342632727419248415651121035047131961583094994438779439078380664656207143187309895280874153167621657602227990850199615587578332393883365169478142077533262283694526612005465820771400826060398839255150948861553177333447506822679211849690448880479070102043288205874672361672971246062341973369704807867768609989464712379097525706498042381815865399434983035941162258347729020489356838477197804973214911448748749915616679253857438010864500220134843719609727912761136925035123155282535741655826107266099467657016111855684257826878422197833994329148734893923892153298966294232703135845615804723993624827409373966761563257981994036006655039613941881183164267144485664874468348587099434743710128859267552473831462181434321232124758618476925803128913233878664527525204324484796532776273320171351979849530142473805976430318655810403609897537469226336015596525652284888167037460054235043655813438329870872734142062859147847007274999414885129441657918212383876056572545671794085637289277002790218604788423519924573051811976377731594412994393860534559159658127123862955315918182841923881357245009246238507097741891437575676886206936433608263660374355173185026954239766173038826275043838965247160428689739548061640664606565379050539422795708801840829664956978192406737307076253014257542221763860230431809477056758905681723033326311408802886092880151777469082375063137750925275331638009836786645991949881018108222446858443984865972449621097999331605268587810061927125889694400669979755648800940895626242917531834388920035663113368763931463847812763130237825562198311791061780856687903309789539747505239545316630638169559777653347655949908779202359718666623572487055558216484036084925217803431104356647417600193631613474196113126657206064282217690428541246560204561459484317744683213906021267727411189443675804442911583757423572500214191467493342871160840582639470485636370375679604797073490813681083838562113841391587052553615073991983125473434527404596547926972539542447555990332809716643578039646945749813368621152410490288581779206318208255069166455507840899628333174744873951607229399258854694188637978240144635295264982572856632103053550891057171748674115218494774077589151115819489068851971959768129214023511454382738867557288320426608338030759515727545577639726238470674634011626346953231815229549718996906470438903536574430644436472716449550868519871817092814068746449470806856174570885105064766494332205391085097539987897980672278869943134632799032372604933150163386774039430519493297142505321117669011820293604482694166301309801111227443654953271242388534939973277749999335296667138307969441135719079969506099821923206878892624416110175909254904610286553512032488285673735148429324009831633211264460376172046209384270528903772251057643968938983722779640468452705694321085455273829462711022737243290606294601651732654594463569861350966095209962038508010899673666470073918705760679801337058347046567503369379598928154437380765511031719081985901371088639600700705631873099251480947989238619052479230983309717938226245725600119571130722386790431255742179135633111146646083268382596762356018472772209198013121983224179079476134977421748168833934278876403014334318798493417716613256506422668264638388429786875443810986754386459491846082078633346046469418429778813833857755519670005669840456587642130852057050148314568259387702428619224671173187370822224627538313365937868201435535126600146246249435880806572693573084485615073901842761167215162204840459913839674251648</pre> |
|||
=={{header|C++}}== |
|||
<syntaxhighlight lang="c++"> |
|||
#include<bits/stdc++.h> |
|||
using namespace std; |
|||
#define _cin ios_base::sync_with_stdio(0); cin.tie(0); |
|||
#define rep(a, b) for(ll i =a;i<=b;++i) |
|||
double agm(double a, double g) //ARITHMETIC GEOMETRIC MEAN |
|||
{ double epsilon = 1.0E-16,a1,g1; |
|||
if(a*g<0.0) |
|||
{ cout<<"Couldn't find arithmetic-geometric mean of these numbers\n"; |
|||
exit(1); |
|||
} |
|||
while(fabs(a-g)>epsilon) |
|||
{ a1 = (a+g)/2.0; |
|||
g1 = sqrt(a*g); |
|||
a = a1; |
|||
g = g1; |
|||
} |
|||
return a; |
|||
} |
|||
int main() |
|||
{ _cin; //fast input-output |
|||
double x, y; |
|||
cout<<"Enter X and Y: "; //Enter two numbers |
|||
cin>>x>>y; |
|||
cout<<"\nThe Arithmetic-Geometric Mean of "<<x<<" and "<<y<<" is "<<agm(x, y); |
|||
return 0; |
|||
} |
|||
</syntaxhighlight> |
|||
<pre> |
|||
Enter X and Y: 1.0 2.0 |
|||
The Arithmetic-Geometric Mean of 1.0 and 2.0 is 1.45679103104690677028543177584651857614517211914062 |
|||
</pre> |
|||
=={{header|Clojure}}== |
|||
<syntaxhighlight lang="lisp">(ns agmcompute |
|||
(:gen-class)) |
|||
; Java Arbitray Precision Library |
|||
(import '(org.apfloat Apfloat ApfloatMath)) |
|||
(def precision 70) |
|||
(def one (Apfloat. 1M precision)) |
|||
(def two (Apfloat. 2M precision)) |
|||
(def half (Apfloat. 0.5M precision)) |
|||
(def isqrt2 (.divide one (ApfloatMath/pow two half))) |
|||
(def TOLERANCE (Apfloat. 0.000000M precision)) |
|||
(defn agm [a g] |
|||
" Simple AGM Loop calculation " |
|||
(let [THRESH 1e-65 ; done when error less than threshold or we exceed max loops |
|||
MAX-LOOPS 1000000] |
|||
(loop [[an gn] [a g], cnt 0] |
|||
(if (or (< (ApfloatMath/abs (.subtract an gn)) THRESH) |
|||
(> cnt MAX-LOOPS)) |
|||
an |
|||
(recur [(.multiply (.add an gn) half) (ApfloatMath/pow (.multiply an gn) half)] |
|||
(inc cnt)))))) |
|||
(println (agm one isqrt2)) |
|||
</syntaxhighlight> |
|||
{{Output}} |
|||
<pre> |
|||
8.47213084793979086606499123482191636481445910326942185060579372659734e-1 |
|||
</pre> |
|||
=={{header|COBOL}}== |
|||
<syntaxhighlight lang="cobol">IDENTIFICATION DIVISION. |
|||
PROGRAM-ID. ARITHMETIC-GEOMETRIC-MEAN-PROG. |
|||
DATA DIVISION. |
|||
WORKING-STORAGE SECTION. |
|||
01 AGM-VARS. |
|||
05 A PIC 9V9(16). |
|||
05 A-ZERO PIC 9V9(16). |
|||
05 G PIC 9V9(16). |
|||
05 DIFF PIC 9V9(16) VALUE 1. |
|||
* Initialize DIFF with a non-zero value, otherwise AGM-PARAGRAPH |
|||
* is never performed at all. |
|||
PROCEDURE DIVISION. |
|||
TEST-PARAGRAPH. |
|||
MOVE 1 TO A. |
|||
COMPUTE G = 1 / FUNCTION SQRT(2). |
|||
* The program will run with the test values. If you would rather |
|||
* calculate the AGM of numbers input at the console, comment out |
|||
* TEST-PARAGRAPH and un-comment-out INPUT-A-AND-G-PARAGRAPH. |
|||
* INPUT-A-AND-G-PARAGRAPH. |
|||
* DISPLAY 'Enter two numbers.' |
|||
* ACCEPT A. |
|||
* ACCEPT G. |
|||
CONTROL-PARAGRAPH. |
|||
PERFORM AGM-PARAGRAPH UNTIL DIFF IS LESS THAN 0.000000000000001. |
|||
DISPLAY A. |
|||
STOP RUN. |
|||
AGM-PARAGRAPH. |
|||
MOVE A TO A-ZERO. |
|||
COMPUTE A = (A-ZERO + G) / 2. |
|||
MULTIPLY A-ZERO BY G GIVING G. |
|||
COMPUTE G = FUNCTION SQRT(G). |
|||
SUBTRACT A FROM G GIVING DIFF. |
|||
COMPUTE DIFF = FUNCTION ABS(DIFF).</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.8472130847939792</pre> |
|||
=={{header|Common Lisp}}== |
|||
<syntaxhighlight lang="lisp">(defun agm (a0 g0 &optional (tolerance 1d-8)) |
|||
(loop for a = a0 then (* (+ a g) 5d-1) |
|||
and g = g0 then (sqrt (* a g)) |
|||
until (< (abs (- a g)) tolerance) |
|||
finally (return a))) |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>CL-USER> (agm 1d0 (/ 1d0 (sqrt 2d0))) |
|||
0.8472130848351929d0 |
|||
CL-USER> (agm 1d0 (/ 1d0 (sqrt 2d0)) 1d-10) |
|||
0.8472130848351929d0 |
|||
CL-USER> (agm 1d0 (/ 1d0 (sqrt 2d0)) 1d-12) |
|||
0.8472130847939792d0</pre> |
|||
=={{header|D}}== |
|||
<syntaxhighlight lang="d">import std.stdio, std.math, std.meta, std.typecons; |
|||
real agm(real a, real g, in int bitPrecision=60) pure nothrow @nogc @safe { |
|||
do { |
|||
//{a, g} = {(a + g) / 2.0, sqrt(a * g)}; |
|||
AliasSeq!(a, g) = tuple((a + g) / 2.0, sqrt(a * g)); |
|||
} while (feqrel(a, g) < bitPrecision); |
|||
return a; |
|||
} |
|||
void main() @safe { |
|||
writefln("%0.19f", agm(1, 1 / sqrt(2.0))); |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.8472130847939790866</pre> |
|||
All the digits shown are exact. |
|||
=={{header|Delphi}}== |
|||
{{libheader| System.SysUtils}} |
|||
{{Trans|C#}} |
|||
<syntaxhighlight lang="delphi"> |
|||
program geometric_mean; |
|||
{$APPTYPE CONSOLE} |
|||
uses |
|||
System.SysUtils; |
|||
function Fabs(value: Double): Double; |
|||
begin |
|||
Result := value; |
|||
if Result < 0 then |
|||
Result := -Result; |
|||
end; |
|||
function agm(a, g: Double):Double; |
|||
var |
|||
iota, a1, g1: Double; |
|||
begin |
|||
iota := 1.0E-16; |
|||
if a * g < 0.0 then |
|||
begin |
|||
Writeln('arithmetic-geometric mean undefined when x*y<0'); |
|||
exit(1); |
|||
end; |
|||
while Fabs(a - g) > iota do |
|||
begin |
|||
a1 := (a + g) / 2.0; |
|||
g1 := sqrt(a * g); |
|||
a := a1; |
|||
g := g1; |
|||
end; |
|||
Exit(a); |
|||
end; |
|||
var |
|||
x, y: Double; |
|||
begin |
|||
Write('Enter two numbers:'); |
|||
Readln(x, y); |
|||
writeln(format('The arithmetic-geometric mean is %.6f', [agm(x, y)])); |
|||
readln; |
|||
end.</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Enter two numbers:1 |
|||
2 |
|||
The arithmetic-geometric mean is 1,456791</pre> |
|||
=={{header|dc}}== |
|||
<syntaxhighlight lang="dc">>>> 200 k ? sbsa [lalb +2/ lalb *vsb dsa lb - 0!=:]ds:xlap |
|||
?> 1 1 2 v /</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
.8472130847939790866064991234821916364814459103269421850605793726597\ |
|||
34004834134759723200293994611229942122285625233410963097962665830871\ |
|||
05969971363598338425117632681428906038970676860161665004828118868 |
|||
</pre> |
|||
You can change the precision (200 by default) |
|||
=={{header|EasyLang}}== |
|||
{{trans|AWK}} |
|||
<syntaxhighlight lang=easylang> |
|||
func agm a g . |
|||
repeat |
|||
a0 = a |
|||
a = (a0 + g) / 2 |
|||
g = sqrt (a0 * g) |
|||
until abs (a0 - a) < abs (a) * 1e-15 |
|||
. |
|||
return a |
|||
. |
|||
numfmt 16 0 |
|||
print agm 1 sqrt 0.5 |
|||
</syntaxhighlight> |
|||
=={{header|EchoLisp}}== |
|||
We use the '''(~= a b)''' operator which tests for |a - b| < ε = (math-precision). |
|||
<syntaxhighlight lang="scheme"> |
|||
(lib 'math) |
|||
(define (agm a g) |
|||
(if (~= a g) a |
|||
(agm (// (+ a g ) 2) (sqrt (* a g))))) |
|||
(math-precision) |
|||
→ 0.000001 ;; default |
|||
(agm 1 (/ 1 (sqrt 2))) |
|||
→ 0.8472130848351929 |
|||
(math-precision 1.e-15) |
|||
→ 1e-15 |
|||
(agm 1 (/ 1 (sqrt 2))) |
|||
→ 0.8472130847939792 |
|||
</syntaxhighlight> |
|||
=={{header|Elixir}}== |
|||
<syntaxhighlight lang="elixir">defmodule ArithhGeom do |
|||
def mean(a,g,tol) when abs(a-g) <= tol, do: a |
|||
def mean(a,g,tol) do |
|||
mean((a+g)/2,:math.pow(a*g, 0.5),tol) |
|||
end |
|||
end |
|||
IO.puts ArithhGeom.mean(1,1/:math.sqrt(2),0.0000000001)</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
0.8472130848351929 |
|||
</pre> |
|||
=={{header|Erlang}}== |
|||
<syntaxhighlight lang="erlang">%% Arithmetic Geometric Mean of 1 and 1 / sqrt(2) |
|||
%% Author: Abhay Jain |
|||
-module(agm_calculator). |
|||
-export([find_agm/0]). |
|||
-define(TOLERANCE, 0.0000000001). |
|||
find_agm() -> |
|||
A = 1, |
|||
B = 1 / (math:pow(2, 0.5)), |
|||
AGM = agm(A, B), |
|||
io:format("AGM = ~p", [AGM]). |
|||
agm (A, B) when abs(A-B) =< ?TOLERANCE -> |
|||
A; |
|||
agm (A, B) -> |
|||
A1 = (A+B) / 2, |
|||
B1 = math:pow(A*B, 0.5), |
|||
agm(A1, B1).</syntaxhighlight> |
|||
Output: |
|||
<syntaxhighlight lang="erlang">AGM = 0.8472130848351929</syntaxhighlight> |
|||
=={{header|ERRE}}== |
|||
<syntaxhighlight lang="text"> |
|||
PROGRAM AGM |
|||
! |
|||
! for rosettacode.org |
|||
! |
|||
!$DOUBLE |
|||
PROCEDURE AGM(A,G->A) |
|||
LOCAL TA |
|||
REPEAT |
|||
TA=A |
|||
A=(A+G)/2 |
|||
G=SQR(TA*G) |
|||
UNTIL A=TA |
|||
END PROCEDURE |
|||
BEGIN |
|||
AGM(1.0,1/SQR(2)->A) |
|||
PRINT(A) |
|||
END PROGRAM |
|||
</syntaxhighlight> |
|||
=={{header|F_Sharp|F#}}== |
|||
{{trans|OCaml}} |
|||
<syntaxhighlight lang="fsharp">let rec agm a g precision = |
|||
if precision > abs(a - g) then a else |
|||
agm (0.5 * (a + g)) (sqrt (a * g)) precision |
|||
printfn "%g" (agm 1. (sqrt(0.5)) 1e-15)</syntaxhighlight> |
|||
Output |
|||
<pre>0.847213</pre> |
|||
=={{header|Factor}}== |
|||
<syntaxhighlight lang="factor">USING: kernel math math.functions prettyprint ; |
|||
IN: rosetta-code.arithmetic-geometric-mean |
|||
: agm ( a g -- a' g' ) 2dup [ + 0.5 * ] 2dip * sqrt ; |
|||
1 1 2 sqrt / [ 2dup - 1e-15 > ] [ agm ] while drop .</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
0.8472130847939792 |
|||
</pre> |
|||
=={{header|Forth}}== |
|||
<syntaxhighlight lang="forth">: agm ( a g -- m ) |
|||
begin |
|||
fover fover f+ 2e f/ |
|||
frot frot f* fsqrt |
|||
fover fover 1e-15 f~ |
|||
until |
|||
fdrop ; |
|||
1e 2e -0.5e f** agm f. \ 0.847213084793979</syntaxhighlight> |
|||
=={{header|Fortran}}== |
|||
A '''Fortran 77''' implementation |
|||
<syntaxhighlight lang="fortran"> function agm(a,b) |
|||
implicit none |
|||
double precision agm,a,b,eps,c |
|||
parameter(eps=1.0d-15) |
|||
10 c=0.5d0*(a+b) |
|||
b=sqrt(a*b) |
|||
a=c |
|||
if(a-b.gt.eps*a) go to 10 |
|||
agm=0.5d0*(a+b) |
|||
end |
|||
program test |
|||
implicit none |
|||
double precision agm |
|||
print*,agm(1.0d0,1.0d0/sqrt(2.0d0)) |
|||
end</syntaxhighlight> |
|||
=={{header|Futhark}}== |
|||
{{incorrect|Futhark|Futhark's syntax has changed, so this example will not compile}} |
|||
<syntaxhighlight lang="futhark"> |
|||
import "futlib/math" |
|||
fun agm(a: f64, g: f64): f64 = |
|||
let eps = 1.0E-16 |
|||
loop ((a,g)) = while f64.abs(a-g) > eps do |
|||
((a+g) / 2.0, |
|||
f64.sqrt (a*g)) |
|||
in a |
|||
fun main(x: f64, y: f64): f64 = |
|||
agm(x,y) |
|||
</syntaxhighlight> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 108: | Line 1,552: | ||
func main() { |
func main() { |
||
fmt.Println(agm(1, 1/math.Sqrt2)) |
fmt.Println(agm(1, 1/math.Sqrt2)) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
0.8472130847939792 |
0.8472130847939792 |
||
</pre> |
</pre> |
||
The referenced Mathworld page mentions that AGM is meaningful on the complex plane as well. |
|||
:It certainly has. It has been called The Mind of God (perhaps beyond the scope of this task!). There is a little more to it than adding +0i to the real solution. In Real Maths sqrt 4 is 2(This task assumes this). In fantasy maths sqrt 4 is 2 and -2. Then the next iteration takes the sqrt of a negative number, and maths goes complex. The result in Complex maths is the set of all these arithmetric geometric means.--[[User:Nigel Galloway|Nigel Galloway]] 14:20, 23 April 2012 (UTC) |
|||
<lang go>package main |
|||
=={{header|Groovy}}== |
|||
import ( |
|||
{{trans|Java}} |
|||
"fmt" |
|||
Solution: |
|||
"math" |
|||
<syntaxhighlight lang="groovy">double agm (double a, double g) { |
|||
"math/cmplx" |
|||
double an = a, gn = g |
|||
) |
|||
while ((an-gn).abs() >= 10.0**-14) { (an, gn) = [(an+gn)*0.5, (an*gn)**0.5] } |
|||
an |
|||
}</syntaxhighlight> |
|||
Test: |
|||
const ε = 1e-14 |
|||
<syntaxhighlight lang="groovy">println "agm(1, 0.5**0.5) = agm(1, ${0.5**0.5}) = ${agm(1, 0.5**0.5)}" |
|||
assert (0.8472130847939792 - agm(1, 0.5**0.5)).abs() <= 10.0**-14</syntaxhighlight> |
|||
Output: |
|||
func agm(a, g complex128) complex128 { |
|||
<pre>agm(1, 0.5**0.5) = agm(1, 0.7071067811865476) = 0.8472130847939792</pre> |
|||
for cmplx.Abs(a-g) > cmplx.Abs(a)*ε { |
|||
a, g = (a+g)*.5, cmplx.Rect(math.Sqrt(cmplx.Abs(a)*cmplx.Abs(g)), |
|||
(cmplx.Phase(a)+cmplx.Phase(g))*.5) |
|||
} |
|||
return a |
|||
} |
|||
=={{header|Haskell}}== |
|||
func main() { |
|||
<syntaxhighlight lang="haskell">-- Return an approximation to the arithmetic-geometric mean of two numbers. |
|||
fmt.Println(agm(1, 1/math.Sqrt2)) |
|||
-- The result is considered accurate when two successive approximations are |
|||
}</lang> |
|||
-- sufficiently close, as determined by "eq". |
|||
agm :: (Floating a) => a -> a -> ((a, a) -> Bool) -> a |
|||
agm a g eq = snd $ until eq step (a, g) |
|||
where |
|||
step (a, g) = ((a + g) / 2, sqrt (a * g)) |
|||
-- Return the relative difference of the pair. We assume that at least one of |
|||
-- the values is far enough from 0 to not cause problems. |
|||
relDiff :: (Fractional a) => (a, a) -> a |
|||
relDiff (x, y) = |
|||
let n = abs (x - y) |
|||
d = (abs x + abs y) / 2 |
|||
in n / d |
|||
main :: IO () |
|||
main = do |
|||
let equal = (< 0.000000001) . relDiff |
|||
print $ agm 1 (1 / sqrt 2) equal</syntaxhighlight> |
|||
{{out}} |
{{out}} |
||
<pre>0.8472130847527654</pre> |
|||
=={{header|Icon}} and {{header|Unicon}}== |
|||
<syntaxhighlight lang="text">procedure main(A) |
|||
a := real(A[1]) | 1.0 |
|||
g := real(A[2]) | (1 / 2^0.5) |
|||
epsilon := real(A[3]) |
|||
write("agm(",a,",",g,") = ",agm(a,g,epsilon)) |
|||
end |
|||
procedure agm(an, gn, e) |
|||
/e := 1e-15 |
|||
while abs(an-gn) > e do { |
|||
ap := (an+gn)/2.0 |
|||
gn := (an*gn)^0.5 |
|||
an := ap |
|||
} |
|||
return an |
|||
end</syntaxhighlight> |
|||
Output: |
|||
<pre> |
<pre> |
||
->agm |
|||
(0.8472130847939792+0i) |
|||
agm(1.0,0.7071067811865475) = 0.8472130847939792 |
|||
-> |
|||
</pre> |
</pre> |
||
=={{header|J}}== |
=={{header|J}}== |
||
This one is worth not naming, in J, because there are so many interesting variations. |
This one is probably worth not naming, in J, because there are so many interesting variations. |
||
First, the basic approach (with display precision set to 16 digits, which slightly exceeds the accuracy of 64 bit IEEE floating point arithmetic): |
First, the basic approach (with display precision set to 16 digits, which slightly exceeds the accuracy of 64 bit IEEE floating point arithmetic): |
||
< |
<syntaxhighlight lang="j">mean=: +/ % # |
||
(mean , */ %:~ #)^:_] 1,%%:2 |
(mean , */ %:~ #)^:_] 1,%%:2 |
||
0.8472130847939792 0.8472130847939791</ |
0.8472130847939792 0.8472130847939791</syntaxhighlight> |
||
This is the limit -- it stops when values are within a small epsilon of previous calculations. We can ask J for unique values (which also means -- unless we specify otherwise -- values within a small epsilon of each other, for floating point values): |
This is the limit -- it stops when values are within a small epsilon of previous calculations. We can ask J for unique values (which also means -- unless we specify otherwise -- values within a small epsilon of each other, for floating point values): |
||
< |
<syntaxhighlight lang="j"> ~.(mean , */ %:~ #)^:_] 1,%%:2 |
||
0.8472130847939792</ |
0.8472130847939792</syntaxhighlight> |
||
Another variation would be to show intermediate values, in the limit process: |
Another variation would be to show intermediate values, in the limit process: |
||
< |
<syntaxhighlight lang="j"> (mean, */ %:~ #)^:a: 1,%%:2 |
||
1 0.7071067811865475 |
1 0.7071067811865475 |
||
0.8535533905932737 0.8408964152537145 |
0.8535533905932737 0.8408964152537145 |
||
0.8472249029234942 0.8472012667468915 |
0.8472249029234942 0.8472012667468915 |
||
0.8472130848351929 0.8472130847527654 |
0.8472130848351929 0.8472130847527654 |
||
0.8472130847939792 0.8472130847939791</ |
0.8472130847939792 0.8472130847939791</syntaxhighlight> |
||
=== Arbitrary Precision === |
|||
Another variation would be to use [[j:Essays/Extended%20Precision%20Functions|arbitrary precision arithmetic]] in place of floating point arithmetic. (out of time, maybe later) |
|||
Another variation would be to use [[j:Essays/Extended%20Precision%20Functions|arbitrary precision arithmetic]] in place of floating point arithmetic. |
|||
=={{header|Mathematica}}== |
|||
Borrowing routines from that page, but going with a default of approximately 100 digits of precision: |
|||
<syntaxhighlight lang="j">DP=:101 |
|||
round=: DP&$: : (4 : 0) |
|||
b %~ <.1r2+y*b=. 10x^x |
|||
) |
|||
sqrt=: DP&$: : (4 : 0) " 0 |
|||
assert. 0<:y |
|||
%/ <.@%: (2 x: (2*x) round y)*10x^2*x+0>.>.10^.y |
|||
) |
|||
ln=: DP&$: : (4 : 0) " 0 |
|||
assert. 0<y |
|||
m=. <.0.5+2^.y |
|||
t=. (<:%>:) (x:!.0 y)%2x^m |
|||
if. x<-:#":t do. t=. (1+x) round t end. |
|||
ln2=. 2*+/1r3 (^%]) 1+2*i.>.0.5*(%3)^.0.5*0.1^x+>.10^.1>.m |
|||
lnr=. 2*+/t (^%]) 1+2*i.>.0.5*(|t)^.0.5*0.1^x |
|||
lnr + m * ln2 |
|||
) |
|||
exp=: DP&$: : (4 : 0) " 0 |
|||
m=. <.0.5+y%^.2 |
|||
xm=. x+>.m*10^.2 |
|||
d=. (x:!.0 y)-m*xm ln 2 |
|||
if. xm<-:#":d do. d=. xm round d end. |
|||
e=. 0.1^xm |
|||
n=. e (>i.1:) a (^%!@]) i.>.a^.e [ a=. |y-m*^.2 |
|||
(2x^m) * 1++/*/\d%1+i.n |
|||
)</syntaxhighlight> |
|||
We are also going to want a routine to display numbers with this precision, and we are going to need to manage epsilon manually, and we are going to need an arbitrary root routine: |
|||
<syntaxhighlight lang="j">fmt=:[: ;:inv DP&$: : (4 :0)&.> |
|||
x{.deb (x*2j1)":y |
|||
) |
|||
root=: ln@] exp@% [ |
|||
epsilon=: 1r9^DP</syntaxhighlight> |
|||
Some example uses: |
|||
<syntaxhighlight lang="j"> fmt sqrt 2 |
|||
1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641572 |
|||
fmt *~sqrt 2 |
|||
2.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
|||
fmt epsilon |
|||
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000418 |
|||
fmt 2 root 2 |
|||
1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641572</syntaxhighlight> |
|||
Note that 2 root 2 is considerably slower than sqrt 2. The price of generality. So, while we could define geometric mean generally, a desire for good performance pushes us to use a routine specialized for two numbers: |
|||
<syntaxhighlight lang="j">geomean=: */ root~ # |
|||
geomean2=: [: sqrt */</syntaxhighlight> |
|||
A quick test to make sure these can be equivalent: |
|||
<syntaxhighlight lang="j"> fmt geomean 3 5 |
|||
3.872983346207416885179265399782399610832921705291590826587573766113483091936979033519287376858673517 |
|||
fmt geomean2 3 5 |
|||
3.872983346207416885179265399782399610832921705291590826587573766113483091936979033519287376858673517</syntaxhighlight> |
|||
Now for our task example: |
|||
<syntaxhighlight lang="j"> fmt (mean, geomean2)^:(epsilon <&| -/)^:a: 1,%sqrt 2 |
|||
1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0.707106781186547524400844362104849039284835937688474036588339868995366239231053519425193767163820786 |
|||
0.853553390593273762200422181052424519642417968844237018294169934497683119615526759712596883581910393 0.840896415253714543031125476233214895040034262356784510813226085974924754953902239814324004199292536 |
|||
0.847224902923494152615773828642819707341226115600510764553698010236303937284714499763460443890601464 0.847201266746891460403631453693352397963981013612000500823295747923488191871327668107581434542353536 |
|||
0.847213084835192806509702641168086052652603564606255632688496879079896064578021083935520939216477500 0.847213084752765366704298051779902070392110656059452583317776227659438896688518556753569298762449381 |
|||
0.847213084793979086607000346473994061522357110332854108003136553369667480633269820344545118989463440 0.847213084793979086605997900490389211440534858586261300461413929971399281619068666682569108141224710 |
|||
0.847213084793979086606499123482191636481445984459557704232275241670533381126169243513557113565344075 0.847213084793979086606499123482191636481445836194326665888883503648934628542100275932846717790147361 |
|||
0.847213084793979086606499123482191636481445910326942185060579372659734004834134759723201915677745718 0.847213084793979086606499123482191636481445910326942185060579372659734004834134759723198672311476741 |
|||
0.847213084793979086606499123482191636481445910326942185060579372659734004834134759723200293994611229 0.847213084793979086606499123482191636481445910326942185060579372659734004834134759723200293994611229</syntaxhighlight> |
|||
We could of course extract out only a representative final value, but it's obvious enough, and showing how rapidly this converges is fun. |
|||
=={{header|Java}}== |
|||
<syntaxhighlight lang="java">/* |
|||
* Arithmetic-Geometric Mean of 1 & 1/sqrt(2) |
|||
* Brendan Shaklovitz |
|||
* 5/29/12 |
|||
*/ |
|||
public class ArithmeticGeometricMean { |
|||
public static double agm(double a, double g) { |
|||
double a1 = a; |
|||
double g1 = g; |
|||
while (Math.abs(a1 - g1) >= 1.0e-14) { |
|||
double arith = (a1 + g1) / 2.0; |
|||
double geom = Math.sqrt(a1 * g1); |
|||
a1 = arith; |
|||
g1 = geom; |
|||
} |
|||
return a1; |
|||
} |
|||
public static void main(String[] args) { |
|||
System.out.println(agm(1.0, 1.0 / Math.sqrt(2.0))); |
|||
} |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.8472130847939792</pre> |
|||
=={{header|JavaScript}}== |
|||
===ES5=== |
|||
<syntaxhighlight lang="javascript">function agm(a0, g0) { |
|||
var an = (a0 + g0) / 2, |
|||
gn = Math.sqrt(a0 * g0); |
|||
while (Math.abs(an - gn) > tolerance) { |
|||
an = (an + gn) / 2, gn = Math.sqrt(an * gn) |
|||
} |
|||
return an; |
|||
} |
|||
agm(1, 1 / Math.sqrt(2));</syntaxhighlight> |
|||
===ES6=== |
|||
<syntaxhighlight lang="javascript">(() => { |
|||
'use strict'; |
|||
// ARITHMETIC-GEOMETRIC MEAN |
|||
// agm :: Num a => a -> a -> a |
|||
let agm = (a, g) => { |
|||
let abs = Math.abs, |
|||
sqrt = Math.sqrt; |
|||
return until( |
|||
m => abs(m.an - m.gn) < tolerance, |
|||
m => { |
|||
return { |
|||
an: (m.an + m.gn) / 2, |
|||
gn: sqrt(m.an * m.gn) |
|||
}; |
|||
}, { |
|||
an: (a + g) / 2, |
|||
gn: sqrt(a * g) |
|||
} |
|||
) |
|||
.an; |
|||
}, |
|||
// GENERIC |
|||
// until :: (a -> Bool) -> (a -> a) -> a -> a |
|||
until = (p, f, x) => { |
|||
let v = x; |
|||
while (!p(v)) v = f(v); |
|||
return v; |
|||
}; |
|||
// TEST |
|||
let tolerance = 0.000001; |
|||
return agm(1, 1 / Math.sqrt(2)); |
|||
})();</syntaxhighlight> |
|||
{{Out}} |
|||
<syntaxhighlight lang="javascript">0.8472130848351929</syntaxhighlight> |
|||
=={{header|jq}}== |
|||
{{works with|jq|1.4}} |
|||
Naive version that assumes tolerance is appropriately specified: |
|||
<syntaxhighlight lang="jq">def naive_agm(a; g; tolerance): |
|||
def abs: if . < 0 then -. else . end; |
|||
def _agm: |
|||
# state [an,gn] |
|||
if ((.[0] - .[1])|abs) > tolerance |
|||
then [add/2, ((.[0] * .[1])|sqrt)] | _agm |
|||
else . |
|||
end; |
|||
[a, g] | _agm | .[0] ;</syntaxhighlight> |
|||
This version avoids an infinite loop if the requested tolerance is too small: |
|||
<syntaxhighlight lang="jq">def agm(a; g; tolerance): |
|||
def abs: if . < 0 then -. else . end; |
|||
def _agm: |
|||
# state [an,gn, delta] |
|||
((.[0] - .[1])|abs) as $delta |
|||
| if $delta == .[2] and $delta < 10e-16 then . |
|||
elif $delta > tolerance |
|||
then [ .[0:2]|add / 2, ((.[0] * .[1])|sqrt), $delta] | _agm |
|||
else . |
|||
end; |
|||
if tolerance <= 0 then error("specified tolerance must be > 0") |
|||
else [a, g, 0] | _agm | .[0] |
|||
end ; |
|||
# Example: |
|||
agm(1; 1/(2|sqrt); 1e-100)</syntaxhighlight> |
|||
{{Out}} |
|||
$ jq -n -f Arithmetic-geometric_mean.jq |
|||
0.8472130847939792 |
|||
=={{header|Julia}}== |
|||
{{works with|Julia|1.2}} |
|||
<syntaxhighlight lang="julia">function agm(x, y, e::Real = 5) |
|||
(x ≤ 0 || y ≤ 0 || e ≤ 0) && throw(DomainError("x, y must be strictly positive")) |
|||
g, a = minmax(x, y) |
|||
while e * eps(x) < a - g |
|||
a, g = (a + g) / 2, sqrt(a * g) |
|||
end |
|||
a |
|||
end |
|||
x, y = 1.0, 1 / √2 |
|||
println("# Using literal-precision float numbers:") |
|||
@show agm(x, y) |
|||
println("# Using half-precision float numbers:") |
|||
x, y = Float32(x), Float32(y) |
|||
@show agm(x, y) |
|||
println("# Using ", precision(BigFloat), "-bit float numbers:") |
|||
x, y = big(1.0), 1 / √big(2.0) |
|||
@show agm(x, y)</syntaxhighlight> |
|||
The ε for this calculation is given as a positive integer multiple of the machine ε for <tt>x</tt>. |
|||
{{out}} |
|||
<pre># Using literal-precision float numbers: |
|||
agm(x, y) = 0.8472130847939792 |
|||
# Using half-precision float numbers: |
|||
agm(x, y) = 0.84721315f0 |
|||
# Using 256-bit float numbers: |
|||
agm(x, y) = 8.472130847939790866064991234821916364814459103269421850605793726597340048341323e-01</pre> |
|||
=={{header|Klingphix}}== |
|||
{{trans|Oforth}} |
|||
<syntaxhighlight lang="klingphix">include ..\Utilitys.tlhy |
|||
:agm [ over over + 2 / rot rot * sqrt ] [ over over tostr swap tostr # ] while drop ; |
|||
1 1 2 sqrt / agm |
|||
pstack |
|||
" " input</syntaxhighlight> |
|||
{{trans|F#}} |
|||
<syntaxhighlight lang="klingphix">include ..\Utilitys.tlhy |
|||
:agm %a %g %p !p !g !a |
|||
$p $a $g - abs > ( [$a] [.5 $a $g + * $a $g * sqrt $p agm] ) if ; |
|||
1 .5 sqrt 1e-15 agm |
|||
pstack |
|||
" " input</syntaxhighlight> |
|||
{{out}} |
|||
<pre>(0.847213)</pre> |
|||
=={{header|Kotlin}}== |
|||
<syntaxhighlight lang="scala">// version 1.0.5-2 |
|||
fun agm(a: Double, g: Double): Double { |
|||
var aa = a // mutable 'a' |
|||
var gg = g // mutable 'g' |
|||
var ta: Double // temporary variable to hold next iteration of 'aa' |
|||
val epsilon = 1.0e-16 // tolerance for checking if limit has been reached |
|||
while (true) { |
|||
ta = (aa + gg) / 2.0 |
|||
if (Math.abs(aa - ta) <= epsilon) return ta |
|||
gg = Math.sqrt(aa * gg) |
|||
aa = ta |
|||
} |
|||
} |
|||
fun main(args: Array<String>) { |
|||
println(agm(1.0, 1.0 / Math.sqrt(2.0))) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
0.8472130847939792 |
|||
</pre> |
|||
=={{header|Lambdatalk}}== |
|||
<syntaxhighlight lang="Scheme"> |
|||
{def eps 1e-15} |
|||
-> eps |
|||
{def agm |
|||
{lambda {:a :g} |
|||
{if {> {abs {- :a :g}} {eps}} |
|||
then {agm {/ {+ :a :g} 2} |
|||
{sqrt {* :a :g}}} |
|||
else :a }}} |
|||
-> agm |
|||
{agm 1 {/ 1 {sqrt 2}}} |
|||
-> 0.8472130847939792 |
|||
Multi-precision version using the lib_BN library |
|||
{BN.DEC 70} |
|||
-> 70 digits |
|||
{def EPS {BN./ 1 {BN.pow 10 45}}} |
|||
-> EPS |
|||
{def AGM |
|||
{lambda {:a :g} |
|||
{if {= {BN.compare {BN.abs {BN.- :a :g}} {EPS}} 1} |
|||
then {AGM {BN./ {BN.+ :a :g} 2} |
|||
{BN.sqrt {BN.* :a :g}}} |
|||
else :a }}} |
|||
-> AGM |
|||
{AGM 1 {BN./ 1 {BN.sqrt 2}}} |
|||
-> 0.8472130847939790866064991234821916364814459103269421850605793726597339 |
|||
</syntaxhighlight> |
|||
=={{header|LFE}}== |
|||
<syntaxhighlight lang="lisp"> |
|||
(defun agm (a g) |
|||
(agm a g 1.0e-15)) |
|||
(defun agm (a g tol) |
|||
(if (=< (- a g) tol) |
|||
a |
|||
(agm (next-a a g) |
|||
(next-g a g) |
|||
tol))) |
|||
(defun next-a (a g) |
|||
(/ (+ a g) 2)) |
|||
(defun next-g (a g) |
|||
(math:sqrt (* a g))) |
|||
</syntaxhighlight> |
|||
Usage: |
|||
<pre> |
|||
> (agm 1 (/ 1 (math:sqrt 2))) |
|||
0.8472130847939792 |
|||
</pre> |
|||
=={{header|LiveCode}}== |
|||
<syntaxhighlight lang="livecode">function agm aa,g |
|||
put abs(aa-g) into absdiff |
|||
put (aa+g)/2 into aan |
|||
put sqrt(aa*g) into gn |
|||
repeat while abs(aan - gn) < absdiff |
|||
put abs(aa-g) into absdiff |
|||
put (aa+g)/2 into aan |
|||
put sqrt(aa*g) into gn |
|||
put aan into aa |
|||
put gn into g |
|||
end repeat |
|||
return aa |
|||
end agm</syntaxhighlight> |
|||
Example |
|||
<syntaxhighlight lang="livecode">put agm(1, 1/sqrt(2)) |
|||
-- ouput |
|||
-- 0.847213</syntaxhighlight> |
|||
=={{header|LLVM}}== |
|||
<syntaxhighlight lang="llvm">; This is not strictly LLVM, as it uses the C library function "printf". |
|||
; LLVM does not provide a way to print values, so the alternative would be |
|||
; to just load the string into memory, and that would be boring. |
|||
; Additional comments have been inserted, as well as changes made from the output produced by clang such as putting more meaningful labels for the jumps |
|||
$"ASSERTION" = comdat any |
|||
$"OUTPUT" = comdat any |
|||
@"ASSERTION" = linkonce_odr unnamed_addr constant [48 x i8] c"arithmetic-geometric mean undefined when x*y<0\0A\00", comdat, align 1 |
|||
@"OUTPUT" = linkonce_odr unnamed_addr constant [42 x i8] c"The arithmetic-geometric mean is %0.19lf\0A\00", comdat, align 1 |
|||
;--- The declarations for the external C functions |
|||
declare i32 @printf(i8*, ...) |
|||
declare void @exit(i32) #1 |
|||
declare double @sqrt(double) #1 |
|||
declare double @llvm.fabs.f64(double) #2 |
|||
;---------------------------------------------------------------- |
|||
;-- arithmetic geometric mean |
|||
define double @agm(double, double) #0 { |
|||
%3 = alloca double, align 8 ; allocate local g |
|||
%4 = alloca double, align 8 ; allocate local a |
|||
%5 = alloca double, align 8 ; allocate iota |
|||
%6 = alloca double, align 8 ; allocate a1 |
|||
%7 = alloca double, align 8 ; allocate g1 |
|||
store double %1, double* %3, align 8 ; store param g in local g |
|||
store double %0, double* %4, align 8 ; store param a in local a |
|||
store double 1.000000e-15, double* %5, align 8 ; store 1.0e-15 in iota (1.0e-16 was causing the program to hang) |
|||
%8 = load double, double* %4, align 8 ; load a |
|||
%9 = load double, double* %3, align 8 ; load g |
|||
%10 = fmul double %8, %9 ; a * g |
|||
%11 = fcmp olt double %10, 0.000000e+00 ; a * g < 0.0 |
|||
br i1 %11, label %enforce, label %loop |
|||
enforce: |
|||
%12 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"ASSERTION", i32 0, i32 0)) |
|||
call void @exit(i32 1) #6 |
|||
unreachable |
|||
loop: |
|||
%13 = load double, double* %4, align 8 ; load a |
|||
%14 = load double, double* %3, align 8 ; load g |
|||
%15 = fsub double %13, %14 ; a - g |
|||
%16 = call double @llvm.fabs.f64(double %15) ; fabs(a - g) |
|||
%17 = load double, double* %5, align 8 ; load iota |
|||
%18 = fcmp ogt double %16, %17 ; fabs(a - g) > iota |
|||
br i1 %18, label %loop_body, label %eom |
|||
loop_body: |
|||
%19 = load double, double* %4, align 8 ; load a |
|||
%20 = load double, double* %3, align 8 ; load g |
|||
%21 = fadd double %19, %20 ; a + g |
|||
%22 = fdiv double %21, 2.000000e+00 ; (a + g) / 2.0 |
|||
store double %22, double* %6, align 8 ; store %22 in a1 |
|||
%23 = load double, double* %4, align 8 ; load a |
|||
%24 = load double, double* %3, align 8 ; load g |
|||
%25 = fmul double %23, %24 ; a * g |
|||
%26 = call double @sqrt(double %25) #4 ; sqrt(a * g) |
|||
store double %26, double* %7, align 8 ; store %26 in g1 |
|||
%27 = load double, double* %6, align 8 ; load a1 |
|||
store double %27, double* %4, align 8 ; store a1 in a |
|||
%28 = load double, double* %7, align 8 ; load g1 |
|||
store double %28, double* %3, align 8 ; store g1 in g |
|||
br label %loop |
|||
eom: |
|||
%29 = load double, double* %4, align 8 ; load a |
|||
ret double %29 ; return a |
|||
} |
|||
;---------------------------------------------------------------- |
|||
;-- main |
|||
define i32 @main() #0 { |
|||
%1 = alloca double, align 8 ; allocate x |
|||
%2 = alloca double, align 8 ; allocate y |
|||
store double 1.000000e+00, double* %1, align 8 ; store 1.0 in x |
|||
%3 = call double @sqrt(double 2.000000e+00) #4 ; calculate the square root of two |
|||
%4 = fdiv double 1.000000e+00, %3 ; divide 1.0 by %3 |
|||
store double %4, double* %2, align 8 ; store %4 in y |
|||
%5 = load double, double* %2, align 8 ; reload y |
|||
%6 = load double, double* %1, align 8 ; reload x |
|||
%7 = call double @agm(double %6, double %5) ; agm(x, y) |
|||
%8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([42 x i8], [42 x i8]* @"OUTPUT", i32 0, i32 0), double %7) |
|||
ret i32 0 ; finished |
|||
} |
|||
attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } |
|||
attributes #1 = { noreturn "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } |
|||
attributes #2 = { nounwind readnone speculatable } |
|||
attributes #4 = { nounwind } |
|||
attributes #6 = { noreturn }</syntaxhighlight> |
|||
{{out}} |
|||
<pre>The arithmetic-geometric mean is 0.8472130847939791654</pre> |
|||
=={{header|Logo}}== |
|||
<syntaxhighlight lang="logo">to about :a :b |
|||
output and [:a - :b < 1e-15] [:a - :b > -1e-15] |
|||
end |
|||
to agm :arith :geom |
|||
if about :arith :geom [output :arith] |
|||
output agm (:arith + :geom)/2 sqrt (:arith * :geom) |
|||
end |
|||
show agm 1 1/sqrt 2 |
|||
</syntaxhighlight> |
|||
=={{header|Lua}}== |
|||
<syntaxhighlight lang="lua">function agm(a, b, tolerance) |
|||
if not tolerance or tolerance < 1e-15 then |
|||
tolerance = 1e-15 |
|||
end |
|||
repeat |
|||
a, b = (a + b) / 2, math.sqrt(a * b) |
|||
until math.abs(a-b) < tolerance |
|||
return a |
|||
end |
|||
print(string.format("%.15f", agm(1, 1 / math.sqrt(2))))</syntaxhighlight> |
|||
'''Output:''' |
|||
0.847213084793979 |
|||
=={{header|M2000 Interpreter}}== |
|||
<syntaxhighlight lang="m2000 interpreter"> |
|||
Module Checkit { |
|||
Function Agm { |
|||
\\ new stack constructed at calling the Agm() with two values |
|||
Repeat { |
|||
Read a0, b0 |
|||
Push Sqrt(a0*b0), (a0+b0)/2 |
|||
' last pushed first read |
|||
} Until Stackitem(1)==Stackitem(2) |
|||
=Stackitem(1) |
|||
\\ stack deconstructed at exit of function |
|||
} |
|||
Print Agm(1,1/Sqrt(2)) |
|||
} |
|||
Checkit |
|||
</syntaxhighlight> |
|||
=={{header|Maple}}== |
|||
Maple provides this function under the name GaussAGM. To compute a floating point approximation, use evalf. |
|||
<syntaxhighlight lang="maple"> |
|||
> evalf( GaussAGM( 1, 1 / sqrt( 2 ) ) ); # default precision is 10 digits |
|||
0.8472130847 |
|||
> evalf[100]( GaussAGM( 1, 1 / sqrt( 2 ) ) ); # to 100 digits |
|||
0.847213084793979086606499123482191636481445910326942185060579372659\ |
|||
7340048341347597232002939946112300 |
|||
</syntaxhighlight> |
|||
Alternatively, if one or both arguments is already a float, Maple will compute a floating point approximation automatically. |
|||
<syntaxhighlight lang="maple"> |
|||
> GaussAGM( 1.0, 1 / sqrt( 2 ) ); |
|||
0.8472130847 |
|||
</syntaxhighlight> |
|||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
|||
To any arbitrary precision, just increase PrecisionDigits |
To any arbitrary precision, just increase PrecisionDigits |
||
< |
<syntaxhighlight lang="mathematica">PrecisionDigits = 85; |
||
AGMean[a_, b_] := FixedPoint[{ |
AGMean[a_, b_] := FixedPoint[{ Tr@#/2, Sqrt[Times@@#] }&, N[{a,b}, PrecisionDigits]]〚1〛</syntaxhighlight> |
||
<pre>AGMean[1, 1/Sqrt[2]] |
<pre>AGMean[1, 1/Sqrt[2]] |
||
0.8472130847939790866064991234821916364814459103269421850605793726597340048341347597232</pre> |
0.8472130847939790866064991234821916364814459103269421850605793726597340048341347597232</pre> |
||
=={{header|Perl 6}}== |
|||
<lang perl6>sub agm ($a, $g) { |
|||
sub iter ($old) { |
|||
my $new := [ 0.5 * [+](@$old), sqrt [*](@$old) ]; |
|||
last if $new ~~ $old; |
|||
$new; |
|||
} |
|||
=={{header|MATLAB}} / {{header|Octave}}== |
|||
([$a,$g], &iter ... 0)[*-1][0]; |
|||
<syntaxhighlight lang="matlab">function [a,g]=agm(a,g) |
|||
%%arithmetic_geometric_mean(a,g) |
|||
while (1) |
|||
a0=a; |
|||
a=(a0+g)/2; |
|||
g=sqrt(a0*g); |
|||
if (abs(a0-a) < a*eps) break; end; |
|||
end; |
|||
end</syntaxhighlight> |
|||
<pre>octave:26> agm(1,1/sqrt(2)) |
|||
ans = 0.84721 |
|||
</pre> |
|||
=={{header|Maxima}}== |
|||
<syntaxhighlight lang="maxima">agm(a, b) := %pi/4*(a + b)/elliptic_kc(((a - b)/(a + b))^2)$ |
|||
agm(1, 1/sqrt(2)), bfloat, fpprec: 85; |
|||
/* 8.472130847939790866064991234821916364814459103269421850605793726597340048341347597232b-1 */</syntaxhighlight> |
|||
=={{header|МК-61/52}}== |
|||
<syntaxhighlight lang="text">П1 <-> П0 1 ВП 8 /-/ П2 ИП0 ИП1 |
|||
- ИП2 - /-/ x<0 31 ИП1 П3 ИП0 ИП1 |
|||
* КвКор П1 ИП0 ИП3 + 2 / П0 БП |
|||
08 ИП0 С/П</syntaxhighlight> |
|||
=={{header|Modula-2}}== |
|||
{{trans|C}} |
|||
<syntaxhighlight lang="modula2">MODULE AGM; |
|||
FROM EXCEPTIONS IMPORT AllocateSource,ExceptionSource,GetMessage,RAISE; |
|||
FROM LongConv IMPORT ValueReal; |
|||
FROM LongMath IMPORT sqrt; |
|||
FROM LongStr IMPORT RealToStr; |
|||
FROM Terminal IMPORT ReadChar,Write,WriteString,WriteLn; |
|||
VAR |
|||
TextWinExSrc : ExceptionSource; |
|||
PROCEDURE ReadReal() : LONGREAL; |
|||
VAR |
|||
buffer : ARRAY[0..63] OF CHAR; |
|||
i : CARDINAL; |
|||
c : CHAR; |
|||
BEGIN |
|||
i := 0; |
|||
LOOP |
|||
c := ReadChar(); |
|||
IF ((c >= '0') AND (c <= '9')) OR (c = '.') THEN |
|||
buffer[i] := c; |
|||
Write(c); |
|||
INC(i) |
|||
ELSE |
|||
WriteLn; |
|||
EXIT |
|||
END |
|||
END; |
|||
buffer[i] := 0C; |
|||
RETURN ValueReal(buffer) |
|||
END ReadReal; |
|||
PROCEDURE WriteReal(r : LONGREAL); |
|||
VAR |
|||
buffer : ARRAY[0..63] OF CHAR; |
|||
BEGIN |
|||
RealToStr(r, buffer); |
|||
WriteString(buffer) |
|||
END WriteReal; |
|||
PROCEDURE AGM(a,g : LONGREAL) : LONGREAL; |
|||
CONST iota = 1.0E-16; |
|||
VAR a1, g1 : LONGREAL; |
|||
BEGIN |
|||
IF a * g < 0.0 THEN |
|||
RAISE(TextWinExSrc, 0, "arithmetic-geometric mean undefined when x*y<0") |
|||
END; |
|||
WHILE ABS(a - g) > iota DO |
|||
a1 := (a + g) / 2.0; |
|||
g1 := sqrt(a * g); |
|||
a := a1; |
|||
g := g1 |
|||
END; |
|||
RETURN a |
|||
END AGM; |
|||
VAR |
|||
x, y, z: LONGREAL; |
|||
BEGIN |
|||
WriteString("Enter two numbers: "); |
|||
x := ReadReal(); |
|||
y := ReadReal(); |
|||
WriteReal(AGM(x, y)); |
|||
WriteLn |
|||
END AGM.</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Enter two numbers: 1.0 |
|||
2.0 |
|||
1.456791031046900</pre> |
|||
<pre>Enter two numbers: 1.0 |
|||
0.707 |
|||
0.847154622368330</pre> |
|||
=={{header|NetRexx}}== |
|||
{{trans|Java}} |
|||
<syntaxhighlight lang="netrexx">/* NetRexx */ |
|||
options replace format comments java crossref symbols nobinary |
|||
numeric digits 18 |
|||
parse arg a_ g_ . |
|||
if a_ = '' | a_ = '.' then a0 = 1 |
|||
else a0 = a_ |
|||
if g_ = '' | g_ = '.' then g0 = 1 / Math.sqrt(2) |
|||
else g0 = g_ |
|||
say agm(a0, g0) |
|||
return |
|||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
|||
method agm(a0, g0) public static returns Rexx |
|||
a1 = a0 |
|||
g1 = g0 |
|||
loop while (a1 - g1).abs() >= Math.pow(10, -14) |
|||
temp = (a1 + g1) / 2 |
|||
g1 = Math.sqrt(a1 * g1) |
|||
a1 = temp |
|||
end |
|||
return a1 + 0 |
|||
</syntaxhighlight> |
|||
'''Output:''' |
|||
<pre> |
|||
0.8472130847939792 |
|||
</pre> |
|||
=={{header|NewLISP}}== |
|||
<syntaxhighlight lang="newlisp"> |
|||
(define (a-next a g) (mul 0.5 (add a g))) |
|||
(define (g-next a g) (sqrt (mul a g))) |
|||
(define (amg a g tolerance) |
|||
(if (<= (sub a g) tolerance) |
|||
a |
|||
(amg (a-next a g) (g-next a g) tolerance) |
|||
) |
|||
) |
|||
(define quadrillionth 0.000000000000001) |
|||
(define root-reciprocal-2 (div 1.0 (sqrt 2.0))) |
|||
(println |
|||
"To the nearest one-quadrillionth, " |
|||
"the arithmetic-geometric mean of " |
|||
"1 and the reciprocal of the square root of 2 is " |
|||
(amg 1.0 root-reciprocal-2 quadrillionth) |
|||
) |
|||
</syntaxhighlight> |
|||
=={{header|Nim}}== |
|||
<syntaxhighlight lang="nim">import math |
|||
proc agm(a, g: float,delta: float = 1.0e-15): float = |
|||
var |
|||
aNew: float = 0 |
|||
aOld: float = a |
|||
gOld: float = g |
|||
while (abs(aOld - gOld) > delta): |
|||
aNew = 0.5 * (aOld + gOld) |
|||
gOld = sqrt(aOld * gOld) |
|||
aOld = aNew |
|||
result = aOld |
|||
echo agm(1.0,1.0/sqrt(2.0))</syntaxhighlight> |
|||
Output:<br/> |
|||
<pre> |
|||
8.4721308479397917e-01 |
|||
</pre> |
|||
See first 24 iterations: |
|||
<syntaxhighlight lang="nim">from math import sqrt |
|||
from strutils import parseFloat, formatFloat, ffDecimal |
|||
proc agm(x,y: float): tuple[resA,resG: float] = |
|||
var |
|||
a,g: array[0 .. 23,float] |
|||
a[0] = x |
|||
g[0] = y |
|||
for n in 1 .. 23: |
|||
a[n] = 0.5 * (a[n - 1] + g[n - 1]) |
|||
g[n] = sqrt(a[n - 1] * g[n - 1]) |
|||
(a[23], g[23]) |
|||
var t = agm(1, 1/sqrt(2.0)) |
|||
echo("Result A: " & formatFloat(t.resA, ffDecimal, 24)) |
|||
echo("Result G: " & formatFloat(t.resG, ffDecimal, 24))</syntaxhighlight> |
|||
=={{header|Oberon-2}}== |
|||
{{works with|oo2c}} |
|||
<syntaxhighlight lang="oberon2"> |
|||
MODULE Agm; |
|||
IMPORT |
|||
Math := LRealMath, |
|||
Out; |
|||
CONST |
|||
epsilon = 1.0E-15; |
|||
PROCEDURE Of*(a,g: LONGREAL): LONGREAL; |
|||
VAR |
|||
na,ng,og: LONGREAL; |
|||
BEGIN |
|||
na := a; ng := g; |
|||
LOOP |
|||
og := ng; |
|||
ng := Math.sqrt(na * ng); |
|||
na := (na + og) * 0.5; |
|||
IF na - ng <= epsilon THEN EXIT END |
|||
END; |
|||
RETURN ng; |
|||
END Of; |
|||
BEGIN |
|||
Out.LongReal(Of(1,1 / Math.sqrt(2)),0,0);Out.Ln |
|||
END Agm. |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> |
|||
8.4721308479397905E-1 |
|||
</pre> |
|||
=={{header|Objeck}}== |
|||
{{trans|Java}} |
|||
<syntaxhighlight lang="objeck"> |
|||
class ArithmeticMean { |
|||
function : Amg(a : Float, g : Float) ~ Nil { |
|||
a1 := a; |
|||
g1 := g; |
|||
while((a1-g1)->Abs() >= Float->Power(10, -14)) { |
|||
tmp := (a1+g1)/2.0; |
|||
g1 := Float->SquareRoot(a1*g1); |
|||
a1 := tmp; |
|||
}; |
|||
a1->PrintLine(); |
|||
} |
|||
function : Main(args : String[]) ~ Nil { |
|||
Amg(1,1/Float->SquareRoot(2)); |
|||
} |
|||
} |
} |
||
</syntaxhighlight> |
|||
Output: |
|||
<pre>0.847213085</pre> |
|||
=={{header|OCaml}}== |
|||
<syntaxhighlight lang="ocaml">let rec agm a g tol = |
|||
if tol > abs_float (a -. g) then a else |
|||
agm (0.5*.(a+.g)) (sqrt (a*.g)) tol |
|||
let _ = Printf.printf "%.16f\n" (agm 1.0 (sqrt 0.5) 1e-15)</syntaxhighlight> |
|||
Output |
|||
<pre>0.8472130847939792</pre> |
|||
=={{header|Oforth}}== |
|||
<syntaxhighlight lang="oforth">: agm \ a b -- m |
|||
while( 2dup <> ) [ 2dup + 2 / -rot * sqrt ] drop ;</syntaxhighlight> |
|||
Usage : |
|||
<syntaxhighlight lang="oforth">1 2 sqrt inv agm</syntaxhighlight> |
|||
say agm 1, 1/sqrt 2;</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
|||
<pre>0.84721308479397917</pre> |
|||
0.847213084793979 |
|||
Obviously the "fixed point" detector here is relying on the floating-point representation running out of bits, or this algorithm would not terminate before using up all memory. |
|||
</pre> |
|||
=={{header|OOC}}== |
|||
<syntaxhighlight lang="ooc"> |
|||
import math // import for sqrt() function |
|||
amean: func (x: Double, y: Double) -> Double { |
|||
(x + y) / 2. |
|||
} |
|||
gmean: func (x: Double, y: Double) -> Double { |
|||
sqrt(x * y) |
|||
} |
|||
agm: func (a: Double, g: Double) -> Double { |
|||
while ((a - g) abs() > pow(10, -12)) { |
|||
(a1, g1) := (amean(a, g), gmean(a, g)) |
|||
(a, g) = (a1, g1) |
|||
} |
|||
a |
|||
} |
|||
main: func { |
|||
"%.16f" printfln(agm(1., sqrt(0.5))) |
|||
} |
|||
</syntaxhighlight> |
|||
Output |
|||
<pre>0.8472130847939792</pre> |
|||
=={{header|ooRexx}}== |
|||
<syntaxhighlight lang="oorexx">numeric digits 20 |
|||
say agm(1, 1/rxcalcsqrt(2,16)) |
|||
::routine agm |
|||
use strict arg a, g |
|||
numeric digits 20 |
|||
a1 = a |
|||
g1 = g |
|||
loop while abs(a1 - g1) >= 1e-14 |
|||
temp = (a1 + g1)/2 |
|||
g1 = rxcalcsqrt(a1*g1,16) |
|||
a1 = temp |
|||
end |
|||
return a1+0 |
|||
::requires rxmath LIBRARY</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.8472130847939791968</pre> |
|||
=={{header|PARI/GP}}== |
|||
Built-in: |
|||
<syntaxhighlight lang="parigp">agm(1,1/sqrt(2))</syntaxhighlight> |
|||
Iteration: |
|||
<syntaxhighlight lang="parigp">agm2(x,y)=if(x==y,x,agm2((x+y)/2,sqrt(x*y))</syntaxhighlight> |
|||
=={{header|Pascal}}== |
|||
{{works with|Free_Pascal}} |
|||
{{libheader|GMP}} |
|||
Port of the C example: |
|||
<syntaxhighlight lang="pascal">Program ArithmeticGeometricMean; |
|||
uses |
|||
gmp; |
|||
procedure agm (in1, in2: mpf_t; var out1, out2: mpf_t); |
|||
begin |
|||
mpf_add (out1, in1, in2); |
|||
mpf_div_ui (out1, out1, 2); |
|||
mpf_mul (out2, in1, in2); |
|||
mpf_sqrt (out2, out2); |
|||
end; |
|||
const |
|||
nl = chr(13)+chr(10); |
|||
var |
|||
x0, y0, resA, resB: mpf_t; |
|||
i: integer; |
|||
begin |
|||
mpf_set_default_prec (65568); |
|||
mpf_init_set_ui (y0, 1); |
|||
mpf_init_set_d (x0, 0.5); |
|||
mpf_sqrt (x0, x0); |
|||
mpf_init (resA); |
|||
mpf_init (resB); |
|||
for i := 0 to 6 do |
|||
begin |
|||
agm(x0, y0, resA, resB); |
|||
agm(resA, resB, x0, y0); |
|||
end; |
|||
mp_printf ('%.20000Ff'+nl, @x0); |
|||
mp_printf ('%.20000Ff'+nl+nl, @y0); |
|||
end.</syntaxhighlight> |
|||
Output is as long as the C example. |
|||
=={{header|Perl}}== |
|||
<syntaxhighlight lang="perl">#!/usr/bin/perl -w |
|||
my ($a0, $g0, $a1, $g1); |
|||
sub agm($$) { |
|||
$a0 = shift; |
|||
$g0 = shift; |
|||
do { |
|||
$a1 = ($a0 + $g0)/2; |
|||
$g1 = sqrt($a0 * $g0); |
|||
$a0 = ($a1 + $g1)/2; |
|||
$g0 = sqrt($a1 * $g1); |
|||
} while ($a0 != $a1); |
|||
return $a0; |
|||
} |
|||
print agm(1, 1/sqrt(2))."\n";</syntaxhighlight> |
|||
Output: |
|||
<pre>0.847213084793979</pre> |
|||
=={{header|Phix}}== |
|||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">agm</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">g</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">tolerance</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1.0e-15</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">while</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">-</span><span style="color: #000000;">g</span><span style="color: #0000FF;">)></span><span style="color: #000000;">tolerance</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">g</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{(</span><span style="color: #000000;">a</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">g</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">*</span><span style="color: #000000;">g</span><span style="color: #0000FF;">)}</span> |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%0.15g\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">a</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #0000FF;">?</span><span style="color: #000000;">agm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">))</span> <span style="color: #000080;font-style:italic;">-- (rounds to 10 d.p.)</span> |
|||
<!--</syntaxhighlight>--> |
|||
{{out}} |
|||
<pre> |
|||
0.853553390593274 |
|||
0.847224902923494 |
|||
0.847213084835193 |
|||
0.847213084793979 |
|||
0.8472130848 |
|||
</pre> |
|||
=={{header|Phixmonti}}== |
|||
<syntaxhighlight lang="phixmonti">include ..\Utilitys.pmt |
|||
1.0e-15 var tolerance |
|||
def test |
|||
over over - abs tolerance > |
|||
enddef |
|||
def agm /# n1 n2 -- n3 #/ |
|||
test while |
|||
over over + 2 / rot rot * sqrt |
|||
test endwhile |
|||
enddef |
|||
1 1 2 sqrt / agm tostr ?</syntaxhighlight> |
|||
=={{header|PHP}}== |
|||
<syntaxhighlight lang="php"> |
|||
define('PRECISION', 13); |
|||
function agm($a0, $g0, $tolerance = 1e-10) |
|||
{ |
|||
// the bc extension deals in strings and cannot convert |
|||
// floats in scientific notation by itself - hence |
|||
// this manual conversion to a string |
|||
$limit = number_format($tolerance, PRECISION, '.', ''); |
|||
$an = $a0; |
|||
$gn = $g0; |
|||
do { |
|||
list($an, $gn) = array( |
|||
bcdiv(bcadd($an, $gn), 2), |
|||
bcsqrt(bcmul($an, $gn)), |
|||
); |
|||
} while (bccomp(bcsub($an, $gn), $limit) > 0); |
|||
return $an; |
|||
} |
|||
bcscale(PRECISION); |
|||
echo agm(1, 1 / bcsqrt(2)); |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
0.8472130848350 |
|||
</pre> |
|||
=={{header|Picat}}== |
|||
<syntaxhighlight lang="picat">main => |
|||
println(agm(1.0, 1/sqrt(2))). |
|||
agm(A,G) = A, A-G < 1.0e-10 => true. |
|||
agm(A,G) = agm((A+G)/2, sqrt(A*G)). |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
0.847213084835193 |
|||
</pre> |
|||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang="picolisp">(scl 80) |
||
(de agm (A G) |
(de agm (A G) |
||
(do 7 |
(do 7 |
||
(prog1 (/ (+ A G) 2) |
(prog1 (/ (+ A G) 2) |
||
(setq G (sqrt |
(setq G (sqrt A G) A @) ) ) ) |
||
(round |
(round |
||
(agm 1.0 (*/ 1.0 1.0 (sqrt |
(agm 1.0 (*/ 1.0 1.0 (sqrt 2.0 1.0))) |
||
70 )</ |
70 )</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>-> "0.8472130847939790866064991234821916364814459103269421850605793726597340"</pre> |
<pre>-> "0.8472130847939790866064991234821916364814459103269421850605793726597340"</pre> |
||
=={{header|PureBasic}}== |
|||
<lang purebasic>Procedure.d AGM(a.d, g.d, ErrLim.d=1e-15) |
|||
Protected.d ta=a+1, tg |
|||
While ta <> a |
|||
ta=a: tg=g |
|||
a=(ta+tg)*0.5 |
|||
g=Sqr(ta*tg) |
|||
Wend |
|||
ProcedureReturn a |
|||
EndProcedure |
|||
=={{header|PL/I}}== |
|||
If OpenConsole() |
|||
<syntaxhighlight lang="pl/i"> |
|||
PrintN(StrD(AGM(1, 1/Sqr(2)), 16)) |
|||
arithmetic_geometric_mean: /* 31 August 2012 */ |
|||
Input() |
|||
procedure options (main); |
|||
CloseConsole() |
|||
declare (a, g, t) float (18); |
|||
EndIf</lang> |
|||
a = 1; g = 1/sqrt(2.0q0); |
|||
0.8472130847939792 |
|||
put skip list ('The arithmetic-geometric mean of ' || a || ' and ' || g || ':'); |
|||
do until (abs(a-g) < 1e-15*a); |
|||
t = (a + g)/2; g = sqrt(a*g); |
|||
a = t; |
|||
put skip data (a, g); |
|||
end; |
|||
put skip list ('The result is:', a); |
|||
end arithmetic_geometric_mean; |
|||
</syntaxhighlight> |
|||
Results: |
|||
<pre> |
|||
The arithmetic-geometric mean of 1.00000000000000000E+0000 and 7.07106781186547524E-0001: |
|||
A= 8.53553390593273762E-0001 G= 8.40896415253714543E-0001; |
|||
A= 8.47224902923494153E-0001 G= 8.47201266746891460E-0001; |
|||
A= 8.47213084835192807E-0001 G= 8.47213084752765367E-0001; |
|||
A= 8.47213084793979087E-0001 G= 8.47213084793979087E-0001; |
|||
The result is: 8.47213084793979087E-0001 |
|||
</pre> |
|||
=={{header|Potion}}== |
|||
Input values should be floating point |
|||
<syntaxhighlight lang="potion">sqrt = (x) : |
|||
xi = 1 |
|||
7 times : |
|||
xi = (xi + x / xi) / 2 |
|||
. |
|||
xi |
|||
. |
|||
agm = (x, y) : |
|||
7 times : |
|||
a = (x + y) / 2 |
|||
g = sqrt(x * y) |
|||
x = a |
|||
y = g |
|||
. |
|||
x |
|||
.</syntaxhighlight> |
|||
=={{header|PowerShell}}== |
|||
<syntaxhighlight lang="powershell"> |
|||
function agm ([Double]$a, [Double]$g) { |
|||
[Double]$eps = 1E-15 |
|||
[Double]$a1 = [Double]$g1 = 0 |
|||
while([Math]::Abs($a - $g) -gt $eps) { |
|||
$a1, $g1 = $a, $g |
|||
$a = ($a1 + $g1)/2 |
|||
$g = [Math]::Sqrt($a1*$g1) |
|||
} |
|||
[pscustomobject]@{ |
|||
a = "$a" |
|||
g = "$g" |
|||
} |
|||
} |
|||
agm 1 (1/[Math]::Sqrt(2)) |
|||
</syntaxhighlight> |
|||
<b>Output:</b> |
|||
<pre> |
|||
a g |
|||
- - |
|||
0.847213084793979 0.847213084793979 |
|||
</pre> |
|||
=={{header|Prolog}}== |
|||
<syntaxhighlight lang="prolog"> |
|||
agm(A,G,A) :- abs(A-G) < 1.0e-15, !. |
|||
agm(A,G,Res) :- A1 is (A+G)/2.0, G1 is sqrt(A*G),!, agm(A1,G1,Res). |
|||
?- agm(1,1/sqrt(2),Res). |
|||
Res = 0.8472130847939792. |
|||
</syntaxhighlight> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
The calculation generates two new values from two existing values which is the classic example for the use of [https://docs.python.org/3/reference/simple_stmts.html#grammar-token-target_list assignment to a list of values in the one statement], so ensuring a<sub>n</sub> g<sub>n</sub> are only calculated from a<sub>n-1</sub> g<sub>n-1</sub>. |
|||
{{libheader| Math}} |
|||
<lang python> |
|||
from math import sqrt |
|||
######################################################### |
|||
# Calculating the arithmetic-geometric |
|||
# mean of two numbers a0, g0. |
|||
# |
|||
# tolerance the tolerance for the converged |
|||
# value of the arithmetic-geometric mean |
|||
# (default value = 1e-10) |
|||
#-------------------------------------------------------- |
|||
def agm(a0,g0,tolerance=1e-10): |
|||
[an, gn] = [(a0+g0)/2.0, sqrt(a0*g0)] |
|||
while abs(an-gn)>tolerance: |
|||
[an, gn] = [(an+gn)/2.0, sqrt(an*gn)] |
|||
return an |
|||
######################################################### |
|||
===Basic Version=== |
|||
print agm(1,1/sqrt(2)) |
|||
<syntaxhighlight lang="python">from math import sqrt |
|||
</lang> |
|||
Output: |
|||
def agm(a0, g0, tolerance=1e-10): |
|||
""" |
|||
Calculating the arithmetic-geometric mean of two numbers a0, g0. |
|||
tolerance the tolerance for the converged |
|||
value of the arithmetic-geometric mean |
|||
(default value = 1e-10) |
|||
""" |
|||
an, gn = (a0 + g0) / 2.0, sqrt(a0 * g0) |
|||
while abs(an - gn) > tolerance: |
|||
an, gn = (an + gn) / 2.0, sqrt(an * gn) |
|||
return an |
|||
print agm(1, 1 / sqrt(2))</syntaxhighlight> |
|||
{{out}} |
|||
<pre> 0.847213084835</pre> |
<pre> 0.847213084835</pre> |
||
===Multi-Precision Version=== |
|||
<syntaxhighlight lang="python">from decimal import Decimal, getcontext |
|||
def agm(a, g, tolerance=Decimal("1e-65")): |
|||
while True: |
|||
a, g = (a + g) / 2, (a * g).sqrt() |
|||
if abs(a - g) < tolerance: |
|||
return a |
|||
getcontext().prec = 70 |
|||
print agm(Decimal(1), 1 / Decimal(2).sqrt())</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.847213084793979086606499123482191636481445910326942185060579372659734</pre> |
|||
All the digits shown are correct. |
|||
=={{header|Quackery}}== |
|||
<syntaxhighlight lang="quackery"> [ $ "bigrat.qky" loadfile ] now! |
|||
[ temp put |
|||
[ 2over 2over temp share approx= |
|||
iff 2drop done |
|||
2over 2over v* |
|||
temp share vsqrt drop |
|||
dip [ dip [ v+ 2 n->v v/ ] ] |
|||
again ] |
|||
base share temp take ** round ] is agm ( n/d n/d n --> n/d ) |
|||
1 n->v |
|||
2 n->v 125 vsqrt drop 1/v |
|||
125 agm |
|||
2dup |
|||
125 point$ echo$ cr cr |
|||
swap say "Num: " echo cr |
|||
say "Den: " echo</syntaxhighlight> |
|||
{{out}} |
|||
Rational approximation good to 125 decimal places. |
|||
<pre>0.84721308479397908660649912348219163648144591032694218506057937265973400483413475972320029399461122994212228562523341096309796 |
|||
Num: 25070388762104643854110087231213532104992429267859552974434367463980830062627660152123462048041692668477424160883635235463565 |
|||
Den: 29591597689029002472001305353032599592592702596663142670993392754036951453351898973702304260474345315746065192782388085181246 |
|||
</pre> |
|||
=={{header|R}}== |
|||
<syntaxhighlight lang="r">arithmeticMean <- function(a, b) { (a + b)/2 } |
|||
geometricMean <- function(a, b) { sqrt(a * b) } |
|||
arithmeticGeometricMean <- function(a, b) { |
|||
rel_error <- abs(a - b) / pmax(a, b) |
|||
if (all(rel_error < .Machine$double.eps, na.rm=TRUE)) { |
|||
agm <- a |
|||
return(data.frame(agm, rel_error)); |
|||
} |
|||
Recall(arithmeticMean(a, b), geometricMean(a, b)) |
|||
} |
|||
agm <- arithmeticGeometricMean(1, 1/sqrt(2)) |
|||
print(format(agm, digits=16))</syntaxhighlight> |
|||
{{out}} |
|||
<pre> agm rel_error |
|||
1 0.8472130847939792 1.310441309927519e-16</pre> |
|||
This function also works on vectors a and b (following the spirit of R): |
|||
<syntaxhighlight lang="r">a <- c(1, 1, 1) |
|||
b <- c(1/sqrt(2), 1/sqrt(3), 1/2) |
|||
agm <- arithmeticGeometricMean(a, b) |
|||
print(format(agm, digits=16))</syntaxhighlight> |
|||
{{out}} |
|||
<pre> agm rel_error |
|||
1 0.8472130847939792 1.310441309927519e-16 |
|||
2 0.7741882646460426 0.000000000000000e+00 |
|||
3 0.7283955155234534 0.000000000000000e+00</pre> |
|||
=={{header|Racket}}== |
|||
This version uses Racket's normal numbers: |
|||
<syntaxhighlight lang="racket"> |
|||
#lang racket |
|||
(define (agm a g [ε 1e-15]) |
|||
(if (<= (- a g) ε) |
|||
a |
|||
(agm (/ (+ a g) 2) (sqrt (* a g)) ε))) |
|||
(agm 1 (/ 1 (sqrt 2))) |
|||
</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
0.8472130847939792 |
|||
</pre> |
|||
This alternative version uses arbitrary precision floats: |
|||
<syntaxhighlight lang="racket"> |
|||
#lang racket |
|||
(require math/bigfloat) |
|||
(bf-precision 200) |
|||
(bfagm 1.bf (bf/ (bfsqrt 2.bf))) |
|||
</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
(bf #e0.84721308479397908660649912348219163648144591032694218506057918) |
|||
</pre> |
|||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
<syntaxhighlight lang="raku" line>sub agm( $a is copy, $g is copy ) { |
|||
($a, $g) = ($a + $g)/2, sqrt $a * $g until $a ≅ $g; |
|||
return $a; |
|||
} |
|||
say agm 1, 1/sqrt 2;</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.84721308479397917</pre> |
|||
It's also possible to write it recursively: |
|||
<syntaxhighlight lang="raku" line>sub agm( $a, $g ) { |
|||
$a ≅ $g ?? $a !! agm(|@$_) |
|||
given ($a + $g)/2, sqrt $a * $g; |
|||
} |
|||
say agm 1, 1/sqrt 2;</syntaxhighlight> |
|||
We can also get a bit fancy and use a converging sequence of complex numbers: |
|||
<syntaxhighlight lang=raku>sub agm { |
|||
($^z, {(.re+.im)/2 + (.re*.im).sqrt*1i} ... * ≅ *) |
|||
.tail.re |
|||
} |
|||
say agm 1 + 1i/2.sqrt</syntaxhighlight> |
|||
=={{header|Raven}}== |
|||
<syntaxhighlight lang="raven">define agm use $a, $g, $errlim |
|||
# $errlim $g $a "%d %g %d\n" print |
|||
$a 1.0 + as $t |
|||
repeat $a 1.0 * $g - abs -15 exp10 $a * > while |
|||
$a $g + 2 / as $t |
|||
$a $g * sqrt as $g |
|||
$t as $a |
|||
$g $a $t "t: %g a: %g g: %g\n" print |
|||
$a |
|||
16 1 2 sqrt / 1 agm "agm: %.15g\n" print</syntaxhighlight> |
|||
{{out}} |
|||
<pre>t: 0.853553 a: 0.853553 g: 0.840896 |
|||
t: 0.847225 a: 0.847225 g: 0.847201 |
|||
t: 0.847213 a: 0.847213 g: 0.847213 |
|||
t: 0.847213 a: 0.847213 g: 0.847213 |
|||
agm: 0.847213084793979</pre> |
|||
=={{header|Relation}}== |
|||
<syntaxhighlight lang="relation"> |
|||
function agm(x,y) |
|||
set a = x |
|||
set g = y |
|||
while abs(a - g) > 0.00000000001 |
|||
set an = (a + g)/2 |
|||
set gn = sqrt(a * g) |
|||
set a = an |
|||
set g = gn |
|||
set i = i + 1 |
|||
end while |
|||
set result = g |
|||
end function |
|||
set x = 1 |
|||
set y = 1/sqrt(2) |
|||
echo (x + y)/2 |
|||
echo sqrt(x+y) |
|||
echo agm(x,y) |
|||
</syntaxhighlight> |
|||
<pre> |
|||
0.853553391 |
|||
0.840896415 |
|||
0.847213085 |
|||
</pre> |
|||
=={{header|REXX}}== |
|||
Also, this version of the AGM REXX program has three ''short circuits'' within it for an equality case and for two zero cases. |
|||
REXX supports arbitrary precision, so the default digits can be changed if desired. |
|||
<syntaxhighlight lang="rexx">/*REXX program calculates the AGM (arithmetic─geometric mean) of two (real) numbers. */ |
|||
parse arg a b digs . /*obtain optional numbers from the C.L.*/ |
|||
if digs=='' | digs=="," then digs= 120 /*No DIGS specified? Then use default.*/ |
|||
numeric digits digs /*REXX will use lots of decimal digits.*/ |
|||
if a=='' | a=="," then a= 1 /*No A specified? Then use the default*/ |
|||
if b=='' | b=="," then b= 1 / sqrt(2) /* " B " " " " " */ |
|||
call AGM a,b /*invoke the AGM function. */ |
|||
say '1st # =' a /*display the A value. */ |
|||
say '2nd # =' b /* " " B " */ |
|||
say ' AGM =' agm(a, b) /* " " AGM " */ |
|||
exit 0 /*stick a fork in it, we're all done. */ |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
agm: procedure: parse arg x,y; if x=y then return x /*is this an equality case?*/ |
|||
if y=0 then return 0 /*is Y equal to zero ? */ |
|||
if x=0 then return y/2 /* " X " " " */ |
|||
d= digits() /*obtain the current decimal digits. */ |
|||
numeric digits d + 5 /*add 5 more digs to ensure convergence*/ |
|||
tiny= '1e-' || (digits() - 1) /*construct a pretty tiny REXX number. */ |
|||
ox= x + 1 /*ensure that the old X ¬= new X. */ |
|||
do while ox\=x & abs(ox)>tiny /*compute until the old X ≡ new X. */ |
|||
ox= x; oy= y /*save the old value of X and Y. */ |
|||
x= (ox + oy) * .5 /*compute " new " " X. */ |
|||
y= sqrt(ox * oy) /* " " " " " Y. */ |
|||
end /*while*/ |
|||
numeric digits d /*restore the original decimal digits. */ |
|||
return x / 1 /*normalize X to new " " */ |
|||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
|||
sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); m.=9; numeric form; h=d+6 |
|||
numeric digits; parse value format(x,2,1,,0) 'E0' with g 'E' _ .; g=g *.5'e'_ % 2 |
|||
do j=0 while h>9; m.j=h; h=h % 2 + 1; end /*j*/ |
|||
do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g)*.5; end /*k*/; return g</syntaxhighlight> |
|||
{{out|output|text= when using the default input:}} |
|||
<pre> |
|||
1st # = 1 |
|||
2nd # = 0.707106781186547524400844362104849039284835937688474036588339868995366239231053519425193767163820786367506923115456148513 |
|||
AGM = 0.847213084793979086606499123482191636481445910326942185060579372659734004834134759723200293994611229942122285625233410963 |
|||
</pre> |
|||
=={{header|Ring}}== |
|||
<syntaxhighlight lang="ring"> |
|||
decimals(9) |
|||
see agm(1, 1/sqrt(2)) + nl |
|||
see agm(1,1/pow(2,0.5)) + nl |
|||
func agm agm,g |
|||
while agm |
|||
an = (agm + g)/2 |
|||
gn = sqrt(agm*g) |
|||
if fabs(agm-g) <= fabs(an-gn) exit ok |
|||
agm = an |
|||
g = gn |
|||
end |
|||
return gn |
|||
</syntaxhighlight> |
|||
=={{header|RPL}}== |
|||
≪ 1E-10 → epsilon |
|||
≪ '''WHILE''' DUP2 - ABS epsilon > '''REPEAT''' |
|||
DUP2 + 2 / ROT ROT * √ |
|||
'''END''' DROP |
|||
≫ ≫ ‘'''AGM'''’ STO |
|||
{{in}} |
|||
<pre> |
|||
1 2 / √ AGM |
|||
</pre> |
|||
{{out}} |
|||
<pre> |
|||
1: .847213084835 |
|||
</pre> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
===Flt Version=== |
|||
The thing to note about this implementation is that it uses the [http://flt.rubyforge.org/ Flt] library for high-precision math. This lets you adapt context (including precision and epsilon) to a ridiculous-in-real-life degree. |
The thing to note about this implementation is that it uses the [http://flt.rubyforge.org/ Flt] library for high-precision math. This lets you adapt context (including precision and epsilon) to a ridiculous-in-real-life degree. |
||
<syntaxhighlight lang="ruby"># The flt package (http://flt.rubyforge.org/) is useful for high-precision floating-point math. |
|||
<lang ruby> |
|||
# |
|||
# The flt package (http://flt.rubyforge.org/) is useful for high-precision floating-point math. |
|||
# It lets us control 'context' of numbers, individually or collectively -- including precision |
# It lets us control 'context' of numbers, individually or collectively -- including precision |
||
# (which adjusts the context's value of epsilon accordingly). |
# (which adjusts the context's value of epsilon accordingly). |
||
Line 259: | Line 3,063: | ||
BinNum.Context.precision = 512 # default 53 (bits) |
BinNum.Context.precision = 512 # default 53 (bits) |
||
def |
def agm(a,g) |
||
new_a = BinNum a |
new_a = BinNum a |
||
new_g = BinNum g |
new_g = BinNum g |
||
Line 270: | Line 3,074: | ||
end |
end |
||
puts |
puts agm(1, 1 / BinNum(2).sqrt)</syntaxhighlight> |
||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>0.84721308479397908660649912348219163648144591032694218506057937265973400483413475972320029399461122994212228562523341096309796266583087105969971363598338426</pre> |
<pre>0.84721308479397908660649912348219163648144591032694218506057937265973400483413475972320029399461122994212228562523341096309796266583087105969971363598338426</pre> |
||
Adjusting the precision setting (at about line 9) will of course affect this. :-) |
Adjusting the precision setting (at about line 9) will of course affect this. :-) |
||
===BigDecimal Version=== |
|||
Ruby has a BigDecimal class in standard library |
|||
<syntaxhighlight lang="ruby">require 'bigdecimal' |
|||
PRECISION = 100 |
|||
EPSILON = 0.1 ** (PRECISION/2) |
|||
BigDecimal::limit(PRECISION) |
|||
def agm(a,g) |
|||
while a - g > EPSILON |
|||
a, g = (a+g)/2, (a*g).sqrt(PRECISION) |
|||
end |
|||
[a, g] |
|||
end |
|||
a = BigDecimal(1) |
|||
g = 1 / BigDecimal(2).sqrt(PRECISION) |
|||
puts agm(a, g)</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
0.847213084793979086606499123482191636481445910326942185060579372659734004834134759723201915677745718E0 |
|||
0.8472130847939790866064991234821916364814459103269421850605793726597340048341347597231986723114767413E0 |
|||
</pre> |
|||
=={{header|Rust}}== |
|||
<syntaxhighlight lang="rust">// Accepts two command line arguments |
|||
// cargo run --name agm arg1 arg2 |
|||
fn main () { |
|||
let mut args = std::env::args(); |
|||
let x = args.nth(1).expect("First argument not specified.").parse::<f32>().unwrap(); |
|||
let y = args.next().expect("Second argument not specified.").parse::<f32>().unwrap(); |
|||
let result = agm(x,y); |
|||
println!("The arithmetic-geometric mean is {}", result); |
|||
} |
|||
fn agm (x: f32, y: f32) -> f32 { |
|||
let e: f32 = 0.000001; |
|||
let mut a = x; |
|||
let mut g = y; |
|||
let mut a1: f32; |
|||
let mut g1: f32; |
|||
if a * g < 0f32 { panic!("The arithmetric-geometric mean is undefined for numbers less than zero!"); } |
|||
else { |
|||
loop { |
|||
a1 = (a + g) / 2.; |
|||
g1 = (a * g).sqrt(); |
|||
a = a1; |
|||
g = g1; |
|||
if (a - g).abs() < e { return a; } |
|||
} |
|||
} |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
Output of running with arguments 1, 0.70710678: |
|||
<pre> |
|||
The arithmetic-geometric mean is 1.456791 |
|||
</pre> |
|||
=={{header|Scala}}== |
|||
<syntaxhighlight lang="scala"> |
|||
def agm(a: Double, g: Double, eps: Double): Double = { |
|||
if (math.abs(a - g) < eps) (a + g) / 2 |
|||
else agm((a + g) / 2, math.sqrt(a * g), eps) |
|||
} |
|||
agm(1, math.sqrt(2)/2, 1e-15) |
|||
</syntaxhighlight> |
|||
=={{header|Scheme}}== |
|||
<syntaxhighlight lang="scheme"> |
|||
(define agm |
|||
(case-lambda |
|||
((a0 g0) ; call again with default value for tolerance |
|||
(agm a0 g0 1e-8)) |
|||
((a0 g0 tolerance) ; called with three arguments |
|||
(do ((a a0 (* (+ a g) 1/2)) |
|||
(g g0 (sqrt (* a g)))) |
|||
((< (abs (- a g)) tolerance) a))))) |
|||
(display (agm 1 (/ 1 (sqrt 2)))) (newline) |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
0.8472130848351929 |
|||
</pre> |
|||
=={{header|Seed7}}== |
|||
<syntaxhighlight lang="seed7">$ 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;</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1.456791 |
|||
0.847213 |
|||
</pre> |
|||
=={{header|SequenceL}}== |
|||
<syntaxhighlight lang="sequencel">import <Utilities/Math.sl>; |
|||
agm(a, g) := |
|||
let |
|||
iota := 1.0e-15; |
|||
arithmeticMean := 0.5 * (a + g); |
|||
geometricMean := sqrt(a * g); |
|||
in |
|||
a when abs(a-g) < iota |
|||
else |
|||
agm(arithmeticMean, geometricMean); |
|||
main := agm(1.0, 1.0 / sqrt(2));</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
0.847213 |
|||
</pre> |
|||
=={{header|Sidef}}== |
|||
<syntaxhighlight lang="ruby">func agm(a, g) { |
|||
loop { |
|||
var (a1, g1) = ((a+g)/2, sqrt(a*g)) |
|||
[a1,g1] == [a,g] && return a |
|||
(a, g) = (a1, g1) |
|||
} |
|||
} |
|||
say agm(1, 1/sqrt(2))</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.8472130847939790866064991234821916364814</pre> |
|||
=={{header|Smalltalk}}== |
|||
{{works with|Smalltalk/X}} |
|||
That is simply a copy/paste of the already existing agm method in the Number class: |
|||
<syntaxhighlight lang="smalltalk">agm:y |
|||
"return the arithmetic-geometric mean agm(x, y) |
|||
of the receiver (x) and the argument, y. |
|||
See https://en.wikipedia.org/wiki/Arithmetic-geometric_mean" |
|||
|ai an gi gn epsilon delta| |
|||
ai := (self + y) / 2. |
|||
gi := (self * y) sqrt. |
|||
epsilon := self ulp. |
|||
[ |
|||
an := (ai + gi) / 2. |
|||
gn := (ai * gi) sqrt. |
|||
delta := (an - ai) abs. |
|||
ai := an. |
|||
gi := gn. |
|||
] doUntil:[ delta < epsilon ]. |
|||
^ ai</syntaxhighlight> |
|||
<syntaxhighlight lang="smalltalk">Transcript showCR: (24 agm:6). |
|||
Transcript showCR: ( (1/2) agm:(1/6) ). |
|||
Transcript showCR: (1 agm:(1 / 2 sqrt)).</syntaxhighlight> |
|||
{{out}} |
|||
<pre>13.4581714817256 |
|||
0.310602797207483 |
|||
0.847213084793979</pre> |
|||
=={{header|SQL}}== |
|||
{{works with|oracle|11.2 and higher}} |
|||
The solution uses recursive WITH clause (aka recursive CTE, recursive query, recursive factored subquery). Some, perhaps many, but not all SQL dialects support recursive WITH clause. The solution below was written and tested in Oracle SQL - Oracle has supported recursive WITH clause since version 11.2. |
|||
<syntaxhighlight lang="sql">with |
|||
rec (rn, a, g, diff) as ( |
|||
select 1, 1, 1/sqrt(2), 1 - 1/sqrt(2) |
|||
from dual |
|||
union all |
|||
select rn + 1, (a + g)/2, sqrt(a * g), (a + g)/2 - sqrt(a * g) |
|||
from rec |
|||
where diff > 1e-38 |
|||
) |
|||
select * |
|||
from rec |
|||
where diff <= 1e-38 |
|||
;</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
RN A G DIFF |
|||
-- ----------------------------------------- ------------------------------------------ ------------------------------------------ |
|||
6 0.847213084793979086606499123482191636480 0.8472130847939790866064991234821916364792 0.0000000000000000000000000000000000000008</pre> |
|||
=={{header|Standard ML}}== |
|||
<syntaxhighlight lang="sml"> |
|||
fun agm(a, g) = let |
|||
fun agm'(a, g, eps) = |
|||
if Real.abs(a-g) < eps then |
|||
a |
|||
else |
|||
agm'((a+g)/2.0, Math.sqrt(a*g), eps) |
|||
in agm'(a, g, 1e~15) |
|||
end; |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
agm(1.0, 1.0/Math.sqrt(2.0)) => 0.847213084794 |
|||
</pre> |
|||
=={{header|Stata}}== |
|||
<syntaxhighlight lang="stata">mata |
|||
real scalar agm(real scalar a, real scalar b) { |
|||
real scalar c |
|||
do { |
|||
c=0.5*(a+b) |
|||
b=sqrt(a*b) |
|||
a=c |
|||
} while (a-b>1e-15*a) |
|||
return(0.5*(a+b)) |
|||
} |
|||
agm(1,1/sqrt(2)) |
|||
end</syntaxhighlight> |
|||
{{out}} |
|||
<pre>.8472130848</pre> |
|||
=={{header|Swift}}== |
|||
<syntaxhighlight lang="swift">import Darwin |
|||
enum AGRError : Error { |
|||
case undefined |
|||
} |
|||
func agm(_ a: Double, _ g: Double, _ iota: Double = 1e-8) throws -> Double { |
|||
var a = a |
|||
var g = g |
|||
var a1: Double = 0 |
|||
var g1: Double = 0 |
|||
guard a * g >= 0 else { |
|||
throw AGRError.undefined |
|||
} |
|||
while abs(a - g) > iota { |
|||
a1 = (a + g) / 2 |
|||
g1 = sqrt(a * g) |
|||
a = a1 |
|||
g = g1 |
|||
} |
|||
return a |
|||
} |
|||
do { |
|||
try print(agm(1, 1 / sqrt(2))) |
|||
} catch { |
|||
print("agr is undefined when a * g < 0") |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.847213084835193</pre> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
The tricky thing about this implementation is that despite the finite precision available to IEEE doubles (which Tcl uses in its implementation of floating point arithmetic, in common with many other languages) the sequence of values does not ''quite'' converge to a single value; it gets to within a ULP and then errors prevent it from getting closer. This means that an additional termination condition is required: once a value does not change (hence the <code>old_b</code> variable) we have got as close as we can. Note also that we are using exact equality with floating point; this is reasonable because this is a rapidly converging sequence (it only takes 4 iterations in this case). |
The tricky thing about this implementation is that despite the finite precision available to IEEE doubles (which Tcl uses in its implementation of floating point arithmetic, in common with many other languages) the sequence of values does not ''quite'' converge to a single value; it gets to within a ULP and then errors prevent it from getting closer. This means that an additional termination condition is required: once a value does not change (hence the <code>old_b</code> variable) we have got as close as we can. Note also that we are using exact equality with floating point; this is reasonable because this is a rapidly converging sequence (it only takes 4 iterations in this case). |
||
< |
<syntaxhighlight lang="tcl">proc agm {a b} { |
||
set old_b [expr {$b<0?inf:-inf}] |
set old_b [expr {$b<0?inf:-inf}] |
||
while {$a != $b && $b != $old_b} { |
while {$a != $b && $b != $old_b} { |
||
Line 288: | Line 3,378: | ||
} |
} |
||
puts [agm 1 [expr 1/sqrt(2)]]</ |
puts [agm 1 [expr 1/sqrt(2)]]</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>0.8472130847939792</pre> |
<pre>0.8472130847939792</pre> |
||
=={{header|TI SR-56}}== |
|||
{| class="wikitable" |
|||
|+ Texas Instruments SR-56 Program Listing for "Arithmetic-geometric mean" |
|||
|- |
|||
! Display !! Key !! Display !! Key !! Display !! Key !! Display !! Key |
|||
|- |
|||
| 00 33 || STO || 25 03 || 3 || 50 || || 75 || |
|||
|- |
|||
| 01 02 || 2 || 26 12 || INV || 51 || || 76 || |
|||
|- |
|||
| 02 32 || x<>t || 27 44 || EE || 52 || || 77 || |
|||
|- |
|||
| 03 64 || × || 28 41 || R/S || 53 || || 78 || |
|||
|- |
|||
| 04 32 || x<>t || 29 || || 54 || || 79 || |
|||
|- |
|||
| 05 94 || = || 30 || || 55 || || 80 || |
|||
|- |
|||
| 06 48 || *√x || 31 || || 56 || || 81 || |
|||
|- |
|||
| 07 32 || x<>t || 32 || || 57 || || 82 || |
|||
|- |
|||
| 08 84 || + || 33 || || 58 || || 83 || |
|||
|- |
|||
| 09 34 || RCL || 34 || || 59 || || 84 || |
|||
|- |
|||
| 10 02 || 2 || 35 || || 60 || || 85 || |
|||
|- |
|||
| 11 94 || = || 36 || || 61 || || 86 || |
|||
|- |
|||
| 12 54 || ÷ || 37 || || 62 || || 87 || |
|||
|- |
|||
| 13 02 || 2 || 38 || || 63 || || 88 || |
|||
|- |
|||
| 14 94 || = || 39 || || 64 || || 89 || |
|||
|- |
|||
| 15 33 || STO || 40 || || 65 || || 90 || |
|||
|- |
|||
| 16 02 || 2 || 41 || || 66 || || 91 || |
|||
|- |
|||
| 17 44 || EE || 42 || || 67 || || 92 || |
|||
|- |
|||
| 18 94 || = || 43 || || 68 || || 93 || |
|||
|- |
|||
| 19 32 || x<>t || 44 || || 69 || || 94 || |
|||
|- |
|||
| 20 44 || EE || 45 || || 70 || || 95 || |
|||
|- |
|||
| 21 94 || = || 46 || || 71 || || 96 || |
|||
|- |
|||
| 22 12 || INV || 47 || || 72 || || 97 || |
|||
|- |
|||
| 23 37 || *x=t || 48 || || 73 || || 98 || |
|||
|- |
|||
| 24 00 || 0 || 49 || || 74 || || 99 || |
|||
|} |
|||
Asterisk denotes 2nd function key. |
|||
{| class="wikitable" |
|||
|+ Register allocation |
|||
|- |
|||
| 0: Unused || 1: Unused || 2: Previous Term || 3: Unused || 4: Unused |
|||
|- |
|||
| 5: Unused || 6: Unused || 7: Unused || 8: Unused || 9: Unused |
|||
|} |
|||
Annotated listing: |
|||
<syntaxhighlight lang="text"> |
|||
STO 2 x<>t // x := term a, t := R2 := term g |
|||
× x<>t = √x // Calculate term g' |
|||
x<>t + RCL 2 = / 2 = STO 2 // Calculate term a' |
|||
EE = x<>t EE = // Round terms to ten digits |
|||
INV x=t 0 3 // Loop if unequal |
|||
INV EE // Exit scientific notation |
|||
R/S // End |
|||
</syntaxhighlight> |
|||
'''Usage:''' |
|||
Enter term a, press x<>t, then enter term g. Finally, press RST R/S to run the program. |
|||
{{in}} |
|||
<pre> |
|||
1 x<>t 2 √x 1/x RST R/S |
|||
</pre> |
|||
{{out}} |
|||
<pre> |
|||
.8472130848 |
|||
</pre> |
|||
=={{header|UNIX Shell}}== |
|||
{{works with|ksh93}} |
|||
ksh is one of the few unix shells that can do floating point arithmetic (bash does not). |
|||
<syntaxhighlight lang="bash">function agm { |
|||
float a=$1 g=$2 eps=${3:-1e-11} tmp |
|||
while (( abs(a-g) > eps )); do |
|||
print "debug: a=$a\tg=$g" |
|||
tmp=$(( (a+g)/2.0 )) |
|||
g=$(( sqrt(a*g) )) |
|||
a=$tmp |
|||
done |
|||
echo $a |
|||
} |
|||
agm $((1/sqrt(2))) 1</syntaxhighlight> |
|||
{{output}} |
|||
<pre>debug: a=0.7071067812 g=1 |
|||
debug: a=0.8535533906 g=0.8408964153 |
|||
debug: a=0.8472249029 g=0.8472012668 |
|||
debug: a=0.8472130848 g=0.8472130847 |
|||
debug: a=0.8472130848 g=0.8472130848 |
|||
debug: a=0.8472130848 g=0.8472130848 |
|||
0.8472130848</pre> |
|||
You can get a more approximate convergence by changing the while condition to compare the numbers as strings: change <syntaxhighlight lang="bash">while (( abs(a-g) > eps ))</syntaxhighlight> to <syntaxhighlight lang="bash">while [[ $a != $g ]]</syntaxhighlight> |
|||
=={{header|V (Vlang)}}== |
|||
<syntaxhighlight lang="v (vlang)">import math |
|||
const ep = 1e-14 |
|||
fn agm(aa f64, gg f64) f64 { |
|||
mut a, mut g := aa, gg |
|||
for math.abs(a-g) > math.abs(a)*ep { |
|||
t := a |
|||
a, g = (a+g)*.5, math.sqrt(t*g) |
|||
} |
|||
return a |
|||
} |
|||
fn main() { |
|||
println(agm(1.0, 1.0/math.sqrt2)) |
|||
}</syntaxhighlight> |
|||
Using standard math module |
|||
<syntaxhighlight lang="vlang">import math.stats |
|||
import math |
|||
fn main() { |
|||
println(stats.geometric_mean<f64>([1.0, 1.0/math.sqrt2])) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>0.8408964152537145 |
|||
</pre> |
|||
=={{header|Wren}}== |
|||
{{trans|Go}} |
|||
<syntaxhighlight lang="wren">var eps = 1e-14 |
|||
var agm = Fn.new { |a, g| |
|||
while ((a-g).abs > a.abs * eps) { |
|||
var t = a |
|||
a = (a+g)/2 |
|||
g = (t*g).sqrt |
|||
} |
|||
return a |
|||
} |
|||
System.print(agm.call(1, 1/2.sqrt))</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
0.84721308479398 |
|||
</pre> |
|||
=={{header|XPL0}}== |
=={{header|XPL0}}== |
||
< |
<syntaxhighlight lang="xpl0">include c:\cxpl\codesi; |
||
real A, A1, G; |
real A, A1, G; |
||
[Format(0, 16); |
[Format(0, 16); |
||
Line 302: | Line 3,561: | ||
RlOut(0, A); RlOut(0, G); RlOut(0, A-G); CrLf(0); |
RlOut(0, A); RlOut(0, G); RlOut(0, A-G); CrLf(0); |
||
until A=G; |
until A=G; |
||
]</ |
]</syntaxhighlight> |
||
Output: |
Output: |
||
Line 310: | Line 3,569: | ||
8.4721308483519300E-001 8.4721308475276500E-001 8.2427509262572600E-011 |
8.4721308483519300E-001 8.4721308475276500E-001 8.2427509262572600E-011 |
||
8.4721308479397900E-001 8.4721308479397900E-001 0.0000000000000000E+000 |
8.4721308479397900E-001 8.4721308479397900E-001 0.0000000000000000E+000 |
||
</pre> |
|||
=={{header|zkl}}== |
|||
{{trans|XPL0}} |
|||
<syntaxhighlight lang="zkl">a:=1.0; g:=1.0/(2.0).sqrt(); |
|||
while(not a.closeTo(g,1.0e-15)){ |
|||
a1:=(a+g)/2.0; g=(a*g).sqrt(); a=a1; |
|||
println(a," ",g," ",a-g); |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
0.853553 0.840896 0.012657 |
|||
0.847225 0.847201 2.36362e-05 |
|||
0.847213 0.847213 8.24275e-11 |
|||
0.847213 0.847213 1.11022e-16 |
|||
</pre> |
|||
Or, using tail recursion |
|||
<syntaxhighlight lang="zkl">fcn(a=1.0, g=1.0/(2.0).sqrt()){ println(a," ",g," ",a-g); |
|||
if(a.closeTo(g,1.0e-15)) return(a) else return(self.fcn((a+g)/2.0, (a*g).sqrt())); |
|||
}()</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 0.707107 0.292893 |
|||
0.853553 0.840896 0.012657 |
|||
0.847225 0.847201 2.36362e-05 |
|||
0.847213 0.847213 8.24275e-11 |
|||
0.847213 0.847213 1.11022e-16 |
|||
</pre> |
</pre> |
Latest revision as of 08:11, 16 November 2023
You are encouraged to solve this task according to the task description, using any language you may know.
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 , and is equal to the limit of the sequence:
Since the limit of tends (rapidly) to zero with iterations, this is an efficient method.
Demonstrate the function by calculating:
- Also see
11l
F agm(a0, g0, tolerance = 1e-10)
V an = (a0 + g0) / 2.0
V gn = sqrt(a0 * g0)
L abs(an - gn) > tolerance
(an, gn) = ((an + gn) / 2.0, sqrt(an * gn))
R an
print(agm(1, 1 / sqrt(2)))
- Output:
0.847213
360 Assembly
For maximum compatibility, this program uses only the basic instruction set.
AGM CSECT
USING AGM,R13
SAVEAREA B STM-SAVEAREA(R15)
DC 17F'0'
DC CL8'AGM'
STM STM R14,R12,12(R13)
ST R13,4(R15)
ST R15,8(R13)
LR R13,R15
ZAP A,K a=1
ZAP PWL8,K
MP PWL8,K
DP PWL8,=P'2'
ZAP PWL8,PWL8(7)
BAL R14,SQRT
ZAP G,PWL8 g=sqrt(1/2)
WHILE1 EQU * while a!=g
ZAP PWL8,A
SP PWL8,G
CP PWL8,=P'0' (a-g)!=0
BE EWHILE1
ZAP PWL8,A
AP PWL8,G
DP PWL8,=P'2'
ZAP AN,PWL8(7) an=(a+g)/2
ZAP PWL8,A
MP PWL8,G
BAL R14,SQRT
ZAP G,PWL8 g=sqrt(a*g)
ZAP A,AN a=an
B WHILE1
EWHILE1 EQU *
ZAP PWL8,A
UNPK ZWL16,PWL8
MVC CWL16,ZWL16
OI CWL16+15,X'F0'
MVI CWL16,C'+'
CP PWL8,=P'0'
BNM *+8
MVI CWL16,C'-'
MVC CWL80+0(15),CWL16
MVC CWL80+9(1),=C'.' /k (15-6=9)
XPRNT CWL80,80 display a
L R13,4(0,R13)
LM R14,R12,12(R13)
XR R15,R15
BR R14
DS 0F
K DC PL8'1000000' 10^6
A DS PL8
G DS PL8
AN DS PL8
* ****** SQRT *******************
SQRT CNOP 0,4 function sqrt(x)
ZAP X,PWL8
ZAP X0,=P'0' x0=0
ZAP X1,=P'1' x1=1
WHILE2 EQU * while x0!=x1
ZAP PWL8,X0
SP PWL8,X1
CP PWL8,=P'0' (x0-x1)!=0
BE EWHILE2
ZAP X0,X1 x0=x1
ZAP PWL16,X
DP PWL16,X1
ZAP XW,PWL16(8) xw=x/x1
ZAP PWL8,X1
AP PWL8,XW
DP PWL8,=P'2'
ZAP PWL8,PWL8(7)
ZAP X2,PWL8 x2=(x1+xw)/2
ZAP X1,X2 x1=x2
B WHILE2
EWHILE2 EQU *
ZAP PWL8,X1 return x1
BR R14
DS 0F
X DS PL8
X0 DS PL8
X1 DS PL8
X2 DS PL8
XW DS PL8
* end SQRT
PWL8 DC PL8'0'
PWL16 DC PL16'0'
CWL80 DC CL80' '
CWL16 DS CL16
ZWL16 DS ZL16
LTORG
YREGS
END AGM
- Output:
+00000000.84721
8th
: epsilon 1.0e-12 ;
with: n
: iter \ n1 n2 -- n1 n2
2dup * sqrt >r + 2 / r> ;
: agn \ n1 n2 -- n
repeat iter 2dup epsilon ~= not while! drop ;
"agn(1, 1/sqrt(2)) = " . 1 1 2 sqrt / agn "%.10f" s:strfmt . cr
;with
bye
- Output:
agn(1, 1/sqrt(2)) = 0.8472130848
Action!
INCLUDE "H6:REALMATH.ACT"
PROC Agm(REAL POINTER a0,g0,result)
REAL a,g,prevA,tmp,r2
RealAssign(a0,a)
RealAssign(g0,g)
IntToReal(2,r2)
DO
RealAssign(a,prevA)
RealAdd(a,g,tmp)
RealDiv(tmp,r2,a)
RealMult(prevA,g,tmp)
Sqrt(tmp,g)
IF RealGreaterOrEqual(a,prevA) THEN
EXIT
FI
OD
RealAssign(a,result)
RETURN
PROC Main()
REAL r1,r2,tmp,g,res
Put(125) PutE() ;clear screen
MathInit()
IntToReal(1,r1)
IntToReal(2,r2)
Sqrt(r2,tmp)
RealDiv(r1,tmp,g)
Agm(r1,g,res)
Print("agm(") PrintR(r1)
Print(",") PrintR(g)
Print(")=") PrintRE(res)
RETURN
- Output:
Screenshot from Atari 8-bit computer
agm(1,.7071067873)=.847213085
Ada
with Ada.Text_IO, Ada.Numerics.Generic_Elementary_Functions;
procedure Arith_Geom_Mean is
type Num is digits 18; -- the largest value gnat/gcc allows
package N_IO is new Ada.Text_IO.Float_IO(Num);
package Math is new Ada.Numerics.Generic_Elementary_Functions(Num);
function AGM(A, G: Num) return Num is
Old_G: Num;
New_G: Num := G;
New_A: Num := A;
begin
loop
Old_G := New_G;
New_G := Math.Sqrt(New_A*New_G);
New_A := (Old_G + New_A) * 0.5;
exit when (New_A - New_G) <= Num'Epsilon;
-- Num'Epsilon denotes the relative error when performing arithmetic over Num
end loop;
return New_G;
end AGM;
begin
N_IO.Put(AGM(1.0, 1.0/Math.Sqrt(2.0)), Fore => 1, Aft => 17, Exp => 0);
end Arith_Geom_Mean;
Output:
0.84721308479397909
ALGOL 68
Algol 68 Genie gives IEEE double precision for REAL quantities, 28 decimal digits for LONG REALs and, by default, 63 decimal digits for LONG LONG REAL though this can be made arbitrarily greater with a pragmat.
Printing out the difference between the means at each iteration nicely demonstrates the quadratic convergence.
BEGIN
PROC agm = (LONG REAL x, y) LONG REAL :
BEGIN
IF x < LONG 0.0 OR y < LONG 0.0 THEN -LONG 1.0
ELIF x + y = LONG 0.0 THEN LONG 0.0 CO Edge cases CO
ELSE
LONG REAL a := x, g := y;
LONG REAL epsilon := a + g;
LONG REAL next a := (a + g) / LONG 2.0, next g := long sqrt (a * g);
LONG REAL next epsilon := ABS (a - g);
WHILE next epsilon < epsilon
DO
print ((epsilon, " ", next epsilon, newline));
epsilon := next epsilon;
a := next a; g := next g;
next a := (a + g) / LONG 2.0; next g := long sqrt (a * g);
next epsilon := ABS (a - g)
OD;
a
FI
END;
printf (($l(-35,33)l$, agm (LONG 1.0, LONG 1.0 / long sqrt (LONG 2.0))))
END
Output:
+1.707106781186547524400844362e +0 +2.928932188134524755991556379e -1 +2.928932188134524755991556379e -1 +1.265697533955921916929670477e -2 +1.265697533955921916929670477e -2 +2.363617660269221214237489508e -5 +2.363617660269221214237489508e -5 +8.242743980540458935740117000e -11 +8.242743980540458935740117000e -11 +1.002445937606580000000000000e -21 +1.002445937606580000000000000e -21 +4.595001000000000000000000000e -29 +4.595001000000000000000000000e -29 +4.595000000000000000000000000e -29 0.847213084793979086606499123550000
APL
agd←{(⍺-⍵)<10*¯8:⍺⋄((⍺+⍵)÷2)∇(⍺×⍵)*÷2}
1 agd ÷2*÷2
Output:
0.8472130848
AppleScript
By functional composition:
-- ARITHMETIC GEOMETRIC MEAN -------------------------------------------------
property tolerance : 1.0E-5
-- agm :: Num a => a -> a -> a
on agm(a, g)
script withinTolerance
on |λ|(m)
tell m to ((its an) - (its gn)) < tolerance
end |λ|
end script
script nextRefinement
on |λ|(m)
tell m
set {an, gn} to {its an, its gn}
{an:(an + gn) / 2, gn:(an * gn) ^ 0.5}
end tell
end |λ|
end script
an of |until|(withinTolerance, ¬
nextRefinement, {an:(a + g) / 2, gn:(a * g) ^ 0.5})
end agm
-- TEST ----------------------------------------------------------------------
on run
agm(1, 1 / (2 ^ 0.5))
--> 0.847213084835
end run
-- GENERIC FUNCTIONS ---------------------------------------------------------
-- until :: (a -> Bool) -> (a -> a) -> a -> a
on |until|(p, f, x)
set mp to mReturn(p)
set v to x
tell mReturn(f)
repeat until mp's |λ|(v)
set v to |λ|(v)
end repeat
end tell
return v
end |until|
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
- Output:
0.847213084835
Arturo
agm: function [a,g][
delta: 1e-15
[aNew, aOld, gOld]: @[0, a, g]
while [delta < abs aOld - gOld][
aNew: 0.5 * aOld + gOld
gOld: sqrt aOld * gOld
aOld: aNew
]
return aOld
]
print agm 1.0 1.0/sqrt 2.0</lang>
{{out}}
<pre>0.8472130847939792</pre>
=={{header|AutoHotkey}}==
<syntaxhighlight lang="ahk">agm(a, g, tolerance=1.0e-15){
While abs(a-g) > tolerance
{
an := .5 * (a + g)
g := sqrt(a*g)
a := an
}
return a
}
SetFormat, FloatFast, 0.15
MsgBox % agm(1, 1/sqrt(2))
Output:
0.847213084793979
AWK
#!/usr/bin/awk -f
BEGIN {
printf "%.16g\n", agm(1.0,sqrt(0.5))
}
function agm(a,g) {
while (1) {
a0=a
a=(a0+g)/2
g=sqrt(a0*g)
if (abs(a0-a) < abs(a)*1e-15) break
}
return a
}
function abs(x) {
return (x<0 ? -x : x)
}
Output
0.8472130847939792
BASIC
ANSI BASIC
100 PROGRAM ArithmeticGeometricMean
110 FUNCTION AGM (A, G)
120 DO
130 LET TA = (A + G) / 2
140 LET G = SQR(A * G)
150 LET Tmp = A
160 LET A = TA
170 LET TA = Tmp
180 LOOP UNTIL A = TA
190 LET AGM = A
200 END FUNCTION
210 REM ********************
220 PRINT AGM(1, 1 / SQR(2))
230 END
- Output:
.84721308479398
Applesoft BASIC
Same code as Commodore BASIC The BASIC solution works without any changes.
BASIC256
print AGM(1, 1 / sqr(2))
end
function AGM(a, g)
Do
ta = (a + g) / 2
g = sqr(a * g)
x = a
a = ta
ta = x
until a = ta
return a
end function
- Output:
0.84721308479
BBC BASIC
*FLOAT 64
@% = &1010
PRINT FNagm(1, 1/SQR(2))
END
DEF FNagm(a,g)
LOCAL ta
REPEAT
ta = a
a = (a+g)/2
g = SQR(ta*g)
UNTIL a = ta
= a
- Output:
0.8472130847939792
Chipmunk Basic
10 print agm(1,1/sqr(2))
20 end
100 sub agm(a,g)
110 do
120 let ta = (a+g)/2
130 let g = sqr(a*g)
140 let x = a
150 let a = ta
160 let ta = x
170 loop until a = ta
180 agm = a
190 end sub
- Output:
0.847213
Commodore BASIC
10 A = 1
20 G = 1/SQR(2)
30 GOSUB 100
40 PRINT A
50 END
100 TA = A
110 A = (A+G)/2
120 G = SQR(TA*G)
130 IF A<TA THEN 100
140 RETURN
Craft Basic
let a = 1
let g = 1 / sqrt(2)
do
let t = (a + g) / 2
let g = sqrt(a * g)
let x = a
let a = t
let t = x
loopuntil a = t
print a
- Output:
0.85
FreeBASIC
' version 16-09-2015
' compile with: fbc -s console
Function agm(a As Double, g As Double) As Double
Dim As Double t_a
Do
t_a = (a + g) / 2
g = Sqr(a * g)
Swap a, t_a
Loop Until a = t_a
Return a
End Function
' ------=< MAIN >=------
Print agm(1, 1 / Sqr(2) )
' empty keyboard buffer
While InKey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End
- Output:
0.8472130847939792
Gambas
Public Sub Main()
Print AGM(1, 1 / Sqr(2))
End
Function AGM(a As Float, g As Float) As Float
Dim t_a As Float
Do
t_a = (a + g) / 2
g = Sqr(a * g)
Swap a, t_a
Loop Until a = t_a
Return a
End Function
GW-BASIC
10 A = 1
20 G = 1!/SQR(2!)
30 FOR I=1 TO 20 'twenty iterations is plenty
40 B = (A+G)/2
50 G = SQR(A*G)
60 A = B
70 NEXT I
80 PRINT A
IS-BASIC
100 PRINT AGM(1,1/SQR(2))
110 DEF AGM(A,G)
120 DO
130 LET TA=A
140 LET A=(A+G)/2:LET G=SQR(TA*G)
150 LOOP UNTIL A=TA
160 LET AGM=A
170 END DEF
Liberty BASIC
print agm(1, 1/sqr(2))
print using("#.#################",agm(1, 1/sqr(2)))
end
function agm(a,g)
do
absdiff = abs(a-g)
an=(a+g)/2
gn=sqr(a*g)
a=an
g=gn
loop while abs(an-gn)< absdiff
agm = a
end function
- Output:
0.84721308 0.84721308479397904
Minimal BASIC
10 LET A = 1
20 LET G = 1 / SQR(2)
30 GOSUB 60
40 PRINT A
50 STOP
60 LET T = A
70 LET A = (A + G) / 2
80 LET G = SQR(T * G)
90 IF A < T THEN 60
100 RETURN
110 END
- Output:
.84721308
MSX Basic
The Commodore BASIC solution works without any changes.
The GW-BASIC solution works without any changes.
PureBasic
Procedure.d AGM(a.d, g.d, ErrLim.d=1e-15)
Protected.d ta=a+1, tg
While ta <> a
ta=a: tg=g
a=(ta+tg)*0.5
g=Sqr(ta*tg)
Wend
ProcedureReturn a
EndProcedure
If OpenConsole()
PrintN(StrD(AGM(1, 1/Sqr(2)), 16))
Input()
CloseConsole()
EndIf
- Output:
0.8472130847939792
QuickBASIC
PRINT AGM(1, 1 / SQR(2))
END
FUNCTION AGM (a, g)
DO
ta = (a + g) / 2
g = SQR(a * g)
SWAP a, ta
LOOP UNTIL a = ta
AGM = a
END FUNCTION
- Output:
.8472131
Quite BASIC
10 LET A = 1
20 LET G = 1 / SQR(2)
30 GOSUB 100
40 PRINT A
50 END
100 LET T = A
110 LET A = (A + G) / 2
120 LET G = SQR(T * G)
130 IF A < T THEN 100
140 RETURN
- Output:
0.8472130847939792
Run BASIC
print agm(1, 1/sqr(2))
print agm(1,1/2^.5)
print using("#.############################",agm(1, 1/sqr(2)))
function agm(agm,g)
while agm
an = (agm + g)/2
gn = sqr(agm*g)
if abs(agm-g) <= abs(an-gn) then exit while
agm = an
g = gn
wend
end function
- Output:
0.847213085 0.847213085 0.8472130847939791165772005376
Sinclair ZX81 BASIC
Works with 1k of RAM.
The specification calls for a function. Sadly that is not available to us, so this program uses a subroutine: pass the arguments in the global variables A and G, and the result will be returned in AGM. The performance is quite acceptable. Note that the subroutine clobbers A and G, so you should save them if you want to use them again.
Better precision than this is not easily obtainable on the ZX81, unfortunately.
10 LET A=1
20 LET G=1/SQR 2
30 GOSUB 100
40 PRINT AGM
50 STOP
100 LET A0=A
110 LET A=(A+G)/2
120 LET G=SQR (A0*G)
130 IF ABS(A-G)>.00000001 THEN GOTO 100
140 LET AGM=A
150 RETURN
- Output:
0.84721309
TI-83 BASIC
1→A:1/sqrt(2)→G
While abs(A-G)>e-15
(A+G)/2→B
sqrt(AG)→G:B→A
End
A
- Output:
.8472130848
True BASIC
FUNCTION AGM (a, g)
DO
LET ta = (a + g) / 2
LET g = SQR(a * g)
LET x = a
LET a = ta
LET ta = x
LOOP UNTIL a = ta
LET AGM = a
END FUNCTION
PRINT AGM(1, 1 / SQR(2))
END
- Output:
.84721308
VBA
Private Function agm(a As Double, g As Double, Optional tolerance As Double = 0.000000000000001) As Double
Do While Abs(a - g) > tolerance
tmp = a
a = (a + g) / 2
g = Sqr(tmp * g)
Debug.Print a
Loop
agm = a
End Function
Public Sub main()
Debug.Print agm(1, 1 / Sqr(2))
End Sub
- Output:
0,853553390593274 0,847224902923494 0,847213084835193 0,847213084793979 0,847213084793979
VBScript
Function agm(a,g)
Do Until a = tmp_a
tmp_a = a
a = (a + g)/2
g = Sqr(tmp_a * g)
Loop
agm = a
End Function
WScript.Echo agm(1,1/Sqr(2))
- Output:
0.847213084793979
Yabasic
print AGM(1, 1 / sqrt(2))
end
sub AGM(a, g)
repeat
ta = (a + g) / 2
g = sqrt(a * g)
x = a
a = ta
ta = x
until a = ta
return a
end sub
- Output:
0.847213
Visual Basic .NET
Double, Decimal Versions
Imports System.Math
Imports System.Console
Module Module1
Function CalcAGM(ByVal a As Double, ByVal b As Double) As Double
Dim c As Double, d As Double = 0, ld As Double = 1
While ld <> d : c = a : a = (a + b) / 2 : b = Sqrt(c * b)
ld = d : d = a - b : End While : Return b
End Function
Function DecSqRoot(ByVal v As Decimal) As Decimal
Dim r As Decimal = CDec(Sqrt(CDbl(v))), t As Decimal = 0, d As Decimal = 0, ld As Decimal = 1
While ld <> d : t = v / r : r = (r + t) / 2
ld = d : d = t - r : End While : Return t
End Function
Function CalcAGM(ByVal a As Decimal, ByVal b As Decimal) As Decimal
Dim c As Decimal, d As Decimal = 0, ld As Decimal = 1
While ld <> d : c = a : a = (a + b) / 2 : b = DecSqRoot(c * b)
ld = d : d = a - b : End While : Return b
End Function
Sub Main(ByVal args As String())
WriteLine("Double result: {0}", CalcAGM(1.0, DecSqRoot(0.5)))
WriteLine("Decimal result: {0}", CalcAGM(1D, DecSqRoot(0.5D)))
If System.Diagnostics.Debugger.IsAttached Then ReadKey()
End Sub
End Module
- Output:
Double result: 0.847213084793979 Decimal result: 0.8472130847939790866064991235
System.Numerics
Imports System.Math
Imports System.Console
Imports BI = System.Numerics.BigInteger
Module Module1
Function BIP(ByVal leadDig As Char, ByVal numDigs As Integer) As BI
BIP = BI.Parse(leadDig & New String("0"c, numDigs))
End Function
Function IntSqRoot(ByVal v As BI, ByVal res As BI) As BI ' res is the initial guess of the square root
Dim d As BI = 0, dl As BI = 1
While dl <> d : IntSqRoot = v / res : res = (res + IntSqRoot) / 2
dl = d : d = IntSqRoot - res : End While
End Function
Function CalcByAGM(ByVal digits As Integer) As BI
Dim a As BI = BIP("1"c, digits), ' value is 1, extended to required number of digits
c as BI, ' a temporary variable for swapping a and b
diff As BI = 0, ldiff As BI = 1 ' difference of a and b, last difference
CalcByAGM = BI.Parse(String.Format("{0:0.00000000000000000}", ' initial value of square root of 0.5
Sqrt(0.5)).Substring(2) & New String("0"c, digits - 17))
CalcByAGM = IntSqRoot(BIP("5"c, (digits << 1) - 1), CalcByAGM) ' value is now the square root of 0.5
While ldiff <> diff : c = a : a = (a + CalcByAGM) >> 1 : CalcByAGM = IntSqRoot(c * CalcByAGM, a)
ldiff = diff : diff = a - CalcByAGM : End While
End Function
Sub Main(ByVal args As String())
Dim digits As Integer = 25000
If args.Length > 0 Then Integer.TryParse(args(0), digits) : _
If digits < 1 OrElse digits > 999999 Then digits = 25000
WriteLine("0.{0}", CalcByAGM(digits))
If System.Diagnostics.Debugger.IsAttached Then ReadKey()
End Sub
End Module
- Output:
0.8472130847939790866064991234821916364814459103269421850605793726597340048341347597232002939946112299421222856252334109630979626658308710596997136359833842511763268142890603897067686016166500482811887218977133094117674620199443929629021672891944995072316778973468639476066710579805578521731403493983042004221192160398395535950981936412937163406460295999679705994343516020318426487569502421748638554059819545816017424178878541927588041627190120855876856483268341404312184008040358092045594943138778151209265222545743971242868207663409547336745996217926655353486256861185433086262872872875630108355631935706687147856390889821151088363521476969796126218329432284178681137684451700181460219136940270209459966835135963278808042743454817445873632200251539529362658066141983656164916262596074347237066169023530800173753128478525584306319074542749341526857906552694060031475910203327467196861247963255105546489028208552974396512499400966255286606758044873538921857014011677169765350140849524768489932573213370289846689391946658618737529663875622660459147770442046810892565844083803204091061900315370673411959410100747433105990550582052432600995169279241747821697678106168369771411073927334392155014302200708736736596227214925877619285105238036702689046390962190766364423553808590294523406519001334234510583834171218051425500392370111132541114461262890625413355052664365359582455215629339751825147065013464104705697935568130660632937334503871097709729487591717901581732028157828848714993134081549334236779704471278593761859508514667736455467920161593422399714298407078888227903265675159652843581779572728480835648996350440414073422611018338354697596266333042208499985230074270393027724347497971797326455254654301983169496846109869074390506801376611925291977093844129970701588949316666116199459226501131118396635250253056164643158720845452298877547517727274765672164898291823923889520720764283971088470596035692199292183190154814128076659269829446445714923966632997307581390495762243896242317520950731901842446244237098642728114951118082282605386248461767518014098312749725765198375649235690280021617490553142720815343954059556357637112728165705973733744297003905604015638866307222570038923015911237696012158008177907786335124086243107357158376592650454665278733787444483440631024475703968125545398226643035341641303561380163416557526558975294452116687345122019122746673319157124076375382110696814107692639007483317574339675231966033086497357138387419609898383220288269488219130281936694995442224069727616862136951165783888501219909616065545461154325314816424933269479700415949147632311292059351651899794335004597628821729262591808940550843146639378254833513955019065337087206206402407705607584879649984365159272826453442863661541914258577710675618501727803328717519518930503180550524542602233552290077141812879865435118791800635627959362476826778641224946033812608262825409889531252767753465624327921451122955551603181843313369296172304178385515712556740498341666592696958000895372457305769454227537216020968719147039887846636724326270619112707171659082464004167994112040565710364083000241929439855307399465653967781049270105541035951333943219992506667620207839469555376055179640100974921885631130101781388857879381317209594806253920130098365028791769582798590527994772194179799702494306215841946888532811549772157996019440962347768614408507573928429882375939682322367058033413477462311289762585932437663177897491107726190970448952220450963072551559009382490402136480779203476721504856844602255440999282616317431264228578762898338065072202301037175314926350463106018857377256700661838129058063895450812703131137104371613583348806583395543121790134839883321641305763524471251153947206667033010134871651632411382881763983962952612114126321979596509865678675525076076042409590751752302194610453256433324961490125353332922372386894812788502013596630537605584935892839163046940388785496002747148719780145765957904958580226006609952496736432496683346176010660815670697514238186650361083885220976165500251607311499216129477579019972924868963822060380876027628167237016681910663358577515465038133423672234764202655856558846416010210540489855618711473588497637840648642679818650448631907747038228671143515112300360708657429886477146674733750114345818852797006056211724692174847180694866251199472893444270378304620707354938052872720621560630718828685805645211106967080285699069825769177220998671959968507790681443494932804976811543680463259938693076235070999518295129581121235707245383354826190752395158273098248180549665897909168867984071707793705959045775840910473413109604194111357756620727337797833203797301137672658535747710279781409721309612142393854737462769615041307952837372882050658719152259765084027796991761175393006725492491229845082362975568722711065849435533850494532638736489804606655979954360169503092790092450057856477235876198848986034412195340795369002996411974549060741600978859537660722905160772428590070901156639138364299041220826769629797867649032356499981990765997439870548648769091024911927099968275697011368762244046402960383700066212734577664709711326374656811502985863032260337383421358423937896114617192083071953915643782093641496780334152464507396683173198363362743392555311712019454146844880895622417898031894341231284027858378289009624209541345002101072736323285272576209646851994468240550629391742053301706461917215178844296705314335503772310709716080285145314144106105023117310877779933248932087727229897821330120834074305604998159963202687793307156940302439156118926767517249511766526248547096041991473113657920697330996088897286789780735587578500623575157123771653042063631002703129296694025421967877168846655727580898306467662007014679585693082220620905330827782226503112520278733512519159918893900284319218166686548434879621972211763904959895793607330943697457628943200384117552941594754747183936381144125610351023459581080768558985657007445308909428669251190101718122826689349269528261052518556736045877702288147821446968500918347219741420546128072347950059811766364526150190788545471193803557145930744635656260752787518824386409506964649815131170591457990619376560858650175616864501924098327235724333688813080022186368700209641119724303603558649793773314916749593151188673535025505982303047060284740458456676849620934506396302909441632516408692889814507247877727673378033828929504978384342943766566737297587430575141036417476861639624198941904730996100228428079444920026904845254139188246001559089131943255610365769362364161784646693141456109984038312265504115251494445380042090428718182468431624610552637677520970104063944687837375017436089751693486887651283453677552786547090231542029453873076141196649767521919808902105772633472397958968722923357769041244458682297806209887089816018179521454920370956252850733023255060096611329479148443416687429872654204083552056456404421174124065041932362831296643126330768715450444950733554418200793669701331244638824360062439816712409346806322169771701563590417609841261977801052586956634654144702511135382841010278579543061802357275500930513955637771043922799597114118278203358118398952338720119626666828781215343331193353019800652511924103594315072427251589774226901431325149775220621148653209528291784172678852791825950189428306645453380829438548491390660090152646315666940813051689857738445716110134773528439558663918031477128997248977232695083095920860316390860179422146804892537147135669490647597566350405076105930300153453613446834614136284840473063909580064862482211399539962122107992774053203059756987131501429238941821989218445861496845306346078287058864262560349767113385390753047360747520569725532663517964059488138127648519130232826129551720747594498863925111049785977410104647258831744969489273332281068408949475978706769012216951869658194406136694310323411619613160554381608728305543504819071159752742665917363693001980988797627218662628543311906086034280619151845297823703639898449414417889008602782220998390227472837967411429578924346545640402855167478372538831386154780508035236893583332887355879794886804980971406868936719416711504307402575102269081707385928535837390976424975922421061832372517021428320986753744507133218963666908565634963306077455683011837149400258404997766113525532847665618870592978212729899729592794781820428719807102278646183807006401083138975677112754136221127444534535584959769252575758312999039536959893249951324106784265611556743660088737484274038234811784911002123537108015334407708175281579422928548731689863980071896268684985779061942582000173178473797975815609269087287850270024414741281953578873964745859459899535543412801653553049058528794674398220606230386688852700505218904927782197514115595435549125326115087432280435609563176116321811794164884206928474315699133677787956913705592704959893911100786224112449931719539890308215307126971807352814294437374058180589784287101566325873726600012296180403780429093175160473979931236882466314524590792512088916974765430245705320638670468411054034201437664442213212750799846299157010147106552946146746392249574530619682203425444816247545977269653430250686824205288099692448923652171403817749282935917315481284919621433304080904306867233682060716291289398517406255904282247558159509102324206160816363511440953267967974466214658121897383725705201831800678505181233270743236051760236565304605919728246762046497950757124332306210615236617229324468286251110577832854712371857906482302429199129753477340618812393224405123793229248698239302094605799468502209356458018864737205798950819968285087908120645175464792846657029993496146354533816989879012073959534299458051884682918835631136138879631316173442207506218212945047503433730640140356614106403320867621443183928438969994268286836082535591242751488383392264668222963323657488981599104902374571278077062853236895690028469742954774248422335523859049299225453318270693966088603518491166875108552006265340966412611220069290556369052744064893640087015171662929356529921474420793873710647399136453402185931518201576110059405556600166318190916348212818643068418256991194316266715898588673650488980580832972145195811525832974358064432698289209364284959616975339927502383832695801109608954786457256109785378297307074918168744735731189049849490781632210127110919398357638892753131749978321368280932894349330930087868884127092076359007648065118301317440813138170776478562086983456849957696333241556699085937149528437303782174166781012624737754844959408277598042857813775448446192929537153359741871355556678028606484917974827559022377376189703770332489774349235376523557139076431488967144133099539679871046284747721772185865851985971282165739148574494328320308464163956096301047370473988450307936956928683464113764226308568695688152053749196294562881085987015910764955019272667378276517237450013662421051146709184898952269727656206976263055094938932099216377529415335060027109430018977339221845390337351007942764665232509045377940478212355620488638969640291029182673024368888013982750049655688955540362739754118359277009094291839958396298535952123465573707751680432023872401008786292362558484920221296055948232317635214207117650427699747801290249150914873347204981208353486521246233538858471700470120592394582541522312967601307268280232044633644234100026474341568399123881048049819491200940244895720301881220640996997340843736095812449945913231793359333819197360248853375641030435643732302001328359990615298394916710687997693926699033522064083729586994304357670917169796698442332656830732550000321312902706719106342428311390049478179307304556219943912072209495471916547109605404919944186051724981471812994063119290173738101176617356976495636675620278895592099504686163440305250658681735840269428736633431167832903837475658050990783985384926064721246565130660487673608585790218386643241627198210378772796337736742692945663985470529377745854692207002046330357343505517537014050310355526578082729897049230547545589009275410944504014157125357682801074915174627928533783099570631952876838237806368177841661186334747789420166190186143388804514884174361681454810362321037643274595653364629397295294049952661691181657740018116146497654407589150912557599100855273107733703213603505619407350405223414533224306604743600257212590127202517146952605462439215815151732661454812243619860357386922465403688559787750083268386930674253759349376972691382532780570135683441862315010318955128705494038594760949278590520009881447715839714713971813720554960331191642239195313230213875992717401904622413925914800620171561815889352945121978193704745708538695427900233080410588007250947512318930796844637224171170594606197614751977323896101315556406372309310279476973938229476346893933755946893665094049910252612163538072005644241026471164639800490998535570282059396054554479255558624918709232180130454102936332893619326596350851413637207293142767763267817840066780089558654877782630822818446508158509625695020697797889664140551101421185533444015948880284701657904464926309216120238068566472631611326995533585414320547442896728173291714010643730593960222482733969720865809194288803963344344876467583385597351333330628439786357062196382217705500672607607570202305548328439335937369624085404957344415141889143812206076832329063384332685935928226648361622876815670931303789678327741487845287838232474038340893449427806045589018183673133602271167285304427194507315740913600066356089181219040305019319028163972135790696025211929562455952835850442627787993214468221041325612271290302469610374855134599106662606082143546126463790846952338680559237822828610361386416013753920426888371192602742087474507782730180882648297991489233434653363930327991816476995529468892904060335470265188317825821391915073117022336839564945335630414192442838503954209073337511117053790819768061378846157004292392264788138228486672543415580694421193506836000488465561599083339184724263183698928130695654949153165010313216361224018298711517222401523368101476246169896417259748838727189598765602350324828709741468793415378708814573190327920453219231685852735108372055942456601545647944675449566859142997988233179819059574125368681032194798082603876241044848730208905065871934264174092007936669883601462309762759844113071525758916288010581709353072588887654386253201848624931923638568216562603110434528313030704972291334873033240933736956347974889824930017415805659182123288343858101250171537305398462043432455721482088547523494730467761429282915391485852688505423074450548192619166975975031503447208211845313907683486006908772752077246485706597636740936173143436990399498908375710246545650814962015988805204483379491707040848303909417512426275869868668644293498242419667403627076032399201407183071270759837132000712447159523642782162488472933913713634046138974088894178399320090051543608421618891328957740354384456107645016010462709579098652495342014766016330458293537653454523438667413798731255017029554582809547897542497367109038598264606895622241257303208140890607025206140457815282368504505765710043804228592032720729190222134651835930255942940875306994701101153416476785623543575023993736414532895773499876167502240919794121893188059017977444329403624038551082491954751841177014150820554999148803286500065069030165028455616533514890711974194172310029663247936640825364542104897640445108081123906368188594908660418340025631562661211506365309297219580687177632051461355581309500814563826112416521487163593643553646268872746276680368630680088231249970572706496265335285424273723449757482776061300818063419639083097882249478922949525891665782610044424440110326748539620120023397129834624242363283711074267309902126029110038109050751840523266273905031934856015485510632624318778970878895198168073096354223096005536267735905099473408744371024816727970009494589707630185344952680106730984246828848883760016695887137355969244555238536396178788134209309376484848406842940499731494663578455826688245825356635393289729316700066238128368519670627697889769929009597838069557440769080950069594659578325366066060213000525012998145215099629307110700615796004759918829827472751877492472674770755413679265775060149528336859838085353420874215682758801259992855903410097963019943741001394975591822918846705741010634931594527954742032057295356596869586863097328488381174243827058441735659667485315202886191192125286398739560928127513223214119754229343092375569339614672740517569529376699061052365448344078610425576694541873486379356070861240473688356773437140126350120823765176390562050604076894729400293162079760342896846897639867830553941515230713725560502914671175123451932131962571791940911728951123948113598860588062424037835751996487088330150679210175429060531418836978611027896830689666851868410470182364780700615529883149883111601949965815038674390467105247175993726709203381051984777006122752302698038537619917731907133105816779008651480172440446403764720673784583395382889380902941273987910475254258486561698048543296782281040453997661165123290729161619992628751086519341731116513305659182981762584769428708454819029344222186027977405519291266188948708010515922860149238393490889782166965109499761673179583522105791358724355029782111425280584380959770472177893827382916471882671437865821461326011263516554280516418422188264141890686619186492751718984735037496602686033671961304915922609442146773092074476794711917820209913226872184947548378003848726148872742881265579174794634151444545105599464567614478293387968015412886418098284885525959617399177657635267081989985408930744564199296902459275405143647525648661932959903068323866757518479741015342911416508753572892479684280248440220211898390243430190746592470563991910024225814399068391457857458095344096826158489731615822039837691005171654390590093326827586419753439483771905973079465029210363641972615923872187876095687197681934481955852567024141433671590889694204781798936556351775101591005026585947279448642317311892727153525046034081896227383114600546852406398855471859684088277722162250586368419379964112646321070639818773794369650252104438622320671517228411475433482803041707675438555447584321271846396281391925884972509051040944134450429845346071848875654240709690138592611645519676563708429710676494635766201285381926791204110977805857352062737510466943591592074904378966129808716274322385039032007477854211063899544954185997641428116395197239708078986048758264126544825149923227286176571389697334537835963603962709038002668921324389159009375225033651171937770657226295341257068980907793198879997076783263303670667342657925395849950582363998610492878479976185891384024744790742355981796013254960652684988733518397287191251899388324341602608356164496670902390042273216221931567939944001215159910054381084520081133103207553492484487369268314444466610780275891777468369344585045949963237156043800258227618908603074550819931892899703285549507330240121766349515315827830897786432254556221744305752825143708087184314470811004510108612122699931396969361066523608721126359012344828262284427191281973187269761974740398071778378188160519801862257232970224762494767912932684020188061795236229174601398576604233579094407723017353015337974435643738584248250538061547193075224429309117207447677149522141919390974201716026970557825836923707297811545552570788004955666915477901830719591663516687057984336951611189153751912396714116378197000784953115386326766369269172016978409040396969804861828436417776804088449208439901095951205751340861060375353408155737087188313898337656322533650946010308686111901241541794900659835366926383515058402026098259570385429145865025692157987309807064597082326377138235585737704225628144262793497769429358804020882742028263786443615935817930817858306265712263479452174065216410798029333573961137404301928294367884626832432449078812684787281988676202931062510264948586549463964789154366240635570346688477784815271412470430646040615614277320107003575855033995279377529716156628381118518085523414187577256025217995103662771477552291036839539792329375184700131215428652464111526297830742328651189481978920924682746392250346179819781021313400022272303222234731521016033826145645816472110340883197207109422849637006090510260943044730126801795349152894613046101033061811314821366141874985466628809585678299308824993966655499624380015821082410781190328189506855057581990908848597095494573176672201417764187253816862426293852974092626551536758155537683368451820154793964862810533857810979434793077956125541240828563089647076354827276586047900779183041806574320855302776686899978897939486987950729652971448050889517660684386673056662911929857913206598752762097197279390208473846210277152094212386266930256260451209117402079233658157593274696841906354187366092529138116574357045728290417433832596884391356956442617823006949118156994294295529170211353842468704890572313005646106202029653246628477843902025194715815133791174898257040115532858624973690714844800747184719290671002133191274834310662201874141841328708920709275866745037664169280121112867057832132585948539987132879098472640550013972043153470930436509718084070853723316111111611632600262171748813737621046013600544051850633175245231989785291065646466038278748870331134307620041356514295482843502245454400571392386492526283423907951705366640483826875013469850263767974528926285288366544314868036628329638912254207094687335597669512007687507292940623176435604796651807847095408991068514998003358735387989422028901542800717906482276185298683079286137204396993726503610285463352157718364571843381950031926272352293654343387522809514152498052577486366048613580539162662183475105825647260311633442002377527140625112075332294909525522330744664115572260242435895269482927435844022622001466247093866533879048392320516224276433339282642640953964341822416705658461244760448817737705782669080880834418822622611342632727419248415651121035047131961583094994438779439078380664656207143187309895280874153167621657602227990850199615587578332393883365169478142077533262283694526612005465820771400826060398839255150948861553177333447506822679211849690448880479070102043288205874672361672971246062341973369704807867768609989464712379097525706498042381815865399434983035941162258347729020489356838477197804973214911448748749915616679253857438010864500220134843719609727912761136925035123155282535741655826107266099467657016111855684257826878422197833994329148734893923892153298966294232703135845615804723993624827409373966761563257981994036006655039613941881183164267144485664874468348587099434743710128859267552473831462181434321232124758618476925803128913233878664527525204324484796532776273320171351979849530142473805976430318655810403609897537469226336015596525652284888167037460054235043655813438329870872734142062859147847007274999414885129441657918212383876056572545671794085637289277002790218604788423519924573051811976377731594412994393860534559159658127123862955315918182841923881357245009246238507097741891437575676886206936433608263660374355173185026954239766173038826275043838965247160428689739548061640664606565379050539422795708801840829664956978192406737307076253014257542221763860230431809477056758905681723033326311408802886092880151777469082375063137750925275331638009836786645991949881018108222446858443984865972449621097999331605268587810061927125889694400669979755648800940895626242917531834388920035663113368763931463847812763130237825562198311791061780856687903309789539747505239545316630638169559777653347655949908779202359718666623572487055558216484036084925217803431104356647417600193631613474196113126657206064282217690428541246560204561459484317744683213906021267727411189443675804442911583757423572500214191467493342871160840582639470485636370375679604797073490813681083838562113841391587052553615073991983125473434527404596547926972539542447555990332809716643578039646945749813368621152410490288581779206318208255069166455507840899628333174744873951607229399258854694188637978240144635295264982572856632103053550891057171748674115218494774077589151115819489068851971959768129214023511454382738867557288320426608338030759515727545577639726238470674634011626346953231815229549718996906470438903536574430644436472716449550868519871817092814068746449470806856174570885105064766494332205391085097539987897980672278869943134632799032372604933150163386774039430519493297142505321117669011820293604482694166301309801111227443654953271242388534939973277749999335296667138307969441135719079969506099821923206878892624416110175909254904610286553512032488285673735148429324009831633211264460376172046209384270528903772251057643968938983722779640468452705694321085455273829462711022737243290606294601651732654594463569861350966095209962038508010899673666470073918705760679801337058347046567503369379598928154437380765511031719081985901371088639600700705631873099251480947989238619052479230983309717938226245725600119571130722386790431255742179135633111146646083268382596762356018472772209198013121983224179079476134977421748168833934278876403014334318798493417716613256506422668264638388429786875443810986754386459491846082078633346046469418429778813833857755519670005669840456587642130852057050148314568259387702428619224671173187370822224627538313365937868201435535126600146246249435880806572693573084485615073901842761167215162204840459913839674251648
ZX Spectrum Basic
10 LET a=1: LET g=1/SQR 2
20 LET ta=a
30 LET a=(a+g)/2
40 LET g=SQR (ta*g)
50 IF a<ta THEN GO TO 20
60 PRINT a
- Output:
0.84721309
bc
/* Calculate the arithmethic-geometric mean of two positive
* numbers x and y.
* Result will have d digits after the decimal point.
*/
define m(x, y, d) {
auto a, g, o
o = scale
scale = d
d = 1 / 10 ^ d
a = (x + y) / 2
g = sqrt(x * y)
while ((a - g) > d) {
x = (a + g) / 2
g = sqrt(a * g)
a = x
}
scale = o
return(a)
}
scale = 20
m(1, 1 / sqrt(2), 20)
- Output:
.84721308479397908659
BQN
AGM ← {
(|𝕨-𝕩) ≤ 1e¯15? 𝕨;
(0.5×𝕨+𝕩) 𝕊 √𝕨×𝕩
}
1 AGM 1÷√2
- Output:
0.8472130847939792
C
Basic
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
double agm( double a, double g ) {
/* arithmetic-geometric mean */
double iota = 1.0E-16;
double a1, g1;
if( a*g < 0.0 ) {
printf( "arithmetic-geometric mean undefined when x*y<0\n" );
exit(1);
}
while( fabs(a-g)>iota ) {
a1 = (a + g) / 2.0;
g1 = sqrt(a * g);
a = a1;
g = g1;
}
return a;
}
int main( void ) {
double x, y;
printf( "Enter two numbers: " );
scanf( "%lf%lf", &x, &y );
printf( "The arithmetic-geometric mean is %lf\n", agm(x, y) );
return 0;
}
Original output:
Enter two numbers: 1.0 2.0 The arithmetic-geometric mean is 1.456791
Task output, the second input (0.707) is 1/sqrt(2) correct to 3 decimal places:
Enter two numbers: 1 0.707 The arithmetic-geometric mean is 0.847155
GMP
/*Arithmetic Geometric Mean of 1 and 1/sqrt(2)
Nigel_Galloway
February 7th., 2012.
*/
#include "gmp.h"
void agm (const mpf_t in1, const mpf_t in2, mpf_t out1, mpf_t out2) {
mpf_add (out1, in1, in2);
mpf_div_ui (out1, out1, 2);
mpf_mul (out2, in1, in2);
mpf_sqrt (out2, out2);
}
int main (void) {
mpf_set_default_prec (65568);
mpf_t x0, y0, resA, resB;
mpf_init_set_ui (y0, 1);
mpf_init_set_d (x0, 0.5);
mpf_sqrt (x0, x0);
mpf_init (resA);
mpf_init (resB);
for(int i=0; i<7; i++){
agm(x0, y0, resA, resB);
agm(resA, resB, x0, y0);
}
gmp_printf ("%.20000Ff\n", x0);
gmp_printf ("%.20000Ff\n\n", y0);
return 0;
}
The first couple of iterations produces:
0.853 0.840
Then 7 iterations produces:
0.84721308479397908660649912348219163648144591032694218506057937265973400483413475972320029399461122994212228562523341096309796266583087105969971363598338425117632681428906038970676860161665004828118872189771330941176746201994439296290216728919449950723167789734686394760667105798055785217314034939830420042211921603983955359509819364129371634064602959996797059943435160203184264875695024217486385540598195458160174241788785419275880416271901208558768564832683414043121840080403580920455949431387781512092652225457439712428682076634095473367459962179266553534862568611854330862628728728756301083556319357066871478563908898211510883635214769697961262183294322841786811376844517001814602191369402702094599668351359632788080427434548174458736322002515395293626580661419836561649162625960743472370661690235308001737531284785255843063190745427493415268579065526940600314759102033274671968612479632551055464890282085529743965124994009662552866067580448735389218570140116771697653501408495247684899325732133702898466893919466586187375296638756226604591477704420468108925658440838032040910619003153706734119594101007474331059905505820524326009951692792417478216976781061683697714110739273343921550143022007087367365962272149258776192851052380367026890463909621907663644235538085902945234065190013342345105838341712180514255003923701111325411144612628906254133550526643653595824552156293397518251470650134641047056979355681306606329373345038710977097294875917179015817320281578288487149931340815493342367797044712785937618595085146677364554679201615934223997142984070788882279032656751596528435817795727284808356489963504404140734226110183383546975962663330422084999852300742703930277243474979717973264552546543019831694968461098690743905068013766119252919770938441299707015889493166661161994592265011311183966352502530561646431587208454522988775475177272747656721648982918239238895207207642839710884705960356921992921831901548141280766592698294464457149239666329973075813904957622438962423175209507319018424462442370986427281149511180822826053862484617675180140983127497257651983756492356902800216174905531427208153439540595563576371127281657059737337442970039056040156388663072225700389230159112376960121580081779077863351240862431073571583765926504546652787337874444834406310244757039681255453982266430353416413035613801634165575265589752944521166873451220191227466733191571240763753821106968141076926390074833175743396752319660330864973571383874196098983832202882694882191302819366949954422240697276168621369511657838885012199096160655454611543253148164249332694797004159491476323112920593516518997943350045976288217292625918089405508431466393782548335139550190653370872062064024077056075848796499843651592728264534428636615419142585777106756185017278033287175195189305031805505245426022335522900771418128798654351187918006356279593624768267786412249460338126082628254098895312527677534656243279214511229555516031818433133692961723041783855157125567404983416665926969580008953724573057694542275372160209687191470398878466367243262706191127071716590824640041679941120405657103640830002419294398553073994656539677810492701055410359513339432199925066676202078394695553760551796401009749218856311301017813888578793813172095948062539201300983650287917695827985905279947721941797997024943062158419468885328115497721579960194409623477686144085075739284298823759396823223670580334134774623112897625859324376631778974911077261909704489522204509630725515590093824904021364807792034767215048568446022554409992826163174312642285787628983380650722023010371753149263504631060188573772567006618381290580638954508127031311371043716135833488065833955431217901348398833216413057635244712511539472066670330101348716516324113828817639839629526121141263219795965098656786755250760760424095907517523021946104532564333249614901253533329223723868948127885020135966305376055849358928391630469403887854960027471487197801457659579049585802260066099524967364324966833461760106608156706975142381866503610838852209761655002516073114992161294775790199729248689638220603808760276281672370166819106633585775154650381334236722347642026558565588464160102105404898556187114735884976378406486426798186504486319077470382286711435151123003607086574298864771466747337501143458188527970060562117246921748471806948662511994728934442703783046207073549380528727206215606307188286858056452111069670802856990698257691772209986719599685077906814434949328049768115436804632599386930762350709995182951295811212357072453833548261907523951582730982481805496658979091688679840717077937059590457758409104734131096041941113577566207273377978332037973011376726585357477102797814097213096121423938547374627696150413079528373728820506587191522597650840277969917611753930067254924912298450823629755687227110658494355338504945326387364898046066559799543601695030927900924500578564772358761988489860344121953407953690029964119745490607416009788595376607229051607724285900709011566391383642990412208267696297978676490323564999819907659974398705486487690910249119270999682756970113687622440464029603837000662127345776647097113263746568115029858630322603373834213584239378961146171920830719539156437820936414967803341524645073966831731983633627433925553117120194541468448808956224178980318943412312840278583782890096242095413450021010727363232852725762096468519944682405506293917420533017064619172151788442967053143355037723107097160802851453141441061050231173108777799332489320877272298978213301208340743056049981599632026877933071569403024391561189267675172495117665262485470960419914731136579206973309960888972867897807355875785006235751571237716530420636310027031292966940254219678771688466557275808983064676620070146795856930822206209053308277822265031125202787335125191599188939002843192181666865484348796219722117639049598957936073309436974576289432003841175529415947547471839363811441256103510234595810807685589856570074453089094286692511901017181228266893492695282610525185567360458777022881478214469685009183472197414205461280723479500598117663645261501907885454711938035571459307446356562607527875188243864095069646498151311705914579906193765608586501756168645019240983272357243336888130800221863687002096411197243036035586497937733149167495931511886735350255059823030470602847404584566768496209345063963029094416325164086928898145072478777276733780338289295049783843429437665667372975874305751410364174768616396241989419047309961002284280794449200269048452541391882460015590891319432556103657693623641617846466931414561099840383122655041152514944453800420904287181824684316246105526376775209701040639446878373750174360897516934868876512834536775527865470902315420294538730761411966497675219198089021057726334723979589687229233577690412444586822978062098870898160181795214549203709562528507330232550600966113294791484434166874298726542040835520564564044211741240650419323628312966431263307687154504449507335544182007936697013312446388243600624398167124093468063221697717015635904176098412619778010525869566346541447025111353828410102785795430618023572755009305139556377710439227995971141182782033581183989523387201196266668287812153433311933530198006525119241035943150724272515897742269014313251497752206211486532095282917841726788527918259501894283066454533808294385484913906600901526463156669408130516898577384457161101347735284395586639180314771289972489772326950830959208603163908601794221468048925371471356694906475975663504050761059303001534536134468346141362848404730639095800648624822113995399621221079927740532030597569871315014292389418219892184458614968453063460782870588642625603497671133853907530473607475205697255326635179640594881381276485191302328261295517207475944988639251110497859774101046472588317449694892733322810684089494759787067690122169518696581944061366943103234116196131605543816087283055435048190711597527426659173636930019809887976272186626285433119060860342806191518452978237036398984494144178890086027822209983902274728379674114295789243465456404028551674783725388313861547805080352368935833328873558797948868049809714068689367194167115043074025751022690817073859285358373909764249759224210618323725170214283209867537445071332189636669085656349633060774556830118371494002584049977661135255328476656188705929782127298997295927947818204287198071022786461838070064010831389756771127541362211274445345355849597692525757583129990395369598932499513241067842656115567436600887374842740382348117849110021235371080153344077081752815794229285487316898639800718962686849857790619425820001731784737979758156092690872878502700244147412819535788739647458594598995355434128016535530490585287946743982206062303866888527005052189049277821975141155954355491253261150874322804356095631761163218117941648842069284743156991336777879569137055927049598939111007862241124499317195398903082153071269718073528142944373740581805897842871015663258737266000122961804037804290931751604739799312368824663145245907925120889169747654302457053206386704684110540342014376644422132127507998462991570101471065529461467463922495745306196822034254448162475459772696534302506868242052880996924489236521714038177492829359173154812849196214333040809043068672336820607162912893985174062559042822475581595091023242061608163635114409532679679744662146581218973837257052018318006785051812332707432360517602365653046059197282467620464979507571243323062106152366172293244682862511105778328547123718579064823024291991297534773406188123932244051237932292486982393020946057994685022093564580188647372057989508199682850879081206451754647928466570299934961463545338169898790120739595342994580518846829188356311361388796313161734422075062182129450475034337306401403566141064033208676214431839284389699942682868360825355912427514883833922646682229633236574889815991049023745712780770628532368956900284697429547742484223355238590492992254533182706939660886035184911668751085520062653409664126112200692905563690527440648936400870151716629293565299214744207938737106473991364534021859315182015761100594055566001663181909163482128186430684182569911943162667158985886736504889805808329721451958115258329743580644326982892093642849596169753399275023838326958011096089547864572561097853782973070749181687447357311890498494907816322101271109193983576388927531317499783213682809328943493309300878688841270920763590076480651183013174408131381707764785620869834568499576963332415566990859371495284373037821741667810126247377548449594082775980428578137754484461929295371533597418713555566780286064849179748275590223773761897037703324897743492353765235571390764314889671441330995396798710462847477217721858658519859712821657391485744943283203084641639560963010473704739884503079369569286834641137642263085686956881520537491962945628810859870159107649550192726673782765172374500136624210511467091848989522697276562069762630550949389320992163775294153350600271094300189773392218453903373510079427646652325090453779404782123556204886389696402910291826730243688880139827500496556889555403627397541183592770090942918399583962985359521234655737077516804320238724010087862923625584849202212960559482323176352142071176504276997478012902491509148733472049812083534865212462335388584717004701205923945825415223129676013072682802320446336442341000264743415683991238810480498194912009402448957203018812206409969973408437360958124499459132317933593338191973602488533756410304356437323020013283599906152983949167106879976939266990335220640837295869943043576709171697966984423326568307325500003213129027067191063424283113900494781793073045562199439120722094954719165471096054049199441860517249814718129940631192901737381011766173569764956366756202788955920995046861634403052506586817358402694287366334311678329038374756580509907839853849260647212465651306604876736085857902183866432416271982103787727963377367426929456639854705293777458546922070020463303573435055175370140503103555265780827298970492305475455890092754109445040141571253576828010749151746279285337830995706319528768382378063681778416611863347477894201661901861433888045148841743616814548103623210376432745956533646293972952940499526616911816577400181161464976544075891509125575991008552731077337032136035056194073504052234145332243066047436002572125901272025171469526054624392158151517326614548122436198603573869224654036885597877500832683869306742537593493769726913825327805701356834418623150103189551287054940385947609492785905200098814477158397147139718137205549603311916422391953132302138759927174019046224139259148006201715618158893529451219781937047457085386954279002330804105880072509475123189307968446372241711705946061976147519773238961013155564063723093102794769739382294763468939337559468936650940499102526121635380720056442410264711646398004909985355702820593960545544792555586249187092321801304541029363328936193265963508514136372072931427677632678178400667800895586548777826308228184465081585096256950206977978896641405511014211855334440159488802847016579044649263092161202380685664726316113269955335854143205474428967281732917140106437305939602224827339697208658091942888039633443448764675833855973513333306284397863570621963822177055006726076075702023055483284393359373696240854049573444151418891438122060768323290633843326859359282266483616228768156709313037896783277414878452878382324740383408934494278060455890181836731336022711672853044271945073157409136000663560891812190403050193190281639721357906960252119295624559528358504426277879932144682210413256122712903024696103748551345991066626060821435461264637908469523386805592378228286103613864160137539204268883711926027420874745077827301808826482979914892334346533639303279918164769955294688929040603354702651883178258213919150731170223368395649453356304141924428385039542090733375111170537908197680613788461570042923922647881382284866725434155806944211935068360004884655615990833391847242631836989281306956549491531650103132163612240182987115172224015233681014762461698964172597488387271895987656023503248287097414687934153787088145731903279204532192316858527351083720559424566015456479446754495668591429979882331798190595741253686810321947980826038762410448487302089050658719342641740920079366698836014623097627598441130715257589162880105817093530725888876543862532018486249319236385682165626031104345283130307049722913348730332409337369563479748898249300174158056591821232883438581012501715373053984620434324557214820885475234947304677614292829153914858526885054230744505481926191669759750315034472082118453139076834860069087727520772464857065976367409361731434369903994989083757102465456508149620159888052044833794917070408483039094175124262758698686686442934982424196674036270760323992014071830712707598371320007124471595236427821624884729339137136340461389740888941783993200900515436084216188913289577403543844561076450160104627095790986524953420147660163304582935376534545234386674137987312550170295545828095478975424973671090385982646068956222412573032081408906070252061404578152823685045057657100438042285920327207291902221346518359302559429408753069947011011534164767856235435750239937364145328957734998761675022409197941218931880590179774443294036240385510824919547518411770141508205549991488032865000650690301650284556165335148907119741941723100296632479366408253645421048976404451080811239063681885949086604183400256315626612115063653092972195806871776320514613555813095008145638261124165214871635936435536462688727462766803686306800882312499705727064962653352854242737234497574827760613008180634196390830978822494789229495258916657826100444244401103267485396201200233971298346242423632837110742673099021260291100381090507518405232662739050319348560154855106326243187789708788951981680730963542230960055362677359050994734087443710248167279700094945897076301853449526801067309842468288488837600166958871373559692445552385363961787881342093093764848484068429404997314946635784558266882458253566353932897293167000662381283685196706276978897699290095978380695574407690809500695946595783253660660602130005250129981452150996293071107006157960047599188298274727518774924726747707554136792657750601495283368598380853534208742156827588012599928559034100979630199437410013949755918229188467057410106349315945279547420320572953565968695868630973284883811742438270584417356596674853152028861911921252863987395609281275132232141197542293430923755693396146727405175695293766990610523654483440786104255766945418734863793560708612404736883567734371401263501208237651763905620506040768947294002931620797603428968468976398678305539415152307137255605029146711751234519321319625717919409117289511239481135988605880624240378357519964870883301506792101754290605314188369786110278968306896668518684104701823647807006155298831498831116019499658150386743904671052471759937267092033810519847770061227523026980385376199177319071331058167790086514801724404464037647206737845833953828893809029412739879104752542584865616980485432967822810404539976611651232907291616199926287510865193417311165133056591829817625847694287084548190293442221860279774055192912661889487080105159228601492383934908897821669651094997616731795835221057913587243550297821114252805843809597704721778938273829164718826714378658214613260112635165542805164184221882641418906866191864927517189847350374966026860336719613049159226094421467730920744767947119178202099132268721849475483780038487261488727428812655791747946341514445451055994645676144782933879680154128864180982848855259596173991776576352670819899854089307445641992969024592754051436475256486619329599030683238667575184797410153429114165087535728924796842802484402202118983902434301907465924705639919100242258143990683914578574580953440968261584897316158220398376910051716543905900933268275864197534394837719059730794650292103636419726159238721878760956871976819344819558525670241414336715908896942047817989365563517751015910050265859472794486423173118927271535250460340818962273831146005468524063988554718596840882777221622505863684193799641126463210706398187737943696502521044386223206715172284114754334828030417076754385554475843212718463962813919258849725090510409441344504298453460718488756542407096901385926116455196765637084297106764946357662012853819267912041109778058573520627375104669435915920749043789661298087162743223850390320074778542110638995449541859976414281163951972397080789860487582641265448251499232272861765713896973345378359636039627090380026689213243891590093752250336511719377706572262953412570689809077931988799970767832633036706673426579253958499505823639986104928784799761858913840247447907423559817960132549606526849887335183972871912518993883243416026083561644966709023900422732162219315679399440012151599100543810845200811331032075534924844873692683144444666107802758917774683693445850459499632371560438002582276189086030745508199318928997032855495073302401217663495153158278308977864322545562217443057528251437080871843144708110045101086121226999313969693610665236087211263590123448282622844271912819731872697619747403980717783781881605198018622572329702247624947679129326840201880617952362291746013985766042335790944077230173530153379744356437385842482505380615471930752244293091172074476771495221419193909742017160269705578258369237072978115455525707880049556669154779018307195916635166870579843369516111891537519123967141163781970007849531153863267663692691720169784090403969698048618284364177768040884492084399010959512057513408610603753534081557370871883138983376563225336509460103086861119012415417949006598353669263835150584020260982595703854291458650256921579873098070645970823263771382355857377042256281442627934977694293588040208827420282637864436159358179308178583062657122634794521740652164107980293335739611374043019282943678846268324324490788126847872819886762029310625102649485865494639647891543662406355703466884777848152714124704306460406156142773201070035758550339952793775297161566283811185180855234141875772560252179951036627714775522910368395398000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
The limit (19,740) is imposed by the accuracy (65568). Using 6 iterations would produce a less accurate result. At 7 iterations increasing the 65568 would mean we already have 38,000 or so digits accurate.
C#
namespace RosettaCode.ArithmeticGeometricMean
{
using System;
using System.Collections.Generic;
using System.Globalization;
internal static class Program
{
private static double ArithmeticGeometricMean(double number,
double otherNumber,
IEqualityComparer<double>
comparer)
{
return comparer.Equals(number, otherNumber)
? number
: ArithmeticGeometricMean(
ArithmeticMean(number, otherNumber),
GeometricMean(number, otherNumber), comparer);
}
private static double ArithmeticMean(double number, double otherNumber)
{
return 0.5 * (number + otherNumber);
}
private static double GeometricMean(double number, double otherNumber)
{
return Math.Sqrt(number * otherNumber);
}
private static void Main()
{
Console.WriteLine(
ArithmeticGeometricMean(1, 0.5 * Math.Sqrt(2),
new RelativeDifferenceComparer(1e-5)).
ToString(CultureInfo.InvariantCulture));
}
private class RelativeDifferenceComparer : IEqualityComparer<double>
{
private readonly double _maximumRelativeDifference;
internal RelativeDifferenceComparer(double maximumRelativeDifference)
{
_maximumRelativeDifference = maximumRelativeDifference;
}
public bool Equals(double number, double otherNumber)
{
return RelativeDifference(number, otherNumber) <=
_maximumRelativeDifference;
}
public int GetHashCode(double number)
{
return number.GetHashCode();
}
private static double RelativeDifference(double number,
double otherNumber)
{
return AbsoluteDifference(number, otherNumber) /
Norm(number, otherNumber);
}
private static double AbsoluteDifference(double number,
double otherNumber)
{
return Math.Abs(number - otherNumber);
}
private static double Norm(double number, double otherNumber)
{
return 0.5 * (Math.Abs(number) + Math.Abs(otherNumber));
}
}
}
}
Output:
0.847213084835193
Note that the last 5 digits are spurious, as maximumRelativeDifference was only specified to be 1e-5. Using 1e-11 instead will give the result 0.847213084793979, which is as far as double can take it.
Using Decimal Type
using System;
class Program {
static Decimal DecSqRoot(Decimal v) {
Decimal r = (Decimal)Math.Sqrt((double)v), t = 0, d = 0, ld = 1;
while (ld != d) { t = v / r; r = (r + t) / 2;
ld = d; d = t - r; } return t; }
static Decimal CalcAGM(Decimal a, Decimal b) {
Decimal c, d = 0, ld = 1; while (ld != d) { ld = d; c = a;
d = (a = (a + b) / 2) - (b = DecSqRoot(c * b)); } return b; }
static void Main(string[] args) {
Console.WriteLine(CalcAGM(1M, DecSqRoot(0.5M)));
if (System.Diagnostics.Debugger.IsAttached) Console.ReadKey();
}
}
- Output:
0.8472130847939790866064991235
C# with System.Numerics
Even though the System.Numerics library directly supports only BigInteger (and not big rationals or big floating point numbers), it can be coerced into making this calculation. One just has to keep track of the decimal place and multiply by a very large constant.
using static System.Math;
using static System.Console;
using BI = System.Numerics.BigInteger;
class Program {
static BI BIP(char leadDig, int numDigs) { // makes big constant
return BI.Parse(leadDig + new string('0', numDigs)); }
static BI IntSqRoot(BI v, BI res) { // res is the initial guess
BI term = 0, d = 0, dl = 1; while (dl != d) { term = v / res; res = (res + term) >> 1;
dl = d; d = term - res; } return term; }
static BI CalcByAGM(int digs) { // note: a and b are hard-coded for this RC task
BI a = BIP('1', digs), // value of 1, extended to required number of digits
b = BI.Parse(string.Format("{0:0.00000000000000000}", Sqrt(0.5)).Substring(2) +
new string('0', digs - 17)), // initial guess for square root of 0.5
c, // temporary variable to swap a and b
diff = 0, ldiff = 1; // difference of a and b, last difference
b = IntSqRoot(BIP('5', (digs << 1) - 1), b); // value of square root of 0.5
while (ldiff != diff) { ldiff = diff; c = a; a = (a + b) >> 1;
diff = a - (b = IntSqRoot(c * b, a)); } return b; }
static void Main(string[] args) {
int digits = 25000; if (args.Length > 0) {
int.TryParse(args[0], out digits);
if (digits < 1 || digits > 999999) digits = 25000; }
WriteLine("0.{0}", CalcByAGM(digits));
if (System.Diagnostics.Debugger.IsAttached) ReadKey(); }
}
- Output:
0.8472130847939790866064991234821916364814459103269421850605793726597340048341347597232002939946112299421222856252334109630979626658308710596997136359833842511763268142890603897067686016166500482811887218977133094117674620199443929629021672891944995072316778973468639476066710579805578521731403493983042004221192160398395535950981936412937163406460295999679705994343516020318426487569502421748638554059819545816017424178878541927588041627190120855876856483268341404312184008040358092045594943138778151209265222545743971242868207663409547336745996217926655353486256861185433086262872872875630108355631935706687147856390889821151088363521476969796126218329432284178681137684451700181460219136940270209459966835135963278808042743454817445873632200251539529362658066141983656164916262596074347237066169023530800173753128478525584306319074542749341526857906552694060031475910203327467196861247963255105546489028208552974396512499400966255286606758044873538921857014011677169765350140849524768489932573213370289846689391946658618737529663875622660459147770442046810892565844083803204091061900315370673411959410100747433105990550582052432600995169279241747821697678106168369771411073927334392155014302200708736736596227214925877619285105238036702689046390962190766364423553808590294523406519001334234510583834171218051425500392370111132541114461262890625413355052664365359582455215629339751825147065013464104705697935568130660632937334503871097709729487591717901581732028157828848714993134081549334236779704471278593761859508514667736455467920161593422399714298407078888227903265675159652843581779572728480835648996350440414073422611018338354697596266333042208499985230074270393027724347497971797326455254654301983169496846109869074390506801376611925291977093844129970701588949316666116199459226501131118396635250253056164643158720845452298877547517727274765672164898291823923889520720764283971088470596035692199292183190154814128076659269829446445714923966632997307581390495762243896242317520950731901842446244237098642728114951118082282605386248461767518014098312749725765198375649235690280021617490553142720815343954059556357637112728165705973733744297003905604015638866307222570038923015911237696012158008177907786335124086243107357158376592650454665278733787444483440631024475703968125545398226643035341641303561380163416557526558975294452116687345122019122746673319157124076375382110696814107692639007483317574339675231966033086497357138387419609898383220288269488219130281936694995442224069727616862136951165783888501219909616065545461154325314816424933269479700415949147632311292059351651899794335004597628821729262591808940550843146639378254833513955019065337087206206402407705607584879649984365159272826453442863661541914258577710675618501727803328717519518930503180550524542602233552290077141812879865435118791800635627959362476826778641224946033812608262825409889531252767753465624327921451122955551603181843313369296172304178385515712556740498341666592696958000895372457305769454227537216020968719147039887846636724326270619112707171659082464004167994112040565710364083000241929439855307399465653967781049270105541035951333943219992506667620207839469555376055179640100974921885631130101781388857879381317209594806253920130098365028791769582798590527994772194179799702494306215841946888532811549772157996019440962347768614408507573928429882375939682322367058033413477462311289762585932437663177897491107726190970448952220450963072551559009382490402136480779203476721504856844602255440999282616317431264228578762898338065072202301037175314926350463106018857377256700661838129058063895450812703131137104371613583348806583395543121790134839883321641305763524471251153947206667033010134871651632411382881763983962952612114126321979596509865678675525076076042409590751752302194610453256433324961490125353332922372386894812788502013596630537605584935892839163046940388785496002747148719780145765957904958580226006609952496736432496683346176010660815670697514238186650361083885220976165500251607311499216129477579019972924868963822060380876027628167237016681910663358577515465038133423672234764202655856558846416010210540489855618711473588497637840648642679818650448631907747038228671143515112300360708657429886477146674733750114345818852797006056211724692174847180694866251199472893444270378304620707354938052872720621560630718828685805645211106967080285699069825769177220998671959968507790681443494932804976811543680463259938693076235070999518295129581121235707245383354826190752395158273098248180549665897909168867984071707793705959045775840910473413109604194111357756620727337797833203797301137672658535747710279781409721309612142393854737462769615041307952837372882050658719152259765084027796991761175393006725492491229845082362975568722711065849435533850494532638736489804606655979954360169503092790092450057856477235876198848986034412195340795369002996411974549060741600978859537660722905160772428590070901156639138364299041220826769629797867649032356499981990765997439870548648769091024911927099968275697011368762244046402960383700066212734577664709711326374656811502985863032260337383421358423937896114617192083071953915643782093641496780334152464507396683173198363362743392555311712019454146844880895622417898031894341231284027858378289009624209541345002101072736323285272576209646851994468240550629391742053301706461917215178844296705314335503772310709716080285145314144106105023117310877779933248932087727229897821330120834074305604998159963202687793307156940302439156118926767517249511766526248547096041991473113657920697330996088897286789780735587578500623575157123771653042063631002703129296694025421967877168846655727580898306467662007014679585693082220620905330827782226503112520278733512519159918893900284319218166686548434879621972211763904959895793607330943697457628943200384117552941594754747183936381144125610351023459581080768558985657007445308909428669251190101718122826689349269528261052518556736045877702288147821446968500918347219741420546128072347950059811766364526150190788545471193803557145930744635656260752787518824386409506964649815131170591457990619376560858650175616864501924098327235724333688813080022186368700209641119724303603558649793773314916749593151188673535025505982303047060284740458456676849620934506396302909441632516408692889814507247877727673378033828929504978384342943766566737297587430575141036417476861639624198941904730996100228428079444920026904845254139188246001559089131943255610365769362364161784646693141456109984038312265504115251494445380042090428718182468431624610552637677520970104063944687837375017436089751693486887651283453677552786547090231542029453873076141196649767521919808902105772633472397958968722923357769041244458682297806209887089816018179521454920370956252850733023255060096611329479148443416687429872654204083552056456404421174124065041932362831296643126330768715450444950733554418200793669701331244638824360062439816712409346806322169771701563590417609841261977801052586956634654144702511135382841010278579543061802357275500930513955637771043922799597114118278203358118398952338720119626666828781215343331193353019800652511924103594315072427251589774226901431325149775220621148653209528291784172678852791825950189428306645453380829438548491390660090152646315666940813051689857738445716110134773528439558663918031477128997248977232695083095920860316390860179422146804892537147135669490647597566350405076105930300153453613446834614136284840473063909580064862482211399539962122107992774053203059756987131501429238941821989218445861496845306346078287058864262560349767113385390753047360747520569725532663517964059488138127648519130232826129551720747594498863925111049785977410104647258831744969489273332281068408949475978706769012216951869658194406136694310323411619613160554381608728305543504819071159752742665917363693001980988797627218662628543311906086034280619151845297823703639898449414417889008602782220998390227472837967411429578924346545640402855167478372538831386154780508035236893583332887355879794886804980971406868936719416711504307402575102269081707385928535837390976424975922421061832372517021428320986753744507133218963666908565634963306077455683011837149400258404997766113525532847665618870592978212729899729592794781820428719807102278646183807006401083138975677112754136221127444534535584959769252575758312999039536959893249951324106784265611556743660088737484274038234811784911002123537108015334407708175281579422928548731689863980071896268684985779061942582000173178473797975815609269087287850270024414741281953578873964745859459899535543412801653553049058528794674398220606230386688852700505218904927782197514115595435549125326115087432280435609563176116321811794164884206928474315699133677787956913705592704959893911100786224112449931719539890308215307126971807352814294437374058180589784287101566325873726600012296180403780429093175160473979931236882466314524590792512088916974765430245705320638670468411054034201437664442213212750799846299157010147106552946146746392249574530619682203425444816247545977269653430250686824205288099692448923652171403817749282935917315481284919621433304080904306867233682060716291289398517406255904282247558159509102324206160816363511440953267967974466214658121897383725705201831800678505181233270743236051760236565304605919728246762046497950757124332306210615236617229324468286251110577832854712371857906482302429199129753477340618812393224405123793229248698239302094605799468502209356458018864737205798950819968285087908120645175464792846657029993496146354533816989879012073959534299458051884682918835631136138879631316173442207506218212945047503433730640140356614106403320867621443183928438969994268286836082535591242751488383392264668222963323657488981599104902374571278077062853236895690028469742954774248422335523859049299225453318270693966088603518491166875108552006265340966412611220069290556369052744064893640087015171662929356529921474420793873710647399136453402185931518201576110059405556600166318190916348212818643068418256991194316266715898588673650488980580832972145195811525832974358064432698289209364284959616975339927502383832695801109608954786457256109785378297307074918168744735731189049849490781632210127110919398357638892753131749978321368280932894349330930087868884127092076359007648065118301317440813138170776478562086983456849957696333241556699085937149528437303782174166781012624737754844959408277598042857813775448446192929537153359741871355556678028606484917974827559022377376189703770332489774349235376523557139076431488967144133099539679871046284747721772185865851985971282165739148574494328320308464163956096301047370473988450307936956928683464113764226308568695688152053749196294562881085987015910764955019272667378276517237450013662421051146709184898952269727656206976263055094938932099216377529415335060027109430018977339221845390337351007942764665232509045377940478212355620488638969640291029182673024368888013982750049655688955540362739754118359277009094291839958396298535952123465573707751680432023872401008786292362558484920221296055948232317635214207117650427699747801290249150914873347204981208353486521246233538858471700470120592394582541522312967601307268280232044633644234100026474341568399123881048049819491200940244895720301881220640996997340843736095812449945913231793359333819197360248853375641030435643732302001328359990615298394916710687997693926699033522064083729586994304357670917169796698442332656830732550000321312902706719106342428311390049478179307304556219943912072209495471916547109605404919944186051724981471812994063119290173738101176617356976495636675620278895592099504686163440305250658681735840269428736633431167832903837475658050990783985384926064721246565130660487673608585790218386643241627198210378772796337736742692945663985470529377745854692207002046330357343505517537014050310355526578082729897049230547545589009275410944504014157125357682801074915174627928533783099570631952876838237806368177841661186334747789420166190186143388804514884174361681454810362321037643274595653364629397295294049952661691181657740018116146497654407589150912557599100855273107733703213603505619407350405223414533224306604743600257212590127202517146952605462439215815151732661454812243619860357386922465403688559787750083268386930674253759349376972691382532780570135683441862315010318955128705494038594760949278590520009881447715839714713971813720554960331191642239195313230213875992717401904622413925914800620171561815889352945121978193704745708538695427900233080410588007250947512318930796844637224171170594606197614751977323896101315556406372309310279476973938229476346893933755946893665094049910252612163538072005644241026471164639800490998535570282059396054554479255558624918709232180130454102936332893619326596350851413637207293142767763267817840066780089558654877782630822818446508158509625695020697797889664140551101421185533444015948880284701657904464926309216120238068566472631611326995533585414320547442896728173291714010643730593960222482733969720865809194288803963344344876467583385597351333330628439786357062196382217705500672607607570202305548328439335937369624085404957344415141889143812206076832329063384332685935928226648361622876815670931303789678327741487845287838232474038340893449427806045589018183673133602271167285304427194507315740913600066356089181219040305019319028163972135790696025211929562455952835850442627787993214468221041325612271290302469610374855134599106662606082143546126463790846952338680559237822828610361386416013753920426888371192602742087474507782730180882648297991489233434653363930327991816476995529468892904060335470265188317825821391915073117022336839564945335630414192442838503954209073337511117053790819768061378846157004292392264788138228486672543415580694421193506836000488465561599083339184724263183698928130695654949153165010313216361224018298711517222401523368101476246169896417259748838727189598765602350324828709741468793415378708814573190327920453219231685852735108372055942456601545647944675449566859142997988233179819059574125368681032194798082603876241044848730208905065871934264174092007936669883601462309762759844113071525758916288010581709353072588887654386253201848624931923638568216562603110434528313030704972291334873033240933736956347974889824930017415805659182123288343858101250171537305398462043432455721482088547523494730467761429282915391485852688505423074450548192619166975975031503447208211845313907683486006908772752077246485706597636740936173143436990399498908375710246545650814962015988805204483379491707040848303909417512426275869868668644293498242419667403627076032399201407183071270759837132000712447159523642782162488472933913713634046138974088894178399320090051543608421618891328957740354384456107645016010462709579098652495342014766016330458293537653454523438667413798731255017029554582809547897542497367109038598264606895622241257303208140890607025206140457815282368504505765710043804228592032720729190222134651835930255942940875306994701101153416476785623543575023993736414532895773499876167502240919794121893188059017977444329403624038551082491954751841177014150820554999148803286500065069030165028455616533514890711974194172310029663247936640825364542104897640445108081123906368188594908660418340025631562661211506365309297219580687177632051461355581309500814563826112416521487163593643553646268872746276680368630680088231249970572706496265335285424273723449757482776061300818063419639083097882249478922949525891665782610044424440110326748539620120023397129834624242363283711074267309902126029110038109050751840523266273905031934856015485510632624318778970878895198168073096354223096005536267735905099473408744371024816727970009494589707630185344952680106730984246828848883760016695887137355969244555238536396178788134209309376484848406842940499731494663578455826688245825356635393289729316700066238128368519670627697889769929009597838069557440769080950069594659578325366066060213000525012998145215099629307110700615796004759918829827472751877492472674770755413679265775060149528336859838085353420874215682758801259992855903410097963019943741001394975591822918846705741010634931594527954742032057295356596869586863097328488381174243827058441735659667485315202886191192125286398739560928127513223214119754229343092375569339614672740517569529376699061052365448344078610425576694541873486379356070861240473688356773437140126350120823765176390562050604076894729400293162079760342896846897639867830553941515230713725560502914671175123451932131962571791940911728951123948113598860588062424037835751996487088330150679210175429060531418836978611027896830689666851868410470182364780700615529883149883111601949965815038674390467105247175993726709203381051984777006122752302698038537619917731907133105816779008651480172440446403764720673784583395382889380902941273987910475254258486561698048543296782281040453997661165123290729161619992628751086519341731116513305659182981762584769428708454819029344222186027977405519291266188948708010515922860149238393490889782166965109499761673179583522105791358724355029782111425280584380959770472177893827382916471882671437865821461326011263516554280516418422188264141890686619186492751718984735037496602686033671961304915922609442146773092074476794711917820209913226872184947548378003848726148872742881265579174794634151444545105599464567614478293387968015412886418098284885525959617399177657635267081989985408930744564199296902459275405143647525648661932959903068323866757518479741015342911416508753572892479684280248440220211898390243430190746592470563991910024225814399068391457857458095344096826158489731615822039837691005171654390590093326827586419753439483771905973079465029210363641972615923872187876095687197681934481955852567024141433671590889694204781798936556351775101591005026585947279448642317311892727153525046034081896227383114600546852406398855471859684088277722162250586368419379964112646321070639818773794369650252104438622320671517228411475433482803041707675438555447584321271846396281391925884972509051040944134450429845346071848875654240709690138592611645519676563708429710676494635766201285381926791204110977805857352062737510466943591592074904378966129808716274322385039032007477854211063899544954185997641428116395197239708078986048758264126544825149923227286176571389697334537835963603962709038002668921324389159009375225033651171937770657226295341257068980907793198879997076783263303670667342657925395849950582363998610492878479976185891384024744790742355981796013254960652684988733518397287191251899388324341602608356164496670902390042273216221931567939944001215159910054381084520081133103207553492484487369268314444466610780275891777468369344585045949963237156043800258227618908603074550819931892899703285549507330240121766349515315827830897786432254556221744305752825143708087184314470811004510108612122699931396969361066523608721126359012344828262284427191281973187269761974740398071778378188160519801862257232970224762494767912932684020188061795236229174601398576604233579094407723017353015337974435643738584248250538061547193075224429309117207447677149522141919390974201716026970557825836923707297811545552570788004955666915477901830719591663516687057984336951611189153751912396714116378197000784953115386326766369269172016978409040396969804861828436417776804088449208439901095951205751340861060375353408155737087188313898337656322533650946010308686111901241541794900659835366926383515058402026098259570385429145865025692157987309807064597082326377138235585737704225628144262793497769429358804020882742028263786443615935817930817858306265712263479452174065216410798029333573961137404301928294367884626832432449078812684787281988676202931062510264948586549463964789154366240635570346688477784815271412470430646040615614277320107003575855033995279377529716156628381118518085523414187577256025217995103662771477552291036839539792329375184700131215428652464111526297830742328651189481978920924682746392250346179819781021313400022272303222234731521016033826145645816472110340883197207109422849637006090510260943044730126801795349152894613046101033061811314821366141874985466628809585678299308824993966655499624380015821082410781190328189506855057581990908848597095494573176672201417764187253816862426293852974092626551536758155537683368451820154793964862810533857810979434793077956125541240828563089647076354827276586047900779183041806574320855302776686899978897939486987950729652971448050889517660684386673056662911929857913206598752762097197279390208473846210277152094212386266930256260451209117402079233658157593274696841906354187366092529138116574357045728290417433832596884391356956442617823006949118156994294295529170211353842468704890572313005646106202029653246628477843902025194715815133791174898257040115532858624973690714844800747184719290671002133191274834310662201874141841328708920709275866745037664169280121112867057832132585948539987132879098472640550013972043153470930436509718084070853723316111111611632600262171748813737621046013600544051850633175245231989785291065646466038278748870331134307620041356514295482843502245454400571392386492526283423907951705366640483826875013469850263767974528926285288366544314868036628329638912254207094687335597669512007687507292940623176435604796651807847095408991068514998003358735387989422028901542800717906482276185298683079286137204396993726503610285463352157718364571843381950031926272352293654343387522809514152498052577486366048613580539162662183475105825647260311633442002377527140625112075332294909525522330744664115572260242435895269482927435844022622001466247093866533879048392320516224276433339282642640953964341822416705658461244760448817737705782669080880834418822622611342632727419248415651121035047131961583094994438779439078380664656207143187309895280874153167621657602227990850199615587578332393883365169478142077533262283694526612005465820771400826060398839255150948861553177333447506822679211849690448880479070102043288205874672361672971246062341973369704807867768609989464712379097525706498042381815865399434983035941162258347729020489356838477197804973214911448748749915616679253857438010864500220134843719609727912761136925035123155282535741655826107266099467657016111855684257826878422197833994329148734893923892153298966294232703135845615804723993624827409373966761563257981994036006655039613941881183164267144485664874468348587099434743710128859267552473831462181434321232124758618476925803128913233878664527525204324484796532776273320171351979849530142473805976430318655810403609897537469226336015596525652284888167037460054235043655813438329870872734142062859147847007274999414885129441657918212383876056572545671794085637289277002790218604788423519924573051811976377731594412994393860534559159658127123862955315918182841923881357245009246238507097741891437575676886206936433608263660374355173185026954239766173038826275043838965247160428689739548061640664606565379050539422795708801840829664956978192406737307076253014257542221763860230431809477056758905681723033326311408802886092880151777469082375063137750925275331638009836786645991949881018108222446858443984865972449621097999331605268587810061927125889694400669979755648800940895626242917531834388920035663113368763931463847812763130237825562198311791061780856687903309789539747505239545316630638169559777653347655949908779202359718666623572487055558216484036084925217803431104356647417600193631613474196113126657206064282217690428541246560204561459484317744683213906021267727411189443675804442911583757423572500214191467493342871160840582639470485636370375679604797073490813681083838562113841391587052553615073991983125473434527404596547926972539542447555990332809716643578039646945749813368621152410490288581779206318208255069166455507840899628333174744873951607229399258854694188637978240144635295264982572856632103053550891057171748674115218494774077589151115819489068851971959768129214023511454382738867557288320426608338030759515727545577639726238470674634011626346953231815229549718996906470438903536574430644436472716449550868519871817092814068746449470806856174570885105064766494332205391085097539987897980672278869943134632799032372604933150163386774039430519493297142505321117669011820293604482694166301309801111227443654953271242388534939973277749999335296667138307969441135719079969506099821923206878892624416110175909254904610286553512032488285673735148429324009831633211264460376172046209384270528903772251057643968938983722779640468452705694321085455273829462711022737243290606294601651732654594463569861350966095209962038508010899673666470073918705760679801337058347046567503369379598928154437380765511031719081985901371088639600700705631873099251480947989238619052479230983309717938226245725600119571130722386790431255742179135633111146646083268382596762356018472772209198013121983224179079476134977421748168833934278876403014334318798493417716613256506422668264638388429786875443810986754386459491846082078633346046469418429778813833857755519670005669840456587642130852057050148314568259387702428619224671173187370822224627538313365937868201435535126600146246249435880806572693573084485615073901842761167215162204840459913839674251648
C++
#include<bits/stdc++.h>
using namespace std;
#define _cin ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(a, b) for(ll i =a;i<=b;++i)
double agm(double a, double g) //ARITHMETIC GEOMETRIC MEAN
{ double epsilon = 1.0E-16,a1,g1;
if(a*g<0.0)
{ cout<<"Couldn't find arithmetic-geometric mean of these numbers\n";
exit(1);
}
while(fabs(a-g)>epsilon)
{ a1 = (a+g)/2.0;
g1 = sqrt(a*g);
a = a1;
g = g1;
}
return a;
}
int main()
{ _cin; //fast input-output
double x, y;
cout<<"Enter X and Y: "; //Enter two numbers
cin>>x>>y;
cout<<"\nThe Arithmetic-Geometric Mean of "<<x<<" and "<<y<<" is "<<agm(x, y);
return 0;
}
Enter X and Y: 1.0 2.0 The Arithmetic-Geometric Mean of 1.0 and 2.0 is 1.45679103104690677028543177584651857614517211914062
Clojure
(ns agmcompute
(:gen-class))
; Java Arbitray Precision Library
(import '(org.apfloat Apfloat ApfloatMath))
(def precision 70)
(def one (Apfloat. 1M precision))
(def two (Apfloat. 2M precision))
(def half (Apfloat. 0.5M precision))
(def isqrt2 (.divide one (ApfloatMath/pow two half)))
(def TOLERANCE (Apfloat. 0.000000M precision))
(defn agm [a g]
" Simple AGM Loop calculation "
(let [THRESH 1e-65 ; done when error less than threshold or we exceed max loops
MAX-LOOPS 1000000]
(loop [[an gn] [a g], cnt 0]
(if (or (< (ApfloatMath/abs (.subtract an gn)) THRESH)
(> cnt MAX-LOOPS))
an
(recur [(.multiply (.add an gn) half) (ApfloatMath/pow (.multiply an gn) half)]
(inc cnt))))))
(println (agm one isqrt2))
- Output:
8.47213084793979086606499123482191636481445910326942185060579372659734e-1
COBOL
IDENTIFICATION DIVISION.
PROGRAM-ID. ARITHMETIC-GEOMETRIC-MEAN-PROG.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 AGM-VARS.
05 A PIC 9V9(16).
05 A-ZERO PIC 9V9(16).
05 G PIC 9V9(16).
05 DIFF PIC 9V9(16) VALUE 1.
* Initialize DIFF with a non-zero value, otherwise AGM-PARAGRAPH
* is never performed at all.
PROCEDURE DIVISION.
TEST-PARAGRAPH.
MOVE 1 TO A.
COMPUTE G = 1 / FUNCTION SQRT(2).
* The program will run with the test values. If you would rather
* calculate the AGM of numbers input at the console, comment out
* TEST-PARAGRAPH and un-comment-out INPUT-A-AND-G-PARAGRAPH.
* INPUT-A-AND-G-PARAGRAPH.
* DISPLAY 'Enter two numbers.'
* ACCEPT A.
* ACCEPT G.
CONTROL-PARAGRAPH.
PERFORM AGM-PARAGRAPH UNTIL DIFF IS LESS THAN 0.000000000000001.
DISPLAY A.
STOP RUN.
AGM-PARAGRAPH.
MOVE A TO A-ZERO.
COMPUTE A = (A-ZERO + G) / 2.
MULTIPLY A-ZERO BY G GIVING G.
COMPUTE G = FUNCTION SQRT(G).
SUBTRACT A FROM G GIVING DIFF.
COMPUTE DIFF = FUNCTION ABS(DIFF).
- Output:
0.8472130847939792
Common Lisp
(defun agm (a0 g0 &optional (tolerance 1d-8))
(loop for a = a0 then (* (+ a g) 5d-1)
and g = g0 then (sqrt (* a g))
until (< (abs (- a g)) tolerance)
finally (return a)))
- Output:
CL-USER> (agm 1d0 (/ 1d0 (sqrt 2d0))) 0.8472130848351929d0 CL-USER> (agm 1d0 (/ 1d0 (sqrt 2d0)) 1d-10) 0.8472130848351929d0 CL-USER> (agm 1d0 (/ 1d0 (sqrt 2d0)) 1d-12) 0.8472130847939792d0
D
import std.stdio, std.math, std.meta, std.typecons;
real agm(real a, real g, in int bitPrecision=60) pure nothrow @nogc @safe {
do {
//{a, g} = {(a + g) / 2.0, sqrt(a * g)};
AliasSeq!(a, g) = tuple((a + g) / 2.0, sqrt(a * g));
} while (feqrel(a, g) < bitPrecision);
return a;
}
void main() @safe {
writefln("%0.19f", agm(1, 1 / sqrt(2.0)));
}
- Output:
0.8472130847939790866
All the digits shown are exact.
Delphi
program geometric_mean;
{$APPTYPE CONSOLE}
uses
System.SysUtils;
function Fabs(value: Double): Double;
begin
Result := value;
if Result < 0 then
Result := -Result;
end;
function agm(a, g: Double):Double;
var
iota, a1, g1: Double;
begin
iota := 1.0E-16;
if a * g < 0.0 then
begin
Writeln('arithmetic-geometric mean undefined when x*y<0');
exit(1);
end;
while Fabs(a - g) > iota do
begin
a1 := (a + g) / 2.0;
g1 := sqrt(a * g);
a := a1;
g := g1;
end;
Exit(a);
end;
var
x, y: Double;
begin
Write('Enter two numbers:');
Readln(x, y);
writeln(format('The arithmetic-geometric mean is %.6f', [agm(x, y)]));
readln;
end.
- Output:
Enter two numbers:1 2 The arithmetic-geometric mean is 1,456791
dc
>>> 200 k ? sbsa [lalb +2/ lalb *vsb dsa lb - 0!=:]ds:xlap
?> 1 1 2 v /
- Output:
.8472130847939790866064991234821916364814459103269421850605793726597\ 34004834134759723200293994611229942122285625233410963097962665830871\ 05969971363598338425117632681428906038970676860161665004828118868
You can change the precision (200 by default)
EasyLang
func agm a g .
repeat
a0 = a
a = (a0 + g) / 2
g = sqrt (a0 * g)
until abs (a0 - a) < abs (a) * 1e-15
.
return a
.
numfmt 16 0
print agm 1 sqrt 0.5
EchoLisp
We use the (~= a b) operator which tests for |a - b| < ε = (math-precision).
(lib 'math)
(define (agm a g)
(if (~= a g) a
(agm (// (+ a g ) 2) (sqrt (* a g)))))
(math-precision)
→ 0.000001 ;; default
(agm 1 (/ 1 (sqrt 2)))
→ 0.8472130848351929
(math-precision 1.e-15)
→ 1e-15
(agm 1 (/ 1 (sqrt 2)))
→ 0.8472130847939792
Elixir
defmodule ArithhGeom do
def mean(a,g,tol) when abs(a-g) <= tol, do: a
def mean(a,g,tol) do
mean((a+g)/2,:math.pow(a*g, 0.5),tol)
end
end
IO.puts ArithhGeom.mean(1,1/:math.sqrt(2),0.0000000001)
- Output:
0.8472130848351929
Erlang
%% Arithmetic Geometric Mean of 1 and 1 / sqrt(2)
%% Author: Abhay Jain
-module(agm_calculator).
-export([find_agm/0]).
-define(TOLERANCE, 0.0000000001).
find_agm() ->
A = 1,
B = 1 / (math:pow(2, 0.5)),
AGM = agm(A, B),
io:format("AGM = ~p", [AGM]).
agm (A, B) when abs(A-B) =< ?TOLERANCE ->
A;
agm (A, B) ->
A1 = (A+B) / 2,
B1 = math:pow(A*B, 0.5),
agm(A1, B1).
Output:
AGM = 0.8472130848351929
ERRE
PROGRAM AGM
!
! for rosettacode.org
!
!$DOUBLE
PROCEDURE AGM(A,G->A)
LOCAL TA
REPEAT
TA=A
A=(A+G)/2
G=SQR(TA*G)
UNTIL A=TA
END PROCEDURE
BEGIN
AGM(1.0,1/SQR(2)->A)
PRINT(A)
END PROGRAM
F#
let rec agm a g precision =
if precision > abs(a - g) then a else
agm (0.5 * (a + g)) (sqrt (a * g)) precision
printfn "%g" (agm 1. (sqrt(0.5)) 1e-15)
Output
0.847213
Factor
USING: kernel math math.functions prettyprint ;
IN: rosetta-code.arithmetic-geometric-mean
: agm ( a g -- a' g' ) 2dup [ + 0.5 * ] 2dip * sqrt ;
1 1 2 sqrt / [ 2dup - 1e-15 > ] [ agm ] while drop .
- Output:
0.8472130847939792
Forth
: agm ( a g -- m )
begin
fover fover f+ 2e f/
frot frot f* fsqrt
fover fover 1e-15 f~
until
fdrop ;
1e 2e -0.5e f** agm f. \ 0.847213084793979
Fortran
A Fortran 77 implementation
function agm(a,b)
implicit none
double precision agm,a,b,eps,c
parameter(eps=1.0d-15)
10 c=0.5d0*(a+b)
b=sqrt(a*b)
a=c
if(a-b.gt.eps*a) go to 10
agm=0.5d0*(a+b)
end
program test
implicit none
double precision agm
print*,agm(1.0d0,1.0d0/sqrt(2.0d0))
end
Futhark
import "futlib/math"
fun agm(a: f64, g: f64): f64 =
let eps = 1.0E-16
loop ((a,g)) = while f64.abs(a-g) > eps do
((a+g) / 2.0,
f64.sqrt (a*g))
in a
fun main(x: f64, y: f64): f64 =
agm(x,y)
Go
package main
import (
"fmt"
"math"
)
const ε = 1e-14
func agm(a, g float64) float64 {
for math.Abs(a-g) > math.Abs(a)*ε {
a, g = (a+g)*.5, math.Sqrt(a*g)
}
return a
}
func main() {
fmt.Println(agm(1, 1/math.Sqrt2))
}
- Output:
0.8472130847939792
Groovy
Solution:
double agm (double a, double g) {
double an = a, gn = g
while ((an-gn).abs() >= 10.0**-14) { (an, gn) = [(an+gn)*0.5, (an*gn)**0.5] }
an
}
Test:
println "agm(1, 0.5**0.5) = agm(1, ${0.5**0.5}) = ${agm(1, 0.5**0.5)}"
assert (0.8472130847939792 - agm(1, 0.5**0.5)).abs() <= 10.0**-14
Output:
agm(1, 0.5**0.5) = agm(1, 0.7071067811865476) = 0.8472130847939792
Haskell
-- Return an approximation to the arithmetic-geometric mean of two numbers.
-- The result is considered accurate when two successive approximations are
-- sufficiently close, as determined by "eq".
agm :: (Floating a) => a -> a -> ((a, a) -> Bool) -> a
agm a g eq = snd $ until eq step (a, g)
where
step (a, g) = ((a + g) / 2, sqrt (a * g))
-- Return the relative difference of the pair. We assume that at least one of
-- the values is far enough from 0 to not cause problems.
relDiff :: (Fractional a) => (a, a) -> a
relDiff (x, y) =
let n = abs (x - y)
d = (abs x + abs y) / 2
in n / d
main :: IO ()
main = do
let equal = (< 0.000000001) . relDiff
print $ agm 1 (1 / sqrt 2) equal
- Output:
0.8472130847527654
Icon and Unicon
procedure main(A)
a := real(A[1]) | 1.0
g := real(A[2]) | (1 / 2^0.5)
epsilon := real(A[3])
write("agm(",a,",",g,") = ",agm(a,g,epsilon))
end
procedure agm(an, gn, e)
/e := 1e-15
while abs(an-gn) > e do {
ap := (an+gn)/2.0
gn := (an*gn)^0.5
an := ap
}
return an
end
Output:
->agm agm(1.0,0.7071067811865475) = 0.8472130847939792 ->
J
This one is probably worth not naming, in J, because there are so many interesting variations.
First, the basic approach (with display precision set to 16 digits, which slightly exceeds the accuracy of 64 bit IEEE floating point arithmetic):
mean=: +/ % #
(mean , */ %:~ #)^:_] 1,%%:2
0.8472130847939792 0.8472130847939791
This is the limit -- it stops when values are within a small epsilon of previous calculations. We can ask J for unique values (which also means -- unless we specify otherwise -- values within a small epsilon of each other, for floating point values):
~.(mean , */ %:~ #)^:_] 1,%%:2
0.8472130847939792
Another variation would be to show intermediate values, in the limit process:
(mean, */ %:~ #)^:a: 1,%%:2
1 0.7071067811865475
0.8535533905932737 0.8408964152537145
0.8472249029234942 0.8472012667468915
0.8472130848351929 0.8472130847527654
0.8472130847939792 0.8472130847939791
Arbitrary Precision
Another variation would be to use arbitrary precision arithmetic in place of floating point arithmetic.
Borrowing routines from that page, but going with a default of approximately 100 digits of precision:
DP=:101
round=: DP&$: : (4 : 0)
b %~ <.1r2+y*b=. 10x^x
)
sqrt=: DP&$: : (4 : 0) " 0
assert. 0<:y
%/ <.@%: (2 x: (2*x) round y)*10x^2*x+0>.>.10^.y
)
ln=: DP&$: : (4 : 0) " 0
assert. 0<y
m=. <.0.5+2^.y
t=. (<:%>:) (x:!.0 y)%2x^m
if. x<-:#":t do. t=. (1+x) round t end.
ln2=. 2*+/1r3 (^%]) 1+2*i.>.0.5*(%3)^.0.5*0.1^x+>.10^.1>.m
lnr=. 2*+/t (^%]) 1+2*i.>.0.5*(|t)^.0.5*0.1^x
lnr + m * ln2
)
exp=: DP&$: : (4 : 0) " 0
m=. <.0.5+y%^.2
xm=. x+>.m*10^.2
d=. (x:!.0 y)-m*xm ln 2
if. xm<-:#":d do. d=. xm round d end.
e=. 0.1^xm
n=. e (>i.1:) a (^%!@]) i.>.a^.e [ a=. |y-m*^.2
(2x^m) * 1++/*/\d%1+i.n
)
We are also going to want a routine to display numbers with this precision, and we are going to need to manage epsilon manually, and we are going to need an arbitrary root routine:
fmt=:[: ;:inv DP&$: : (4 :0)&.>
x{.deb (x*2j1)":y
)
root=: ln@] exp@% [
epsilon=: 1r9^DP
Some example uses:
fmt sqrt 2
1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641572
fmt *~sqrt 2
2.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
fmt epsilon
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000418
fmt 2 root 2
1.414213562373095048801688724209698078569671875376948073176679737990732478462107038850387534327641572
Note that 2 root 2 is considerably slower than sqrt 2. The price of generality. So, while we could define geometric mean generally, a desire for good performance pushes us to use a routine specialized for two numbers:
geomean=: */ root~ #
geomean2=: [: sqrt */
A quick test to make sure these can be equivalent:
fmt geomean 3 5
3.872983346207416885179265399782399610832921705291590826587573766113483091936979033519287376858673517
fmt geomean2 3 5
3.872983346207416885179265399782399610832921705291590826587573766113483091936979033519287376858673517
Now for our task example:
fmt (mean, geomean2)^:(epsilon <&| -/)^:a: 1,%sqrt 2
1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0.707106781186547524400844362104849039284835937688474036588339868995366239231053519425193767163820786
0.853553390593273762200422181052424519642417968844237018294169934497683119615526759712596883581910393 0.840896415253714543031125476233214895040034262356784510813226085974924754953902239814324004199292536
0.847224902923494152615773828642819707341226115600510764553698010236303937284714499763460443890601464 0.847201266746891460403631453693352397963981013612000500823295747923488191871327668107581434542353536
0.847213084835192806509702641168086052652603564606255632688496879079896064578021083935520939216477500 0.847213084752765366704298051779902070392110656059452583317776227659438896688518556753569298762449381
0.847213084793979086607000346473994061522357110332854108003136553369667480633269820344545118989463440 0.847213084793979086605997900490389211440534858586261300461413929971399281619068666682569108141224710
0.847213084793979086606499123482191636481445984459557704232275241670533381126169243513557113565344075 0.847213084793979086606499123482191636481445836194326665888883503648934628542100275932846717790147361
0.847213084793979086606499123482191636481445910326942185060579372659734004834134759723201915677745718 0.847213084793979086606499123482191636481445910326942185060579372659734004834134759723198672311476741
0.847213084793979086606499123482191636481445910326942185060579372659734004834134759723200293994611229 0.847213084793979086606499123482191636481445910326942185060579372659734004834134759723200293994611229
We could of course extract out only a representative final value, but it's obvious enough, and showing how rapidly this converges is fun.
Java
/*
* Arithmetic-Geometric Mean of 1 & 1/sqrt(2)
* Brendan Shaklovitz
* 5/29/12
*/
public class ArithmeticGeometricMean {
public static double agm(double a, double g) {
double a1 = a;
double g1 = g;
while (Math.abs(a1 - g1) >= 1.0e-14) {
double arith = (a1 + g1) / 2.0;
double geom = Math.sqrt(a1 * g1);
a1 = arith;
g1 = geom;
}
return a1;
}
public static void main(String[] args) {
System.out.println(agm(1.0, 1.0 / Math.sqrt(2.0)));
}
}
- Output:
0.8472130847939792
JavaScript
ES5
function agm(a0, g0) {
var an = (a0 + g0) / 2,
gn = Math.sqrt(a0 * g0);
while (Math.abs(an - gn) > tolerance) {
an = (an + gn) / 2, gn = Math.sqrt(an * gn)
}
return an;
}
agm(1, 1 / Math.sqrt(2));
ES6
(() => {
'use strict';
// ARITHMETIC-GEOMETRIC MEAN
// agm :: Num a => a -> a -> a
let agm = (a, g) => {
let abs = Math.abs,
sqrt = Math.sqrt;
return until(
m => abs(m.an - m.gn) < tolerance,
m => {
return {
an: (m.an + m.gn) / 2,
gn: sqrt(m.an * m.gn)
};
}, {
an: (a + g) / 2,
gn: sqrt(a * g)
}
)
.an;
},
// GENERIC
// until :: (a -> Bool) -> (a -> a) -> a -> a
until = (p, f, x) => {
let v = x;
while (!p(v)) v = f(v);
return v;
};
// TEST
let tolerance = 0.000001;
return agm(1, 1 / Math.sqrt(2));
})();
- Output:
0.8472130848351929
jq
Naive version that assumes tolerance is appropriately specified:
def naive_agm(a; g; tolerance):
def abs: if . < 0 then -. else . end;
def _agm:
# state [an,gn]
if ((.[0] - .[1])|abs) > tolerance
then [add/2, ((.[0] * .[1])|sqrt)] | _agm
else .
end;
[a, g] | _agm | .[0] ;
This version avoids an infinite loop if the requested tolerance is too small:
def agm(a; g; tolerance):
def abs: if . < 0 then -. else . end;
def _agm:
# state [an,gn, delta]
((.[0] - .[1])|abs) as $delta
| if $delta == .[2] and $delta < 10e-16 then .
elif $delta > tolerance
then [ .[0:2]|add / 2, ((.[0] * .[1])|sqrt), $delta] | _agm
else .
end;
if tolerance <= 0 then error("specified tolerance must be > 0")
else [a, g, 0] | _agm | .[0]
end ;
# Example:
agm(1; 1/(2|sqrt); 1e-100)
- Output:
$ jq -n -f Arithmetic-geometric_mean.jq 0.8472130847939792
Julia
function agm(x, y, e::Real = 5)
(x ≤ 0 || y ≤ 0 || e ≤ 0) && throw(DomainError("x, y must be strictly positive"))
g, a = minmax(x, y)
while e * eps(x) < a - g
a, g = (a + g) / 2, sqrt(a * g)
end
a
end
x, y = 1.0, 1 / √2
println("# Using literal-precision float numbers:")
@show agm(x, y)
println("# Using half-precision float numbers:")
x, y = Float32(x), Float32(y)
@show agm(x, y)
println("# Using ", precision(BigFloat), "-bit float numbers:")
x, y = big(1.0), 1 / √big(2.0)
@show agm(x, y)
The ε for this calculation is given as a positive integer multiple of the machine ε for x.
- Output:
# Using literal-precision float numbers: agm(x, y) = 0.8472130847939792 # Using half-precision float numbers: agm(x, y) = 0.84721315f0 # Using 256-bit float numbers: agm(x, y) = 8.472130847939790866064991234821916364814459103269421850605793726597340048341323e-01
Klingphix
include ..\Utilitys.tlhy
:agm [ over over + 2 / rot rot * sqrt ] [ over over tostr swap tostr # ] while drop ;
1 1 2 sqrt / agm
pstack
" " input
include ..\Utilitys.tlhy
:agm %a %g %p !p !g !a
$p $a $g - abs > ( [$a] [.5 $a $g + * $a $g * sqrt $p agm] ) if ;
1 .5 sqrt 1e-15 agm
pstack
" " input
- Output:
(0.847213)
Kotlin
// version 1.0.5-2
fun agm(a: Double, g: Double): Double {
var aa = a // mutable 'a'
var gg = g // mutable 'g'
var ta: Double // temporary variable to hold next iteration of 'aa'
val epsilon = 1.0e-16 // tolerance for checking if limit has been reached
while (true) {
ta = (aa + gg) / 2.0
if (Math.abs(aa - ta) <= epsilon) return ta
gg = Math.sqrt(aa * gg)
aa = ta
}
}
fun main(args: Array<String>) {
println(agm(1.0, 1.0 / Math.sqrt(2.0)))
}
- Output:
0.8472130847939792
Lambdatalk
{def eps 1e-15}
-> eps
{def agm
{lambda {:a :g}
{if {> {abs {- :a :g}} {eps}}
then {agm {/ {+ :a :g} 2}
{sqrt {* :a :g}}}
else :a }}}
-> agm
{agm 1 {/ 1 {sqrt 2}}}
-> 0.8472130847939792
Multi-precision version using the lib_BN library
{BN.DEC 70}
-> 70 digits
{def EPS {BN./ 1 {BN.pow 10 45}}}
-> EPS
{def AGM
{lambda {:a :g}
{if {= {BN.compare {BN.abs {BN.- :a :g}} {EPS}} 1}
then {AGM {BN./ {BN.+ :a :g} 2}
{BN.sqrt {BN.* :a :g}}}
else :a }}}
-> AGM
{AGM 1 {BN./ 1 {BN.sqrt 2}}}
-> 0.8472130847939790866064991234821916364814459103269421850605793726597339
LFE
(defun agm (a g)
(agm a g 1.0e-15))
(defun agm (a g tol)
(if (=< (- a g) tol)
a
(agm (next-a a g)
(next-g a g)
tol)))
(defun next-a (a g)
(/ (+ a g) 2))
(defun next-g (a g)
(math:sqrt (* a g)))
Usage:
> (agm 1 (/ 1 (math:sqrt 2))) 0.8472130847939792
LiveCode
function agm aa,g
put abs(aa-g) into absdiff
put (aa+g)/2 into aan
put sqrt(aa*g) into gn
repeat while abs(aan - gn) < absdiff
put abs(aa-g) into absdiff
put (aa+g)/2 into aan
put sqrt(aa*g) into gn
put aan into aa
put gn into g
end repeat
return aa
end agm
Example
put agm(1, 1/sqrt(2))
-- ouput
-- 0.847213
LLVM
; This is not strictly LLVM, as it uses the C library function "printf".
; LLVM does not provide a way to print values, so the alternative would be
; to just load the string into memory, and that would be boring.
; Additional comments have been inserted, as well as changes made from the output produced by clang such as putting more meaningful labels for the jumps
$"ASSERTION" = comdat any
$"OUTPUT" = comdat any
@"ASSERTION" = linkonce_odr unnamed_addr constant [48 x i8] c"arithmetic-geometric mean undefined when x*y<0\0A\00", comdat, align 1
@"OUTPUT" = linkonce_odr unnamed_addr constant [42 x i8] c"The arithmetic-geometric mean is %0.19lf\0A\00", comdat, align 1
;--- The declarations for the external C functions
declare i32 @printf(i8*, ...)
declare void @exit(i32) #1
declare double @sqrt(double) #1
declare double @llvm.fabs.f64(double) #2
;----------------------------------------------------------------
;-- arithmetic geometric mean
define double @agm(double, double) #0 {
%3 = alloca double, align 8 ; allocate local g
%4 = alloca double, align 8 ; allocate local a
%5 = alloca double, align 8 ; allocate iota
%6 = alloca double, align 8 ; allocate a1
%7 = alloca double, align 8 ; allocate g1
store double %1, double* %3, align 8 ; store param g in local g
store double %0, double* %4, align 8 ; store param a in local a
store double 1.000000e-15, double* %5, align 8 ; store 1.0e-15 in iota (1.0e-16 was causing the program to hang)
%8 = load double, double* %4, align 8 ; load a
%9 = load double, double* %3, align 8 ; load g
%10 = fmul double %8, %9 ; a * g
%11 = fcmp olt double %10, 0.000000e+00 ; a * g < 0.0
br i1 %11, label %enforce, label %loop
enforce:
%12 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([48 x i8], [48 x i8]* @"ASSERTION", i32 0, i32 0))
call void @exit(i32 1) #6
unreachable
loop:
%13 = load double, double* %4, align 8 ; load a
%14 = load double, double* %3, align 8 ; load g
%15 = fsub double %13, %14 ; a - g
%16 = call double @llvm.fabs.f64(double %15) ; fabs(a - g)
%17 = load double, double* %5, align 8 ; load iota
%18 = fcmp ogt double %16, %17 ; fabs(a - g) > iota
br i1 %18, label %loop_body, label %eom
loop_body:
%19 = load double, double* %4, align 8 ; load a
%20 = load double, double* %3, align 8 ; load g
%21 = fadd double %19, %20 ; a + g
%22 = fdiv double %21, 2.000000e+00 ; (a + g) / 2.0
store double %22, double* %6, align 8 ; store %22 in a1
%23 = load double, double* %4, align 8 ; load a
%24 = load double, double* %3, align 8 ; load g
%25 = fmul double %23, %24 ; a * g
%26 = call double @sqrt(double %25) #4 ; sqrt(a * g)
store double %26, double* %7, align 8 ; store %26 in g1
%27 = load double, double* %6, align 8 ; load a1
store double %27, double* %4, align 8 ; store a1 in a
%28 = load double, double* %7, align 8 ; load g1
store double %28, double* %3, align 8 ; store g1 in g
br label %loop
eom:
%29 = load double, double* %4, align 8 ; load a
ret double %29 ; return a
}
;----------------------------------------------------------------
;-- main
define i32 @main() #0 {
%1 = alloca double, align 8 ; allocate x
%2 = alloca double, align 8 ; allocate y
store double 1.000000e+00, double* %1, align 8 ; store 1.0 in x
%3 = call double @sqrt(double 2.000000e+00) #4 ; calculate the square root of two
%4 = fdiv double 1.000000e+00, %3 ; divide 1.0 by %3
store double %4, double* %2, align 8 ; store %4 in y
%5 = load double, double* %2, align 8 ; reload y
%6 = load double, double* %1, align 8 ; reload x
%7 = call double @agm(double %6, double %5) ; agm(x, y)
%8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([42 x i8], [42 x i8]* @"OUTPUT", i32 0, i32 0), double %7)
ret i32 0 ; finished
}
attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { noreturn "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #2 = { nounwind readnone speculatable }
attributes #4 = { nounwind }
attributes #6 = { noreturn }
- Output:
The arithmetic-geometric mean is 0.8472130847939791654
Logo
to about :a :b
output and [:a - :b < 1e-15] [:a - :b > -1e-15]
end
to agm :arith :geom
if about :arith :geom [output :arith]
output agm (:arith + :geom)/2 sqrt (:arith * :geom)
end
show agm 1 1/sqrt 2
Lua
function agm(a, b, tolerance)
if not tolerance or tolerance < 1e-15 then
tolerance = 1e-15
end
repeat
a, b = (a + b) / 2, math.sqrt(a * b)
until math.abs(a-b) < tolerance
return a
end
print(string.format("%.15f", agm(1, 1 / math.sqrt(2))))
Output:
0.847213084793979
M2000 Interpreter
Module Checkit {
Function Agm {
\\ new stack constructed at calling the Agm() with two values
Repeat {
Read a0, b0
Push Sqrt(a0*b0), (a0+b0)/2
' last pushed first read
} Until Stackitem(1)==Stackitem(2)
=Stackitem(1)
\\ stack deconstructed at exit of function
}
Print Agm(1,1/Sqrt(2))
}
Checkit
Maple
Maple provides this function under the name GaussAGM. To compute a floating point approximation, use evalf.
> evalf( GaussAGM( 1, 1 / sqrt( 2 ) ) ); # default precision is 10 digits
0.8472130847
> evalf[100]( GaussAGM( 1, 1 / sqrt( 2 ) ) ); # to 100 digits
0.847213084793979086606499123482191636481445910326942185060579372659\
7340048341347597232002939946112300
Alternatively, if one or both arguments is already a float, Maple will compute a floating point approximation automatically.
> GaussAGM( 1.0, 1 / sqrt( 2 ) );
0.8472130847
Mathematica/Wolfram Language
To any arbitrary precision, just increase PrecisionDigits
PrecisionDigits = 85;
AGMean[a_, b_] := FixedPoint[{ Tr@#/2, Sqrt[Times@@#] }&, N[{a,b}, PrecisionDigits]]〚1〛
AGMean[1, 1/Sqrt[2]] 0.8472130847939790866064991234821916364814459103269421850605793726597340048341347597232
MATLAB / Octave
function [a,g]=agm(a,g)
%%arithmetic_geometric_mean(a,g)
while (1)
a0=a;
a=(a0+g)/2;
g=sqrt(a0*g);
if (abs(a0-a) < a*eps) break; end;
end;
end
octave:26> agm(1,1/sqrt(2)) ans = 0.84721
Maxima
agm(a, b) := %pi/4*(a + b)/elliptic_kc(((a - b)/(a + b))^2)$
agm(1, 1/sqrt(2)), bfloat, fpprec: 85;
/* 8.472130847939790866064991234821916364814459103269421850605793726597340048341347597232b-1 */
МК-61/52
П1 <-> П0 1 ВП 8 /-/ П2 ИП0 ИП1
- ИП2 - /-/ x<0 31 ИП1 П3 ИП0 ИП1
* КвКор П1 ИП0 ИП3 + 2 / П0 БП
08 ИП0 С/П
Modula-2
MODULE AGM;
FROM EXCEPTIONS IMPORT AllocateSource,ExceptionSource,GetMessage,RAISE;
FROM LongConv IMPORT ValueReal;
FROM LongMath IMPORT sqrt;
FROM LongStr IMPORT RealToStr;
FROM Terminal IMPORT ReadChar,Write,WriteString,WriteLn;
VAR
TextWinExSrc : ExceptionSource;
PROCEDURE ReadReal() : LONGREAL;
VAR
buffer : ARRAY[0..63] OF CHAR;
i : CARDINAL;
c : CHAR;
BEGIN
i := 0;
LOOP
c := ReadChar();
IF ((c >= '0') AND (c <= '9')) OR (c = '.') THEN
buffer[i] := c;
Write(c);
INC(i)
ELSE
WriteLn;
EXIT
END
END;
buffer[i] := 0C;
RETURN ValueReal(buffer)
END ReadReal;
PROCEDURE WriteReal(r : LONGREAL);
VAR
buffer : ARRAY[0..63] OF CHAR;
BEGIN
RealToStr(r, buffer);
WriteString(buffer)
END WriteReal;
PROCEDURE AGM(a,g : LONGREAL) : LONGREAL;
CONST iota = 1.0E-16;
VAR a1, g1 : LONGREAL;
BEGIN
IF a * g < 0.0 THEN
RAISE(TextWinExSrc, 0, "arithmetic-geometric mean undefined when x*y<0")
END;
WHILE ABS(a - g) > iota DO
a1 := (a + g) / 2.0;
g1 := sqrt(a * g);
a := a1;
g := g1
END;
RETURN a
END AGM;
VAR
x, y, z: LONGREAL;
BEGIN
WriteString("Enter two numbers: ");
x := ReadReal();
y := ReadReal();
WriteReal(AGM(x, y));
WriteLn
END AGM.
- Output:
Enter two numbers: 1.0 2.0 1.456791031046900
Enter two numbers: 1.0 0.707 0.847154622368330
NetRexx
/* NetRexx */
options replace format comments java crossref symbols nobinary
numeric digits 18
parse arg a_ g_ .
if a_ = '' | a_ = '.' then a0 = 1
else a0 = a_
if g_ = '' | g_ = '.' then g0 = 1 / Math.sqrt(2)
else g0 = g_
say agm(a0, g0)
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method agm(a0, g0) public static returns Rexx
a1 = a0
g1 = g0
loop while (a1 - g1).abs() >= Math.pow(10, -14)
temp = (a1 + g1) / 2
g1 = Math.sqrt(a1 * g1)
a1 = temp
end
return a1 + 0
Output:
0.8472130847939792
NewLISP
(define (a-next a g) (mul 0.5 (add a g)))
(define (g-next a g) (sqrt (mul a g)))
(define (amg a g tolerance)
(if (<= (sub a g) tolerance)
a
(amg (a-next a g) (g-next a g) tolerance)
)
)
(define quadrillionth 0.000000000000001)
(define root-reciprocal-2 (div 1.0 (sqrt 2.0)))
(println
"To the nearest one-quadrillionth, "
"the arithmetic-geometric mean of "
"1 and the reciprocal of the square root of 2 is "
(amg 1.0 root-reciprocal-2 quadrillionth)
)
Nim
import math
proc agm(a, g: float,delta: float = 1.0e-15): float =
var
aNew: float = 0
aOld: float = a
gOld: float = g
while (abs(aOld - gOld) > delta):
aNew = 0.5 * (aOld + gOld)
gOld = sqrt(aOld * gOld)
aOld = aNew
result = aOld
echo agm(1.0,1.0/sqrt(2.0))
Output:
8.4721308479397917e-01
See first 24 iterations:
from math import sqrt
from strutils import parseFloat, formatFloat, ffDecimal
proc agm(x,y: float): tuple[resA,resG: float] =
var
a,g: array[0 .. 23,float]
a[0] = x
g[0] = y
for n in 1 .. 23:
a[n] = 0.5 * (a[n - 1] + g[n - 1])
g[n] = sqrt(a[n - 1] * g[n - 1])
(a[23], g[23])
var t = agm(1, 1/sqrt(2.0))
echo("Result A: " & formatFloat(t.resA, ffDecimal, 24))
echo("Result G: " & formatFloat(t.resG, ffDecimal, 24))
Oberon-2
MODULE Agm;
IMPORT
Math := LRealMath,
Out;
CONST
epsilon = 1.0E-15;
PROCEDURE Of*(a,g: LONGREAL): LONGREAL;
VAR
na,ng,og: LONGREAL;
BEGIN
na := a; ng := g;
LOOP
og := ng;
ng := Math.sqrt(na * ng);
na := (na + og) * 0.5;
IF na - ng <= epsilon THEN EXIT END
END;
RETURN ng;
END Of;
BEGIN
Out.LongReal(Of(1,1 / Math.sqrt(2)),0,0);Out.Ln
END Agm.
- Output:
8.4721308479397905E-1
Objeck
class ArithmeticMean {
function : Amg(a : Float, g : Float) ~ Nil {
a1 := a;
g1 := g;
while((a1-g1)->Abs() >= Float->Power(10, -14)) {
tmp := (a1+g1)/2.0;
g1 := Float->SquareRoot(a1*g1);
a1 := tmp;
};
a1->PrintLine();
}
function : Main(args : String[]) ~ Nil {
Amg(1,1/Float->SquareRoot(2));
}
}
Output:
0.847213085
OCaml
let rec agm a g tol =
if tol > abs_float (a -. g) then a else
agm (0.5*.(a+.g)) (sqrt (a*.g)) tol
let _ = Printf.printf "%.16f\n" (agm 1.0 (sqrt 0.5) 1e-15)
Output
0.8472130847939792
Oforth
: agm \ a b -- m
while( 2dup <> ) [ 2dup + 2 / -rot * sqrt ] drop ;
Usage :
1 2 sqrt inv agm
- Output:
0.847213084793979
OOC
import math // import for sqrt() function
amean: func (x: Double, y: Double) -> Double {
(x + y) / 2.
}
gmean: func (x: Double, y: Double) -> Double {
sqrt(x * y)
}
agm: func (a: Double, g: Double) -> Double {
while ((a - g) abs() > pow(10, -12)) {
(a1, g1) := (amean(a, g), gmean(a, g))
(a, g) = (a1, g1)
}
a
}
main: func {
"%.16f" printfln(agm(1., sqrt(0.5)))
}
Output
0.8472130847939792
ooRexx
numeric digits 20
say agm(1, 1/rxcalcsqrt(2,16))
::routine agm
use strict arg a, g
numeric digits 20
a1 = a
g1 = g
loop while abs(a1 - g1) >= 1e-14
temp = (a1 + g1)/2
g1 = rxcalcsqrt(a1*g1,16)
a1 = temp
end
return a1+0
::requires rxmath LIBRARY
- Output:
0.8472130847939791968
PARI/GP
Built-in:
agm(1,1/sqrt(2))
Iteration:
agm2(x,y)=if(x==y,x,agm2((x+y)/2,sqrt(x*y))
Pascal
Port of the C example:
Program ArithmeticGeometricMean;
uses
gmp;
procedure agm (in1, in2: mpf_t; var out1, out2: mpf_t);
begin
mpf_add (out1, in1, in2);
mpf_div_ui (out1, out1, 2);
mpf_mul (out2, in1, in2);
mpf_sqrt (out2, out2);
end;
const
nl = chr(13)+chr(10);
var
x0, y0, resA, resB: mpf_t;
i: integer;
begin
mpf_set_default_prec (65568);
mpf_init_set_ui (y0, 1);
mpf_init_set_d (x0, 0.5);
mpf_sqrt (x0, x0);
mpf_init (resA);
mpf_init (resB);
for i := 0 to 6 do
begin
agm(x0, y0, resA, resB);
agm(resA, resB, x0, y0);
end;
mp_printf ('%.20000Ff'+nl, @x0);
mp_printf ('%.20000Ff'+nl+nl, @y0);
end.
Output is as long as the C example.
Perl
#!/usr/bin/perl -w
my ($a0, $g0, $a1, $g1);
sub agm($$) {
$a0 = shift;
$g0 = shift;
do {
$a1 = ($a0 + $g0)/2;
$g1 = sqrt($a0 * $g0);
$a0 = ($a1 + $g1)/2;
$g0 = sqrt($a1 * $g1);
} while ($a0 != $a1);
return $a0;
}
print agm(1, 1/sqrt(2))."\n";
Output:
0.847213084793979
Phix
function agm(atom a, atom g, atom tolerance=1.0e-15) while abs(a-g)>tolerance do {a,g} = {(a + g)/2,sqrt(a*g)} printf(1,"%0.15g\n",a) end while return a end function ?agm(1,1/sqrt(2)) -- (rounds to 10 d.p.)
- Output:
0.853553390593274 0.847224902923494 0.847213084835193 0.847213084793979 0.8472130848
Phixmonti
include ..\Utilitys.pmt
1.0e-15 var tolerance
def test
over over - abs tolerance >
enddef
def agm /# n1 n2 -- n3 #/
test while
over over + 2 / rot rot * sqrt
test endwhile
enddef
1 1 2 sqrt / agm tostr ?
PHP
define('PRECISION', 13);
function agm($a0, $g0, $tolerance = 1e-10)
{
// the bc extension deals in strings and cannot convert
// floats in scientific notation by itself - hence
// this manual conversion to a string
$limit = number_format($tolerance, PRECISION, '.', '');
$an = $a0;
$gn = $g0;
do {
list($an, $gn) = array(
bcdiv(bcadd($an, $gn), 2),
bcsqrt(bcmul($an, $gn)),
);
} while (bccomp(bcsub($an, $gn), $limit) > 0);
return $an;
}
bcscale(PRECISION);
echo agm(1, 1 / bcsqrt(2));
- Output:
0.8472130848350
Picat
main =>
println(agm(1.0, 1/sqrt(2))).
agm(A,G) = A, A-G < 1.0e-10 => true.
agm(A,G) = agm((A+G)/2, sqrt(A*G)).
- Output:
0.847213084835193
PicoLisp
(scl 80)
(de agm (A G)
(do 7
(prog1 (/ (+ A G) 2)
(setq G (sqrt A G) A @) ) ) )
(round
(agm 1.0 (*/ 1.0 1.0 (sqrt 2.0 1.0)))
70 )
Output:
-> "0.8472130847939790866064991234821916364814459103269421850605793726597340"
PL/I
arithmetic_geometric_mean: /* 31 August 2012 */
procedure options (main);
declare (a, g, t) float (18);
a = 1; g = 1/sqrt(2.0q0);
put skip list ('The arithmetic-geometric mean of ' || a || ' and ' || g || ':');
do until (abs(a-g) < 1e-15*a);
t = (a + g)/2; g = sqrt(a*g);
a = t;
put skip data (a, g);
end;
put skip list ('The result is:', a);
end arithmetic_geometric_mean;
Results:
The arithmetic-geometric mean of 1.00000000000000000E+0000 and 7.07106781186547524E-0001: A= 8.53553390593273762E-0001 G= 8.40896415253714543E-0001; A= 8.47224902923494153E-0001 G= 8.47201266746891460E-0001; A= 8.47213084835192807E-0001 G= 8.47213084752765367E-0001; A= 8.47213084793979087E-0001 G= 8.47213084793979087E-0001; The result is: 8.47213084793979087E-0001
Potion
Input values should be floating point
sqrt = (x) :
xi = 1
7 times :
xi = (xi + x / xi) / 2
.
xi
.
agm = (x, y) :
7 times :
a = (x + y) / 2
g = sqrt(x * y)
x = a
y = g
.
x
.
PowerShell
function agm ([Double]$a, [Double]$g) {
[Double]$eps = 1E-15
[Double]$a1 = [Double]$g1 = 0
while([Math]::Abs($a - $g) -gt $eps) {
$a1, $g1 = $a, $g
$a = ($a1 + $g1)/2
$g = [Math]::Sqrt($a1*$g1)
}
[pscustomobject]@{
a = "$a"
g = "$g"
}
}
agm 1 (1/[Math]::Sqrt(2))
Output:
a g - - 0.847213084793979 0.847213084793979
Prolog
agm(A,G,A) :- abs(A-G) < 1.0e-15, !.
agm(A,G,Res) :- A1 is (A+G)/2.0, G1 is sqrt(A*G),!, agm(A1,G1,Res).
?- agm(1,1/sqrt(2),Res).
Res = 0.8472130847939792.
Python
The calculation generates two new values from two existing values which is the classic example for the use of assignment to a list of values in the one statement, so ensuring an gn are only calculated from an-1 gn-1.
Basic Version
from math import sqrt
def agm(a0, g0, tolerance=1e-10):
"""
Calculating the arithmetic-geometric mean of two numbers a0, g0.
tolerance the tolerance for the converged
value of the arithmetic-geometric mean
(default value = 1e-10)
"""
an, gn = (a0 + g0) / 2.0, sqrt(a0 * g0)
while abs(an - gn) > tolerance:
an, gn = (an + gn) / 2.0, sqrt(an * gn)
return an
print agm(1, 1 / sqrt(2))
- Output:
0.847213084835
Multi-Precision Version
from decimal import Decimal, getcontext
def agm(a, g, tolerance=Decimal("1e-65")):
while True:
a, g = (a + g) / 2, (a * g).sqrt()
if abs(a - g) < tolerance:
return a
getcontext().prec = 70
print agm(Decimal(1), 1 / Decimal(2).sqrt())
- Output:
0.847213084793979086606499123482191636481445910326942185060579372659734
All the digits shown are correct.
Quackery
[ $ "bigrat.qky" loadfile ] now!
[ temp put
[ 2over 2over temp share approx=
iff 2drop done
2over 2over v*
temp share vsqrt drop
dip [ dip [ v+ 2 n->v v/ ] ]
again ]
base share temp take ** round ] is agm ( n/d n/d n --> n/d )
1 n->v
2 n->v 125 vsqrt drop 1/v
125 agm
2dup
125 point$ echo$ cr cr
swap say "Num: " echo cr
say "Den: " echo
- Output:
Rational approximation good to 125 decimal places.
0.84721308479397908660649912348219163648144591032694218506057937265973400483413475972320029399461122994212228562523341096309796 Num: 25070388762104643854110087231213532104992429267859552974434367463980830062627660152123462048041692668477424160883635235463565 Den: 29591597689029002472001305353032599592592702596663142670993392754036951453351898973702304260474345315746065192782388085181246
R
arithmeticMean <- function(a, b) { (a + b)/2 }
geometricMean <- function(a, b) { sqrt(a * b) }
arithmeticGeometricMean <- function(a, b) {
rel_error <- abs(a - b) / pmax(a, b)
if (all(rel_error < .Machine$double.eps, na.rm=TRUE)) {
agm <- a
return(data.frame(agm, rel_error));
}
Recall(arithmeticMean(a, b), geometricMean(a, b))
}
agm <- arithmeticGeometricMean(1, 1/sqrt(2))
print(format(agm, digits=16))
- Output:
agm rel_error 1 0.8472130847939792 1.310441309927519e-16
This function also works on vectors a and b (following the spirit of R):
a <- c(1, 1, 1)
b <- c(1/sqrt(2), 1/sqrt(3), 1/2)
agm <- arithmeticGeometricMean(a, b)
print(format(agm, digits=16))
- Output:
agm rel_error 1 0.8472130847939792 1.310441309927519e-16 2 0.7741882646460426 0.000000000000000e+00 3 0.7283955155234534 0.000000000000000e+00
Racket
This version uses Racket's normal numbers:
#lang racket
(define (agm a g [ε 1e-15])
(if (<= (- a g) ε)
a
(agm (/ (+ a g) 2) (sqrt (* a g)) ε)))
(agm 1 (/ 1 (sqrt 2)))
Output:
0.8472130847939792
This alternative version uses arbitrary precision floats:
#lang racket
(require math/bigfloat)
(bf-precision 200)
(bfagm 1.bf (bf/ (bfsqrt 2.bf)))
Output:
(bf #e0.84721308479397908660649912348219163648144591032694218506057918)
Raku
(formerly Perl 6)
sub agm( $a is copy, $g is copy ) {
($a, $g) = ($a + $g)/2, sqrt $a * $g until $a ≅ $g;
return $a;
}
say agm 1, 1/sqrt 2;
- Output:
0.84721308479397917
It's also possible to write it recursively:
sub agm( $a, $g ) {
$a ≅ $g ?? $a !! agm(|@$_)
given ($a + $g)/2, sqrt $a * $g;
}
say agm 1, 1/sqrt 2;
We can also get a bit fancy and use a converging sequence of complex numbers:
sub agm {
($^z, {(.re+.im)/2 + (.re*.im).sqrt*1i} ... * ≅ *)
.tail.re
}
say agm 1 + 1i/2.sqrt
Raven
define agm use $a, $g, $errlim
# $errlim $g $a "%d %g %d\n" print
$a 1.0 + as $t
repeat $a 1.0 * $g - abs -15 exp10 $a * > while
$a $g + 2 / as $t
$a $g * sqrt as $g
$t as $a
$g $a $t "t: %g a: %g g: %g\n" print
$a
16 1 2 sqrt / 1 agm "agm: %.15g\n" print
- Output:
t: 0.853553 a: 0.853553 g: 0.840896 t: 0.847225 a: 0.847225 g: 0.847201 t: 0.847213 a: 0.847213 g: 0.847213 t: 0.847213 a: 0.847213 g: 0.847213 agm: 0.847213084793979
Relation
function agm(x,y)
set a = x
set g = y
while abs(a - g) > 0.00000000001
set an = (a + g)/2
set gn = sqrt(a * g)
set a = an
set g = gn
set i = i + 1
end while
set result = g
end function
set x = 1
set y = 1/sqrt(2)
echo (x + y)/2
echo sqrt(x+y)
echo agm(x,y)
0.853553391 0.840896415 0.847213085
REXX
Also, this version of the AGM REXX program has three short circuits within it for an equality case and for two zero cases.
REXX supports arbitrary precision, so the default digits can be changed if desired.
/*REXX program calculates the AGM (arithmetic─geometric mean) of two (real) numbers. */
parse arg a b digs . /*obtain optional numbers from the C.L.*/
if digs=='' | digs=="," then digs= 120 /*No DIGS specified? Then use default.*/
numeric digits digs /*REXX will use lots of decimal digits.*/
if a=='' | a=="," then a= 1 /*No A specified? Then use the default*/
if b=='' | b=="," then b= 1 / sqrt(2) /* " B " " " " " */
call AGM a,b /*invoke the AGM function. */
say '1st # =' a /*display the A value. */
say '2nd # =' b /* " " B " */
say ' AGM =' agm(a, b) /* " " AGM " */
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
agm: procedure: parse arg x,y; if x=y then return x /*is this an equality case?*/
if y=0 then return 0 /*is Y equal to zero ? */
if x=0 then return y/2 /* " X " " " */
d= digits() /*obtain the current decimal digits. */
numeric digits d + 5 /*add 5 more digs to ensure convergence*/
tiny= '1e-' || (digits() - 1) /*construct a pretty tiny REXX number. */
ox= x + 1 /*ensure that the old X ¬= new X. */
do while ox\=x & abs(ox)>tiny /*compute until the old X ≡ new X. */
ox= x; oy= y /*save the old value of X and Y. */
x= (ox + oy) * .5 /*compute " new " " X. */
y= sqrt(ox * oy) /* " " " " " Y. */
end /*while*/
numeric digits d /*restore the original decimal digits. */
return x / 1 /*normalize X to new " " */
/*──────────────────────────────────────────────────────────────────────────────────────*/
sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); m.=9; numeric form; h=d+6
numeric digits; parse value format(x,2,1,,0) 'E0' with g 'E' _ .; g=g *.5'e'_ % 2
do j=0 while h>9; m.j=h; h=h % 2 + 1; end /*j*/
do k=j+5 to 0 by -1; numeric digits m.k; g=(g+x/g)*.5; end /*k*/; return g
- output when using the default input:
1st # = 1 2nd # = 0.707106781186547524400844362104849039284835937688474036588339868995366239231053519425193767163820786367506923115456148513 AGM = 0.847213084793979086606499123482191636481445910326942185060579372659734004834134759723200293994611229942122285625233410963
Ring
decimals(9)
see agm(1, 1/sqrt(2)) + nl
see agm(1,1/pow(2,0.5)) + nl
func agm agm,g
while agm
an = (agm + g)/2
gn = sqrt(agm*g)
if fabs(agm-g) <= fabs(an-gn) exit ok
agm = an
g = gn
end
return gn
RPL
≪ 1E-10 → epsilon ≪ WHILE DUP2 - ABS epsilon > REPEAT DUP2 + 2 / ROT ROT * √ END DROP ≫ ≫ ‘AGM’ STO
- Input:
1 2 / √ AGM
- Output:
1: .847213084835
Ruby
Flt Version
The thing to note about this implementation is that it uses the Flt library for high-precision math. This lets you adapt context (including precision and epsilon) to a ridiculous-in-real-life degree.
# The flt package (http://flt.rubyforge.org/) is useful for high-precision floating-point math.
# It lets us control 'context' of numbers, individually or collectively -- including precision
# (which adjusts the context's value of epsilon accordingly).
require 'flt'
include Flt
BinNum.Context.precision = 512 # default 53 (bits)
def agm(a,g)
new_a = BinNum a
new_g = BinNum g
while new_a - new_g > new_a.class.Context.epsilon do
old_g = new_g
new_g = (new_a * new_g).sqrt
new_a = (old_g + new_a) * 0.5
end
new_g
end
puts agm(1, 1 / BinNum(2).sqrt)
- Output:
0.84721308479397908660649912348219163648144591032694218506057937265973400483413475972320029399461122994212228562523341096309796266583087105969971363598338426
Adjusting the precision setting (at about line 9) will of course affect this. :-)
BigDecimal Version
Ruby has a BigDecimal class in standard library
require 'bigdecimal'
PRECISION = 100
EPSILON = 0.1 ** (PRECISION/2)
BigDecimal::limit(PRECISION)
def agm(a,g)
while a - g > EPSILON
a, g = (a+g)/2, (a*g).sqrt(PRECISION)
end
[a, g]
end
a = BigDecimal(1)
g = 1 / BigDecimal(2).sqrt(PRECISION)
puts agm(a, g)
- Output:
0.847213084793979086606499123482191636481445910326942185060579372659734004834134759723201915677745718E0 0.8472130847939790866064991234821916364814459103269421850605793726597340048341347597231986723114767413E0
Rust
// Accepts two command line arguments
// cargo run --name agm arg1 arg2
fn main () {
let mut args = std::env::args();
let x = args.nth(1).expect("First argument not specified.").parse::<f32>().unwrap();
let y = args.next().expect("Second argument not specified.").parse::<f32>().unwrap();
let result = agm(x,y);
println!("The arithmetic-geometric mean is {}", result);
}
fn agm (x: f32, y: f32) -> f32 {
let e: f32 = 0.000001;
let mut a = x;
let mut g = y;
let mut a1: f32;
let mut g1: f32;
if a * g < 0f32 { panic!("The arithmetric-geometric mean is undefined for numbers less than zero!"); }
else {
loop {
a1 = (a + g) / 2.;
g1 = (a * g).sqrt();
a = a1;
g = g1;
if (a - g).abs() < e { return a; }
}
}
}
- Output:
Output of running with arguments 1, 0.70710678:
The arithmetic-geometric mean is 1.456791
Scala
def agm(a: Double, g: Double, eps: Double): Double = {
if (math.abs(a - g) < eps) (a + g) / 2
else agm((a + g) / 2, math.sqrt(a * g), eps)
}
agm(1, math.sqrt(2)/2, 1e-15)
Scheme
(define agm
(case-lambda
((a0 g0) ; call again with default value for tolerance
(agm a0 g0 1e-8))
((a0 g0 tolerance) ; called with three arguments
(do ((a a0 (* (+ a g) 1/2))
(g g0 (sqrt (* a g))))
((< (abs (- a g)) tolerance) a)))))
(display (agm 1 (/ 1 (sqrt 2)))) (newline)
- Output:
0.8472130848351929
Seed7
$ 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;
- Output:
1.456791 0.847213
SequenceL
import <Utilities/Math.sl>;
agm(a, g) :=
let
iota := 1.0e-15;
arithmeticMean := 0.5 * (a + g);
geometricMean := sqrt(a * g);
in
a when abs(a-g) < iota
else
agm(arithmeticMean, geometricMean);
main := agm(1.0, 1.0 / sqrt(2));
- Output:
0.847213
Sidef
func agm(a, g) {
loop {
var (a1, g1) = ((a+g)/2, sqrt(a*g))
[a1,g1] == [a,g] && return a
(a, g) = (a1, g1)
}
}
say agm(1, 1/sqrt(2))
- Output:
0.8472130847939790866064991234821916364814
Smalltalk
That is simply a copy/paste of the already existing agm method in the Number class:
agm:y
"return the arithmetic-geometric mean agm(x, y)
of the receiver (x) and the argument, y.
See https://en.wikipedia.org/wiki/Arithmetic-geometric_mean"
|ai an gi gn epsilon delta|
ai := (self + y) / 2.
gi := (self * y) sqrt.
epsilon := self ulp.
[
an := (ai + gi) / 2.
gn := (ai * gi) sqrt.
delta := (an - ai) abs.
ai := an.
gi := gn.
] doUntil:[ delta < epsilon ].
^ ai
Transcript showCR: (24 agm:6).
Transcript showCR: ( (1/2) agm:(1/6) ).
Transcript showCR: (1 agm:(1 / 2 sqrt)).
- Output:
13.4581714817256 0.310602797207483 0.847213084793979
SQL
The solution uses recursive WITH clause (aka recursive CTE, recursive query, recursive factored subquery). Some, perhaps many, but not all SQL dialects support recursive WITH clause. The solution below was written and tested in Oracle SQL - Oracle has supported recursive WITH clause since version 11.2.
with
rec (rn, a, g, diff) as (
select 1, 1, 1/sqrt(2), 1 - 1/sqrt(2)
from dual
union all
select rn + 1, (a + g)/2, sqrt(a * g), (a + g)/2 - sqrt(a * g)
from rec
where diff > 1e-38
)
select *
from rec
where diff <= 1e-38
;
- Output:
RN A G DIFF -- ----------------------------------------- ------------------------------------------ ------------------------------------------ 6 0.847213084793979086606499123482191636480 0.8472130847939790866064991234821916364792 0.0000000000000000000000000000000000000008
Standard ML
fun agm(a, g) = let
fun agm'(a, g, eps) =
if Real.abs(a-g) < eps then
a
else
agm'((a+g)/2.0, Math.sqrt(a*g), eps)
in agm'(a, g, 1e~15)
end;
- Output:
agm(1.0, 1.0/Math.sqrt(2.0)) => 0.847213084794
Stata
mata
real scalar agm(real scalar a, real scalar b) {
real scalar c
do {
c=0.5*(a+b)
b=sqrt(a*b)
a=c
} while (a-b>1e-15*a)
return(0.5*(a+b))
}
agm(1,1/sqrt(2))
end
- Output:
.8472130848
Swift
import Darwin
enum AGRError : Error {
case undefined
}
func agm(_ a: Double, _ g: Double, _ iota: Double = 1e-8) throws -> Double {
var a = a
var g = g
var a1: Double = 0
var g1: Double = 0
guard a * g >= 0 else {
throw AGRError.undefined
}
while abs(a - g) > iota {
a1 = (a + g) / 2
g1 = sqrt(a * g)
a = a1
g = g1
}
return a
}
do {
try print(agm(1, 1 / sqrt(2)))
} catch {
print("agr is undefined when a * g < 0")
}
- Output:
0.847213084835193
Tcl
The tricky thing about this implementation is that despite the finite precision available to IEEE doubles (which Tcl uses in its implementation of floating point arithmetic, in common with many other languages) the sequence of values does not quite converge to a single value; it gets to within a ULP and then errors prevent it from getting closer. This means that an additional termination condition is required: once a value does not change (hence the old_b
variable) we have got as close as we can. Note also that we are using exact equality with floating point; this is reasonable because this is a rapidly converging sequence (it only takes 4 iterations in this case).
proc agm {a b} {
set old_b [expr {$b<0?inf:-inf}]
while {$a != $b && $b != $old_b} {
set old_b $b
lassign [list [expr {0.5*($a+$b)}] [expr {sqrt($a*$b)}]] a b
}
return $a
}
puts [agm 1 [expr 1/sqrt(2)]]
Output:
0.8472130847939792
TI SR-56
Display | Key | Display | Key | Display | Key | Display | Key |
---|---|---|---|---|---|---|---|
00 33 | STO | 25 03 | 3 | 50 | 75 | ||
01 02 | 2 | 26 12 | INV | 51 | 76 | ||
02 32 | x<>t | 27 44 | EE | 52 | 77 | ||
03 64 | × | 28 41 | R/S | 53 | 78 | ||
04 32 | x<>t | 29 | 54 | 79 | |||
05 94 | = | 30 | 55 | 80 | |||
06 48 | *√x | 31 | 56 | 81 | |||
07 32 | x<>t | 32 | 57 | 82 | |||
08 84 | + | 33 | 58 | 83 | |||
09 34 | RCL | 34 | 59 | 84 | |||
10 02 | 2 | 35 | 60 | 85 | |||
11 94 | = | 36 | 61 | 86 | |||
12 54 | ÷ | 37 | 62 | 87 | |||
13 02 | 2 | 38 | 63 | 88 | |||
14 94 | = | 39 | 64 | 89 | |||
15 33 | STO | 40 | 65 | 90 | |||
16 02 | 2 | 41 | 66 | 91 | |||
17 44 | EE | 42 | 67 | 92 | |||
18 94 | = | 43 | 68 | 93 | |||
19 32 | x<>t | 44 | 69 | 94 | |||
20 44 | EE | 45 | 70 | 95 | |||
21 94 | = | 46 | 71 | 96 | |||
22 12 | INV | 47 | 72 | 97 | |||
23 37 | *x=t | 48 | 73 | 98 | |||
24 00 | 0 | 49 | 74 | 99 |
Asterisk denotes 2nd function key.
0: Unused | 1: Unused | 2: Previous Term | 3: Unused | 4: Unused |
5: Unused | 6: Unused | 7: Unused | 8: Unused | 9: Unused |
Annotated listing:
STO 2 x<>t // x := term a, t := R2 := term g
× x<>t = √x // Calculate term g'
x<>t + RCL 2 = / 2 = STO 2 // Calculate term a'
EE = x<>t EE = // Round terms to ten digits
INV x=t 0 3 // Loop if unequal
INV EE // Exit scientific notation
R/S // End
Usage:
Enter term a, press x<>t, then enter term g. Finally, press RST R/S to run the program.
- Input:
1 x<>t 2 √x 1/x RST R/S
- Output:
.8472130848
UNIX Shell
ksh is one of the few unix shells that can do floating point arithmetic (bash does not).
function agm {
float a=$1 g=$2 eps=${3:-1e-11} tmp
while (( abs(a-g) > eps )); do
print "debug: a=$a\tg=$g"
tmp=$(( (a+g)/2.0 ))
g=$(( sqrt(a*g) ))
a=$tmp
done
echo $a
}
agm $((1/sqrt(2))) 1
- Output:
debug: a=0.7071067812 g=1 debug: a=0.8535533906 g=0.8408964153 debug: a=0.8472249029 g=0.8472012668 debug: a=0.8472130848 g=0.8472130847 debug: a=0.8472130848 g=0.8472130848 debug: a=0.8472130848 g=0.8472130848 0.8472130848
You can get a more approximate convergence by changing the while condition to compare the numbers as strings: change
while (( abs(a-g) > eps ))
to
while [[ $a != $g ]]
V (Vlang)
import math
const ep = 1e-14
fn agm(aa f64, gg f64) f64 {
mut a, mut g := aa, gg
for math.abs(a-g) > math.abs(a)*ep {
t := a
a, g = (a+g)*.5, math.sqrt(t*g)
}
return a
}
fn main() {
println(agm(1.0, 1.0/math.sqrt2))
}
Using standard math module
import math.stats
import math
fn main() {
println(stats.geometric_mean<f64>([1.0, 1.0/math.sqrt2]))
}
- Output:
0.8408964152537145
Wren
var eps = 1e-14
var agm = Fn.new { |a, g|
while ((a-g).abs > a.abs * eps) {
var t = a
a = (a+g)/2
g = (t*g).sqrt
}
return a
}
System.print(agm.call(1, 1/2.sqrt))
- Output:
0.84721308479398
XPL0
include c:\cxpl\codesi;
real A, A1, G;
[Format(0, 16);
A:= 1.0; G:= 1.0/sqrt(2.0);
repeat A1:= (A+G)/2.0;
G:= sqrt(A*G);
A:= A1;
RlOut(0, A); RlOut(0, G); RlOut(0, A-G); CrLf(0);
until A=G;
]
Output:
8.5355339059327400E-001 8.4089641525371500E-001 1.2656975339559100E-002 8.4722490292349400E-001 8.4720126674689100E-001 2.3636176602726000E-005 8.4721308483519300E-001 8.4721308475276500E-001 8.2427509262572600E-011 8.4721308479397900E-001 8.4721308479397900E-001 0.0000000000000000E+000
zkl
a:=1.0; g:=1.0/(2.0).sqrt();
while(not a.closeTo(g,1.0e-15)){
a1:=(a+g)/2.0; g=(a*g).sqrt(); a=a1;
println(a," ",g," ",a-g);
}
- Output:
0.853553 0.840896 0.012657 0.847225 0.847201 2.36362e-05 0.847213 0.847213 8.24275e-11 0.847213 0.847213 1.11022e-16
Or, using tail recursion
fcn(a=1.0, g=1.0/(2.0).sqrt()){ println(a," ",g," ",a-g);
if(a.closeTo(g,1.0e-15)) return(a) else return(self.fcn((a+g)/2.0, (a*g).sqrt()));
}()
- Output:
1 0.707107 0.292893 0.853553 0.840896 0.012657 0.847225 0.847201 2.36362e-05 0.847213 0.847213 8.24275e-11 0.847213 0.847213 1.11022e-16
- Programming Tasks
- Solutions by Programming Task
- WikipediaSourced
- 11l
- 360 Assembly
- 8th
- Action!
- Action! Tool Kit
- Action! Real Math
- Ada
- ALGOL 68
- APL
- AppleScript
- Arturo
- AWK
- BASIC
- ANSI BASIC
- Applesoft BASIC
- BASIC256
- BBC BASIC
- Chipmunk Basic
- Commodore BASIC
- Craft Basic
- FreeBASIC
- Gambas
- GW-BASIC
- IS-BASIC
- Liberty BASIC
- Minimal BASIC
- MSX Basic
- PureBasic
- QuickBASIC
- Quite BASIC
- Run BASIC
- Sinclair ZX81 BASIC
- TI-83 BASIC
- True BASIC
- VBA
- VBScript
- Yabasic
- Visual Basic .NET
- System.Numerics
- ZX Spectrum Basic
- Bc
- BQN
- C
- C sharp
- C++
- Clojure
- COBOL
- Common Lisp
- D
- Delphi
- System.SysUtils
- Dc
- EasyLang
- EchoLisp
- Elixir
- Erlang
- ERRE
- F Sharp
- Factor
- Forth
- Fortran
- Futhark
- Futhark examples needing attention
- Examples needing attention
- Go
- Groovy
- Haskell
- Icon
- Unicon
- J
- Java
- JavaScript
- Jq
- Julia
- Klingphix
- Kotlin
- Lambdatalk
- LFE
- LiveCode
- LLVM
- Logo
- Lua
- M2000 Interpreter
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- Octave
- Maxima
- МК-61/52
- Modula-2
- NetRexx
- NewLISP
- Nim
- Oberon-2
- Objeck
- OCaml
- Oforth
- OOC
- OoRexx
- PARI/GP
- Pascal
- GMP
- Perl
- Phix
- Phixmonti
- PHP
- Picat
- PicoLisp
- PL/I
- Potion
- PowerShell
- Prolog
- Python
- Quackery
- R
- Racket
- Raku
- Raven
- Relation
- REXX
- Ring
- RPL
- Ruby
- Rust
- Scala
- Scheme
- Seed7
- SequenceL
- Sidef
- Smalltalk
- SQL
- Standard ML
- Stata
- Swift
- Tcl
- TI SR-56
- UNIX Shell
- V (Vlang)
- Wren
- XPL0
- Zkl
- Pages with too many expensive parser function calls