Understanding Sign

October 05, 2021 | 8 minutes, 27 seconds


The sign function isn't a function which is commonly agreed upon. In fact, when we say sign function, we're referring to any function which satisfies this main relation over some subset of \(\mathbb{R}\):

\[ \left|x\right|=x\operatorname{sgn}(x)\]

This could be any number of function, and the reason is that at \(0\), this relation is satisfied irrespective of the value of the sign function. There are, however, a few conventions, much like with the unit step function, which are used in fourier transforms. The adopted convention, depending on circumstance, is one of the following:

  1. The sign function remains undefined at \(0\), or,
  2. the sign function is either \(1\) or \(-1\) at \(0\) (usually the former), or more commonly,
  3. the sign function is \(0\) at \(0\).

The convention I've personally adopted and find the most useful is the third. Not only does it have a more intuitive reason for its definition (namely, 0 is neither positive nor negative and therefore has 'no', or 0, sign), but it simplifies calculation when working with nonelementary functions, like sign itself.

Furthermore, when we attempt fit a specific non-piecewise definition to sign, depending on definition we can:

  1. Use the form of \(\frac{|x|}{x}\) for the first definition,
  2. Note the first and second definitions can be written in terms of the third,
  3. Find an arbitrary form for the third function.


We're going to refer to the first definition of signum as pseudosignum. This is namely because even though it's an equally valid definition of signum, it can be written in terms of elementary functions. Over \(\mathbb{R}\setminus\left\{0\right\}\), pseudosignum is in fact continuous and elementary.

Furthermore, the second and third definitions can be written piecewise in terms of pseudosignum:

\[ \operatorname{sgn}(x)=\begin{cases}\frac{|x|}{x} & x\neq 0\\a & x=0\end{cases}\]

For \(a\in\left\{-1,0,1\right\}\). This, however, isn't a very useful definition and moreover encourages nesting of piecewise objects (which, while not inherently bad, is unnecessary here).

Piecewise-linear Approximation of Sign

Turns out piecewise-linearity is a thing. The more you know (and less you care). I digress; from here on out, we'll make use of the third definition of sign/signum.

Suppose we want a linear approximation near zero of sign; the way to do this is to introduce a variable called \(\delta\approx0\) such that we have a line that more and more approaches zero. Moreover, we require a positive value so we'll take the absolute value of \(\delta\) when using it. Why this is done will become apparent later:

\[ f(x)=\begin{cases} 1 & x=|\delta|\\ 0 & x=0\\ -1 & x=-|\delta| \end{cases}=\frac{x}{|\delta|}\]

Outside of this region, we wish to map the remaining values of the signum function. So we'll let our approximation be:

\[ \operatorname{sgn}(x)\approx\begin{cases} 1 & x\geq|\delta|\\ \frac{x}{|\delta|} & -|\delta|\leq x\leq|\delta|\\ -1 & x\leq-|\delta| \end{cases}\]

We can rewrite this using a single expression using the sticking formula previously derived:

\[ \operatorname{sgn}(x)\approx\frac{1}{|\delta|}\max(\min(x,|\delta|),-|\delta|)\]

And some quick rewriting by the properties of \(\max\) and \(\min\) (as previously explored in the same sticking formula post) give us:

\[ \operatorname{sgn}(x)\approx\frac{1}{2}\left(\left|\frac{x}{|\delta|}+1\right|-\left|\frac{x}{|\delta|}-1\right|\right)\]

More formally, we write this as:

\[ \operatorname{sgn}(x)=\lim_{\delta\to0}{\frac{1}{2}\left(\left|\frac{x}{|\delta|}+1\right|-\left|\frac{x}{|\delta|}-1\right|\right)}\]

Piecewise Hyperbolic Approximation

Instead of relying on an approximation that behaves differently near zero, we can instead consider the sign function as a piecewise function consisting of two hyperbolas; more accurately, two transformations of hyperbolas. We'll consider constructing our function in terms of the branches separately. The motivation for this is that we want to approximate roughly the function, and we note that hyperbolas are bounded functions on their branches. Furthermore, we notice that the asymptotes of these hyperbolas would lie outside of their piece's domains, ergo permitting a continuous function to be created.

For \(x\geq 0\), or the rightmost branch, notice that any hyperbola that is less than or equal to \(\operatorname{sgn}(x)\) will be bounded above by \(1\) and must be \(0\) at \(0\). This isn't a hyperbola; so we instead consider the contrary where our hyperbola is bounded below \(0\) and is \(1\) at \(0\).

We therefore consider:

\[ f(x)=\frac{1}{x-a}\]

For some value of \(a\). A quick substitution at \(0\) tells us \(a=-1\). From there, we can reconsider our original hyperbola (bounded above by \(1\)) which gives us:

