4

First of all, a bit of introduction in order to avoid the XY problem: when I write a test/exams I like to keep text and solution together. Now, both the main text and the solution can have equations; I'd like that the equation numbering of the main text could be kept constant, both in the formulation-only document and the full one (formulation with the solution).

I am able to do it for figures (I use newfloat to define a solfigure environment which has labels like Figure S1 and so on), but I am at a loss thinking something similar with equation.

I prepared this MWE:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{xcolor}
\usepackage{environ}
\newif\ifsolution
\solutiontrue
\NewEnviron{solution}{\ifsolution\color{red}\expandafter\BODY\fi}
\begin{document}
\begin{equation}
    2x=4
    \label{eq:one}
\end{equation}

\begin{solution}
    \begin{equation}
        x=2
        \label{eq:solone}
    \end{equation}
\end{solution}

\begin{equation}
    3x=6
    \label{eq:two}
\end{equation}

\end{document}

With \solutiontfalse I have equation (1), (2); with \solutiontrue I have (1), (2), (3); I'd like to have (1), (S1), (2)... and so on, so that the equation for (2) is the same one both in the formulation and the formulation+solution document.

Extra point for having the tag in red, too.

With \solutionfalse:

output for the formulation

With \solutiontrue:

output for the formulation + solution

1

4 Answers 4

8

How about just play with counters?

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{xcolor}
\usepackage{environ}
\newif\ifsolution
\solutiontrue
\newcounter{fakeequation}
\newcounter{fakeeqtmp}
\NewEnviron{solution}{\setcounter{fakeeqtmp}{\value{equation}}\setcounter{equation}{\value{fakeequation}}%
    \renewcommand\theequation{S\arabic{equation}}\ifsolution\color{red}\expandafter\BODY\fi%
    \setcounter{fakeequation}{\value{equation}}\setcounter{equation}{\value{fakeeqtmp}}\renewcommand\theequation{\arabic{equation}}}
\begin{document}
\begin{equation}
    2x=4
    \label{eq:one}
\end{equation}

\begin{solution}
    \begin{equation}
        x=2
        \label{eq:solone}
    \end{equation}
\end{solution}

\begin{equation}
    3x=6
    \label{eq:two}
\end{equation}

\begin{solution}
    \begin{equation}
        x = 2
        \label{eq:soltwo}
    \end{equation}
\end{solution}

\end{document}

enter image description here

Explanation

I defined two extra counters fakeequation and fakeeqtmp.

At the start of the solution environment I stashed the value of equation into fakeeqtmp and loaded the value of fakeequation into equation. This is reversed at the end of the environment. So that inside the solution environment the counter being used is really the fakeequation counter, just addressed as equation.

I also included some code to format \theequation so that the equation labels look different inside and outside of the solution environments, included the capital "S" that you wanted.

2
  • Thanks, +1, this will work. I will wait a bit to see if more solutions appear!
    – Rmano
    Mar 2, 2020 at 19:28
  • I like this solution for its simplicity --- and that it will probably work also with other math environments like align and so on. Thanks!
    – Rmano
    Mar 3, 2020 at 10:35
4

Use \tag with \ref.

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{xcolor}
\usepackage{xparse}
\usepackage{amsmath}

\newif\ifsolution
\solutiontrue
\NewDocumentEnvironment{solution}{+b}{%
  \ifsolution\color{red}#1\fi
}{}

\begin{document}
\begin{equation}
    2x=4
    \label{eq:one}
\end{equation}

\begin{solution}
    \begin{equation}
        x=2
        \tag{S\ref{eq:one}}
    \end{equation}
\end{solution}

\begin{equation}
    3x=6
    \label{eq:two}
\end{equation}

\end{document}

enter image description here

2

Presumably both the question and the solution will sometimes have multiple equations, and they may not necessarily appear in the same order in the questions and the solutions, so using parallel counters is not an ideal solution. A better idea, as @egreg suggests, is to use \ref{...} to label the equations combined with the \tag{..} command.

To make this automatic you need to change the behaviour of the equation environment inside a solution environment. The code below redefines the equation environment inside a solution environment so that it is really an equation* environment (i.e. it has no equation number), and then the equation number is added using a \tag command. As well, a reference to the equation in the solution is added automatically. To make this work, inside a solution environment the equation environment requires an extra argument, which is the label of the equation from the questions.

With this in place, the code:

\begin{equation}
    2x=4
    \label{eq:one}
\end{equation}

\begin{solution}
  \begin{equation}{eq:one}% must give the ref to the question eq.
        x=2
    \end{equation}
\end{solution}

\begin{equation}
    3x=6
    \label{eq:two}
\end{equation}

Equations \ref{eq:one}, \ref{eq:onesol} and \ref{eq:two}.

produces:

enter image description here

Notice that the label for the equation in the solutions is the same as the label for the corresponding equation in the question with sol appended.

Here is the full code:

\documentclass{article}
\usepackage{amsmath}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{xcolor}
\usepackage{xparse}

\newif\ifsolution
\solutiontrue

