Advertisement
Guest User

Differentiation

a guest
Oct 28th, 2014
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 7.78 KB | None | 0 0
  1. type Expression =
  2.     | Var of string
  3.     | Pi
  4.     | Const of float
  5.     | Add of Expression * Expression
  6.     | Sub of Expression * Expression
  7.     | Mul of Expression * Expression
  8.     | Div of Expression * Expression
  9.     | Pow of Expression * Expression
  10.     | Sqrt of Expression
  11.     | Exp of Expression
  12.     | Ln of Expression
  13.     | Sin of Expression
  14.     | Cos of Expression
  15.     | Tan of Expression
  16.     | Sec of Expression
  17.     | Csc of Expression
  18.     | Cot of Expression
  19.     | Log10 of Expression
  20.     | Log of Expression * Expression
  21.     | Neg of Expression
  22.     | Undefined
  23.     | PositiveInfinity
  24.     | NegativeInfinity
  25.  
  26. let (|Op|_|) (x : Expression) =
  27.     match x with
  28.     | Add(e1, e2) -> Some(Add, e1, e2)
  29.     | Sub(e1, e2) -> Some(Sub, e1, e2)
  30.     | Mul(e1, e2) -> Some(Mul, e1, e2)
  31.     | Div(e1, e2) -> Some(Div, e1, e2)
  32.     | Pow(e1, e2) -> Some(Pow, e1, e2)
  33.     | Log(e1, e2) -> Some(Log, e1, e2)
  34.     | _ -> None
  35.  
  36. let (|Func|_|) (x : Expression) =
  37.     match x with
  38.     | Neg(e) -> Some(Neg, e)
  39.     | Sqrt(e) -> Some(Sqrt, e)
  40.     | Exp(e) -> Some(Exp, e)
  41.     | Ln(e) -> Some(Ln, e)
  42.     | Log10(e) -> Some(Log10, e)
  43.     | Sin(e) -> Some(Sin, e)
  44.     | Cos(e) -> Some(Cos, e)
  45.     | Tan(e) -> Some(Tan, e)
  46.     | Csc(e) -> Some(Csc, e)
  47.     | Sec(e) -> Some(Sec, e)
  48.     | Cot(e) -> Some(Cot, e)
  49.     | _ -> None
  50.  
  51. let rec Evaluate expression =
  52.     match expression with
  53.     | Neg(Const(v)) -> Const(-v)
  54.     | Add(Const(v), Const(v2)) -> Const(v + v2)
  55.     | Sub(Const(v), Const(v2)) -> Const(v - v2)
  56.     | Mul(Const(v), Const(v2)) -> Const(v * v2)
  57.     | Mul(Const(v), Mul(Const(v2), e2)) -> Mul(Const(v * v2), Evaluate e2)
  58.     | Mul(Const(v), Mul(e2, Const(v2))) -> Mul(Const(v * v2), Evaluate e2)
  59.     | Mul(Const(v), Mul(e, Mul(Const(v2), eq))) -> Mul(Mul(Const(v * v2), Evaluate e), Evaluate eq)
  60.     //| Mul(Mul(Const(v), e2), Const(v2)) -> Mul(Const(v*v2), Evaluate e2)
  61.     //| Mul(Mul(e2, Const(v)), Const(v2)) -> Mul(Const(v*v2), Evaluate e2)
  62.     | Div(Const(v), Const(v2)) -> Const(v / v2)
  63.     | Pow(Const(v), Const(v2)) -> Const(v ** v2)
  64.     //| Sqrt(Const(v)) -> Const(sqrt(v))
  65.     //| Log(Const(v), Const(v2)) -> Const(log10(v2) / log10(v))
  66.     //| Log10(Const(v)) -> Const(log10(v))
  67.     //| Ln(Const(v)) -> Const(log(v))
  68.     //| Exp(Const(v)) -> Const(exp(v))
  69.     //| Sin(Const(v)) -> Const(sin(v))
  70.     //| Cos(Const(v)) -> Const(cos(v))
  71.     //| Tan(Const(v)) -> Const(tan(v))
  72.     //| Sec(Const(v)) -> Const(1. / cos(v))
  73.     //| Csc(Const(v)) -> Const(1. / sin(v))
  74.     //| Cot(Const(v)) -> Const(1. / tan(v))
  75.     | Op(op, expr, expr2) -> op(Evaluate expr, Evaluate expr2)
  76.     | Func(func, expr) -> func(Evaluate expr)
  77.     | _ -> expression
  78.  
  79. let rec Simplify expression =
  80.     match expression with
  81.     | Neg(Const(0.)) -> Const(0.)
  82.     | Neg(Neg(v)) -> v
  83.     | Add(Const(0.), expr) -> Simplify expr
  84.     | Add(expr, Const(0.)) -> Simplify expr
  85.     | Sub(Const(0.), expr) -> Neg(Simplify expr)
  86.     | Sub(expr, Const(0.)) -> Simplify expr
  87.     | Mul(expr, Const(0.)) -> Const(0.)
  88.     | Mul(Const(0.), expr) -> Const(0.)
  89.     | Mul(expr, Const(1.)) -> Simplify expr
  90.     | Mul(Const(1.), expr) -> Simplify expr
  91.     | Div(expr, Const(0.)) -> Undefined
  92.     | Div(Const(0.), expr) -> Const(0.)
  93.     | Div(expr, Const(1.)) -> Simplify expr
  94.     | Div(expr, expr2) when Simplify expr = Simplify expr2 -> Const(1.)
  95.     | Pow(Const(0.), expr) -> Const(0.)
  96.     | Pow(Const(1.), expr) -> Const(1.)
  97.     | Pow(expr, Const(1.)) -> Simplify expr
  98.     | Pow(expr, Const(0.)) -> Const(1.)
  99.     | Op (op, e1, e2)
  100.         ->
  101.         let e1s = Simplify e1
  102.         let e2s = Simplify e2
  103.         if e1s <> e1 || e2s <> e2 then
  104.             op(e1s, e2s) |> Simplify
  105.         else
  106.             op(e1, e2)
  107.     | _ -> expression
  108.  
  109. let rec Derive expression =
  110.     let deriv =
  111.         match expression with
  112.         | Const(v) -> Const(0.)
  113.         | Var(v) -> Const(1.)
  114.         | Neg(e) -> Neg(Derive(e))
  115.         | Add(left, right) -> Add(Derive(left), Derive(right))
  116.         | Sub(left, right) -> Sub(Derive(left), Derive(right))
  117.         | Mul(Const(v), f) -> Mul(Const(v), Derive(f))
  118.         | Mul(expr, Exp(Mul(expr2, Ln(expr1)))) -> Mul(expr, Pow(expr1, expr2))
  119.         | Mul(Exp(Mul(expr2, Ln(expr1))), expr) -> Mul(expr, Pow(expr1, expr2))
  120.         | Mul(f, g) -> Add(Mul(Derive(f), g), Mul(f, Derive(g)))
  121.         | Div(Const(1.), e) -> Div(Derive(e), Pow(e, Const(2.)))
  122.         | Div(f, g) -> Div(Sub(Mul(Derive(f), g), Mul(Derive(g), f)), Pow(g, Const(2.)))
  123.         | Sqrt(Var(x)) -> Pow(Var(x), Div(Const(1.), Const(2.))) |> Derive
  124.         | Pow(Var(x), Const(g)) -> Mul(Const(g), Pow(Var(x), Const(g - 1.)))
  125.         | Pow(Const(f), g) -> Mul(Ln(Const(f)), Pow(Const(f), g))
  126.         | Ln(Var(x)) -> Div(Const(1.), Var(x))
  127.         | Sin(Var(x)) -> Cos(Var(x))
  128.         | Cos(Var(x)) -> Neg(Sin(Var(x)))
  129.         | Tan(Var(x)) -> Pow(Sec(Var(x)), Const(2.))
  130.         | Sec(Var(x)) -> Mul(Sec(Var(x)), Tan(Var(x)))
  131.         | Csc(Var(x)) -> Neg(Mul(Csc(Var(x)), Cot(Var(x))))
  132.         | Cot(Var(x)) -> Neg(Pow(Csc(Var(x)), Const(2.)))
  133.         | Exp(Var(x)) -> Exp(Var(x))
  134.                 | Op(f, g, e) ->
  135.             let f' = Derive(f(Var("x"), e))
  136.            let g' = Derive(g)
  137.             match f' with
  138.            | Func(f'x, expr) -> Mul(g', f'x(g))
  139.             | Op (op, e1, e2) -> Mul(g', op(e1, g))
  140.            | _ -> failwith(sprintf "Unable to match expression [%A]" f')
  141.         | Func(g, f) ->
  142.             let dg = Derive(g(Var("x")))
  143.             let df = Derive(f)
  144.             match dg with
  145.             | Func(dgf, dge) -> Mul(dgf(f), df)
  146.             | Op (op, e1, e2) -> Mul(op(e1, e2), df)
  147.             | _ -> failwith(sprintf "Unable to match compound function [%A]" dg)
  148.         | _ -> failwith "Unsupported expression"
  149.     Simplify deriv
  150.  
  151. let formatOp (e: Expression) : string =
  152.     match e with
  153.     | Add(e1, e2) -> "+"
  154.     | Sub(e1, e2) -> "-"
  155.     | Mul(e1, e2) -> "*"
  156.     | Div(e1, e2) -> "/"
  157.     | Pow(e1, e2) -> "^"
  158.     | _ -> failwith(sprintf "Unrecognized operator [%A]" e)
  159.  
  160. let formatFunc (e: Expression) (a : string) : string =
  161.     match e with
  162.     | Sqrt(x) -> sprintf "sqrt(%s)" a
  163.     | Exp(x) -> sprintf "e^(%s)" a
  164.     | Ln(x) -> sprintf "ln(%s)" a
  165.     | Log10(x) -> sprintf "log10(%s)" a
  166.     | Sin(x) -> sprintf "sin(%s)" a
  167.     | Cos(x) -> sprintf "cos(%s)" a
  168.     | Tan(x) -> sprintf "tan(%s)" a
  169.     | Csc(x) -> sprintf "csc(%s)" a
  170.     | Sec(x) -> sprintf "sec(%s)" a
  171.     | Cot(x) -> sprintf "cot(%s)" a
  172.     | _ -> failwith(sprintf "Unrecognized function [%A]" e)
  173.  
  174. let rec format (inner : Expression) : string =
  175.     match inner with
  176.     | Var(n) -> n
  177.     | Const(n) -> sprintf "%g" n
  178.     | Pi -> "pi"
  179.     | Neg x -> x |> format |> sprintf "-%s"
  180.     | Mul(Pi, Const(v)) -> sprintf "%gpi" v
  181.     | Mul(Const(v), Pi) -> sprintf "%gpi" v
  182.     | Mul(Const(v), Var(n)) -> sprintf "%g%s" v n
  183.     | Pow(expr, expr2) -> sprintf "%s^(%s)" (expr |> format) (expr2 |> format)
  184.     | Op(op, e1, e2) -> sprintf "(%s %s %s)" (e1 |> format) (inner |> formatOp) (e2 |> format)
  185.     | Func(f, e) -> (inner |> formatFunc) (e |> format)
  186.     | _ -> failwith "Could not format"
  187.  
  188. let pi =
  189.     System.Math.PI
  190.  
  191. [<EntryPoint>]
  192. let main argv =
  193.     let fx = Add(Pow(Var("x"), Const(3.)), Mul(Const(3.), Pow(Var("x"), Const(2.)))) |> Simplify |> Evaluate
  194.     let fx' = fx |> Derive |> Simplify |> Evaluate |> format
  195.    // cos(sqrt(sin(tan(pi*x))))
  196.    //let fx2 = Cos(Pow(Sin(Tan(Mul(Const(pi), Var("x")))), Div(Const(1.), Const(2.))))
  197.    //let fx2 = Pow(Var("x"), Pow(Sin(Var("x")), Const(2.)))
  198.    let fx2 = Pow(Add(Const(1.), Pow(Var("x"), Const(2.))), Const(100.)) |> Simplify |> Evaluate
  199.    let fx2' = fx2 |> Derive |> Simplify |> Evaluate |> format
  200.    
  201.     printfn "f(x) = %A\nf(x)' = %A\ng(x) = %A\ng(x)' = %A" (fx |> format) fx' (fx2 |> format) fx2'
  202.     System.Console.ReadLine() |> ignore
  203.     0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement