5

I want to align a multi-line equation so that it basically looks like this:

a = (b + c
   + d + e)
f = g

The requirements of this alignment are:

  1. The equal signs should be aligned.
  2. The beginning of "b" should be aligned with the beginning of "d".
  3. There should be no introduction of white space in the middle of the lines. To satisfy the alignment requirements, the whole line should be shifted horizontially.

I do not know how to accomplished this. When using the alignat environment, even putting an alignment sign (&) between the "(" and the "b" (to try to align the beginning of "b" and "d") introduces white space between them, which is not allowed.

Can this be done?

(Note: the letters are just variables for any math expression. Make sure your solution does not depend on, say, the width of "a" and "f" being the same.)

EDIT:

As my note says, the letters are just variables for any math expression to give a MWE. I am actually interested in setting d = \left[\begin{smallmatrix} 1 \\ 0 \end{smallmatrix}\right]. Qrrbrbirlbel's current solution works using the letters but not after setting d as above:

enter image description here

As you can see, the beginning of d matches the beginning of b, but the beginning of [ is further right than the beginning of b.

The ['s should be aligned in this example:

enter image description here

The source for the two images above is:

\documentclass{article}

\usepackage{mathtools} % amsmath is loaded by mathtools
\usepackage{xcolor}
\newcommand*{\gphantom}[1]{{\color[gray]{.75}#1}}

\begin{document}
\begin{align*}
    a & = (b + c \\
      & \hphantom{{}={} (}\mathllap{{}+{}}d + e) \\
      & \hphantom{{}={} (}\mathllap{{}+{}}\left[\begin{smallmatrix} 1 \\ 0 \end{smallmatrix}\right] + e) \\
    f & = g
\end{align*}

\begin{align*}
    a & = (\left[\begin{smallmatrix} 1 \\ 0 \end{smallmatrix}\right] + c \\
      & \hphantom{{}={} (}\mathllap{{}+{}}\left[\begin{smallmatrix} 1 \\ 0 \end{smallmatrix}\right] + e) \\
    f & = g
\end{align*}
\end{document}

Solution

For clarity, simplicity, and further understanding, I am posting the (current best) solution here. This is a slight modification Qrrbrbirlbel's solution bases on his own comments.

enter image description here

\documentclass{article}
\usepackage{mathtools} % amsmath is loaded by mathtools
\begin{document}
\begin{align*}
    a & = (\left[\begin{smallmatrix} 1 \\ 0 \end{smallmatrix}\right] + c \\
      & \hphantom{{}={} (}\mathllap{{}+{}}{\left[\begin{smallmatrix} 1 \\ 0 \end{smallmatrix}\right]} + e) \\
    f & = g
\end{align*}
\end{document}
0

3 Answers 3

8

There a probably a few ways to produce that.


This is my suggestion. I used

  • amsmath (loaded by mathtools) for align and split,
  • mathtools for \mathllap and
  • \hphantom for horizontal white spacing.

For the sake of this answer I also used xcolor and my own macro \gphantom.

\mathllap overlaps its argument to the left of the current horizontal location.

I added some further solutions because I am little bit unsatisfied with the first solution due the + overlapping into the = region; but that's just my two cents.

Hopefully, the last bit shows how spacing around a binary + is chosen.

Custom macro?

You might consider your own macro to shortcut this repetitive task, maybe something like:

\newcommand*{\bettername}[2][{}={} (]{% #1 = hide, #2 = show instead
    \hphantom{#1}
    \mathllap{#2}
}

No whitespace between + and d

\begin{align}
    \begin{split}
    a & = ( b + c \\
      & \bettername{+}d + e)
    \end{split} \\
    f & = g
\end{align}

Output:
without whitespace between + and d

Code

\documentclass{article}
\usepackage{mathtools} % amsmath is loaded by mathtools
\usepackage{xcolor}
\newcommand*{\gphantom}[1]{{\color[gray]{.75}#1}}
%\renewcommand*{\gphantom}[1]{\hphantom{#1}} % comment out to see \hphantom'ed stuff
\begin{document}
\begin{align}
    \begin{split}
    a & = ( b + c \\
      & \gphantom{{}={} (}\mathllap{{}+{}}d + e)
    \end{split} \\
    f & = g
\end{align}
\begin{align}
\begin{split}
    a & = \gphantom{+\:}\mathllap{(} b + c \\
      &  \gphantom{{}={}} {+\:} d + e)
    \end{split} \\
    f & = g
\end{align}
\begin{align}
    \begin{split}
    a & = \gphantom{{}+{}}\mathllap{(} b + c \\
      &  \gphantom{{}={}} {{}+{}} d + e)
    \end{split} \\
    f & = g
\end{align}
\begin{gather}
    = x + y \\
    = x{\: +\:}y \\
    = x{+}y \\
    %
    = {+\:}y \\
    = {} + y \\
\end{gather}
\end{document}

Output

Output

smallmatrix

Code

\documentclass{article}
\usepackage{mathtools}
\usepackage{xcolor}

\newcommand*{\gphantom}[1]{{\smash{\color[gray]{.75}#1}}}
\renewcommand*\gphantom[1]{\hphantom{#1}}

\newcommand*{\mathindent}[2][{}={} (]{% #1 = hide, #2 = show instead
    \gphantom{#1}
    \mathllap{#2}
}

\def\bmatr{\ensuremath{\begin{bsmallmatrix} 1 \\ 0 \end{bsmallmatrix}}} % mathtools
\def\matr{\ensuremath{\left[\begin{smallmatrix} 1 \\ 0 \end{smallmatrix}\right]}}
\begin{document}
\begin{align}
    a & = ( \matr + c                 \\
      & \mathindent{{}+{}}\matr + c   \\
      & \mathindent{{}+{}}{\matr} + c \\
      & \mathindent{{}+{}}\bmatr + c  \\
      & \mathindent{} \gphantom{\matr} + c_2) \\
    f & = g
\end{align}
\end{document}

Output

smallmatrix problem?

9
  • The first output looks correct. I will take a closer look later when I get more time. In the meantime, can you explain how your solution works? Oct 20, 2012 at 2:11
  • @TysonWilliams I've updated my answer. Note, that the usages of split is only a matter of equation numbering (and position). Compare the output of the three answers to the linked question. Oct 20, 2012 at 2:43
  • Thanks for the explanation. I understand what you are trying to do. However, if I set d to the expression \left[\begin{smallmatrix} 1 \\ 0 \end{smallmatrix}\right], there is too much space between + and d. Do you know why? Can you fix it? Oct 20, 2012 at 5:24
  • @TysonWilliams Hmm … the [ is always left-aligned to the left side of the b. Maybe you can edit your question to insert that particular point highlighting the space you consider too much and how you would want it to look like. Oct 20, 2012 at 11:16
  • 2
    @tyson: \left...\right produces a so-called "inner atom", which has different spacing. The {} converts the inner atom into an ordinary atom with usual spacing. Oct 20, 2012 at 20:53
1

To use the alignat environment, you need to keep in mind that alignat yields pairs of r/l aligned equations, so you need to use a double && to skip past the right aligned column so that you are aligning things on the left:

enter image description here

Furthermore, if you want to also align the + sign you can use another && to do so as in the second example:

enter image description here

In the comments it was pointed out that the additional spacing that was being added to the right of the opening ( was not acceptable. I have added additional spacing to the right of the opening ( so that the space to the right of the ( is not stretched as shown in the third example above.

As Gonzalo Medina commented, the spacing of the + sign before the d is incorrect. The only way to remedy that, while still maintaining the other alignment requirements given in the question, is to introduce additional horizontal spacing, or move the + sign to the line above:

enter image description here

As per Hendrik Vogt's suggestion, I added a \mathrlap around the g (since the g is wider than a ()

Code:

\documentclass{article}
\usepackage{mathtools}

\begin{document}
\begin{minipage}{0.2\linewidth}
\begin{alignat*}{4}
a &=     ( &&b + c \\
  &\quad + &&d + e) \\
f & = g
\end{alignat*}
\end{minipage}
%
\begin{minipage}{0.2\linewidth}
\begin{alignat*}{4}
a &=     ( &&b &&+ c \\
  &\quad + &&d &&+ e) \\
f & = g
\end{alignat*}
\end{minipage}
%
\begin{minipage}{0.2\linewidth}
\begin{alignat*}{4}
a &=\\
( &&b &&+ c \\
  &\quad + &&d &&+ e) \\
f & = g
\end{alignat*}
\end{minipage}
\end{document}

Code: Correct \mathbin spacing:

\documentclass{article}
\usepackage{mathtools}

\begin{document}
\begin{minipage}{0.3\linewidth}
    \begin{alignat*}{4}
        a &=     ( &&b &&+ c \\
          &\quad +{} &&d &&+ e) \\
        f & = g
    \end{alignat*}
\end{minipage}
%
\begin{minipage}{0.3\linewidth}
    \begin{alignat*}{4}
        a &= ( &&b &&+ c +{}\\
          &    &&d &&+ e) \\
        f & = \mathrlap{g}
    \end{alignat*}
\end{minipage}
\end{document}
8
  • @GonzaloMedina: Yes I realize that, but the OP requested no additional white space. Making that a binary operator woudl mean that you either have to have space after or before the (. I will add that as an option when I get back. Oct 20, 2012 at 2:44
  • @GonzaloMedina: Updated. Let me know if you see any other options. Oct 20, 2012 at 4:46
  • There is white space between the "(" and the "b". Compare the space between them in your output and between them in \[a = (b + c\]. Oct 20, 2012 at 4:59
  • Compare the output with \begin{alignat}{4} a &= ( &&b + c \end{alignat} and you will see that the spacing around the ( is identical. This spacing you are seeing is coming from the alignment requirements. If there was not this additional padding on the right of the (, the padding on the left would need to be much larger. Oct 20, 2012 at 5:20
  • Introducing white space in between ( and b (relative to \[a = (b + c\]) is not acceptable. This suggests that alignat is not capable of fulfilling my requirements. Oct 20, 2012 at 5:28
1

You can use a command \leftplus defined as follows:

\newcommand*{\leftplus}{\mathllap{{}+{}}\mathopen{}}

The \mathllap puts the plus to the left (with proper spacing around it), and \mathopen{} takes care that no additional space is added to the right. (\mathopen{} generates an empty "opening atom", and TeX never adds horizontal space after an opening atom.)

Now you could use \leftplus together with alignat, aligned or array, but each of these possibilities has some drawback; see below. That's why I define a new environment stacked (based on gathered) that stacks the lines inside left aligned.

output

\documentclass{article}
\usepackage{mathtools} % amsmath is loaded by mathtools
\makeatletter
\newenvironment{stacked}[1][c]{%
    \RIfM@\else
        \nonmatherr@{\begin{stacked}}%
    \fi
    \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi\fi \bgroup
        \Let@ \chardef\dspbrk@context\@ne \restore@math@cr
        \spread@equation
        \ialign\bgroup
            \strut@$\m@th\displaystyle##$\hfil
            \crcr
}{%
  \endaligned
}
\makeatother
\newcommand*{\myvector}{\left[\begin{smallmatrix} 1 \\ 0 \end{smallmatrix}\right]}
\newcommand*{\leftplus}{\mathllap{{}+{}}\mathopen{}}
\begin{document}
\begin{align*}
    a &= ( \begin{stacked}[t]
                     \myvector + c \\
           \leftplus \myvector + e)
           \end{stacked} \\
    f &= g
\end{align*}
\end{document}

The only differences between stacked and gathered: the latter adds a horizontal space \, at the left that is not wanted here, and it centers the lines.


Here are possible solutions with alignat, aligned and array, each yielding the same output as above:

\documentclass{article}
\usepackage{mathtools} % amsmath is loaded by mathtools
\newcommand*{\myvector}{\left[\begin{smallmatrix} 1 \\ 0 \end{smallmatrix}\right]}
\newcommand*{\leftplus}{\mathllap{{}+{}}\mathopen{}}
\begin{document}
\begin{alignat*}{2}
    a &= (&&\mathopen{} \myvector + c \\
      &   &&\leftplus   \myvector + e) \\
    f &= \mathrlap{g}
\end{alignat*}
\begin{align*}
    a &= \!\begin{aligned}[t]
         ( & \mathopen{} \myvector + c \\
           & \leftplus   \myvector + e)
         \end{aligned} \\
    f &= g
\end{align*}
\begin{align*}
    a &= ( \begin{array}[t]{@{}l@{}}
                     \myvector + c \\[\jot]
           \leftplus \myvector + e)
           \end{array} \\
    f &= g
\end{align*}
\end{document}

In alignat and aligned I need a \mathopen{} hack in the first line since otherwise there would be some additional horizontal space before the vector. For aligned I need \! to compensate for some \, that is issued by aligned. In the array solution, @{} avoids additional horizontal space, and one needs to specify \\[\jot] to obtain the same vertical spacing as with aligned.

You must log in to answer this question.

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