\[ F(x)=1-\frac{1}{x+1}=\frac{x}{x+1}\]

Now, for \(x\leq 0\), or the leftmost branch, notice that any hyperbola that is greater than or equal to \(\operatorname{sgn}(x)\) will be bounded below by \(-1\) and must be \(0\) at \(0\). We'll also note that we'll need to have a branch of the hyperbola that's positive; namely \(x\) is negative so we'll need \(-x\). Like last time, we'll consider the hyperbola without transformation.

Hence we consider:

\[ g(x)=\frac{1}{a-x}\]

Noting that \(0\), this should be \(1\); \(a=1\) and then translating one unit down we get:

\[ G(x)=\frac{1}{1-x}-1=\frac{x}{1-x}\]

From here we can combine the equations:

\[ h(x)=\begin{cases} \frac{x}{x+1} & x\geq 0\\ \frac{x}{1-x} & x\leq 0 \end{cases}=\frac{x}{|x|+1}\approx\operatorname{sgn}(x)\]

It here here that we note that \(|x|\) can be 'replaced' with other even functions which are not necessarily piecewise, although worse approximations will be given.

Here Comes the Floor

Let \(\lambda:\mathbb{R}\to\mathbb{R}^{+}\) be a non-negative continuous non-reciprocal function ("choose a nice function Jimmy" -- "1/(|x|+1), Bob?" -- "no, Jimmy"). Then we can approximate the sign function using:

\[ \operatorname{sgn}(x)\approx\frac{x}{\lambda(x)+1}\]

Namely, \(\lambda(x)\geq0\implies0\leq\frac{1}{\lambda(x)+1}\leq 1\). Namely, for \(x>0\),

\[ {0}\leq\frac{x}{\lambda(x)+1}\leq1\]

and for \(x<0\):

\[ -1\leq\frac{x}{\lambda(x)+1}\leq0\]

Now, given that our approximation is \(0\iff x=0\), we notice that:

\[ \left\lfloor\frac{x}{\lambda(x)+1}\right\rfloor=\begin{cases} 0 & x>0\\ 0 & x=0\\ -1 & x<0 \end{cases}\]

\[ \left\lceil\frac{x}{\lambda(x)+1}\right\rceil=\begin{cases} 1 & x>0\\ 0 & x=0\\ 0 & x<0 \end{cases}\]

And we can just add those to get:

\[ \operatorname{sgn}(x)=\left\lceil\frac{x}{\lambda(x)+1}\right\rceil+\left\lfloor\frac{x}{\lambda(x)+1}\right\rfloor\]

Now, one can attempt to do this purely using piecewise. But as someone who is insanely dedicated to this stuff, I have not found a single way to do this without reverse engineering this formula.

Some Properties

One of the posts I made mostly asking a question and subsequently solving it goes briefly over some properties of the sign function.

Namely given an odd function \(f:A\to\mathbb{R},\ A=-A\),

\[ f(x)\operatorname{sgn}(x)=f(|x|)\]


\[ f(x)\operatorname{sgn}(x-a)=f(|x-a|+a\operatorname{sgn}(x-a))\]


\[ f(x-a)\operatorname{sgn}(x)=f(|x|-a\operatorname{sgn}(x))\]

Likewise, if a function can be decomposed into even and odd components, these identities can be applied to the odd components. There are further interactions with other piecewise functions like the absolute value, i.e. \(x=|x|\operatorname{sgn}(x)\).

As has been previously demonstrated, the presence of the sign function does not imply the relevant function or expression is non-elementary.

Notes on Sign

Signum/sign is one of the fundamental piecewise functions on \(\mathbb{R}\). In fact, the combination of functions and relations over \(\mathbb{R}\) and \(\mathbb{R}^2\) are made possible by signum, albeit mostly indirectly. As with my first post on this website though, it's fundamental to creating a relation that has no regard for continuity.

Intuitively, signum also gives us the ability to quickly match signs of numbers to the numbers themselves. In game development especially, sign and vectors composed of the signs of vector components are used. Sign can be computed efficiently and branchlessly depending on its implementation.

The signum function is also related to the unit step function - both can be composed in terms of each other. Notably, we also saw a version of the unit step function is the last form of sign using floor and ceiling functions.

Ultimately though, how we formulate sign is irrelevant. Very very rarely do we use any formulas of sign other than the one given piecewise, and this is just one major example of how a single expression may not yield anything nice, even if the mathematics behind it is (namely, developing approximations to sign to derive sign itself).

Most of my work goes incidentally into continuous and so signum very often goes overlooked. Over the coming months, however, I'll come back to it to see if there's much more I can work with and produce using it.