--------------------------------------------------------------------------------------------
--   Posit Numbers
--   Copyright   :  (C) 2022 Nathan Waivio
--   License     :  BSD3
--   Maintainer  :  Nathan Waivio <nathan.waivio@gmail.com>
--   Stability   :  Stable
--   Portability :  Portable
--
-- | Library implementing standard Posit Numbers (Posit Standard version
--   3.2, with some improvements) a fixed width word size of
--   2^es bytes.
-- 
---------------------------------------------------------------------------------------------


{-# LANGUAGE GADTs #-} --   For our main type Posit (es :: ES)
{-# LANGUAGE DataKinds #-}  --   For our ES kind and the constructors Z, I, II, III, IV, V for exponent size type
{-# LANGUAGE KindSignatures #-}  --   For defining the type of kind ES that indexes the GADT
{-# LANGUAGE ViewPatterns #-}  --   To decode the posit in the pattern
{-# LANGUAGE BangPatterns #-}  --   Added Strictness for some fixed point algorithms
{-# LANGUAGE PatternSynonyms #-}  --   for a nice NaR interface
{-# LANGUAGE FlexibleInstances #-} --   To make instances for each specific type [Posit8 .. Posit256]
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeApplications #-} --   To apply types: @Type, it seems to select the specific class instance, when GHC is not able to reason about things, commenting this out shows an interesting interface
{-# LANGUAGE MultiParamTypeClasses #-}  --   To convert between Posit Types
{-# LANGUAGE ScopedTypeVariables #-} --   To reduce some code duplication
{-# LANGUAGE UndecidableInstances #-}  --   To reduce some code duplication, I think the code is decidable but GHC is not smart enough ;), like there being only 1 instance that is polymorphic and works for all of my types.
{-# LANGUAGE CPP #-} --   To remove Storable instances to remove noise when performing analysis of Core
{-# OPTIONS_GHC -Wno-unticked-promoted-constructors #-}  --   Turn off noise
{-# OPTIONS_GHC -Wno-type-defaults #-}  --   Turn off noise
{-# OPTIONS_GHC -Wno-unused-top-binds #-}  --   Turn off noise


-- ----
--  Posit numbers implementing:
--
--    * Show
--    * Eq
--    * Ord  -- compare as an integer representation
--    * Num  -- Addition, subtraction, multiplication, and other operations
--    * Enum  -- Successor and Predecessor
--    * Fractional  -- division, divide by zero is Not a Real (NaR) number
--    * Real
--    * Bounded
--    * FusedOps  -- dot product and others
--    * Convertible  -- Conversions between different posit formats
--    * AltShow
--    * Read
--    * Storable  -- Formats for binary data, for computation and data interchange
--    * RealFrac
--    * RealFloat
--    * Floating  -- Mathematical functions such as logarithm, exponential, trigonometric, and hyperbolic functions. Warning! May induce trance.
--
-- ----

module Posit
(Posit(),
 -- * Main Exported Types
 Posit8, -- |An 8-bit Posit number with 'es' ~ 'Z'
 Posit16, -- |An 16-bit Posit number with 'es' ~ 'I'
 Posit32, -- |An 32-bit Posit number with 'es' ~ 'II'
 Posit64, -- |An 64-bit Posit number with 'es' ~ 'III'
 Posit128, -- |An 128-bit Posit number with 'es' ~ 'IV'
 Posit256, -- |An 256-bit Posit number with 'es' ~ 'V'
 
 -- * Patterns for Matching Exported Types
 pattern NaR,  -- |A pattern for Exception handling when a value is Not a Real number (NaR).
 pattern R,  -- |A pattern for the non-Exceptional case, yielding a Rational, will make a total function when paired with NaR, if the Rational implementation is total.
 
 -- * Fused Operation Interface defined by the Posit Standard
 FusedOps(..),
 
 -- * Posits are Convertable between different Posit representations
 Convertible(..),
 
#ifndef O_NO_SHOW
 -- * Additional functions to show the Posit in different formats
 AltShow(..),
#endif
 
 -- * Additional Special Functions
 AltFloating(..),
 
 -- * Functions to lift functions of Integers or Rationals to operate on Posit Types
 viaIntegral,
 viaRational,
 viaRational2,
 viaRational3,
 viaRational4,
 viaRational6,
 viaRational8,
 
#ifdef O_TEST
 -- * Alternative algorithms for test purposes
 funExp,
 funExp2,
 funExpTaylor,
 funLogTaylor,
 funExpTuma,
 funGammaSeriesFused,
 funGammaRamanujan,
 funGammaCalc,
 funGammaNemes,
 funGammaYang,
 funGammaChen,
 funGammaXminus1,
 funLogTuma,
 funLogDomainReduction,
 funPi1,
 funPi2,
 funPi3,
 funPi4,
 funPi5,
 funPi6,
 funPsiSha1,
 funPsiSha2,
 funPsiSha3
#endif

 ) where


import Prelude hiding (rem)

-- Imports for Show and Read Instances
import Data.Scientific (scientificP
                       ,fromRationalRepetendUnlimited
                       ,formatScientific
                       ,FPFormat(Generic)) -- Used to print/show and read the rational value

import Text.Read (Lexeme(Ident)
                 ,readPrec
                 ,readListPrec
                 ,(+++)
                 ,pfail
                 ,readListPrecDefault
                 ,lexP
                 ,lift
                 ,parens) -- Used to read a Posit value

-- Imports for Vectorization Class Instances
import Data.Foldable (toList)  -- Used for fused operations on foldable/lists

-- Imports for Storable Instance
import Foreign.Storable (Storable, sizeOf, alignment, peek, poke)  -- Used for Storable Instances of Posit
import Foreign.Ptr (Ptr, castPtr)  -- Used for dealing with Pointers for the Posit Storable Instance


-- would like to:
-- import Posit.Internal.ElementaryFunctions
-- Perhaps on the chopping block if we are moving to ElementaryFunctions
-- Imports for implementing the Transcendental Functions
import GHC.Natural (Natural) -- Import the Natural Numbers ℕ (u+2115) for some of the Transcendental Functions
import Data.Ratio ((%))  -- Import the Rational Numbers ℚ (u+211A), ℚ can get arbitrarily close to Real numbers ℝ (u+211D), used for some of the Transcendental Functions

-- for NFData instance
import Control.DeepSeq (NFData, rnf)

import Debug.Trace (trace) -- temporary for debug purposes


-- =====================================================================
-- ===                  Posit Implementation                         ===
-- =====================================================================

-- The machine implementation of the Posit encoding/decoding
import Posit.Internal.PositC  -- The main internal implementation details


-- |Base GADT rapper type, that uses the Exponent Size kind to index the various implementations
data Posit (es :: ES) where
     Posit :: PositC es => !(IntN es) -> Posit es

-- |NFData Instance
instance NFData (Posit es) where
  rnf :: Posit es -> ()
rnf (Posit IntN es
_) = ()

-- |Not a Real Number, the Posit is like a Maybe type, it's either a real number or not
pattern NaR :: forall es. PositC es => Posit es
pattern $bNaR :: forall (es :: ES). PositC es => Posit es
$mNaR :: forall {r} {es :: ES}.
PositC es =>
Posit es -> ((# #) -> r) -> ((# #) -> r) -> r
NaR <- (Posit (decode @es -> Nothing)) where
  NaR = forall (es :: ES). PositC es => IntN es -> Posit es
Posit (forall (es :: ES). PositC es => IntN es
unReal @es)
--

--
-- |A Real or at least Rational Number, rounded to the nearest Posit Rational representation
pattern R :: forall es. PositC es => Rational -> Posit es
pattern $bR :: forall (es :: ES). PositC es => Rational -> Posit es
$mR :: forall {r} {es :: ES}.
PositC es =>
Posit es -> (Rational -> r) -> ((# #) -> r) -> r
R r <- (Posit (decode @es -> Just r)) where
  R Rational
r = forall (es :: ES). PositC es => IntN es -> Posit es
Posit (forall (es :: ES). PositC es => Maybe Rational -> IntN es
encode @es forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just Rational
r)
--

-- Posit functions are complete if the following two patterns are completely defined.
{-# COMPLETE NaR, R #-}

-- Concrete types exported for use.
type Posit8 = Posit Z
type Posit16 = Posit I
type Posit32 = Posit II
type Posit64 = Posit III
type Posit128 = Posit IV
type Posit256 = Posit V

#ifndef O_NO_SHOW
-- Show
--
instance PositC es => Show (Posit es) where
  show :: Posit es -> String
show Posit es
NaR = String
"NaR"
  show (R Rational
r) = FPFormat -> Maybe Int -> Scientific -> String
formatScientific FPFormat
Generic (forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall (es :: ES). PositC es => Int
decimalPrec @es) (forall a b. (a, b) -> a
fstforall b c a. (b -> c) -> (a -> b) -> a -> c
.Rational -> (Scientific, Maybe Int)
fromRationalRepetendUnlimited forall a b. (a -> b) -> a -> b
$ Rational
r)
--
#endif



-- Two Posit Numbers are Equal if their Finite Precision Integer representation is Equal
--
-- All things equal I would rather write it like this:
instance PositC es => Eq (Posit es) where
  (Posit IntN es
int1) == :: Posit es -> Posit es -> Bool
== (Posit IntN es
int2) = IntN es
int1 forall a. Eq a => a -> a -> Bool
== IntN es
int2
--



-- Two Posit Numbers are ordered by their Finite Precision Integer representation
--
-- Ordinarily I would only like one instance to cover them all
instance PositC es => Ord (Posit es) where
  compare :: Posit es -> Posit es -> Ordering
compare (Posit IntN es
int1) (Posit IntN es
int2) = forall a. Ord a => a -> a -> Ordering
compare IntN es
int1 IntN es
int2
--



-- Num
--
-- I'm num trying to get this definition:
instance PositC es => Num (Posit es) where
  -- Addition
  + :: Posit es -> Posit es -> Posit es
(+) = forall (es :: ES).
PositC es =>
(Rational -> Rational -> Rational)
-> Posit es -> Posit es -> Posit es
viaRational2 forall a. Num a => a -> a -> a
(+)
  -- Multiplication
  * :: Posit es -> Posit es -> Posit es
(*) = forall (es :: ES).
PositC es =>
(Rational -> Rational -> Rational)
-> Posit es -> Posit es -> Posit es
viaRational2 forall a. Num a => a -> a -> a
(*)
  -- 'abs', Absolute Value, it's like a magnitude of sorts, abs of a posit is the same as abs of the integer representation
  abs :: Posit es -> Posit es
abs = forall (es :: ES).
PositC es =>
(IntN es -> IntN es) -> Posit es -> Posit es
viaIntegral forall a. Num a => a -> a
abs
  -- 'signum' it is a kind of an representation of directionality, the sign of a number for instance
  signum :: Posit es -> Posit es
signum = forall (es :: ES).
PositC es =>
(Rational -> Rational) -> Posit es -> Posit es
viaRational forall a. Num a => a -> a
signum
  -- 'fromInteger' rounds the integer into the closest posit number
  fromInteger :: Integer -> Posit es
fromInteger Integer
int = forall (es :: ES). PositC es => Rational -> Posit es
R forall a b. (a -> b) -> a -> b
$ forall a. Num a => Integer -> a
fromInteger Integer
int
  -- 'negate', Negates the sign of the directionality. negate of a posit is the same as negate of the integer representation
  negate :: Posit es -> Posit es
negate = forall (es :: ES).
PositC es =>
(IntN es -> IntN es) -> Posit es -> Posit es
viaIntegral forall a. Num a => a -> a
negate
--

-- deriving via Integral Class, for the Integral representation of the posit
viaIntegral :: PositC es => (IntN es -> IntN es) -> Posit es -> Posit es
viaIntegral :: forall (es :: ES).
PositC es =>
(IntN es -> IntN es) -> Posit es -> Posit es
viaIntegral IntN es -> IntN es
f (Posit IntN es
int) = forall (es :: ES). PositC es => IntN es -> Posit es
Posit forall a b. (a -> b) -> a -> b
$ IntN es -> IntN es
f IntN es
int
--



-- Enum-ish, A Posit has a Successor and Predecessor so its an ordinal number, as per Posit standard next, prior
-- The Posit Standard requires 2's complement integer overflow to be ignored
instance PositC es => Enum (Posit es) where
  -- succ (Posit int) = Posit (int + 1)
  succ :: Posit es -> Posit es
succ = forall (es :: ES).
PositC es =>
(IntN es -> IntN es) -> Posit es -> Posit es
viaIntegral (forall a. Num a => a -> a -> a
+IntN es
1)
  -- succ = viaIntegral succ  -- Non-compliant, runtime error pred NaR, and worse it is Int64 for types of greater precision, probably because of Preludes gross abomination of toEnum/fromEnum
  -- pred (Posit int) = Posit (int - 1)
  pred :: Posit es -> Posit es
pred = forall (es :: ES).
PositC es =>
(IntN es -> IntN es) -> Posit es -> Posit es
viaIntegral (forall a. Num a => a -> a -> a
subtract IntN es
1)
  -- pred = viaIntegral pred  -- Non-compliant, runtime error pred NaR, and worse it is Int64 for types of greater precision, probably because of Preludes gross abomination of toEnum/fromEnum
  -- enumFrom :: Posit es -> [Posit es]
  enumFrom :: Posit es -> [Posit es]
enumFrom Posit es
n = forall a. Enum a => a -> a -> [a]
enumFromTo Posit es
n forall a. Bounded a => a
maxBound
  enumFromTo :: Posit es -> Posit es -> [Posit es]
enumFromTo Posit es
n Posit es
m
    | Posit es
n forall a. Eq a => a -> a -> Bool
== Posit es
m = [Posit es
n]
    | Posit es
n forall a. Ord a => a -> a -> Bool
< Posit es
m = Posit es
n forall a. a -> [a] -> [a]
: forall a. Enum a => a -> a -> [a]
enumFromTo (forall a. Enum a => a -> a
succ Posit es
n) Posit es
m
    | Bool
otherwise = []
  -- enumFromThen n m :: Posit es -> Posit es -> [Posit es]
  enumFromThen :: Posit es -> Posit es -> [Posit es]
enumFromThen Posit es
NaR Posit es
_ = [forall (es :: ES). PositC es => Posit es
NaR]
  enumFromThen Posit es
_ Posit es
NaR = [forall (es :: ES). PositC es => Posit es
NaR]
  enumFromThen Posit es
n Posit es
m = Posit es
n forall a. a -> [a] -> [a]
: Posit es -> [Posit es]
go Posit es
n
    where
      step :: Posit es
step = Posit es
m forall a. Num a => a -> a -> a
- Posit es
n
      go :: Posit es -> [Posit es]
      go :: Posit es -> [Posit es]
go Posit es
NaR = [forall (es :: ES). PositC es => Posit es
NaR]
      go !Posit es
l = case forall a. Ord a => a -> a -> Ordering
compare Posit es
step Posit es
0 of
                Ordering
LT -> let !n' :: Posit es
n' = Posit es
l forall a. Num a => a -> a -> a
+ Posit es
step  -- rounding occurs here, because the next comparison needs it, it wouldn't make sense otherwise...
                      in if Posit es
n' forall a. Num a => a -> a -> a
- Posit es
l forall a. Ord a => a -> a -> Bool
> Posit es
step
                         then []
                         else Posit es
n' forall a. a -> [a] -> [a]
: Posit es -> [Posit es]
go Posit es
n'
                Ordering
EQ -> [Posit es
n, Posit es
m]
                Ordering
GT -> let !n' :: Posit es
n' = Posit es
l forall a. Num a => a -> a -> a
+ Posit es
step
                      in if Posit es
n' forall a. Num a => a -> a -> a
- Posit es
l forall a. Ord a => a -> a -> Bool
< Posit es
step
                         then []  -- with tapered resolution this algorithm can reach a fixed point where the next value is equal to the previous value
                         else Posit es
n' forall a. a -> [a] -> [a]
: Posit es -> [Posit es]
go Posit es
n'
  enumFromThenTo :: Posit es -> Posit es -> Posit es -> [Posit es]
enumFromThenTo Posit es
NaR  Posit es
_   Posit es
_  = [forall (es :: ES). PositC es => Posit es
NaR]
  enumFromThenTo  Posit es
_  Posit es
NaR  Posit es
_  = [forall (es :: ES). PositC es => Posit es
NaR]
  enumFromThenTo  Posit es
_   Posit es
_  Posit es
NaR = [forall (es :: ES). PositC es => Posit es
NaR]
  enumFromThenTo  Posit es
e1  Posit es
e2  Posit es
e3 = forall a. (a -> Bool) -> [a] -> [a]
takeWhile Posit es -> Bool
predicate (forall a. Enum a => a -> a -> [a]
enumFromThen Posit es
e1 Posit es
e2)
    where
      mid :: Posit es
mid = (Posit es
e2 forall a. Num a => a -> a -> a
- Posit es
e1) forall a. Fractional a => a -> a -> a
/ Posit es
2
      predicate :: Posit es -> Bool
predicate | Posit es
e2 forall a. Ord a => a -> a -> Bool
>= Posit es
e1  = (forall a. Ord a => a -> a -> Bool
<= Posit es
e3 forall a. Num a => a -> a -> a
+ Posit es
mid)
                | Bool
otherwise = (forall a. Ord a => a -> a -> Bool
>= Posit es
e3 forall a. Num a => a -> a -> a
+ Posit es
mid)
--



-- Fractional Instances; (Num => Fractional)
--
-- How the Frac do I get this definition:
instance PositC es => Fractional (Posit es) where
  fromRational :: Rational -> Posit es
fromRational = forall (es :: ES). PositC es => Rational -> Posit es
R
 
  recip :: Posit es -> Posit es
recip Posit es
0 = forall (es :: ES). PositC es => Posit es
NaR
  recip Posit es
p = forall (es :: ES).
PositC es =>
(Rational -> Rational) -> Posit es -> Posit es
viaRational forall a. Fractional a => a -> a
recip Posit es
p
--

-- Rational Instances; Num & Ord Instanced => Real
--
-- I for real want this definition:
instance PositC es => Real (Posit es) where
  toRational :: Posit es -> Rational
toRational Posit es
NaR = forall a. HasCallStack => String -> a
error String
"Your input is Not a Real or Rational (NaR) number, please try again!"
  toRational (R Rational
r) = Rational
r
--

-- Implementing instances via Rational Data Type's instance,
-- The function checks for NaR, to protect against the runtime error 'toRational' would generate if called with a NaR value
-- Unary::Arity NaR guarded pass through with wrapping and unwrapping use of a Rational function
viaRational :: PositC es => (Rational -> Rational) -> Posit es -> Posit es
viaRational :: forall (es :: ES).
PositC es =>
(Rational -> Rational) -> Posit es -> Posit es
viaRational Rational -> Rational
_ Posit es
NaR = forall (es :: ES). PositC es => Posit es
NaR
viaRational Rational -> Rational
f (R Rational
r) = forall a. Fractional a => Rational -> a
fromRational forall a b. (a -> b) -> a -> b
$ Rational -> Rational
f Rational
r

-- Binary NaR guarded pass through with wrapping and unwrapping use of a Rational function
viaRational2 :: PositC es => (Rational -> Rational -> Rational) -> Posit es -> Posit es -> Posit es
viaRational2 :: forall (es :: ES).
PositC es =>
(Rational -> Rational -> Rational)
-> Posit es -> Posit es -> Posit es
viaRational2 Rational -> Rational -> Rational
_ Posit es
NaR  Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational2 Rational -> Rational -> Rational
_  Posit es
_  Posit es
NaR = forall (es :: ES). PositC es => Posit es
NaR
viaRational2 Rational -> Rational -> Rational
f (R Rational
r1) (R Rational
r2) = forall (es :: ES). PositC es => Rational -> Posit es
R forall a b. (a -> b) -> a -> b
$ Rational
r1 Rational -> Rational -> Rational
`f` Rational
r2

-- Ternary NaR guarded pass through with wrapping and unwrapping use of a Rational function
viaRational3 :: PositC es => (Rational -> Rational -> Rational -> Rational) -> Posit es -> Posit es -> Posit es -> Posit es
viaRational3 :: forall (es :: ES).
PositC es =>
(Rational -> Rational -> Rational -> Rational)
-> Posit es -> Posit es -> Posit es -> Posit es
viaRational3 Rational -> Rational -> Rational -> Rational
_ Posit es
NaR  Posit es
_   Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational3 Rational -> Rational -> Rational -> Rational
_  Posit es
_  Posit es
NaR  Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational3 Rational -> Rational -> Rational -> Rational
_  Posit es
_   Posit es
_  Posit es
NaR = forall (es :: ES). PositC es => Posit es
NaR
viaRational3 Rational -> Rational -> Rational -> Rational
f (R Rational
r1) (R Rational
r2) (R Rational
r3) = forall (es :: ES). PositC es => Rational -> Posit es
R forall a b. (a -> b) -> a -> b
$ Rational -> Rational -> Rational -> Rational
f Rational
r1 Rational
r2 Rational
r3

-- Quaternary NaR guarded pass through with wrapping and unwrapping use of a Rational function
viaRational4 :: PositC es => (Rational -> Rational -> Rational -> Rational -> Rational) -> Posit es -> Posit es -> Posit es -> Posit es -> Posit es
viaRational4 :: forall (es :: ES).
PositC es =>
(Rational -> Rational -> Rational -> Rational -> Rational)
-> Posit es -> Posit es -> Posit es -> Posit es -> Posit es
viaRational4 Rational -> Rational -> Rational -> Rational -> Rational
_ Posit es
NaR  Posit es
_   Posit es
_   Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational4 Rational -> Rational -> Rational -> Rational -> Rational
_  Posit es
_  Posit es
NaR  Posit es
_   Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational4 Rational -> Rational -> Rational -> Rational -> Rational
_  Posit es
_   Posit es
_  Posit es
NaR  Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational4 Rational -> Rational -> Rational -> Rational -> Rational
_  Posit es
_   Posit es
_   Posit es
_  Posit es
NaR = forall (es :: ES). PositC es => Posit es
NaR
viaRational4 Rational -> Rational -> Rational -> Rational -> Rational
f (R Rational
r0) (R Rational
r1) (R Rational
r2) (R Rational
r3) = forall (es :: ES). PositC es => Rational -> Posit es
R forall a b. (a -> b) -> a -> b
$ Rational -> Rational -> Rational -> Rational -> Rational
f Rational
r0 Rational
r1 Rational
r2 Rational
r3

-- Senary NaR guarded pass through with wrapping and unwrapping use of a Rational function
viaRational6 :: PositC es => (Rational -> Rational -> Rational -> Rational -> Rational -> Rational -> Rational) -> Posit es -> Posit es -> Posit es -> Posit es -> Posit es -> Posit es -> Posit es
viaRational6 :: forall (es :: ES).
PositC es =>
(Rational
 -> Rational
 -> Rational
 -> Rational
 -> Rational
 -> Rational
 -> Rational)
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
viaRational6 Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
_ Posit es
NaR  Posit es
_   Posit es
_   Posit es
_   Posit es
_   Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational6 Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
_  Posit es
_  Posit es
NaR  Posit es
_   Posit es
_   Posit es
_   Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational6 Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
_  Posit es
_   Posit es
_  Posit es
NaR  Posit es
_   Posit es
_   Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational6 Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
_  Posit es
_   Posit es
_   Posit es
_  Posit es
NaR  Posit es
_   Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational6 Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
_  Posit es
_   Posit es
_   Posit es
_   Posit es
_  Posit es
NaR  Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational6 Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
_  Posit es
_   Posit es
_   Posit es
_   Posit es
_   Posit es
_  Posit es
NaR = forall (es :: ES). PositC es => Posit es
NaR
viaRational6 Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
f (R Rational
a1) (R Rational
a2) (R Rational
a3) (R Rational
b1) (R Rational
b2) (R Rational
b3) = forall (es :: ES). PositC es => Rational -> Posit es
R forall a b. (a -> b) -> a -> b
$ Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
f Rational
a1 Rational
a2 Rational
a3 Rational
b1 Rational
b2 Rational
b3

-- Octonary NaR guarded pass through with wrapping and unwrapping use of a Rational function
viaRational8 :: PositC es => (Rational -> Rational -> Rational -> Rational -> Rational -> Rational -> Rational -> Rational -> Rational) -> Posit es -> Posit es -> Posit es -> Posit es -> Posit es -> Posit es -> Posit es -> Posit es -> Posit es
viaRational8 :: forall (es :: ES).
PositC es =>
(Rational
 -> Rational
 -> Rational
 -> Rational
 -> Rational
 -> Rational
 -> Rational
 -> Rational
 -> Rational)
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
viaRational8 Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
_ Posit es
NaR  Posit es
_   Posit es
_   Posit es
_   Posit es
_   Posit es
_   Posit es
_   Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational8 Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
_  Posit es
_  Posit es
NaR  Posit es
_   Posit es
_   Posit es
_   Posit es
_   Posit es
_   Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational8 Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
_  Posit es
_   Posit es
_  Posit es
NaR  Posit es
_   Posit es
_   Posit es
_   Posit es
_   Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational8 Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
_  Posit es
_   Posit es
_   Posit es
_  Posit es
NaR  Posit es
_   Posit es
_   Posit es
_   Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational8 Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
_  Posit es
_   Posit es
_   Posit es
_   Posit es
_  Posit es
NaR  Posit es
_   Posit es
_   Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational8 Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
_  Posit es
_   Posit es
_   Posit es
_   Posit es
_   Posit es
_  Posit es
NaR  Posit es
_   Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational8 Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
_  Posit es
_   Posit es
_   Posit es
_   Posit es
_   Posit es
_   Posit es
_  Posit es
NaR  Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
viaRational8 Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
_  Posit es
_   Posit es
_   Posit es
_   Posit es
_   Posit es
_   Posit es
_   Posit es
_  Posit es
NaR = forall (es :: ES). PositC es => Posit es
NaR
viaRational8 Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
f (R Rational
a0) (R Rational
a1) (R Rational
a2) (R Rational
a3) (R Rational
b0) (R Rational
b1) (R Rational
b2) (R Rational
b3) = forall (es :: ES). PositC es => Rational -> Posit es
R forall a b. (a -> b) -> a -> b
$ Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
f Rational
a0 Rational
a1 Rational
a2 Rational
a3 Rational
b0 Rational
b1 Rational
b2 Rational
b3



-- Bounded, bounded to what?!? To the ℝ! NaR is out of bounds!!!
--
-- I'm bound to want this definition:
instance PositC es => Bounded (Posit es) where
  -- 'minBound' the most negative number represented
  minBound :: Posit es
minBound = forall (es :: ES). PositC es => IntN es -> Posit es
Posit (forall (es :: ES). PositC es => IntN es
mostNegVal @es)
  -- 'maxBound' the most positive number represented
  maxBound :: Posit es
maxBound = forall (es :: ES). PositC es => IntN es -> Posit es
Posit (forall (es :: ES). PositC es => IntN es
mostPosVal @es)
--


-- =====================================================================
-- ===                    Fused Operations                           ===
-- =====================================================================

-- |A class that delays the rounding operation until the end for some operations
class Num a => FusedOps a where
  -- |Fused Multiply Add: (a * b) + c
  fma :: a -> a -> a -> a
  -- |Fused Add Multiply: (a + b) * c
  fam :: a -> a -> a -> a
  -- |Fused Multiply Multiply Subtract: (a * b) - (c * d)
  fmms :: a -> a -> a -> a -> a
  -- |Fused Sum of 3 values: a + b + c
  fsum3 :: a -> a -> a -> a
  -- |Fused Sum of 4 values: a + b + c + d
  fsum4 :: a -> a -> a -> a -> a
  -- |Fused Sum of a List of Posits
  fsumL :: Foldable t => t a -> a
  -- |Fused Dot Product of 3 element vector: (a1 * b1) + (a2 * b2) + (a3 * b3)
  fdot3 :: a -> a -> a -> a -> a -> a -> a
  -- |Fused Dot Product of 4 element vector: (a0 * b0) + (a1 * b1) + (a2 * b2) + (a3 * b3)
  fdot4 :: a -> a -> a -> a -> a -> a -> a -> a -> a
  -- |Fused Dot Product of Two Lists
  fdotL :: Foldable t => t a -> t a -> a
  -- |Fused Subtract Multiply: a - (b * c)
  fsm :: a -> a -> a -> a
 


-- Rational Instance
instance FusedOps Rational where
  fsm :: Rational -> Rational -> Rational -> Rational
fsm Rational
a Rational
b Rational
c = Rational
a forall a. Num a => a -> a -> a
- (Rational
b forall a. Num a => a -> a -> a
* Rational
c)
  fma :: Rational -> Rational -> Rational -> Rational
fma Rational
a Rational
b Rational
c = (Rational
a forall a. Num a => a -> a -> a
* Rational
b) forall a. Num a => a -> a -> a
+ Rational
c
  fam :: Rational -> Rational -> Rational -> Rational
fam Rational
a Rational
b Rational
c = (Rational
a forall a. Num a => a -> a -> a
+ Rational
b) forall a. Num a => a -> a -> a
* Rational
c
  fmms :: Rational -> Rational -> Rational -> Rational -> Rational
fmms Rational
a Rational
b Rational
c Rational
d = (Rational
a forall a. Num a => a -> a -> a
* Rational
b) forall a. Num a => a -> a -> a
- (Rational
c forall a. Num a => a -> a -> a
* Rational
d)
  fsum3 :: Rational -> Rational -> Rational -> Rational
fsum3 Rational
a Rational
b Rational
c = Rational
a forall a. Num a => a -> a -> a
+ Rational
b forall a. Num a => a -> a -> a
+ Rational
c
  fsum4 :: Rational -> Rational -> Rational -> Rational -> Rational
fsum4 Rational
a Rational
b Rational
c Rational
d = Rational
a forall a. Num a => a -> a -> a
+ Rational
b forall a. Num a => a -> a -> a
+ Rational
c forall a. Num a => a -> a -> a
+ Rational
d
  fsumL :: forall (t :: * -> *). Foldable t => t Rational -> Rational
fsumL (forall (t :: * -> *) a. Foldable t => t a -> [a]
toList -> [Rational]
l) = forall {t}. Num t => [t] -> t -> t
go [Rational]
l Rational
0
    where
      go :: [t] -> t -> t
go [] t
acc = t
acc
      go (t
x : [t]
xs) t
acc = [t] -> t -> t
go [t]
xs (t
acc forall a. Num a => a -> a -> a
+ t
x)
  fdot3 :: Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
fdot3 Rational
a1 Rational
a2 Rational
a3 Rational
b1 Rational
b2 Rational
b3 = (Rational
a1 forall a. Num a => a -> a -> a
* Rational
b1) forall a. Num a => a -> a -> a
+ (Rational
a2 forall a. Num a => a -> a -> a
* Rational
b2) forall a. Num a => a -> a -> a
+ (Rational
a3 forall a. Num a => a -> a -> a
* Rational
b3)
  fdot4 :: Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
-> Rational
fdot4 Rational
a0 Rational
a1 Rational
a2 Rational
a3 Rational
b0 Rational
b1 Rational
b2 Rational
b3 = (Rational
a0 forall a. Num a => a -> a -> a
* Rational
b0) forall a. Num a => a -> a -> a
+ (Rational
a1 forall a. Num a => a -> a -> a
* Rational
b1) forall a. Num a => a -> a -> a
+ (Rational
a2 forall a. Num a => a -> a -> a
* Rational
b2) forall a. Num a => a -> a -> a
+ (Rational
a3 forall a. Num a => a -> a -> a
* Rational
b3)
  fdotL :: forall (t :: * -> *).
Foldable t =>
t Rational -> t Rational -> Rational
fdotL (forall (t :: * -> *) a. Foldable t => t a -> [a]
toList -> [Rational]
l1) (forall (t :: * -> *) a. Foldable t => t a -> [a]
toList -> [Rational]
l2) = forall {t}. FusedOps t => [t] -> [t] -> t -> t
go [Rational]
l1 [Rational]
l2 Rational
0
    where
      go :: [t] -> [t] -> t -> t
go [] [] t
acc = t
acc
      go []  [t]
_  t
_  = forall a. HasCallStack => String -> a
error String
"Lists not the same length"
      go [t]
_  []  t
_  = forall a. HasCallStack => String -> a
error String
"Lists not the same length"
      go (t
b : [t]
bs) (t
c : [t]
cs) t
acc = [t] -> [t] -> t -> t
go [t]
bs [t]
cs (forall a. FusedOps a => a -> a -> a -> a
fma t
b t
c t
acc)
--

--
instance PositC es => FusedOps (Posit es) where
  -- Fused Subtract Multiply
  fsm :: Posit es -> Posit es -> Posit es -> Posit es
fsm = forall (es :: ES).
PositC es =>
(Rational -> Rational -> Rational -> Rational)
-> Posit es -> Posit es -> Posit es -> Posit es
viaRational3 forall a. FusedOps a => a -> a -> a -> a
fsm
  -- Fuse Multiply Add
  fma :: Posit es -> Posit es -> Posit es -> Posit es
fma = forall (es :: ES).
PositC es =>
(Rational -> Rational -> Rational -> Rational)
-> Posit es -> Posit es -> Posit es -> Posit es
viaRational3 forall a. FusedOps a => a -> a -> a -> a
fma
  -- Fuse Add Multiply
  fam :: Posit es -> Posit es -> Posit es -> Posit es
fam = forall (es :: ES).
PositC es =>
(Rational -> Rational -> Rational -> Rational)
-> Posit es -> Posit es -> Posit es -> Posit es
viaRational3 forall a. FusedOps a => a -> a -> a -> a
fam
  -- Fuse Multiply Multiply Subtract
  fmms :: Posit es -> Posit es -> Posit es -> Posit es -> Posit es
fmms = forall (es :: ES).
PositC es =>
(Rational -> Rational -> Rational -> Rational -> Rational)
-> Posit es -> Posit es -> Posit es -> Posit es -> Posit es
viaRational4 forall a. FusedOps a => a -> a -> a -> a -> a
fmms
  -- Fuse Sum of 3 Posits
  fsum3 :: Posit es -> Posit es -> Posit es -> Posit es
fsum3 = forall (es :: ES).
PositC es =>
(Rational -> Rational -> Rational -> Rational)
-> Posit es -> Posit es -> Posit es -> Posit es
viaRational3 forall a. FusedOps a => a -> a -> a -> a
fsum3
  -- Fuse Sum of 4 Posits
  fsum4 :: Posit es -> Posit es -> Posit es -> Posit es -> Posit es
fsum4 = forall (es :: ES).
PositC es =>
(Rational -> Rational -> Rational -> Rational -> Rational)
-> Posit es -> Posit es -> Posit es -> Posit es -> Posit es
viaRational4 forall a. FusedOps a => a -> a -> a -> a -> a
fsum4
  -- Fuse Sum of a List
  fsumL :: forall (t :: * -> *). Foldable t => t (Posit es) -> Posit es
fsumL (forall (t :: * -> *) a. Foldable t => t a -> [a]
toList -> [Posit es]
l) = forall (es :: ES). PositC es => IntN es -> Posit es
Posit forall a b. (a -> b) -> a -> b
$ forall (es :: ES). PositC es => Maybe Rational -> IntN es
encode @es (forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ [Posit es] -> Rational -> Rational
go [Posit es]
l Rational
0)
    where
      go :: [Posit es] -> Rational -> Rational
      go :: [Posit es] -> Rational -> Rational
go [] !Rational
acc = Rational
acc
      go ((Posit IntN es
int) : [Posit es]
xs) !Rational
acc = case forall (es :: ES). PositC es => IntN es -> Maybe Rational
decode @es IntN es
int of
                                     Maybe Rational
Nothing -> forall a. HasCallStack => String -> a
error String
"Posit List contains NaR"
                                     Just Rational
r -> [Posit es] -> Rational -> Rational
go [Posit es]
xs (Rational
acc forall a. Num a => a -> a -> a
+ Rational
r)
  -- Fuse Dot Product of a 3-Vector
  fdot3 :: Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
fdot3 = forall (es :: ES).
PositC es =>
(Rational
 -> Rational
 -> Rational
 -> Rational
 -> Rational
 -> Rational
 -> Rational)
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
viaRational6 forall a. FusedOps a => a -> a -> a -> a -> a -> a -> a
fdot3
  -- Fuse Dot Product of a 4-Vector
  fdot4 :: Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
fdot4 = forall (es :: ES).
PositC es =>
(Rational
 -> Rational
 -> Rational
 -> Rational
 -> Rational
 -> Rational
 -> Rational
 -> Rational
 -> Rational)
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
-> Posit es
viaRational8 forall a. FusedOps a => a -> a -> a -> a -> a -> a -> a -> a -> a
fdot4
  -- Fuse Dot Product of two Lists
  fdotL :: forall (t :: * -> *).
Foldable t =>
t (Posit es) -> t (Posit es) -> Posit es
fdotL (forall (t :: * -> *) a. Foldable t => t a -> [a]
toList -> [Posit es]
l1) (forall (t :: * -> *) a. Foldable t => t a -> [a]
toList -> [Posit es]
l2) = forall (es :: ES). PositC es => IntN es -> Posit es
Posit forall a b. (a -> b) -> a -> b
$ forall (es :: ES). PositC es => Maybe Rational -> IntN es
encode @es (forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ [Posit es] -> [Posit es] -> Rational -> Rational
go [Posit es]
l1 [Posit es]
l2 Rational
0)
    where
      go :: [Posit es] -> [Posit es] -> Rational -> Rational
go [] [] !Rational
acc = Rational
acc
      go []  [Posit es]
_   Rational
_  = forall a. HasCallStack => String -> a
error String
"Lists not the same length"
      go [Posit es]
_  []   Rational
_  = forall a. HasCallStack => String -> a
error String
"Lists not the same length"
      go ((Posit IntN es
int1) : [Posit es]
bs) ((Posit IntN es
int2) : [Posit es]
cs) !Rational
acc = case forall (es :: ES). PositC es => IntN es -> Maybe Rational
decode @es IntN es
int1 of
                                                          Maybe Rational
Nothing -> forall a. HasCallStack => String -> a
error String
"First Posit List contains NaR"
                                                          Just Rational
r1 -> case forall (es :: ES). PositC es => IntN es -> Maybe Rational
decode @es IntN es
int2 of
                                                                       Maybe Rational
Nothing -> forall a. HasCallStack => String -> a
error String
"Second Posit List contains NaR"
                                                                       Just Rational
r2 -> [Posit es] -> [Posit es] -> Rational -> Rational
go [Posit es]
bs [Posit es]
cs (Rational
acc forall a. Num a => a -> a -> a
+ (Rational
r1 forall a. Num a => a -> a -> a
* Rational
r2))
--




-- =====================================================================
-- ===                  Conversion Between Posits Types              ===
-- =====================================================================

-- |A Convertible class that will cast or 'convert' between two different Posit es types
class Convertible a b where
  convert :: a -> b

instance (PositC es1, PositC es2) => Convertible (Posit es1) (Posit es2) where
  convert :: Posit es1 -> Posit es2
convert Posit es1
NaR = forall (es :: ES). PositC es => Posit es
NaR
  convert (R Rational
r) = forall (es :: ES). PositC es => Rational -> Posit es
R Rational
r
--


#ifndef O_NO_SHOW
-- =====================================================================
-- ===                Alternative Show Formats                       ===
-- =====================================================================

-- |A Alternative to the typical 'Show' class to assist in displaying the Posit es type in different formats
class AltShow a where
  -- |Display the Posit in its Binary Representation
  displayBinary :: a -> String
  -- |Display the Posit in its Integral Representation
  displayIntegral :: a -> String
  -- |Display the Posit as a Rational
  displayRational :: a -> String
  -- |Display the Posit as a Decimal until the Repetend occurs
  displayDecimal :: a -> String
--

--
instance PositC es => AltShow (Posit es) where
  displayBinary :: Posit es -> String
displayBinary (Posit IntN es
int) = forall (es :: ES). PositC es => IntN es -> String
displayBin @es IntN es
int
 
  displayIntegral :: Posit es -> String
displayIntegral (Posit IntN es
int) = forall a. Show a => a -> String
show IntN es
int
 
  displayRational :: Posit es -> String
displayRational = forall a (es :: ES).
(Show a, PositC es) =>
(Rational -> a) -> Posit es -> String
viaShowable forall a. a -> a
id
 
  displayDecimal :: Posit es -> String
displayDecimal = forall a (es :: ES).
(Show a, PositC es) =>
(Rational -> a) -> Posit es -> String
viaShowable (forall a b. (a, b) -> a
fstforall b c a. (b -> c) -> (a -> b) -> a -> c
.Rational -> (Scientific, Maybe Int)
fromRationalRepetendUnlimited)
--

viaShowable :: (Show a, PositC es) => (Rational -> a) -> Posit es -> String
viaShowable :: forall a (es :: ES).
(Show a, PositC es) =>
(Rational -> a) -> Posit es -> String
viaShowable Rational -> a
_ Posit es
NaR = String
"NaR"
viaShowable Rational -> a
f (R Rational
r) = forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ Rational -> a
f Rational
r
#endif

#ifndef O_NO_READ
-- =====================================================================
-- ===                         Read Posit                            ===
-- =====================================================================

--
instance PositC es => Read (Posit es) where
  readPrec :: ReadPrec (Posit es)
readPrec =
    forall a. ReadPrec a -> ReadPrec a
parens forall a b. (a -> b) -> a -> b
$ do
      Lexeme
x <- ReadPrec Lexeme
lexP
      case Lexeme
x of
        Ident String
"NaR" -> forall (m :: * -> *) a. Monad m => a -> m a
return forall (es :: ES). PositC es => Posit es
NaR
        Lexeme
_ -> forall a. ReadPrec a
pfail
      forall a. ReadPrec a -> ReadPrec a -> ReadPrec a
+++
      do
        Scientific
s <- forall a. ReadP a -> ReadPrec a
lift ReadP Scientific
scientificP
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (es :: ES). PositC es => Rational -> Posit es
R (forall a. Real a => a -> Rational
toRational Scientific
s)
 
  readListPrec :: ReadPrec [Posit es]
readListPrec = forall a. Read a => ReadPrec [a]
readListPrecDefault
--
#endif


-- =====================================================================
-- ===                  Storable Instances                           ===
-- =====================================================================
--
#ifndef O_NO_STORABLE
--
instance PositC es => Storable (Posit es) where
  sizeOf :: Posit es -> Int
sizeOf Posit es
_ = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall (es :: ES). PositC es => Natural
nBytes @es
  alignment :: Posit es -> Int
alignment Posit es
_ = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall (es :: ES). PositC es => Natural
nBytes @es
  peek :: Ptr (Posit es) -> IO (Posit es)
peek Ptr (Posit es)
ptr = do
    IntN es
int <- forall a. Storable a => Ptr a -> IO a
peek (forall a b. Ptr a -> Ptr b
castPtr Ptr (Posit es)
ptr :: Ptr (IntN es))
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (es :: ES). PositC es => IntN es -> Posit es
Posit IntN es
int
  poke :: Ptr (Posit es) -> Posit es -> IO ()
poke Ptr (Posit es)
ptr (Posit IntN es
int) = do
    forall a. Storable a => Ptr a -> a -> IO ()
poke (forall a b. Ptr a -> Ptr b
castPtr Ptr (Posit es)
ptr :: Ptr (IntN es)) IntN es
int
--
#endif


-- =====================================================================
-- ===                        Real Frac                              ===
-- =====================================================================

--
instance PositC es => RealFrac (Posit es) where
  -- properFraction :: Integral b => a -> (b, a)
  properFraction :: forall b. Integral b => Posit es -> (b, Posit es)
properFraction = forall (es :: ES) a.
PositC es =>
String -> (Rational -> (a, Rational)) -> Posit es -> (a, Posit es)
viaRationalErrTrunkation String
"NaR value is not a RealFrac" forall a b. (RealFrac a, Integral b) => a -> (b, a)
properFraction
--

viaRationalErrTrunkation :: PositC es => String -> (Rational -> (a, Rational)) -> Posit es -> (a, Posit es)
viaRationalErrTrunkation :: forall (es :: ES) a.
PositC es =>
String -> (Rational -> (a, Rational)) -> Posit es -> (a, Posit es)
viaRationalErrTrunkation String
err Rational -> (a, Rational)
_ Posit es
NaR = forall a. HasCallStack => String -> a
error String
err
viaRationalErrTrunkation String
_ Rational -> (a, Rational)
f (R Rational
r) =
  let (a
int, Rational
r') = Rational -> (a, Rational)
f Rational
r
  in (a
int, forall (es :: ES). PositC es => Rational -> Posit es
R Rational
r')

-- =====================================================================
-- ===                         Real Float                            ===
-- =====================================================================
--
instance (Floating (Posit es), PositC es) => RealFloat (Posit es) where
  isIEEE :: Posit es -> Bool
isIEEE Posit es
_ = Bool
False
  isDenormalized :: Posit es -> Bool
isDenormalized Posit es
_ = Bool
False
  isNegativeZero :: Posit es -> Bool
isNegativeZero Posit es
_ = Bool
False
 
  isNaN :: Posit es -> Bool
isNaN Posit es
NaR = Bool
True
  isNaN  Posit es
_  = Bool
False
 
  isInfinite :: Posit es -> Bool
isInfinite Posit es
NaR = Bool
True
  isInfinite Posit es
_ = Bool
False
 
  -- 'atan2' of y x is the argument "arg function" (also called phase or angle) of the complex number x + i y.
  -- angle from an x basis vector to some other vector
  --
  --     Y
  --     ^
  --     |    ^ (x,y)
  --     |   /
  --     |  / <-  alpha (radians)
  --     | /                      \
  --      /                        |
  --      -----------------------------------> X
  --
  --
  atan2 :: Posit es -> Posit es -> Posit es
atan2 Posit es
NaR  Posit es
_  = forall (es :: ES). PositC es => Posit es
NaR
  atan2  Posit es
_  Posit es
NaR = forall (es :: ES). PositC es => Posit es
NaR
  atan2 Posit es
y Posit es
x
    | Posit es
x forall a. Eq a => a -> a -> Bool
== Posit es
0 Bool -> Bool -> Bool
&& Posit es
y forall a. Eq a => a -> a -> Bool
== Posit es
0 = forall (es :: ES). PositC es => Posit es
NaR
    | Posit es
x forall a. Ord a => a -> a -> Bool
> Posit es
0             = forall a. Floating a => a -> a
atan (Posit es
yforall a. Fractional a => a -> a -> a
/Posit es
x)
    | Posit es
x forall a. Ord a => a -> a -> Bool
< Posit es
0  Bool -> Bool -> Bool
&& Posit es
y forall a. Ord a => a -> a -> Bool
>= Posit es
0  = forall a. Floating a => a -> a
atan (Posit es
yforall a. Fractional a => a -> a -> a
/Posit es
x) forall a. Num a => a -> a -> a
+ forall a. Floating a => a
pi
    | Posit es
x forall a. Ord a => a -> a -> Bool
< Posit es
0  Bool -> Bool -> Bool
&& Posit es
y  forall a. Ord a => a -> a -> Bool
< Posit es
0  = forall a. Floating a => a -> a
atan (Posit es
yforall a. Fractional a => a -> a -> a
/Posit es
x) forall a. Num a => a -> a -> a
- forall a. Floating a => a
pi
    | Posit es
x forall a. Eq a => a -> a -> Bool
== Posit es
0 Bool -> Bool -> Bool
&& Posit es
y  forall a. Ord a => a -> a -> Bool
> Posit es
0  = forall a. Floating a => a
pi forall a. Fractional a => a -> a -> a
/ Posit es
2
    | Posit es
x forall a. Eq a => a -> a -> Bool
== Posit es
0 Bool -> Bool -> Bool
&& Posit es
y  forall a. Ord a => a -> a -> Bool
< Posit es
0  = forall a. Num a => a -> a
negate forall a b. (a -> b) -> a -> b
$ forall a. Floating a => a
pi forall a. Fractional a => a -> a -> a
/ Posit es
2
    | Bool
otherwise = forall a. HasCallStack => String -> a
error String
"What!?!?!" -- The case where x == 0 && y == 0
 
  floatRadix :: Posit es -> Integer
floatRadix Posit es
_ = Integer
2
  floatDigits :: Posit es -> Int
floatDigits Posit es
_ = forall a. HasCallStack => a
undefined
  floatRange :: Posit es -> (Int, Int)
floatRange Posit es
_ = (forall a. Num a => a -> a
negate Int
maxExponent, Int
maxExponent)
    where
      maxExponent :: Int
maxExponent = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ (forall (es :: ES). PositC es => Natural
nBytes @es) forall a. Num a => a -> a -> a
* ((forall (es :: ES). PositC es => Natural
nBits @es) forall a. Num a => a -> a -> a
- Natural
2)
  decodeFloat :: Posit es -> (Integer, Int)
decodeFloat = forall a. HasCallStack => a
undefined
  encodeFloat :: Integer -> Int -> Posit es
encodeFloat = forall a. HasCallStack => a
undefined
--



-- =====================================================================
-- ===                         Floating                              ===
-- =====================================================================


instance Floating Posit8 where
  pi :: Posit8
pi = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a
pi :: Posit256) :: Posit8
  exp :: Posit8 -> Posit8
exp Posit8
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
exp (forall a b. Convertible a b => a -> b
convert Posit8
x) :: Posit256) :: Posit8
  log :: Posit8 -> Posit8
log Posit8
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
log (forall a b. Convertible a b => a -> b
convert Posit8
x) :: Posit256) :: Posit8
  Posit8
x ** :: Posit8 -> Posit8 -> Posit8
** Posit8
y = forall a b. Convertible a b => a -> b
convert forall a b. (a -> b) -> a -> b
$ (forall a b. Convertible a b => a -> b
convert Posit8
x :: Posit256) forall a. Floating a => a -> a -> a
** (forall a b. Convertible a b => a -> b
convert Posit8
y :: Posit256) :: Posit8
  sin :: Posit8 -> Posit8
sin Posit8
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
sin (forall a b. Convertible a b => a -> b
convert Posit8
x) :: Posit256) :: Posit8
  cos :: Posit8 -> Posit8
cos Posit8
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
cos (forall a b. Convertible a b => a -> b
convert Posit8
x) :: Posit256) :: Posit8
  asin :: Posit8 -> Posit8
asin Posit8
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
asin (forall a b. Convertible a b => a -> b
convert Posit8
x) :: Posit256) :: Posit8
  acos :: Posit8 -> Posit8
acos Posit8
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
acos (forall a b. Convertible a b => a -> b
convert Posit8
x) :: Posit256) :: Posit8
  atan :: Posit8 -> Posit8
atan Posit8
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
atan (forall a b. Convertible a b => a -> b
convert Posit8
x) :: Posit256) :: Posit8
  sinh :: Posit8 -> Posit8
sinh Posit8
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
sinh (forall a b. Convertible a b => a -> b
convert Posit8
x) :: Posit256) :: Posit8
  cosh :: Posit8 -> Posit8
cosh Posit8
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
cosh (forall a b. Convertible a b => a -> b
convert Posit8
x) :: Posit256) :: Posit8
  asinh :: Posit8 -> Posit8
asinh Posit8
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
asinh (forall a b. Convertible a b => a -> b
convert Posit8
x) :: Posit256) :: Posit8
  acosh :: Posit8 -> Posit8
acosh Posit8
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
acosh (forall a b. Convertible a b => a -> b
convert Posit8
x) :: Posit256) :: Posit8
  atanh :: Posit8 -> Posit8
atanh Posit8
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
atanh (forall a b. Convertible a b => a -> b
convert Posit8
x) :: Posit256) :: Posit8

instance Floating Posit16 where
  pi :: Posit16
pi = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a
pi :: Posit256) :: Posit16
  exp :: Posit16 -> Posit16
exp Posit16
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
exp (forall a b. Convertible a b => a -> b
convert Posit16
x) :: Posit256) :: Posit16
  log :: Posit16 -> Posit16
log Posit16
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
log (forall a b. Convertible a b => a -> b
convert Posit16
x) :: Posit256) :: Posit16
  Posit16
x ** :: Posit16 -> Posit16 -> Posit16
** Posit16
y = forall a b. Convertible a b => a -> b
convert forall a b. (a -> b) -> a -> b
$ (forall a b. Convertible a b => a -> b
convert Posit16
x :: Posit256) forall a. Floating a => a -> a -> a
** (forall a b. Convertible a b => a -> b
convert Posit16
y :: Posit256) :: Posit16
  sin :: Posit16 -> Posit16
sin Posit16
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
sin (forall a b. Convertible a b => a -> b
convert Posit16
x) :: Posit256) :: Posit16
  cos :: Posit16 -> Posit16
cos Posit16
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
cos (forall a b. Convertible a b => a -> b
convert Posit16
x) :: Posit256) :: Posit16
  asin :: Posit16 -> Posit16
asin Posit16
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
asin (forall a b. Convertible a b => a -> b
convert Posit16
x) :: Posit256) :: Posit16
  acos :: Posit16 -> Posit16
acos Posit16
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
acos (forall a b. Convertible a b => a -> b
convert Posit16
x) :: Posit256) :: Posit16
  atan :: Posit16 -> Posit16
atan Posit16
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
atan (forall a b. Convertible a b => a -> b
convert Posit16
x) :: Posit256) :: Posit16
  sinh :: Posit16 -> Posit16
