Giter VIP home page Giter VIP logo

clj-maxima's Introduction

clj-maxima

Maxima as a Clojure library, using ABCLJ.

Clojars Project

But... how?

Maxima is written in Common Lisp, and can be used as a Common Lisp library. Maxima by itself has a good Common Lisp interop with options to even switch to the Common Lisp REPL and go back to the Maxima REPL.

With the powers of ABCL and ABCLJ we can interop with Common Lisp software from Clojure very easily, without any servers or subprocessing. Most of the Maxima integrations I've seen depends of having a Maxima installed in your machine (for example Maxima.jl ), opens the Maxima repl on a subprocess pipe and send commands to it. This library access the Maxima functions directly through ABCL, everything happens on the same JVM process (clojure, common lisp or maxima code). You don't even need Maxima installed in your machine to use this library, this library already have Maxima binaries for ABCL which will be extracted and loaded in the Common Lisp environment automatically.

Maxima is an outstanding project. Is the oldest computer program that I know that is used until nowadays (Macsyma dates from the 60's!!). With this library I hope to improve the clojure current state for scientific computation, and improve Maxima and Common Lisp reach.

Currently this library is using Maxima version 5.44.0 and ABCL version 1.8.0.

Usage

Maxima and this library relies 100% on Common Lisp interop, which means that most of the time you will be working with Common Lisp data. Maxima does not directly eval code in Maxima syntax, it always convert to its lisp list syntax, for example the maxima expression x*sin(a*x) is evaluated to ((MAXIMA::MTIMES MAXIMA::SIMP) MAXIMA::$X ((MAXIMA::%SIN MAXIMA::SIMP) ((MAXIMA::MTIMES MAXIMA::SIMP) MAXIMA::$A MAXIMA::$X))) in lisp. It is perfectly fine to use this lisp syntax in this library along with Common Lisp interop, but things can become ugly pretty quickly. I recommend to use Maxima code with Maxima syntax, and just use the Lisp syntax when needed. If you need to build maxima expressions programmatically try using mexpr.

To use maxima syntax use the meval function.

(require '[clj-maxima.core :as m])
(require '[abclj.core :as cl])

(m/meval "integrate(x*sin(a*x),x)")
; ==> returns
;#abclj/cl-cons ((MAXIMA::MTIMES MAXIMA::SIMP) ((MAXIMA::MEXPT MAXIMA::SIMP) MAXIMA::$A -2) ((MAXIMA::MPLUS MAXIMA::SIMP) ((MAXIMA::MTIMES MAXIMA::SIMP) -1 MAXIMA::$A MAXIMA::$X ((MAXIMA::%COS MAXIMA::SIMP) ((MAXIMA::MTIMES MAXIMA::SIMP) MAXIMA::$A MAXIMA::$X))) ((MAXIMA::%SIN MAXIMA::SIMP) ((MAXIMA::MTIMES MAXIMA::SIMP) MAXIMA::$A MAXIMA::$X))))

;eval and pretty print
(m/mevalp "integrate(x*sin(a*x),x)")
; ==> prints
;sin(a x) - a x cos(a x)
;-----------------------
;           2
;          a

It is possible to create maxima expressions using clojure primitives using mexpr:

(m/mexpr '[= [+ [** $%e [* $%pi $%i]] 1] 0])
;=> returns
; #abclj/cl-cons ((MAXIMA::MEQUAL) ((MAXIMA::MPLUS) ((MAXIMA::MEXPT) MAXIMA::$%E ((MAXIMA::MTIMES) MAXIMA::$%PI MAXIMA::$%I)) 1) 0)

(m/displap (m/mexpr '[= [+ [** $%e [* $%pi $%i]] 1] 0]))
;=>prints
;  %pi %i
;%e       + 1 = 0

To create Maxima lists use mlist:

(m/displap (m/mlist '$x -5 5))
;=> [x, - 5, 5]

This library does not provides wrapper functions to all maxima functions (really, it is a lot of them to maintain, see Maxima Function and Variable Index ), but it provides a unified way to access and call all of maxima functions using the clj-maxima.core/funcall function. It is important to notice that common maxima functions can be accessed in lisp with a $ prefix on the symbol, so the maxima function diff is accessed by the symbol $diff in lisp for example (see Lisp and Maxima for more details). This is also true for constants, for example %pi is accessed in lisp with $%pi. To maintain consistency with the Maxima documentation in this library we keep this convention and never auto prefix any symbol with a $. When using clj-maxima.core/funcall we automatically put the maxima namespace on all symbols and convert them to their common lisp correspondent classes, if a clojure sequential is passed as a argument mexpr will be applied.

funcall examples:

(require '[clj-maxima.core :refer :all])

(funcall '$diff '[** $x 3] '$x)
;is equivalent to
(meval "diff(x**3,x)")

(displap (funcall '$solve '[= 0 [* [+ [$f $x] -1] [$asin [$cos [* 3 $x]]]]] '$x))
;=> prints
;     %pi
;[x = ---, f(x) = 1]
;      6
; is equivalent to
(mevalp "solve(asin (cos (3*x))*(f(x) - 1)=0,x)")

Plotting

Plotting is fully supported, however it needs gnuplot installed in your system. Maxima alone does not have any GUI facilities, when asked for plots it creates arrays of points and passes to a external program. When you call the plotting functions Maxima will look for the gnuplot binary on your $PATH, if it does not find will raise an exception.

To install gnuplot (on Debian based distributions):

sudo apt install gnuplot-x11

To plot use:

(require '[clj-maxima.core :as m])
(require '[abclj.core :as cl])

(m/meval "plot2d(x^2,[x,-5,5])")

;or use funcall
(m/funcall '$plot2d '[** $x 2] (m/mlist '$x -5 5))

;or call the Maxima lisp functions directly using the lisp syntax through abcl java api
(cl/funcall (cl/getfunction 'maxima/$plot2d)
            (cl/cl-cons '[[maxima/mexpt maxima/simp nil] maxima/$x 2 nil])
            (cl/cl-cons '[[maxima/mlist maxima/simp nil] maxima/$x -5 5 nil]))

;or even with the common lisp interpreter
(cl/with-cl '(in-package :maxima)
            '($PLOT2D '((MEXPT SIMP) $X 2) '((MLIST SIMP) $X -5 5)))

Packaging

clj-maxima is not a conventional clojure package, is half a clojure package and half a common lisp one. The common lisp part (maxima itself) is bundled in this library as a zipped resource. When clj-maxima is required it will unzip the common lisp portion to (System/getProperty "java.io.tmpdir") and then import it to the common lisp environment. This is necessary because of maxima package system. If it is necessary to change the location of maxima change this property on clojure boot.

Important Links

TODOS

  • mfuncall (call functions defined on maxima on cl/clj side).
  • maxima contrib packages.

License

GNU General Public License v2.0

(Same as Maxima)

clj-maxima's People

Contributors

lsevero avatar phasetr avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.