{- Copyright (C) 2011 Dr. Alistair Ward This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . -} {- | [@AUTHOR@] Dr. Alistair Ward [@DESCRIPTION@] Defines the /Borwein/ series for /Pi/; -} module Factory.Math.Implementations.Pi.Borwein.Borwein1993( -- * Constants series ) where -- import Control.Arrow((***)) import Data.Ratio((%)) -- import Factory.Data.PrimeFactors((>*<), (>/<), (>^)) -- import qualified Factory.Data.PrimeFactors as Data.PrimeFactors import qualified Factory.Math.Factorial as Math.Factorial import qualified Factory.Math.Implementations.Factorial as Math.Implementations.Factorial import qualified Factory.Math.Implementations.Pi.Borwein.Series as Math.Implementations.Pi.Borwein.Series import qualified Factory.Math.Power as Math.Power import qualified Factory.Math.Precision as Math.Precision import qualified Factory.Math.SquareRoot as Math.SquareRoot -- | Defines the parameters of the /Borwein/ series. series :: (Math.SquareRoot.Algorithmic squareRootAlgorithm, Math.Factorial.Algorithmic factorialAlgorithm) => Math.Implementations.Pi.Borwein.Series.Series squareRootAlgorithm factorialAlgorithm series = Math.Implementations.Pi.Borwein.Series.MkSeries { Math.Implementations.Pi.Borwein.Series.terms = \squareRootAlgorithm factorialAlgorithm decimalDigits -> let simplify, squareRoot :: Rational -> Rational simplify = Math.Precision.simplify $ pred decimalDigits {-ignore single integral digit-} -- This makes a gigantic difference to performance. squareRoot = simplify . Math.SquareRoot.squareRoot squareRootAlgorithm decimalDigits sqrt5, a, b, c3 :: Rational sqrt5 = squareRoot 5 a = 63365028312971999585426220 + sqrt5 * (28337702140800842046825600 + 384 * squareRoot (10891728551171178200467436212395209160385656017 + 4870929086578810225077338534541688721351255040 * sqrt5)) b = 7849910453496627210289749000 + 3510586678260932028965606400 * sqrt5 + 2515968 * squareRoot (3110 * (6260208323789001636993322654444020882161 + 2799650273060444296577206890718825190235 * sqrt5)) c3 = simplify . Math.Power.cube $ negate 214772995063512240 - sqrt5 * (96049403338648032 + 1296 * squareRoot (10985234579463550323713318473 + 4912746253692362754607395912 * sqrt5)) in ( squareRoot $ negate c3, -- The factor into which the series must be divided, to yield Pi. zipWith ( {- \n power -> let product' = Data.PrimeFactors.product' (recip 2) 10 in uncurry (/) . ( (* (a + b * fromIntegral n)) . fromIntegral . product' *** (* power) . fromIntegral . product' ) $ Math.Implementations.Factorial.primeFactors (6 * n) >/< ( Math.Implementations.Factorial.primeFactors (3 * n) >*< Math.Implementations.Factorial.primeFactors n >^ 3 ) -} \n power -> ( Math.Implementations.Factorial.risingFactorial (succ $ 3 * n) (3 * n) % Math.Power.cube (Math.Factorial.factorial factorialAlgorithm n) ) * ( (a + b * fromIntegral n) / power ) ) [0 :: Integer ..] $ iterate (* c3) 1 ), Math.Implementations.Pi.Borwein.Series.convergenceRate = 10 ** negate 50 -- Empirical. }