I defined a command for probability distributions, for example:

\usepackage{amsmath}
\usepackage{xstring}

\DeclarePairedDelimiterX{\RoundBrackets}[1]{(}{)}{#1}
\newcommand{\p}[1]{\RoundBrackets{\StrSubstitute[0]{#1}{|}{\mid}}}

This can be used as \p{x|y}. However, I would like to use it as \p(x|y). Is there some TeX magic to make that possible?

  • Please state your question clearly and give a minimal working example! – Kuttens Aug 19 at 15:07
up vote 15 down vote accepted

xparse makes defining a macro with a different kind of mandatory argument delimiter requirement fairly easy. Below, r() does just that.

enter image description here

\documentclass{article}

\usepackage{mathtools,xparse,etoolbox}

\DeclarePairedDelimiterX{\RoundBrackets}[1]{(}{)}{#1}

\NewDocumentCommand{\pr}{ r() }{%
  \def\prArg{#1}% Capture argument in macro
  \patchcmd{\prArg}{|}{\mid}{}{}% Replace | with \mid
  \RoundBrackets{\prArg}% Set argument in round brackets
}

\begin{document}

$\pr(a|b)$

\end{document}

etoolbox is used to replace | with \mid.

  • Great, thank you! This also works with mathematical symbols inside the probability distribution that I had problems with earlier. Is there any reason why defining my probability distributions like this would be discouraged? – danijar Aug 19 at 16:11
  • How would I modify this to pass the symbol in front of the parentheses (p, q , p_\theta, etc) into the command? I know I can just write it before the command but it would be easier to see that it belongs together if it were an argument. – danijar Aug 19 at 16:22
  • 3
    @danijar: Look at this example. – Werner Aug 19 at 16:29

This also supports the usual options for \DeclarePairedDelimiter:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\usepackage{mleftright}

\ExplSyntaxOn

\NewDocumentCommand{\p}{sO{}r()}
 {
  \IfBooleanTF{#1}
   {
    \mleft(
    \danijar_middlevert:
    #3
    \mright)
   }
   {
    \group_begin:
    \danijar_sizedvert:n {#2}
    \mathopen{#2(}
    #3
    \mathclose{#2)}
    \group_end:
   }
 }

\cs_new_protected:Nn \danijar_middlevert:
 {
  \char_set_active_eq:NN | \__danijar_middle:
  \mathcode`|="8000 \scan_stop:
 }
\cs_new_protected:Nn \__danijar_middle:
 {
  \;\middle\vert\;
 }

\cs_new_protected:Nn \danijar_sizedvert:n
 {
  \tl_set:Nn \l__danijar_size_tl { #1 }
  \char_set_active_eq:NN | \__danijar_mid:
  \mathcode`|="8000 \scan_stop:
 }
\cs_new_protected:Nn \__danijar_mid:
 {
  \mathrel{\l__danijar_size_tl\vert}
 }

\ExplSyntaxOff

\begin{document}

$\p(x) \neq \p(x|y)$
\qquad
$\p[\big](x) \neq \p[\big](x|y)$
\qquad
$\p[\Big](x) \neq \p[\Big](x|y)$
\qquad
$\p*(\dfrac{a}{b})\neq \p*(\dfrac{a}{b}|y)$

\end{document}

enter image description here

The idea is to locally make | math active, with an appropriate definition, which is \;\middle\vert\; when automatic sizing is declared, or \mathrel{<size>\vert} when a manual size is selected.

If you want to add the “P” for “probability”:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}
\usepackage{mleftright}

\ExplSyntaxOn

\NewDocumentCommand{\p}{sO{}r()}
 {
  \operatorname{P}
  \IfBooleanTF{#1}
   {
    \mleft(
    \danijar_middlevert:
    #3
    \mright)
   }
   {
    \group_begin:
    \danijar_sizedvert:n {#2}
    \mathopen{#2(}
    #3
    \mathclose{#2)}
    \group_end:
   }
 }

\cs_new_protected:Nn \danijar_middlevert:
 {
  \char_set_active_eq:NN | \__danijar_middle:
  \mathcode`|="8000 \scan_stop:
 }
\cs_new_protected:Nn \__danijar_middle:
 {
  \;\middle\vert\;
 }

\cs_new_protected:Nn \danijar_sizedvert:n
 {
  \tl_set:Nn \l__danijar_size_tl { #1 }
  \char_set_active_eq:NN | \__danijar_mid:
  \mathcode`|="8000 \scan_stop:
 }
\cs_new_protected:Nn \__danijar_mid:
 {
  \mathrel{\l__danijar_size_tl\vert}
 }

\ExplSyntaxOff

\begin{document}

$\p(x) \neq \p(x|y)$

$\p[\big](x) \neq \p[\big](x|y)$

$\p[\Big](x) \neq \p[\Big](x|y)$

$\p*(\dfrac{a}{b})\neq \p*(\dfrac{a}{b}|y)$

\end{document}

enter image description here

  • Wow, that's amazing. It's a bit more than what I need right now, but if I need symbols of vastly different height inside the parentheses I can go back here and replace the macro with this one. – danijar Aug 19 at 16:24

Probably @Werner's answer is the way to go (robust and easily modified), but in this case, plain TeX also seems to work:

\documentclass{article}

\def\pr(#1|#2){(#1 \mid #2)}

\begin{document}

$\pr(a|b)$
$\pr(a_r|b^2)$

\end{document}

resulting output

  • 2
    This makes the use of | also mandatory (for conditional probability), which might not be the case in general. You'll have to update the definition of \pr to accommodate for that conditional use. – Werner Aug 19 at 15:40

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.