Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

In the question typesetting a column vector, a very nice solution was given for typesetting a column vector with an arbitrary number of rows. I am attempting to modify the code to produce row vectors instead of column vectors. I made the "obvious" change, i.e., substituting the & for the \\ as indicated by the snippet below:

\newcount\colveccount
\newcommand*\colvec[1]{
        \global\colveccount#1
        \begin{pmatrix}
        \colvecnext
}
\def\colvecnext#1{
        #1
        \global\advance\colveccount-1
        \ifnum\colveccount>0
                &
                \expandafter\colvecnext
        \else
                \end{pmatrix}
        \fi
}
My modification however fails to compile and the errors, of course, are not very helpful. So my question is, How can I modify the \colvec and \colvecnext macros to produce row vectors?

share|improve this question
add comment

3 Answers 3

up vote 19 down vote accepted

You have to collect the row beforehand, as doing it inside an array environment is quite difficult, as TeX ends a cell as soon as it sees an &. I prefer to do in with a token register and the \count255 scratch counter.

We collect two arguments: the first is the number of entries, the second the first entry, in order to initialize the token register with it. We set the counter to the number of requested element (since we have already collected one, we step it down immediately).

Then we start the recursion; the macro \rowvectnexta examines the value of the counter; if it's still greater than 0, it calls \rowvecnextb that gathers another argument, stores it into the token register (adding an &) and steps down the counter; otherwise it builds the pmatrix by releasing the contents of the register.

\newtoks\rowvectoks
\newcommand{\rowvec}[2]{%
  \rowvectoks={#2}\count255=#1\relax
  \advance\count255 by -1
  \rowvecnexta}
\newcommand{\rowvecnexta}{%
  \ifnum\count255>0
    \expandafter\rowvecnextb
  \else
    \begin{pmatrix}\the\rowvectoks\end{pmatrix}
  \fi}
\newcommand\rowvecnextb[1]{%
    \rowvectoks=\expandafter{\the\rowvectoks&#1}%
    \advance\count255 by -1
    \rowvecnexta}

It shouldn't be a big limitation the fact that you need at least one element:

\rowvec{1}{a}
\rowvec{2}{a}{b}
\rowvec{3}{a}{b}{c}

Notice: \usepackage{amsmath} is required. So a minimal example might be the following.

\documentclass{article}
\usepackage{amsmath}

\newtoks\rowvectoks
\newcommand{\rowvec}[2]{%
  \rowvectoks={#2}\count255=#1\relax
  \advance\count255 by -1
  \rowvecnexta}
\newcommand{\rowvecnexta}{%
  \ifnum\count255>0
    \expandafter\rowvecnextb
  \else
    \begin{pmatrix}\the\rowvectoks\end{pmatrix}
  \fi}
\newcommand\rowvecnextb[1]{%
    \rowvectoks=\expandafter{\the\rowvectoks&#1}%
    \advance\count255 by -1
    \rowvecnexta}

\begin{document}

$\rowvec{1}{a}$
$\rowvec{2}{a}{b}$
$\rowvec{3}{a}{b}{c}$

\end{document}

A completely different solution that can be generalized to column vectors uses xparse and LaTeX3.

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\Rowvec}{ O{,} m }
 {
  \vector_main:nnnn { p } { & } { #1 } { #2 }
 }
\NewDocumentCommand{\Colvec}{ O{,} m }
 {
  \vector_main:nnnn { p } { \\ } { #1 } { #2 }
 }

\seq_new:N \l__vector_arg_seq
\cs_new_protected:Npn \vector_main:nnnn #1 #2 #3 #4
 {
  \seq_set_split:Nnn \l__vector_arg_seq { #3 } { #4 }
  \begin{#1matrix}
  \seq_use:Nnnn \l__vector_arg_seq { #2 } { #2 } { #2 }
  \end{#1matrix}
 }
\ExplSyntaxOff

\begin{document}

$\Rowvec{a}\Rowvec{a,b}\Rowvec[;]{a;b;c}$

$\Colvec{a}\Colvec{a,b}\Colvec[;]{a;b;c}$

\end{document}

The optional argument is the delimiter to be used to separate entries in the list given as argument.

It's sufficient to change { p } into { b } in the two main definitions to get brackets instead of parentheses.

enter image description here

Note: this requires expl3 dated September 2012 or later.

share|improve this answer
    
Thank you! Your solution works beautifully. Considering the necessary steps, my modification attempt was naively futile. –  3Sphere Dec 21 '11 at 22:05
3  
I'll expand the answer: the TV was broadcasting Beethoven's Ninth from the new theater in Florence, so my main attention was to it. :) –  egreg Dec 21 '11 at 22:15
    
I suggest adding this to mathtools package. –  azetina Nov 12 '13 at 19:55
add comment

I would like to suggest a dirty solution, which I use:

\newcommand*{\rowvec}[1]{\left( #1\right)}

The advantage is that its usage is simple: rowvec{a,b,c,d,e}. I can easily imagine that it is not robust... For me it works.

share|improve this answer
add comment

This is an old question... but as it surfaced again let me point out that one can do these things without token register or macro storage or count registers.

\documentclass{article}
\usepackage{amsmath}
\makeatletter
% USAGE \Matrix { a,..,z; A,.., Z ; ... ; aA, ..., zZ}
% NO semi-colon for the last row.
\newcommand{\Matrix}[1]
    {\begin{pmatrix}
      \Matrix@r #1;\@bye;\Matrix@r
     \end{pmatrix}}

\def\Matrix@r #1;{\@bye #1\Matrix@z\@bye\Matrix@s #1,\@bye, }%
\def\Matrix@s #1,{#1\Matrix@t }%
\def\Matrix@t #1,{\@bye #1\Matrix@y\@bye\@firstofone {&#1}\Matrix@t}%
\def\Matrix@y #1\Matrix@t{\\ \Matrix@r }%
\def\Matrix@z #1\Matrix@r {}
\def\@bye  #1\@bye   {}% (the idea of \@bye is from xint code)

\makeatother

\begin{document}\thispagestyle{empty}


\[ \Matrix { a, b  , c , d ; e ,f , 3, 5; 8, -1, x, y }\]

\[ \Matrix { abc , \mathrm{XYZ}; 7, 913; \alpha, \beta }\] 

\end{document}

matrices

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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