Best way to create an system of equations environment?
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.
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}
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: eitherR
orL
. 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 coefficientProvide 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 caseR
/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}