Alignment in multiple locations of a single equation based on first line

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:

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:

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.

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

-

There a probably a few ways to produce that.

This is my suggestion. I used

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:

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}


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

-
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? – Tyson Williams Oct 20 '12 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. – Qrrbrbirlbel Oct 20 '12 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? – Tyson Williams Oct 20 '12 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. – Qrrbrbirlbel Oct 20 '12 at 11:16
@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. – Hendrik Vogt Oct 20 '12 at 20:53

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:

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

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:

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}

-
@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. – Peter Grill Oct 20 '12 at 2:44
@GonzaloMedina: Updated. Let me know if you see any other options. – Peter Grill Oct 20 '12 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$. – Tyson Williams Oct 20 '12 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. – Peter Grill Oct 20 '12 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. – Tyson Williams Oct 20 '12 at 5:28

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.

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

-