Mess up Matlab codes and outputs in LaTeX

You do not want to mess up, right? When writing a LaTeX document, you may once in a while want to include some Matlab codes and/or outputs (preferably typeset using typewriter font if you have the same taste as me) during the course of your writing. What I used to do was to copy and paste the Matlab codes into my LaTeX file, execute the codes in Matlab, then do another copy and paste to place the results in my LaTeX file, and finally decorate them in a verbatim block or something like that. Guess what, Matlab provides a command, called publish, that helps you do all these in a simpler way.

In a nutshell, the way to use publish is to first type in the texts (as your usually LaTeX editing), including Matlab codes, in a single .m file. Let’s say the file name is example.m. Then, in Matlab, you issue the command

publish('example.m', struct('format','latex','outputDir','ltx-src'));

It means that you want Matlab to process example.m and output a LaTeX file example.tex (that you can compile to get pdf) in the sub-directory ltx-src. This is it. Instead of writing example.tex, you write a file example.m.

So, how should I write example.m? It is best to give an example. See the following:

% <latex>
% The eigenvalues of a circulant matrix can be
% obtained by performing FFT on the first column
% of the matrix. First, let us construct a
% $5\times5$ circulant matrix \verb|C| whose first
% column \verb|c| is generated with random input:
% </latex>

c = rand(5,1);
% sad that Matlab does not provide a circulant()
% command...
C = toeplitz(c, c([1 end:-1:2]))

% <latex>
% The eigenvalues of \verb|C| are nothing but
% </latex>

lambda = fft(c)

% <latex>
% Check it out! The output is the same as using
% the \verb|eig| command:
% </latex>


% Fun, isn't it?

It is nothing but a script file that Matlab can execute, right? The trick part is that all the texts and LaTeX markups are buried in comment blocks. How the Matlab command publish makes a LaTeX output is that whenever it meets a whole block of comments starting with ‘%%‘, it strips the comment signs and decorates the whole block using the pair \begin{par} and \end{par}. On the other hand, whenever it meets a block of codes that does not start with ‘%%‘, Matlab knows that they are executable commands. Matlab uses \begin{verbatim} and \end{verbatim} to typeset these command texts, and automatically add the Matlab outputs of the commands, which are also decorated by the \begin{verbatim} and \end{verbatim} pair, in the LaTeX file. Something I am not satisfied is that Matlab does not recognize LaTeX commands such as \verb||. I have to put <latex></latex> so that Matlab can do a verbatim copy of \verb||, instead of expand the text \verb|| in some weird way, in the output LaTeX file.

It is time to try the above example yourself. Have fun.


9 Responses to “Mess up Matlab codes and outputs in LaTeX”

  1. 1 Mankoff April 15, 2011 at 6:49 pm

    You are right you should never duplicate your code! Just use ‘minted’ and include your source, syntax-highlighted, from the original file. What I’ve been doing is the following in my MATLAB code:

    % At the top of the .m file:
    delete ‘ex.m.out’, diary ‘ex.m.out’
    % now all output is recorded

    % At the bottom of the .m file.
    diary off
    % End of .m

    I usually have more to say than what fits in some comments, and want the full power of LaTeX, so I have an external LaTeX document. In there, I use the “minted” package to include the source (ex.m) and the output (ex.m.out).

    Your solution is nicer because the output is embedded in the source in the correct location.

    I’d like to combine the solutions and make it auto-magic, and wonder if you have a hint. What I’ve done is removed the ‘diary’ commands, and added the ‘publish’ command at the bottom of my script. In my LaTeX document I would then use \input{ex.m.tex}. However, since the publish command is in my script, it calls itself recursively.

    Presumably there is a way to tell if my code is running because I ran it manually, or because publish() is running it. I just need to wrap my publish() call in an IF block that detects this. Any ideas?

    • 2 Jie April 15, 2011 at 11:46 pm

      Thanks for sharing the minted package. I used to use the listings package to include C or MATLAB source codes in latex. Guess minted more or less does the same thing as listings but better supports syntax highlighting.

      I do not quite follow why you want to put something like publish(‘ex.m’) in your ex.m file. If you want to have LaTeX source codes in ex.m, then do what is said in my original post; if you do not want LaTeX codes in ex.m, then follow the minted-package way. Either method looks automatic enough to me. So what do you mean by combining the two methods?

  2. 3 mankoff April 16, 2011 at 10:10 am

    Right now my ‘diary’ commands are in the MATLAB source, so I have 3 files: LaTeX source, MATLAB source, and MATLAB output (from dairy). The MATLAB output file is automatically generated and kept up-to-date with the source (each time I modify the source, I hit CTRL+C+S (emacs)) and the source runs. The LaTeX is compiled with “latexmk”, which is watching all the other files, and it automagically recompiles. Result: I change my MATLAB code, run it, and the LaTeX doc is kept up-to-date.

    Since ‘publish’ cannot be inside my MATLAB code (because it causes infinite recursion), I need to manually run ‘publish’. I’m trying to skip this step. If I update my MATLAB code, but forget to run ‘publish’, then the LaTeX document is not in sync.

    • 4 mankoff April 16, 2011 at 11:37 am

      I think I’ve figured out some work-arounds. For example, I could add shell code to my LaTeX where I include the output. If the MATLAB ‘publish’-generated LaTeX file is older than the MATLAB source file, then batch-run MATLAB on the source (ex: matlab -r ‘publish();quit’). This is a bit hack-ish, and I’d prefer a more elegant solution, but it will work and should help maintain document/code consistency.

      • 5 Jie April 16, 2011 at 2:02 pm

        Let me imagine what you are doing. You have a MATLAB script ex.m as in the following:

        diary on
        diary off

        And you have a LaTeX souce file foo.tex as in the following:

        This is to show how to generate a random matrix:

        So every time you change ex.m, you hit C-c C-s in emacs to run the new ex.m and get the new output ex.m.out. I do not know how you make latexmk automatically run without your manually typing ‘latexmk’ in the command line, but let’s just assume that it works. Then that’s. Why do you want to use the publish() command? To get rid of the diary() commands in ex.m so that your LaTeX document does not show them? In that case, you can write a small script to get rid of the lines with ‘diary’ in foo.tex before you compile foo.tex.

  3. 6 mankoff April 16, 2011 at 5:28 pm

    I was interested in ‘publish’ over ‘diary’ because ‘publish’ supports latex in the comments, and also embeds the output in the code. With ‘diary’, the output must be separate. I can get around the latex-in-comments problem because I found out that minted supports latex in comments. It would be nice to show the output embedded in the code, not after the code, but it is not that important.

    • 7 Jie April 16, 2011 at 11:31 pm

      I see what you mean. Why not just run publish(‘ex.m’,’latex’) every time when you change ex.m. You can open a MATLAB shell in emacs and execute the publish command. You do not need to put publish() in ex.m.

      BTW, in MATLAB you can turn on ‘echo’ so every line in ex.m will be displayed when you are executing ex.m. Then your diary file will show not only the outputs, but also the source code. Thus in LaTeX you just need to ask minted to format the output file, but not the source code file. Well I did not try this, but I guess minted can not distinguish between MATLAB code and MATLAB output, so it may not be smart enough to do things like ‘format MATLAB code in black and format output in gray’.

  1. 1 Mess up Matlab codes and outputs in LaTeX « LaTeX and Miscellaneous | 零度季节 Trackback on April 18, 2011 at 9:06 pm

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Blog Stats

  • 244,135 hits

%d bloggers like this: