55

I would like to define a command which typesets a column vector.

For one vector I can have something like:

\left(
\begin{array}{c}
a\\
b\\
\end{array}
\right)

I would like the command to produce such a vector, for either 2 or 3 arguments. \colvec{a}{b}{c} should produce the same vector as above only with one more entry where \colvec{a}{b} will produce the above vector. How should I do it? I tried to overload a command name but that's impossible.

49

Note that you have extra space around your vector. You should probably using something like (pmatrix is part of the amsmath package)

\begin{pmatrix}a\\b\end{pmatrix}

The standard LaTeX \newcommand provides a way to have a single optional argument.

\newcommand*\colvec[3][]{
    \begin{pmatrix}\ifx\relax#1\relax\else#1\\\fi#2\\#3\end{pmatrix}
}

Note that you have to use \colvec[a]{b}{c} if you want three elements or \colvec{a}{b} if you want two.

Update
As per your request in the comments, here's one that takes any number of elements based on the number passed in the first argument.

\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
}

You use it exactly as you wanted, \colvec{5}{a}{b}{c}{d}{e}.

  • Can it be extended to a vector of arbitrary length? say something like: \colvec{5}{a}{b}{c}{d}{e} will produce a column vector with 5 entries? – Dror Sep 4 '10 at 9:18
  • 16
    Yeah, you could do that. Seems like more hassle than it's worth though. How about \newcommand*\colvec[1]{\begin{pmatrix}#1\end{pmatrix} and you write \colvec{a\\b\\c\\d\\e}? – TH. Sep 4 '10 at 9:31
  • Yes!!! This is what I was looking for! Simple and easy to use. Thanks! – Dror Sep 4 '10 at 10:03
  • the smallpmatrix from mathtools may also be handy – daleif Apr 21 '12 at 16:36
  • 2
    It's psmallmatrix not smallpmatrix. Just to clear up any mistakes (run into that problem just now). – Florian Pilz Mar 9 '13 at 10:14
12

This is a more "TeX" approach. The number of rows is arbitrary. The columns are aligned right by default, but can be c or l as well:

\documentclass{article}

\makeatletter
\newcommand{\Spvek}[2][r]{%
  \gdef\@VORNE{1}
  \left(\hskip-\arraycolsep%
    \begin{array}{#1}\vekSp@lten{#2}\end{array}%
  \hskip-\arraycolsep\right)}

\def\vekSp@lten#1{\xvekSp@lten#1;vekL@stLine;}
\def\vekL@stLine{vekL@stLine}
\def\xvekSp@lten#1;{\def\temp{#1}%
  \ifx\temp\vekL@stLine
  \else
    \ifnum\@VORNE=1\gdef\@VORNE{0}
    \else\@arraycr\fi%
    #1%
    \expandafter\xvekSp@lten
  \fi}
\makeatother


\begin{document}
\[
\Spvek{1;-2} \quad \Spvek[l]{1;-2;3}\quad \Spvek[c]{1;-2;-3}\quad\Spvek{1;2;-3;4}
\]
\end{document}

Output will be:

enter image description here

6

For vectors with only two elements, or any doublet you want to express in column form, there is a standard LaTeX command in math mode $\binom{a}{b}$ or alternatively ${n \choose k}$. These look nice with tight vertically lengthened parentheses.

6

I would to supplement the solution above about \Spvek by Peter B. Yes, it is a more "TeX" approach but pure "TeX" approach is in two lines only:

\def\spvec#1{\left(\vcenter{\halign{\hfil$##$\hfil\cr \spvecA#1;;}}\right)}
\def\spvecA#1;{\if;#1;\else #1\cr \expandafter \spvecA \fi}

$\spvec{1;2;3} + \spvec{1;2;-3;4} + \spvec{1;2}$

This solution will be work in LaTeX too because only TeX primitives are used here.

  • Does anyone care to elaborate on this code? I like it and want to modify it, but anything I attempt will fail. What is going on here $##$ ? – fborchers Apr 4 at 20:28
