6

I'm currently using the algorithm package for typesetting Matlab source code in my document. However, the way keywords are typeset doesn't match the Matlab syntax. For instance, \EndFor is typeset as "end for" instead of "end", which is the terminating keyword of a for loop in Matlab. How can I fix this?

I have the following code:

\usepackage{algorithm} 
\usepackage{algpseudocode}

\floatname{algorithm}
\begin{algorithm}[H]
 \begin{algorithmic}\State
alpha=0;  rho=0;\State
\For {$r=1:p$}\State
    rho=rho+1/(r\^{}2);\State
    alpha=alpha+1/(r\^{}4);
\EndFor \State
\end{algorithmic}
 \end{algorithm}
4
  • You have way too many \State's. Leave the For in End For. It makes it much much clearer for the reader what exactly the End refers to. – daleif Oct 18 '13 at 8:59
  • But it's not a Pesudocode, and it wouldn't be right anymore (it's a Matlab Code) – little_miss_sunshine Oct 18 '13 at 9:13
  • 2
    Why are you formatting Matlab code as pseudo code then? Why don't you use say listings – daleif Oct 18 '13 at 9:19
  • Consider using the matlab-prettifier package; see this answer of mine. – jub0bs Feb 10 '14 at 13:19
10

Short answer: don't use algorithm for typesetting source code. Use either the listings or minted package instead, or (edit) the matlab-prettifier package; see below.


Detailed answer:

You can change the way algpseudocode's keywords (such as for, while, etc.) are typeset by redefining them using algorithm's \algdef command. The following modification answers your specific question about for and end for.

enter image description here

\documentclass{article}

\usepackage{algorithm} 
\usepackage{algpseudocode}
\algdef{SE}[FOR]{For}{EndFor}[1]{\algorithmicfor\ #1}{\algorithmicend}%

\floatname{algorithm}

\begin{document}
\begin{algorithm}[H]
 \begin{algorithmic}\State
alpha=0;  rho=0;\State
\For {$r=1:p$}\State
    rho=rho+1/(r\^{}2);\State
    alpha=alpha+1/(r\^{}4);
\EndFor \State
\end{algorithmic}
 \end{algorithm}
\end{document}

However, while reconfiguring algorithm & friends to comply with some language's syntax may be possible to an extent (and at the cost of great effort and tedium), those packages are really not intended for anything other than pseudocode (i.e. "algorithms explained in plain English").

Other packages such as listings or minted are better suited for typesetting source code (i.e., in your case, the contents of an m-file). Those packages come with predefined settings for numerous programming languages (C, Python, Matlab, etc.), settings which can be customised. Additionally, both of those packages allow for line numbering and syntax highlighting.

Edit: I've recently written a package called matlab-prettifier for typesetting Matlab code nicely. It's built on top of the listings package, but I've defined a style that mimicks minted output, with overall better syntax-highlighting capabilities; note, in particular, that, in my example, the end keyword is highlighted differently, depending on the context in which it is used.

enter image description here

\documentclass{article}

\usepackage[T1]{fontenc}
\usepackage[framed,numbered]{matlab-prettifier}

\usepackage{filecontents} % to generate an external file from this tex file
\begin{filecontents*}{mysourcefile.m}
function I = Simprule(f,a,b,m)
% Applies the composite Simpson's rule to function f
% (using 2m+1 points) between limits a and b.
% INPUTS:
%       - f  inline function
%       - a  lower limit of the integral
%       - b  upper limit of the integral
%       - m  positive integer    
%
% OUTPUT:
%       - I  approximate value of the integral

% --- Sanity checks ---
  % 1 - Check that a<=b.
  if a>b
    error('b must be smaller than a.');
  end
  % 2 - Check that m is a positive integer.
  if (floor(m)~=m) || (m<=0) 
    error('m must be a positive integer.');
  end

% --- Create subintervals of [a,b] ---
  x = linspace(a,b,2*m+1);
  h = (b-a)/(2*m);

% --- Apply the composite Simpson's rule ---
    int = (h/3)*(   f(x(1))...                       
                    + 2 * sum( f(x(3:2:end-2)) )...
                    + 4 * sum( f(x(2:2:end-1)) )...
                    + f(x(end))  );

\end{filecontents*}

\begin{document}
\lstinputlisting[style=Matlab-Pyglike,basicstyle=\mlttfamily]{mysourcefile.m}
\end{document}

I've generated the m-file fromn within my tex file, just for completeness of my example. In practice, you would have your m-files sitting somewhere on your machine and you would just link to them inside your input file.


Finallly, a comment that is only peripheral to the main topic here (TeX): Matlab loops are slow! For improved performance, you should, whenever possible, avoid using Matlab (for or while) loops and use, instead, a combination of the colon operator and vectorised commands (such as sum). Here is the alternative I would recommend:

enter image description here

The reduction in computation time of my version over yours becomes significant as p increases.

4
  • I tried the listings before, but I can't install the usepackage. I always get the following error message: ! Package caption Error: For a successful cooperation we need at least version `2004/02/13 v1.2' of package listings, – little_miss_sunshine Oct 18 '13 at 10:08
  • 2
    Have you tried updating your TeX distribution? – jub0bs Oct 18 '13 at 10:10
  • 2
    @little_miss_sunshine What Jubobs says. If a package demands a 2004 version of another package and you don't have it, it's time to re-install ;) – yo' Oct 18 '13 at 10:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.