## Montag, 23. September 2013

### Finished GSoC project Expresso

Finished GSoC project Expresso

# Finished GSoC project Expresso

GSoC ends today and I can announce the 0.2.0 version of the expresso library. It is build on top of core.logic and core.matrix and provides symbolic manipulation of algebraic expressions.

What's there?

1. An api/dsl for manipulation of algebraic expressions which doesn't get in your way. Expresso's expressions are just clojure s-expressions and can be manipulated with rich set of clojure sequence functions
2. useful manipulations for mathematical expressions: simplify, multiply-out, differentiate, …
3. An equation solver which is capable of solving a single equation and multiple equations for unknowns.
4. An optimizer which transforms a mathematical expression to a semantically equivalent but performanter one
5. An expression compiler to compile an expression to an efficient clojure function
6. A semantic rule based translator on top of which many of expresso's features are implemented

The code is fully documented and I wrote a tutorial and showcase of expresso, the expresso-tutorial.

GSoC has been a really fun and valuable time for me. I learned a lot. Of course I will continue developing expresso! Expresso and core.matrix are the first steps in the direction of a full computer algebra system for clojure. I hope that it will help clojure to be an attractive choice for scientific computing projects in the future.

Showcase: Here are two examples of expresso's facility to manipulate mathematical expressions. They can be found and are explained in the expresso-tutorial 1.

1. solving word problems:
```(solve 'blue
(ex (= pencils (+ green white blue red)))
(ex (= (/ pencils 10) green))
(ex (= (/ pencils 2) white))
(ex (= (/ pencils 4) blue))
(ex (= red 45))) ;=> #{{blue 75N}}
```
1. Analyzing roots and extremata of functions. This code shows how easy one can implement tasks involving symbolic manipulation with expresso:
```(defn roots
"returns the set of roots of the expression in regard to var"
[var expr]
(solve var (ex (= ~expr 0))))

(defn extremata
"gets the extrema of the expression in regard to var. Returns a map with the
keys :maxima and :minima"
[var expr]
(let [d1 (differentiate [var] expr)
d2 (differentiate [var] d1)
candidates (roots var d1)]
(if (seq candidates)
(let [extremata
(->> candidates
(map (fn [candidate] [candidate (evaluate d2 {var candidate})]))
(remove #(== 0 (second %)))
(group-by #(< 0 (second %))))]
{:maxima (map first (get extremata false))
:minima (map first (get extremata true))}))))

(defn analyse-function
"returns a map with the :roots, the :maxima and the :minima of the expression
in regard to var"
[var expr]
(assoc (extremata var expr)
:roots (roots var expr)))

(analyse-function 'x (ex (- (** x 4) (** x 2))))
;=> {:roots #{0 -1 1},
;;   :maxima (0),
;;   :minima (0.7071067811865476 -0.7071067811865476)}
```

Ideas/feedbacks etc are greatly appreciated! Enjoy, Maik