디스플레이, 정렬 및 번호 매긴 수식

여러 줄에 걸친 별행 수식에서 정말 어려운 것은 어디서 줄을 나눌지가 아니라 그 결과에 식 번호가 몇 개 붙는가입니다. LaTeX의 align은 줄마다 하나, multline은 식 전체에 하나, split은 스스로는 갖지 않고 바깥 구조에서 하나를 빌립니다. 여기를 잘못 잡으면 그 뒤의 번호가 모두 밀리고 상호 참조도 한꺼번에 어긋납니다. 이 페이지에서는 amsmath가 제공하는 equation, align, gather, multline, split, cases를 “번호가 몇 개 붙는가”라는 축으로 정리하고, \notag, \tag, subequations에 의한 번호 제어와 \label\eqref에 의한 참조까지 다룹니다. 마지막은 eqnarray, 그리고 다시는 쓰지 말아야 할 이유를 보여 주는 실측값입니다.

먼저 amsmath를 읽어 들이고, 환경 안에 빈 줄을 두지 않습니다

이 페이지에서 다루는 환경은 equation을 빼면 모두 amsmath가 제공하므로, 프리앰블의 한 줄이 모든 것의 전제입니다. amsmath는 순수 LaTeX에 거의 아무것도 없던 다중 행 수식 영역을 단번에 메우며 alignalign*, gathergather*, multlinemultline*, alignatalignat*, flalignflalign*, 그리고 split을 더합니다. 수식 번호를 왼쪽 여백에 두려면 \usepackage[leqno]{amsmath}, 오른쪽(가로쓰기 기본값)이면 [reqno], 별행 수식을 왼쪽 정렬하려면 [fleqn]을 패키지 옵션으로 넘깁니다.

latex
\usepackage{amsmath}

무엇보다 먼저 첫 지뢰를 제거해 둡니다. 이 환경들 안에 빈 줄을 두면 안 됩니다. 두면 ! Paragraph ended before \align was complete.가 납니다. 이유는 역사에 있습니다. AMS의 기술 노트에 따르면, 이 별행 환경들은 내용을 매크로 인수로 한꺼번에 읽어 들여 여러 차례 훑으며 너비와 위치를 정하는데, 그 알고리즘은 Michael Spivak의 amstex.tex에서 물려받은 것이라고 적혀 있습니다. 빈 줄은 TeX에게 \par이고, \par\long으로 선언되지 않은 매크로의 인수를 넘지 못합니다. 이 오류 메시지는 amsmath가 1980년대 AMS-TeX의 피를 이어받았다는 직접적인 증거입니다.

번호가 붙는 한 줄 — equation 환경

출발점은 equation 환경입니다. 내용을 독립된 줄에 조판하고 오른쪽 끝(가로쓰기 기본값)에 일련번호를 자동으로 붙입니다. 번호는 equation 카운터가 관리하며, \label{…}을 붙이면 본문에서 \ref{…}\eqref{…}로 부를 수 있습니다. 번호만 없애고 싶다면 별표가 붙은 equation*을 씁니다. amsmath를 읽어 들인 환경에서는 이것이 \[\]와 완전히 같은 물건입니다. 요컨대 equation한 줄 분량의 식에 번호 하나를 주는 환경이며, 그 이상도 이하도 아닙니다.

latex
\begin{equation}
  \label{eq:euler}
  e^{i\pi} + 1 = 0
\end{equation}

이는 오일러 항등식을 독립된 줄 가운데에 조판하고 그 줄 오른쪽 끝에 (1) 같은 번호를 둡니다(번호는 문서의 연속 번호이므로 반드시 1은 아닙니다). 한 줄에 들어가지 않는 식이나 여러 식을 맞추고 싶다면 다음 절부터의 환경으로 넘어갑니다. 경고 하나: 번호가 붙는 환경을 \[\] 안에 넣으면 안 됩니다. \[ \begin{align} … \end{align} \]라고 쓰면 ! Package amsmath Error: Erroneous nesting of equation structures;가 납니다. 바깥의 \[\]는 그저 군더더기입니다.

여러 줄 맞추기 — aligngather의 차이

align은 관계 기호에서 맞추고, gather는 맞추지 않고 가운데에 쌓습니다. 차이는 그것뿐이며, 둘 다 각 줄에 번호를 붙입니다(별표가 붙은 align*gather*는 붙이지 않습니다). align에서는 줄을 \\로 나누고 맞추고 싶은 위치에 &를 하나 둡니다. 관례상 등호나 부등호 같은 관계 기호 바로 앞입니다. &의 왼쪽은 오른쪽 정렬, 오른쪽은 왼쪽 정렬로 조판되므로 양쪽이 관계 기호에서 정확히 만납니다. amsmath 매뉴얼은 &를 관계 기호 에 두면 정상적인 간격이 망가진다고 명시합니다. 옛 eqnarray가 바로 그렇게 설계되어 있었습니다.

latex
\begin{align}
  (x + y)^2 &= x^2 + 2xy + y^2 \\
  (x - y)^2 &= x^2 - 2xy + y^2
\end{align}

이는 두 식을 세로로 쌓고 두 등호를 같은 가로 위치에 맞추며 각 줄 오른쪽에 번호를 둡니다. 마지막 줄 뒤에 \\를 붙이면 안 됩니다. amsmath 매뉴얼이 명시적으로 경고하는 부분으로, 수식 아래에 불필요한 세로 여백이 들어갑니다. 가장 흔한 실수는 gather&를 쓰는 것입니다. 거기에는 정렬 열이 없으므로 ! Extra alignment tab has been changed to \cr.가 납니다. split의 한 줄에 &를 둘 놓아도 같은 오류가 나옵니다.

align여러 식을 가로로 나란히 놓을 수도 있습니다. &가 정렬 표시와 열 구분자를 겸하여, 한 묶음은 “오른쪽 정렬 부분 & 관계 기호와 왼쪽 정렬 부분”이 되고, 다음 묶음과의 사이에 또 하나의 &를 둡니다. 열 사이 간격은 amsmath가 고정 폭으로 자동 확보합니다. 이 간격을 직접 정하고 싶다면 alignat을 씁니다. 열 쌍의 수를 인수로 받고 열 사이를 비워 두어 \quad 등으로 직접 넣게 합니다. 판면 전체 너비까지 벌리고 싶다면 flalign을 씁니다.

latex
\begin{align}
  x      &= y       & X      &= Y       & a   &= b + c \\
  x'     &= y'      & X'     &= Y'      & a'  &= b      \\
  x + x' &= y + y'  & X + X' &= Y + Y'  & a'b &= c'b
\end{align}

반면 gather에는 정렬이 전혀 없어 각 줄이 저마다 독립적으로 가운데 정렬됩니다. 줄은 \\로 나누고 줄마다 번호가 붙습니다(gather*는 붙지 않습니다). align은 “관계 기호에서 맞춘다”, gather는 “그냥 가운데에 쌓는다”로 기억하면 선택에 망설임이 없습니다. gather의 한 줄 안에 뒤에서 설명할 split을 넣어 그 줄만 여러 줄로 나눌 수도 있습니다.

latex
\begin{gather}
  a^2 + b^2 = c^2 \\
  e^x = \sum_{n=0}^{\infty} \frac{x^n}{n!}
\end{gather}

align이 쪽 경계에 걸리면 LaTeX는 기본적으로 나누지 않습니다. amsmath가 \interdisplaylinepenalty를 최댓값으로 두기 때문입니다. 수십 줄짜리 계산을 싣는 문서라면 프리앰블에 \allowdisplaybreaks를 쓰면 이 금지가 느슨해집니다. 선택 인수는 [1]부터 [4]까지 마지못한 쪽에서 너그러운 쪽으로 이어지고, 기본값은 가장 너그러운 [4]입니다. 특정 줄 뒤에서 끊기지 않게 하려면 그 줄의 \\\\*로 씁니다.

긴 식 하나 나누기 — multlinesplit

한 줄에 들어가지 않는 하나의 식을 나누는 환경은 둘이며, 둘 다 “식 하나에 번호 하나”라는 점에서 aligngather와 결정적으로 다릅니다. multline은 아무것도 맞추지 않습니다. 첫 줄은 왼쪽 끝, 마지막 줄은 오른쪽 끝에 붙이고 중간 줄은 가운데에 둡니다. “왼쪽 끝”이라 해도 실측하면 왼쪽 여백에서 10pt 안쪽, 곧 \multlinegap의 기본값만큼 들어갑니다. 전체 식의 번호는 마지막 줄에 붙습니다(leqno면 첫 줄). 식 하나에 번호 하나이므로 개별 줄을 \notag로 지우면 안 됩니다. 중간 줄을 한쪽으로 밀고 싶으면 그 줄 전체(바로 뒤의 \\ 제외)를 \shoveleft{…} 또는 \shoveright{…}에 넘깁니다. 번호 없는 형태는 multline*입니다.

latex
\begin{multline}
  a + b + c + d + e + f \\
  + g + h + i + j + k + l + m + n
\end{multline}