\NewDocumentEnvironment{solution}{+b}{
  \ifsolution\color{red}
    % redefine the equation* environment
    \RenewDocumentEnvironment{equation}{m +b}{
      \begin{equation*}##2\tag{S\ref{##1}}
      \xdef\@currentlabel{S\noexpand\ref{##1}}% attach an S to the equation label
      \label{##1sol}% add the label
    }{\end{equation*}}
    #1
  \fi
}{}

\begin{document}
\begin{equation}
    2x=4
    \label{eq:one}
\end{equation}

\begin{solution}
  \begin{equation}{eq:one}
        x=2
    \end{equation}
\end{solution}

\begin{equation}
    3x=6
    \label{eq:two}
\end{equation}

Equations \ref{eq:one}, \ref{eq:onesol} and \ref{eq:two}.
\end{document}

Note that I have used the \NewDocumentEnvironment command from the xparse package, together with the +b option (which makes the body of the environment equal to #1...and with the \RenewDocumentEnvironment command above the body becomes #2, since #1 is the equation label), instead of the environ package.

One side effect of this is that you cannot have a labelled equation in the solutions unless it corresponds to an equation in the questions. With a little more effort it is possible to support this as well.

2

I am copying what I am using myself. It is based on this answer (at least I used it as a starting point). (At the very least I wanted to honorably mention this post. ;-) It does not precisely yield the output you want, but for a reason. Over the time I found that I want the thing work with hyperref and cleveref (so this answer is relevant), and wanted to be able to move the solutions to separate locations, such as the end of the chapter. This is what I got.

\documentclass[fleqn]{article}
\usepackage{environ}
\usepackage{amsthm}
\usepackage{etoolbox} 
\newtheoremstyle{exercise}% name
  {6pt}%      Space above
  {6pt}%      Space below
  {}%         Body font
  {}%         Indent amount (empty = no indent, \parindent = para indent)
  {\bfseries\boldmath}% Thm head font
  {}%        Punctuation after thm head
  {\newline}%     Space after thm head: " " = qnormal interword space;
        %       \newline = linebreak
  {\bignumber{#2} : #3}%         Thm head spec (can be left empty, meaning `normal')

\theoremstyle{exercise}

\newtheorem{Problem}{Problem}

\newtheoremstyle{solution}% name
  {3pt}%      Space above
  {3pt}%      Space below
  {\small}%         Body font
  {}%         Indent amount (empty = no indent, \parindent = para indent)
  {\bfseries\boldmath}% Thm head font
  {:}%        Punctuation after thm head
  {.3em}%     Space after thm head: " " = qnormal interword space;
        %       \newline = linebreak
  {Solution for exercise #3}%         Thm head spec (can be left empty, meaning `normal')

\theoremstyle{solution}
\newtheorem{solution}{Solution}

\makeatletter
\let\latex@theequation\theequation
\AtBeginEnvironment{Problem}{\setcounter{equationstore}{\value{equation}}%
\setcounter{equation}{\value{solequationstore}}%
\renewcommand{\theequation}{P\latex@theequation}%
\renewcommand{\theHequation}{P\latex@theequation}}
\AtBeginEnvironment{solution}{\setcounter{equationstore}{\value{equation}}%
\setcounter{equation}{\value{solequationstore}}%
\renewcommand{\theequation}{S\latex@theequation}%
\renewcommand{\theHequation}{S\latex@theequation}}
\AtEndEnvironment{Problem}{%
\setcounter{solequationstore}{\value{equation}}%
\setcounter{equation}{\value{equationstore}}%
}
\AtEndEnvironment{solution}{%
\setcounter{solequationstore}{\value{equation}}%
\setcounter{equation}{\value{equationstore}}%
}
\makeatother

\NewEnviron{Solution}[1][]{%
\ifkeepsol
\begin{solution}[#1]~%
\BODY
\end{solution}%
\fi
}

\usepackage{hyperref}
\usepackage{cleveref}
\newif\ifkeepsol
\keepsoltrue

\crefname{Problem}{problem}{problems}
\Crefname{Problem}{Problem}{Problems}
\newcounter{equationstore}
\newcounter{solequationstore}

\crefname{solution}{solution}{solutions}
\Crefname{solution}{Solution}{Solutions}


\begin{document}
\keepsolfalse\keepsoltrue
\begin{equation}
    2x=4
    \label{eq:one}
\end{equation}

\begin{Solution}[\ref{eq:one}]
    \begin{equation}
        x=2
        \label{eq:solone}
    \end{equation}
\end{Solution}

\begin{equation}
    3x=6
    \label{eq:two}
\end{equation}

\begin{Solution}[\ref{eq:two}]
    \begin{equation}
        x=2
        \label{eq:soltwo}
    \end{equation}
\end{Solution}

\begin{equation}
    3x=9
    \label{eq:three}
\end{equation}

\begin{Solution}[\ref{eq:three}]
    \begin{equation}
        x=3
        \label{eq:solthree}
    \end{equation}
\end{Solution}

\end{document}

enter image description here

You must log in to answer this question.

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