Skip to content

Instantly share code, notes, and snippets.

@pbevin
Created April 23, 2015 00:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pbevin/b87beb6c00969697b690 to your computer and use it in GitHub Desktop.
Save pbevin/b87beb6c00969697b690 to your computer and use it in GitHub Desktop.
import Data.Char
e = map (intToDigit . fromInteger) $ stream next safe prod cons init lfts where
init = unit
lfts = [(1, k, 0, k) | k<-[1..]]
next z = floor (extr z 1)
safe z n = (n == floor (extr z 2))
prod z n = comp (10, -10*n, 0, 1) z
cons z z' = comp z z'
type LFT = (Integer, Integer, Integer, Integer)
extr :: LFT -> Integer -> Rational
extr (q,r,s,t) x = ((fromInteger $ q * x) + (fromInteger r)) / ((fromInteger $ s * x) + (fromInteger t))
unit :: LFT
unit = (1,0,0,1)
comp :: LFT -> LFT -> LFT
comp (q,r,s,t) (u,v,w,x) = (q*u+r*w,q*v+r*x,s*u+t*w,s*v+t*x)
stream :: (b->c) -> (b->c->Bool) -> (b->c->b) -> (b->a->b) -> b -> [a] -> [c]
stream next safe prod cons z (x:xs) =
if safe z y
then y : stream next safe prod cons (prod z y) (x:xs)
else stream next safe prod cons (cons z x) xs
where y = next z
@pbevin
Copy link
Author

pbevin commented Apr 23, 2015

The idea is that e = 1 + 1/1 * (1 + 1/2 * (1 + 1/3 * ...)) and each term reduces the range [1,2] back to a smaller subrange. The rest is from http://www.cs.ox.ac.uk/jeremy.gibbons/publications/spigot.pdf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment