# Best way to create an system of equations environment?

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?

-

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
\fi
\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.

-
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 '11 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 '11 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. –  N3buchadnezzar Nov 17 '11 at 17:23
@N3buchadnezzar See edit –  egreg Nov 18 '11 at 0:41
@DamienWalters I don't think it's possible. –  egreg Mar 3 '12 at 23:44

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}


-
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 =) –  N3buchadnezzar Nov 17 '11 at 19:57

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

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

-

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:


\documentclass{article}
\usepackage{stackengine}
\makeatletter
\renewcommand*\@stack[4]{%
\getargsC{#2}%
\if U#3%
\setcounter{stackindex}{\narg}%
\def\@stacksign{-}%
\def\@stackcondition{\thestackindex > 1}%
\else%
\setcounter{stackindex}{1}%
\def\@stacksign{}%
\def\@stackcondition{\thestackindex < \narg}%
\fi%
\sbox{\stackedbox}{$\csname arg\roman{stackindex}\endcsname$}%
\whiledo{\@stackcondition}{%
\stackengine{\csname#4stackgap\endcsname}%
{$\csname arg\roman{stackindex}\endcsname$}%
{\usebox{\stackedbox}}{#3}{#1}{T}{\useanchorwidth}{#4}%
}%
\if F\quietstack\usebox{\stackedbox}\fi%
}
\makeatother
\begin{document}
$\Longstack[r]{2x x x} \mathrel{\Longstack[r]{+ + +}} \Longstack[r]{y y 3y} \mathrel{\Longstack[r]{+ + +}} \Longstack[r]{3z z 2z} \mathrel{\Longstack[r]{= = =}} \Longstack[r]{10 6 13}$
\setstackgap{L}{1.5\baselineskip}
$\Longstack[r]{2x x x} \mathrel{\Longstack[r]{+ + +}} \Longstack[r]{y y 3y} \mathrel{\Longstack[r]{+ + +}} \Longstack[r]{3z z 2z} \quad \mathrel{\Longstack[r]{= = =}} \quad \Longstack[r]{10 6 13}$
\end{document}


-