Cálculo de pi mediante el método de Newton
El método de Newton para el cálculo de pi se basa en la relación
y en el desarrollo del arco seno
de donde se obtiene la fórmula
La primeras aproximaciones son
1 2 3 |
a(0) = 6*(1/2) = 3.0 a(1) = 6*(1/2+1/(2*3*2^3)) = 3.125 a(2) = 6*(1/2+1/(2*3*2^3)+(1*3)/(2*4*5*2^5)) = 3.1390625 |
Definir las funciones
1 2 |
aproximacionPi :: Int -> Double grafica :: [Int] -> IO () |
tales que
- (aproximacionPi n) es la n-ésima aproximación de pi con la fórmula de Newton. Por ejemplo,
1 2 3 4 5 6 |
aproximacionPi 0 == 3.0 aproximacionPi 1 == 3.125 aproximacionPi 2 == 3.1390625 aproximacionPi 10 == 3.1415926468755613 aproximacionPi 21 == 3.141592653589793 pi == 3.141592653589793 |
- (grafica xs) dibuja la gráfica de las k-ésimas aproximaciones de pi donde k toma los valores de la lista xs. Por ejemplo, (grafica [1..30]) dibuja
Nota: Este ejercicio ha sido propuesto por Manuel Herrera.
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
import Graphics.Gnuplot.Simple -- 1ª definición -- ============= aproximacionPi :: Int -> Double aproximacionPi n = 6 * arcsinX where arcsinX = 0.5 + sum (take n factoresN) factoresN :: [Double] factoresN = zipWith (*) (potenciasK 3) fraccionesPI potenciasK :: Double -> [Double] potenciasK k = (0.5**k)/k : potenciasK (k+2) fraccionesPI :: [Double] fraccionesPI = scanl (*) (1/2) (tail (zipWith (/) [1,3..] [2,4..])) -- 2ª definición -- ============= aproximacionPi2 :: Int -> Double aproximacionPi2 n = 6 * (serie !! n) serie :: [Double] serie = scanl1 (+) (zipWith (/) (map fromIntegral numeradores) (map fromIntegral denominadores)) where numeradores = 1 : scanl1 (*) [1,3..] denominadores = zipWith (*) denominadores1 denominadores2 denominadores1 = 2 : scanl1 (*) [2,4..] denominadores2 = 1 : [n * 2^n | n <- [3,5..]] grafica :: [Int] -> IO () grafica xs = plotList [Key Nothing] [(k,aproximacionPi k) | k <- xs] |
9 Comentarios