Continued fraction: Difference between revisions
m
→{{header|Fōrmulæ}}
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
|||
(24 intermediate revisions by 12 users not shown) | |||
Line 1,119:
2.7182818284590452354
3.1415926228048469486</pre>
=={{header|dc}}==
<syntaxhighlight lang="dc">[20k 0 200 si [li lbx r li lax + / li 1 - dsi 0<:]ds:x 0 lax +]sf
[[2q]s2[0<2 1]sa[R1]sb]sr # sqrt(2)
[[R2q]s2[d 0=2]sa[R1q]s1[d 1=1 1-]sb]se # e
[[3q]s3[0=3 6]sa[2*1-d*]sb]sp # pi
c lex lfx p
lrx lfx p
lpx lfx p</syntaxhighlight>
{{out}}
<pre>3.14159262280484694855
1.41421356237309504880
2.71828182845904523536</pre>
20 decimal places and 200 iterations.
=={{header|EasyLang}}==
<syntaxhighlight lang="easylang">
numfmt 8 0
func calc_sqrt .
n = 100
sum = n
while n >= 1
a = 1
if n > 1
a = 2
.
b = 1
sum = a + b / sum
n -= 1
.
return sum
.
func calc_e .
n = 100
sum = n
while n >= 1
a = 2
if n > 1
a = n - 1
.
b = 1
if n > 1
b = n - 1
.
sum = a + b / sum
n -= 1
.
return sum
.
func calc_pi .
n = 100
sum = n
while n >= 1
a = 3
if n > 1
a = 6
.
b = 2 * n - 1
b *= b
sum = a + b / sum
n -= 1
.
return sum
.
print calc_sqrt
print calc_e
print calc_pi
</syntaxhighlight>
=={{header|Elixir}}==
<syntaxhighlight lang="elixir">
defmodule CFrac do
def compute([a | _], []), do: a
def compute([a | as], [b | bs]), do: a + b/compute(as, bs)
def sqrt2 do
a = [1 | Stream.cycle([2]) |> Enum.take(1000)]
b = Stream.cycle([1]) |> Enum.take(1000)
IO.puts compute(a, b)
end
def exp1 do
a = [2 | Stream.iterate(1, &(&1 + 1)) |> Enum.take(1000)]
b = [1 | Stream.iterate(1, &(&1 + 1)) |> Enum.take(999)]
IO.puts compute(a, b)
end
def pi do
a = [3 | Stream.cycle([6]) |> Enum.take(1000)]
b = 1..1000 |> Enum.map(fn k -> (2*k - 1)**2 end)
IO.puts compute(a, b)
end
end
</syntaxhighlight>
{{out}}
<pre>
>elixir -e CFrac.sqrt2()
1.4142135623730951
>elixir -e CFrac.exp1()
2.7182818284590455
>elixir -e CFrac.pi()
3.141592653340542
</pre>
=={{header|Erlang}}==
Line 1,293 ⟶ 1,403:
2.71828165766640 < e < 2.71828184277783
2.71828182735187 < e < 2.71828184277783
</pre>
===Apéry's constant===
See [https://tpiezas.wordpress.com/2012/05/04/continued-fractions-for-zeta2-and-zeta3/ Continued fractions for Zeta(2) and Zeta(3)] section II. Zeta(3)
<syntaxhighlight lang="fsharp">
let aπ()=let mutable n=0 in (fun ()->n<-n+1;-decimal(pown n 6))
let bπ()=let mutable n=0M in (fun ()->n<-n+1M; (2M*n-1M)*(17M*n*n-17M*n+5M))
cf2S (aπ()) (bπ()) |>Seq.map(fun n->6M/n) |> Seq.take 10 |> Seq.pairwise |> Seq.iter(fun(n,g)->printfn "%1.20f < p < %- 1.20f" (min n g) (max n g));;
</syntaxhighlight>
{{out}}
<pre>
1.20205479452054794521 < p < 1.20205690119184928874
1.20205690119184928874 < p < 1.20205690315781676650
1.20205690315781676650 < p < 1.20205690315959270361
1.20205690315959270361 < p < 1.20205690315959428400
1.20205690315959428400 < p < 1.20205690315959428540
1.20205690315959428540 < p < 1.20205690315959428540
1.20205690315959428540 < p < 1.20205690315959428540
1.20205690315959428540 < p < 1.20205690315959428540
1.20205690315959428540 < p < 1.20205690315959428540
</pre>
Line 1,564 ⟶ 1,693:
=={{header|Fōrmulæ}}==
{{FormulaeEntry|page=https://formulae.org/?script=examples/Continued_fraction}}
'''Solution'''
The following function definition creates a continued fraction:
[[File:Fōrmulæ - Continued fraction 01.png]]
The function accepts the following parameters:
{| class="wikitable" style="margin:auto"
|-
! Parameter !! Description
|-
| a₀ || Value for a₀
|-
| λa || Lambda expression to define aᵢ
|-
| λb || Lambda expression to define bᵢ
|-
| depth || Depth to calculate the continued fraction
|}
Since Fōrmulæ arithmetic simplifies numeric results as they are generated, the result is not a continued fraction by default.
If we want to create the structure, we can introduce the parameters as string or text expressions (or lambda expressions that produce them). Because string or text expressions are not reduced when they are operands of additions and divisions, the structure is preserved, such as follows:
[[File:Fōrmulæ - Continued fraction 02.png]]
[[File:Fōrmulæ - Continued fraction 03.png]]
'''Case 1.''' <math>\sqrt 2</math>
In this case
* a₀ is 1
* λa is n ↦ 2
* λb is n ↦ 1
Let us show the results as a table, for several levels of depth (1 to 10).
The columns are:
* The depth
* The "textual" call, in order to generate the structure
* The normal (numeric) call. Since arithmetic operations are exact by default, it is usually a rational number.
* The value of the normal (numeric) call, forced to be shown as a decimal number, by using the Math.Numeric expression (the N(x) expression)
[[File:Fōrmulæ - Continued fraction 04.png]]
[[File:Fōrmulæ - Continued fraction 05.png]]
'''Case 2.''' <math>e</math>
In this case
* a₀ is 2
* λa is n ↦ n
* λb is n ↦ 1 if n = 1, n - 1 elsewhere
[[File:Fōrmulæ - Continued fraction 06.png]]
[[File:Fōrmulæ - Continued fraction 07.png]]
'''Case 3.''' <math>\pi</math>
In this case
* a₀ is 3
* λa is n ↦ 6
* λb is n ↦ 2(n - 1)²
[[File:Fōrmulæ - Continued fraction 08.png]]
[[File:Fōrmulæ - Continued fraction 09.png]]
=={{header|Go}}==
Line 1,739 ⟶ 1,938:
main :: IO ()
main = mapM_ putStrLn [cf2dec 200 sqrt2, cf2dec 200 napier, cf2dec 200 pie]</syntaxhighlight>
=={{header|Icon}}==
<syntaxhighlight lang="icon">
$define EVAL_DEPTH 100
# A generalized continued fraction, represented by two functions. Each
# function maps from an index to a floating-point value.
record continued_fraction (a, b)
procedure main ()
writes (" sqrt 2.0 = ")
write (evaluate_continued_fraction (continued_fraction (sqrt2_a, sqrt2_b),
EVAL_DEPTH))
writes (" e = ")
write (evaluate_continued_fraction (continued_fraction (e_a, e_b),
EVAL_DEPTH))
writes (" pi = ")
write (evaluate_continued_fraction (continued_fraction (pi_a, pi_b),
EVAL_DEPTH))
end
procedure evaluate_continued_fraction (frac, depth)
local i, retval
retval := frac.a (depth)
every i := depth to 1 by -1 do {
retval := frac.a (i - 1) + (frac.b (i) / retval)
}
return retval
end
procedure sqrt2_a (i)
return (if i = 0 then 1.0 else 2.0)
end
procedure sqrt2_b (i)
return 1.0
end
procedure e_a (i)
return (if i = 0 then 2.0 else real (i))
end
procedure e_b (i)
return (if i = 1 then 1.0 else real (i - 1))
end
procedure pi_a (i)
return (if i = 0 then 3.0 else 6.0)
end
procedure pi_b (i)
return real (((2 * i) - 1)^2)
end
</syntaxhighlight>
{{out}}
<pre>$ icon continued-fraction-task.icn
sqrt 2.0 = 1.414213562
e = 2.718281828
pi = 3.141592411
</pre>
=={{header|J}}==
Line 1,809 ⟶ 2,069:
which may be 0, as previously noted.
<syntaxhighlight lang="jq">
# "first" is the first triple, e.g. [1,a,b];
#
def continued_fraction( first; next; count ):
# input: [i, a, b
def cf:
if .[0] == count then 0
Line 1,851 ⟶ 2,111:
=={{header|Julia}}==
{{works with|Julia|
High performant lazy evaluation on demand with Julias iterators.
<syntaxhighlight lang="julia">
using .Iterators: countfrom, flatten, repeated, zip
using .MathConstants: ℯ
using Printf
function
m = BigInt[a₀ 1; 1 0]
for (aᵢ, bᵢ) ∈ zip(a, b)
m *= [aᵢ 1; bᵢ 0]
end
m[1]/m[2]
end
out((k, v)) = @printf "%2s: %.12f ≈ %.12f\n" k v eval(k)
foreach(out, (
:(√2) => cf(1, repeated(2)),
:ℯ => cf(2, countfrom(), flatten((1, countfrom()))),
:π => cf(3, repeated(6), (k^2 for k ∈ countfrom(1, 2)))))
</syntaxhighlight>
{{out}}
<pre>
ℯ: 2.718281828459 ≈ 2.718281828459
=={{header|Klong}}==
Line 2,246 ⟶ 2,491:
Output:
<pre>%1 = 1.4142135623730950488016887242096980786</pre>
=={{header|Pascal}}==
This console application is written in Delphi, which allows the results to be displayed to 17 correct decimal places (Free Pascal seems to allow only 16). As in the jq solution, we aim to work forwards and stop as soon the desired precision has been reached, rather than guess a suitable number of terms and work backwards. In this program, the continued fraction is converted to an infinite sum, each term after the first being the difference between consecutive convergents. The convergence for pi is very slow (as others have noted) so as well as the c.f. in the task description an alternative is given from the Wikipedia article "Continued fraction".
<syntaxhighlight lang="pascal">
program ContFrac_console;
{$APPTYPE CONSOLE}
uses
SysUtils;
type TCoeffFunction = function( n : integer) : extended;
// Calculate continued fraction as a sum, working forwards.
// Stop on reaching a term with absolute value less than epsilon,
// or on reaching the maximum number of terms.
procedure CalcContFrac( a, b : TCoeffFunction;
epsilon : extended;
maxNrTerms : integer = 1000); // optional, with default
var
n : integer;
sum, term, u, v : extended;
whyStopped : string;
begin
sum := a(0);
term := b(1)/a(1);
v := a(1);
n := 1;
repeat
sum := sum + term;
inc(n);
u := v;
v := a(n) + b(n)/u;
term := -term * b(n)/(u*v);
until (Abs(term) < epsilon) or (n >= maxNrTerms);
if n >= maxNrTerms then whyStopped := 'too many terms'
else whyStopped := 'converged';
WriteLn( SysUtils.Format( '%21.17f after %d terms (%s)',
[sum, n, whyStopped]));
end;
//---------------- a and b for sqrt(2) ----------------
function a_sqrt2( n : integer) : extended;
begin
if n = 0 then result := 1
else result := 2;
end;
function b_sqrt2( n : integer) : extended;
begin
result := 1;
end;
//---------------- a snd b for e ----------------
function a_e( n : integer) : extended;
begin
if n = 0 then result := 2
else result := n;
end;
function b_e( n : integer) : extended;
begin
if n = 1 then result := 1
else result := n - 1;
end;
//-------- Rosetta Code a and b for pi --------
function a_pi( n : integer) : extended;
begin
if n = 0 then result := 3
else result := 6;
end;
function b_pi( n : integer) : extended;
var
temp : extended;
begin
temp := 2*n - 1;
result := temp*temp;
end;
//-------- More efficient a and b for pi --------
function a_pi_alt( n : integer) : extended;
begin
if n = 0 then result := 0
else result := 2*n - 1;
end;
function b_pi_alt( n : integer) : extended;
var
temp : extended;
begin
if n = 1 then
result := 4
else begin
temp := n - 1;
result := temp*temp;
end;
end;
//---------------- Main routine ----------------
// Unlike Free Pascal, Delphi does not require
// an @ sign before the function names.
begin
WriteLn( 'sqrt(2)');
CalcContFrac( a_sqrt2, b_sqrt2, 1E-20);
WriteLn( 'e');
CalcContFrac( a_e, b_e, 1E-20);
WriteLn( 'pi');
CalcContFrac( a_pi, b_pi, 1E-20);
WriteLn( 'pi (alternative formula)');
CalcContFrac( a_pi_alt, b_pi_alt, 1E-20);
end.
</syntaxhighlight>
{{out}}
<pre>
sqrt(2)
1.41421356237309505 after 27 terms (converged)
e
2.71828182845904524 after 20 terms (converged)
pi
3.14159265383979293 after 1000 terms (too many terms)
pi (alternative formula)
3.14159265358979324 after 29 terms (converged)
</pre>
=={{header|Perl}}==
Line 3,046 ⟶ 3,412:
e = 2.718281828459046
PI = 3.141592653588017
</pre>
=={{header|RPL}}==
This task demonstrates how both global and local variables, arithmetic expressions and stack can be used together to build a compact and versatile piece of code.
{{works with|Halcyon Calc|4.2.7}}
{| class="wikitable"
! RPL code
! Comment
|-
|
≪
4 ROLL ROT → an bn
≪ 'N' STO 0 '''WHILE''' N 2 ≥ '''REPEAT'''
an + INV bn * EVAL
'N' 1 STO- '''END'''
an + / + EVAL
'N' PURGE
≫ ≫ ‘'''→CFRAC'''’ STO
|
'''→CFRAC''' ''( a0 an b1 bn N -- x ) ''
Unstack an and bn
Loop from N to 2
Calculate Nth fraction
Decrement counter
Calculate last fraction with b1 in stack, then add a0
Discard N variable - not mandatory but hygienic
|}
{{in}}
<pre>
1 2 1 1 100 →CFRAC
2 'N' 1 'N-1' 100 →CFRAC
3 6 1 '(2*N-1)^2' 1000 →CFRAC
1 1 1 1 100 →CFRAC
1 '2-MOD(N,2)' 1 1 100 →CFRAC
</pre>
{{out}}
<pre>
5: 1.41421356237
4: 2.71828182846
3: 3.14159265334
2: 1.61803398875
1: 1.73205080757
</pre>
Line 3,465 ⟶ 3,874:
e ≈ 2.7182818284590455
π ≈ 3.141592653339042</pre>
{{trans|Java}}
<syntaxhighlight lang="swift">
import Foundation
func calculate(n: Int, operation: (Int) -> [Int])-> Double {
var tmp: Double = 0
for ni in stride(from: n, to:0, by: -1) {
var p = operation(ni)
tmp = Double(p[1])/(Double(p[0]) + tmp);
}
return Double(operation(0)[0]) + tmp;
}
func sqrt (n: Int) -> [Int] {
return [n > 0 ? 2 : 1, 1]
}
func napier (n: Int) -> [Int] {
var res = [n > 0 ? n : 2, n > 1 ? (n - 1) : 1]
return res
}
func pi(n: Int) -> [Int] {
var res = [n > 0 ? 6 : 3, Int(pow(Double(2 * n - 1), 2))]
return res
}
print (calculate(n: 200, operation: sqrt));
print (calculate(n: 200, operation: napier));
print (calculate(n: 200, operation: pi));
</syntaxhighlight>
=={{header|Tcl}}==
Line 3,594 ⟶ 4,036:
=={{header|Wren}}==
{{trans|D}}
<syntaxhighlight lang="
var t = 0
for (i in n..1) {
|