The University of Sheffield
Neil Lawrence ML@SITraN
MATweave: Integrating MATLAB Software with LaTeX Documents

MATweave: Integrating MATLAB Software with LaTeX Documents

I believe very strongly in the ideas of reproducible research. These ideas arise from Jon Claerbout and were summarized by Buckheit and Donoho:

An article about computational science in a scientific publication is not the scholarship itself, it is merely advertising of the scholarship. The actual scholarship is the complete software development environment and the complete set of instructions which generated the figures.

For some time my group has been practising what they preach with making software available for reproducing all figures in the papers we produce. This should be true for all papers we are the principal authors on since about 2003. One problem that arises is that the code for reproducing the figures is normally kept in a separate file from the paper itself. If you write papers in LaTeX and produce figures in a package like R, then there is the elegant solution of using Sweave for integrating your code and your report. However, in machine learning many people use MATLAB and increasingly I'm using Octave, an open source alternative for MATLAB. MATweave is a solution for integrating Octave or MATLAB code in a LaTeX environment. I say solution, rather than software, because currently it is a couple of tricks and a couple of lines of code.

  1. The first trick is to make use of block comments, introduced in Octave 3.2 and MATLAB R14. Block comments are of the form:

    %{ This is a comment!  
    This line is also commented!  
    %} 
    for i = 1:10 % Code here is outside the block comment.  
      disp(i) 
    end 
    
    And the great thing is that a block comment in MATLAB is also a LaTeX comment (but not a block comment!) because it starts with a %.
  2. The second trick is to include the verbatim package and define new MATLAB/Octave environments based on comment and verbatim using the following commands.

    \usepackage{verbatim}
    \newenvironment{matlab}{\comment}{\endcomment}    
    \newenvironment{octave}{\comment}{\endcomment}    
    \newenvironment{matlabv}{\verbatim}{\endverbatim} 
    \newenvironment{octavev}{\verbatim}{\endverbatim} 
    
    This allows you to include MATLAB/Octave code that won't be read by LaTeX using e.g. \begin{octave} ... \end{octave} and code that will be shown in a verbatim environment using \begin{octavev} ... \end{octavev}. Below there is a short example.

Neil Lawrence
4th October 2010

Example

The full source code of the example is at the bottom of this page, but you may also find it in this file.

Octave

You need to use at least Octave 3.2 for the block comments to work, but then you can simply write
octave --eval source\ myexample.tex
and results will be written into files in your directory. You can achieve the same result by opening an interactive Octave session and simply type
source myexample.tex
The resulting files can be processed by LaTeX or pdfLaTeX.
pdflatex myexample
giving a result like this.

MATLAB

The absence of a source command in MATLAB makes usage less wieldy. However, a couple of tricks can be used. Under unix-like systems a symlink of the form
ln -s myexample.tex myexample.m
will allow you to treat the LaTeX code like a regular m-file. Alternatively
matlab < myexample.tex 
will cause the contents of myexample.tex to be run through the MATLAB engine.

Full Example Source Code

For the compiled version of the example see this PDF.
%{ 
% This opens a block comment for MATLAB and Octave
\documentclass{article}

\usepackage[margin=3cm]{geometry}
\usepackage{verbatim}
\usepackage{graphicx}
\usepackage{natbib}
\usepackage{times}

\newenvironment{matlab}{\comment}{\endcomment}
\newenvironment{octave}{\comment}{\endcomment}
\newenvironment{matlabv}{\verbatim}{\endverbatim}
\newenvironment{octavev}{\verbatim}{\endverbatim}

\begin{matlab}
%}
% Matlab code starts here
% Let's set up the entire document with a known random seed value and
% clear the memory and figures. You could also use this spot to set any 
% global variables you want like font names or font sizes, or add things
% to the path. You might also want to record what version of MATLAB you 
% used here.

% Clear memory and close figures
clear all
close all

% Set random seeds.
rand('seed', 1e5);
randn('seed', 1e5);

% Set font size and name.
fontName = 'times';
fontSize = 26;

% Record version of MATLAB/Octave
a = ver('octave');
if length(a) == 0
  a = ver('matlab');
end
fid = fopen('vers.tex', 'w');
fprintf(fid, [a.Name ' version ' a.Version]);
fclose(fid);

% Record computer architecture.
fid = fopen('computer.tex', 'w');
fprintf(fid, ['\\verb+' computer '+']);
fclose(fid);

