{-# LANGUAGE LambdaCase, ScopedTypeVariables, BangPatterns #-} {- Copyright 2013 Ken Takusagawa This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . -} module Main where { import System.Environment(getArgs); logistic_chaos :: Double -> Double; logistic_chaos x = 3.57 * x * (1-x); strict_chaos :: Double -> Double; strict_chaos !x = 3.57 * x * (1-x); result :: Double; result = iterateN 1000000000 logistic_chaos 0.5; go :: (Int -> (Double -> Double) -> Double -> Double) -> (IO ()); go f = print $ f 1000000000 logistic_chaos 0.5; -- fastest iterateN :: Int -> (a -> a) -> a -> a; iterateN = iterateN_5; iterateN_1 :: Int -> (a -> a) -> a -> a; iterateN_1 n f start = (iterate f start) !! n; iterateN_2 :: Int -> (a -> a) -> (a -> a); iterateN_2 n f = last . (take (1+n)) . (iterate f); iterateN_3 :: Int -> (a -> a) -> a -> a; iterateN_3 n f start = let { seq_iterate :: (a -> a) -> a -> [a]; seq_iterate f start = start : (seq start (seq_iterate f (f start))) } in (seq_iterate f start) !! n; iterateN_4 :: Int -> (a -> a) -> a -> a; iterateN_4 n f start = let { seq_iterate :: (a -> a) -> a -> [a]; seq_iterate f start = seq start (start : (seq_iterate f (f start))) } in (seq_iterate f start) !! n; iterateN_5 :: forall a.Int -> (a -> a) -> a -> a; iterateN_5 n f start = let { seq_iterate :: a -> [a]; seq_iterate start = start : (seq start (seq_iterate (f start))) } in (seq_iterate start) !! n; iterateN_6 :: forall a.Int -> (a -> a) -> a -> a; iterateN_6 n f start = let { seq_iterate :: a -> [a]; seq_iterate start = seq start (start : (seq_iterate (f start))) } in (seq_iterate start) !! n; iterateN_7 :: Int -> (a -> a) -> a -> a; iterateN_7 n f start = case (compare n 0) of { LT -> error "cannot iterate less than zero"; EQ -> start; GT -> seq start (iterateN_7 (pred n) f (f start)) }; iterateN_Integer :: Integer -> (a -> a) -> a -> a; iterateN_Integer n f start = case (compare n 0) of { LT -> error "cannot iterate less than zero"; EQ -> start; GT -> seq start (iterateN_Integer (pred n) f (f start)) }; -- main = print result; main :: (IO ()); main = (getArgs >>= (\case { ["1"] -> (go iterateN_1); ["2"] -> (go iterateN_2); ["3"] -> (go iterateN_3); ["4"] -> (go iterateN_4); ["5"] -> (go iterateN_5); ["6"] -> (go iterateN_6); ["7"] -> (go iterateN_7); ["8"] -> print $ (iterate strict_chaos 0.5) !! 1000000000; ["9"] -> (print (iterateN_Integer 1000000000 logistic_chaos 0.5)); _ -> (error "need number") })) } -- see also logisticc.cpp for c++ version which is twice as fast.