Emmy is a Clojure(Script) implementation of the scmutils system for math and physics investigations in the Clojure and ClojureScript languages. Emmy provides facilities for
And implementations of many different mathematical objects, all built on a tower of generic, extensible mathematical operations.
Scmutils is extensively used in the textbooks The Structure and Interpretation of Classical Mechanics and Functional Differential Geometry by G.J. Sussman and J. Wisdom.
:wave: Need help getting started? Say hi on Clojurians Slack in #emmy.
Note Emmy is best experienced in an interactive environment like the REPL. We support many environments with rich support for TeX rendering and plotting.
Install Emmy
into your Clojure(Script) project using the instructions at its
Clojars page:
Or grab the most recent code using a Git dependency:
;; Replace $GIT_SHA with the most recent commit:
{io.github.mentat-collective/emmy
{:git/sha "$GIT_SHA"}}
Require emmy.env
in your Clojure(Script) namespace:
(ns my-app
(:require [emmy.env :as e :refer :all]))
Or clone this repository:
git clone git@github.com:mentat-collective/emmy.git
cd emmy
then install the Clojure command line
tool and run the following command
to launch a REPL with emmy.env
already loaded:
clj -M:test:dev:repl
Math works as expected (see Generics for the full menu of operations), but notice that the numeric tower includes complex numbers, and proper ratios in ClojureScript:
(- (* 7 (/ 1 2)) 2)
;;=> 3/2
(asin -10)
;;=> #emmy/complex [-1.5707963267948966 2.9932228461263786]
Symbols are interpreted as abstract complex numbers, and arithmetic on them
generates symbolic expressions. You can render these with
->TeX
and
->infix
:
(def render (comp ->infix simplify))
(square (sin (+ 'a 3)))
;;=> (expt (sin (+ a 3)) 2)
(render (square (sin (+ 'a 3))))
;;=> "sin²(a + 3)"
Use the
D
operator to perform forward-mode automatic
differentiation
and
simplify
to
collapse symbolic expressions into tidy form:
((D cube) 'x)
;;=> (+ (* x (+ x x)) (* x x))
(simplify ((D cube) 'x))
;;=> (* 3 (expt x 2))
(->infix
(simplify ((D cube) 'x)))
;;-> "3 x²"
Emmy is based on the engine behind The Structure and Interpretation of Classical Mechanics, and has a built-in API for exploring Lagrangian and Hamiltonian mechanics.
Define a Lagrangian for a
central potential U
acting on a particle with mass m
:
(defn L-central-polar [m U]
(fn [[_ [r] [rdot thetadot]]]
(- (* 1/2 m
(+ (square rdot)
(square (* r thetadot))))
(U r))))
and generate the two Euler-Lagrange equations of
motion
for the r
and theta
coordinates:
(let [potential-fn (literal-function 'U)
L (L-central-polar 'm potential-fn)
state (up (literal-function 'r)
(literal-function 'theta))]
(render
(((Lagrange-equations L) state) 't)))
;;=> "down(- m r(t) (Dθ(t))² + m D²r(t) + DU(r(t)), m (r(t))² D²θ(t) + 2 m r(t) Dr(t) Dθ(t))"
There is so much more! This is a dense library, and lots of documentation remains to be written. Some suggested next steps, for now:
If you want to use Emmy
with Clerk, check out the emmy/clerk
template. This deps-new
template
will generate a Clerk project for you, fully configured to use Emmy
in your
Clerk notebooks.
The project's interactive documentation was generated using Nextjournal's Clerk. If you'd like to edit or play with the documentation, you'll need to install
Next, clone the repository:
git clone git@github.com:mentat-collective/emmy.git
cd emmy
Run this command in the cloned repository:
bb clerk-watch
This will open a browser window to http://localhost:7777
with the contents of
the documentation notebook. Any edits you make to dev/emmy/notebook.clj
will be picked up and displayed in the browser on save.
SICM and FDG can be thought of as spiritual successors to The Structure and Interpretation of Computer Programs, a very influential text—as I can attest, since carefully reading this book in my 30s changed my life as a programmer. To see the same techniques applied to differential geometry and physics is an irresistible lure.
Scmutils is an excellent system, but it is written in an older variant of LISP (Scheme) and is tied to a particular implementation of Scheme—MIT/GNU Scheme. (There is a port to Guile, but due to the fact that Guile does not support MIT Scheme's apply hooks some glue code is required to run examples from the book in that environment.)
Having the system in Clojure offers a number of advantages. It is not necessary to obtain or prepare a MIT/GNU Scheme executable to execute: only a Java runtime is required. It does not require the X Window System for graphics, as MIT Scheme does. All of the standard tooling for Java and Clojure become available, and this is a lot compared to what we get with MIT/GNU scheme. Clojure support is now extensive in any number of editors and IDEs. Even better, you can interact with the system in the context of a Jupyter notebook.
You can invoke the system from within Java or JavaScript code or use any Java or JS packages you like together with the mathematics system. It's my hope that continuing this project will extend the reach of SICM and FDG by allowing experimentation and collaboration with them in modern environments.
To cite this repository, see the "Cite this Repository" link on the top right of
the Github page. Citation information is generated from
CITATION.cff
.
Here is the generated BibTeX entry:
@software{Ritchie_Emmy_Functional_Computer_2016},
author = {Ritchie, Sam and Smith, Colin},
license = {GPL-3.0},
month = {4},
title = {{Emmy: Functional Computer Algebra in Clojure}},
url = {https://github.com/mentat-collective/emmy},
version = {0.32.0},
year = {2016}
In the above BibTeX entry, the version number is intended to be that from resources/EMMY_VERSION, and the year corresponds to the project's open-source release.
Copyright © 2016-2024 Colin Smith, Sam Ritchie.