Lab Sheet 3¶

In [1]:
from header import *

Exercise 1.1

Here we plot $y=2e^{-t}\sin(30t)$ against $t$. This oscillates and dies away, like the motion of a guitar string after it has been plucked.

In [2]:
ts = np.linspace(-1,5,1000)         # array of values of t
ys = 2 * np.exp(-ts)*np.sin(30*ts)  # corresponding values of y
fig = go.Figure()
fig.update_layout(width=1000,height=400)
move_legend(fig, 0.5)
fig.add_trace(go.Scatter(x=ts, y=ys, mode='lines', line=dict(color='blue'), name=r'$2e^{-t} \sin(30t)$', showlegend=True))

Here we plot $y=2\sin(20t)+3\sin(21t)$ against $t$. This is a sum of two signals of slightly different frequencies; musicians will be familiar with the resulting effect. The combined signal oscillates rapidly (at the same frequency as $\sin(20.5t)$), with the size of the oscillations varying more slowly (like $\cos(t)$).

In [3]:
ts = np.linspace(0,30,1000)
ys = 2 * np.sin(20*ts) + 3 * np.sin(21*ts)
fig = go.Figure()
fig.update_layout(
 width=1000, 
 height=400, 
 yaxis_range=[-5,7]
)
move_legend(fig, 0.5)
fig.add_trace(go.Scatter(x=ts, y=ys, mode='lines', line=dict(color='blue'), name=r'$2\sin(20t)+3\sin(31t)$', showlegend=True))

Here we plot $y=\sin(x)+\sin(3x)/3+\sin(5x)/5+\sin(7x)/7$ against $x$. Half the time this wiggles around near $y = 0.8$, and half the time it wiggles around near $y = -0.8$. It jumps quite rapidly between the two levels, and the jumps occur at multiples of $\pi$.

In [4]:
xs = np.linspace(0,20,1000)
ys = np.sin(xs) + np.sin(3*xs)/3 + np.sin(5*xs)/5 + np.sin(7*xs)/7
fig = go.Figure()
fig.update_layout(
 width=1000, 
 height=400, 
 yaxis_range=[-1.1,1.4]
)
move_legend(fig, 0.5)
use_pi_ticks(fig, 0, 6)
fig.add_trace(go.Scatter(x=xs, y=ys, mode='lines', line=dict(color='blue'), name=r'$y=\sin(x)+\sin(3x)/3+\sin(5x)/5+\sin(7x)/7$', showlegend=True))

Here we plot $y=\cos(\pi x^2)$ against $x$. The function oscillates between $-1$ and $1$, with the oscillations becoming more and more rapid as the absolute value of $x$ increases.

In [5]:
xs = np.linspace(-5,5,1000)
ys = np.cos(np.pi * xs**2)
fig = go.Figure()
fig.update_layout(width=1000, height=400, yaxis_range=[-1.2,1.5])
move_legend(fig, 0.5)
fig.add_trace(go.Scatter(x=xs, y=ys, mode='lines', line=dict(color='blue'), name=r'$\cos(\pi x^2)$', showlegend=True))

Exercise 1.2

We now investigate the function $f(x)=(x^3-x)(x^2-4/9)(x^2-1/9)$.

In [6]:
x = sp.symbols('x')
f = (x**3 - x) * (x**2 - sp.Rational(4,9)) * (x**2 - sp.Rational(1,9))
display(f)
f1 = sp.lambdify(x, f, 'numpy')
$\displaystyle \left(x^{2} - \frac{4}{9}\right) \left(x^{2} - \frac{1}{9}\right) \left(x^{3} - x\right)$

The graph of $f(x)$ is quite flat and close to zero between $x=-1$ and $x=1$, crossing the $x$-axis seven times, at $x=-1,-\frac{2}{3},-\frac{1}{3},0,\frac{1}{3},\frac{2}{3}$ and $1$. The function increases rapidly towards $\infty$ for $x>1$, and drops rapidly towards $-\infty$ fo $x<-1$.

The rate of growth is similar to $x^7$, and in fact $f(x)$ is indistinguishable from $x^7$ when $x$ is reasonably large.

In [7]:
fig = make_subplots(rows=1, cols=3)
fig.update_layout(height=600, width=1000, showlegend=True)

xs = np.linspace(-2,2,1000)
ys = f1(xs)
fig.add_trace(go.Scatter(x=xs, y=ys, mode='lines', name=r'$f(x)$', line=dict(color='blue')), row=1, col=1)
fig.update_yaxes(range=[-1,1], row=1, col=1) 

xs = np.linspace(-3,3,1000)
ys = f1(xs)
fig.add_trace(go.Scatter(x=xs, y=ys, mode='lines', line=dict(color='blue'), showlegend=False), row=1, col=2)
fig.add_trace(go.Scatter(x=xs, y=xs**7, mode='lines', name=r'$x^7$', line=dict(color='red')), row=1, col=2)
fig.update_yaxes(range=[-500,500], row=1, col=2) 

xs = np.linspace(-7,7,1000)
ys = f1(xs)
fig.add_trace(go.Scatter(x=xs, y=ys, mode='lines', line=dict(color='blue'), showlegend=False), row=1, col=3)
fig.add_trace(go.Scatter(x=xs, y=xs**7, mode='lines', line=dict(color='red'), showlegend=False), row=1, col=3)
fig.update_yaxes(range=[-4e5,4e5], row=1, col=3) 

fig.show()

To see the reason for this, just expand out $f(x)$. The leading term is $x^7$, and the remaining terms are multiples of $x^5$ or lower, so they are much smaller than $x^7$ when $x$ is large.

In [8]:
sp.expand(f)
Out[8]:
$\displaystyle x^{7} - \frac{14 x^{5}}{9} + \frac{49 x^{3}}{81} - \frac{4 x}{81}$
In [9]:
del x, f, f1, xs, ys

Exercise 1.3

Here we investigate the function $g(x)=\frac{2x-3}{3x-4}$.

In [10]:
x, y = sp.symbols('x y')
g = lambda x: (2 * x - 3)/(3*x - 4)
display(Latex("$g(x) = " + sp.latex(g(x)) + "$"))
g1 = sp.lambdify(x, g(x), 'numpy')
$g(x) = \frac{2 x - 3}{3 x - 4}$
In [11]:
xs = np.linspace(-10,10,2000)
ys = g1(xs)
fig = go.Figure()
fig.update_layout(width=800, height=600, yaxis_range=[-10,10])
move_legend(fig, 0.7)
# plot the part of the graph where x < 4/3
fig.add_trace(go.Scatter(x=xs[xs<4/3], y=ys[xs<4/3], mode='lines', line=dict(color='blue'), name=r'$g(x)$', showlegend=True))
#plt.plot(xs[xs>4/3], ys[xs>4/3],'b-')     # plot the part of the graph where x > 4/3
fig.add_trace(go.Scatter(x=xs[xs>4/3], y=ys[xs>4/3], mode='lines', line=dict(color='blue'), showlegend=False))
# horizontal line at y=2/3
fig.add_hline(y=2/3, line=dict(color='red', dash='dash'), name=r'$y=\frac{2}{3}$')
# vertical line at x=4/3
fig.add_vline(x=4/3, line=dict(color='green', dash='dash'), name=r'$x=\frac{4}{3}$')

fig.show()

Most of the time the graph is very flat, and close to $y=0.7$. Somewhere close to $x=1.3$, the graph climbs steeply to $\infty$, jumps down discontinuously to $-\infty$, and then climbs back up to around $0.7$ again.

The function is discontinuous at the point where the formula $g(x)=\frac{2 x -3}{3 x -4}$ involves division by zero, which means $3x-4=0$ or in other words $x=\frac{4}{3}$.

The picture shows that the graph does not cross the line $y=\frac{2}{3}$. To see this algebraically, we first find the general formula for the point where the curve crosses the line $y=a$.

In [12]:
a = sp.symbols('a')
g_inv = sp.lambdify(a, sp.solve(sp.Eq(g(y),a),[y])[0])
display(g_inv(a))
$\displaystyle \frac{4 a - 3}{3 a - 2}$

The formula involves division by zero when $a=\frac{2}{3}$, indicating that the curve does not in fact cross the line $y=\frac{2}{3}$.

We now find the limit of $g(x)$ as $x\to\pm\infty$.

In [13]:
sp.limit(g(x), x, sp.oo), sp.limit(g(x), x, -sp.oo)
Out[13]:
(2/3, 2/3)

This is of course the same answer as in (c). As $x$ approaches $\infty$, the function $g (x)$ approaches $\frac{2}{3}$ from below, but never reaches it. As $x$ approaches $-\infty$, the function approaches $\frac{2}{3}$ from above, but again never reaches it.

In [14]:
del x, y, a, g, g1, g_inv, xs, ys

Exercise 1.4

Here we investigate the function $f(x)=\frac{1-e^x+e^{2x}-e^{3x}}{\sin(x)}$, including the limit as $x$ approaches zero.

In [15]:
x = sp.symbols('x')
f = (1 - sp.exp(x) + sp.exp(2*x) - sp.exp(3*x))/sp.sin(x)
display(f)
f1 = sp.lambdify(x, f, 'numpy')
$\displaystyle \frac{- e^{3 x} + e^{2 x} - e^{x} + 1}{\sin{\left(x \right)}}$
In [16]:
xs = np.linspace(-1,1,100)
ys = f1(xs)
fig = go.Figure()
fig.update_layout(width=500, height=500, yaxis_range=[-20,0], showlegend=False)
fig.add_trace(go.Scatter(x=xs, y=ys, mode='lines', line=dict(color='blue')))

Although the formula for $f(x)$ does not make sense when $x=0$, the only reasonable definition is $f(0)=-2$, as we see from the graph. Here is a non-graphical way to get sympy to produce this answer:

In [17]:
sp.limit(f,x,0)
Out[17]:
$\displaystyle -2$

To do this by hand we can use L'Hôpital's rule: $$ \lim_{x\to 0} \frac{1-e^x+e^{2x}-e^{3x}}{\sin(x)} = \lim_{x\to 0} \frac{-e^x+2e^{2x}-3e^{3x}}{\cos(x)} = \frac{-e^0+2e^0-3e^0}{\cos(0)} = \frac{-2}{1} = -2. $$

In [18]:
del x, f, f1, xs, ys

Exercise 1.5

Here we investigate the Bessel function $J_2(x)$, which often appears in physical problems involving circular symmetry. For symbolic properties of $J_2(x)$ it is best to use the sympy version of this function, which is sp.functions.special.besselj(2,x). For numerical calculations it is better to use the scipy implementation, which is sc.special.jv(2,x). We first make abbreviate names for these.

In [19]:
x = sp.symbols('x')
J2 = lambda x: sp.functions.special.bessel.besselj(2, x)  # sympy version
J2n = lambda x: sc.special.jv(2, x)                       # scipy version
J2(x)
Out[19]:
$\displaystyle J_{2}\left(x\right)$
In [20]:
xs = np.linspace(-50,50,1000)
ys = J2n(xs)
fig = go.Figure()
fig.update_layout(width=1000,height=400)
move_legend(fig, 0.7)
fig.add_trace(go.Scatter(x=xs, y=ys, mode='lines', line=dict(color='blue'), name=r'$J_2(x)$', showlegend=True))

The Bessel function is even (i.e. $J_{2}(-x)=J_{2}(x)$). It oscillates quite regularly, with amplitude decreasing slowly as $x$ approaches $\infty$ or $-\infty$.

For small $x$, the function $J_{2}(x)$ is very close to $\frac{x^{2}}{8}$, as shown by the plot below.

In [21]:
xs = np.linspace(-1,1,1000)
ys = J2n(xs)
fig = go.Figure()
fig.update_layout(width=1000, height=400)
move_legend(fig, 0.7)
fig.add_trace(go.Scatter(x=xs, y=ys, mode='lines', line=dict(color='blue'), name=r'$J_2(x)$', showlegend=True))
fig.add_trace(go.Scatter(x=xs, y=xs**2/8, mode='lines', line=dict(color='orange'), name=r'$x^2/8$', showlegend=True))

The upper envelope of the oscillation is $y=0.8 x^{-\frac{1}{2}}$, as shown by the plot below.

In [22]:
xs = np.linspace(10,300,1000)
ys = J2n(xs)
fig = go.Figure()
fig.update_layout(width=1000, height=400)
move_legend(fig, 0.7)
fig.add_trace(go.Scatter(x=xs, y=ys, mode='lines', line=dict(color='blue'), name=r'$J_2(x)$', showlegend=True))
fig.add_trace(go.Scatter(x=xs, y=0.8*xs**-0.5, mode='lines', line=dict(color='orange'), name=r'$\frac{4}{5}x^{-1/2}$', showlegend=True))

The plot below shows that $J_{2}(x)$ has (to a very good approximation) the same frequency as $\sin (x)$.

In [23]:
xs = np.linspace(10,100,1000)
ys = J2n(xs)
zs = 0.15 * np.sin(xs - 3*np.pi/4)
fig = go.Figure()
fig.update_layout(width=1000, height=400)
move_legend(fig, 0.7)
fig.add_trace(go.Scatter(x=xs, y=ys, mode='lines', line=dict(color='blue'), name=r'$J_2(x)$', showlegend=True))
fig.add_trace(go.Scatter(x=xs, y=zs, mode='lines', line=dict(color='orange'), name=r'$0.15 \sin(x-3\pi/4)$', showlegend=True))

By combining the above results, we see that the function $\frac{4}{5}x^{-1/2}\sin(x-3\pi/4)$ should be a good approximation to $J_{2}(x)$ for large $x$. The plot below shows this graphically.

In [24]:
xs = np.linspace(1,50,1000)
ys = J2n(xs)
zs = 0.8 * xs**-0.5 * np.sin(xs - 3*np.pi/4)
fig = go.Figure()
fig.update_layout(width=1000, height=400)
move_legend(fig, 0.7)
fig.add_trace(go.Scatter(x=xs, y=ys, mode='lines', line=dict(color='blue'), name=r'$J_2(x)$', showlegend=True))
fig.add_trace(go.Scatter(x=xs, y=zs, mode='lines', line=dict(color='orange'), name=r'$\frac{4}{5}x^{-1/2}\sin(x-3\pi/4)$', showlegend=True))
In [25]:
del x, J2, J2n, xs

Exercise 1.6

Here we investigate the function $g(a,x)$ defined below.

In [26]:
a, x = sp.symbols('a x')
g = (x-1-sp.sin(a/4))*(x-1-sp.cos(a/4))* (x+1-sp.sin(a/4))*(x+1-sp.cos(a/4))/(1+x**4)
display(Latex("$$g(a, x) = " + sp.latex(g) + "$$"))
g1 = sp.lambdify((a,x), g, 'numpy')
$$g(a, x) = \frac{\left(x - \sin{\left(\frac{a}{4} \right)} - 1\right) \left(x - \sin{\left(\frac{a}{4} \right)} + 1\right) \left(x - \cos{\left(\frac{a}{4} \right)} - 1\right) \left(x - \cos{\left(\frac{a}{4} \right)} + 1\right)}{x^{4} + 1}$$

The graph $y=g(2,x)$ approaches $y=1$ very closely when $x$ is very large (positive or negative). Close to $x=0$ it climbs quickly to about $y=2.5$, then drops very quickly to about $y=0$, then climbs again to just below $y=1$. The graphs for $g(3,x)$ and $g(4,x)$ look very similar on this scale.

In [27]:
xs = np.linspace(-20,20,1000)
fig = go.Figure()
fig.update_layout(width=1000, height=400)
move_legend(fig, 0.9)
fig.add_trace(go.Scatter(x=xs, y=g1(2,xs), mode='lines', line=dict(color='blue'  ), name=r'$g(2,x)$', showlegend=True))
fig.add_trace(go.Scatter(x=xs, y=g1(3,xs), mode='lines', line=dict(color='orange'), name=r'$g(3,x)$', showlegend=True))
fig.add_trace(go.Scatter(x=xs, y=g1(4,xs), mode='lines', line=dict(color='green' ), name=r'$g(4,x)$', showlegend=True))
In [28]:
xs = np.linspace(-1,2,1000)
fig = go.Figure()
fig.update_layout(width=1000, height=500)
move_legend(fig, 0.9)
fig.add_trace(go.Scatter(x=xs, y=g1(2,xs), mode='lines', line=dict(color='blue'  ), name=r'$g(2,x)$', showlegend=True))
fig.add_trace(go.Scatter(x=xs, y=g1(3,xs), mode='lines', line=dict(color='orange'), name=r'$g(3,x)$', showlegend=True))
fig.add_trace(go.Scatter(x=xs, y=g1(4,xs), mode='lines', line=dict(color='green' ), name=r'$g(4,x)$', showlegend=True))

It works out that the graph of $g(\pi,x)=g(3.1415927,x)$ stays above the $x$-axis, just touching it in two places. We first show this graphically:

In [29]:
xs0  = np.linspace(-0.5,2,1000)
ys0 = g1(np.pi, xs0)
xs1 = np.linspace(-0.292899,-0.292885,1000)
ys1 = g1(np.pi, xs1)
fig = make_subplots(rows=1, cols=2)
fig.add_trace(go.Scatter(x=xs0, y=ys0, mode='lines'), row=1, col=1)
fig.add_trace(go.Scatter(x=xs1, y=ys1, mode='lines'), row=1, col=2)

fig.show()

