61

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.

Dror
  • 22,613

9 Answers9

60

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

TH.
  • 62,639
  • 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 04 '10 at 09:18
  • 19
    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 04 '10 at 09:31
  • Yes!!! This is what I was looking for! Simple and easy to use. Thanks! – Dror Sep 04 '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 09 '13 at 10:14
  • How do we get a rectangular, not parentheses, vector? – user3180 Jun 28 '20 at 02:34
13

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

percusse
  • 157,807
9

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.

wipet
  • 74,238
7

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

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

n4pK
  • 305
  • 2
  • 8
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 04 '10 at 09:17
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.

2

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

Ulrich Diez
  • 28,770
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.

fborchers
  • 465
  • 2
  • 13