55

I am trying to write a few systems of equations, and I want the terms to be nicely spaced as below

2x  +   y  +  3z  =  10   \\ 
 x  +   y  +   z  =   6   \\
 x  +  3y  +  2z  =  13 

Now, using some very ugly code, I was able to produce the results above.

\documentclass[10pt,a4paper]{article}
\usepackage{mathtools}
\usepackage{amsmath}

\begin{document}

\begin{align*}
\begin{bmatrix}
\begin{tabular}{r c r c r c r }
$2x$ & $+$ & $ y$ & $+$ & $3z$ & $=$ & $10$ \\
$ x$ & $+$ & $ y$ & $+$ & $ z$ & $=$ & $ 6$ \\
$ x$ & $+$ & $3y$ & $+$ & $2z$ & $=$ & $13$
\end{tabular}
\end{bmatrix}
\end{align*}

\section{Another system of equations, now without the brackets}

\begin{table}[!htpb]
\centering
\begin{tabular}{r c r c r c r }
$2x$ & $+$ & $ y$ & $+$ & $3z$ & $=$ & $10$ \\
$ x$ & $+$ & $ y$ & $+$ & $ z$ & $=$ & $ 6$ \\
$ x$ & $+$ & $3y$ & $+$ & $2z$ & $=$ & $13$
\end{tabular}
\end{table}

\end{document}    

I would very much want a more automatic way to do this, and a simple method for controlling the spacing between elements. I have looked at earlier posts like

Multicol layout for systems of (linear) equations

It seems that I am looking for a simple version of this one. I have no need to use side-by-side equations, nor have numbers in front of them.