To see why this works algebraically, note that $\sin(\frac{\pi}{4})=\frac{\sqrt{2}}{2}$ and $\cos(\frac{\pi}{4})=\frac{\sqrt{2}}{2}$. Putting this in the definition of $g(a,x)$ gives the following:

In [30]:
sp.simplify(g.subs({a : sp.pi}))
Out[30]:
$\displaystyle \frac{\left(- 2 x + \sqrt{2} + 2\right)^{2} \left(2 x - \sqrt{2} + 2\right)^{2}}{16 \left(x^{4} + 1\right)}$

As the square or fourth power of any real number is nonnegative, this formula shows that $g(\pi,x)\geq 0$ for all $x$.

It also turns out that $1-8 g(a,0)=\cos (a)$.

In [31]:
sp.simplify(1 - 8 * g.subs({x : 0}))
Out[31]:
$\displaystyle \cos{\left(a \right)}$

To do this simplification by hand, note that $$ \left(-1-\cos (\frac{a}{4})\right)\left(1-\cos (\frac{a}{4})\right)=\cos (\frac{a}{4})^{2}-1, $$ which is the same as $-\sin (\frac{a}{4})^{2}$. Similarly, we have $$ {\left(-1-\sin (\frac{a}{4})\right)\left(1-\sin (\frac{a}{4})\right)} = {-\cos (\frac{a}{4})^{2}} $$ Putting these together, we see that $$ {8 g (a ,0)} = {8 \sin(\frac{a}{4})^{2} \cos(\frac{a}{4})^{2}} $$ which is the same as $2 (2 \sin (\frac{a}{4}) \cos (\frac{a}{4}))^{2}$. Using the standard formula $\sin (2 \theta)=2 \sin (\theta) \cos (\theta)$, this simplifies to $2 \sin (\frac{a}{2})^{2}$. We can then use the standard formula $\cos (2 \varphi)=1-2 \sin (\varphi)^{2}$ to deduce that $1-8 g (a ,0)=\cos (a)$.

In [32]:
h = g.subs({x : sp.Rational(1,2)})
slope = sp.diff(h, a)
slope
Out[32]:
$\displaystyle \frac{4 \left(\frac{3}{2} - \sin{\left(\frac{a}{4} \right)}\right) \left(\frac{3}{2} - \cos{\left(\frac{a}{4} \right)}\right) \left(- \sin{\left(\frac{a}{4} \right)} - \frac{1}{2}\right) \sin{\left(\frac{a}{4} \right)}}{17} - \frac{4 \left(\frac{3}{2} - \sin{\left(\frac{a}{4} \right)}\right) \left(\frac{3}{2} - \cos{\left(\frac{a}{4} \right)}\right) \left(- \cos{\left(\frac{a}{4} \right)} - \frac{1}{2}\right) \cos{\left(\frac{a}{4} \right)}}{17} + \frac{4 \left(\frac{3}{2} - \sin{\left(\frac{a}{4} \right)}\right) \left(- \sin{\left(\frac{a}{4} \right)} - \frac{1}{2}\right) \left(- \cos{\left(\frac{a}{4} \right)} - \frac{1}{2}\right) \sin{\left(\frac{a}{4} \right)}}{17} - \frac{4 \left(\frac{3}{2} - \cos{\left(\frac{a}{4} \right)}\right) \left(- \sin{\left(\frac{a}{4} \right)} - \frac{1}{2}\right) \left(- \cos{\left(\frac{a}{4} \right)} - \frac{1}{2}\right) \cos{\left(\frac{a}{4} \right)}}{17}$
In [33]:
[slope.subs({a : n * sp.pi}) for n in [-7, 1, 9]]
Out[33]:
[0, 0, 0]
In [34]:
aa0 = np.linspace(-20,20,200)
xx0 = np.linspace(-10,10,500)
aa, xx = np.meshgrid(aa0, xx0)
yy = g1(aa, xx)

fig = go.Figure(data=[go.Surface(x=aa, y=xx, z=yy, colorscale='viridis')])
fig.add_trace(go.Surface(x=aa, y=xx, z=0*yy, colorscale='greys'))

fig.update_layout(
    scene=dict(
        xaxis=dict(showticklabels=False),
        yaxis=dict(showticklabels=False),
        zaxis=dict(showticklabels=False),
        xaxis_title='',
        yaxis_title='',
        zaxis_title=''
    ),
    margin=dict(l=0, r=0, b=0, t=0)
)

fig.show()
In [ ]: