# Typeset saturation function

For the thesis that I'm writing I'm dealing a lot with input saturation, for which I would like to define a saturation function. To do so, I would like to have a symbol that represents saturation, as well as a way to define its upper and lower bounds, see the picture below. From this question I managed to find a way to implement a decent saturation symbol, used in the picture above. Credits go to Steven B. Segletes. However, I would like to be able to add the upper and lower bounds in a command, like \sat_{-5}^{10}, or simply \sat{-5}{10}. Since I'm not at all familiar with Tikz, I have no idea how to properly add these bounds (the picture above was made in Paint). Also, the bounds should have a smaller font, since now they're too large. What would be entirely completely useful is if the saturation symbol could be lowered a bit as well such that it's vertically centered, and if it could reshape like the \sum command, see the picture below, where the left version was created using math mode and the right was made in an align environment. Is there anyone out there skilled enough and kind enough to help me out here?

The saturation symbol is created in a .tex file saturation.tex with content

\documentclass[border=0mm]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\coordinate (A) at (-.7,-.6);
\coordinate (B) at (-.2,-.6);
\coordinate (C) at (+.2,+.6);
\coordinate (D) at (+.7,+.6);
\draw [black, line width=3pt] (A)--(B)--(C)--(D);
\end{tikzpicture}
\end{document}


after which one creates the command

\newcommand\sat{\ThisStyle{\kern.5\LMpt\includegraphics[height=2\LMex]{saturation}\kern.5\LMpt}}


to be able to type \sat. Here is an MWE:

\documentclass{article}
\usepackage{scalerel,graphicx}
\newcommand\sat{\ThisStyle{%
\kern.5\LMpt\includegraphics[height=2\LMex]{saturation}\kern.5\LMpt}}
\begin{document}
\centering

\sat

\end{document}


A solution with tikz.

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

