Menu Close

Cálculo de pi mediante la fracción continua de Lange

En 1999, L.J. Lange publicó el artículo An elegant new continued fraction for π.

En el primer teorema del artículo se demuestra la siguiente expresión de π mediante una fracción continua
Calculo_de_pi_mediante_la_fraccion_continua_de_Lange

La primeras aproximaciones son

   a(1) = 3+1                = 4.0
   a(2) = 3+(1/(6+9))        = 3.066666666666667
   a(3) = 3+(1/(6+9/(6+25))) = 3.158974358974359

Definir las funciones

   aproximacionPi :: Int -> Double
   grafica        :: [Int] -> IO ()

tales que

  • (aproximacionPi n) es la n-ésima aproximación de pi con la fracción continua de Lange. Por ejemplo,
     aproximacionPi 1     ==  4.0
     aproximacionPi 2     ==  3.066666666666667
     aproximacionPi 3     ==  3.158974358974359
     aproximacionPi 10    ==  3.141287132741557
     aproximacionPi 100   ==  3.141592398533554
     aproximacionPi 1000  ==  3.1415926533392926
  • (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..10]) dibuja
    Calculo_de_pi_mediante_la_fraccion_continua_de_Lange_2
    (grafica [10..100]) dibuja
    Calculo_de_pi_mediante_la_fraccion_continua_de_Lange_3
    y (grafica [100..200]) dibuja
    Calculo_de_pi_mediante_la_fraccion_continua_de_Lange_4

Soluciones

import Graphics.Gnuplot.Simple
 
-- fraccionPi es la representación de la fracción continua de pi como un
-- par de listas infinitas.
fraccionPi :: [(Integer, Integer)]
fraccionPi = zip (3 : [6,6..]) (map (^2) [1,3..])
 
-- (aproximacionFC n fc) es la n-ésima aproximación de la fracción
-- continua fc (como un par de listas).  
aproximacionFC :: Int -> [(Integer, Integer)] -> Double
aproximacionFC n =
  foldr (\(a,b) z -> fromIntegral a + fromIntegral b / z) 1 . take n
 
aproximacionPi :: Int -> Double
aproximacionPi n =
  aproximacionFC n fraccionPi
 
grafica :: [Int] -> IO ()
grafica xs = 
  plotList [Key Nothing]
           [(k,aproximacionPi k) | k <- xs]

Otras soluciones

  • Se pueden escribir otras soluciones en los comentarios.
  • El código se debe escribir entre una línea con <pre lang="haskell"> y otra con </pre>
Posted in Medio

3 Comments

  1. rebgongor
    import Graphics.Gnuplot.Simple
     
    aproximacionPi :: Int -> Double
    aproximacionPi n = foldr f 1 xs
      where xs = take n $ zip (3:repeat 6) (map (^2) [1,3..])
            f (a,b) c = fromIntegral a + fromIntegral b / c
     
    grafica :: [Int] -> IO ()
    grafica xs =
      plotList [Key Nothing, PNG "graficaLange.png"]
               [aproximacionPi k | k <- xs]
  2. Enrique Zubiría
    import Graphics.Gnuplot.Simple
     
    aproximacionPi :: Int -> Double
    aproximacionPi n = 3 + 1/(aux n 1)
      where aux n m
              | n == 1     = 1
              | m == (n-1) = fromIntegral (6 + (2*m+1)^2)
              | otherwise  = 6 + fromIntegral ((2*m+1)^2)/(aux n (m+1))
     
    grafica :: [Int] -> IO ()
    grafica ns = do
      plotList [ Key Nothing
               , PNG "calculoPiFraccionContinuaLange.png"
               ]
               (map aproximacionPi ns)
  3. melgonaco
    import Graphics.Gnuplot.Simple
     
    aproximacionPi :: Int -> Double
    aproximacionPi n = 3 + aux n (map (^2) [1,3..])
      where aux 1 (x:xs) = x
            aux n (x:xs) = x/(6+aux (n-1) xs)
     
    grafica :: [Int] -> IO ()
    grafica xs = 
      plotList [ Key Nothing
               , PNG "aproximacionpiLange.png"]
               (map aproximacionPi xs)

Escribe tu solución

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.