Skip to content

Instantly share code, notes, and snippets.

@barrucadu
Created November 7, 2011 10:48
Show Gist options
  • Save barrucadu/1344656 to your computer and use it in GitHub Desktop.
Save barrucadu/1344656 to your computer and use it in GitHub Desktop.
-- -- Expression type
data Expression = Constant Float
| Variable String
| Partial String String
| BinOp String Expression Expression
| Func String Expression
| Exp Expression Float
deriving Show
-- -- Evaluation
eval e = simplify e
-- -- Pretty Printing
pretty (Variable a) = a
pretty (Constant a) = show a
pretty (Func a b) = a ++ pretty b
pretty (Partial a b) = "d" ++ a ++ "/d" ++ b
pretty (BinOp a b c) = "(" ++ pretty b ++ " " ++ a ++ " " ++ pretty c ++ ")"
pretty (Exp a b) = pretty a ++ "^" ++ show b
-- -- Differentiation
chainrule a b v = BinOp "*" (diff b v) (Func a b)
diff (Constant a) _ = Constant 0
diff (Variable a) v | a == v = Constant 1
| a /= v = Partial a v
diff (BinOp a b c) v | a == "+" = BinOp "+" (diff b v) (diff c v)
| a == "*" = BinOp "+" (BinOp "*" (diff b v) c) (BinOp "*" b (diff c v))
| a == "/" = BinOp "/" (BinOp "+" (BinOp "*" (diff b v) c) (BinOp "*" (Constant (-1)) (BinOp "*" b (diff c v)))) (BinOp "*" c c)
diff (Func a b) v | a == "sin" = chainrule "cos" b v
| a == "cos" = BinOp "*" (Constant (-1)) (chainrule "sin" b v)
| True = chainrule (a ++ "'") b v
diff (Exp a b) v = Exp (BinOp "*" (Constant b) (BinOp "*" (diff a v) a)) (b - 1)
-- -- Simplification
-- Special Cases
simplify (BinOp "*" (Constant 0) _) = Constant 0
simplify (BinOp "*" _ (Constant 0)) = Constant 0
simplify (BinOp "*" (Constant 1) b) = simplify b
simplify (BinOp "*" a (Constant 1)) = simplify a
simplify (BinOp "*" (Constant a) (Constant b)) = Constant (a * b)
simplify (BinOp "+" (Constant 0) b) = simplify b
simplify (BinOp "+" a (Constant 0)) = simplify a
simplify (BinOp "+" (Constant a) (Constant b)) = Constant (a + b)
simplify (BinOp "/" a (Constant 1)) = simplify a
simplify (BinOp "/" (Constant a) (Constant b)) = Constant (a / b)
simplify (Exp (Constant a) b) = Constant (a ** b)
-- General Cases
simplify (BinOp a (Func b c) d) = BinOp a (simplify (Func b c)) (simplify d)
simplify (BinOp a b (Func c d)) = BinOp a (simplify b) (simplify (Func c d))
simplify (BinOp a (Variable b) c) = BinOp a (Variable b) (simplify c)
simplify (BinOp a b (Variable c)) = BinOp a (simplify b) (Variable c)
simplify (BinOp a b c) = BinOp a (simplify b) (simplify c)
simplify (Func a b) = Func a (simplify b)
simplify (Exp a b) = Exp (simplify a) b
simplify a = a
-- Some example expressions
x = Variable "x"
y = Variable "y"
expr1 = BinOp "*" (BinOp "+" (Constant 1) (Constant 6.3)) (BinOp "*" (Constant 3) (Constant 2.4))
expr2 = BinOp "*" (Constant 10) (BinOp "+" (Constant 5) (Constant 1))
expr3 = BinOp "+" (BinOp "+" (BinOp "*" (Constant 5) (Constant 4.2)) (Constant 6.3)) (BinOp "*" (Constant 2) (Constant 3))
expr4 = BinOp "+" (Constant 5) (Constant 6)
fx = Func "f" (BinOp "*" x x)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment