3. Algorithmic Implementation
In our recent publication, we showed that [
15]
Consequently, in accordance with Equation (
4), we obtain the following approximation:
At sufficiently large
k, the value
. Therefore, according to Lemma 5, in this equation, we can replace the first arctangent term by a rational number
. This gives
Unfortunately, we cannot compute efficiently the tangent function in this approximation since its argument
is not a small number as it tends to
with increasing
k. However, again by taking into consideration that
from which it follows that
we can write
Now we can take advantage of the fact that the multiplier
is continuously divisible by 2. Therefore, we can use the trigonometric identity
times over and over again. Thus, this leads to the following iterative formula:
with an initial value
such that
Since the left side of the equation above provides an exact value without (tangent and arctangent) trigonometric functions, we can regard this equation
as a rational approximation. This rational approximation of the two-term Machin-like formula for
can be used in an algorithm providing a quadratic convergence. This can be achieved with help of Theorem 3.
Theorem 3. There is a conversion formulasuch that Proof. The proof is related to the parity of the integer
. According to Lemma 5, we can write
or
Consequently, if the integer
is even, then
However, if the integer
is odd, then
This means that
contributes a binary digit
to the previous value
if and only if
is odd. This completes the proof. □
Consider an example. There are four consecutive values
,
and
and
. Since the first three values are even, we have
However, since
is odd, we obtain
Consider how the number of digits of
can be doubled without computing square roots for the nested radicals
. We can take, for example,
. This yields
However, it is not reasonable to compute the square roots of 2 so many times to obtain this number. Instead, we can simplify computation considerably by using the value
in the binary form according to Theorem 3. Thus, ignoring the first two initial zeros in the binary output of Equation (
33), we have a corresponding sequence
This sequence can be obtained by using the built-in Mathematica directly using . For example, the following code:
RealDigits[
ImportString[ToString[BaseForm[N[1/\[Pi],20],2]],
"Table"][[1]][[1]]][[1]][[1;;20]]
returns the first 20 digits from the sequence (
36):
{1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0}
From this sequence, we choose the sub-sequence (say, up to seventh element)
and apply it accordingly as
Explicitly, defining
, this step-by-step procedure results in
Thus, we can see how a very simple procedure can be used to determine the value of the rational number
without using a sophisticated Equation (
35) consisting of 14 nested square roots of 2.
At
, the corresponding Machin-like formula is
where the constant
can be computed either by using Equation (
7) or, more efficiently, by using Equation (
13) based on two-step iteration (
14).
The following Mathematica code:
(∗ String for long number \[Beta]_7 ∗)
strBeta7=
ToString[StringJoin[
"21549475820057881611210311984288158234143531212163819254",
"1568712000964806160594022446140062110943660584298183679/",
"459948920218008069525744651226752553899687099736076594466",
"78719072620659988130828378620624183170066256006981324801"
]];
(∗ Verification ∗)
Print[\[Pi]/4==64∗ArcTan[1/81]-ArcTan[ToExpression[strBeta7]]];
validates Equation (
37) by returning
True.
Suppose that we do not know the sequence other than
. However, with the help of Equation (
32), we can find other digits of
in the iterative process. In particular, using Equation (
31), we have
Substituting this value into Equation (
32), we can find a significantly better approximation of
.
The following is the Mathematica code:
Print["Equation (34) at k = 7: ",
MantissaExponent[N[\[Pi]-4∗(64/81),20]][[2]] // Abs,
" digits of \[Pi]"];
Print["Equation (32) at k = 7: ",
MantissaExponent[
N[\[Pi]-4∗(64/81+1/2∗(1-1.00941448647564092749)),
20]][[2]]//Abs," digits of \[Pi]"];
which produces the following output:
Equation (34) at k = 7: 1 digits of π
Equation (32) at k = 7: 4 digits of π
The initial sequence
helped us to find the value
. Now, due to the higher accuracy of Equation (
32), we can generate the sequence in which its upper index is doubled
and with the help of this sequence, we can find the corresponding value
= 10,430.
Unfortunately, doubling the upper index k does not always work. For example, if we attempt to double the upper index by using the initial sequence , then we obtain = 41,722 instead of the correct value = 41,721. Therefore, the upper index of the sequence should be slightly less than two.
The two-term approximation (
32) doubles the number of digits of
as compared to the single-term approximation (
34). This means that using the sequence
, we can obtain all sequences
,
,
, etc., up to
, where
is an integer slightly smaller than
. Our numerical results show that doubling the value of
k does not always provide the correct sequence, as a few binary digits at the end of the sequence
occasionally may not be correct. However, when we use the empirical equation
then the corresponding sequence
is a sub-sequence of the infinite sequence (
36) and, therefore, it is appeared to be correct. It is interesting to note that the number 32 in this equation is the largest integer that we found on the basis of our numerical results.
The following is a Mathematica code that shows number of digits of at given iteration number n and integer k:
Clear[str,sps,k,\[Gamma],\[Alpha],lst,\[Eta]]
(∗ String for conversion of 1/\[Pi] to sequence ∗)
str="ImportString[ToString[BaseForm[N[1/piAppr,k0],2]],
\"Table\"][[1]][[1]]";
(∗ String for space separation ∗)
sps[n_]:=Module[{m=1,sps=" "},
While[m<n,sps=StringJoin[sps," "];m++];If[m==n,sps]];
(∗ Converting number to string with length q ∗)
cnv2str[p_,q_]:=Module[{},StringTake[StringJoin[ToString[p],sps[q]],q]]
(∗ Defining \[Eta]-function ∗)
\[Eta][n_,x_,k_]:=Module[{K=k/1.5,y=x},y=N[(2∗y)/(1-y^2),K];cntr = 1;
While[cntr<n,y=(2∗y)/(1-y^2);cntr++];y];
(∗ Define \[Alpha]_1, \[Alpha]_2 and \[Alpha]_3] ∗)
\[Alpha][1]=1;
\[Alpha][2]=2;
\[Alpha][3]=5;
(∗ Input values ∗)
k=3;\[Gamma]=\[Alpha][3];
(∗ Heading ∗)
Print["-------------------------------"];
Print["Iteration | k", sps[5], "| Digits of \[Pi]"];
Print["-------------------------------"];
n=1;
While[n<=12,
intR=1/\[Gamma];
k0=\[LeftFloor](2-1/32)∗k\[RightFloor];
piAppr=4∗(2^(k-1)∗intR+1/2∗(1-\[Eta][k-1,intR,k0]));
(∗ Extracting the sequence {1,0,1,0,0,0,1...} ∗)
lst=RealDigits[ToExpression[str]][[1]][[1;;k0]];
(∗ Main computation ∗)
K=k+1;
While[K<=k0,\[Gamma]=
2∗\[Gamma]+lst[[K]];\[Alpha][K]=\[Gamma];K++];k=k0;
(∗ Aligned output" ∗)
Print[cnv2str[n,5],sps[4]," | ",cnv2str[k,5]," | ",
MantissaExponent[N[\[Pi]-piAppr,k0]][[2]]//Abs];
n++];
This code generates the output:
---------------------------------------
Iteration | k | Digits of π
---------------------------------------
1 | 5 | 1
2 | 9 | 2
3 | 17 | 4
4 | 33 | 9
5 | 64 | 20
6 | 126 | 38
7 | 248 | 75
8 | 488 | 149
9 | 960 | 293
10 | 1890 | 577
11 | 3720 | 1137
12 | 7323 | 2240
As we can see from the third column, the number of digits of doubles at each iteration.
It should be noted that the tangent function
can also be computed by combining together Equations (
30) and (
31). In particular, taking
, we can apply the identity
The following is the Mathematica code where the identity (
38) is implemented by using Equations (
30) and (
31) at
and
:
Clear[tanF]
(∗ Computing tangent ∗)
tanF[n_,x_,k_]:=Module[{p=0,q=0,m=1,x0=N[x,k]},xSq=x0^2;
While[m<=n,
r=(-1)^(m-1)/(2∗m-1)!∗x0;
p=p+r;
q=q+2^(2∗m-1)∗r;
m++;x0=x0∗xSq];
(2∗p^2)/q];
(∗ Case k = k0 = 7323 ∗)
n=1;
\[Sigma]=100;
While[n<=10,numb=tanF[n,2^(k0-1-\[Sigma])/\[Alpha][k0],k0];
Print["n = ",n,": ",MantissaExponent[\[Pi]-
4∗(2^(k0-1)/\[Alpha][k0]+
1/2∗(1-\[Eta][\[Sigma],numb,k0]))][[2]]//Abs,
" digits of \[Pi]"];n++];
This code returns the following output:
n = 1: 60 digits of π
n = 2: 121 digits of π
n = 3: 182 digits of π
n = 4: 244 digits of π
n = 5: 306 digits of π
n = 6: 368 digits of π
n = 7: 430 digits of π
n = 8: 492 digits of π
n = 9: 554 digits of π
n = 10: 617 digits of π
This output shows a high convergence rate. Specifically, we can see that each increment
n in Equation (
30) contributes more than 60 digits of
. Generally, this convergence rate has no upper limitation. However, in order to increase
in Equation (
38), we have to increase the value of the integer
k.
Although this convergence rate is significantly higher than those in some modern algorithms for computing digits of
[
4], even without nested square roots of 2, the proposed method at large values
k still requires a powerful computer to compute the coefficients
by using the binary form of
.
The presence of the multiplier
in Equation (
38) is continuously divisible by 2. Therefore, its application may be advantageous for more rapid computation since each multiplication by 2 implies just a binary shift of the mantissa.
The Mathematica code below shows the values of at given k:
(∗Heading∗)
Print["-----------------"];
Print["k",sps[5],"| \[Alpha][k]"];
Print["-----------------"];
k=2;
While[k<=25,
(∗Aligned output" ∗)
Print[cnv2str[k,5], " | ", \[Alpha][k]];
k++];
This code returns the following output:
------------------------
k | αk
------------------------
2 | 2
3 | 5
4 | 10
5 | 20
6 | 40
7 | 81
8 | 162
9 | 325
10 | 651
11 | 1303
12 | 2607
13 | 5215
14 | 10430
15 | 20860
16 | 41721
17 | 83443
18 | 166886
19 | 333772
20 | 667544
21 | 1335088
22 | 2670176
23 | 5340353
24 | 10680707
25 | 21361414
As we can see, all numbers
are the same as those reported in [
9].
Since the constants
have been computed already, we can use them to validate the formula (
33) for
in the binary form. The Mathematica code below:
f[K_]:=N[Sum[(1/10^(k+1))∗Mod[\[Alpha][k],2],{k,1,K}],K];
Print["-------------------------------------------------------------"]
Print["k",sps[2]," | Binary output"];
Print["-------------------------------------------------------------"]
k := 1;
While[k<=5,Print[10∗k,sps[2],"| ",Subscript[f[10∗k],2]];k++]
Print["-------------------------------------------------------------"]
Print["Built-in Mathematica:"]
Print["1/\[Pi]=",
Subscript[StringJoin["[",
StringSplit[ToString[BaseForm[N[1/Pi,15],2]]][[1]], "...]"],
2]];
returns the output:
------------------------------------------------------
k | Binary output
------------------------------------------------------
10 | 0.010100010112
20 | 0.0101000101111100110002
30 | 0.01010001011111001100000110110112
40 | 0.010100010111110011000001101101110010011102
50 | 0.0101000101111100110000011011011100100111001000100002
————————————————————-
Built-in Mathematica:
= [0.010100010111110011000001101101110010011100100010000...]2
according to Equation (
33). The original binary representation of the number
generated by the built-in Mathematica is also shown for comparison (see also [
26] for binary sequence for
).