posit-2022.1.0.0: test/TestElementaryFunctions.hs
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Main (main) where
import Data.Int (Int16)
import Posit (Posit, P16, Posit16, AltShow(..), pattern NaR)
import Posit.Internal.PositC
import Graphics.Rendering.Chart.Easy
import Graphics.Rendering.Chart.Backend.Cairo
main :: IO ()
main = do expPlotP16Posit16
logPlotP16Posit16
sqrtPlotsP16Posit16
sinPlotsP16Posit16
cosPlotsP16Posit16
asinPlotsP16Posit16
acosPlotsP16Posit16
atanPlotsP16Posit16
sinhPlotsP16Posit16
coshPlotsP16Posit16
asinhPlotsP16Posit16
acoshPlotsP16Posit16
atanhPlotsP16Posit16
--
expPlotP16Posit16 = toFile def "./test/Results/Bits Accuracy of exp with P16 and Posit16.png" $ do
let expP16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (exp p) exp) | p <- enumFrom (NaR :: P16)]
expPosit16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (exp p) exp) | p <- enumFrom (NaR :: Posit16)]
layout_title .= "Number of Accurate Bits of P16 and Posit16 'exp'"
plot (line "exp P16 error" [expP16])
plot (line "exp Posit16 error" [expPosit16])
logPlotP16Posit16 = toFile def "./test/Results/Bits Accuracy of log with P16 and Posit16.png" $ do
let lnP16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (log p) log) | p <- enumFrom (0 :: P16)]
lnPosit16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (log p) log) | p <- enumFrom (0 :: Posit16)]
layout_title .= "Number of Accurate Bits of P16 and Posit16 'log'"
plot (line "log P16 error" [lnP16])
plot (line "log Posit16 error" [lnPosit16])
sqrtPlotsP16Posit16 = toFile def "./test/Results/Bits Accuracy of sqrt with P16 and Posit16.png" $ do
let sqrtP16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (sqrt p) sqrt) | p <- enumFrom (0 :: P16)]
sqrtPosit16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (sqrt p) sqrt) | p <- enumFrom (0 :: Posit16)]
layout_title .= "Number of Accurate Bits of P16 and Posit16 'sqrt'"
plot (line "sqrt P16 error" [sqrtP16])
plot (line "sqrt Posit16 error" [sqrtPosit16])
sinPlotsP16Posit16 = toFile def "./test/Results/Bits Accuracy of sin with P16 and Posit16.png" $ do
let sineP16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (sin p) sin) | p <- enumFrom (NaR :: P16)]
sinePosit16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (sin p) sin) | p <- enumFrom (NaR :: Posit16)]
layout_title .= "Number of Accurate Bits of P16 and Posit16 'sin'"
plot (line "sin P16 error" [sineP16])
plot (line "sin Posit16 error" [sinePosit16])
cosPlotsP16Posit16 = toFile def "./test/Results/Bits Accuracy of cos with P16 and Posit16.png" $ do
let cosineP16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (cos p) cos) | p <- enumFrom (NaR :: P16)]
cosinePosit16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (cos p) cos) | p <- enumFrom (NaR :: Posit16)]
layout_title .= "Number of Accurate Bits of P16 and Posit16 'cos'"
plot (line "cos P16 error" [cosineP16])
plot (line "cos Posit16 error" [cosinePosit16])
asinPlotsP16Posit16 = toFile def "./test/Results/Bits Accuracy of asin with P16 and Posit16.png" $ do
let arcsineP16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (asin p) sin) | p <- enumFromTo (-1 :: P16) 1]
arcsinePosit16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (asin p) sin) | p <- enumFromTo (-1 :: Posit16) 1]
layout_title .= "Number of Accurate Bits of P16 and Posit16 'asin'"
plot (line "asin P16 error" [arcsineP16])
plot (line "asin Posit16 error" [arcsinePosit16])
acosPlotsP16Posit16 = toFile def "./test/Results/Bits Accuracy of acos with P16 and Posit16.png" $ do
let arccosineP16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (acos p) acos) | p <- enumFromTo (-1 :: P16) 1]
arccosinePosit16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (acos p) acos) | p <- enumFromTo (-1 :: Posit16) 1]
layout_title .= "Number of Accurate Bits of P16 and Posit16 'acos'"
plot (line "acos P16 error" [arccosineP16])
plot (line "acos Posit16 error" [arccosinePosit16])
atanPlotsP16Posit16 = toFile def "./test/Results/Bits Accuracy of atan with P16 and Posit16.png" $ do
let arctangentP16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (atan p) atan) | p <- enumFrom (NaR :: P16)]
arctangentPosit16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (atan p) atan) | p <- enumFrom (NaR :: Posit16)]
layout_title .= "Number of Accurate Bits of P16 and Posit16 'atan'"
plot (line "atan P16 error" [arctangentP16])
plot (line "atan Posit16 error" [arctangentPosit16])
sinhPlotsP16Posit16 = toFile def "./test/Results/Bits Accuracy of sinh with P16 and Posit16.png" $ do
let hypsineP16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (sinh p) sinh) | p <- enumFrom (NaR :: P16)]
hypsinePosit16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (sinh p) sinh) | p <- enumFrom (NaR :: Posit16)]
layout_title .= "Number of Accurate Bits of P16 and Posit16 'sinh'"
plot (line "sinh P16 error" [hypsineP16])
plot (line "sinh Posit16 error" [hypsinePosit16])
coshPlotsP16Posit16 = toFile def "./test/Results/Bits Accuracy of cosh with P16 and Posit16.png" $ do
let hypcosineP16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (cosh p) cosh) | p <- enumFrom (NaR :: P16)]
hypcosinePosit16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (cosh p) cosh) | p <- enumFrom (NaR :: Posit16)]
layout_title .= "Number of Accurate Bits of P16 and Posit16 'cosh'"
plot (line "cosh P16 error" [hypcosineP16])
plot (line "cosh Posit16 error" [hypcosinePosit16])
asinhPlotsP16Posit16 = toFile def "./test/Results/Bits Accuracy of asinh with P16 and Posit16.png" $ do
let archypsineP16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (asinh p) asinh) | p <- enumFrom (NaR :: P16)]
archypsinePosit16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (asinh p) asinh) | p <- enumFrom (NaR :: Posit16)]
layout_title .= "Number of Accurate Bits of P16 and Posit16 'asinh'"
plot (line "asinh P16 error" [archypsineP16])
plot (line "asinh Posit16 error" [archypsinePosit16])
acoshPlotsP16Posit16 = toFile def "./test/Results/Bits Accuracy of acosh with P16 and Posit16.png" $ do
let archypcosineP16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (acosh p) acosh) | p <- enumFrom (NaR :: P16)]
archypcosinePosit16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (acosh p) acosh) | p <- enumFrom (NaR :: Posit16)]
layout_title .= "Number of Accurate Bits of P16 and Posit16 'acosh'"
plot (line "acosh P16 error" [archypcosineP16])
plot (line "acosh Posit16 error" [archypcosinePosit16])
atanhPlotsP16Posit16 = toFile def "./test/Results/Bits Accuracy of atanh with P16 and Posit16.png" $ do
let archyptangentP16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (atanh p) atanh) | p <- enumFrom (NaR :: P16)]
archyptangentPosit16 = filter (\(_,d) -> not $ nanOrInf d) [(read (displayIntegral p) :: Double, err p (atanh p) atanh) | p <- enumFrom (NaR :: Posit16)]
layout_title .= "Number of Accurate Bits of P16 and Posit16 'atanh'"
plot (line "atanh P16 error" [archyptangentP16])
plot (line "atanh Posit16 error" [archyptangentPosit16])
err :: PositC es => Posit es -> Posit es -> (Double -> Double) -> Double
err NaR _ _ = 0 / 0
err _ NaR _ = 0 / 0
err p fp f =
let pDouble :: Double = fromRational.toRational $ p
fpDouble :: Double = fromRational.toRational $ fp
nBitsError = (negate.log.abs $ f pDouble - fpDouble) / log 2
in max nBitsError 0
nanOrInf :: Double -> Bool
nanOrInf d = isNaN d || isInfinite d