sinh Posit16
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
sinh (forall a b. Convertible a b => a -> b
convert Posit16
x) :: Posit256) :: Posit16
  cosh :: Posit16 -> Posit16
cosh Posit16
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
cosh (forall a b. Convertible a b => a -> b
convert Posit16
x) :: Posit256) :: Posit16
  asinh :: Posit16 -> Posit16
asinh Posit16
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
asinh (forall a b. Convertible a b => a -> b
convert Posit16
x) :: Posit256) :: Posit16
  acosh :: Posit16 -> Posit16
acosh Posit16
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
acosh (forall a b. Convertible a b => a -> b
convert Posit16
x) :: Posit256) :: Posit16
  atanh :: Posit16 -> Posit16
atanh Posit16
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
atanh (forall a b. Convertible a b => a -> b
convert Posit16
x) :: Posit256) :: Posit16

instance Floating Posit32 where
  pi :: Posit32
pi = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a
pi :: Posit256) :: Posit32
  exp :: Posit32 -> Posit32
exp Posit32
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
exp (forall a b. Convertible a b => a -> b
convert Posit32
x) :: Posit256) :: Posit32
  log :: Posit32 -> Posit32
log Posit32
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
log (forall a b. Convertible a b => a -> b
convert Posit32
x) :: Posit256) :: Posit32
  Posit32
