Menu Close

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
Calculo_de_pi_mediante_el_metodo_de_Newton_1
y en el desarrollo del arco seno
Calculo_de_pi_mediante_el_metodo_de_Newton_2
de donde se obtiene la fórmula
Calculo_de_pi_mediante_el_metodo_de_Newton_3

La primeras aproximaciones son

   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

   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,
     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
    Calculo_de_pi_mediante_el_metodo_de_Newton_4

Nota: Este ejercicio ha sido propuesto por Manuel Herrera.

Soluciones

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

9 soluciones de “Cálculo de pi mediante el método de Newton

  1. albcercid
    aproximacionPi :: Int -> Double
    aproximacionPi n = 6*aux (1/2) (1/(2*3*2^3)) 0 3
     where aux  a b c d | c == n = a
                        | otherwise = aux (a+b) (b*d^2/((d+1)*(2+d)*2^2)) (c+1) (d+2)
     
    grafica        :: [Int] -> IO ()
    grafica xs = plotList [] a
         where a = [aproximacionPi n | n <- xs]
  2. antmorper3
    aproximacionPi :: Int -> Double
    aproximacionPi n = 6 * aux n (1/2)
     where aux 0 x = x
           aux a x = (x * (product $ take (a-1) xs)/(product $ take (a-1) ys) *
                      (x^(f a)/(f a))) + aux (a-1) x
           xs = [3,5..]
           ys = [4,6..]
           f 0 = 0
           f b = head $ drop b [1,3..]
     
    grafica :: [Int] -> IO ()
    grafica xs = plotLists [Key Nothing]
                  [[(x,aproximacionPi x) | x <- xs]]
  3. enrnarbej
    aproximacionPi :: Int -> Double
    aproximacionPi n = 6 * (1/2 + aux 1 2 3 n)
                       where
                        aux _ _ _ 0 = 0
                        aux x z y n = x/(z*y*(2**y)) + aux (x*y) (z*(y+1)) (y+2) (n-1)
     
    grafica :: [Int] -> IO ()
    grafica xs = plotLists [Key Nothing]
                  [[(x,aproximacionPiManu x) | x <- xs]]
  4. eliguivil
    import Graphics.Gnuplot.Simple (plotLists)
    import Data.List (zipWith)
     
    aproximacionPi4 :: Int -> Double
    aproximacionPi4 n = 6 * (aux (take n [1,3..]) (take n [2,4..]))
      where
        aux is ps = sum $
          zipWith (*) (zipWith (/) (scanl (*) 1 is)
                                   (scanl (*) 1 ps))
                      [1/(2**k*k) | k <- [1,3..]]      
     
     
    grafica4 :: [Int] -> IO ()
    grafica4 xs = do
      plotLists [] [[(x, aproximacionPi4 x) | x <- xs]]
  5. antdursan
    sucesion :: Double -> [Double]
    sucesion x = [x**n / n | n <- [1,3..]]
     
    sucesion2 :: Int -> [Double]
    sucesion2 1 = [1]
    sucesion2 x = (product (take (x-1) [1,3..])) / (product (take (x-1) [2,4..])) : sucesion2 (x-1)
     
    productoPar :: (Double,Double) -> Double
    productoPar (a,b) = a*b
     
    aproximacionPi :: Int -> Double
    aproximacionPi x  = 6 * sum (map (productoPar) (zip (sucesion 0.5) (reverse (sucesion2 (x+1)))))
     
    grafica        :: [Int] -> IO ()
    grafica xs = plotList [] x
                where x = [aproximacionPi k | k <- xs]
  6. paumacpar
    aproximacionPi :: Int -> Double
    aproximacionPi n = 6*(auxSuma sucesion 0)
      where auxSuma (x:xs) k | k == n = (fromRational x)
                             | otherwise = (fromRational x) + (auxSuma xs (k+1))
     
    sucesion :: [Rational]
    sucesion = [a%b | (a,b) <- zip sucesion1 sucesion2]
      where sucesion1 = 1:aux1 [1,3..] []
              where aux1 (x:xs) ts = product (x:ts): aux1 xs (x:ts)
            sucesion2 = aux2 [1,3..] (1:[2,4..]) []
              where aux2 (x:xs) (y:ys) ts = (2^x)*x*(product (y:ts)): (aux2 xs ys (y:ts))
  7. joscasgom1
     
    aproximacionPi :: Int -> Double
    aproximacionPi n = 6*(aux (0.5) [3,5..] (factores n)) +3
     
    factores n = take n [(product (take s [1,3..]))/(product (take s [2,4..]))| s <- [1..]]
     
     
    aux n (x:xs) (y:ys) = y*(n**x)/x + (aux n xs ys)
    aux n _ [] = 0
     
    grafica        :: [Int] -> IO ()
    grafica xs = plotLists [Key Nothing]
                 [[(x,aproximacionPi x) | x <- xs]]
  8. Juanjo Ortega (juaorture)
    import Graphics.Gnuplot.Simple
     
    aproximacionPi :: Int -> Double
    aproximacionPi n = 6 * ((1/2) + aux 1 2 3)
                   where fI a = fromIntegral a
                         aux x y z | n+1 == y `div` 2 = 0
                                   | otherwise = product [1,3..fI x] / product [2,4..fI y]                                               * (1/2^z /fI z) + aux (x+2) (y+2) (z+2)
     
    grafica :: [Int] -> IO ()
    grafica xs = plotList [Key Nothing] (map aproximacionPi xs)
  9. migibagar
    sucArcSen :: Double -> [Double]
    sucArcSen x = [((product (take n xs)) / (product (take n ys))) * ((x**m) / (m)) |
                       (n,m) <- zip [1..] [3,5..]]
      where xs = [1,3..]
            ys = [2,4..]
     
    arcSen :: Int -> Double -> Double
    arcSen n x = x + (sum $ take n (sucArcSen x))
     
    aproximaPiNewton :: Int -> Double
    aproximaPiNewton n = 6 * arcSen n 0.5
     
    grafica :: [Int] -> IO ()
    grafica xs = plotList [Key Nothing] [(x, aproximaPiNewton 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.