{"id":7106,"date":"2022-06-30T06:00:33","date_gmt":"2022-06-30T04:00:33","guid":{"rendered":"http:\/\/www.glc.us.es\/~jalonso\/exercitium\/?p=7106"},"modified":"2022-07-02T08:51:01","modified_gmt":"2022-07-02T06:51:01","slug":"aproximacion-del-numero-pi","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/aproximacion-del-numero-pi\/","title":{"rendered":"Aproximaci\u00f3n del n\u00famero pi"},"content":{"rendered":"<p>Una forma de aproximar el n\u00famero \u03c0 es usando la siguiente igualdad:<\/p>\n<pre lang=\"text\">\n    \u03c0         1     1\u00b72     1\u00b72\u00b73     1\u00b72\u00b73\u00b74     \n   --- = 1 + --- + ----- + ------- + --------- + ....\n    2         3     3\u00b75     3\u00b75\u00b77     3\u00b75\u00b77\u00b79\n<\/pre>\n<p>Es decir, la serie cuyo t\u00e9rmino general n-\u00e9simo es el cociente entre el producto de los primeros n n\u00fameros y los primeros n n\u00fameros impares:<\/p>\n<pre lang=\"text\">\n               \u03a0 i   \n   s(n) =  -----------\n            \u03a0 (2*i+1)\n<\/pre>\n<p>Definir la funci\u00f3n<\/p>\n<pre lang=\"text\">\n   aproximaPi :: Integer -> Double\n<\/pre>\n<p>tal que (aproximaPi n) es la aproximaci\u00f3n del n\u00famero \u03c0 calculada con la serie anterior hasta el t\u00e9rmino n-\u00e9simo. Por ejemplo,<\/p>\n<pre lang=\"text\">\n   aproximaPi 10     == 3.1411060206\n   aproximaPi 20     == 3.1415922987403397\n   aproximaPi 30     == 3.1415926533011596\n   aproximaPi 40     == 3.1415926535895466\n   aproximaPi 50     == 3.141592653589793\n   aproximaPi (10^4) == 3.141592653589793\n   pi                == 3.141592653589793\n<\/pre>\n<h4>Soluciones<\/h4>\n<pre lang=\"haskell\">\nimport Data.Ratio ((%))\nimport Data.List (genericTake)\nimport Test.QuickCheck (Property, arbitrary, forAll, suchThat, quickCheck)\n\n-- 1\u00aa soluci\u00f3n\n-- ===========\n\naproximaPi1 :: Integer -> Double\naproximaPi1 n = \n  fromRational (2 * sum [product [1..i] % product [1,3..2*i+1] | i <- [0..n]])\n\n-- 2\u00aa soluci\u00f3n\n-- ===========\n\naproximaPi2 :: Integer -> Double\naproximaPi2 0 = 2\naproximaPi2 n = \n  aproximaPi2 (n-1) + fromRational (2 * product [1..n] % product [3,5..2*n+1])\n\n-- 3\u00aa soluci\u00f3n\n-- ===========\n\naproximaPi3 :: Integer -> Double\naproximaPi3 n = \n  fromRational (2 * (1 + sum (zipWith (%) numeradores (genericTake n denominadores))))\n\n-- numeradores es la sucesi\u00f3n de los numeradores. Por ejemplo,\n--    \u03bb> take 10 numeradores\n--    [1,2,6,24,120,720,5040,40320,362880,3628800]\nnumeradores :: [Integer]\nnumeradores = scanl (*) 1 [2..]\n\n-- denominadores es la sucesi\u00f3n de los denominadores. Por ejemplo,\n--    \u03bb> take 10 denominadores\n--    [3,15,105,945,10395,135135,2027025,34459425,654729075,13749310575]\ndenominadores :: [Integer]\ndenominadores = scanl (*) 3 [5, 7..]\n \n-- 4\u00aa soluci\u00f3n\n-- ===========\n\naproximaPi4 :: Integer -> Double\naproximaPi4 n = \n  read (x : \".\" ++ xs)\n  where (x:xs) = show (aproximaPi4' n)\n\naproximaPi4' :: Integer -> Integer\naproximaPi4' n = \n  2 * (p + sum (zipWith div (map (*p) numeradores) (genericTake n denominadores))) \n  where p = 10^n\n\n-- Comprobaci\u00f3n de equivalencia\n-- ============================\n\n-- La propiedad es\nprop_aproximaPi :: Property\nprop_aproximaPi =\n  forAll (arbitrary `suchThat` (> 3)) $ \\n ->\n  all (=~ aproximaPi1 n)\n      [aproximaPi2 n,\n       aproximaPi3 n,\n       aproximaPi4 n]\n\n(=~) :: Double -> Double -> Bool\nx =~ y = abs (x - y) < 0.001\n\n-- La comprobaci\u00f3n es\n--    \u03bb> quickCheck prop_aproximaPi\n--    +++ OK, passed 100 tests.\n\n-- Comparaci\u00f3n de eficiencia\n-- =========================\n\n-- La comparaci\u00f3n es\n--    \u03bb> aproximaPi1 3000 \n--    3.141592653589793\n--    (4.96 secs, 27,681,824,408 bytes)\n--    \u03bb> aproximaPi2 3000 \n--    3.1415926535897922\n--    (3.00 secs, 20,496,194,496 bytes)\n--    \u03bb> aproximaPi3 3000 \n--    3.141592653589793\n--    (3.13 secs, 13,439,528,432 bytes)\n--    \u03bb> aproximaPi4 3000 \n--    3.141592653589793\n--    (0.09 secs, 23,142,144 bytes)\n<\/pre>\n<p>El c\u00f3digo se encuentra en <a href=\"https:\/\/github.com\/jaalonso\/Exercitium\/blob\/main\/src\/Aproximacion_de_numero_pi.hs\">GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Una forma de aproximar el n\u00famero \u03c0 es usando la siguiente igualdad: \u03c0 1 1\u00b72 1\u00b72\u00b73 1\u00b72\u00b73\u00b74 &#8212; = 1 + &#8212; + &#8212;&#8211; + &#8212;&#8212;- + &#8212;&#8212;&#8212; + &#8230;. 2 3 3\u00b75 3\u00b75\u00b77 3\u00b75\u00b77\u00b79 Es decir, la serie cuyo t\u00e9rmino general n-\u00e9simo es el cociente entre el producto de los primeros n n\u00fameros y&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false},"categories":[2],"tags":[580,579],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/7106"}],"collection":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/comments?post=7106"}],"version-history":[{"count":2,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/7106\/revisions"}],"predecessor-version":[{"id":7125,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/posts\/7106\/revisions\/7125"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/media?parent=7106"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/categories?post=7106"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/exercitium\/wp-json\/wp\/v2\/tags?post=7106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}