x ** :: Posit32 -> Posit32 -> Posit32
** Posit32
y = forall a b. Convertible a b => a -> b
convert forall a b. (a -> b) -> a -> b
$ (forall a b. Convertible a b => a -> b
convert Posit32
x :: Posit256) forall a. Floating a => a -> a -> a
** (forall a b. Convertible a b => a -> b
convert Posit32
y :: Posit256) :: Posit32
  sin :: Posit32 -> Posit32
sin Posit32
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
sin (forall a b. Convertible a b => a -> b
convert Posit32
x) :: Posit256) :: Posit32
  cos :: Posit32 -> Posit32
cos Posit32
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
cos (forall a b. Convertible a b => a -> b
convert Posit32
x) :: Posit256) :: Posit32
  asin :: Posit32 -> Posit32
asin Posit32
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
asin (forall a b. Convertible a b => a -> b
convert Posit32
x) :: Posit256) :: Posit32
  acos :: Posit32 -> Posit32
acos Posit32
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
acos (forall a b. Convertible a b => a -> b
convert Posit32
x) :: Posit256) :: Posit32
  atan :: Posit32 -> Posit32
atan Posit32
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
atan (forall a b. Convertible a b => a -> b
convert Posit32
x) :: Posit256) :: Posit32
  sinh :: Posit32 -> Posit32
sinh Posit32
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
sinh (forall a b. Convertible a b => a -> b
convert Posit32
x) :: Posit256) :: Posit32
  cosh :: Posit32 -> Posit32
cosh Posit32
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
cosh (forall a b. Convertible a b => a -> b
convert Posit32
x) :: Posit256) :: Posit32
  asinh :: Posit32 -> Posit32
asinh Posit32
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
asinh (forall a b. Convertible a b => a -> b
convert Posit32
x) :: Posit256) :: Posit32
  acosh :: Posit32 -> Posit32
acosh Posit32
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
acosh (forall a b. Convertible a b => a -> b
convert Posit32
x) :: Posit256) :: Posit32
  atanh :: Posit32 -> Posit32
atanh Posit32
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
atanh (forall a b. Convertible a b => a -> b
convert Posit32
x) :: Posit256) :: Posit32

instance Floating Posit64 where
  pi :: Posit64
pi = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a
pi :: Posit256) :: Posit64
  exp :: Posit64 -> Posit64
