Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Spigot algorithm
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{Short description|Algorithm for computing the value of a transcendental number}}A '''spigot algorithm''' is an [[algorithm]] for computing the value of a [[transcendental number]] (such as [[pi|{{pi}}]] or [[e (mathematical constant)|''e'']]) that generates the digits of the number sequentially from left to right providing increasing precision as the algorithm proceeds. Spigot algorithms also aim to minimize the amount of intermediate storage required. The name comes from the sense of the word "spigot" for a [[Tap (valve)|tap or valve]] controlling the flow of a liquid. Spigot algorithms can be contrasted with algorithms that store and process complete numbers to produce successively more accurate approximations to the desired transcendental. Interest in spigot algorithms was spurred in the early days of computational mathematics by extreme constraints on memory, and such an algorithm for calculating the digits of ''e'' appeared in a paper by Sale in 1968.<ref>{{cite journal |author=Sale, AHJ |year=1968 |title=The calculation of ''e'' to many significant digits |journal= The Computer Journal|volume=11 |issue=2 |pages=229–230 |doi=10.1093/comjnl/11.2.229|doi-access=free }}</ref> In 1970, Abdali presented a more general algorithm to compute the sums of series in which the ratios of successive terms can be expressed as quotients of integer functions of term positions. This algorithm is applicable to many familiar series for trigonometric functions, logarithms, and transcendental numbers because these series satisfy the above condition.<ref>{{cite journal |url=http://geomete.com/abdali/papers/algoCACM393.pdf |author=Abdali, S Kamal |year=1970 |title=Special Series Summation with Arbitrary Precision |journal=Communications of the ACM |volume=13 |issue=9 |page=570 |doi=10.1145/362736.362756}}</ref> The name "spigot algorithm" seems to have been coined by [[Stanley Rabinowitz]] and [[Stan Wagon]], whose algorithm for calculating the digits of {{pi}} is sometimes referred to as "''the'' spigot algorithm for {{pi}}".<ref> {{cite journal |url=http://stanleyrabinowitz.com/bibliography/spigot.pdf |title= A Spigot Algorithm for the Digits of Pi|last1= Rabinowitz|first1= Stanley|last2=Wagon|first2=Stan|journal=American Mathematical Monthly|volume=102|year=1995|pages=195–203|accessdate=8 May 2013 |doi=10.2307/2975006 |issue=3|jstor= 2975006}}</ref> The spigot algorithm of Rabinowitz and Wagon is ''bounded'', in the sense that the number of terms of the infinite series that will be processed must be specified in advance. The term "streaming algorithm"<ref>{{cite web|first=Jeremy|last=Gibbons|date=24 May 2004|url=http://web.comlab.ox.ac.uk/oucl/work/jeremy.gibbons/publications/spigot.pdf|title=Unbounded Spigot Algorithms for the Digits of Pi}}</ref> indicates an approach without this restriction. This allows the calculation to run indefinitely varying the amount of intermediate storage as the calculation progresses. A variant of the spigot approach uses an algorithm which can be used to compute a single arbitrary digit of the transcendental without computing the preceding digits: an example is the [[Bailey–Borwein–Plouffe formula]], a digit extraction algorithm for {{pi}} which produces base 16 digits. The inevitable truncation of the underlying infinite series of the algorithm means that the accuracy of the result may be limited by the number of terms calculated. ==Example== This example illustrates the working of a spigot algorithm by calculating the binary digits of the [[natural logarithm]] of 2 {{OEIS|id=A068426}} using the identity :<math>\ln(2)=\sum_{k=1}^{\infty}\frac{1}{k2^k}\, .</math> To start calculating binary digits from, as an example, the 8th place we multiply this identity by 2<sup>7</sup> (since 7 = 8 − 1): :<math>2^7\ln(2) =2^7\sum_{k=1}^\infty \frac{1}{k2^k}\, .</math> We then divide the infinite sum into a "head", in which the exponents of 2 are greater than or equal to zero, and a "tail", in which the exponents of 2 are negative: :<math>2^7\ln(2) =\sum_{k=1}^{7}\frac{2^{7-k}}{k}+\sum_{k=8}^{\infty}\frac{1}{k2^{k-7}}\, .</math> We are only interested in the fractional part of this value, so we can replace each of the summands in the "head" by :<math>\frac{2^{7-k} } k \bmod 1 = \frac{2^{7-k} \bmod k} k \, .</math> Calculating each of these terms and adding them to a running total where we again only keep the fractional part, we have: :{| class="wikitable" |- ! ''k'' ! ''A'' = 2<sup>7−''k''</sup> ! ''B'' = ''A'' mod ''k'' ! ''C'' = {{sfrac|''B''|''k''}} ! Sum of ''C'' mod 1 |- | 1 | 64 | 0 | 0 | 0 |- | 2 | 32 | 0 | 0 | 0 |- | 3 | 16 | 1 | {{sfrac|1|3}} | {{sfrac|1|3}} |- | 4 | 8 | 0 | 0 | {{sfrac|1|3}} |- | 5 | 4 | 4 | {{sfrac|4|5}} | {{sfrac|2|15}} |- | 6 | 2 | 2 | {{sfrac|1|3}} | {{sfrac|7|15}} |- | 7 | 1 | 1 | {{sfrac|1|7}} | {{sfrac|64|105}} |} We add a few terms in the "tail", noting that the error introduced by truncating the sum is less than the final term: :{| class="wikitable" |- ! ''k'' ! ''D'' = {{sfrac|1|''k''2<sup>''k''−7</sup>}} ! Sum of ''D'' ! Maximum error |- | 8 | {{sfrac|1|16}} | {{sfrac|1|16}} | {{sfrac|1|16}} |- | 9 | {{sfrac|1|36}} | {{sfrac|13|144}} | {{sfrac|1|36}} |- | 10 | {{sfrac|1|80}} | {{sfrac|37|360}} | {{sfrac|1|80}} |} Adding the "head" and the first few terms of the "tail" together we get: :<math>2^7\ln(2)\bmod1 \approx \frac{64}{105}+\frac{37}{360}=0.10011100 \ldots_2 + 0.00011010 \ldots_2 = 0.1011 \ldots_2 \, ,</math> so the 8th to 11th binary digits in the binary expansion of ln(2) are 1, 0, 1, 1. Note that we have not calculated the values of the first seven binary digits – indeed, all information about them has been intentionally discarded by using [[modular arithmetic]] in the "head" sum. The same approach can be used to calculate digits of the binary expansion of ln(2) starting from an arbitrary ''n''th position. The number of terms in the "head" sum increases linearly with ''n'', but the complexity of each term only increases with the logarithm of ''n'' if an efficient method of [[modular exponentiation]] is used. The [[precision (arithmetic)|precision]] of calculations and intermediate results and the number of terms taken from the "tail" sum are all independent of ''n'', and only depend on the number of binary digits that are being calculated – [[single precision]] arithmetic can be used to calculate around 12 binary digits, regardless of the starting position. ==References== {{reflist}} ==Further reading== * Arndt, Jorg; Haenel, Christoph, ''{{pi}} unleashed'', Springer Verlag, 2000. * {{MathWorld|urlname=SpigotAlgorithm|title=Spigot algorithm}} [[Category:Computer arithmetic algorithms]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)
Pages transcluded onto the current version of this page
(
help
)
:
Template:Cite journal
(
edit
)
Template:Cite web
(
edit
)
Template:MathWorld
(
edit
)
Template:OEIS
(
edit
)
Template:Pi
(
edit
)
Template:Reflist
(
edit
)
Template:SfnRef
(
edit
)
Template:Sfrac
(
edit
)
Template:Short description
(
edit
)