Character math in Clojure compared to F #

I stumbled upon the next F # sample and found it intriguing.

http://www.codeproject.com/KB/net-languages/SymbolicCalcInFS.aspx

Does Clojure have language / library features to facilitate this? It is normal to call up Polish notation for formulas if this makes the process easier.

Thanks, and let me know if you have any questions.

+4
source share
6 answers

I don't know much about Clojure, but here are at least some pointers.

A key feature that makes F # code good is pattern matching by algebraic data types. The type of algebraic data is, for example, an Expression type declaration (which is used to represent mathematical expressions), and template matching is the match construct, which is used to test various known cases when implementing simplification or differentiation.

I do not think that Clojure has built-in support for pattern matching, but can be implemented as a library. One library that looks pretty interesting is the match matching module (in Clojars). Here is an example that an algebraic evaluator uses to implement (which is pretty close to the F # article).

Another thing that appears in the F # article is active templates (which allow you to declare and reuse templates). I do not think that there is a Clojure library for this, but given the flexibility of the language, it should also be possible to implement them (however, they are not needed in the F # article).

+6
source

Lisp has a long history in symbolic computing. See Peter Norwig AI Tutorial . Lisp provides many great language features for abstracting common character operations. Sometimes you can write very compressed code (shorter / shorter than F #).

Static languages ​​like F # have strong type systems and convenient pattern matching by data type. The compiler can find errors that are caught by a type system, for example. missing consideration is one special case. Thinking about the types with your data can also reduce the chances of an error at runtime. Type inference in F # also makes F # code very concise.

+6
source

Symbolic differentiation was one of the first lisp applications!

I made a blogpost about a simple symbolic differentiator. It deals only with + and *, but it expands easily.

It was part of a series I wrote to introduce newcomers to clojure at a conference in London to show how easy it is for clojure to manage their own code.

Of course, the nice thing is that by doing the differentiation, the code can then be compiled! This way you can create differentiated versions of user input or macros that produce functions and their derivatives, etc.

The original is here and the beautiful syntax is:

http://www.learningclojure.com/2010/02/clojure-dojo-4-symbolic-differentiation.html

But I posted the code here so you can see:

 ;; The simplest possible symbolic differentiator ;; Functions to create and unpack additions like (+ 1 2) (defn make-add [ ab ] (list '+ ab)) (defn addition? [x] (and (=(count x) 3) (= (first x) '+))) (defn add1 [x] (second x)) (defn add2 [x] (second (rest x))) ;; Similar for multiplications (* 1 2) (defn make-mul [ ab ] (list '* ab)) (defn multiplication? [x] (and (=(count x) 3) (= (first x) '*))) (defn mul1 [x] (second x)) (defn mul2 [x] (second (rest x))) ;; Differentiation. (defn deriv [exp var] (cond (number? exp) 0 ;; d/dx c -> 0 (symbol? exp) (if (= exp var) 1 0) ;; d/dx x -> 1, d/dx y -> 0 (addition? exp) (make-add (deriv (add1 exp) var) (deriv (add2 exp) var)) ;; d/dx a+b -> d/dx a + d/dx b (multiplication? exp) (make-add (make-mul (deriv (mul1 exp) var) (mul2 exp)) ;; d/dx a*b -> d/dx a * b + a * d/dx b (make-mul (mul1 exp) (deriv (mul2 exp) var))) :else :error)) ;;an example of use: create the function x -> x^3 + 2x^2 + 1 and its derivative (def poly '(+ (+ (* x (* xx)) (* 2 (* xx))) 1)) (defn poly->fnform [poly] (list 'fn '[x] poly)) (def polyfn (eval (poly->fnform poly))) (def dpolyfn (eval (poly->fnform (deriv poly 'x)))) ;;tests (use 'clojure.test) (deftest deriv-test (testing "binary operators" (is (= (let [m '(* ab)] [(multiplication? m) (make-mul (mul1 m) (mul2 m))]) [true '(* ab)])) (is (= (let [m '(* ab)] [(addition? m) (make-add (add1 m) (add2 m))]) [false '(+ ab)]))) (testing "derivative function" (is (= (deriv '0 'x) '0)) (is (= (deriv '1 'x) '0)) (is (= (deriv 'x 'x) '1)) (is (= (deriv 'y 'x) '0)) (is (= (deriv '(+ xx) 'x) '(+ 1 1))) (is (= (deriv '(* xx) 'x) '(+ (* 1 x) (* x 1)))) (is (= (deriv '(* xx) 'y) '(+ (* 0 x) (* x 0)))) (is (= (deriv '(* x (* xx)) 'x) '(+ (* 1 (* xx)) (* x (+ (* 1 x) (* x 1))))))) (testing "function creation: d/dx (x^3 + 2x^2 + 1) = 3x^2 + 4x " (let [poly '(+ (+ (* x (* xx)) (* 2 (* xx))) 1)] (is (= ((eval (poly->fnform poly)) 3) 46)) (is (= ((eval (poly->fnform (deriv poly 'x))) 3)))))) 
+4
source

I have not tried it, but Clojuratica looks very interesting.

+2
source

Ok, now Clojure offer powerful template matching libraries:

+1
source

Yes, the system you are describing now exists on Clojure! This is none other than Jerry Sussman's companion system for his book Wisdom - SICM (Structure and Interpretation of Classical Mechanics). For Clojure, it was called sicmutils and ported by Colin Smith.

I briefly described it elsewhere - fooobar.com/questions/394107 / ... - but briefly yes, it definitely does the four things that the F # article mentions, namely:

  • Differentiation:
  • Simplification of algebraic expressions
  • Formatting
  • Expression Analysis

and many many others...

1) Differentiation (full partial differentiation is supported)

 > (defn ff [xy] (* (expt x 3)(expt y 5))) > ((D ff) 'x 'y) ==> (down (* 3 (expt x 2) (expt y 5)) (* 5 (expt x 3) (expt y 4))) > ;; ie vector of results wrt to both variables 

NB. Two types of vectors are supported: up and down to accommodate covariant and contravariant expressions

2) Simplification of expressions: Oh, yes ...

 > (def unity (+ (square sin) (square cos))) > (unity 'x) ==> 1 ;; yes we can deal with symbols 

3) Formatting. Expressions can be made in TeX for a beautiful display. I can't show it easily here, but a Maple-style laptop / workhhet is being developed using Clojure "Gorilla"

4) Analysis: Obviously. The conversion between expressions and functions is an essential part of the system.

Take a look at https://github.com/littleredcomputer/sicmutils . you don’t even need Clojure to run it, you can use the jar file provided by Java.

0
source

All Articles