Elementary functions 2
Contents
Elementary functions 2#
Now that we know what an inverse function is, let us think about the inverse functions of elementary functions we explored in a previous notebook.
Roots#
import numpy as np
import matplotlib.pyplot as plt
x1 = np.linspace(0, 10, 101)
x2 = np.linspace(-10, 10, 101)
fig, ax = plt.subplots(1, 2, figsize=(10, 5))
ax[0].plot(x1, x1**2, label=r'$G(x^2)$')
ax[0].plot(x1, np.sqrt(x1), label=r'$G(x^{1/2})$')
ax[0].set_xlim(0, 10)
ax[0].set_ylim(0, 10)
ax[1].plot(x2, x2**3, label=r'$G(x^3)$')
ax[1].plot(x2, np.cbrt(x2), label=r'$G(x^{1/3})$')
ax[1].set_ylim(-10, 10)
ax[1].set_yticks([-10, -5, 5, 10])
for i in range(2):
ax[i].plot(x2, x2, '--k', alpha=0.2)
ax[i].text(7.5, 7, 'y=x', alpha=0.5)
ax[i].set_aspect('equal')
ax[i].spines['left'].set_position('zero')
ax[i].spines['bottom'].set_position('zero')
ax[i].spines['right'].set_visible(False)
ax[i].spines['top'].set_visible(False)
ax[i].legend(loc='best')
plt.show()
Logarithmic functions#
The exponential function \(f: \mathbb{R} \to (0, + \infty), f(x)=a^x\) is an injection because it is strictly increasing and it is a surjection because its image is \(f(\mathbb{R}) = (0, + \infty)\). Therefore, it is a bijection and the inverse function \(f^{-1} : (0, + \infty) \to \mathbb{R}\) exists.
We denote this inverse function as \(\log_a x := f^{-1}(x)\) and we call it the logarithm with base a.
We call a logarithm with base \(e\) the natural logarithm and define it as:
Properties
Domain: \((0, + \infty)\), range: \(\mathbb{R}\)
For all \(x, y \in (0, + \infty), a, b, c \in (0, 1) \cup (1, + \infty)\):
Since the exponential function maps a sum to a product, i.e. \(a^{x+y} = a^x a^y\), the logarithmic function maps a product to a sum:
Change of base:
x1 = np.linspace(-10, 10, 201)
x2 = np.linspace(0.001, 10, 301)
fig, ax = plt.subplots(1, 2, figsize=(10, 5))
ax[0].plot(x1, 0.5**x1, label=r'$0.5^x$')
ax[0].plot(x2, np.log(x2)/np.log(0.5), label=r'$\log_{0.5}x$')
ax[0].set_title('0 < a < 1')
ax[1].plot(x1, np.exp(x1), label=r'$e^x$')
ax[1].plot(x2, np.log(x2), label=r'$\ln x$')
ax[1].set_title('a > 1')
for i in range(2):
ax[i].plot(x1, x1, '--k', alpha=0.2)
ax[i].set_aspect('equal')
ax[i].spines['left'].set_position('zero')
ax[i].spines['bottom'].set_position('zero')
ax[i].spines['right'].set_visible(False)
ax[i].spines['top'].set_visible(False)
ax[i].legend(loc='upper right')
ax[i].set_ylim(-4, 10)
ax[i].set_xlim(-4, 10)
Inverse trigonometric functions#
Inverse trigonometric functions are also called arcus functions so we denote them with the prefix \(\text{arc-}\), e.g. \(\arcsin x\). They are also often denoted as \(\sin^{-1} x\).
Periodic functions are not injections so they do not have inverses. Therefore, we need to restrict them to parts of their natural domain where they are strictly monotonic - here they are injections.
Then trigonometric functions with the following domain restrictions are bijections:
so we can define their inverse functions:
# for demonstration purposes will suppress warnings when plotting
import warnings; warnings.simplefilter('ignore')
ax = [0, 0, 0]
fig = plt.figure(constrained_layout=True, figsize=(10, 8))
gs = plt.GridSpec(2, 2, width_ratios=[1.3, 3], height_ratios=[1, 1])
ax[0] = fig.add_subplot(gs[:, 0])
ax[1] = fig.add_subplot(gs[0, 1])
ax[2] = fig.add_subplot(gs[1, 1])
x = np.linspace(-1, 1, 101)
ax[0].plot(x, np.arcsin(x), label=r'$\arcsin x$')
ax[0].plot(x, np.arccos(x), label=r'$\arccos x$')
# will include 0 to separate lines joining
x = np.concatenate((np.linspace(-5, -1, 100), [0], np.linspace(1, 5, 100)))
ax[1].plot(x, np.arcsin(1/x), label=r'arccsc $x$')
ax[1].plot(x, np.arccos(1/x), label=r'arcsec $x$')
x = np.linspace(-10, 10, 201)
ax[2].plot(x, np.arctan(x), label=r'$\arctan x$')
ax[2].plot(x, np.pi/2 - np.arctan(x), label=r'arccot $x$')
for i in range(3):
ax[i].spines['left'].set_position('zero')
ax[i].spines['bottom'].set_position('zero')
ax[i].spines['right'].set_visible(False)
ax[i].spines['top'].set_visible(False)
ax[i].legend(loc='best')
ax[i].set_yticks(np.pi * np.array([-2, -1.5, -1, -0.5, 0, 0.5, 1, 1.5, 2]))
ax[i].set_yticklabels(['$-2\pi $', r'$-\frac{3}{2} \pi $', r'$-\pi$',
r'$-\frac{1}{2}\pi$', '0', r'$\frac{1}{2}\pi$',
r'$\pi$', r'$\frac{3}{2}\pi$', r'$2\pi$'])
ax[0].set_xlim(-1.2, 1.2)
ax[0].set_ylim(-1.8, 3.3)
ax[1].set_xlim(-5, 5)
ax[1].set_ylim(-1.7, 3.3)
ax[2].set_ylim(-1.7, 3.3)
plt.show()
Properties
For a more complete list of properties and their visualisation, visit Wikipedia. Here we will name a few.
Complementary angles:
Reciprocal arguments:
Inverse hyperbolic functions#
Inverse hyperbolic functions are also called area functions so we denote them with the prefix \(\text{ar-}\), e.g. \(\text{arsinh} x\). They are also often denoted as \(\sinh^{-1} x\), for example.
Hyperbolic functions
are bijections, so we can define their inverses:
where
Derivation of arcosh \(x\)
For demonstration purposes let us derive the above equation for \(\text{arcosh} x\). Recall that \(\cosh x = \frac{e^x + e^{-x}}{2}\). Let that equal some \(y\), so that \(\frac{e^x + e^{-x}}{2} = y\) or \(e^x + e^{-x} - 2y = 0\). Now let \(u = e^x\) and multiply both sides by \(u\). We get:
which is a simple quadratic equation with solutions:
But since \(u = e^x > 0\) the only possible solution is
We take the natural logarithm of both sides:
fig = plt.figure(figsize=(10, 8))
ax = plt.gca()
x = np.linspace(-4, 4, 201)
plt.plot(x, np.log(x + np.sqrt(x**2 + 1)), label=r'arsinh $x$')
x = np.linspace(1, 4, 101)
plt.plot(x, np.log(x + np.sqrt(x**2 - 1)), label=r'arcosh $x$')
x = np.linspace(-0.999, 0.999, 200)
plt.plot(x, np.log((1+x)/(1-x)) / 2, label=r'artanh $x$')
# will include 0 to avoid joining lines, this returns an error
x = np.concatenate((np.linspace(-4, -1.001, 100), [0], np.linspace(1.001, 4, 100)))
plt.plot(x, np.log((x+1)/(x-1)) / 2, label=r'artanh $x$')
ax.spines['left'].set_position('zero')
ax.spines['bottom'].set_position('zero')
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.set_aspect('equal')
ax.legend(loc='best')
plt.show()