#+OPTIONS: H:3 num:nil toc:2 \n:nil ::t |:t ^:{} -:t f:t *:t tex:t d:(HIDE) tags:not-in-toc #+STARTUP: align fold nodlcheck hidestars oddeven lognotestate hideblocks #+SEQ_TODO: TODO(t) INPROGRESS(i) WAITING(w@) | DONE(d) CANCELED(c@) #+TAGS: Write(w) Update(u) Fix(f) Check(c) noexport(n) #+TITLE: Maxima Source Code Blocks in Org Mode #+AUTHOR: Thomas S. Dye #+EMAIL: tsd[at]tsdye[dot]com #+LANGUAGE: en #+HTML_LINK_UP: index.html #+HTML_LINK_HOME: https://orgmode.org/worg/ #+EXCLUDE_TAGS: noexport #+PROPERTY: header-args:org :exports code :results replace #+name: banner #+begin_export html

Org Mode support for Maxima

#+end_export #+name: ob-doc-maxima-requires-ob-org #+begin_src elisp :exports none :results silent (require 'ob-org) #+end_src * Template Checklist [9/12] :noexport: - [X] Revise #+TITLE: - [X] Indicate #+AUTHOR: - [X] Add #+EMAIL: - [X] Revise banner source block [3/3] - [X] Add link to a useful language web site - [X] Replace "Language" with language name - [X] Find a suitable graphic and use it to link to the language web site - [X] Write an [[Introduction]] - [X] Describe [[Requirements and Setup][Requirements and Setup]] - [X] Replace "Language" with language name in [[Org Mode Features for Language Source Code Blocks][Org Mode Features for Language Source Code Blocks]] - [X] Describe [[Header Arguments][Header Arguments]] - [ ] Describe support for [[Sessions]] - [ ] Describe [[Result Types][Result Types]] - [ ] Describe [[Other]] differences from supported languages - [X] Provide brief [[Examples of Use][Examples of Use]] * Introduction Maxima is a computer algebra system descended from Macsyma, which was originally released in 1982. It is released under the terms of the GNU General Public License. Maxima is written in Common Lisp. It can be accessed and extended in Lisp. * Requirements and Setup Maxima binaries are available for Windows and Linux. These either require a compatible Common Lisp or an executable Lisp image. Mac OS X users can install via brew or MacPorts. The combinations of operating system and Lisp implementation known to run Maxima can be found on [[http://maxima-project.org/wiki/index.php?title%3DMaxima_ports][the Maxima ports page]]. There are several versions of Maxima, some with different names. The variable =org-babel-maxima-command= can be set to the name of your Maxima executable. The default value is "maxima". Maxima ships with =Emacs= modes. Instructions for configuring them can be found on [[http://emacswiki.org/emacs/MaximaMode][emacswiki]]. =imaxima= is an =Emacs= front end with image that displays fully typeset math in your =Emacs= window. You must activate Maxima by adding a line to =org-babel-load-languages=: #+BEGIN_SRC emacs-lisp (org-babel-do-load-languages 'org-babel-load-languages '((maxima . t))) ; this line activates maxima #+END_SRC * Org Mode Features for Maxima Source Code Blocks ** Header Arguments There are no Maxima-specific /default/ header arguments. There are two Maxima-specific header arguments: - =:batch= :: This can be set to one of Maxima's source-code loaders: =batch=, =load= or =batchload=. The default loader is =batchload=. - =:graphics-pkg= :: This can set to one of Maxima's graphics packages: =draw= or =plot=. The default package is =plot=. If a =:file filename.ext= header argument is provided to a Maxima source block, in conjunction with a =:results graphics file= header argument, then the graphics device is determined from the file-ending =ext=. For the =plot= package, the following graphics devices (gnuplot terminals) are supported: #+begin_example png, pdf, ps, svg. #+end_example The =draw= package supports these graphics devices: #+begin_example png, jpg, gif, eps, svg, pdf. #+end_example The header argument, =:cmdline=, can be used to pass command line arguments to Maxima. ** Sessions Org-mode support for Maxima does not include sessions. ** Result Types Maxima produces the full range of result types. * Examples of Use ** Calculator The following source code block uses =maxima= as a calculator for powers of 12, where the powers are passed with a variable. #+begin_example ,#+name: test-maxima ,#+header: :exports results ,#+header: :var x=1.3121254 ,#+begin_src maxima programmode: false; print(12^x); ,#+end_src #+end_example #+name: test-maxima #+header: :exports results #+header: :var x=1.3121254 #+begin_src maxima programmode: false; print(12^x); #+end_src HTML export of the result: #+RESULTS: test-maxima : 26.06280316745402 ** Solver Of course, =maxima= is more than a calculator. #+begin_example ,#+name: solve-maxima ,#+header: :exports results ,#+begin_src maxima :results output programmode: false; eq: x**2-16 = 0; solution: solve(eq, x); print(solution); ,#+end_src #+end_example #+name: solve-maxima #+header: :exports results #+begin_src maxima :results output programmode: false; eq: x**2-16 = 0; solution: solve(eq, x); print(solution); #+end_src HTML export of the result: #+RESULTS: solve-maxima : solve: solution: : x = - 4 : x = 4 : [%t1, %t2] ** 3D plots With =gnuplot= installed (4.0 or higher), 3D graphics are possible. This example is from [[http://maxima.sourceforge.net/maxima-gnuplot.html][a tutorial on the maxima/gnuplot interface]]. #+begin_example ,#+name: 3d-maxima ,#+header: :file images/maxima-3d.png ,#+header: :exports results ,#+header: :results file graphics ,#+begin_src maxima programmode: false; plot3d(atan(-x^2+y^3/4),[x,-4,4],[y,-4,4],[grid,50,50],[gnuplot_pm3d,true]); ,#+end_src #+end_example #+name: 3d-maxima #+header: :file images/maxima-3d.png #+header: :exports results #+header: :results file graphics #+begin_src maxima programmode: false; plot3d(atan(-x^2+y^3/4),[x,-4,4],[y,-4,4],[grid,50,50],[gnuplot_pm3d,true]); #+end_src HTML export of the Maxima code block result: #+RESULTS: 3d-maxima [[file:images/maxima-3d.png]] ** Inline Display of Maxima LaTeX Output [[http://maxima.sourceforge.net/][Maxima]] code can be evaluated and displayed inline in Org mode through babel [fn:1] as in the example below, based on RS initial example. #+begin_example ,#+NAME: tex-maxima ,#+HEADER: :exports results ,#+BEGIN_SRC maxima :results raw tex(exp(-x)/x); ,#+END_SRC #+end_example #+NAME: tex-maxima #+HEADER: :exports results #+BEGIN_SRC maxima :results raw tex(exp(-x)/x); #+END_SRC HTML export of the result: #+RESULTS: tex-maxima $${{e^ {- x }}\over{x}}$$ ** The =:batch= header argument Setting the =:batch= header argument to =batch=: - allows the use of the =:lisp= reader; - provides a more verbose output; - allows one to typeset calculations in LaTeX. *** An example with the =:lisp= reader Sample code block: #+name: batch-maxima.org #+begin_src org :exports code :results replace ,#+NAME: batch-maxima ,#+HEADER: :batch batch ,#+HEADER: :exports results ,#+HEADER: :results raw ,#+HEADER: :wrap example ,#+BEGIN_SRC maxima (assume(z>0), integrate(t^z*exp(-t),t,0,inf)); :lisp $% ,#+END_SRC #+end_src #+RESULTS: batch-maxima.org #+NAME: batch-maxima #+HEADER: :batch batch #+HEADER: :exports results #+HEADER: :results raw #+HEADER: :wrap example #+BEGIN_SRC maxima (assume(z>0), integrate(t^z*exp(-t),t,0,inf)); :lisp $% #+END_SRC The first line of input computes the integral \(\int_0^{\infty} t^z\,e^{-t}\,dt\), assuming that \(z\) is positive. The second input line uses the =:lisp= reader to print the internal representation of that result as a sexp. HTML export of results: #+RESULTS: batch-maxima #+begin_example (assume(z > 0),integrate(t^z*exp(-t),t,0,inf)) gamma(z + 1) ((%GAMMA SIMP) ((MPLUS SIMP) 1 $Z)) #+end_example *** An example with line numbering By default, the command-line option =--very-quiet= is passed to the Maxima executable; this option suppresses the output of the start-up banner and input/output labels. That can be modified by setting =:cmdline --quiet=, which allows printing of input/output labels. Sample code block: #+name: batch-quiet-maxima.org #+begin_src org :exports code :results replace ,#+NAME: batch-quiet-maxima ,#+HEADER: :batch batch ,#+HEADER: :exports results ,#+HEADER: :results raw ,#+HEADER: :wrap example ,#+HEADER: :cmdline --quiet ,#+BEGIN_SRC maxima rat(1/(x+1) + x/(x-1)); ,#+END_SRC #+end_src #+RESULTS: batch-quiet-maxima.org #+NAME: batch-quiet-maxima #+HEADER: :batch batch #+HEADER: :exports results #+HEADER: :results raw #+HEADER: :wrap example #+HEADER: :cmdline --quiet #+BEGIN_SRC maxima rat(1/(x+1) + x/(x-1)); #+END_SRC HTML export of results: #+RESULTS: batch-quiet-maxima #+begin_example (%i1) rat(1/(x+1)+x/(x-1)) 2 x + 2 x - 1 (%o1)/R/ ------------ 2 x - 1 #+end_example Maxima's default is to print input in linear (or 1d) fashion, while output is printed in 2d. *** LaTeX output To produce LaTeX output for an extended computation, one needs to set-up a LaTeX printer. This example uses the ~alt-display~ package to do that. To print output as LaTeX, Maxima's 2d printer is replaced with ~org_tex_display~; to ensure input lines are not echoed, its 1d printer is replaced with a sink, ~org_no_display~ (see also this [[batch-note][Note]]). Tangle this code block (=C-u C-c C-v t=): #+comment: Ensure the block is evaluated (C-c C-c) after a change. #+comment: Move to the results block and tangle it (C-u C-c C-v t) #+name: maxima-initialize.lisp.org #+begin_src org ,#+NAME: maxima-initialize.lisp ,#+HEADER: :tangle ./maxima-initialize.lisp ,#+HEADER: :exports none ,#+HEADER: :eval none ,#+begin_src maxima #$(load("alt-display.mac"), define_alt_display(org_no_display(output_form), ""), define_alt_display(org_tex_display(output_form), block([], printf(true,"~&#+begin_example~%(~a~d)~%",outchar,linenum), printf(true,"~&#+end_example~%"), tex(second(output_form)))), set_alt_display(2,org_tex_display), set_alt_display(1,org_no_display));#$ ,#+end_src #+end_src #+RESULTS: maxima-initialize.lisp.org #+NAME: maxima-initialize.lisp #+HEADER: :tangle ./maxima-initialize.lisp #+HEADER: :exports none #+HEADER: :eval none #+begin_src maxima #$(load("alt-display.mac"), define_alt_display(org_no_display(output_form), ""), define_alt_display(org_tex_display(output_form), block([], printf(true,"~&#+begin_example~%(~a~d)~%",outchar,linenum), printf(true,"~&#+end_example~%"), tex(second(output_form)))), set_alt_display(2,org_tex_display), set_alt_display(1,org_no_display));#$ #+end_src Next, write a Maxima code block that sets the =:cmdline= header to read in the initialization code that was just tangled. #+name: batch-latex-maxima.org #+begin_src org ,#+NAME: batch-latex-maxima ,#+HEADER: :batch batch ,#+HEADER: :exports results ,#+HEADER: :results raw ,#+HEADER: :wrap maximablock ,#+HEADER: :cmdline --quiet --preload-lisp ./maxima-initialize.lisp ,#+BEGIN_SRC maxima (assume(z>0), 'integrate(t^z*exp(-t),t,0,inf) = integrate(t^z*exp(-t),t,0,inf)); diff(%,z); ,#+END_SRC #+end_src #+RESULTS: batch-latex-maxima.org #+NAME: batch-latex-maxima #+HEADER: :batch batch #+HEADER: :exports results #+HEADER: :results raw #+HEADER: :wrap maximablock #+HEADER: :cmdline --quiet --preload-lisp ./maxima-initialize.lisp #+BEGIN_SRC maxima (assume(z>0), 'integrate(t^z*exp(-t),t,0,inf) = integrate(t^z*exp(-t),t,0,inf)); diff(%,z); #+END_SRC HTML export of the results: #+RESULTS: batch-latex-maxima #+begin_maximablock #+begin_example (%o1) #+end_example $$\int_{0}^{\infty }{t^{z}\,e^ {- t }\;dt}=\Gamma\left(z+1\right)$$ #+begin_example (%o2) #+end_example $$\int_{0}^{\infty }{t^{z}\,e^ {- t }\,\log t\;dt}=\psi_{0}(z+1)\, \Gamma\left(z+1\right)$$ #+end_maximablock *** <> Note Prior to version =5.47=, Maxima could only pre-load a lisp file; to get around this constraint, the Maxima code is written into a lisp file, and the =#$= reader macro is used to read the Maxima code. In versions 5.47 and higher, the Maxima code can be put in a =.mac= file and pre-loaded without the need for such tricks. ** The =:graphics-pkg= header argument The =:graphics-pkg= header argument can be set to use either Maxima's built-in =plot= package (the default), or the =draw= package. *** The =plot= package The =plot= package is the default package that provides a simplified interface to =gnuplot=. Here is an example that creates a =gif= file. #+name: graphics-pkg--plot.org #+begin_src org ,#+NAME: graphics-pkg--plot ,#+HEADER: :graphics-pkg plot ,#+HEADER: :file images/ob-maxima-plot.gif ,#+HEADER: :results graphics file ,#+HEADER: :exports both ,#+begin_src maxima plot2d( sin(x), [x,0,2*%pi]); ,#+end_src #+end_src #+RESULTS: graphics-pkg--plot.org #+NAME: graphics-pkg--plot #+HEADER: :graphics-pkg plot #+HEADER: :file images/ob-maxima-plot.gif #+HEADER: :results graphics file #+HEADER: :exports both #+begin_src maxima plot2d( sin(x), [x,0,2*%pi]); #+end_src HTML export of the results: #+CAPTION: The graph of /sin(x)/ created with =plot=. #+RESULTS: graphics-pkg--plot [[file:images/ob-maxima-plot.gif]] *** The =draw= package The =draw= package has more features than =plot=, including an object-oriented interface to several graphics engines, including =gnuplot=. Here is an example that creates an =svg= file containing the graph of a discontinuous function. #+name: graphics-pkg--draw.org #+begin_src org ,#+NAME: graphics-pkg--draw ,#+HEADER: :graphics-pkg draw ,#+HEADER: :file images/ob-maxima-draw.svg ,#+HEADER: :results graphics file ,#+HEADER: :exports both ,#+begin_src maxima f(x) := if x>0 then cos(x) else if x<0 then 0; draw2d( line_width=2, grid=true, yrange=[-1.2,1.2], explicit(f,x,0,%pi), explicit(f,x,-1,0), fill_color=white, ellipse(0,0,0.05,0.05,0,360), fill_color=blue , ellipse(0,1,0.05,0.05,0,360)); ,#+end_src #+end_src #+RESULTS: graphics-pkg--draw.org #+NAME: graphics-pkg--draw #+HEADER: :graphics-pkg draw #+HEADER: :file images/ob-maxima-draw.svg #+HEADER: :results graphics file #+HEADER: :exports both #+begin_src maxima f(x) := if x>0 then cos(x) else if x<0 then 0; draw2d( line_width=2, grid=true, yrange=[-1.2,1.2], explicit(f,x,0,%pi), explicit(f,x,-1,0), fill_color=white, ellipse(0,0,0.05,0.05,0,360), fill_color=blue , ellipse(0,1,0.05,0.05,0,360)); #+end_src HTML export of the results: #+CAPTION: A discontinuous function plotted with =draw=. #+RESULTS: graphics-pkg--draw [[file:images/ob-maxima-draw.svg]] **** Note Internally, =ob-maxima= uses the function =set_draw_defaults=. Because this function _overwrites_ the existing defaults, using it in code blocks with the =:graphics-pkg draw= header argument will cause the source block evaluation to fail silently. * Additional Notes ** Toggle inline display of latex code Latex code in org mode can be displayed inline by 'C-c C-x C-l'. To remove the inline display 'C-c C-c' is used. This is described further in the manual [fn:2]. ** Set scale of output If the inline display of the equations are illegible, the scale can be set by customising the variable 'org-format-latex-options', by setting the :scale variable to a value >1. ** Export This exports nicely to both html (C-c C-e h h) and pdf (C-c C-e l p). See [fn:3] and [fn:4] in the manual. ** Noweb expansion _NOTE:_ I have not tested this yet, but as Eric Schulte noted on the mailing list: "Alternately, if you really want to get fancy you could use noweb expansion [fn:5] to insert the results of the imaxima code block into a latex code block, and then use the existing latex code block functionality to convert the imaxima output to images of different types depending on the export target." [fn:6] ** Footnotes [fn:1] (info "(org)Library of Babel") [fn:2] (info "(org)Previewing LaTeX fragments") [fn:3] (info "(org)Exporting code blocks") [fn:4] (info "(org)The export dispatcher") [fn:5] (info "(org)noweb") [fn:6] [[https://lists.gnu.org/archive/html/emacs-orgmode/2013-11/msg00893.html][Re: imaxima babel]]