나눈 줄들을 맞추고 싶을 때split입니다. splitalign처럼 &에서 맞추지만 정렬 열은 하나뿐이고(한 줄에 & 하나) 스스로 번호를 갖지 않습니다. 번호를 제공하는 equation(또는 align, gather) 안쪽에 놓으면 전체 구조가 하나의 번호를 받습니다. 단독으로 쓰면 ! Package amsmath Error: \begin{split} won't work here.가 납니다. split의 내용은 바깥 구조의 본문 전체를 채워야 하며, \label처럼 출력을 만들지 않는 명령만 함께 둘 수 있습니다. multline 안에는 넣을 수 없습니다.

latex
\begin{equation}
  \label{eq:cosh}
  \begin{split}
    \cosh x &= \frac{e^x + e^{-x}}{2} \\
            &= 1 + \frac{x^2}{2!} + \frac{x^4}{4!} + \cdots
  \end{split}
\end{equation}
환경식과 번호정렬주요 용도
equation하나 / 하나없음별행 수식 한 줄
align여러 개 / 줄마다&에서관계 기호에 맞춰 쌓기
gather여러 개 / 줄마다없음(각 줄 가운데)정렬 없이 가운데 쌓기
multline하나 / 하나(마지막 줄)없음(왼쪽→오른쪽)긴 식 나누기, 정렬 없음
split하나 / 번호는 바깥 구조가 제공& 열 하나나눈 식의 줄을 정렬

경우 나누기 정의 — cases

함수를 조건에 따라 나누어 정의할 때는 cases 환경을 씁니다. 왼쪽의 큰 중괄호는 자동으로 붙고, 각 줄에서 &가 값과 조건을 나누며, 줄은 \\로 구분합니다. 조건의 말(“if …” 등)을 그대로 쓰면 여전히 수식 모드이므로 기울임꼴로 좁게 나옵니다. \text{…}로 감싸세요. cases는 스스로 번호를 갖지 않으므로 보통 equation 안에 넣어 전체에 번호 하나를 붙입니다.

latex
\begin{equation}
  |x| =
  \begin{cases}
    x  & \text{if } x \ge 0, \\
    -x & \text{if } x < 0.
  \end{cases}
\end{equation}

이는 큰 중괄호 오른쪽에 두 줄, 곧 x(조건 x ≥ 0)와 −x(조건 x < 0)를 놓고 equation이 주는 번호 하나를 붙입니다. 값 열과 조건 열 모두 왼쪽 정렬입니다. 함정이 하나 있습니다. cases의 내용은 텍스트 스타일로 조판됩니다. 실측하면 cases 안의 \frac{1}{2} 숫자는 높이 6.19pt로, 같은 분수를 보통 별행 수식에 두었을 때의 8.85pt보다 작습니다. 분수를 크게 내고 싶다면 mathtools 패키지의 dcases를 쓰세요. 디스플레이 스타일로 조판하는 같은 형태의 환경입니다.

번호 제어 — \notag, \tag, subequations

번호가 붙는 환경에서는 각 줄에 자동으로 번호가 매겨지지만 줄 단위로 조정할 수 있습니다. 알아 두면 마음이 놓이는 사실이 하나 있습니다. \notag을 둔 줄은 번호를 “소비하지” 않습니다. amsmath는 \nonumber를 재정의해, 억제한 줄만큼 카운터를 하나 되돌립니다. amsmath.sty\addtocounter{equation}\m@ne이라고 적혀 있습니다. 실제로 align 세 줄 중 둘째 줄에 \notag을 붙이면 번호는 (1), 없음, (2)로 이어지고 그다음 수식은 (3)이 됩니다. 번호에 구멍이 생기지 않습니다.

  • 한 줄의 번호만 없애기: 그 줄의 \\ 앞에 \notag을 둡니다. 동의어는 \nonumber이며, amsmath에서 \notag은 문자 그대로 \nonumber의 별칭으로 정의되어 있습니다.
  • 번호를 직접 정하기: \tag{…}는 자동 번호 대신 준 내용을 조판하고 괄호를 보태 줍니다. \tag*{…}는 괄호를 붙이지 않고 인수를 그대로 찍습니다. \tag{$\star$}는 (⋆), \tag*{NP}는 NP가 됩니다.
  • 관련 식을 (4a), (4b)로 묶기: subequations 환경으로 감싸면 안쪽 식이 부모 번호에 문자를 붙여 번호가 매겨집니다. \begin{subequations} 바로 뒤에 둔 \label은 자식 (4a)가 아니라 부모 번호 (4)를 가리킵니다.
  • 장이나 절마다 번호를 다시 시작하기: 프리앰블에 \numberwithin{equation}{section}이라고 쓰면 2절의 첫 식이 (2.1)이 됩니다. 긴 문서에서 번호가 네 자리에 이르는 것을 막는 정석입니다.
latex
\begin{align}
  y &= (x + 1)^2    \notag \\
    &= x^2 + 2x + 1 \\
  E &= mc^2         \tag{$\star$}
\end{align}

