Created
October 17, 2012 23:42
-
-
Save weskerfoot/3909034 to your computer and use it in GitHub Desktop.
Fun with Stern-Brocot tree
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Control.Monad | |
import Data.Ratio | |
data FakeRatio = FakeRatio { numr :: Int, denom :: Int} deriving (Show) | |
data SBTriple = SBTriple { left :: FakeRatio, | |
mid :: FakeRatio, | |
right :: FakeRatio} | |
data Directions = TLeft | TRight deriving (Show) | |
data SBTree = SBTree FakeRatio SBTree SBTree | |
combine f1 f2 = FakeRatio ((numr f1) + (numr f2)) ((denom f1) + (denom f2)) | |
genSB :: SBTriple -> SBTree | |
genSB SBTriple {left=l, mid=m, right=r} = SBTree m (genSB (SBTriple l (combine m l) m)) (genSB (SBTriple m (combine m r) r)) | |
sbHead (SBTree m _ _) = m | |
sbLeft (SBTree _ a _) = a | |
sbRight (SBTree _ _ a) = a | |
phiDirections = map f [1..] where | |
f n = case (odd n) of | |
True -> TLeft | |
_ -> TRight | |
eDirections = TRight : join (zipWith conv [1..100] [2,4..]) where | |
conv n r = case (odd n) of | |
True -> [TRight,TLeft] ++ (take r $ repeat TRight) | |
_ -> [TLeft, TRight] ++ (take r $ repeat TLeft) | |
findSB [] sb = sbHead sb | |
findSB (d:ds) sb = findSB ds (f sb) where | |
f sb = case d of | |
TRight -> sbRight sb | |
TLeft -> sbLeft sb | |
sbTree = genSB (SBTriple (FakeRatio 0 1) (FakeRatio 1 1) (FakeRatio 1 0)) | |
divideFakeRatio r = (fromIntegral (numr r)) / (fromIntegral (denom r)) | |
genIrrational ds = let r = findSB ds sbTree in divideFakeRatio r | |
fromReal' n sbTree = let sbh = (sbHead sbTree) in check sbh (divideFakeRatio sbh) where | |
check sbh h | h == n = (numr sbh) % (denom sbh) | |
| n < h = fromReal' n (sbLeft sbTree) | |
| otherwise = fromReal' n (sbRight sbTree) | |
sbLogB' b n sbTree = let sbh = (sbHead sbTree) in let sbh' = divideFakeRatio sbh in check sbh' where | |
check sh | b**sh == n = sh | |
| b**sh < n = sbLogB' b n (sbRight sbTree) | |
| otherwise = sbLogB' b n (sbLeft sbTree) | |
sbLogBase b n = sbLogB' b n sbTree | |
fromReal n = fromReal' n sbTree | |
main = do | |
print $ genIrrational (take 70 eDirections) | |
print $ 1 / (genIrrational (take 20 phiDirections)) | |
print $ map fromReal [1.5,2..10] | |
print $ sbLogBase 2 pi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment