Index of all namespaces
Algebolic expressions are Clojure data structures that represent mathematical expressions. They are trees built from a set of possible functions (non-leaf nodes) and terminals (leaf nodes). Terminals are either Clojure symbols, representing a variable (i.e. 'x) or numbers, representing a constant. Valid expressions are either a terminal, or a vector whose first is a function name and whose rest is the appropriate number of arguments to that function, which themselves must be expressions. Function names are represented as Clojure keywords. Algebolic expressions are not used to build Clojure functions, as in classic LISP symbolic regression, rather they are fed to a fast interpreter which calculates their value. This interpreter is written in Java and optimised for performance, as expression evaluation is a significant part of the run-time of a regression run.
Core genetic operation on expressions. Includes functions for creating expressions.
Provides a fast interpreter for algebolic expressions. The core of the interpreter is implemented in Java, for speed. It transforms expressions to its own internal representation - nested Java objects - and then evaluates them. For efficiency, the interpreter takes a list of variable values at which to evaluate the expression, and returns a list of expression values. This is because transforming the expression to the interpreter's internal format has a non-trivial fixed cost which is best amortized over a whole set of values. The core of the interpreter is implemented in Java because I found it difficult to make a Clojure interpreter as fast. This was after many tests of different approaches in Clojure. I think the difficulty of making it as fast in Clojure comes from the fact the interpreter naturally has a deeply-nested recursive call graph, with methods that do very little. So even a small amount of overhead on calls and dispatch becomes significant. The closest I was able to get to the Java performace was using a protocol and type approach, but it was still a (small) few times slower. I suspect this was down to primitive type boxing/unboxing on the function calls, but I'm not sure, as that is typically very fast on the JVM.
Some functions for using Mathematica with algebolic expressions.
Gorilla REPL rendering support for algebolic expressions.
Score functions for algebolic expressions.
Algebolic is a library for evolving mathematical expressions. You can use it to perform what’s known as symbolic regression, where a symbolic mathematical expression is found that fits a given dataset. More generally, you can use it to evolve mathematical expressions that optimise any score function. The expressions are implemented so they can be very quickly evaluated, as can their derivatives which is useful in more advanced applications. We use it in our research lab, for example, to evolve laws of physics directly from data.
Algebolic is built on the darwin genetic algorithm framework.
Add it to your project.clj file:
Examples can be found in the ws/demo directory. The intro.clj worksheet is quite readable. With the others you might have to put in some thought/experimentation! You can view them on the web:
- Introduction, basic symbolic regression
- Simple symbolic regression, full configuration
- SPEA2 symbolic regression, full configuration
- Adaptive evolution
Copyright © 2015 Imperial College London
Distributed under the MIT licence.