Using ideas from the post above, I guess the result is done by redefining commands such as - and + inside of the table? I tried to do something like this, but the code looked rather complex =(

To sum it up: Is there a way to define a simple System of Equations enviroment, with proper alignment and a optional command for defining the spacing?

0

8 Answers 8

45

You can try the package systeme. Its documentation is in French, but there are many examples to play with.

Your example would be input as

\systeme{
2x  +   y  +  3z  =  10,
 x  +   y  +   z  =   6,
 x  +  3y  +  2z  =  13}

To get right alignment in the column of right hand sides, one has to manually modify the package code:

\makeatletter
\def\SYS@makesyspreamble@i#1{%
  \ifnum#1<\SYS@preamblenum
    \SYS@addtotok\SYS@systempreamble{\hfil$##$&\hfil$##$&}% 
    \expandafter\SYS@makesyspreamble@i\expandafter{\number\numexpr#1+\@ne\expandafter}%
  \else
    \SYS@addtotok\SYS@systempreamble{\hfil$##$&$##$&\hfil$##$\null}% 
    \ifSYS@extracol
      \SYS@addtotok\SYS@systempreamble{&\SYS@extracolstart##\SYS@extracolend\hfil\null}% 
    \fi
    \SYS@addtotok\SYS@systempreamble{\cr\SYS@strutup}% 
  \fi
}
\makeatother

The patch is simply changing $##$\hfil into \hfil$##$ but, since this involves # it's not possible to use etoolbox's \patchcmd.

One can modify the distance between the lines by saying something like

\syslineskipcoeff{1.2}

and act on the column spacing with the parameter \tabskip; so, for example,

\[
\syslineskipcoeff{1.2}\setlength{\tabskip}{3pt}
\systeme{
2x  +   y  +  3z  =  10,
 x  +   y  +   z  =   6,
 x  +  3y  +  2z  =  13}
\]

will spread out the equations both vertically and horizontally. The \syslineskipcoeff can also be issued globally, in the preamble of the document; not the horizontal spacing, though, as \tabskip influences all TeX tables, tabular environments included.

13
  • Are there options in this package to (i) get rid of the (presumably unwanted) curly brace on the left-hand side and (ii) also align the "6" correctly in row 2?
    – Mico
    Nov 17, 2011 at 16:28
  • \sysdelim.. before the system will avoid the brace; I guess that this declaration remains valid until countermanded, but it will respect grouping. For right alignment of the right hand side I think that the code must be modified.
    – egreg
    Nov 17, 2011 at 16:37
  • This seems as almost the perfect solution. Are there any way to add a default spacing length, and perhaps a optional length argument? The optional length argument should simply increase the size between all elements horizontally. Perhaps I am asking too much here. Nov 17, 2011 at 17:23
  • @N3buchadnezzar See edit
    – egreg
    Nov 18, 2011 at 0:41
  • 2
    @DamienWalters I don't think it's possible.
    – egreg
    Mar 3, 2012 at 23:44
46

You could use the alignat* environment of amsmath, it's for multi-line equations with alignment at several places. To correct spacing of operators, you could write them as {}+{}. For example:

\documentclass{article}
\usepackage{amsmath}
\begin{document}
\begin{alignat*}{4}
2x & {}+{} &  y & {}+{} & 3z & {}={} & 10 \\
 x & {}+{} &  y & {}+{} &  z & {}={} &  6 \\
 x & {}+{} & 3y & {}+{} & 2z & {}={} & 13
\end{alignat*}
\end{document}

enter image description here

5
  • 3
    Is there an automatic way to find the number of equations? Then one could make this into an own enviroment by redefinding + as & {}+{} & and so on. The one could fairly easy turn this into a more automatic solution =) Nov 17, 2011 at 19:57
  • Not that one can ever keep track of such things without consulting the manual, so I might be mistaken, but isn't the {} at the beginning of each operator unnecessary, since left-aligned columns implicitly begin with a {}?
    – LSpice
    Jan 15 at 19:08
  • @LSpice To see it, remove all the {} and then compare with a regular equation x+3y+2z=13. With all the {}, the spacing looks the same. Without it, it's very tight.
    – Stefan Kottwitz
    Jan 15 at 20:20
  • Re, I agree that removing all {}s does not work. In my comment, I should have been more explicit that I meant only the {} before, not after. Having just run it, I think that, inside \begin{alignat*}4…\end{alignat*}, x &+{}& 3y &+{}& 2z &={}& 13 and x &{}+{}& 3y &{}+{}& 2z &{}={}& 13 space identically (and, as you say, differently from x &+& 3y &+& 2z &=& 13).
    – LSpice
    Jan 15 at 20:28
  • 1
    @LSpice Yes, looks like +{} is sufficient. Then in case of right aligned columns, not any more. {}+{} may be a bit safer in general and looks symmetric. :-) In any case, thank you for your observation!
    – Stefan Kottwitz
    Jan 15 at 21:21
18

spalign provides an elementary interface for setting systems of equations:

enter image description here

\documentclass{article}

\usepackage{spalign}

\begin{document}

\[
  \spalignsys{
    2x +  y + 3z = 10 ;
     x +  y +  z =  6 ;
     x + 3y + 2z = 13
  }
\]

\spalignsysdelims{.}{\}}% {<left>}{<right>}
\[
  \spalignsys{
    2x \+ \. - 3z =  1 ;
    \. \+ 4y +  z = -4
  }
\]

\end{document}
0
16

Background:

This is inspired by an earlier solution provided by Gonzalo Medina (now deleted), which had an issue if some of the entries were negative.

What I really liked about that solution was its attempt to only require the specification of the basic information. In that solution, + signs were assumed, but adapting that to include - signs it would look like:

\begin{MySystem}{2}{R}
   2x &   y &  z & 10 \\
    x &   y & -z &  6 \\
   -x & -3y & 2z & 13 \\
\end{MySystem}

Note that no plus signs need be entered, just the raw matrix style data.

Solution:

Here, I follow a similar approach but use the collcell package to analyze the data and handle the case of a leading - or + sign and properly align them. Although, I am not really sure why one would want a left aligned system of equations, since Gonzalo had provided such an environment, I have included that here as well. The parameters to the MySystem environment here are:

\begin{MySystem}[<size>]{<n>}{<align>} ... \end{MySystem}
  • <size> is an optional parameter specifying the amount of space to typeset the terms in (necessitated as this solution separates the +/- sign and aligns them). This defaults I used provides a good value for the basic system of equations.
  • <n> the number of variables (using solution from Defining repeated tabular/array columns using a computed value to specify the number).
  • <align>, the alignment to use: either R or L. This corresponds to the new column types defined here.

enter image description here

Further Enhancements:

  • DONE: I attempted to automate this to accept the actual number of variables (as opposed to one less) since that would be a more natural interface, but ran into trouble using a counter's value to specify the number of repeated columns to use. This issue has been posted at: Defining repeated tabular/array columns using a computed value to specify the number.

  • I have used the xstring package to handle the string processing. There are probably ways to achieve the same functionality without requiring this extra package.

  • Currently any empty cells are properly processed in that the + sign is suppressed via the \@PlusIfNonZero macro (see the 5 variable example). Perhaps add an option to provide the same behavior for an entry with a zero coefficient

  • Provide a starred version of this same environment that outputs a matrix instead. This would require extraction of the variables form the columns, or a change to the user interface where the variables are explicitly provided.

  • Note that the signs are not aligned in the first column and last column. Although I think it looks better this way, perhaps one would want an option to also align the sign of those columns as well. This should be as simple as changing the lower case alignment r/l for these columns to the upper case R/L alignment (although I have not tested it).

  • Perhaps use a space as the alignment character and eliminate the need for the &. Then it would be even easier to read.

Code:

\documentclass[border=2pt]{standalone} 
\usepackage{collcell}% This includes the array package
\usepackage{xcolor}% Only used for error message in case an unknown column is specified
\usepackage{xstring}% For string processing

\makeatletter
\newcommand{\@RemovePositiveSignIfAny}[1]{\IfBeginWith{#1}{+}{\StrGobbleLeft{#1}{1}}{#1}}%
\newcommand{\@PlusIfNonZero}[1]{\IfStrEq{#1}{}{}{+}}%
\newlength{\@MySystemWidth}%
\newcommand*{\@ChooseSignWithAlignment}[2]{%
    \IfBeginWith{#2}{-}%
    {{}-\makebox[\@MySystemWidth][#1]{\ensuremath{\StrGobbleLeft{#2}{1}}}}%
    {{}\@PlusIfNonZero{#2}\makebox[\@MySystemWidth][#1]{\ensuremath{\@RemovePositiveSignIfAny{#2}}}}%
}%
\newcommand*{\@ChooseSignWithRightAlignment}[1]{\@ChooseSignWithAlignment{r}{#1}}%
\newcommand*{\@ChooseSignWithLeftAlignment}[1]{\@ChooseSignWithAlignment{l}{#1}}%

\newenvironment{MySystem}[3][1.2em]{% [<width>] {num of variables} {alignment}
    \newcolumntype{R}{>{\collectcell\@ChooseSignWithRightAlignment}{r}<{\endcollectcell}}
    \newcolumntype{L}{>{\collectcell\@ChooseSignWithLeftAlignment}{l}<{\endcollectcell}}
    \setlength{\@MySystemWidth}{#1}% Store the width to use to typeset the terms
    \IfStrEqCase{#3}{%
        {R}{\begin{array}{r@{} *{\numexpr#2-1\relax}{#3@{}} @{{}={}} r}}%
        {L}{\begin{array}{l@{} *{\numexpr#2-1\relax}{#3@{}} @{{}={}} l}}%
    }[\parbox{\linewidth}{\color{red}MySystem Error: Only L and R alignement types are supported. (using R)}\begin{array}{r *{\numexpr#2-1\relax}{#3} @{{}={}} r}]%
}{%
    \end{array}%
}
\makeatother

\begin{document}
Using the \textbf{R} column type with 3 and 5 variables:
\[
\begin{MySystem}{3}{R}
   2x &  y &  z & 10 \\
    x &  y & -z &  6 \\
   -x &-3y & 2z & 13 \\
\end{MySystem}
\]
\[
\begin{MySystem}{5}{R}
   3u &-4w & 2x &   y &  z & 10 \\
   -u & 3w & x  &   y & -z &  6 \\
      &    &-x  &     & 2z & 13 \\
\end{MySystem}
\]


Using the \textbf{R} column type specifying a size:
\[
\begin{MySystem}[3em]{3}{R}
   2x &  y &  z & 10 \\
    x &  y & -z &  6 \\
   -x &-3y & 2z & 13 \\
\end{MySystem}
\]

\hrule\medskip
Using the \textbf{L} column type (not sure why one would want this):
\[
\begin{MySystem}{3}{L}
   2x &  y &  z & 10 \\
    x &  y & -z &  6 \\
   -x &-3y & 2z & 13 \\
\end{MySystem}
\]

Using the \textbf{L} column type specifying a size:
\[
\begin{MySystem}[3em]{3}{L}
   2x &  y &  z & 10 \\
    x &  y & -z &  6 \\
   -x &-3y & 2z & 13 \\
\end{MySystem}
\]
\end{document}
13

The following code, which takes your code as its starting point,

\documentclass[letterpaper]{standalone}
\usepackage{array}  %% provides the command `\newcolumntype`
%% "o": column type for "operators", e.g., +, -, and =
\newcolumntype{o}{@{}>{{}}c<{{}}@{}}

\begin{document}
\[ 
\begin{array}{rororor}  %% or, more succinctly, \begin{array}{*{3}{ro}r}
2x & + &  y & + & 3z & = & 10 \\
 x & + &  y & + &  z & = &  6 \\
 x & + & 3y & + & 2z & = & 13
\end{array} 
\]
\end{document}

produces this output:

enter image description here

Relative to your code, the code above permits omitting 28 [!] $ symbols in each equation. This is made possible by (i) the use of the array environment (instead of the tabular environment), which operates in math mode, and (ii) the use of a custom-designed column type, o, to take care of the spacing around + and =.

Using the method employed in @Herbert's answer, this code can be simplified further with an array that uses half as many & symbols as the one above:

\documentclass{standalone}
\usepackage{array}
\newcolumntype{z}{r<{{}}}
\begin{document}
\[ \setlength\arraycolsep{0pt} % keep this reset local
   \begin{array}{*{4}{z}}         % {zzzr} works too
      2x + &  y + & 3z = & 10 \\
       x + &  y + &  z = &  6 \\
       x + & 3y + & 2z = & 13
   \end{array} 
\]
\end{document}

Addendum: I just noticed that you're also asking how one might go about changing the spacing between rows and setting the widths between the symbols on each row. First, changing the spacing between rows of an array is achieved by issuing the command \renewcommand\arraystretch{x}, where x should be a positive number. The default value is 1.0; setting x to 1.25, not surprisingly, will increase the distance between rows by 25%. Second, the horizontal space that surrounds operators of type "mathbin" (such as + and -) and "mathrel" (such as =) is controlled by the length variables \medmuskip and \thickmuskip. The default values of these variables are, respectively, 4mu plus 2mu minus 4mu and 5mu plus 5mu, where mu is short for "math unit" and generally equals 1/18em. The values of these length parameters may be changed with the \setlength and \addtolength commands.

Suppose, by way of example, that we were to issue the commands \renewcommand\arraystretch{1.2}, \addtolength\medmuskip{2mu} and \addtolength\thickmuskip{3mu}. The system of equations would then be typeset as:

enter image description here

Final comment: Because the \medmuskip and \thickmuskip parameters occur in plenty of places inside TeX's math commands, you should probably make any redefinitions of these two variables local to the system of equations. If you don't do so, you will probably encounter some rather odd-looking formulas elsewhere in your document!

3
  • Doesn't including the \dollarasblank after \begin{align*} restrict the scope? Nov 17, 2011 at 16:33
  • @PeterGrill: Doing so would certainly also restrict the command's scope, but it would no longer work as intended! Once in math mode, it appears you can't change the meaning of the \$ control symbol in the way I've illustrated it; as a result, one would end up with lots of $ symbols instead of blank spaces... :-)
    – Mico
    Nov 17, 2011 at 16:48
  • @PeterGrill: I changed my answer completely after rereading the question and noting the OP's requirement that the method has to be "clean". No more \dollarasblank...
    – Mico
    Nov 17, 2011 at 17:15
13
+50

The bounty asks if the number of equations can be known from the structure of the code. With the stackengine package, the number of rows of a just completed stack are known through the string \narg (Number of ARGuments, in this case rows). The newly introduced tabstackengine package provides a front end to the stackengine package to allow tabbing within the stacks.

Thus, we can build a system of equations as a tabbed stack, and obtain the number of equations from \narg. Furthermore, the number of alignment columns employed in a row is available with \TABcells{roman numeral of row} (e.g., \TABcells{i}). The actual content of a TABstack cell can be recalled with \TABcell{romannumeral row}{column}.

EDITED 10/16 to reflect slightly revised syntax for 2016-10-04 V2.0 package update:

  1. narg --> \TABcells{}

  2. \TABcells{iii} --> \TABcells{3}, etc.

  3. $\TABcell{iii}{5}$ --> \TABcell{3}{5}

  4. \TABcell and \TABcells are not global commands because the listofitems package, as of 2016-10-04, did not support it. However, it now does as of 2016-10-22. So in the MWE below, I patch \readTABstack to make \TABcell and \TABcells global, assuming you have V1.2 of the listofitems package.

Revised MWE:

\documentclass{article}
\usepackage{tabstackengine}[2016-10-04]
\stackMath

\parskip 1em\parindent 0em\stackMath
\textheight 8.5in

\begin{document}

Default right-aligned behavior (as of tabstackengine V1.1)\\
\tabbedCenterstack[r]{
-2x +&   y  +&  3z  =&  10   \\ 
 x  +&   y  +&   z  =&   6   \\
3x  +&  3y +&  2z  =&  13 
}

The number of equations is \TABcells{}, columns are \TABcells{1}. 
Cell content of (1,3) is ``\TABcell{1}{3}''

Here are other options:
{\setstacktabbedgap{1em}%
\[\tabbedCenterstack[r]{
-2x &+&   y  &+&  3z  &=&  10   \\ 
 x  &+&   y  &+&   z  &=&   6   \\
3x  &+&  3y &+&  2z  &=&  13 
}%
\]
The number of equations is \TABcells{}, Alignment columns are \TABcells{1}.
Cell content of (3,5) is ``\TABcell{3}{5}''

\[\bracketMatrixstack[r]{
-2x &+&   y  &+&  3z  &=&  10   \\ 
 x  &+&   y  &+&   z  &=&   6   \\
3x  &+&  3y &+&  2z  &=&  13 \\
7x  &+&  15y &+&  3z  &=&  -12 
}
\]
The number of equations is \TABcells{}, Columns are \TABcells{1}
}

Change space between lines:\\
{\setstackgap{L}{15pt}
\tabbedCenterstack[r]{
-2x +&   y  +&  3z  =&  10   \\ 
 x  +&   y  +&   z  =&   6   \\
3x  +&  3y +&  2z  =&  13 
}}

Change space between columns:\\
{\setstacktabbedgap{1em}
\tabbedCenterstack[r]{
-2x +&   y  +&  3z  =&  10   \\ 
 x  +&   y  +&   z  =&   6   \\
3x  +&  3y +&  2z  =&  13 
}

or

\tabbedCenterstack[r]{
-2x &+&   y  &+&  3z  &=&  10   \\ 
 x  &+&   y  &+&   z  &=&   6   \\
3x  &+&  3y &+&  2z  &=&  13 
}}

Change to center column alignment:\\
{\TABbinary\tabbedCenterstack[c]{
{-}2x &+&   y  &+&  3z  &=&  10   \\ 
 x  &+&   y  &+&   z  &=&   6   \\
3x  &+&  3y &+&  2z  &=&  13 
}}

or left column alignment:\\
{\TABbinary\tabbedCenterstack[l]{
{-}2x &+&   y  &+&  3z  &=&  10   \\ 
 x  &+&   y  &+&   z  &=&   6   \\
3x  &+&  3y &+&  2z  &=&  13 
}}

or choose your column alignments \{ccccccr\}\\
{\setstacktabulargap{0pt}\TABbinary\tabularCenterstack{ccccccr}{
{-}2x &+&   y  &+&  3z  &=&  10   \\ 
 x  &+&   y  &+&   z  &=&   6   \\
3x  &+&  3y &+&  2z  &=&  13 
}}
\end{document}

enter image description here

V2.0 of tabstackengine.sty is now available at http://ctan.org/pkg/tabstackengine


REEDIT:

The second part of the bonus-giver's request can also be met, after a fashion. The tab character in tabstackengine can be reset to a blank space with \setstackTAB{ }. Because of the way LaTeX is parsed, a multiplicity of blanks is treated as a single space token. Thus, the following syntax would produce the same system of equations as the first item in the prior example. One, of course, must be careful about spaces, which could, however, require more discipline than the typing of & characters.

\documentclass{article}
\usepackage{tabstackengine}[2016-10-04]
\stackMath
\setstackTAB{ }
\begin{document}
\noindent Default right-aligned behavior (as of tabstackengine V1.1)\\
\tabbedCenterstack[r]{
-2x+  y+ 3z= 10\\ 
  x+  y+  z=  6\\
  3+ 3y+ 2z= 13
}\\
The number of equations is \TABcells{}, columns are \TABcells{1}. 
Cell content of (1,3) is ``\TABcell{1}{3}''
\end{document}
9
  • @ Steven B. Segletes Can you change when two signs + - in to - (the equation of the last system of equations? Feb 20, 2014 at 12:21
  • @minthao_2011 I changed the presentation, per your request. Feb 20, 2014 at 12:50
  • @ Steven B. Segletes Can I in put the symbol { in front of each system? Feb 20, 2014 at 14:16
  • @minthao_2011 If I understand you correctly, you could do a \[\left{ [tabbed centerstack goes here] \right.\] Feb 20, 2014 at 14:19
  • 1
    @KevinEvans If I understand your comment correctly, it is not a bug...but user error. I presume you refer to the second MWE, in which a space is used to separate fields. In TeX, the use of, for example, \le 6 has no space before the 6, because the absorption of \le swallows the trailing space. Thus, one must adjust the input so that a space before the 6 is recognized, such as \le{} 6. Oct 12, 2021 at 16:55
9
\documentclass{article}
\usepackage{array}
\newcolumntype{R}{r@{}}
\begin{document}

\def\arraystretch{1.3}
\[ \arraycolsep=1.4pt
\begin{array}{*4R} 
2x + &  y +& 3z =& 10 \\
 x + &  y +&  z =&  6 \\
 x + & 3y +& 2z =& 13
\end{array} 
\]
\end{document}

enter image description here

or with package mathtools:

\documentclass{article}
\usepackage{mathtools,array}
\newcolumntype{R}{r<{\null}}
\begin{document}

\def\arraystretch{1.4}
\[ \arraycolsep=0pt 
\begin{matrix*}[R] 
2x +&  y +& 3z =& 10 \\
 x +&  y +&  z =&  6 \\
 x +& 3y +& 2z =& 13
\end{matrix*} 
\]
\end{document}

enter image description here

0
1

An alternative solution with tblr environment of tabularray package:

\documentclass[10pt,a4paper]{article}

\usepackage{tabularray}
\usepackage{environ}

\NewEnviron{myeqn}[1][2pt]{%
  \hbox{$\begin{tblr}[expand=\BODY]{
    column{odd} = {r},
    column{even} = {c},
    colsep = #1,
  }
    \BODY
  \end{tblr}$}
}

\begin{document}

$A=\left[\begin{myeqn}
 2x & + &  y & + & 3z & = & 10 \\ 
  x & + &  y & + &  z & = &  6 \\
  x & + & 3y & + & 2z & = & 13 \\
\end{myeqn}\right]$
%
\qquad
\begin{myeqn}[4pt]
 2x & + &  y & + & 3z & = & 10 \\ 
  x & + &  y & + &  z & = &  6 \\
  x & + & 3y & + & 2z & = & 13 \\
\end{myeqn}

\end{document} 

enter image description here

You must log in to answer this question.

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