\makeatletter
\newif\ifsat@limits
\sbox\z@{$\sum$}
\sbox\@ne{$\displaystyle\sum$}
\tikzset{sat/.search also=/tikz}
\def\satset#1{\tikzset{sat/.cd,#1}}
\satset{
height/.store in=\sat@ht,
is limits/.is if=sat@limits,
nodisplay/.code={
\@tempdima=\dimexpr\dp\z@+\ht\z@
\pgfkeysalso{height=\@tempdima}
},
display/.code={
\@tempdimb=\dimexpr\dp\@ne+\ht\@ne
\pgfkeysalso{height=\@tempdimb}
},
nolimits/.style={is limits=false},
limits/.style={is limits=true},
}
\NewDocumentCommand {\satpic} { O{} m m m } {
\begin{tikzpicture}[baseline=0.5\dp\z@-0.5\ht\z@, x=1ex, y=1ex, sat/.cd, nolimits, nodisplay, #1]
\coordinate (A) at (-\sat@ht/2,-\sat@ht/2);
\coordinate (B) at (-\sat@ht/7,-\sat@ht/2);
\coordinate (C) at (\sat@ht/7,\sat@ht/2);
\coordinate (D) at (\sat@ht/2,\sat@ht/2);
\draw [black, line width=.6pt, #2] (A)--(B)--(C)--(D);
\ifsat@limits
\IfValueT {#3} {
\node [below=1.3pt, inner sep=0pt] at (current bounding box.south) {$#3$};
}
\IfValueT {#4} {
\node [above=1.3pt, inner sep=0pt] at (current bounding box.north) {$#4$};
}
\else
\IfValueT {#3} {
\node [anchor=west, inner sep=0pt, xshift=.3ex] at (B) {$#3$};
}
\IfValueT {#4} {
\node [anchor=east, inner sep=0pt, xshift=-.3ex] at (C) {$#4$};
}
\fi
\end{tikzpicture}
}
\makeatother
\NewDocumentCommand {\sat} { E{!@_^}{{}{}} } {
\mathchoice
{\satpic[display, limits, #1]{#2}{#3}{#4}}
{\satpic[nodisplay, nolimits, #1]{#2}{#3}{#4}}
{\satpic[nodisplay, nolimits, #1]{#2}{#3}{#4}}
{\satpic[nodisplay, nolimits, #1]{#2}{#3}{#4}}
}

\begin{document}
Saturation A: $\sat_{-5}^{10}$ and $\sat!{limits}_{123}^{456}$

Saturation B:
$\sat@{red}_{10}^{200} \sat@{line width=1pt}_{40000}$

\end{document} • I like how your solution is able to deal with putting the bounds on top and below the symbol, but it seems I cannot implement your solution in my .tex file. When I compile, the symbol simply does not show. Since I'm a half-noob with my self-defined packages, it might well be that something is conflicting, but I have no idea how to find out. Any ideas? Jun 27, 2020 at 8:52
• I recompile it in overleaf with no error. You can open another question and provide an example and also the information about the compiler and the error. Jun 27, 2020 at 10:09

Using a technique of egreg at Define macro that scans ahead for super- and/or subscript, "absorbs" them and moves their argument, I let xparse help with redefining ^ and _ to handle the kerning.

This MWE uses the saturation.pdf supplied by the OP's code.

\documentclass{article}
\usepackage{xparse,mathtools}

\NewDocumentCommand{\sat}{e{^_}}{%
\mathop{\IfValueT{#1}{\phantom{\scriptscriptstyle#1}\mathchoice
{\kern-5pt}{\kern-5pt}{\kern-3pt}{\kern-2pt}}%
\rawsat\mathchoice
{^{\IfValueT{#1}{\mathllap{\scriptscriptstyle#1\mkern14mu}}}%
_{\IfValueT{#2}{\scriptscriptstyle\mkern-13mu#2}}}%
{^{\IfValueT{#1}{\mathllap{\scriptscriptstyle#1\mkern14mu\strut}}}%
_{\IfValueT{#2}{\scriptscriptstyle\mkern-13mu#2}}}%
{^{\IfValueT{#1}{\mathllap{\scriptscriptstyle#1\mkern11mu\mathstrut}}}%
_{\IfValueT{#2}{\scriptscriptstyle\mkern-9mu#2}}}%
{^{\IfValueT{#1}{\mathllap{\scriptscriptstyle#1\mkern9mu}}}%
_{\IfValueT{#2}{\scriptscriptstyle\mkern-6mu#2}}}%
}}
\usepackage{scalerel,graphicx}
\newcommand\rawsat{\ThisStyle{\kern.5\LMpt
\includegraphics[height=2\LMex]{saturation}\kern.5\LMpt}}

\begin{document}
$x=\sat_{-5}^{10} u(t)$

$x=\sat_{-5}^{10} u(t)$

$\scriptscriptstyle x= \sat_{-5}^{10} u(t)$
\end{document} And just to prove I have resolved the kerning even as the superscript width changes, here is the same example with a wider superscript: Here is a version that does not require an external image file to be dragged around, but instead saves the tikz image of it at initialization.

\documentclass{article}
\usepackage{xparse,mathtools,stackengine,tikz,scalerel}
\NewDocumentCommand{\sat}{e{^_}}{%
\mathop{\IfValueT{#1}{\phantom{\scriptscriptstyle#1}\mathchoice
{\kern-5pt}{\kern-5pt}{\kern-3pt}{\kern-2pt}}%
\rawsat\mathchoice
{^{\IfValueT{#1}{\mathllap{\scriptscriptstyle#1\mkern15mu}}}%
_{\IfValueT{#2}{\scriptscriptstyle\mkern-14mu#2}}}%
{^{\IfValueT{#1}{\mathllap{\scriptscriptstyle#1\mkern15mu\strut}}}%
_{\IfValueT{#2}{\scriptscriptstyle\mkern-14mu#2}}}%
{^{\IfValueT{#1}{\mathllap{\scriptscriptstyle#1\mkern12mu\mathstrut}}}%
_{\IfValueT{#2}{\scriptscriptstyle\mkern-10mu#2}}}%
{^{\IfValueT{#1}{\mathllap{\scriptscriptstyle#1\mkern10mu}}}%
_{\IfValueT{#2}{\scriptscriptstyle\mkern-7mu#2}}}%
}}
\newcommand\rawsat{\ThisStyle{\kern.5\LMpt
\scaleto{\rawsatimg}{2\LMex}\kern.5\LMpt}}
\savestack\rawsatimg{%
\begin{tikzpicture}
\coordinate (A) at (-.7,-.6);
\coordinate (B) at (-.2,-.6);
\coordinate (C) at (+.2,+.6);
\coordinate (D) at (+.7,+.6);
\draw [black, line width=3pt] (A)--(B)--(C)--(D);
\end{tikzpicture}%
}
\begin{document}
$x=\sat_{-5}^{10} u(t)$

$x=\sat_{-5}^{10} u(t)$

$\scriptscriptstyle x= \sat_{-5}^{10} u(t)$
\end{document}

• Very well done! Although I'm actually not so much a fan of having to "drag around" the saturation.pdf file to new documents, is there an easy way to avoid this? And it seems the bounds' font size does not decrease when decreasing the overall font size, is that correct? Jun 27, 2020 at 8:57
• @StevenHorstink As to the font size, it is always done in \scriptscriptstyle. For OT1 font encoding of the Computer Modern font, there is a lower limit ( I think around 5 pt) for the font size. Try loading the lmodern package (reworks the Computer Modern Font as a T1 scalable font and calls it latin modern) and see if that resolves the font size issue. Jun 27, 2020 at 19:59