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

Nota: Este ejercicio ha sido propuesto por Antonio Morales.

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]
Avanzado

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

  1. albcercid
     
    aproximacionPi n = 3 + 1/(aux 1 3)
          where aux a b | a == n = 1
                        | otherwise = 6 + (b^2)/(aux (a+1) (b+2))
  2. antmorper3
    aproximacionPi :: Int -> Double
    aproximacionPi n = 3 + aux n 0
     where aux n x | n == 0 = 1
                   | otherwise = (xs!!x)^^2 / (6 + aux (n-1) (x+1))
           xs = [1,3..]
     
    grafica :: Int -> IO ()
    grafica n = plotLists [Key Nothing]
                  [[(x,aproximacionPi x) | x <- [(n `div` 10)..n]]]
  3. enrnarbej
    aproximacionPi :: Int -> Double
    aproximacionPi n = aux (map ((^2).(fromIntegral)) [1,3..2*n-1]) - 3
                      where
                       aux [] = 1
                       aux (x:xs) = 6 + x / aux xs
  4. marlobrip
    aproximacionPi :: Int -> Double
    aproximacionPi n = 3 + recursionPi (take n [1,3..])
     
    recursionPi :: Fractional a => [a] -> a
    recursionPi [] = -5
    recursionPi (x:xs) = x^2/(6+(recursionPi xs))
  5. paumacpar
    aproximacionPi :: Int -> Double
    aproximacionPi n = 3 + 1/(aux 1 (map (^2) [3,5..]))
      where aux k (x:xs) | k == n = 1
                         | otherwise = 6 + (x/(aux (k+1) xs))
  6. ignareeva
     
    aproximacionPi :: Int -> Double
    aproximacionPi n = 3 + 1/listaPi xs
      where xs =take (n-1) [x | x <- [3,5..]]
     
    listaPi :: Fractional a => [a] -> a
    listaPi [] = 1
    listaPi (x:xs) = 6 + x^2/ listaPi xs
  7. eliguivil
    aproximacionPi3 :: Int -> Double
    aproximacionPi3 n = 3 + (aux $ take n [1,3..])
      where
        aux [x] = x^2
        aux (x:xs) = x^2/(6 + aux xs)
     
    grafica3 :: [Int] -> IO ()
    grafica3 ns =
      plotLists [] [[(x,aproximacionPi3 x) | x <- ns]]
  8. María Ruiz
    import Graphics.Gnuplot.Simple
     
    aproxFracionContinua:: [Int] -> [Int] -> Int -> Double
    aproxFracionContinua xs ys n = last $ scanl f (a+b) $ zip as bs
      where (a:as) = map fromIntegral $ reverse $ take n xs
            (b:bs) = map fromIntegral $ reverse $ take n ys
            f z (x,y) = x + y/z
     
     
    aproximacionPi :: Int -> Double
    aproximacionPi = aproxFracionContinua as bs
      where as = 3:repeat 6
            bs = map (^2) [1,3..]
     
    grafica :: [Int] -> IO ()
    grafica ns = plotList [] $ map aproximacionPi ns
  9. glovizcas
    aproximacionPi3 :: Int -> Double
    aproximacionPi3 n = 3 + f xs
               where xs = take n [2*k + 1 | k <- [0..]]
     
    f [] = -5
    f (x:xs) = (x^2 / (6+ f xs))
     
     
    grafica3 :: [Int] -> IO ()
    grafica3 xs = plotLists [Key Nothing]
                  [[(x,aproximacionPi3 x) | x <- xs]]

Escribe tu solución

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