\begin{subequations}
  \label{eq:max}
  \begin{align}
    \nabla \cdot \mathbf{E} &= \frac{\rho}{\varepsilon_0} \label{eq:gauss} \\
    \nabla \cdot \mathbf{B} &= 0
  \end{align}
\end{subequations}

위의 align에서는 첫 줄이 \notag 덕에 번호가 없고, 둘째 줄은 평소대로 자동 번호를, 셋째 줄은 자동 번호 대신 (⋆)를 받습니다. 유도의 중간 과정을 번호 없이 두고 결론에만 번호를 붙이는 것이 논문에서 가장 흔한 형태입니다. 아래의 subequations에서는 두 맥스웰 방정식이 (4a), (4b)로 매겨지고, \eqref{eq:gauss}는 (4a)를, \eqref{eq:max}는 그룹 전체를 나타내는 (4)를 돌려줍니다.

\label\eqref로 식을 참조하기

번호가 붙은 식에 \label{…}로 이름표를 달면 본문에서 번호로 부를 수 있습니다. \ref{…}는 번호 자체(예: 3.2)를 돌려주고, amsmath의 \eqref{…}는 괄호를 보태 (3.2)를 돌려줍니다. amsmath.sty에서 \eqref 전체는 \textup{…}으로 감싸여 있어, 주위가 기울임꼴이어도 괄호만은 곧게 조판됩니다. 정리 서술 안에서 식을 처음 참조할 때 바로 눈에 띄는 차이입니다. 여러 줄 환경에서는 번호를 원하는 그 줄\label을 둡니다. 참조는 보조 파일을 거치므로 확정하려면 두 번 컴파일합니다.

latex
By~\eqref{eq:euler}, we have $e^{i\pi} = -1$.

% preamble: number equations within sections, giving (2.1), (2.2), ...
\numberwithin{equation}{section}

번호의 겉모습 자체는 \theequation이 정합니다. article의 기본값은 \arabic{equation}이고, bookreport의 정의는 “장 카운터가 0보다 크면 \thechapter.를 앞에 붙이고 그다음 일련번호”입니다. book.cls에 문자 그대로 그렇게 적혀 있으며, 그래서 앞부속에서는 장 번호가 없는 맨 번호가 나옵니다. 서식을 직접 바꾸고 싶다면 \renewcommand{\theequation}{\thesection.\arabic{equation}}처럼 재정의할 수 있지만, 카운터 초기화까지 함께 챙겨 주는 \numberwithin 쪽이 보통 더 안전합니다.

eqnarray를 쓰지 않습니다 — 등호 주변이 3.6배 넓습니다

오래된 문서에서는 여러 줄 수식에 eqnarray(와 eqnarray*)를 씁니다. 쓰지 마세요. 이유는 감상이 아니라 치수로 말할 수 있습니다. latex.ltx\eqnarray 정의를 보면 관계 기호 열의 양옆에 \hskip \tw@\arraycolsep이 들어 있습니다. \arraycolsep의 기본값은 5pt이므로 한쪽당 10pt입니다. 같은 식을 align이나 equation으로 조판하면 한쪽은 \thickmuskip, 곧 2.78pt입니다. 10pt 문서에서 실측해도 한쪽 9.97pt 대 2.77pt, 즉 3.6배입니다. 게다가 그 10pt는 표 조판의 열 간격에서 온 고정 치수여서 수식 글꼴 크기가 바뀌어도 따라가지 않습니다.

두 번째 실질적인 피해는 식 번호입니다. 긴 줄을 eqnarray에 넣으면 번호가 수식 위에 겹쳐 인쇄됩니다. 실측에서 마지막 항은 가로 483~505pt를 차지했고 번호 (1)은 492~505pt를 차지해 완전히 겹쳤습니다. 같은 내용을 align에 넣으면 amsmath가 충돌을 감지해 번호를 다음 줄로 내립니다. AMS의 Short Math Guide for LaTeXeqnarray를 만류하며 드는 이유가 바로 이 두 가지, 곧 등호 주변 간격이 일관되지 않다는 점과 번호가 식 본체를 덮어 찍는 것을 막으려 하지 않는다는 점입니다. amsmath 매뉴얼은 세 번째를 덧붙입니다. 정리 패키지의 \qed\qedhere가 그 안에서는 작동하지 않습니다.

치환은 기계적입니다. 여러 식을 맞추려면 align, 하나의 식을 나누려면 equation 더하기 split. &의 자리도 바뀝니다. eqnarray&를 관계 기호 에 두도록 설계되었지만 align 계열은 에 둡니다. 그러므로 x &=& yx &= y가 됩니다. 원고를 이어받았다면 이 일괄 치환이 가장 먼저 해야 할 작업입니다.