module Numeric.Probability.Percentage where
import qualified Numeric.Probability.Distribution as Dist
import qualified Numeric.Probability.Random as Rnd
import Numeric.Probability.Show (showR)
import Numeric.Probability.Trace (Trace)
import Data.List.HT (padLeft)
import Data.Tuple.HT (mapFst)
import qualified System.Random as Random
newtype T = Cons Float
deriving (Eq, Ord)
percent :: Float -> T
percent x = Cons (x/100)
showPfix :: (RealFrac prob, Show prob) => Int -> prob -> String
showPfix precision x =
if precision==0
then showR 3 (round (x*100) :: Integer) ++ "%"
else
let str =
padLeft '0' (precision+1)
(show (round (x*10^(precision+2)) :: Integer))
(int,frac) =
splitAt (length str - precision) str
in padLeft ' ' 3 int ++ '.' : frac ++ "%"
{-# DEPRECATED roundRel "was used to implemented showPfix, but is no longer needed for this purpose, and should not be exported anyway, and does not contribute to a safe way to format fixed point values, because the rounded value may not be accurate" #-}
roundRel :: (RealFrac a) => Int -> a -> a
roundRel p x =
let d = 10^p
in fromIntegral (round (x*d) :: Integer)/d
instance Show T where
show (Cons p) = showPfix 1 p
infix 0 //
(//) :: (Ord a, Show a) => Dist a -> Int -> IO ()
(//) x prec = putStr (Dist.pretty (\(Cons p) -> showPfix prec p) x)
(//*) :: (Ord a, Show a) => Dist a -> (Int,Int) -> IO ()
(//*) x (prec,width) = putStr $ flip Dist.pretty x $
\(Cons p) ->
showPfix prec p ++ " " ++
replicate (round (p * fromIntegral width)) '*'
liftP :: (Float -> Float) -> T -> T
liftP f (Cons x) = Cons (f x)
liftP2 :: (Float -> Float -> Float) -> T -> T -> T
liftP2 f (Cons x) (Cons y) = Cons (f x y)
instance Num T where
fromInteger = Cons . fromInteger
(+) = liftP2 (+)
(-) = liftP2 (-)
(*) = liftP2 (*)
abs = liftP abs
signum = liftP signum
negate = liftP negate
instance Fractional T where
fromRational = Cons . fromRational
recip = liftP recip
(/) = liftP2 (/)
instance Floating T where
pi = Cons pi
exp = liftP exp
sqrt = liftP sqrt
log = liftP log
(**) = liftP2 (**)
logBase = liftP2 logBase
sin = liftP sin
tan = liftP tan
cos = liftP cos
asin = liftP asin
atan = liftP atan
acos = liftP acos
sinh = liftP sinh
tanh = liftP tanh
cosh = liftP cosh
asinh = liftP asinh
atanh = liftP atanh
acosh = liftP acosh
instance Random.Random T where
randomR (Cons l, Cons r) = mapFst Cons . Random.randomR (l,r)
random = mapFst Cons . Random.random
type Dist a = Dist.T T a
type Spread a = [a] -> Dist a
type RDist a = Rnd.T (Dist a)
type Trans a = a -> Dist a
type Space a = Trace (Dist a)
type Expand a = a -> Space a
type RTrans a = a -> RDist a
type RSpace a = Rnd.T (Space a)
type RExpand a = a -> RSpace a