[Tex/LaTex] How to get proper Matlab syntax when typesetting Matlab source code using the algorithm package

algorithmsMATLABsourcecode

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}

Best Answer

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.