(tabla f ns) escribe en el fichero f las n-ésimas aproximaciones de pi, donde n toma los valores de la lista ns, junto con sus errores. Por ejemplo, al evaluar la expresión
tabla "AproximacionesPi.txt" [0,10..100]
tabla "AproximacionesPi.txt" [0,10..100]
hace que el contenido del fichero “AproximacionesPi.txt” sea
import Text.Printf
-- 1ª solución-- ===========
aproximacionPi ::Int->Double
aproximacionPi n = serieNilakantha !! n
serieNilakantha ::[Double]
serieNilakantha =scanl1(+) terminosNilakantha
terminosNilakantha ::[Double]
terminosNilakantha =zipWith(/) numeradores denominadores
where numeradores =3:cycle[4,-4]
denominadores =1:[n*(n+1)*(n+2)| n <-[2,4..]]-- 2ª solución-- ===========
aproximacionPi2 ::Int->Double
aproximacionPi2 = aux 321where aux x _ _ 0= x
aux x y z m =
aux (x+4/product[y..y+2]*z)(y+2)(negate z)(m-1)-- Comparación de eficiencia-- =========================-- λ> aproximacionPi (2*10^5)-- 3.141592653589787-- (0.82 secs, 145,964,728 bytes)-- λ> aproximacionPi2 (2*10^5)-- 3.141592653589787-- (2.27 secs, 432,463,496 bytes)-- λ> aproximacionPi (3*10^5)-- 3.141592653589787-- (0.34 secs, 73,056,488 bytes)-- λ> aproximacionPi2 (3*10^5)-- 3.141592653589787-- (3.24 secs, 648,603,824 bytes)-- Definicioń de tabla-- ===================
tabla :: FilePath ->[Int]->IO()
tabla f ns =dowriteFile f (tablaAux ns)
tablaAux ::[Int]->String
tablaAux ns =
linea
++ cabecera
++ linea
++concat[printf "| %4d | %.12f | %.12f |\n" n a e
| n <- ns
, let a = aproximacionPi n
, let e =abs(pi- a)]++ linea
linea ::String
linea ="+------+----------------+----------------+\n"
cabecera ::String
cabecera ="| n | Aproximación | Error |\n"
import Text.Printf
-- 1ª solución
-- ===========
aproximacionPi :: Int -> Double
aproximacionPi n = serieNilakantha !! n
serieNilakantha :: [Double]
serieNilakantha = scanl1 (+) terminosNilakantha
terminosNilakantha :: [Double]
terminosNilakantha = zipWith (/) numeradores denominadores
where numeradores = 3 : cycle [4,-4]
denominadores = 1 : [n*(n+1)*(n+2) | n <- [2,4..]]
-- 2ª solución
-- ===========
aproximacionPi2 :: Int -> Double
aproximacionPi2 = aux 3 2 1
where aux x _ _ 0 = x
aux x y z m =
aux (x+4/product[y..y+2]*z) (y+2) (negate z) (m-1)
-- Comparación de eficiencia
-- =========================
-- λ> aproximacionPi (2*10^5)
-- 3.141592653589787
-- (0.82 secs, 145,964,728 bytes)
-- λ> aproximacionPi2 (2*10^5)
-- 3.141592653589787
-- (2.27 secs, 432,463,496 bytes)
-- λ> aproximacionPi (3*10^5)
-- 3.141592653589787
-- (0.34 secs, 73,056,488 bytes)
-- λ> aproximacionPi2 (3*10^5)
-- 3.141592653589787
-- (3.24 secs, 648,603,824 bytes)
-- Definicioń de tabla
-- ===================
tabla :: FilePath -> [Int] -> IO ()
tabla f ns = do
writeFile f (tablaAux ns)
tablaAux :: [Int] -> String
tablaAux ns =
linea
++ cabecera
++ linea
++ concat [printf "| %4d | %.12f | %.12f |\n" n a e
| n <- ns
, let a = aproximacionPi n
, let e = abs (pi - a)]
++ linea
linea :: String
linea = "+------+----------------+----------------+\n"
cabecera :: String
cabecera = "| n | Aproximación | Error |\n"
aproximacionPi ::Int->Double
aproximacionPi n =sum(3:[terminoPi m | m <-[1..n]])where terminoPi m =(-1)^(m+1)*4/(product(take3(drop(2*m-1)[1..])))
tabla :: FilePath ->[Int]->IO()
tabla fichero ns =dolet texto_tabla ="+------+----------------+----------------+n"++"| n | Aproximación | Error |n"++"+------+----------------+----------------+n"++concat["| "++ printf "%4d | %.12f | %.12f |n" n (aproximacionPi n) err
| n <- ns
, let aprox =(aproximacionPi n)
, let err =abs(pi-aprox)]++"+------+----------------+----------------+"writeFile fichero texto_tabla
aproximacionPi :: Int -> Double
aproximacionPi n = sum (3 : [terminoPi m | m <- [1..n]])
where terminoPi m = (-1)^(m+1)*4/(product (take 3 (drop (2*m-1) [1..])))
tabla :: FilePath -> [Int] -> IO ()
tabla fichero ns = do
let texto_tabla =
"+------+----------------+----------------+n" ++
"| n | Aproximación | Error |n" ++
"+------+----------------+----------------+n" ++
concat ["| "
++ printf "%4d | %.12f | %.12f |n" n (aproximacionPi n) err
| n <- ns
, let aprox = (aproximacionPi n)
, let err = abs (pi-aprox)] ++
"+------+----------------+----------------+"
writeFile fichero texto_tabla
aproximacionPi ::Int->Double
aproximacionPi 0=3
aproximacionPi n
|odd n = aproximacionPi (n-1)+ p
|otherwise= aproximacionPi (n-1)- p
where m =fromIntegral n
p =4/(2*m*(2*m+1)*(2*m+2))
aproximacionPi :: Int -> Double
aproximacionPi 0 = 3
aproximacionPi n
| odd n = aproximacionPi (n-1) + p
| otherwise = aproximacionPi (n-1) - p
where m = fromIntegral n
p = 4/(2*m*(2*m+1)*(2*m+2))
Definición de “aproximacionPi” por recursión: