module Factory.Math.Implementations.Pi.Spigot.Spigot(
decimal,
openI,
) where
import qualified Control.Arrow
import qualified Data.Char
import qualified Data.Ratio
import qualified Factory.Math.Implementations.Pi.Spigot.Series as Math.Implementations.Pi.Spigot.Series
import qualified Factory.Math.Precision as Math.Precision
type I = Int
decimal :: I
decimal :: I
decimal = I
10
type Base = Data.Ratio.Ratio I
type QuotRem = (I, I)
getQuotient, getRemainder :: QuotRem -> I
getQuotient :: QuotRem -> I
getQuotient = QuotRem -> I
forall a b. (a, b) -> a
fst
getRemainder :: QuotRem -> I
getRemainder = QuotRem -> I
forall a b. (a, b) -> b
snd
type PreDigits = [I]
type Pi = [I]
type Coefficients = [I]
carryAndDivide :: (Base, I) -> QuotRem -> QuotRem
carryAndDivide :: (Base, I) -> QuotRem -> QuotRem
carryAndDivide (Base
base, I
lhs) QuotRem
rhs
| I
n I -> I -> Bool
forall a. Ord a => a -> a -> Bool
< I
d = (I
0, I
n)
| Bool
otherwise = (I -> I) -> QuotRem -> QuotRem
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
Control.Arrow.first (I -> I -> I
forall a. Num a => a -> a -> a
* Base -> I
forall a. Ratio a -> a
Data.Ratio.numerator Base
base) (QuotRem -> QuotRem) -> QuotRem -> QuotRem
forall a b. (a -> b) -> a -> b
$ I
n I -> I -> QuotRem
forall a. Integral a => a -> a -> (a, a)
`quotRem` I
d
where
d, n :: I
d :: I
d = Base -> I
forall a. Ratio a -> a
Data.Ratio.denominator Base
base
n :: I
n = I
lhs I -> I -> I
forall a. Num a => a -> a -> a
+ QuotRem -> I
getQuotient QuotRem
rhs
processColumns
:: Math.Implementations.Pi.Spigot.Series.Series I
-> PreDigits
-> [(Base, I)]
-> Pi
processColumns :: Series I -> PreDigits -> [(Base, I)] -> PreDigits
processColumns Series I
series PreDigits
preDigits [(Base, I)]
l
| I
overflowMargin I -> I -> Bool
forall a. Ord a => a -> a -> Bool
> I
1 = PreDigits
preDigits PreDigits -> PreDigits -> PreDigits
forall a. [a] -> [a] -> [a]
++ PreDigits -> PreDigits
nextRow [I
digit]
| I
overflowMargin I -> I -> Bool
forall a. Eq a => a -> a -> Bool
== I
1 = PreDigits -> PreDigits
nextRow (PreDigits -> PreDigits) -> PreDigits -> PreDigits
forall a b. (a -> b) -> a -> b
$ PreDigits
preDigits PreDigits -> PreDigits -> PreDigits
forall a. [a] -> [a] -> [a]
++ [I
digit]
| Bool
otherwise = (I -> I) -> PreDigits -> PreDigits
forall a b. (a -> b) -> [a] -> [b]
map ((I -> I -> I
forall a. Integral a => a -> a -> a
`rem` I
decimal) (I -> I) -> (I -> I) -> I -> I
forall b c a. (b -> c) -> (a -> b) -> a -> c
. I -> I
forall a. Enum a => a -> a
succ) PreDigits
preDigits PreDigits -> PreDigits -> PreDigits
forall a. [a] -> [a] -> [a]
++ PreDigits -> PreDigits
nextRow [I
0]
where
results :: [QuotRem]
results :: [QuotRem]
results = [QuotRem] -> [QuotRem]
forall a. [a] -> [a]
init ([QuotRem] -> [QuotRem]) -> [QuotRem] -> [QuotRem]
forall a b. (a -> b) -> a -> b
$ ((Base, I) -> QuotRem -> QuotRem)
-> QuotRem -> [(Base, I)] -> [QuotRem]
forall a b. (a -> b -> b) -> b -> [a] -> [b]
scanr (Base, I) -> QuotRem -> QuotRem
carryAndDivide (I
0, I
forall a. HasCallStack => a
undefined) [(Base, I)]
l
digit :: I
digit :: I
digit = QuotRem -> I
getQuotient (QuotRem -> I) -> QuotRem -> I
forall a b. (a -> b) -> a -> b
$ [QuotRem] -> QuotRem
forall a. [a] -> a
head [QuotRem]
results
overflowMargin :: I
overflowMargin :: I
overflowMargin = I
decimal I -> I -> I
forall a. Num a => a -> a -> a
- I
digit
nextRow :: [I] -> [I]
nextRow :: PreDigits -> PreDigits
nextRow PreDigits
preDigits' = Series I -> PreDigits -> PreDigits -> PreDigits
mkRow Series I
series PreDigits
preDigits' (PreDigits -> PreDigits) -> PreDigits -> PreDigits
forall a b. (a -> b) -> a -> b
$ (QuotRem -> I) -> [QuotRem] -> PreDigits
forall a b. (a -> b) -> [a] -> [b]
map QuotRem -> I
getRemainder [QuotRem]
results
mkRow :: Math.Implementations.Pi.Spigot.Series.Series I -> PreDigits -> Coefficients -> Pi
mkRow :: Series I -> PreDigits -> PreDigits -> PreDigits
mkRow Series I
series PreDigits
preDigits = Series I -> PreDigits -> [(Base, I)] -> PreDigits
processColumns Series I
series PreDigits
preDigits ([(Base, I)] -> PreDigits)
-> (PreDigits -> [(Base, I)]) -> PreDigits -> PreDigits
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Base] -> PreDigits -> [(Base, I)]
forall a b. [a] -> [b] -> [(a, b)]
zip (Base -> Base
forall a. Fractional a => a -> a
recip (I -> Base
forall a b. (Integral a, Num b) => a -> b
fromIntegral I
decimal) Base -> [Base] -> [Base]
forall a. a -> [a] -> [a]
: Series I -> [Base]
forall i. Integral i => Series i -> [Ratio i]
Math.Implementations.Pi.Spigot.Series.bases Series I
series) (PreDigits -> [(Base, I)])
-> (PreDigits -> PreDigits) -> PreDigits -> [(Base, I)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (I -> I) -> PreDigits -> PreDigits
forall a b. (a -> b) -> [a] -> [b]
map (I -> I -> I
forall a. Num a => a -> a -> a
* I
decimal)
openI :: Math.Implementations.Pi.Spigot.Series.Series I -> Math.Precision.DecimalDigits -> Integer
openI :: Series I -> I -> Integer
openI Series I
series I
decimalDigits = String -> Integer
forall a. Read a => String -> a
read (String -> Integer)
-> (PreDigits -> String) -> PreDigits -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (I -> Char) -> PreDigits -> String
forall a b. (a -> b) -> [a] -> [b]
map (
I -> Char
Data.Char.intToDigit (I -> Char) -> (I -> I) -> I -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. I -> I
forall a b. (Integral a, Num b) => a -> b
fromIntegral
) (PreDigits -> String)
-> (PreDigits -> PreDigits) -> PreDigits -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. I -> PreDigits -> PreDigits
forall a. I -> [a] -> [a]
take I
decimalDigits (PreDigits -> PreDigits)
-> (PreDigits -> PreDigits) -> PreDigits -> PreDigits
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Series I -> PreDigits -> PreDigits -> PreDigits
mkRow Series I
series [] (PreDigits -> PreDigits)
-> (PreDigits -> PreDigits) -> PreDigits -> PreDigits
forall b c a. (b -> c) -> (a -> b) -> a -> c
. I -> PreDigits -> PreDigits
forall a. I -> [a] -> [a]
take (
Series I -> I -> I
forall i. Series i -> I -> I
Math.Implementations.Pi.Spigot.Series.nTerms Series I
series I
decimalDigits
) (PreDigits -> Integer) -> PreDigits -> Integer
forall a b. (a -> b) -> a -> b
$ Series I -> PreDigits
forall i. Series i -> [i]
Math.Implementations.Pi.Spigot.Series.coefficients Series I
series