% Record date of run.
fid = fopen('date.tex', 'w');
fprintf(fid, datestr(now, 'dd/mm/yyyy'));
fclose(fid);

%{
\end{matlab}


\title{MATweave: Integration of MATLAB/Octave Code Inside \LaTeX}
\author{Neil D. Lawrence\\\texttt{neil@dcs.sheffield.ac.uk}\\Sheffield Institute for Translational Neuroscience\\and Department of Computer Science\\University of Sheffield, U.K.}
\date{\input{date.tex}} % Gives date when code was run.
\begin{document}

\maketitle


\begin{abstract}
  MATweave is a set of simple tricks involving code snippets for
  incorporating MATLAB/Octave code in your \LaTeX\ documents and
  producing the result as figures. The idea is to make it as easy as
  possible for MATLAB/Octave users to make their results really
  reproducible.
\end{abstract}

\section{Introduction}

MATweave is a really simple idea for incorporating MATLAB or Octave
code into your \LaTeX\ source code. This will allow This is an example
of incorporating MATLAB or Octave code with \LaTeX\ for really
reproducible research
\citep{Buckheit:wavelab95,Schab:reproducible00}. Really reproducible
research is about ensuring that your results are usable by the rest of
the community. MATweave is inspired by Sweave \citep{Leisch:sweave02},
an approach for combining R programs with \LaTeX\ and dynamically
updating reports.

\subsection{The Tricks}

The idea behind the system is that you can use two tricks to integrate
code from MATLAB with \LaTeX.
\begin{enumerate}
\item The first trick is to make use of block comments, introduced in
  Octave 3.2 and MATLAB R14. Block comments in MATLAB/Octave are
  opened with \texttt{\%\{} and closed with \texttt{\%\}} allowing you
  to write:
\begin{verbatim} 
%{
This is a comment!                         
This line is also commented!               
%}                                         
for i = 1:10                               
  % Code here is outside the block comment.
  disp(i)                                  
end                                        
\end{verbatim}
  The trick for using these comments is that a block comment in
  MATLAB/Octave is a comment in \LaTeX\ (because it starts with a
  \texttt{\%}), but \emph{not} a block comment. This means
\begin{verbatim} 
%{
In MATLAB/Octave this would be a comment, but in \LaTeX\ it would be
compiled! So we can write valid \LaTeX, $\tau = 2\pi$, inside a MATLAB
file. Now we need to be able to write MATLAB inside a \LaTeX\ file!
%}
\end{verbatim}

\item The second trick is to include the \texttt{verbatim} package and
  use it to define a new MATLAB/Octave environment using the following
  commands.
\begin{verbatim}
\newenvironment{matlab}{\comment}{\endcomment}    
\newenvironment{octave}{\comment}{\endcomment}    
\newenvironment{matlabv}{\verbatim}{\endverbatim} 
\newenvironment{octavev}{\verbatim}{\endverbatim} 
\end{verbatim}
  This allows you to include MATLAB/Octave code that won't be read by
  LaTeX using e.g. \texttt{\textbackslash begin\{octave\}
    ... \textbackslash end\{octave\}} and code that will be shown in a
  verbatim environment using \texttt{\textbackslash begin\{octavev\}
    ... \textbackslash end\{octavev\}}. Of course you could do this
  using the standard \texttt{verbatim} environment, but by defining a
  new environment you can keep track of which bits of code are being
  run.
\end{enumerate}

\subsection{Example}
The following code is included using the \texttt{matlabv} environment
defined above. The source code for this document starts with a
MATLAB/Octave open block quote, \texttt{\%\{}. In effect, that quote
is closed at the beginning of the MATLAB/Octave code listed below so
that the code will be compiled when it is read in MATLAB/Octave.

\begin{matlabv}
%} 
% Matlab code starts here
tau = 2*pi;
x = linspace(-3, 3, 100)';
y = 1/sqrt(tau)*exp(-0.5*x.^2);
plot(x, y, 'r-');
set(gca, 'fontname', fontName, 'fontsize', fontSize);
print -depsc myGaussian.eps
% If you use pdflatex you will need a 
% system call here to convert the
% eps to a pdf. For example 
system('epstopdf myGaussian.eps');
% Matlab code ends here
%{ 
\end{matlabv}

This combination of two tricks means that the source code for this
document can be compiled in \LaTeX\ or in MATLAB/Octave.

\section{Running MATweave}

You can run the \LaTeX\ file in Octave with the command
\texttt{source}. For example, save this as \texttt{myexample.tex} and
run \texttt{source myexample.tex}. MATLAB is slightly more complicated.

The result of the code is included in Figure \ref{fig:one}.
\begin{figure}
\centerline{\includegraphics[width=0.5\textwidth]{myGaussian}}
\caption{Plot of the standard Gaussian density.}\label{fig:one}
\end{figure}

Of course in most cases you would probably want to hide the MATLAB
code that was used to generate the figure (although in early versions
of the paper you might want it there for debugging). The histogram in
Figure \ref{fig:two} has the code hidden using the
\texttt{\textbackslash begin\{matlab\} ... \textbackslash
  end\{matlab\}} environment.
\begin{matlab}
%}
a = randn(1000, 1);
b = hist(a, 30);
bar(b);
set(gca, 'fontname', fontName, 'fontsize', fontSize);
print -depsc myHistogram.eps
system('epstopdf myHistogram.eps');
%{
\end{matlab}
\begin{figure}
\centerline{\includegraphics[width=0.5\textwidth]{myHistogram}}
\caption{Histogram of 1000 samples from the standard Gaussian
  density.}\label{fig:two}
\end{figure}

These tricks should allow anyone to recreate your figures if they have
the \LaTeX\ source file.

You could also use the \texttt{listings} package to display your
MATLAB/Octave code to better effect.

You can even use the system to generate tables, or other text to be
included directly in your \LaTeX\ document,
\begin{matlabv}
%}
% Code for generating a table of random numbers.
rows = 3;
cols = 4;
numSigFigs = 3;
resultMatrix = randn(3, 4); % Would normally come from an algorithm.
fid = fopen('results.tex', 'w');
for i = 1:rows
  for j = 1:cols
    fprintf(fid, ['$' num2str(resultMatrix(i, j), numSigFigs) '$']);
    if j < cols
      fprintf(fid, ' & ');
    end
  end
  if i < rows
    fprintf(fid, '\\\\\n');
  end 
end
fclose(fid);
%{
\end{matlabv}

The results file can then be incorporated using \texttt{\textbackslash
  input\{results.tex\}} and placed as in Table \ref{table:one}.
\begin{table}
\caption{A table of random numbers generated in MATLAB/Octave.}\label{table:one}
\begin{center}
\begin{tabular}{c|c|c|c}
$A$ & $B$ & $C$ & $D$ \\
\hline
\input{results.tex}
\end{tabular}
\end{center}
\end{table}

\subsection{Tip}

I like to start my \LaTeX\ files with a series of set up commands from
MATLAB, such as loading in the right path, clearing the memory space,
setting the random seed. That means that you can get consistent
results from running the document. Have a look at the source code to
see it being done for this document.

\subsection{Note for Beamer Users}

If you use the MATweave techniques in your slides using Beamer, you
will have to use the option \texttt{[fragile]} for any frame that
contains the MATLAB environment, as without this option Beamer cannot
handle \texttt{verbatim} or \texttt{comment} environments.

You will need to use MATLAB R14 or higher or Octave 3.2 or higher. Then, to
compile this file under Unix write
\begin{verbatim}
octave --eval source\ myexample.tex
\end{verbatim}
or 
\begin{verbatim}
matlab < myexample.tex
\end{verbatim}
then
\begin{verbatim}
pdflatex myexample
\end{verbatim}

\section{Conclusions}

With a couple of simple tricks, its possible to integrate your MATLAB
and Octave code. This has the advantage of ensuring that what you say
is right beside what you do in your \LaTeX\ source file. The system is
slightly less elegant than the bespoke Sweave system for R, where
plots are automatically incorporated when produced, but it comes with
a lot of flexibility to incorporate the results you want in the final
document.

The aim of MATweave is to make it easier for researchers to produce
\emph{really} reproducible research. Please send comments or
suggestions to the author.

\subsection*{Notes}

The results in this document were generated using MATweave. Code was
run using \input{vers.tex} on the architecture
\input{computer.tex}. Experiments were run on \input{date.tex}.

\bibliographystyle{plain}
\bibliography{lawrence,other,zbooks}

\end{document}
%} 
% Don't forget to end your MATLAB comment at the end of the file!

This document last modified Friday, 24-Jan-2014 07:29:11 GMT.