62

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.

2

9 Answers 9

62

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

6
  • 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
    Commented Sep 4, 2010 at 9: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.
    Commented Sep 4, 2010 at 9:31
  • Yes!!! This is what I was looking for! Simple and easy to use. Thanks!
    – Dror
    Commented Sep 4, 2010 at 10:03
  • the smallpmatrix from mathtools may also be handy
    – daleif
    Commented Apr 21, 2012 at 16:36
  • 2
    It's psmallmatrix not smallpmatrix. Just to clear up any mistakes (run into that problem just now). Commented Mar 9, 2013 at 10:14
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

5
  • @percusse How did you crop the picture? I tried, but couldn't find a way. Thank you for cropping. Commented Apr 21, 2012 at 20:39
  • I did it manually using Paint :)
    – percusse
    Commented Apr 21, 2012 at 20:44
  • @PeterBreitfeld: See How do you crop an attached PDF?
    – Werner
    Commented Apr 21, 2012 at 22:26
  • +1 Just what I was looking for. But what does Spvek mean?
    – Oriol
    Commented Mar 16, 2013 at 20:17
  • Turns out to be abb. for spaltenvektor, in german pbreitfeld.de/schule2e.sty
    – osolmaz
    Commented Nov 6, 2013 at 20:13
8

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.

2
  • 1
    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 $##$ ?
    – user154857
    Commented Apr 4, 2019 at 20:28
  • @fborchers Late reply, but in case someone come across this to learn TeX primitive commands read the TeXbook. See also package writing - Where do I start LaTeX programming? - TeX - LaTeX Stack Exchange -- (for one written by wipet, see TeX in a nutshell) Generally it takes a lot of effort to learn it however.
    – user202729
    Commented Feb 8, 2023 at 17:09
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})

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.

1
  • Does this means that I have to define separately the function \twocolvec and \threecolvec?
    – Dror
    Commented Sep 4, 2010 at 9:17
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

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.

1
  • Welcome to TeX.Se. Commented Sep 6, 2018 at 1:29
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.

1
  • @PhelypeOleinik: done.
    – user154857
    Commented Apr 5, 2019 at 18:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .