dvda-0.2.0: Dvda/BinUn.hs
{-# OPTIONS_GHC -Wall #-}
module Dvda.BinUn ( BinOp(..)
, UnOp(..)
, showBinary
, showUnary
, applyUnary
, applyBinary
, unaryDeriv
, binaryDeriv
, isCommutative
, lassoc
, rassoc
) where
import Data.Hashable ( Hashable, hash )
import Dvda.Dual ( Dual(..), dualPerturbation )
data UnOp = Abs
| Neg
| Signum
| Exp
| Sqrt
| Log
| Sin
| Cos
| Tan
| ASin
| ACos
| ATan
| Tanh
| Sinh
| Cosh
| ATanh
| ASinh
| ACosh deriving (Eq, Show, Enum, Bounded)
data BinOp = Add
| Sub
| Mul
| Div
| Pow
| LogBase deriving (Eq, Show, Enum, Bounded)
instance Hashable UnOp where
hash Abs = 0
hash Neg = 1
hash Signum = 2
hash Exp = 3
hash Sqrt = 4
hash Log = 5
hash Sin = 6
hash Cos = 7
hash Tan = 8
hash ASin = 9
hash ACos = 10
hash ATan = 11
hash Tanh = 12
hash Sinh = 13
hash Cosh = 14
hash ATanh = 15
hash ASinh = 16
hash ACosh = 17
instance Hashable BinOp where
hash Add = 18
hash Sub = 19
hash Mul = 20
hash Div = 21
hash Pow = 22
hash LogBase = 23
showUnary :: String -> UnOp -> String
showUnary x Abs = '|': x ++ "|"
showUnary x Neg = '-':paren x
showUnary x Signum = "signum"++paren x
showUnary x Exp = "exp"++paren x
showUnary x Sqrt = "sqrt"++paren x
showUnary x Log = "log"++paren x
showUnary x Sin = "sin"++paren x
showUnary x Cos = "cos"++paren x
showUnary x Tan = "tan"++paren x
showUnary x ASin = "asin"++paren x
showUnary x ACos = "acos"++paren x
showUnary x ATan = "atan"++paren x
showUnary x Sinh = "sinh"++paren x
showUnary x Cosh = "cosh"++paren x
showUnary x Tanh = "tanh"++paren x
showUnary x ASinh = "asinh"++paren x
showUnary x ATanh = "atanh"++paren x
showUnary x ACosh = "acosh"++paren x
applyUnary :: Floating a => UnOp -> a -> a
applyUnary Abs = abs
applyUnary Neg = negate
applyUnary Signum = signum
applyUnary Exp = exp
applyUnary Sqrt = sqrt
applyUnary Log = log
applyUnary Sin = sin
applyUnary Cos = cos
applyUnary Tan = tan
applyUnary ASin = asin
applyUnary ACos = acos
applyUnary ATan = atan
applyUnary Sinh = sinh
applyUnary Cosh = cosh
applyUnary Tanh = tanh
applyUnary ASinh = asinh
applyUnary ATanh = atanh
applyUnary ACosh = acosh
applyBinary :: Floating a => BinOp -> a -> a -> a
applyBinary Add = (+)
applyBinary Sub = (-)
applyBinary Mul = (*)
applyBinary Div = (/)
applyBinary Pow = (**)
applyBinary LogBase = logBase
unaryDeriv :: Floating a => UnOp -> (a,a) -> a
unaryDeriv op (x,x') = dualPerturbation $ applyUnary op (Dual x x')
binaryDeriv :: Floating a => BinOp -> (a,a) -> (a,a) -> a
binaryDeriv op (x,x') (y,y') = dualPerturbation $ applyBinary op (Dual x x') (Dual y y')
showBinary :: BinOp -> String
showBinary Add = "+"
showBinary Sub = "-"
showBinary Mul = "*"
showBinary Div = "/"
showBinary Pow = "**"
showBinary LogBase = "`logbase`"
isCommutative :: BinOp -> Bool
isCommutative Add = True
isCommutative Sub = False
isCommutative Mul = True
isCommutative Div = False
isCommutative Pow = False
isCommutative LogBase = False
lassoc :: BinOp -> BinOp -> Bool
lassoc Add Add = True -- a + b + c == (a + b) + c
lassoc Add Sub = True -- a + b - c == (a + b) - c
--lassoc Add Mul = True -- a + b * c == (a + b) * c
--lassoc Add Div = True -- a + b / c == (a + b) / c
lassoc Sub Add = True -- a - b + c == (a - b) + c
lassoc Sub Sub = True -- a - b - c == (a - b) - c
--lassoc Sub Mul = True -- a - b * c == (a - b) * c
--lassoc Sub Div = True -- a - b / c == (a - b) / c
lassoc Div Add = True -- a / b + c == (a / b) + c
lassoc Div Sub = True -- a / b - c == (a / b) - c
lassoc Div Mul = True -- a / b * c == (a / b) * c
lassoc Div Div = True -- a / b / c == (a / b) / c
lassoc Mul Add = True -- a * b + c == (a * b) + c
lassoc Mul Sub = True -- a * b - c == (a * b) - c
lassoc Mul Mul = True -- a * b * c == (a * b) * c
lassoc Mul Div = True -- a * b / c == (a * b) / c
lassoc _ _ = False
rassoc :: BinOp -> BinOp -> Bool
--rassoc Add Add = True -- a + b + c == a + (b + c)
--rassoc Add Sub = True -- a + b - c == a + (b - c)
rassoc Add Mul = True -- a + b * c == a + (b * c)
rassoc Add Div = True -- a + b / c == a + (b / c)
--rassoc Sub Add = True -- a - b + c == a - (b + c)
--rassoc Sub Sub = True -- a - b - c == a - (b - c)
rassoc Sub Mul = True -- a - b * c == a - (b * c)
rassoc Sub Div = True -- a - b / c == a - (b / c)
--rassoc Div Add = True -- a / b + c == a / (b + c)
--rassoc Div Sub = True -- a / b - c == a / (b - c)
--rassoc Div Mul = True -- a / b * c == a / (b * c)
--rassoc Div Div = True -- a / b / c == a / (b / c)
--rassoc Mul Add = True -- a * b + c == a * (b + c)
--rassoc Mul Sub = True -- a * b - c == a * (b - c)
--rassoc Mul Mul = True -- a * b * c == a * (b * c)
--rassoc Mul Div = True -- a * b / c == a * (b / c)
rassoc _ _ = False
paren :: String -> String
paren x = "( "++ x ++" )"