exp Posit64
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
exp (forall a b. Convertible a b => a -> b
convert Posit64
x) :: Posit256) :: Posit64
  log :: Posit64 -> Posit64
log Posit64
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
log (forall a b. Convertible a b => a -> b
convert Posit64
x) :: Posit256) :: Posit64
  Posit64
x ** :: Posit64 -> Posit64 -> Posit64
** Posit64
y = forall a b. Convertible a b => a -> b
convert forall a b. (a -> b) -> a -> b
$ (forall a b. Convertible a b => a -> b
convert Posit64
x :: Posit256) forall a. Floating a => a -> a -> a
** (forall a b. Convertible a b => a -> b
convert Posit64
y :: Posit256) :: Posit64
  sin :: Posit64 -> Posit64
sin Posit64
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
sin (forall a b. Convertible a b => a -> b
convert Posit64
x) :: Posit256) :: Posit64
  cos :: Posit64 -> Posit64
cos Posit64
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
cos (forall a b. Convertible a b => a -> b
convert Posit64
x) :: Posit256) :: Posit64
  asin :: Posit64 -> Posit64
asin Posit64
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
asin (forall a b. Convertible a b => a -> b
convert Posit64
x) :: Posit256) :: Posit64
  acos :: Posit64 -> Posit64
acos Posit64
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
acos (forall a b. Convertible a b => a -> b
convert Posit64
x) :: Posit256) :: Posit64
  atan :: Posit64 -> Posit64
atan Posit64
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
atan (forall a b. Convertible a b => a -> b
convert Posit64
x) :: Posit256) :: Posit64
  sinh :: Posit64 -> Posit64
sinh Posit64
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
sinh (forall a b. Convertible a b => a -> b
convert Posit64
x) :: Posit256) :: Posit64
  cosh :: Posit64 -> Posit64
cosh Posit64
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
cosh (forall a b. Convertible a b => a -> b
convert Posit64
x) :: Posit256) :: Posit64
  asinh :: Posit64 -> Posit64
asinh Posit64
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
asinh (forall a b. Convertible a b => a -> b
convert Posit64
x) :: Posit256) :: Posit64
  acosh :: Posit64 -> Posit64
acosh Posit64
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
acosh (forall a b. Convertible a b => a -> b
convert Posit64
x) :: Posit256) :: Posit64
  atanh :: Posit64 -> Posit64
atanh Posit64
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
atanh (forall a b. Convertible a b => a -> b
convert Posit64
x) :: Posit256) :: Posit64

instance Floating Posit128 where
  pi :: Posit128
pi = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a
pi :: Posit256) :: Posit128
  exp :: Posit128 -> Posit128
exp Posit128
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
exp (forall a b. Convertible a b => a -> b
convert Posit128
x) :: Posit256) :: Posit128
  log :: Posit128 -> Posit128
log Posit128
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
log (forall a b. Convertible a b => a -> b
convert Posit128
x) :: Posit256) :: Posit128
  Posit128
x ** :: Posit128 -> Posit128 -> Posit128
** Posit128
y = forall a b. Convertible a b => a -> b
convert forall a b. (a -> b) -> a -> b
$ (forall a b. Convertible a b => a -> b
convert Posit128
x :: Posit256) forall a. Floating a => a -> a -> a
** (forall a b. Convertible a b => a -> b
convert Posit128
y :: Posit256) :: Posit128
  sin :: Posit128 -> Posit128
sin Posit128
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
sin (forall a b. Convertible a b => a -> b
convert Posit128
x) :: Posit256) :: Posit128
  cos :: Posit128 -> Posit128
cos Posit128
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
cos (forall a b. Convertible a b => a -> b
convert Posit128
x) :: Posit256) :: Posit128
  asin :: Posit128 -> Posit128
asin Posit128
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
asin (forall a b. Convertible a b => a -> b
convert Posit128
x) :: Posit256) :: Posit128
  acos :: Posit128 -> Posit128
acos Posit128
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
acos (forall a b. Convertible a b => a -> b
convert Posit128
x) :: Posit256) :: Posit128
  atan :: Posit128 -> Posit128
atan Posit128
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
atan (forall a b. Convertible a b => a -> b
convert Posit128
x) :: Posit256) :: Posit128
  sinh :: Posit128 -> Posit128
sinh Posit128
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
sinh (forall a b. Convertible a b => a -> b
convert Posit128
x) :: Posit256) :: Posit128
  cosh :: Posit128 -> Posit128
cosh Posit128
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
cosh (forall a b. Convertible a b => a -> b
convert Posit128
x) :: Posit256) :: Posit128
  asinh :: Posit128 -> Posit128
asinh Posit128
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
asinh (forall a b. Convertible a b => a -> b
convert Posit128
x) :: Posit256) :: Posit128
  acosh :: Posit128 -> Posit128
acosh Posit128
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
acosh (forall a b. Convertible a b => a -> b
convert Posit128
x) :: Posit256) :: Posit128
  atanh :: Posit128 -> Posit128
atanh Posit128
x = forall a b. Convertible a b => a -> b
convert (forall a. Floating a => a -> a
atanh (forall a b. Convertible a b => a -> b
convert Posit128
x) :: Posit256) :: Posit128

instance Floating Posit256 where
  pi :: Posit256
pi = Posit256
3.141592653589793238462643383279502884197169399375105820974944592307816406286 :: Posit256
  exp :: Posit256 -> Posit256
exp = Posit256 -> Posit256
funExp
  log :: Posit256 -> Posit256
log = (Posit256 -> Posit256) -> Posit256 -> Posit256
funLogDomainReduction Posit256 -> Posit256
funLogTaylor
  ** :: Posit256 -> Posit256 -> Posit256
(**) = Posit256 -> Posit256 -> Posit256
funPow
  sin :: Posit256 -> Posit256
sin = Posit256 -> Posit256
funSin
  cos :: Posit256 -> Posit256
cos = Posit256 -> Posit256
funCos
  asin :: Posit256 -> Posit256
asin = Posit256 -> Posit256
funAsin
  acos :: Posit256 -> Posit256
acos = Posit256 -> Posit256
funAcos
  atan :: Posit256 -> Posit256
atan = Posit256 -> Posit256
funAtan
  sinh :: Posit256 -> Posit256
sinh = Posit256 -> Posit256
funSinh
  cosh :: Posit256 -> Posit256
cosh = Posit256 -> Posit256
funCosh
  asinh :: Posit256 -> Posit256
asinh = Posit256 -> Posit256
funAsinh
  acosh :: Posit256 -> Posit256
acosh = Posit256 -> Posit256
funAcosh
  atanh :: Posit256 -> Posit256
atanh = Posit256 -> Posit256
funAtanh





class AltFloating p where
  phi :: p
  gamma :: p -> p
  sinc :: p -> p
  expm1 :: p -> p

instance AltFloating Posit8 where
  phi :: Posit8
phi = forall a b. Convertible a b => a -> b
convert (forall p. AltFloating p => p
phi :: Posit256) :: Posit8
  gamma :: Posit8 -> Posit8
gamma Posit8
x = forall a b. Convertible a b => a -> b
convert (forall p. AltFloating p => p -> p
gamma (forall a b. Convertible a b => a -> b
convert Posit8
x) :: Posit256) :: Posit8
  sinc :: Posit8 -> Posit8
sinc Posit8
x = forall a b. Convertible a b => a -> b
convert (forall p. AltFloating p => p -> p
sinc (forall a b. Convertible a b => a -> b
convert Posit8
x) :: Posit256) :: Posit8
  expm1 :: Posit8 -> Posit8
expm1 Posit8
x =
    let b :: Posit8
b = forall a. Floating a => a -> a
atanh forall a b. (a -> b) -> a -> b
$ Posit8
x forall a. Fractional a => a -> a -> a
/ Posit8
2
    in (Posit8
2 forall a. Num a => a -> a -> a
* Posit8
b) forall a. Fractional a => a -> a -> a
/ (Posit8
1 forall a. Num a => a -> a -> a
- Posit8
b)

instance AltFloating Posit16 where
  phi :: Posit16
phi = forall a b. Convertible a b => a -> b
convert (forall p. AltFloating p => p
phi :: Posit256) :: Posit16
  gamma :: Posit16 -> Posit16
gamma Posit16
x = forall a b. Convertible a b => a -> b
convert (forall p. AltFloating p => p -> p
gamma (forall a b. Convertible a b => a -> b
convert Posit16
x) :: Posit256) :: Posit16
  sinc :: Posit16 -> Posit16
sinc Posit16
x = forall a b. Convertible a b => a -> b
convert (forall p. AltFloating p => p -> p
sinc (forall a b. Convertible a b => a -> b
convert Posit16
x) :: Posit256) :: Posit16
  expm1 :: Posit16 -> Posit16
expm1 Posit16
x =
    let b :: Posit16
b = forall a. Floating a => a -> a
atanh forall a b. (a -> b) -> a -> b
$ Posit16
x forall a. Fractional a => a -> a -> a
/ Posit16
2
    in (Posit16
2 forall a. Num a => a -> a -> a
* Posit16
b) forall a. Fractional a => a -> a -> a
/ (Posit16
1 forall a. Num a => a -> a -> a
- Posit16
b)

instance AltFloating Posit32 where
  phi :: Posit32
phi = forall a b. Convertible a b => a -> b
convert (forall p. AltFloating p => p
phi :: Posit256) :: Posit32
  gamma :: Posit32 -> Posit32
gamma Posit32
x = forall a b. Convertible a b => a -> b
convert (forall p. AltFloating p => p -> p
gamma (forall a b. Convertible a b => a -> b
convert Posit32
x) :: Posit256) :: Posit32
  sinc :: Posit32 -> Posit32
sinc Posit32
x = forall a b. Convertible a b => a -> b
convert (forall p. AltFloating p => p -> p
sinc (forall a b. Convertible a b => a -> b
convert Posit32
x) :: Posit256) :: Posit32
  expm1 :: Posit32 -> Posit32
expm1 Posit32
x =
    let b :: Posit32
b = forall a. Floating a => a -> a
atanh forall a b. (a -> b) -> a -> b
$ Posit32
x forall a. Fractional a => a -> a -> a
/ Posit32
2
    in (Posit32
2 forall a. Num a => a -> a -> a
* Posit32
b) forall a. Fractional a => a -> a -> a
/ (Posit32
1 forall a. Num a => a -> a -> a
- Posit32
b)

instance AltFloating Posit64 where
  phi :: Posit64
phi = forall a b. Convertible a b => a -> b
convert (forall p. AltFloating p => p
phi :: Posit256) :: Posit64
  gamma :: Posit64 -> Posit64
gamma Posit64
x = forall a b. Convertible a b => a -> b
convert (forall p. AltFloating p => p -> p
gamma (forall a b. Convertible a b => a -> b
convert Posit64
x) :: Posit256) :: Posit64
  sinc :: Posit64 -> Posit64
sinc Posit64
x = forall a b. Convertible a b => a -> b
convert (forall p. AltFloating p => p -> p
sinc (forall a b. Convertible a b => a -> b
convert Posit64
x) :: Posit256) :: Posit64
  expm1 :: Posit64 -> Posit64
expm1 Posit64
x =
    let b :: Posit64
b = forall a. Floating a => a -> a
atanh forall a b. (a -> b) -> a -> b
$ Posit64
x forall a. Fractional a => a -> a -> a
/ Posit64
2
    in (Posit64
2 forall a. Num a => a -> a -> a
* Posit64
b) forall a. Fractional a => a -> a -> a
/ (Posit64
1 forall a. Num a => a -> a -> a
- Posit64
b)

instance AltFloating Posit128 where
  phi :: Posit128
phi = forall a b. Convertible a b => a -> b
convert (forall p. AltFloating p => p
phi :: Posit256) :: Posit128
  gamma :: Posit128 -> Posit128
gamma Posit128
x = forall a b. Convertible a b => a -> b
convert (forall p. AltFloating p => p -> p
gamma (forall a b. Convertible a b => a -> b
convert Posit128
x) :: Posit256) :: Posit128
  sinc :: Posit128 -> Posit128
sinc Posit128
x = forall a b. Convertible a b => a -> b
convert (forall p. AltFloating p => p -> p
sinc (forall a b. Convertible a b => a -> b
convert Posit128
x) :: Posit256) :: Posit128
  expm1 :: Posit128 -> Posit128
expm1 Posit128
x =
    let b :: Posit128
b = forall a. Floating a => a -> a
atanh forall a b. (a -> b) -> a -> b
$ Posit128
x forall a. Fractional a => a -> a -> a
/ Posit128
2
    in (Posit128
2 forall a. Num a => a -> a -> a
* Posit128
b) forall a. Fractional a => a -> a -> a
/ (Posit128
1 forall a. Num a => a -> a -> a
- Posit128
b)

instance AltFloating Posit256 where
  phi :: Posit256
phi = Posit256 -> Posit256
funPhi Posit256
1.6
  gamma :: Posit256 -> Posit256
gamma = Posit256 -> Posit256
funGammaSeries
  sinc :: Posit256 -> Posit256
sinc = Posit256 -> Posit256
funSinc
  expm1 :: Posit256 -> Posit256
expm1 Posit256
x =
    let b :: Posit256
b = forall a. Floating a => a -> a
atanh forall a b. (a -> b) -> a -> b
$ Posit256
x forall a. Fractional a => a -> a -> a
/ Posit256
2
    in (Posit256
2 forall a. Num a => a -> a -> a
* Posit256
b) forall a. Fractional a => a -> a -> a
/ (Posit256
1 forall a. Num a => a -> a -> a
- Posit256
b)


-- | 'phi' fixed point recursive algorithm,
funPhi :: Posit256 -> Posit256
funPhi :: Posit256 -> Posit256
funPhi  px :: Posit256
px@(Posit IntN 'V
x)
    | IntN 'V
x forall a. Eq a => a -> a -> Bool
== Int256_Storable
x' = forall (es :: ES). PositC es => IntN es -> Posit es
Posit IntN 'V
x
    | Bool
otherwise = Posit256 -> Posit256
funPhi (forall (es :: ES). PositC es => IntN es -> Posit es
Posit Int256_Storable
x')
      where
        (Posit Int256_Storable
IntN 'V
x') = (Posit256
pxforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
+ Posit256
2forall a. Num a => a -> a -> a
*Posit256
px) forall a. Fractional a => a -> a -> a
/ (Posit256
pxforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
+ Posit256
1)
        -- LiquidHaskell is telling me this is unsafe if px is imaginary
        -- lucky for us Posit256 is not imaginary


-- calculate atan(1/2^n)
-- sum k=0 to k=inf of the terms, iterate until a fixed point is reached
funArcTan :: Natural -> Posit256
funArcTan :: Natural -> Posit256
funArcTan Natural
0 = forall a. Floating a => a
pi forall a. Fractional a => a -> a -> a
/ Posit256
4
funArcTan Natural
n
  | Natural
n forall a. Ord a => a -> a -> Bool
<= Natural
122 = Integer -> Posit256 -> Posit256
go Integer
0 Posit256
0
  | Bool
otherwise = Posit256
z  -- at small z... (atan z) == z "small angle approximation"
    where
      go :: Integer -> Posit256 -> Posit256
go !Integer
k !Posit256
acc
        | Posit256
acc forall a. Eq a => a -> a -> Bool
== (Posit256
acc forall a. Num a => a -> a -> a
+ Integer -> Posit256
term Integer
k) = Posit256
acc
        | Bool
otherwise = Integer -> Posit256 -> Posit256
go (Integer
kforall a. Num a => a -> a -> a
+Integer
1) (Posit256
acc forall a. Num a => a -> a -> a
+ Integer -> Posit256
term Integer
k)
      term :: Integer -> Posit256
      term :: Integer -> Posit256
term Integer
k = ((-Posit256
1)forall a b. (Num a, Integral b) => a -> b -> a
^Integer
k forall a. Num a => a -> a -> a
* Posit256
zforall a b. (Num a, Integral b) => a -> b -> a
^(Integer
2 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
1)) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
2 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
1)
      z :: Posit256
z = Posit256
1 forall a. Fractional a => a -> a -> a
/ Posit256
2forall a b. (Num a, Integral b) => a -> b -> a
^Natural
n  -- recip $ 2^n :: Posit256 -- inv2PowN

-- seems pretty close to 1 ULP with the input of 0.7813
funAtan :: Posit256 -> Posit256
funAtan :: Posit256 -> Posit256
funAtan Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funAtan Posit256
x
  | forall a. Num a => a -> a
abs Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
1forall a. Fractional a => a -> a -> a
/Posit256
2forall a b. (Num a, Integral b) => a -> b -> a
^Integer
122 = Posit256
x  -- small angle approximaiton, found emperically
  | Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
0 = forall a. Num a => a -> a
negateforall b c a. (b -> c) -> (a -> b) -> a -> c
.Posit256 -> Posit256
funAtan forall a b. (a -> b) -> a -> b
$ forall a. Num a => a -> a
negate Posit256
x  -- if negative turn it positive, it reduces the other domain reductions by half, found from Universal CORDIC
  | Posit256
x forall a. Ord a => a -> a -> Bool
> Posit256
1 = forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Posit256
2 forall a. Num a => a -> a -> a
- Posit256 -> Posit256
funAtan (forall a. Fractional a => a -> a
recip Posit256
x)  -- if larger than one use the complementary angle, found from Universal CORDIC
  | Posit256
x forall a. Ord a => a -> a -> Bool
> Posit256
twoMsqrt3 = forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Posit256
6 forall a. Num a => a -> a -> a
+ Posit256 -> Posit256
funAtan ((forall a. Floating a => a -> a
sqrt Posit256
3 forall a. Num a => a -> a -> a
* Posit256
x forall a. Num a => a -> a -> a
- Posit256
1)forall a. Fractional a => a -> a -> a
/(forall a. Floating a => a -> a
sqrt Posit256
3 forall a. Num a => a -> a -> a
+ Posit256
x))  -- another domain reduction, using an identity, found from https://mathonweb.com/help_ebook/html/algorithms.htm
  | Bool
otherwise = Posit256 -> Posit256
funArcTanTaylor Posit256
x
--

twoMsqrt3 :: Posit256
twoMsqrt3 :: Posit256
twoMsqrt3 = Posit256
2 forall a. Num a => a -> a -> a
- forall a. Floating a => a -> a
sqrt Posit256
3

--
funArcTanTaylor :: Posit256 -> Posit256
funArcTanTaylor :: Posit256 -> Posit256
funArcTanTaylor Posit256
x = Integer -> Posit256 -> Posit256
go Integer
0 Posit256
0
  where
    go :: Integer -> Posit256 -> Posit256
go !Integer
k !Posit256
acc
      | Posit256
acc forall a. Eq a => a -> a -> Bool
== (Posit256
acc forall a. Num a => a -> a -> a
+ Integer -> Posit256
term Integer
k) = Posit256
acc
      | Bool
otherwise = Integer -> Posit256 -> Posit256
go (Integer
kforall a. Num a => a -> a -> a
+Integer
1) (Posit256
acc forall a. Num a => a -> a -> a
+ Integer -> Posit256
term Integer
k)
    term :: Integer -> Posit256
    term :: Integer -> Posit256
term Integer
k = ((-Posit256
1)forall a b. (Num a, Integral b) => a -> b -> a
^Integer
k forall a. Num a => a -> a -> a
* Posit256
xforall a b. (Num a, Integral b) => a -> b -> a
^(Integer
2 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
1)) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
2 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
1)
--

--
funAsin :: Posit256 -> Posit256
funAsin :: Posit256 -> Posit256
funAsin Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funAsin Posit256
x
  | forall a. Num a => a -> a
abs Posit256
x forall a. Ord a => a -> a -> Bool
> Posit256
1 = forall (es :: ES). PositC es => Posit es
NaR
  | Posit256
x forall a. Eq a => a -> a -> Bool
== Posit256
1 = forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Posit256
2
  | Posit256
x forall a. Eq a => a -> a -> Bool
== -Posit256
1 = -forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Posit256
2
  | Bool
otherwise = Posit256 -> Posit256
funAtan Posit256
w
    where
      w :: Posit256
w = Posit256
x forall a. Fractional a => a -> a -> a
/ forall a. Floating a => a -> a
sqrt (Posit256
1 forall a. Num a => a -> a -> a
- Posit256
xforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2)
--

--
funAcos :: Posit256 -> Posit256
funAcos :: Posit256 -> Posit256
funAcos Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funAcos Posit256
x
  | forall a. Num a => a -> a
abs Posit256
x forall a. Ord a => a -> a -> Bool
> Posit256
1 = forall (es :: ES). PositC es => Posit es
NaR
  | Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
0 = forall a. Floating a => a
pi forall a. Num a => a -> a -> a
+ Posit256 -> Posit256
funAtan Posit256
invw
  | Posit256
x forall a. Eq a => a -> a -> Bool
== Posit256
0 = forall a. Floating a => a
piforall a. Fractional a => a -> a -> a
/Posit256
2
  | Posit256
x forall a. Ord a => a -> a -> Bool
> Posit256
0 = Posit256 -> Posit256
funAtan Posit256
invw
  | Bool
otherwise = forall a. HasCallStack => String -> a
error String
"Prove it covers for Rational Numbers."
    where
      invw :: Posit256
invw = forall a. Floating a => a -> a
sqrt (Posit256
1 forall a. Num a => a -> a -> a
- Posit256
xforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2) forall a. Fractional a => a -> a -> a
/ Posit256
x
--

-- fI2PN = (1 /) . (2 ^)
funInv2PowN :: Natural -> Posit256
funInv2PowN :: Natural -> Posit256
funInv2PowN Natural
n = Posit256
1 forall a. Fractional a => a -> a -> a
/ Posit256
2forall a b. (Num a, Integral b) => a -> b -> a
^Natural
n


-- calculate atanh(1/2^n)
-- sum k=0 to k=inf of the terms, iterate until a fixed point is reached
funArcHypTan :: Natural -> Posit256
funArcHypTan :: Natural -> Posit256
funArcHypTan Natural
0 = forall (es :: ES). PositC es => Posit es
NaR
funArcHypTan Natural
n
  | Natural
n forall a. Ord a => a -> a -> Bool
<= Natural
122 = Integer -> Posit256 -> Posit256
go Integer
0 Posit256
0
  | Bool
otherwise = Posit256
z  -- at small z... (atan z) == z "small angle approximation"
    where
      go :: Integer -> Posit256 -> Posit256
go !Integer
k !Posit256
acc
        | Posit256
acc forall a. Eq a => a -> a -> Bool
== (Posit256
acc forall a. Num a => a -> a -> a
+ Integer -> Posit256
term Integer
k) = Posit256
acc
        | Bool
otherwise = Integer -> Posit256 -> Posit256
go (Integer
kforall a. Num a => a -> a -> a
+Integer
1) (Posit256
acc forall a. Num a => a -> a -> a
+ Integer -> Posit256
term Integer
k)
      term :: Integer -> Posit256
      term :: Integer -> Posit256
term Integer
k = (Posit256
zforall a b. (Num a, Integral b) => a -> b -> a
^(Integer
2 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
1)) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
2 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
1)
      z :: Posit256
z = Posit256
1 forall a. Fractional a => a -> a -> a
/ Posit256
2forall a b. (Num a, Integral b) => a -> b -> a
^Natural
n


fac :: Natural -> Natural
fac :: Natural -> Natural
fac Natural
0 = Natural
1
fac Natural
n = Natural
n forall a. Num a => a -> a -> a
* Natural -> Natural
fac (Natural
n forall a. Num a => a -> a -> a
- Natural
1)

--
funAsinh :: Posit256 -> Posit256
funAsinh :: Posit256 -> Posit256
funAsinh Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funAsinh Posit256
x = forall a. Floating a => a -> a
log forall a b. (a -> b) -> a -> b
$ Posit256
x forall a. Num a => a -> a -> a
+ forall a. Floating a => a -> a
sqrt (Posit256
xforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
+ Posit256
1)
--

--
funAcosh :: Posit256 -> Posit256
funAcosh :: Posit256 -> Posit256
funAcosh Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funAcosh Posit256
x
  | Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
1 = forall (es :: ES). PositC es => Posit es
NaR
  | Bool
otherwise = forall a. Floating a => a -> a
log forall a b. (a -> b) -> a -> b
$ Posit256
x forall a. Num a => a -> a -> a
+ forall a. Floating a => a -> a
sqrt (Posit256
xforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
- Posit256
1)
--

--
funAtanh :: Posit256 -> Posit256
funAtanh :: Posit256 -> Posit256
funAtanh Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funAtanh Posit256
x
  | forall a. Num a => a -> a
abs Posit256
x forall a. Ord a => a -> a -> Bool
>= Posit256
1 = forall (es :: ES). PositC es => Posit es
NaR
  | Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
0 = forall a. Num a => a -> a
negateforall b c a. (b -> c) -> (a -> b) -> a -> c
.Posit256 -> Posit256
funAtanhforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. Num a => a -> a
negate forall a b. (a -> b) -> a -> b
$ Posit256
x  -- make use of odd parity to only calculate the positive part
  | Bool
otherwise = Posit256
0.5 forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
log ((Posit256
1forall a. Num a => a -> a -> a
+Posit256
t) forall a. Fractional a => a -> a -> a
/ (Posit256
1forall a. Num a => a -> a -> a
-Posit256
t)) forall a. Num a => a -> a -> a
- (forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
ex forall a. Fractional a => a -> a -> a
/ Posit256
2) forall a. Num a => a -> a -> a
* Posit256
lnOf2
    where
      (Integer
ex, Posit256
sig) = (Integer
int forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
2forall a b. (Num a, Integral b) => a -> b -> a
^(forall (es :: ES). PositC es => Natural
exponentSize @V)) forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Natural
nat forall a. Num a => a -> a -> a
+ Integer
1, forall a. Fractional a => Rational -> a
fromRational Rational
rat forall a. Fractional a => a -> a -> a
/ Posit256
2)
      (Bool
_,Integer
int,Natural
nat,Rational
rat) = (forall (es :: ES).
PositC es =>
Rational -> (Bool, Integer, Natural, Rational)
posit2TupPosit @V)forall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. Real a => a -> Rational
toRational forall a b. (a -> b) -> a -> b
$ Posit256
x' -- sign should always be positive
      x' :: Posit256
x' = Posit256
1 forall a. Num a => a -> a -> a
- Posit256
x
      t :: Posit256
t = (Posit256
2 forall a. Num a => a -> a -> a
- Posit256
sig forall a. Num a => a -> a -> a
- Posit256
x') forall a. Fractional a => a -> a -> a
/ (Posit256
2 forall a. Num a => a -> a -> a
+ Posit256
sig forall a. Num a => a -> a -> a
- Posit256
x')
--

--
funAtanhTaylor :: Posit256 -> Posit256
funAtanhTaylor :: Posit256 -> Posit256
funAtanhTaylor Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funAtanhTaylor Posit256
x
  | forall a. Num a => a -> a
abs Posit256
x forall a. Ord a => a -> a -> Bool
>= Posit256
1 = forall (es :: ES). PositC es => Posit es
NaR
  | forall a. Num a => a -> a
abs Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
1forall a. Fractional a => a -> a -> a
/Posit256
2forall a b. (Num a, Integral b) => a -> b -> a
^Integer
122 = Posit256
x  -- small angle approximaiton, found emperically
  | Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
0 = forall a. Num a => a -> a
negateforall b c a. (b -> c) -> (a -> b) -> a -> c
.Posit256 -> Posit256
funAtanhTaylorforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. Num a => a -> a
negate forall a b. (a -> b) -> a -> b
$ Posit256
x
  | Bool
otherwise = Integer -> Posit256 -> Posit256
go Integer
0 Posit256
0
    where
      go :: Integer -> Posit256 -> Posit256
go !Integer
k !Posit256
acc
        | Posit256
acc forall a. Eq a => a -> a -> Bool
== (Posit256
acc forall a. Num a => a -> a -> a
+ Integer -> Posit256
term Integer
k) = Posit256
acc
        | Bool
otherwise = Integer -> Posit256 -> Posit256
go (Integer
kforall a. Num a => a -> a -> a
+Integer
1) (Posit256
acc forall a. Num a => a -> a -> a
+ Integer -> Posit256
term Integer
k)
      term :: Integer -> Posit256
      term :: Integer -> Posit256
term Integer
k = (Posit256
xforall a b. (Num a, Integral b) => a -> b -> a
^(Integer
2 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
1)) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
2 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
1)
--

--
funSin :: Posit256 -> Posit256
funSin :: Posit256 -> Posit256
funSin Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funSin Posit256
0 = Posit256
0
funSin Posit256
x = Posit256 -> Posit256
funSin' forall a b. (a -> b) -> a -> b
$ Posit256
x forall a. Fractional a => a -> a -> a
/ (Posit256
2forall a. Num a => a -> a -> a
*forall a. Floating a => a
pi)
--
-- funSin' is sine normalized by 2*pi
funSin' :: Posit256 -> Posit256
funSin' :: Posit256 -> Posit256
funSin' Posit256
x
  | Posit256
x forall a. Eq a => a -> a -> Bool
== Posit256
0 = Posit256
0
  | Posit256
x forall a. Eq a => a -> a -> Bool
== Posit256
0.25 = Posit256
1
  | Posit256
x forall a. Eq a => a -> a -> Bool
== Posit256
0.5 = Posit256
0
  | Posit256
x forall a. Eq a => a -> a -> Bool
== Posit256
0.75 = -Posit256
1
  | Posit256
x forall a. Eq a => a -> a -> Bool
== Posit256
1 = Posit256
0
  | Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
0 = forall a. Num a => a -> a
negateforall b c a. (b -> c) -> (a -> b) -> a -> c
.Posit256 -> Posit256
funSin'forall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. Num a => a -> a
negate forall a b. (a -> b) -> a -> b
$ Posit256
x
  | Posit256
x forall a. Ord a => a -> a -> Bool
> Posit256
1 =
    let (Integer
_,Posit256
rem) = forall a b. (RealFrac a, Integral b) => a -> (b, a)
properFraction Posit256
x
    in Posit256 -> Posit256
funSin' Posit256
rem
  | Posit256
x forall a. Ord a => a -> a -> Bool
> Posit256
0.75 Bool -> Bool -> Bool
&& Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
1 = forall a. Num a => a -> a
negateforall b c a. (b -> c) -> (a -> b) -> a -> c
.Posit256 -> Posit256
funSin' forall a b. (a -> b) -> a -> b
$ Posit256
1 forall a. Num a => a -> a -> a
- Posit256
x -- reduce domain by quadrant symmetry
  | Posit256
x forall a. Ord a => a -> a -> Bool
> Posit256
0.5 Bool -> Bool -> Bool
&& Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
0.75 = forall a. Num a => a -> a
negateforall b c a. (b -> c) -> (a -> b) -> a -> c
.Posit256 -> Posit256
funSin' forall a b. (a -> b) -> a -> b
$ Posit256
x forall a. Num a => a -> a -> a
- Posit256
0.5
  | Posit256
x forall a. Ord a => a -> a -> Bool
> Posit256
0.25 Bool -> Bool -> Bool
&& Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
0.5 = Posit256 -> Posit256
funSin' forall a b. (a -> b) -> a -> b
$ Posit256
0.5 forall a. Num a => a -> a -> a
- Posit256
x
  | Posit256
x forall a. Ord a => a -> a -> Bool
> Posit256
0.125 Bool -> Bool -> Bool
&& Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
0.25 = Posit256 -> Posit256
funCosTuma forall a b. (a -> b) -> a -> b
$ Posit256
2forall a. Num a => a -> a -> a
*forall a. Floating a => a
pi forall a. Num a => a -> a -> a
* (Posit256
0.25 forall a. Num a => a -> a -> a
- Posit256
x) -- reduce domain and use cofunction
  | Bool
otherwise = Posit256 -> Posit256
funSinTuma forall a b. (a -> b) -> a -> b
$ Posit256
2forall a. Num a => a -> a -> a
*forall a. Floating a => a
pi forall a. Num a => a -> a -> a
* Posit256
x
--

-- Taylor series expansion and fixed point algorithm, most accurate near zero
funSinTaylor :: Posit256 -> Posit256
funSinTaylor :: Posit256 -> Posit256
funSinTaylor Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funSinTaylor Posit256
z = Natural -> Posit256 -> Posit256
go Natural
0 Posit256
0
  where
    go :: Natural -> Posit256 -> Posit256
    go :: Natural -> Posit256 -> Posit256
go !Natural
k !Posit256
acc
      | Posit256
acc forall a. Eq a => a -> a -> Bool
== (Posit256
acc forall a. Num a => a -> a -> a
+ Natural -> Posit256
term Natural
k) = Posit256
acc
      | Bool
otherwise = Natural -> Posit256 -> Posit256
go (Natural
kforall a. Num a => a -> a -> a
+Natural
1) (Posit256
acc forall a. Num a => a -> a -> a
+ Natural -> Posit256
term Natural
k)
    term :: Natural -> Posit256
    term :: Natural -> Posit256
term Natural
k = (-Posit256
1)forall a b. (Num a, Integral b) => a -> b -> a
^Natural
k forall a. Num a => a -> a -> a
* Posit256
zforall a b. (Num a, Integral b) => a -> b -> a
^(Natural
2forall a. Num a => a -> a -> a
*Natural
kforall a. Num a => a -> a -> a
+Natural
1) forall a. Fractional a => a -> a -> a
/ (forall a b. (Integral a, Num b) => a -> b
fromIntegralforall b c a. (b -> c) -> (a -> b) -> a -> c
.Natural -> Natural
fac forall a b. (a -> b) -> a -> b
$ Natural
2forall a. Num a => a -> a -> a
*Natural
kforall a. Num a => a -> a -> a
+Natural
1)
--

--
funSinTuma :: Posit256 -> Posit256
funSinTuma :: Posit256 -> Posit256
funSinTuma Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funSinTuma Posit256
z = Natural -> Posit256 -> Posit256
go Natural
19 Posit256
1
  where
    go :: Natural -> Posit256 -> Posit256
    go :: Natural -> Posit256 -> Posit256
go Natural
1 !Posit256
acc = Posit256
z forall a. Num a => a -> a -> a
* Posit256
acc
    go !Natural
k !Posit256
acc = Natural -> Posit256 -> Posit256
go (Natural
kforall a. Num a => a -> a -> a
-Natural
1) (Posit256
1 forall a. Num a => a -> a -> a
- (Posit256
zforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Natural
2forall a. Num a => a -> a -> a
*Natural
kforall a. Num a => a -> a -> a
-Natural
2)forall a. Num a => a -> a -> a
*(Natural
2forall a. Num a => a -> a -> a
*Natural
kforall a. Num a => a -> a -> a
-Natural
1))) forall a. Num a => a -> a -> a
* Posit256
acc)
--

--
funCos :: Posit256 -> Posit256
funCos :: Posit256 -> Posit256
funCos Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funCos Posit256
0 = Posit256
1
funCos Posit256
x = Posit256 -> Posit256
funCos' forall a b. (a -> b) -> a -> b
$ Posit256
x forall a. Fractional a => a -> a -> a
/ (Posit256
2forall a. Num a => a -> a -> a
*forall a. Floating a => a
pi)
--
-- funCos' is cosine normalized for 2*pi
funCos' :: Posit256 -> Posit256
funCos' :: Posit256 -> Posit256
funCos' Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funCos' Posit256
x
  | Posit256
x forall a. Eq a => a -> a -> Bool
== Posit256
0 = Posit256
1
  | Posit256
x forall a. Eq a => a -> a -> Bool
== Posit256
0.25 = Posit256
0
  | Posit256
x forall a. Eq a => a -> a -> Bool
== Posit256
0.5 = -Posit256
1
  | Posit256
x forall a. Eq a => a -> a -> Bool
== Posit256
0.75 = Posit256
0
  | Posit256
x forall a. Eq a => a -> a -> Bool
== Posit256
1 = Posit256
1
  | Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
0 = Posit256 -> Posit256
funCos'forall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. Num a => a -> a
negate forall a b. (a -> b) -> a -> b
$ Posit256
x  -- reduce domain by symmetry across 0 to turn x positive
  | Posit256
x forall a. Ord a => a -> a -> Bool
> Posit256
1 = -- reduce domain by using perodicity
    let (Integer
_,Posit256
rem) = forall a b. (RealFrac a, Integral b) => a -> (b, a)
properFraction Posit256
x
    in Posit256 -> Posit256
funCos' Posit256
rem
  | Posit256
x forall a. Ord a => a -> a -> Bool
> Posit256
0.75 Bool -> Bool -> Bool
&& Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
1 = Posit256 -> Posit256
funCos' forall a b. (a -> b) -> a -> b
$ Posit256
1 forall a. Num a => a -> a -> a
- Posit256
x  -- reduce domain by quadrant symmetry
  | Posit256
x forall a. Ord a => a -> a -> Bool
> Posit256
0.5 Bool -> Bool -> Bool
&& Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
0.75 = forall a. Num a => a -> a
negateforall b c a. (b -> c) -> (a -> b) -> a -> c
.Posit256 -> Posit256
funCos' forall a b. (a -> b) -> a -> b
$ Posit256
x forall a. Num a => a -> a -> a
- Posit256
0.5
  | Posit256
x forall a. Ord a => a -> a -> Bool
> Posit256
0.25 Bool -> Bool -> Bool
&& Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
0.5 = forall a. Num a => a -> a
negateforall b c a. (b -> c) -> (a -> b) -> a -> c
.Posit256 -> Posit256
funCos' forall a b. (a -> b) -> a -> b
$ Posit256
0.5 forall a. Num a => a -> a -> a
- Posit256
x
  | Posit256
x forall a. Ord a => a -> a -> Bool
> Posit256
0.125 Bool -> Bool -> Bool
&& Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
0.25 = Posit256 -> Posit256
funSinTuma forall a b. (a -> b) -> a -> b
$ Posit256
2forall a. Num a => a -> a -> a
*forall a. Floating a => a
pi forall a. Num a => a -> a -> a
* (Posit256
0.25 forall a. Num a => a -> a -> a
- Posit256
x) -- reduce domain and use cofunction
  | Bool
