Last active
August 23, 2019 15:52
Revisions
-
ericnormand revised this gist
Aug 23, 2019 . 2 changed files with 37 additions and 0 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,37 @@ (defn variable? [v] (symbol? v)) (defn same-variable? [v1 v2] (and (variable? v1) (variable? v2) (= v1 v2))) (defn sum? [expr] (and (seq? expr) (= '+ (first expr)))) (defn ->sum [u v] (list '+ u v)) (defn prod? [expr] (and (seq? expr) (= '* (first expr)))) (defn ->prod [u v] (list '* u v)) (defn deriv [expr var] (cond (same-variable? expr var) 1 (or (variable? expr) (number? expr)) 0 (sum? expr) (let [[_ u v] expr] (->sum (deriv u var) (deriv v var))) (prod? expr) (let [[_ u v] expr] (->sum (->prod u (deriv v var)) (->prod v (deriv u var)))))) File renamed without changes. -
ericnormand revised this gist
Aug 18, 2019 . 1 changed file with 29 additions and 0 deletions.There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,29 @@ (defn sum? [exp] (= (first exp) '+)) (defn product? [exp] (= (first exp) '*)) (defn pred* [exp clauses] (when clauses (list 'if (list (first clauses) exp) (second clauses) (pred* exp (-> clauses next next))))) (defmacro pred [exp & clauses] (pred* exp clauses)) (defn deriv [exp v] (pred exp number? 0 symbol? (if (= exp v) 1 0) sum? (list '+ (deriv (second exp) v) (deriv (last exp) v)) product? (list '+ (list '* (second exp) (deriv (last exp) v)) (list '* (deriv (second exp) v) (last exp))))) -
ericnormand created this gist
Aug 18, 2019 .There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,22 @@ *symbolic differentiation* I got excited last week by the numeric differentiator challenge. When I originally read that section of SICP so many years ago, I was elated. Do you know how hard that would be to do in Java? Now for something that's even harder to do in Java: symbolic differentiation. Here's the [relevant link into SICP](https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book-Z-H-16.html#%_sec_2.3.2), for reference. The challenge this week is to use four differentiation formulas to make a symbolic differentiator. It has been a while since I've done any calculus, so I had to look these up: 1. `dc/dx = 0` (for a constant c, or variable c different from x) 2. `dx/dx = 1` 3. `d(u+v)/dx = du/dx + dv/dx` (addition rule) 4. `d(uv)/dx = u(dv/dx) + v(du/dx)` (product rule) This won't differentiate every formula, but it will differentiate sums and products of variables and numbers. You should make a function that takes an expression and a variable to differentiate by, like so: ```clojure (deriv '(+ x 5) 'x) ;=> (+ 1 0) ``` Don't worry about simplifying the final expression. Just make sure it's right. This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,30 @@ (ns symderiv.main) (defn deriv [expr v] (cond (list? expr) (let [[op a b] expr] (case op + (list '+ (deriv a v) (deriv b v)) * (list '+ (list '* a (deriv b v)) (list '* b (deriv a v))) (throw (ex-info "Unrecognized operator" {:op op})))) (= expr v) 1 (or (number? expr) (symbol? expr)) 0 :else (throw (ex-info "Unrecognized expression" {:expr expr})))) (ns symderiv.main (:require [meander.strategy.delta :as r])) (defn deriv [expr var] (let [operations (r/rewrite ; addition (+ ?u ?v) (+ ~(deriv ?u var) ~(deriv ?v var)) ; multiplication (* ?u ?v) (+ (* ?u ~(deriv ?v var)) (* ?v ~(deriv ?u var)))) var' (r/pipe (r/pred #(= var %)) (r/build 1)) constant' (r/pipe (r/pred number?) (r/build 0)) other-var' (r/pipe (r/pred symbol?) (r/build 0)) choice (r/choice operations var' other-var' constant')] (choice expr)))