5

Since you specified only wanting two or three arguments (not an arbitrary number of them, as others here have given solutions for), you can use the xparse package to define commands with optional braced arguments. Something like (untested)

\DeclareDocumentCommand \colvec {mmg} {%
  \IfNoValueTF #3 {%
    \twocolvec {#1}{#2}
  }{%
    \threecolvec {#1}{#2}{#3}
  }%
}

Where the two intermediate functions (defined as appropriate) typeset the array as appropriate.

  • Does this means that I have to define separately the function \twocolvec and \threecolvec? – Dror Sep 4 '10 at 9:17
4

Here is my KISS-like solution (which is just a wrapper for pmatrix from the amsmath package, inspired by Garrys answer):

\newcommand{\myvec}[1]{\ensuremath{\begin{pmatrix}#1\end{pmatrix}}}

Usage:

\myvec{x\\y\\z}

The good thing is, you don't need to specify a number of elements or anything. You can just add more elements with \\. It also looks tidier in the tex-file then using the pmatrix environment itself.

You can also use it for row-vectors:

\myvec{a&b&c}

(For completion: Matrices work aswell, obviously: \myvec{a&b \\ c&d})

2

Years later and not very tex-y, but for some reason I really wanted to use commas as separators and ended up putting together the following:

\usepackage{iftex}
\RequireLuaTeX
\usepackage{amsmath}
\usepackage{luacode}
\begin{luacode*}
mycolvec = { }
function mycolvec.replace(input)
  tex.sprint(
    "\\ensuremath{\\begin{pmatrix}"
      .. string.gsub(input, ",", " \\\\ ")
      .. "\\end{pmatrix}}")
end
\end{luacode*}
\def\colvec#1{\directlua{mycolvec.replace("#1")}}

Which, when added to the header, allows you to write out column vectors like this:

\colvec{1, 2, 3}
\colvec{8,6,7,5,3,0,9}

This requires that you compile your tex with lualatex instead of xetex or pdftex, but that shouldn't affect the rest of your document.

The seperator can be changed to any arbitrary character by changing the "," on the .. string.gsub(... line.

EDIT: This method breaks when entering tokens (i.e. \colvec{1 \cdot 2, 2 \cdot 3}), for the reasons described here. As such I'll recommend egreg's answer on a related question, which provides the functionality I claim here without the same problem.

  • Welcome to TeX.Se. – CampanIgnis Sep 6 '18 at 1:29
1

I can offer a macro \colvec within whose argument you can supply an arbitrary amount of undelimited arguments whereof each one will be taken for a component of the one-column-vector:

\documentclass{article}
\usepackage{amsmath}

\makeatletter
%%=============================================================================
%% Paraphernalia:
%%    \UD@firstoftwo, \UD@secondoftwo, \UD@Exchange, \UD@PassFirstToSecond,
%%    \UD@CheckWhetherNull, \UD@CheckWhetherBlank, \UD@ExtractFirstArg
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@Exchange[2]{#2#1}%
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral0\expandafter\UD@secondoftwo\string{\expandafter
  \UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
  \UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
  \UD@secondoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument is blank (empty or only spaces):
%%.............................................................................
%% -- Take advantage of the fact that TeX discards space tokens when
%%    "fetching" _un_delimited arguments: --
%% \UD@CheckWhetherBlank{<Argument which is to be checked>}%
%%                      {<Tokens to be delivered in case that
%%                        argument which is to be checked is blank>}%
%%                      {<Tokens to be delivered in case that argument
%%                        which is to be checked is not blank}%
\newcommand\UD@CheckWhetherBlank[1]{%
  \romannumeral\expandafter\expandafter\expandafter\UD@secondoftwo
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo#1{}.}%
}%
%%-----------------------------------------------------------------------------
%% Extract first inner undelimited argument:
%%
%%   \UD@ExtractFirstArg{ABCDE} yields  {A}
%%
%%   \UD@ExtractFirstArg{{AB}CDE} yields  {AB}
%%.............................................................................
\newcommand\UD@RemoveTillUD@SelDOm{}%
\long\def\UD@RemoveTillUD@SelDOm#1#2\UD@SelDOm{{#1}}%
\newcommand\UD@ExtractFirstArg[1]{%
  \romannumeral0%
  \UD@ExtractFirstArgLoop{#1\UD@SelDOm}%
}%
\newcommand\UD@ExtractFirstArgLoop[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo{}#1}%
  { #1}%
  {\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillUD@SelDOm#1}}%
}%
%%=============================================================================
%% Process an arbitrary amount of undelimited arguments as 
%% a one-column-vector:
%%
%% The macro \colvec processes an undelimited argument which in
%% turn consists of an arbitrary amount of undelimited arguments.
%% Each of these undelimited arguments is taken for a row/component
%% of a one-column-vector.
%%
%% You can have spaces between undelimited arguments as (La)TeX does discard
%% spaces that precede undelimited arguments.
%%
%% You can omit braces with undelimited arguments that consist of a 
%% single token. 
%%-----------------------------------------------------------------------------
\newcommand\colvec[1]{%
  \colvecloop{#1}{}%
}%
\newcommand\colvecloop[2]{%
  \UD@CheckWhetherBlank{#1}{%
     \begin{pmatrix}#2\end{pmatrix}%
  }{%
      \expandafter\expandafter\expandafter
      \expandafter\expandafter\expandafter
      \expandafter\UD@PassFirstToSecond
      \expandafter\expandafter\expandafter
      \expandafter\expandafter\expandafter
      \expandafter{\expandafter\expandafter
      \expandafter\UD@Exchange\UD@ExtractFirstArg{#1}{#2}\\}%
      {\expandafter\colvecloop\expandafter{\UD@firstoftwo{}#1}}%
  }%
}%
\makeatother

\begin{document}

\verb|$\colvec{{a}{b}{c}{d}}$| yields:
$\colvec{{a}{b}{c}{d}}$

\verb|$\colvec{ {a} {b} {c} {d} {e} }$| yields:
$\colvec{ {a} {b} {c} {d} {e} }$

\verb|$\colvec{ {a} {b} {c} {d} {e}fg }$| yields:
$\colvec{ {a} {b} {c} {d} {e}fg }$

\end{document}

enter image description here

1

This post presents another possible approach. It improves on this earlier post above. The idea is to use a similar plain TeX mechanism, but wrap it up in amsmaths high level pmatrix environment. This helps with fractions for example. The interface with parentheses is the same as used by PSTricks. Here is a working example:

\documentclass[margin=2pt]{standalone}
\usepackage{amsmath}

\makeatletter
\def\vector(#1){%
\mathchoice%
    {\pmatrix@i{\vector@i#1,,}}%
    {\pmatrix@ii{\vector@i#1,,}}%
    {}% scriptstyle too small,
    {}% ss style too small.
}
\def\vector@i#1,{\if,#1,\else{#1}\cr\expandafter\vector@i\fi}
\def\pmatrix@i#1{\begin{pmatrix}#1\end{pmatrix}}
\def\pmatrix@ii#1{\left(\!\begin{smallmatrix}#1\end{smallmatrix}\!\right)}
\makeatother

\begin{document}
$\displaystyle\vector(-3,+4,5)$ and $\vector(-3,+4,5)$
\end{document}

When typesetting vectors with lots of fractions it is advisable to increase vertical spacing with:

\renewcommand{\arraystretch}{1.1}% stretch value 1.1 for example

example of the command vector in use

Because the macros make use of the @i notation the code will have to be placed inside at \makeatletter - \makeatother wrapping before document begins.

See here for a similar solution for row vectors.

  • @PhelypeOleinik: done. – fborchers Apr 5 at 18:10

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.