otherwise = Posit256 -> Posit256
funCosTuma forall a b. (a -> b) -> a -> b
$ Posit256
2forall a. Num a => a -> a -> a
*forall a. Floating a => a
pi forall a. Num a => a -> a -> a
* Posit256
x --
--

-- Taylor series expansion and fixed point algorithm, most accurate near zero
funCosTaylor :: Posit256 -> Posit256
funCosTaylor :: Posit256 -> Posit256
funCosTaylor Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funCosTaylor Posit256
z = Natural -> Posit256 -> Posit256
go Natural
0 Posit256
0
  where
    go :: Natural -> Posit256 -> Posit256
    go :: Natural -> Posit256 -> Posit256
go !Natural
k !Posit256
acc
      | Posit256
acc forall a. Eq a => a -> a -> Bool
== (Posit256
acc forall a. Num a => a -> a -> a
+ Natural -> Posit256
term Natural
k) = Posit256
acc
      | Bool
otherwise = Natural -> Posit256 -> Posit256
go (Natural
kforall a. Num a => a -> a -> a
+Natural
1) (Posit256
acc forall a. Num a => a -> a -> a
+ Natural -> Posit256
term Natural
k)
    term :: Natural -> Posit256
    term :: Natural -> Posit256
term Natural
k = (-Posit256
1)forall a b. (Num a, Integral b) => a -> b -> a
^Natural
k forall a. Num a => a -> a -> a
* Posit256
zforall a b. (Num a, Integral b) => a -> b -> a
^(Natural
2forall a. Num a => a -> a -> a
*Natural
k) forall a. Fractional a => a -> a -> a
/ (forall a b. (Integral a, Num b) => a -> b
fromIntegralforall b c a. (b -> c) -> (a -> b) -> a -> c
.Natural -> Natural
fac forall a b. (a -> b) -> a -> b
$ Natural
2forall a. Num a => a -> a -> a
*Natural
k)
--

--
funCosTuma :: Posit256 -> Posit256
funCosTuma :: Posit256 -> Posit256
funCosTuma Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funCosTuma Posit256
z = Natural -> Posit256 -> Posit256
go Natural
19 Posit256
1
  where
    go :: Natural -> Posit256 -> Posit256
    go :: Natural -> Posit256 -> Posit256
go Natural
1 !Posit256
acc = Posit256
acc
    go !Natural
k !Posit256
acc = Natural -> Posit256 -> Posit256
go (Natural
kforall a. Num a => a -> a -> a
-Natural
1) (Posit256
1 forall a. Num a => a -> a -> a
- (Posit256
zforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Natural
2forall a. Num a => a -> a -> a
*Natural
kforall a. Num a => a -> a -> a
-Natural
3)forall a. Num a => a -> a -> a
*(Natural
2forall a. Num a => a -> a -> a
*Natural
kforall a. Num a => a -> a -> a
-Natural
2))) forall a. Num a => a -> a -> a
* Posit256
acc)
--

-- ~16 ULP for 42
funSinh :: Posit256 -> Posit256
funSinh :: Posit256 -> Posit256
funSinh Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funSinh Posit256
x = (forall a. Floating a => a -> a
exp Posit256
x forall a. Num a => a -> a -> a
- forall a. Floating a => a -> a
exp (forall a. Num a => a -> a
negate Posit256
x))forall a. Fractional a => a -> a -> a
/Posit256
2
--

-- ~2 ULP for 42
funSinhTaylor :: Posit256 -> Posit256
funSinhTaylor :: Posit256 -> Posit256
funSinhTaylor Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funSinhTaylor Posit256
z = Natural -> Posit256 -> Posit256
go Natural
0 Posit256
0
  where
    go :: Natural -> Posit256 -> Posit256
    go :: Natural -> Posit256 -> Posit256
go !Natural
k !Posit256
acc
      | Posit256
acc forall a. Eq a => a -> a -> Bool
== (Posit256
acc forall a. Num a => a -> a -> a
+ Natural -> Posit256
term Natural
k) = Posit256
acc
      | Bool
otherwise = Natural -> Posit256 -> Posit256
go (Natural
kforall a. Num a => a -> a -> a
+Natural
1) (Posit256
acc forall a. Num a => a -> a -> a
+ Natural -> Posit256
term Natural
k)
    term :: Natural -> Posit256
    term :: Natural -> Posit256
term Natural
k = Posit256
zforall a b. (Num a, Integral b) => a -> b -> a
^(Natural
2forall a. Num a => a -> a -> a
*Natural
kforall a. Num a => a -> a -> a
+Natural
1) forall a. Fractional a => a -> a -> a
/ (forall a b. (Integral a, Num b) => a -> b
fromIntegralforall b c a. (b -> c) -> (a -> b) -> a -> c
.Natural -> Natural
fac forall a b. (a -> b) -> a -> b
$ Natural
2forall a. Num a => a -> a -> a
*Natural
kforall a. Num a => a -> a -> a
+Natural
1)
--

--
funSinhTuma :: Posit256 -> Posit256
funSinhTuma :: Posit256 -> Posit256
funSinhTuma Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funSinhTuma Posit256
0 = Posit256
0
funSinhTuma Posit256
z | Posit256
z forall a. Ord a => a -> a -> Bool
< Posit256
0 = forall a. Num a => a -> a
negateforall b c a. (b -> c) -> (a -> b) -> a -> c
.Posit256 -> Posit256
funSinhTumaforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. Num a => a -> a
negate forall a b. (a -> b) -> a -> b
$ Posit256
z
funSinhTuma Posit256
z | Posit256
z forall a. Ord a => a -> a -> Bool
> Posit256
80 = Posit256
0.5 forall a. Num a => a -> a -> a
* Posit256 -> Posit256
funExpTuma Posit256
z
funSinhTuma Posit256
z = Natural -> Posit256 -> Posit256
go Natural
256 Posit256
1
  where
    go :: Natural -> Posit256 -> Posit256
    go :: Natural -> Posit256 -> Posit256
go Natural
1 !Posit256
acc = Posit256
z forall a. Num a => a -> a -> a
* Posit256
acc
    go !Natural
k !Posit256
acc = Natural -> Posit256 -> Posit256
go (Natural
kforall a. Num a => a -> a -> a
-Natural
1) (Posit256
1 forall a. Num a => a -> a -> a
+ (Posit256
zforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Natural
2forall a. Num a => a -> a -> a
*Natural
kforall a. Num a => a -> a -> a
-Natural
2) forall a. Num a => a -> a -> a
* (Natural
2forall a. Num a => a -> a -> a
*Natural
kforall a. Num a => a -> a -> a
-Natural
1))) forall a. Num a => a -> a -> a
* Posit256
acc)
--

-- ~17 ULP for 42
funCosh :: Posit256 -> Posit256
funCosh :: Posit256 -> Posit256
funCosh Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funCosh Posit256
x = (forall a. Floating a => a -> a
exp Posit256
x forall a. Num a => a -> a -> a
+ forall a. Floating a => a -> a
exp (forall a. Num a => a -> a
negate Posit256
x))forall a. Fractional a => a -> a -> a
/Posit256
2
--

-- ~3 ULP for 42
funCoshTaylor :: Posit256 -> Posit256
funCoshTaylor :: Posit256 -> Posit256
funCoshTaylor Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funCoshTaylor Posit256
z = Natural -> Posit256 -> Posit256
go Natural
0 Posit256
0
  where
    go :: Natural -> Posit256 -> Posit256
    go :: Natural -> Posit256 -> Posit256
go !Natural
k !Posit256
acc
      | Posit256
acc forall a. Eq a => a -> a -> Bool
== (Posit256
acc forall a. Num a => a -> a -> a
+ Natural -> Posit256
term Natural
k) = Posit256
acc
      | Bool
otherwise = Natural -> Posit256 -> Posit256
go (Natural
kforall a. Num a => a -> a -> a
+Natural
1) (Posit256
acc forall a. Num a => a -> a -> a
+ Natural -> Posit256
term Natural
k)
    term :: Natural -> Posit256
    term :: Natural -> Posit256
term Natural
k = Posit256
zforall a b. (Num a, Integral b) => a -> b -> a
^(Natural
2forall a. Num a => a -> a -> a
*Natural
k) forall a. Fractional a => a -> a -> a
/ (forall a b. (Integral a, Num b) => a -> b
fromIntegralforall b c a. (b -> c) -> (a -> b) -> a -> c
.Natural -> Natural
fac forall a b. (a -> b) -> a -> b
$ Natural
2forall a. Num a => a -> a -> a
*Natural
k)
--

--
funCoshTuma :: Posit256 -> Posit256
funCoshTuma :: Posit256 -> Posit256
funCoshTuma Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funCoshTuma Posit256
0 = Posit256
1
funCoshTuma Posit256
z | Posit256
z forall a. Ord a => a -> a -> Bool
< Posit256
0 = Posit256 -> Posit256
funCoshTumaforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. Num a => a -> a
negate forall a b. (a -> b) -> a -> b
$ Posit256
z
funCoshTuma Posit256
z | Posit256
z forall a. Ord a => a -> a -> Bool
> Posit256
3 = Posit256
0.5 forall a. Num a => a -> a -> a
* (Posit256 -> Posit256
funExpTuma Posit256
z forall a. Num a => a -> a -> a
+ Posit256 -> Posit256
funExpTuma (forall a. Num a => a -> a
negate Posit256
z))
funCoshTuma Posit256
z = Natural -> Posit256 -> Posit256
go Natural
20 Posit256
1
  where
    go :: Natural -> Posit256 -> Posit256
    go :: Natural -> Posit256 -> Posit256
go Natural
1 !Posit256
acc = Posit256
acc
    go !Natural
k !Posit256
acc = Natural -> Posit256 -> Posit256
go (Natural
kforall a. Num a => a -> a -> a
-Natural
1) (Posit256
1 forall a. Num a => a -> a -> a
+ (Posit256
zforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Natural
2forall a. Num a => a -> a -> a
*Natural
kforall a. Num a => a -> a -> a
-Natural
3)forall a. Num a => a -> a -> a
*(Natural
2forall a. Num a => a -> a -> a
*Natural
kforall a. Num a => a -> a -> a
-Natural
2)))forall a. Num a => a -> a -> a
*Posit256
acc)
--


--
funLog :: Posit256 -> Posit256
funLog :: Posit256 -> Posit256
funLog Posit256
x = Posit256 -> Posit256
funLog2 Posit256
x forall a. Num a => a -> a -> a
* Posit256
lnOf2
--

--
-- Use the constant, for performance
lnOf2 :: Posit256
lnOf2 :: Posit256
lnOf2 = Posit256
0.6931471805599453094172321214581765680755001343602552541206800094933936219696947156058633269964186875420014810205706857336855202
--

--
-- Some series don't converge reliably, this one does
funLnOf2 :: Posit256
funLnOf2 :: Posit256
funLnOf2 = Natural -> Posit256 -> Posit256
go Natural
1 Posit256
0
  where
    go :: Natural -> Posit256 -> Posit256
    go :: Natural -> Posit256 -> Posit256
go !Natural
k !Posit256
acc
      | Posit256
acc forall a. Eq a => a -> a -> Bool
== (Posit256
acc forall a. Num a => a -> a -> a
+ Natural -> Posit256
term Natural
k) = Posit256
acc
      | Bool
otherwise = Natural -> Posit256 -> Posit256
go (Natural
kforall a. Num a => a -> a -> a
+Natural
1) (Posit256
acc forall a. Num a => a -> a -> a
+ Natural -> Posit256
term Natural
k)
    term :: Natural -> Posit256
    term :: Natural -> Posit256
term Natural
k = Posit256
1 forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral (Natural
2forall a b. (Num a, Integral b) => a -> b -> a
^Natural
k forall a. Num a => a -> a -> a
* Natural
k)
--

--
funLog2 :: Posit256 -> Posit256
funLog2 :: Posit256 -> Posit256
funLog2 Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funLog2 Posit256
z
  | Posit256
z forall a. Ord a => a -> a -> Bool
<= Posit256
0 = forall (es :: ES). PositC es => Posit es
NaR -- includes the NaR case
  | Bool
otherwise = Posit256 -> Posit256 -> Posit256 -> Posit256
go (forall a. Num a => Integer -> a
fromInteger Integer
ex) Posit256
1 Posit256
sig  -- domain reduction
    where
      go :: Posit256 -> Posit256 -> Posit256 -> Posit256
      go :: Posit256 -> Posit256 -> Posit256 -> Posit256
go !Posit256
acc !Posit256
mak !Posit256
sig' -- fixed point iteration, y is [1,2) :: Posit256
        | Posit256
sig forall a. Eq a => a -> a -> Bool
== Posit256
1 = Posit256
acc
        | Posit256
acc forall a. Eq a => a -> a -> Bool
== (Posit256
acc forall a. Num a => a -> a -> a
+ Posit256
mak forall a. Num a => a -> a -> a
* Posit256
2forall a b. (Fractional a, Integral b) => a -> b -> a
^^(forall a. Num a => a -> a
negateforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a b. (a, b) -> a
fstforall b c a. (b -> c) -> (a -> b) -> a -> c
.Posit256 -> (Integer, Posit256)
term forall a b. (a -> b) -> a -> b
$ Posit256
sig')) = Posit256
acc  -- stop when fixed point is reached
        | Bool
otherwise = Posit256 -> Posit256 -> Posit256 -> Posit256
go (Posit256
acc forall a. Num a => a -> a -> a
+ Posit256
mak forall a. Num a => a -> a -> a
* Posit256
2forall a b. (Fractional a, Integral b) => a -> b -> a
^^(forall a. Num a => a -> a
negateforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a b. (a, b) -> a
fstforall b c a. (b -> c) -> (a -> b) -> a -> c
.Posit256 -> (Integer, Posit256)
term forall a b. (a -> b) -> a -> b
$ Posit256
sig')) (Posit256
mak forall a. Num a => a -> a -> a
* Posit256
2forall a b. (Fractional a, Integral b) => a -> b -> a
^^(forall a. Num a => a -> a
negateforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a b. (a, b) -> a
fstforall b c a. (b -> c) -> (a -> b) -> a -> c
.Posit256 -> (Integer, Posit256)
term forall a b. (a -> b) -> a -> b
$ Posit256
sig')) (forall a b. (a, b) -> b
sndforall b c a. (b -> c) -> (a -> b) -> a -> c
.Posit256 -> (Integer, Posit256)
term forall a b. (a -> b) -> a -> b
$ Posit256
sig')
      term :: Posit256 -> (Integer, Posit256)
term = forall {t} {t}. (Fractional t, Num t, Ord t) => t -> t -> (t, t)
findSquaring Integer
0  -- returns (m,s') m the number of times to square, and the new significand
      (Integer
ex, Posit256
sig) = (Integer
int forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
2forall a b. (Num a, Integral b) => a -> b -> a
^(forall (es :: ES). PositC es => Natural
exponentSize @V)) forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Natural
nat, forall a. Fractional a => Rational -> a
fromRational Rational
rat)
      (Bool
_,Integer
int,Natural
nat,Rational
rat) = (forall (es :: ES).
PositC es =>
Rational -> (Bool, Integer, Natural, Rational)
posit2TupPosit @V)forall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. Real a => a -> Rational
toRational forall a b. (a -> b) -> a -> b
$ Posit256
z -- sign should always be positive
      findSquaring :: t -> t -> (t, t)
findSquaring t
m t
s
        | t
s forall a. Ord a => a -> a -> Bool
>= t
2 Bool -> Bool -> Bool
&& t
s forall a. Ord a => a -> a -> Bool
< t
4 = (t
m, t
sforall a. Fractional a => a -> a -> a
/t
2)
        | Bool
otherwise = t -> t -> (t, t)
findSquaring (t
mforall a. Num a => a -> a -> a
+t
1) (t
sforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2)
--


--  Gauss–Legendre algorithm, Seems only accurate to 2-3 ULP, but really slow
funPi1 :: Posit256
funPi1 :: Posit256
funPi1 = Posit256
-> Posit256
-> Posit256
-> Posit256
-> Posit256
-> Posit256
-> Posit256
go Posit256
0 Posit256
3 Posit256
1 (forall a. Fractional a => a -> a
recipforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. Floating a => a -> a
sqrt forall a b. (a -> b) -> a -> b
$ Posit256
2) (forall a. Fractional a => a -> a
recip Posit256
4) Posit256
1
  where
    go :: Posit256 -> Posit256 -> Posit256 -> Posit256 -> Posit256 -> Posit256 -> Posit256
    go :: Posit256
-> Posit256
-> Posit256
-> Posit256
-> Posit256
-> Posit256
-> Posit256
go !Posit256
prev !Posit256
next !Posit256
a !Posit256
b !Posit256
t !Posit256
p
      | Posit256
prev forall a. Eq a => a -> a -> Bool
== Posit256
next = Posit256
next
      | Bool
otherwise =
        let a' :: Posit256
a' = (Posit256
a forall a. Num a => a -> a -> a
+ Posit256
b) forall a. Fractional a => a -> a -> a
/ Posit256
2
            b' :: Posit256
b' = forall a. Floating a => a -> a
sqrt forall a b. (a -> b) -> a -> b
$ Posit256
a forall a. Num a => a -> a -> a
* Posit256
b
            t' :: Posit256
t' = Posit256
t forall a. Num a => a -> a -> a
- Posit256
p forall a. Num a => a -> a -> a
* (Posit256
a forall a. Num a => a -> a -> a
- ((Posit256
a forall a. Num a => a -> a -> a
+ Posit256
b) forall a. Fractional a => a -> a -> a
/ Posit256
2))forall a b. (Num a, Integral b) => a -> b -> a
^Integer
2
            p' :: Posit256
p' = Posit256
2 forall a. Num a => a -> a -> a
* Posit256
p
        in Posit256
-> Posit256
-> Posit256
-> Posit256
-> Posit256
-> Posit256
-> Posit256
go Posit256
next ((Posit256
a' forall a. Num a => a -> a -> a
+ Posit256
b')forall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Fractional a => a -> a -> a
/ (Posit256
4 forall a. Num a => a -> a -> a
* Posit256
t')) Posit256
a' Posit256
b' Posit256
t' Posit256
p'
--

#ifndef O_NO_SHOW
--  Borwein's algorithm, with quintic convergence,
--  gets to 7 ULP in 4 iterations, but really slow due to expensive function evaluations
--  quite unstable and will not converge if sqrt is not accurate, which means log must be accurate
funPi2 :: Posit256
funPi2 :: Posit256
funPi2 = forall a. Fractional a => a -> a
recip forall a b. (a -> b) -> a -> b
$ Posit256 -> Posit256 -> Natural -> Posit256 -> Posit256 -> Posit256
go Posit256
0 Posit256
0 Natural
0 Posit256
0.5 (Posit256
5 forall a. Fractional a => a -> a -> a
/ forall p. AltFloating p => p
phiforall a b. (Num a, Integral b) => a -> b -> a
^Integer
3)
  where
    go :: Posit256 -> Posit256 -> Natural -> Posit256 -> Posit256 -> Posit256
    go :: Posit256 -> Posit256 -> Natural -> Posit256 -> Posit256 -> Posit256
go !Posit256
prevA !Posit256
prevS !Natural
n !Posit256
a !Posit256
s
      | Posit256
prevA forall a. Eq a => a -> a -> Bool
== Posit256
a = Posit256
a
      | Posit256
prevS forall a. Eq a => a -> a -> Bool
== Posit256
s = Posit256
a
      | Bool
otherwise =
        let x :: Posit256
x = Posit256
5 forall a. Fractional a => a -> a -> a
/ Posit256
s forall a. Num a => a -> a -> a
- Posit256
1
            y :: Posit256
y = (Posit256
x forall a. Num a => a -> a -> a
- Posit256
1)forall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
+ Posit256
7
            z :: Posit256
z = (Posit256
0.5 forall a. Num a => a -> a -> a
* Posit256
x forall a. Num a => a -> a -> a
* (Posit256
y forall a. Num a => a -> a -> a
+ forall a. Floating a => a -> a
sqrt (Posit256
yforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
- Posit256
4 forall a. Num a => a -> a -> a
* Posit256
xforall a b. (Num a, Integral b) => a -> b -> a
^Integer
3)))forall a. Floating a => a -> a -> a
**(Posit256
1forall a. Fractional a => a -> a -> a
/Posit256
5)
            a' :: Posit256
a' = Posit256
sforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
* Posit256
a forall a. Num a => a -> a -> a
- (Posit256
5forall a b. (Num a, Integral b) => a -> b -> a
^Natural
n forall a. Num a => a -> a -> a
* ((Posit256
sforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
- Posit256
5)forall a. Fractional a => a -> a -> a
/Posit256
2 forall a. Num a => a -> a -> a
+ forall a. Floating a => a -> a
sqrt (Posit256
s forall a. Num a => a -> a -> a
* (Posit256
sforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
- Posit256
2forall a. Num a => a -> a -> a
*Posit256
s forall a. Num a => a -> a -> a
+ Posit256
5))))
            s' :: Posit256
s' = Posit256
25 forall a. Fractional a => a -> a -> a
/ ((Posit256
z forall a. Num a => a -> a -> a
+ Posit256
xforall a. Fractional a => a -> a -> a
/Posit256
z forall a. Num a => a -> a -> a
+ Posit256
1)forall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
* Posit256
s)
        in Posit256 -> Posit256 -> Natural -> Posit256 -> Posit256 -> Posit256
go Posit256
a Posit256
s (Natural
nforall a. Num a => a -> a -> a
+Natural
1) (forall a. String -> a -> a
trace (String
"ΔA: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Posit256
a' forall a. Num a => a -> a -> a
- Posit256
a)) Posit256
a') (forall a. String -> a -> a
trace (String
"ΔS: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (Posit256
s' forall a. Num a => a -> a -> a
- Posit256
s)) Posit256
s')
--
#endif


-- Bailey–Borwein–Plouffe (BBP) formula, to 1-2 ULP, and blazing fast, converges in 60 iterations
funPi3 :: Posit256
funPi3 :: Posit256
funPi3 = Integer -> Posit256 -> Posit256
go Integer
0 Posit256
0
  where
    go :: Integer -> Posit256 -> Posit256
    go :: Integer -> Posit256 -> Posit256
go !Integer
k !Posit256
acc
      | Posit256
acc forall a. Eq a => a -> a -> Bool
== Posit256
acc forall a. Num a => a -> a -> a
+ Integer -> Posit256
term Integer
k = Posit256
acc
      | Bool
otherwise = Integer -> Posit256 -> Posit256
go (Integer
kforall a. Num a => a -> a -> a
+Integer
1) (Posit256
acc forall a. Num a => a -> a -> a
+ Integer -> Posit256
term Integer
k)
    term :: Integer -> Posit256
    term :: Integer -> Posit256
term Integer
k = forall a. Fractional a => Rational -> a
fromRational forall a b. (a -> b) -> a -> b
$ (Integer
1 forall a. Integral a => a -> a -> Ratio a
% Integer
16forall a b. (Num a, Integral b) => a -> b -> a
^Integer
k) forall a. Num a => a -> a -> a
* ((Integer
120 forall a. Num a => a -> a -> a
* Integer
kforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
+ Integer
151 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
47) forall a. Integral a => a -> a -> Ratio a
% (Integer
512 forall a. Num a => a -> a -> a
* Integer
kforall a b. (Num a, Integral b) => a -> b -> a
^Integer
4 forall a. Num a => a -> a -> a
+ Integer
1024 forall a. Num a => a -> a -> a
* Integer
kforall a b. (Num a, Integral b) => a -> b -> a
^Integer
3 forall a. Num a => a -> a -> a
+ Integer
712 forall a. Num a => a -> a -> a
* Integer
kforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
+ Integer
194 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
15))
--


-- Fabrice Bellard improvement on the BBP, 2-3 ULP, even faster, converges in 25 iterations, really fast
funPi4 :: Posit256
funPi4 :: Posit256
funPi4 = (Posit256
1forall a. Fractional a => a -> a -> a
/Posit256
2forall a b. (Num a, Integral b) => a -> b -> a
^Integer
6) forall a. Num a => a -> a -> a
* Integer -> Posit256 -> Posit256
go Integer
0 Posit256
0
  where
    go :: Integer -> Posit256 -> Posit256
    go :: Integer -> Posit256 -> Posit256
go !Integer
k !Posit256
acc
      | Posit256
acc forall a. Eq a => a -> a -> Bool
== Posit256
acc forall a. Num a => a -> a -> a
+ Integer -> Posit256
term Integer
k = Posit256
acc
      | Bool
otherwise = Integer -> Posit256 -> Posit256
go (Integer
kforall a. Num a => a -> a -> a
+Integer
1) (Posit256
acc forall a. Num a => a -> a -> a
+ Integer -> Posit256
term Integer
k)
    term :: Integer -> Posit256
    term :: Integer -> Posit256
term Integer
k = forall a. Fractional a => Rational -> a
fromRational forall a b. (a -> b) -> a -> b
$ ((-Integer
1)forall a b. (Num a, Integral b) => a -> b -> a
^Integer
k forall a. Integral a => a -> a -> Ratio a
% (Integer
2forall a b. (Num a, Integral b) => a -> b -> a
^(Integer
10forall a. Num a => a -> a -> a
*Integer
k))) forall a. Num a => a -> a -> a
* ((Integer
1 forall a. Integral a => a -> a -> Ratio a
% (Integer
10 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
9)) forall a. Num a => a -> a -> a
- (Integer
2forall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Integral a => a -> a -> Ratio a
% (Integer
10 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
7)) forall a. Num a => a -> a -> a
- (Integer
2forall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Integral a => a -> a -> Ratio a
% (Integer
10 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
5)) forall a. Num a => a -> a -> a
- (Integer
2forall a b. (Num a, Integral b) => a -> b -> a
^Integer
6 forall a. Integral a => a -> a -> Ratio a
% (Integer
10 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
3)) forall a. Num a => a -> a -> a
+ (Integer
2forall a b. (Num a, Integral b) => a -> b -> a
^Integer
8 forall a. Integral a => a -> a -> Ratio a
% (Integer
10 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
1)) forall a. Num a => a -> a -> a
- (Integer
1 forall a. Integral a => a -> a -> Ratio a
% (Integer
4 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
3)) forall a. Num a => a -> a -> a
- (Integer
2forall a b. (Num a, Integral b) => a -> b -> a
^Integer
5 forall a. Integral a => a -> a -> Ratio a
% (Integer
4 forall a. Num a => a -> a -> a
* Integer
k forall a. Num a => a -> a -> a
+ Integer
1)))
--


-- Borwin's Quadradic Alogrithm 1985
funPi5 :: Posit256
funPi5 :: Posit256
funPi5 = forall a. Fractional a => a -> a
recip forall a b. (a -> b) -> a -> b
$ Posit256 -> Posit256 -> Natural -> Posit256 -> Posit256 -> Posit256
go Posit256
0 Posit256
0 Natural
1 (Posit256
6 forall a. Num a => a -> a -> a
- Posit256
4 forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
sqrt Posit256
2) (forall a. Floating a => a -> a
sqrt Posit256
2 forall a. Num a => a -> a -> a
- Posit256
1)
  where
    go :: Posit256 -> Posit256 -> Natural -> Posit256 -> Posit256 -> Posit256
    go :: Posit256 -> Posit256 -> Natural -> Posit256 -> Posit256 -> Posit256
go !Posit256
prevA !Posit256
prevY !Natural
n Posit256
a Posit256
y
      | Posit256
prevA forall a. Eq a => a -> a -> Bool
== Posit256
a = Posit256
a
      | Posit256
prevY forall a. Eq a => a -> a -> Bool
== Posit256
y = Posit256
a
      | Bool
otherwise =
        let f :: Posit256
f = (Posit256
1 forall a. Num a => a -> a -> a
- Posit256
yforall a b. (Num a, Integral b) => a -> b -> a
^Integer
4)forall a. Floating a => a -> a -> a
**(Posit256
1forall a. Fractional a => a -> a -> a
/Posit256
4)
            y' :: Posit256
y' = (Posit256
1 forall a. Num a => a -> a -> a
- Posit256
f) forall a. Fractional a => a -> a -> a
/ (Posit256
1 forall a. Num a => a -> a -> a
+ Posit256
f)
            a' :: Posit256
a' = Posit256
a forall a. Num a => a -> a -> a
* (Posit256
1 forall a. Num a => a -> a -> a
+ Posit256
y')forall a b. (Num a, Integral b) => a -> b -> a
^Integer
4 forall a. Num a => a -> a -> a
- Posit256
2forall a b. (Num a, Integral b) => a -> b -> a
^(Natural
2 forall a. Num a => a -> a -> a
* Natural
n forall a. Num a => a -> a -> a
+ Natural
1) forall a. Num a => a -> a -> a
* Posit256
y' forall a. Num a => a -> a -> a
* (Posit256
1 forall a. Num a => a -> a -> a
+ Posit256
y' forall a. Num a => a -> a -> a
+ Posit256
y'forall a b. (Num a, Integral b) => a -> b -> a
^Integer
2) 
        in if Natural
n forall a. Eq a => a -> a -> Bool
== Natural
3
           then Posit256
a'
           else Posit256 -> Posit256 -> Natural -> Posit256 -> Posit256 -> Posit256
go Posit256
a Posit256
y (Natural
nforall a. Num a => a -> a -> a
+Natural
1) (forall a. String -> a -> a
trace (String
"A: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Posit256
a') Posit256
a') (forall a. String -> a -> a
trace (String
"Y: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Posit256
y') Posit256
y')
--
-- 3.14159265358979323846264338327950288419716939937510582097494459231
-- ULP: -97

-- Borwin's Cubic Algirthm
funPi6 :: Posit256
funPi6 :: Posit256
funPi6 = forall a. Fractional a => a -> a
recip forall a b. (a -> b) -> a -> b
$ Posit256 -> Posit256 -> Natural -> Posit256 -> Posit256 -> Posit256
go Posit256
0 Posit256
0 Natural
1 (Posit256
1forall a. Fractional a => a -> a -> a
/Posit256
3) ((forall a. Floating a => a -> a
sqrt Posit256
3 forall a. Num a => a -> a -> a
- Posit256
1) forall a. Fractional a => a -> a -> a
/ Posit256
2)
  where
    go :: Posit256 -> Posit256 -> Natural -> Posit256 -> Posit256 -> Posit256
    go :: Posit256 -> Posit256 -> Natural -> Posit256 -> Posit256 -> Posit256
go !Posit256
prevA !Posit256
prevS !Natural
n !Posit256
a !Posit256
s
      | Posit256
prevA forall a. Eq a => a -> a -> Bool
== Posit256
a = Posit256
a
      | Posit256
prevS forall a. Eq a => a -> a -> Bool
== Posit256
s = Posit256
a
      | Bool
otherwise =
        let r :: Posit256
r = Posit256
3 forall a. Fractional a => a -> a -> a
/ (Posit256
1 forall a. Num a => a -> a -> a
+ Posit256
2 forall a. Num a => a -> a -> a
* (Posit256
1 forall a. Num a => a -> a -> a
- Posit256
sforall a b. (Num a, Integral b) => a -> b -> a
^Integer
3)forall a. Floating a => a -> a -> a
**(Posit256
1forall a. Fractional a => a -> a -> a
/Posit256
3))
            s' :: Posit256
s'= (Posit256
r forall a. Num a => a -> a -> a
- Posit256
1) forall a. Fractional a => a -> a -> a
/ Posit256
2
            a' :: Posit256
a'= Posit256
rforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
* Posit256
a forall a. Num a => a -> a -> a
- Posit256
3forall a b. (Num a, Integral b) => a -> b -> a
^(Natural
nforall a. Num a => a -> a -> a
-Natural
1) forall a. Num a => a -> a -> a
* (Posit256
rforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
- Posit256
1)
        in if Natural
n forall a. Eq a => a -> a -> Bool
== Natural
4
           then Posit256
a'
           else Posit256 -> Posit256 -> Natural -> Posit256 -> Posit256 -> Posit256
go Posit256
a Posit256
s (Natural
nforall a. Num a => a -> a -> a
+Natural
1) Posit256
a' Posit256
s'
-- 3.14159265358979323846264338327950288419716939937510582097494459231
-- ULP: 216


--
-- looks to be about 4 ULP accurate at -100, right on the money at -1000
funExp :: Posit256 -> Posit256
funExp :: Posit256 -> Posit256
funExp Posit256
x = (Posit256 -> Posit256) -> Posit256 -> Posit256
funExp2 Posit256 -> Posit256
funExpTaylor (Posit256
x forall a. Fractional a => a -> a -> a
/ Posit256
lnOf2)
--

--
--
funExp2 :: (Posit256 -> Posit256) -> Posit256 -> Posit256
funExp2 :: (Posit256 -> Posit256) -> Posit256 -> Posit256
funExp2 Posit256 -> Posit256
_ Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funExp2 Posit256 -> Posit256
_ Posit256
0 = Posit256
1
funExp2 Posit256 -> Posit256
f Posit256
x
  | Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
0 = forall a. Fractional a => a -> a
recipforall b c a. (b -> c) -> (a -> b) -> a -> c
.(Posit256 -> Posit256) -> Posit256 -> Posit256
funExp2 Posit256 -> Posit256
fforall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. Num a => a -> a
negate forall a b. (a -> b) -> a -> b
$ Posit256
x  -- always calculate the positive method
  | Bool
otherwise = case forall a b. (RealFrac a, Integral b) => a -> (b, a)
properFraction Posit256
x of
                  (Integer
int,Posit256
rem) -> forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
2forall a b. (Num a, Integral b) => a -> b -> a
^Integer
int) forall a. Num a => a -> a -> a
* Posit256 -> Posit256
f (Posit256
lnOf2 forall a. Num a => a -> a -> a
* Posit256
rem)



--
-- calculate exp, its most accurate near zero
-- sum k=0 to k=inf of the terms, iterate until a fixed point is reached
funExpTaylor :: Posit256 -> Posit256
funExpTaylor :: Posit256 -> Posit256
funExpTaylor Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funExpTaylor Posit256
0 = Posit256
1
funExpTaylor Posit256
z = Natural -> Posit256 -> Posit256
go Natural
0 Posit256
0
  where
    go :: Natural -> Posit256 -> Posit256
    go :: Natural -> Posit256 -> Posit256
go !Natural
k !Posit256
acc
      | Posit256
acc forall a. Eq a => a -> a -> Bool
== (Posit256
acc forall a. Num a => a -> a -> a
+ Natural -> Posit256
term Natural
k) = Posit256
acc  -- if x == x + dx then terminate and return x
      | Bool
otherwise = Natural -> Posit256 -> Posit256
go (Natural
kforall a. Num a => a -> a -> a
+Natural
1) (Posit256
acc forall a. Num a => a -> a -> a
+ Natural -> Posit256
term Natural
k)
    term :: Natural -> Posit256
    term :: Natural -> Posit256
term Natural
k = (Posit256
zforall a b. (Num a, Integral b) => a -> b -> a
^Natural
k) forall a. Fractional a => a -> a -> a
/ (forall a b. (Integral a, Num b) => a -> b
fromIntegralforall b c a. (b -> c) -> (a -> b) -> a -> c
.Natural -> Natural
fac forall a b. (a -> b) -> a -> b
$ Natural
k)
--

--
-- calculate exp, its most accurate near zero
-- use the Nested Series of Jan J Tuma
funExpTuma :: Posit256 -> Posit256
funExpTuma :: Posit256 -> Posit256
funExpTuma Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funExpTuma Posit256
0 = Posit256
1
funExpTuma Posit256
z = Natural -> Posit256 -> Posit256
go Natural
57 Posit256
1 -- was 66
  where
    go :: Natural -> Posit256 -> Posit256
    go :: Natural -> Posit256 -> Posit256
go !Natural
k !Posit256
acc
      | Natural
k forall a. Eq a => a -> a -> Bool
== Natural
0 = Posit256
acc
      | Bool
otherwise = Natural -> Posit256 -> Posit256
go (Natural
kforall a. Num a => a -> a -> a
-Natural
1) (Posit256
1 forall a. Num a => a -> a -> a
+ (Posit256
z forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral Natural
k) forall a. Num a => a -> a -> a
* Posit256
acc)
--

--
--
funPow :: Posit256 -> Posit256 -> Posit256
Posit256
NaR funPow :: Posit256 -> Posit256 -> Posit256
`funPow` Posit256
_ = forall (es :: ES). PositC es => Posit es
NaR
Posit256
_ `funPow` Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funPow Posit256
0 Posit256
y
  | Posit256
y forall a. Ord a => a -> a -> Bool
< Posit256
0 = forall (es :: ES). PositC es => Posit es
NaR -- NaR: Divide by Zero
  | Posit256
y forall a. Eq a => a -> a -> Bool
== Posit256
0 = forall (es :: ES). PositC es => Posit es
NaR -- NaR: Indeterminate
  | Posit256
y forall a. Ord a => a -> a -> Bool
> Posit256
0 = Posit256
0
funPow Posit256
x Posit256
y
  | Posit256
y forall a. Ord a => a -> a -> Bool
< Posit256
0 = forall a. Fractional a => a -> a
recip forall a b. (a -> b) -> a -> b
$ Posit256 -> Posit256 -> Posit256
funPow Posit256
x (forall a. Num a => a -> a
negate Posit256
y)
  | Posit256
x forall a. Ord a => a -> a -> Bool
< Posit256
0 = -- NaR if y is not an integer
    let (Integer
int,Posit256
rem) = forall a b. (RealFrac a, Integral b) => a -> (b, a)
properFraction Posit256
y
    in if Posit256
rem forall a. Eq a => a -> a -> Bool
== Posit256
0
       then Posit256
xforall a b. (Fractional a, Integral b) => a -> b -> a
^^Integer
int
       else forall (es :: ES). PositC es => Posit es
NaR -- NaR: Imaginary Number
  | Bool
otherwise = forall a. Floating a => a -> a
exp forall a b. (a -> b) -> a -> b
$ Posit256
y forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
log Posit256
x
--

-- Looks like 1 ULP for 0.7813
funSinc :: Posit256 -> Posit256
funSinc :: Posit256 -> Posit256
funSinc Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funSinc Posit256
0 = Posit256
1  -- Why the hell not!
funSinc Posit256
theta = forall a. Floating a => a -> a
sin Posit256
theta forall a. Fractional a => a -> a -> a
/ Posit256
theta
--

-- Interestingly enough, wikipedia defines two alternative solutions
-- for the Shannon Wavelet, eventhough there are infinite solutions
-- where the functions are equal, they are not equal.  It a class of 
-- functions with the charicteristic of being a band pass filter in the 
-- frequency space.
-- Shannon wavelet
funPsiSha1 :: Posit256 -> Posit256
funPsiSha1 :: Posit256 -> Posit256
funPsiSha1 Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funPsiSha1 Posit256
t = Posit256
2 forall a. Num a => a -> a -> a
* Posit256 -> Posit256
funSinc (Posit256
2 forall a. Num a => a -> a -> a
* Posit256
t) forall a. Num a => a -> a -> a
- Posit256 -> Posit256
funSinc Posit256
t
--

-- Shannon wavelet
funPsiSha2 :: Posit256 -> Posit256
funPsiSha2 :: Posit256 -> Posit256
funPsiSha2 Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funPsiSha2 Posit256
t = Posit256 -> Posit256
funSinc (Posit256
tforall a. Fractional a => a -> a -> a
/Posit256
2) forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
cos (Posit256
3forall a. Num a => a -> a -> a
*forall a. Floating a => a
piforall a. Num a => a -> a -> a
*Posit256
tforall a. Fractional a => a -> a -> a
/Posit256
2)
--

-- Shannon wavelet, same as funPsiSha1 but with a factor of pi, with the
-- Law: funPsiSha1.(pi*) === funPsiSha3
-- or : funPsiSha1 === funpsiSha3.(/pi)
-- Posit256 seems to hold to a few ULP
funPsiSha3 :: Posit256 -> Posit256
funPsiSha3 :: Posit256 -> Posit256
funPsiSha3 Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funPsiSha3 Posit256
0 = Posit256
1  -- Why the hell not!
funPsiSha3 Posit256
t =
  let pit :: Posit256
pit = forall a. Floating a => a
pi forall a. Num a => a -> a -> a
* Posit256
t
      invpit :: Posit256
invpit = forall a. Fractional a => a -> a
recip Posit256
pit 
  in Posit256
invpit forall a. Num a => a -> a -> a
* (forall a. Floating a => a -> a
sin (Posit256
2 forall a. Num a => a -> a -> a
* Posit256
pit) forall a. Num a => a -> a -> a
- forall a. Floating a => a -> a
sin Posit256
pit)
--



-- Using the CORDIC domain reduction and some approximation function
funLogDomainReduction :: (Posit256 -> Posit256) -> Posit256 -> Posit256
funLogDomainReduction :: (Posit256 -> Posit256) -> Posit256 -> Posit256
funLogDomainReduction Posit256 -> Posit256
_ Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funLogDomainReduction Posit256 -> Posit256
_ Posit256
1 = Posit256
0
funLogDomainReduction Posit256 -> Posit256
f Posit256
x
  | Posit256
x forall a. Ord a => a -> a -> Bool
<= Posit256
0 = forall (es :: ES). PositC es => Posit es
NaR
  | Bool
otherwise = Posit256 -> Posit256
f Posit256
sig forall a. Num a => a -> a -> a
+ (forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
ex forall a. Num a => a -> a -> a
* Posit256
lnOf2)
    where
      (Integer
ex, Posit256
sig) = (Integer
int forall a. Num a => a -> a -> a
* forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer
2forall a b. (Num a, Integral b) => a -> b -> a
^(forall (es :: ES). PositC es => Natural
exponentSize @V)) forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Natural
nat forall a. Num a => a -> a -> a
+ Integer
1, forall a. Fractional a => Rational -> a
fromRational Rational
rat forall a. Fractional a => a -> a -> a
/ Posit256
2) -- move significand range from 1,2 to 0.5,1
      (Bool
_,Integer
int,Natural
nat,Rational
rat) = (forall (es :: ES).
PositC es =>
Rational -> (Bool, Integer, Natural, Rational)
posit2TupPosit @V)forall b c a. (b -> c) -> (a -> b) -> a -> c
.forall a. Real a => a -> Rational
toRational forall a b. (a -> b) -> a -> b
$ Posit256
x -- sign should always be positive
     
 

-- natural log with log phi acurate to 9 ULP
funLogTaylor :: Posit256 -> Posit256
funLogTaylor :: Posit256 -> Posit256
funLogTaylor Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funLogTaylor Posit256
1 = Posit256
0
funLogTaylor Posit256
x | Posit256
x forall a. Ord a => a -> a -> Bool
<= Posit256
0 = forall (es :: ES). PositC es => Posit es
NaR
funLogTaylor Posit256
x
  | Posit256
x forall a. Ord a => a -> a -> Bool
<= Posit256
2 = Natural -> Posit256 -> Posit256
go Natural
1 Posit256
0
  | Bool
otherwise = forall a. HasCallStack => String -> a
error String
"The funLogTaylor algorithm is being used improperly"
    where
      go :: Natural -> Posit256 -> Posit256
      go :: Natural -> Posit256 -> Posit256
go !Natural
k !Posit256
acc
        | Posit256
acc forall a. Eq a => a -> a -> Bool
== (Posit256
acc forall a. Num a => a -> a -> a
+ Natural -> Posit256
term Natural
k) = Posit256
acc
        | Bool
otherwise = Natural -> Posit256 -> Posit256
go (Natural
k forall a. Num a => a -> a -> a
+ Natural
1) (Posit256
acc forall a. Num a => a -> a -> a
+ Natural -> Posit256
term Natural
k)
      term :: Natural -> Posit256
      term :: Natural -> Posit256
term Natural
k = (-Posit256
1)forall a b. (Num a, Integral b) => a -> b -> a
^(Natural
kforall a. Num a => a -> a -> a
+Natural
1) forall a. Num a => a -> a -> a
* (Posit256
x forall a. Num a => a -> a -> a
- Posit256
1)forall a b. (Num a, Integral b) => a -> b -> a
^Natural
k forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral Natural
k
     



-- natural log the Jan J Tuma way
funLogTuma :: Posit256 -> Posit256
funLogTuma :: Posit256 -> Posit256
funLogTuma Posit256
NaR = forall (es :: ES). PositC es => Posit es
NaR
funLogTuma Posit256
1 = Posit256
0  -- domain reduced input is [0.5,1) and/or , where funLogTuma 1 = 0
funLogTuma Posit256
x | Posit256
x forall a. Ord a => a -> a -> Bool
<= Posit256
0 = forall (es :: ES). PositC es => Posit es
NaR  -- zero and less than zero is NaR
funLogTuma Posit256
x
  = Natural -> Posit256 -> Posit256
go Natural
242 Posit256
1
    where
      xM1 :: Posit256
xM1 = Posit256
x forall a. Num a => a -> a -> a
- Posit256
1  -- now [-0.5, 0)
      go :: Natural -> Posit256 -> Posit256
      go :: Natural -> Posit256 -> Posit256
go !Natural
k !Posit256
acc
        | Natural
k forall a. Eq a => a -> a -> Bool
== Natural
0 = Posit256
xM1 forall a. Num a => a -> a -> a
* Posit256
acc
        | Bool
otherwise = Natural -> Posit256 -> Posit256
go (Natural
kforall a. Num a => a -> a -> a
-Natural
1) (forall a. Fractional a => a -> a
recip (forall a b. (Integral a, Num b) => a -> b
fromIntegral Natural
k) forall a. Num a => a -> a -> a
- Posit256
xM1 forall a. Num a => a -> a -> a
* Posit256
acc)


funGammaRamanujan :: Posit256 -> Posit256
funGammaRamanujan :: Posit256 -> Posit256
funGammaRamanujan Posit256
z = forall a. Floating a => a -> a
sqrt forall a. Floating a => a
pi forall a. Num a => a -> a -> a
* (Posit256
x forall a. Fractional a => a -> a -> a
/ forall a. Floating a => a -> a
exp Posit256
1)forall a. Floating a => a -> a -> a
**Posit256
x forall a. Num a => a -> a -> a
* (Posit256
8forall a. Num a => a -> a -> a
*Posit256
xforall a b. (Num a, Integral b) => a -> b -> a
^Integer
3 forall a. Num a => a -> a -> a
+ Posit256
4forall a. Num a => a -> a -> a
*Posit256
xforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
+ Posit256
x forall a. Num a => a -> a -> a
+ (Posit256
1forall a. Fractional a => a -> a -> a
/Posit256
30))forall a. Floating a => a -> a -> a
**(Posit256
1forall a. Fractional a => a -> a -> a
/Posit256
6)
  where
    x :: Posit256
x = Posit256
z forall a. Num a => a -> a -> a
- Posit256
1

--
a001163 :: [Integer] -- Numerator
a001163 :: [Integer]
a001163 = [Integer
1, Integer
1, -Integer
139, -Integer
571, Integer
163879, Integer
5246819, -Integer
534703531, -Integer
4483131259, Integer
432261921612371, Integer
6232523202521089, -Integer
25834629665134204969, -Integer
1579029138854919086429, Integer
746590869962651602203151, Integer
1511513601028097903631961, -Integer
8849272268392873147705987190261, -Integer
142801712490607530608130701097701]
a001164 :: [Integer]  -- Denominator
a001164 :: [Integer]
a001164 = [Integer
12, Integer
288, Integer
51840, Integer
2488320, Integer
209018880, Integer
75246796800, Integer
902961561600, Integer
86684309913600, Integer
514904800886784000, Integer
86504006548979712000, Integer
13494625021640835072000, Integer
9716130015581401251840000, Integer
116593560186976815022080000, Integer
2798245444487443560529920000, Integer
299692087104605205332754432000000, Integer
57540880724084199423888850944000000]

funGammaSeries :: Posit256 -> Posit256
funGammaSeries :: Posit256 -> Posit256
funGammaSeries Posit256
z = forall a. Floating a => a -> a
sqrt(Posit256
2 forall a. Num a => a -> a -> a
* forall a. Floating a => a
pi) forall a. Num a => a -> a -> a
* (Posit256
zforall a. Floating a => a -> a -> a
**(Posit256
z forall a. Num a => a -> a -> a
- Posit256
0.5)) forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
exp (forall a. Num a => a -> a
negate Posit256
z) forall a. Num a => a -> a -> a
* (Posit256
1 forall a. Num a => a -> a -> a
+ Posit256
series)
  where
    series :: Posit256
    series :: Posit256
series = forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. Num a => a -> a -> a
(*) [forall a. Fractional a => Rational -> a
fromRational (Integer
a forall a. Integral a => a -> a -> Ratio a
% Integer
b) | (Integer
a,Integer
b) <- forall a b. [a] -> [b] -> [(a, b)]
zip [Integer]
a001163 [Integer]
a001164] [forall a. Fractional a => a -> a
recip forall a b. (a -> b) -> a -> b
$ Posit256
zforall a b. (Num a, Integral b) => a -> b -> a
^Int
n |  Int
n <- [Int
1..Int
len]]  -- zipWith (\x y -> ) a001163 a001164
    lenA :: Int
lenA = forall (t :: * -> *) a. Foldable t => t a -> Int
length [Integer]
a001163
    lenB :: Int
lenB = forall (t :: * -> *) a. Foldable t => t a -> Int
length [Integer]
a001164
    len :: Int
len = if Int
lenA forall a. Eq a => a -> a -> Bool
== Int
lenB
            then Int
lenA
            else forall a. HasCallStack => String -> a
error String
"Seiries Numerator and Denominator do not have the same length."

funGammaSeriesFused :: Posit256 -> Posit256
funGammaSeriesFused :: Posit256 -> Posit256
funGammaSeriesFused Posit256
z = forall a. Floating a => a -> a
sqrt(Posit256
2 forall a. Num a => a -> a -> a
* forall a. Floating a => a
pi) forall a. Num a => a -> a -> a
* (Posit256
zforall a. Floating a => a -> a -> a
**(Posit256
z forall a. Num a => a -> a -> a
- Posit256
0.5)) forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
exp (forall a. Num a => a -> a
negate Posit256
z) forall a. Num a => a -> a -> a
* (Posit256
1 forall a. Num a => a -> a -> a
+ Posit256
series)
  where
    series :: Posit256
    series :: Posit256
series = forall a (t :: * -> *). (FusedOps a, Foldable t) => t a -> a
fsumL forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall a. Num a => a -> a -> a
(*) [forall a. Fractional a => Rational -> a
fromRational (Integer
a forall a. Integral a => a -> a -> Ratio a
% Integer
b) | (Integer
a,Integer
b) <- forall a b. [a] -> [b] -> [(a, b)]
zip [Integer]
a001163 [Integer]
a001164] [forall a. Fractional a => a -> a
recip forall a b. (a -> b) -> a -> b
$ Posit256
zforall a b. (Num a, Integral b) => a -> b -> a
^Int
n |  Int
n <- [Int
1..Int
len]]  -- zipWith (\x y -> ) a001163 a001164
    lenA :: Int
lenA = forall (t :: * -> *) a. Foldable t => t a -> Int
length [Integer]
a001163
    lenB :: Int
lenB = forall (t :: * -> *) a. Foldable t => t a -> Int
length [Integer]
a001164
    len :: Int
len = if Int
lenA forall a. Eq a => a -> a -> Bool
== Int
lenB
            then Int
lenA
            else forall a. HasCallStack => String -> a
error String
"Seiries Numerator and Denominator do not have the same length."
--

funGammaCalc :: Posit256 -> Posit256
funGammaCalc :: Posit256 -> Posit256
funGammaCalc Posit256
z = forall a. Floating a => a -> a
sqrt (Posit256
2forall a. Num a => a -> a -> a
*forall a. Floating a => a
pi forall a. Fractional a => a -> a -> a
/ Posit256
z) forall a. Num a => a -> a -> a
* ((Posit256
z forall a. Fractional a => a -> a -> a
/ forall a. Floating a => a -> a
exp Posit256
1) forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
sqrt (Posit256
z forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
sinh (forall a. Fractional a => a -> a
recip Posit256
z) forall a. Num a => a -> a -> a
+ forall a. Fractional a => a -> a
recip (Posit256
810 forall a. Num a => a -> a -> a
* Posit256
zforall a b. (Num a, Integral b) => a -> b -> a
^Integer
6)))forall a. Floating a => a -> a -> a
**Posit256
z


funGammaNemes :: Posit256 -> Posit256
funGammaNemes :: Posit256 -> Posit256
funGammaNemes Posit256
z = forall a. Floating a => a -> a
sqrt (Posit256
2forall a. Num a => a -> a -> a
*forall a. Floating a => a
pi forall a. Fractional a => a -> a -> a
/ Posit256
z) forall a. Num a => a -> a -> a
* (forall a. Fractional a => a -> a
recip (forall a. Floating a => a -> a
exp Posit256
1) forall a. Num a => a -> a -> a
* (Posit256
z forall a. Num a => a -> a -> a
+ forall a. Fractional a => a -> a
recip (Posit256
12 forall a. Num a => a -> a -> a
* Posit256
z forall a. Num a => a -> a -> a
- forall a. Fractional a => a -> a
recip (Posit256
10 forall a. Num a => a -> a -> a
* Posit256
z))))forall a. Floating a => a -> a -> a
**Posit256
z

funGammaYang :: Posit256 -> Posit256
funGammaYang :: Posit256 -> Posit256
funGammaYang Posit256
z = forall a. Floating a => a -> a
sqrt (Posit256
2 forall a. Num a => a -> a -> a
* forall a. Floating a => a
pi forall a. Num a => a -> a -> a
* Posit256
x) forall a. Num a => a -> a -> a
* (Posit256
x forall a. Fractional a => a -> a -> a
/ forall a. Floating a => a -> a
exp Posit256
1)forall a. Floating a => a -> a -> a
**Posit256
x forall a. Num a => a -> a -> a
* (Posit256
x forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
sinh (forall a. Fractional a => a -> a
recip Posit256
x))forall a. Floating a => a -> a -> a
**(Posit256
xforall a. Fractional a => a -> a -> a
/Posit256
2) forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
exp (forall a. Fractional a => Rational -> a
fromRational (Integer
7 forall a. Integral a => a -> a -> Ratio a
% Integer
324) forall a. Num a => a -> a -> a
* forall a. Fractional a => a -> a
recip (Posit256
xforall a b. (Num a, Integral b) => a -> b -> a
^Integer
3 forall a. Num a => a -> a -> a
* (Posit256
35 forall a. Num a => a -> a -> a
* Posit256
xforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
+ Posit256
33)))
  where
    x :: Posit256
x = Posit256
z forall a. Num a => a -> a -> a
- Posit256
1

funGammaChen :: Posit256 -> Posit256
funGammaChen :: Posit256 -> Posit256
funGammaChen Posit256
z = forall a. Floating a => a -> a
sqrt (Posit256
2 forall a. Num a => a -> a -> a
* forall a. Floating a => a
pi forall a. Num a => a -> a -> a
* Posit256
x) forall a. Num a => a -> a -> a
* (Posit256
x forall a. Fractional a => a -> a -> a
/ forall a. Floating a => a -> a
exp Posit256
1)forall a. Floating a => a -> a -> a
**Posit256
x forall a. Num a => a -> a -> a
* (Posit256
1 forall a. Num a => a -> a -> a
+ forall a. Fractional a => a -> a
recip (Posit256
12forall a. Num a => a -> a -> a
*Posit256
xforall a b. (Num a, Integral b) => a -> b -> a
^Integer
3 forall a. Num a => a -> a -> a
+ (Posit256
24forall a. Fractional a => a -> a -> a
/Posit256
7)forall a. Num a => a -> a -> a
*Posit256
x forall a. Num a => a -> a -> a
- Posit256
0.5))forall a. Floating a => a -> a -> a
**(Posit256
xforall a b. (Num a, Integral b) => a -> b -> a
^Integer
2 forall a. Num a => a -> a -> a
+ forall a. Fractional a => Rational -> a
fromRational (Integer
53 forall a. Integral a => a -> a -> Ratio a
% Integer
210))
  where
    x :: Posit256
x = Posit256
z forall a. Num a => a -> a -> a
- Posit256
1

funGammaXminus1 :: Posit256 -> Posit256
funGammaXminus1 :: Posit256 -> Posit256
funGammaXminus1 Posit256
x = forall a. Floating a => a -> a
go (Posit256
x forall a. Num a => a -> a -> a
- Posit256
1)
  where
    go :: a -> a
go a
z = forall a. Floating a => a -> a
sqrt (a
2 forall a. Num a => a -> a -> a
* forall a. Floating a => a
pi) forall a. Num a => a -> a -> a
* forall a. Floating a => a -> a
exp a
z forall a. Floating a => a -> a -> a
** (forall a. Num a => a -> a
negate a
z) forall a. Num a => a -> a -> a
* a
z forall a. Floating a => a -> a -> a
** (a
z forall a. Num a => a -> a -> a
+ a
0.5)