Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Welcome to Lasers and Optomechanics!

Syracuse University
Source
%matplotlib widget
import numpy as np 
import matplotlib as mpl
import matplotlib.pyplot as plt
from ipywidgets import *

plt.style.use('dark_background')

fontsize = 14
mpl.rcParams.update(
    {
        "text.usetex": False,
        "figure.figsize": (9, 6),
        "figure.autolayout": True,
        # "font.family": "serif",
        # "font.serif": "georgia",
        # 'mathtext.fontset': 'cm',
        "lines.linewidth": 1.5,
        "font.size": fontsize,
        "xtick.labelsize": fontsize,
        "ytick.labelsize": fontsize,
        "legend.fancybox": True,
        "legend.fontsize": fontsize,
        "legend.framealpha": 0.7,
        "legend.handletextpad": 0.5,
        "legend.labelspacing": 0.2,
        "legend.loc": "best",
        "axes.edgecolor": "#b0b0b0",
        "grid.color": "#707070",  # grid color"
        "xtick.color": "#b0b0b0",
        "ytick.color": "#b0b0b0",
        "savefig.dpi": 80,
        "pdf.compression": 9,
    }
)

Interactivity

This class will make use of the interactivity of a Jupyter notebook.
Many of the plots will feature interactive sliders or 3D plots that can be better visualized with a live kernel.

In the Jupyter Book, it is possible to launch a kernel in Binder but it takes an absolute age to load, and when if finally does load the interactivity is very slow.

Better is to git clone the course content at https://github.com/ccahilla/lasers-and-optomechanics, create the lasers python environment defined in environment.yml via conda or mamba, then run the Jupyter notebooks in Jupyter Lab yourself.

I highly recommend downloading or running the Jupyter notebooks for lectures and homeworks yourself to better understand the course content. The syllabus has some instructions for downloading

Also, if you make a useful demo in your homeworks or otherwise, please feel free to contribute it back to the course.

Below is an interactive sine wave plot, illustrating an interactive sine wave plot of sin(ωt+θ)\sin(\omega t + \theta).

xx = np.linspace(0, 1, 1000)
kk = 2 * np.pi 

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
line, = ax.plot(xx, np.sin(kk * xx))
ax.grid()

def update(ww = 1.0, theta = (-np.pi, np.pi)):
    line.set_ydata(np.sin(ww  * kk * xx + theta))
    fig.canvas.draw_idle()

interact(update);
Loading...
Loading...

Complex Numbers Review

Here we will review complex numbers, as they will form the basis of the math in this course.
In short, it is often convenient to express light fields as complex quantities, although all electric fields and magnetic fields associated with light must be real-valued in the end. Typically, this can easily be achieved by simply taking the real part of the complex quantity.

Complex Numbers

Cartesian Form

A complex number zCz \in \mathbb{C} a single number made up of a real and imaginary component, which are totally independent of one another. Often, the complex number zz is broken down into it’s components like so

z=a+ibz = a + ib

where zz is the complex number,

aa and bb are real numbers,

and ii is the imaginary unit equal to 1\sqrt{-1}.

Another way to think about this is aa is the Real component of zz, and bb is the Imaginary component of zz:

a=(z),b=(z)a = \Re(z), \quad b = \Im(z)

Complex Plane

Complex numbers can be thought of as occupying a complex plane in the same way as the xyx-y plane, with real and imaginary components described by 1 and ii rather than unit vectors x^\hat{x} and y^\hat{y}. This is often illustrated by a vector-like plot (see the interactive plot below). The complex plane houses all of the possible complex numbers, represented by C\mathbb{C}, which is simply a two-dimensional real space R2\mathbb{R}^2.

Polar Form

Another useful form for representing a complex number is polar form:

z=reiθz = r e^{i \theta}

where rr represents the radial distance away from the (0,0)(0,0) point of the complex plane, and θ\theta is the counterclockwise angle the complex number makes with the x-axis. These can be calculated from the above expressions:

z=r=a2+b2\begin{align} |z| = r = \sqrt{a^2 + b^2} \end{align}
argz=θ=arctan(ba)=arctan2(b,a)\begin{align} \arg z = \theta = \arctan\left(\dfrac{b}{a}\right) = \arctan2(b, a) \end{align}

rr is often described as the magnitude of the complex number: r=zr = |z|, while θ\theta is the argument: θ=arg(z)\theta = \arg(z).

We used arctan\arctan and arctan2\arctan2 functions for the argument calculations.
The arctan2\arctan2 function takes in two arguments bb and aa, compared to one argument for arctan(ba)\arctan\left(\dfrac{b}{a}\right). If bb and aa are both negative or both positive, arctan(ba)\arctan\left(\dfrac{b}{a}\right) will give back the same angle in the upper right quadrant. arctan2\arctan2 allows one to recover information about which quadrant one is in, with positive angles θ[0,π2]\theta \in \left[0, \dfrac{\pi}{2}\right] for positive bb and aa, and negative angles θ[π,π2]\theta \in \left[-\pi, -\dfrac{\pi}{2}\right] for negative bb and aa.

We note here that because arctan\arctan and arctan2\arctan2 are used to find the angle of the complex number, scaling both aa and bb by any number cc will not impact the final result:

arctan2(cb,ca)=arctan2(b,a)\arctan2(cb, ca) = \arctan2(b, a)

Complex Conjugate

Finally, we introduce the concept of the complex conjugate zz^* of a complex number zz. A complex conjugate zz^* is simply equal to the original complex number with its imaginary sign flipped:

z=aib.z^* = a - i b.

Equivalently, in polar form, our angle is θ-\theta instead of θ\theta:

z=reiθ.z^* = r e^{-i \theta}.

This can all be derived by taking wherever you see the imaginary unit ii in an equation, and replacing it with i-i.

Taking the Magnitude Squared

Taking the magnitude of a complex number is the same as finding the length of the complex vector, using Eq. 4 above.

Taking the magnitude squared of a complex number is a very common calculation in quantum mechanics, and has an interesting relationship with complex conjugates:

z2=r2=a2+b2z2=r2=(reiθ)(riθ)=zz\begin{align} |z|^2 = r^2 = a^2 + b^2\\ |z|^2 = r^2 = (r e^{i \theta}) (r^{-i \theta}) = z z^* \end{align}

In short, we can calculate the magnitude squared of a complex number by taking the product of the complex number with it’s conjugate. This is very useful, especially for superposition problems we will be dealing with.

Source
fig = plt.figure(figsize=(11,6))
ax = fig.add_subplot()

aa = 3.0
bb = 4.0
rr = np.sqrt(aa**2 + bb**2)
theta = 180/np.pi * np.arctan2(bb, aa)

thetas = np.linspace(np.pi * theta / 180, 0, 100)
xxs = np.cos(thetas)
yys = np.sin(thetas)

line1, = ax.plot([0, aa], [0, bb], 'o-', label="Complex Number $z = a + i b$")
line2, = ax.plot([0, aa], [0, -bb], 's-', label="Complex Conjugate $z^* = a - i b$")
arc1, = ax.plot(xxs, yys, color="#ff4444", label=r"$\theta$")

vline1, = ax.plot([aa, aa], [0, bb], '--', label="$a$")
hline1, = ax.plot([0, aa], [bb, bb], '--', label="$b$")

ax.set_xlabel("Real")
ax.set_ylabel("Imaginary $i$")
ax.set_xlim([-5, 5])
ax.set_ylim([-5, 5])
ax.grid()

ax.set_title(r"(r, \theta) = (" + f"({rr:.3f}, {theta:.3f})")

ax.legend(bbox_to_anchor=(1.01, 0.6))
ax.set_aspect('equal')
# plt.tight_layout()

def update_complex_number(
    aa_slider_value=aa,
    bb_slider_value=bb,
):
    """
    Create waves plot with synchronized cosine and sine displays.
    """
    aa = aa_slider_value
    bb = bb_slider_value

    rr = np.sqrt(aa**2 + bb**2)
    theta = 180/np.pi * np.arctan2(bb, aa)

    newthetas = np.linspace(np.pi * theta / 180, 0, 100)
    newxxs = np.cos(newthetas)
    newyys = np.sin(newthetas)
    
    # Calculate sine
    newx1 = [0, aa]
    newy1 = [0, bb]
    newx2 = [0, aa]
    newy2 = [0, -bb]
    newvx1 = [aa, aa]
    newvy1 = [0, bb]
    newhx1 = [0, aa]
    newhy1 = [bb, bb]

    line1.set_xdata(newx1)
    line1.set_ydata(newy1)
    line2.set_xdata(newx2)
    line2.set_ydata(newy2)
    arc1.set_xdata(newxxs)
    arc1.set_ydata(newyys)

    vline1.set_xdata(newvx1)
    vline1.set_ydata(newvy1)
    hline1.set_xdata(newhx1)
    hline1.set_ydata(newhy1)

    ax.set_title(r"$(r, \theta)$ = " + f"({rr:.3f}, {theta:.3f})")
    
    fig.canvas.draw_idle()
    return

# Create interactive widget
aa_slider = FloatSlider(
    value=aa,
    min=-5,
    max=5,
    step=0.01,
    description="$a$:",
    continuous_update=True,  # Only update on release for better performance
    orientation='horizontal',
    readout=True,
    readout_format='.3f',
)
bb_slider = FloatSlider(
    value=bb,
    min=-5,
    max=5,
    step=0.01,
    description="$b$:",
    continuous_update=True,  # Only update on release for better performance
    orientation='horizontal',
    readout=True,
    readout_format='.3f',
)

interact(
    update_complex_number, 
    aa_slider_value=aa_slider, 
    bb_slider_value=bb_slider,
)
plt.show()
Loading...
Loading...
Solution to Exercise 1 #

I will leave the graphing up to you, make adjustments to the above code if you are feeling inspired. From the definitions above, we have for Cartesian form

z+z=2az + z^* = 2 a

and

zz=2ibz - z^* = 2 i b

For Polar form, we have to remember some trig identities: cosθ=12(eiθ+eiθ)\cos\theta = \dfrac{1}{2}(e^{i \theta} + e^{-i \theta}) and sinθ=12i(eiθeiθ)\sin\theta = \dfrac{1}{2 i}(e^{i \theta} - e^{-i \theta}) then

z+z=reiθ+reiθ=2rcosθz + z^* = r e^{i \theta} + r e^{-i \theta} = 2 r \cos\theta

and

zz=reiθreiθ=2irsinθz - z^* = r e^{i \theta} - r e^{-i \theta} = 2 i r \sin\theta

Euler’s Formula

From the results of Exercise 1, we can start to piece together an incredibly important result in complex representation: Euler’s Formula.

Euler’s Formula is as follows:

eiθ=cosθ+isinθ\begin{align} \boxed{ e^{i \theta} = \cos{\theta} + i \sin{\theta} } \end{align}

This result can be seen geometrically from the graph above.
The cosine of the angle cosθ\cos\theta gives the x-component, which in this case is the real component. The sine sinθ\sin\theta yields the imaginary component.

Euler’s Formula is an extremely convenient breakdown of the real and imaginary parts of a complex number.
We will use this formula to represent real quantities, like positions xx or electric fields E\boldsymbol{E}, as complex numbers x~\tilde{x} or E~\tilde{\boldsymbol{E}}.

This allows us to make use of the simplified algebra for exponentials during problem solving. At the end, we will take the real component of the complex number to recover the true position.

x=Re(x~)\begin{align} x = \mathrm{Re}(\tilde{x}) \end{align}

Quadratures

A complex number zz is the combination of two real numbers, the real part aa and the imaginary part bb.

It’s sometimes convenient to express zz as a vector:

z=[ab]\begin{align} \vec{z} = \begin{bmatrix} a \\ b \end{bmatrix} \end{align}

This breakdown of the complex number zz is referred to as the quadrature basis.
The real part is commonly called the I-quadrature,
while the imaginary part is called the Q-quadrature.
These quadratures are the independent basis vectors for a complex number, and carry different information.

Phasors

A phasor is typically a complex number that evolves in time:

z(t)=r(t)eiθ(t)z(t) = r(t) e^{i \theta(t)}

where tt is time elapsed and r(t)r(t) and θ(t)\theta(t) are the time-dependent magnitude and argument of the phasor.

It is extremely common to describe a phasor’s angle as evolving linearly with time, while the magnitude r(t)=r0r(t) = r_0 is constant:

θ(t)=ωt,r(t)=r0\theta(t) = \omega t, r(t) = r_0

where ω\omega is the angular frequency in radians / second.

The angular frequency is related to the normal frequency ν\nu in cycles / second via

ω=2πν\omega = 2 \pi \nu

If we say something has a frequency of 1 Hz1~\mathrm{Hz}, we always mean it completes 1 cycle per second, so the angular frequency would be ω=2π(1 Hz)\omega = 2 \pi (1~\mathrm{Hz})

In the quadrature picture, we have a simple breakdown of z(t)z(t):

z(t)=[Re[z(t)]Im[z(t)]]=[r0cosθ(t)r0sinθ(t)]\begin{align} \vec{z}(t) = \begin{bmatrix} \mathrm{Re}[z(t)] \\ \mathrm{Im}[z(t)] \end{bmatrix} = \begin{bmatrix} r_0 \cos \theta(t) \\ r_0 \sin \theta(t) \end{bmatrix} \end{align}

This gives a purely circular motion in time, as can be visualized below.

Source
# Create figure with custom layout
fig = plt.figure(figsize=(9, 9))
fig.set_tight_layout(False)
gs = fig.add_gridspec(3, 3, height_ratios=[1, 1, 0.1], width_ratios=[1, 1, 0.1],
                      hspace=0.05, wspace=0.05)

# Create subplots
ax_cos = fig.add_subplot(gs[0, 0])      # Cosine plot (top)
ax_phasor = fig.add_subplot(gs[1, 0])  # Phasor plot (center)
ax_sin = fig.add_subplot(gs[1, 1])     # Sine plot (right)

theta = 0 # initial values

cos_val = np.cos(theta)
sin_val = np.sin(theta)

# Generate full curves
theta_range = np.linspace(0, 2*np.pi, 1000)
cos_curve = np.cos(theta_range)
sin_curve = np.sin(theta_range)

# Setup cosine plot (top)
ax_cos.plot(cos_curve, theta_range, '-', color='C3', linewidth=2, alpha=0.5)
cos_dot,     = ax_cos.plot([cos_val], [theta], 'o', color='C3', markersize=10, zorder=5)
cos_val_line = ax_cos.axvline(cos_val, color='C3', linestyle='--', alpha=0.5)

ax_cos.set_xlim(-1.3, 1.3)
ax_cos.set_ylim(0, 2*np.pi)
ax_cos.set_ylabel('cos(θ)', fontsize=12, fontweight='bold')
ax_cos.grid(True, alpha=0.3)
ax_cos.axhline(0, linewidth=0.5)
ax_cos.set_xticklabels([])

# Setup phasor plot (center)
circle = plt.Circle((0, 0), 1, fill=False, color='gray', linewidth=2)
ax_phasor.add_patch(circle)

# Draw phasor arrow
# arrow = FancyArrowPatch((0, 0), (cos_val, sin_val),
#                        arrowstyle='->', mutation_scale=20, 
#                        linewidth=3, color='red', zorder=4)
# ax_phasor.add_patch(arrow)

phasor_line, = ax_phasor.plot([0,cos_val],[0,sin_val])
phasor_sin_line = ax_phasor.axhline(sin_val, color='C1', linestyle='--', alpha=0.5)
phasor_cos_line = ax_phasor.axvline(cos_val, color='C3', linestyle='--', alpha=0.5)
phasor_dot, = ax_phasor.plot([cos_val], [sin_val], 'ro', markersize=12, zorder=5)

ax_phasor.set_xlim(-1.3, 1.3)
ax_phasor.set_ylim(-1.3, 1.3)
ax_phasor.set_aspect('equal')
ax_phasor.axhline(0, linewidth=0.5)
ax_phasor.axvline(0, linewidth=0.5)
ax_phasor.set_xlabel('Real')
ax_phasor.set_ylabel('Imag')
ax_phasor.grid(True, alpha=0.3)
# ax_phasor.set_title('Phasor: $e^{i\\theta}$', fontsize=14, pad=10, fontweight='bold')

# Add text annotation
ax_phasor.text(0.02, 0.98, f'θ = {theta:.3f} rad\n= {np.degrees(theta):.1f}°',
               transform=ax_phasor.transAxes, 
               verticalalignment='top',
               bbox=dict(boxstyle='round', facecolor='grey', alpha=0.8),
               fontsize=10)

# Setup sine plot (right)
ax_sin.plot(theta_range, sin_curve, color="C1", linewidth=2, alpha=0.5)
sin_dot, = ax_sin.plot([theta], [sin_val], 'o', color="C1", markersize=10, zorder=5)
sin_val_line = ax_sin.axhline(sin_val, color='C1', linestyle='--', alpha=0.5)
ax_sin.set_xlim(0, 2*np.pi)
ax_sin.set_ylim(-1.3, 1.3)
ax_sin.set_xlabel('sin(θ)')
# ax_sin.set_yticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi])
ax_sin.set_yticklabels([])
ax_sin.grid(True, alpha=0.3)
ax_sin.axvline(0, color='k', linewidth=0.5)

plt.suptitle('Interactive Phasor Visualization: $e^{i\\theta} = \\cos(\\theta) + i\\sin(\\theta)$', 
             fontsize=16, y=0.92, fontweight='bold')

# plt.tight_layout()
# plt.show()

def update_phasor(theta_slider_value=1):
    """
    Create phasor plot with synchronized cosine and sine displays.
    
    Parameters:
    -----------
    theta : float
        Angle in radians (0 to 2π)
    """
    theta = theta_slider_value
    
    # Calculate phasor components
    cos_val = np.cos(theta)
    sin_val = np.sin(theta)

    cos_dot.set_xdata([cos_val])
    cos_dot.set_ydata([theta])
    cos_val_line.set_xdata([cos_val,cos_val])

    phasor_line.set_xdata([0,cos_val])
    phasor_line.set_ydata([0,sin_val])
    phasor_sin_line.set_ydata([sin_val, sin_val])
    phasor_cos_line.set_xdata([cos_val, cos_val])
    phasor_dot.set_xdata([cos_val])
    phasor_dot.set_ydata([sin_val])

    sin_dot.set_xdata([theta])
    sin_dot.set_ydata([sin_val])
    sin_val_line.set_ydata([sin_val,sin_val])

    # fig.canvas.draw()
    # fig.canvas.flush_events()
    fig.canvas.draw_idle()
    return

# Create interactive widget
theta_slider = FloatSlider(
    value=0,
    min=0,
    max=2*np.pi,
    step=0.01,
    description='θ (rad):',
    continuous_update=True,  # Only update on release for better performance
    orientation='horizontal',
    readout=True,
    readout_format='.3f',
)

interact(update_phasor, theta_slider_value=theta_slider)
plt.show()
Loading...
Loading...
Solution to Exercise 2 #

First, we express ii in terms of an exponential. Starting with

eiθ=cos(θ)+isin(θ)\begin{align} e^{i \theta} = \cos(\theta) + i \sin(\theta) \end{align}

we see that we get a purely imaginary expression when θ=π2\theta = \dfrac{\pi}{2}. This gives us i=exp(iπ2)i = \exp\left({i \dfrac{\pi}{2}}\right)

Now, iii^i can be rewritten as

ii=(eiπ2)i=eiπ2i=eπ2i^i = \left(e^{i \frac{\pi}{2}}\right)^i = e^{i \frac{\pi}{2} \cdot i } = e^{-\frac{\pi}{2} }

which happens to be an entirely real number.

Solution to Exercise 3 #

First, look at ei(A+B)e^{i (A + B)}

ei(A+B)=cos(A+B)+isin(A+B)\begin{align} e^{i (A + B)} = \cos(A + B) + i \sin(A + B) \end{align}

Then separate it into to exponentials:

ei(A+B)=eiAeiB=[cos(A)+isin(A)][cos(B)+isin(B)]=[cos(A)cos(B)sin(A)sin(B)]+i[cos(A)sin(B)+cos(B)sin(A)]\begin{align} e^{i (A + B)} &= e^{i A} e^{i B} \\ &= \Big[\cos(A) + i \sin(A)\Big]\Big[\cos(B) + i \sin(B)\Big] \\ &= \Big[\cos(A) \cos(B) - \sin(A) \sin(B)\Big] + i \Big[ \cos(A) \sin(B) + \cos(B) \sin(A)\Big] \end{align}

Matching coefficients from (25) gives

cos(A+B)=cos(A)cos(B)sin(A)sin(B)sin(A+B)=cos(A)sin(B)+cos(B)sin(A)\begin{align} \cos(A + B) &= \cos(A) \cos(B) - \sin(A) \sin(B) \\ \sin(A + B) &= \cos(A) \sin(B) + \cos(B) \sin(A) \end{align}

Sum of two complex numbers

In the last example we looked at the sum of a complex number with it’s own complex conjugate, and found it was always a real number.

For two arbitrary complex numbers u,vu, v, this is not always the case.

Because it will be useful going forward when we discuss superposition and interference, we state some properties of sums of complex numbers.

Cartesian Sum

This one is straightforward, because of the independence of real and imaginary components:

u=a+ibv=c+idu+v=(a+c)+i(b+d)\begin{align} u &= a + i b\\ v &= c + i d\\ u + v &= (a + c) + i (b + d) \end{align}

Polar Sum

This one is less straightforward or immediately useful, but we tend to describe electric fields in polar form, so it is helpful to have this in mind

u=r1eiθ1v=r2eiθ2u+v=r1eiθ1+r2eiθ2u+v=r1(cosθ1+isinθ1)+r2(cosθ2+isinθ2)u+v=r1cosθ1+r2cosθ2+i(r1sinθ1+r2sinθ2)\begin{align} u &= r_1 e^{i \theta_1}\\ v &= r_2 e^{i \theta_2}\\ u + v &= r_1 e^{i \theta_1} + r_2 e^{i \theta_2}\\ u + v &= r_1 (\cos\theta_1 + i \sin\theta_1) + r_2 (\cos\theta_2 + i \sin\theta_2)\\ u + v &= r_1 \cos\theta_1 + r_2 \cos\theta_2 + i ( r_1 \sin\theta_1 + r_2 \sin\theta_2 ) \end{align}

Product of two complex numbers

Here we calculate the product of two complex number u,vu, v:

Cartesian Product
u=a+ibv=c+iduv=(a+ib)(c+id)uv=(acbd)+i(bc+ad)\begin{align} u &= a + i b\\ v &= c + i d\\ u v &= (a + i b)(c + id)\\ u v &= (ac - bd) + i (bc + ad) \end{align}
Polar Product
u=r1eiθ1v=r2eiθ2uv=r1r2ei(θ1+θ2)\begin{align} u &= r_1 e^{i \theta_1}\\ v &= r_2 e^{i \theta_2}\\ u v &= r_1 r_2 e^{i (\theta_1 + \theta_2)} \end{align}

Here we find that multiplying two complex numbers in polar coordinates is far easier than in cartesian coordinates. Additionally, we see a major advantage of multiplication of complex numbers directly from the above: Multiplication of complex numbers corresponds directly to rotations in 2D

Plotting Complex Functions

Suppose I have a complex function z(ϕ)z(\phi) on the domain ϕ[0,2π]\phi \in [0,2\pi]:

z(ϕ)=eiϕ+3eiϕ\begin{align} z(\phi) = e^{i \phi} + 3 e^{-i \phi} \end{align}

Question: Find the magnitude r(ϕ)r(\phi) and argument θ(ϕ)\theta(\phi) of z(ϕ)z(\phi).

The magnitude is straightforward, recalling r=zr = |z|

r2(ϕ)=z(ϕ)2=z(ϕ)z(ϕ)r2(ϕ)=(eiϕ+3eiϕ)(eiϕ+3eiϕ)r2(ϕ)=1+9+3(ei2ϕ+ei2ϕ)r2(ϕ)=10+6cos(2ϕ)r(ϕ)=10+6cos(2ϕ)\begin{align} r^2(\phi) &= |z(\phi)|^2 = z(\phi) z^*(\phi)\\ r^2(\phi) &= \left( e^{i \phi} + 3 e^{-i \phi} \right) \left( e^{-i \phi} + 3 e^{i \phi} \right)\\ r^2(\phi) &= 1 + 9 + 3 (e^{i 2 \phi} + e^{-i 2 \phi})\\ r^2(\phi) &= 10 + 6 \cos(2\phi)\\ r(\phi) &= \sqrt{10 + 6 \cos(2\phi)} \end{align}

For the argument θ(ϕ)\theta(\phi), there is no nice expression. First we note the real and imaginary parts of zz:

Re(z(ϕ))=4cos(ϕ)Im(z(ϕ))=2sin(ϕ)\begin{align} \mathrm{Re}(z(\phi)) &= 4 \cos(\phi)\\ \mathrm{Im}(z(\phi)) &= - 2 \sin(\phi) \end{align}

where we used the fact that eiϕ=cos(ϕ)+sin(ϕ)e^{i \phi} = \cos(\phi) + \sin(\phi) and 3eiϕ=3cos(ϕ)3sin(ϕ)3e^{-i \phi} = 3\cos(\phi) - 3\sin(\phi),
then gathered real and imaginary coefficients.

For finding the argument θ\theta as a function of the parameter ϕ\phi:

θ(ϕ)=arctan2(Im(z),Re(z))θ(ϕ)=arctan2(2sin(ϕ),4cos(ϕ))\begin{align} \theta(\phi) &= \arctan2\left(\mathrm{Im}(z), \mathrm{Re}(z) \right)\\ \theta(\phi) &= \arctan2\left(-2 \sin(\phi), 4 \cos(\phi) \right) \end{align}

Here I’ve used arctan2(y,x)\arctan2(y,x), which is a common two-argument function to maintain quadrant information. In the normal arctan(yz)\arctan\left(\dfrac{y}{z}\right) function, if x and y are both negative or both positive, you can’t tell if you are in Quandrant I or III.

Discussion

We briefly discuss our results from Eqs. (33) and (35). In the above, ϕ\phi serves as a independent, parametric variable controlling zz. The magnitude and phase r(ϕ),θ(ϕ)r(\phi), \theta(\phi) of zz depend on ϕ\phi.

I want to emphasize that ϕθ\phi \neq \theta in the general case.
Our first plot below emphasizes this.

def zzs(phis, aa=4, bb=2, r0=0, rotation=0):
    """Arbitrary ellipse equation, with center on real axis at r0 and rotation by rotation radians.
    aa is real axis of ellipse (with no rotation)
    bb is the imaginary axis of ellipse (with no rotation),
    r0 is the displacement along the real axis of the center,
    rotation is the angle the entire ellipse is rotated"""
    return ((aa * np.cos(phis) - r0) + 1j * bb * np.sin(phis)) * np.exp(1j * rotation)

def dzzdphis(phis, aa=4, bb=2, r0=0, rotation=0):
    """Derivative of arbitrary ellipse equation  with respect to phi.
    aa is real axis of ellipse (with no rotation)
    bb is the imaginary axis of ellipse (with no rotation),
    r0 is the displacement along the real axis of the center,
    rotation is the angle the entire ellipse is rotated"""
    return ( -aa * np.sin(phis) + 1j * bb * np.cos(phis) ) * np.exp(1j * rotation)
Source
fig, (ax1, ax2, ax3) = plt.subplots(3, figsize=(8,9), gridspec_kw={'height_ratios': [3, 1, 1]})

phis = np.linspace(0, 2 * np.pi, 100)

aa = 4.0
bb = 2.0
r0 = 0.0
rotation = 0.0
phi0 = np.pi/4

plot_zzs = zzs(phis, aa, bb, r0, rotation)
plot_xxs = np.real(plot_zzs)
plot_yys = np.imag(plot_zzs)
plot_rrs = np.abs(plot_zzs)
plot_thetas = 180/np.pi * np.angle(plot_zzs)

plot_zz0 = zzs(phi0, aa, bb, r0, rotation)
plot_xx0 = np.real(plot_zz0)
plot_yy0 = np.imag(plot_zz0)
plot_rr0 = np.abs(plot_zz0)
plot_theta0 = 180/np.pi * np.angle(plot_zz0)

ax1.plot([0, plot_xx0], [0, plot_yy0], 'o-', color="C3", label=r" $z(\phi_0) = r e^{i \theta}$")
ax1.plot(plot_xxs, plot_yys, color=line1.get_color(), label="Ellipse")
ax2.plot(180/np.pi * phis, plot_rrs, label=r"$r(\phi)$")
ax2.axvline(x=180/np.pi * phi0, ls="--", color="C3", label=r"$\phi_0$ = " + f"{180/np.pi*phi0:.0f}" + r"${}^\circ$")
ax3.plot(180/np.pi * phis, plot_thetas, label=r"$\theta(\phi)$")
ax3.axvline(x=180/np.pi * phi0, ls="--", color="C3", label=r"$\phi_0$ = " + f"{180/np.pi*phi0:.0f}" + r"${}^\circ$")

ax1.set_xlabel("Real")
ax1.set_ylabel("Imaginary $i$")
ax2.set_ylabel(r"$r(\phi)$")
ax3.set_xlabel(r"$\phi$ [degs]")
ax3.set_ylabel(r"$\theta(\phi)$ [degs]")

ax1.set_xlim([-5, 5])
ax1.set_ylim([-5, 5])
ax1.grid()
ax2.set_xlim([0, 360])
ax2.set_ylim(bottom=0)
ax2.grid()
ax2.set_xticks([0,90,180,270,360])
ax3.set_xlim([0, 360])
ax3.set_ylim([-180, 180])
ax3.grid()
ax3.set_xticks([0,90,180,270,360])
ax3.set_yticks([-180,0,180])

ax1.set_title(r"$(r, \theta)$ = " + f"({plot_rr0:.3f}, {plot_theta0:.3f}"+r"$^\circ$)")

ax1.legend(bbox_to_anchor=(1.01, 0.6))
ax2.legend(bbox_to_anchor=(1.01, 0.6))
ax3.legend(bbox_to_anchor=(1.01, 0.6))
ax1.set_aspect('equal')
Loading...
Source
fig = plt.figure(figsize=(11,6))
ax = fig.add_subplot()

phis = np.linspace(0, 2 * np.pi, 100)

aa = 4.0
bb = 2.0
r0 = 0.0
rotation = 0.0
phi0 = 0

plot_zzs = zzs(phis, aa, bb, r0, rotation)
plot_xxs = np.real(plot_zzs)
plot_yys = np.imag(plot_zzs)

plot_zz0 = zzs(phi0, aa, bb, r0, rotation)
plot_rr0 = np.abs(plot_zz0)
plot_theta0 = np.angle(plot_zz0)
plot_xx0 = np.real(plot_zz0)
plot_yy0 = np.imag(plot_zz0)

plot_dz0 = dzzdphis(phi0, aa, bb, r0, rotation)
plot_dx0 = np.real(plot_dz0)
plot_dy0 = np.imag(plot_dz0)


line1, = ax.plot([0, plot_xx0], [0, plot_yy0], 'o-', label=r" $z(\phi_0) = r e^{i \theta}$")
arc1, = ax.plot(plot_xxs, plot_yys, color=line1.get_color(), label="Ellipse")

arrow1 = ax.arrow(plot_xx0, plot_yy0, plot_dx0, plot_dy0, shape='full', color="#ff5500", lw=2, length_includes_head=True, head_width=.15, zorder=2, label="Velocity")

ax.set_xlabel("Real")
ax.set_ylabel("Imaginary $i$")
ax.set_xlim([-5, 5])
ax.set_ylim([-5, 5])
ax.grid()

ax.set_title(r"$(r, \theta)$ = " + f"({plot_rr0:.3f}, {180/np.pi*plot_theta0:.3f})")

ax.legend(bbox_to_anchor=(1.01, 0.6))
ax.set_aspect('equal')
# plt.tight_layout()

def update_complex_function(
    aa_slider_value=aa,
    bb_slider_value=bb,
    r0_slider_value=r0,
    phi0_slider_value=phi0
):
    """
    Create waves plot with synchronized cosine and sine displays.
    """
    new_aa = aa_slider_value
    new_bb = bb_slider_value
    new_r0 = r0_slider_value
    new_rotation = 0
    new_phi0 = np.pi / 180 * phi0_slider_value
    
    new_plot_zzs = zzs(phis, new_aa, new_bb, new_r0, new_rotation)
    new_plot_xxs = np.real(new_plot_zzs)
    new_plot_yys = np.imag(new_plot_zzs)
    
    new_plot_zz0 = zzs(new_phi0, new_aa, new_bb, new_r0, new_rotation)
    new_plot_rr0 = np.abs(new_plot_zz0)
    new_plot_theta0 = np.angle(new_plot_zz0)
    new_plot_xx0 = np.real(new_plot_zz0)
    new_plot_yy0 = np.imag(new_plot_zz0)

    new_plot_dz0 = dzzdphis(new_phi0, new_aa, new_bb, new_r0, new_rotation)
    new_plot_dx0 = np.real(new_plot_dz0)
    new_plot_dy0 = np.imag(new_plot_dz0)
    
    new_xx0 = [0, new_plot_xx0]
    new_yy0 = [0, new_plot_yy0]
    new_xxs = new_plot_xxs
    new_yys = new_plot_yys

    line1.set_xdata(new_xx0)
    line1.set_ydata(new_yy0)
    arc1.set_xdata(new_xxs)
    arc1.set_ydata(new_yys)
    arrow1.set_data(x=new_plot_xx0, y=new_plot_yy0, dx=new_plot_dx0, dy=new_plot_dy0)

    ax.set_title(r"$(r, \theta)$ = " + f"({new_plot_rr0:.3f}, {180/np.pi*new_plot_theta0:.3f}"+r"$^\circ$)")
    
    fig.canvas.draw_idle()
    return

# Create interactive widget
aa_slider = FloatSlider(
    value=aa,
    min=-5,
    max=5,
    step=0.01,
    description="$a$:",
    continuous_update=True,  # Only update on release for better performance
    orientation='horizontal',
    readout=True,
    readout_format='.3f',
)
bb_slider = FloatSlider(
    value=bb,
    min=-5,
    max=5,
    step=0.01,
    description="$b$:",
    continuous_update=True,  # Only update on release for better performance
    orientation='horizontal',
    readout=True,
    readout_format='.3f',
)
r0_slider = FloatSlider(
    value=r0,
    min=-2,
    max=2,
    step=0.01,
    description="$r_0$:",
    continuous_update=True,  # Only update on release for better performance
    orientation='horizontal',
    readout=True,
    readout_format='.3f',
)
phi0_slider = FloatSlider(
    value=phi0,
    min=0,
    max=180,
    step=0.1,
    description=r"$\phi_0$ [deg]:",
    continuous_update=True,  # Only update on release for better performance
    orientation='horizontal',
    readout=True,
    readout_format='.3f',
)

interact(
    update_complex_function, 
    aa_slider_value=aa_slider, 
    bb_slider_value=bb_slider,
    r0_slider_value=r0_slider, 
    phi0_slider_value=phi0_slider,
)
plt.show()
Loading...
Loading...

Complex Time Derivatives

Suppose we have a general phasor z(t)=r(t)eiθ(t)z(t) = r(t) e^{i \theta(t)}.

Let’s calculate the generalized velocity dzdt=z˙\dfrac{dz}{dt} = \dot{z} in both cartesian and polar coordinates

Cartesian

This one is very straightforward, because the real and imaginary components x,yx, y do not interact:

dzdt=dxdt+idydtz˙=x˙+iy˙\begin{align} \dfrac{dz}{dt} &= \dfrac{dx}{dt} + i \dfrac{dy}{dt}\\ \dot{z} &= \dot{x} + i \dot{y} \end{align}

This separates the velocity into two entirely separate and general 1D velocities.
However, this may not always be the best choice.

Polar

In polar coordinates, r(t)r(t) and θ(t)\theta(t) are no longer entirely independent: a change in θ\theta will result in different arc lengths depending on rr. If we take the time-derivative z˙\dot{z}:

z˙=r˙eiθ+iθ˙reiθ\begin{align} \dot{z} = \dot{r} e^{i \theta} + i \dot{\theta} r e^{i \theta} \end{align}

Analyzing this velocity for a moment, we see that a change in the magnitude r˙\dot{r} occurs rotated by the argument θ\theta. Additionally, the change in the phase θ˙\dot{\theta} is also rotated by the argument θ\theta, and also scaled by the magnitude rr. In fact, there is a convenient way of expressing these scalings, found by dividing by the original number z=reiθz = r e^{i \theta}:

z˙z=r˙r+iθ˙\begin{align} \boxed{ \dfrac{\dot{z}}{z} = \dfrac{\dot{r}}{r} + i \dot{\theta} } \end{align}

This normalized velocity z˙z\dfrac{\dot{z}}{z} gives a convenient expression in the real and imaginary parts. The real part r˙r\dfrac{\dot{r}}{r} is only the normalized radial velocity, while the imaginary part θ˙\dot{\theta} is only the angular velocity. By normalizing by zz, we are able to pick off the polar velocity terms by taking the real and imaginary components.

Solution to Exercise 4 #

The cartesian solution is very simple:

z¨=x¨+iy¨\begin{align} \ddot{z} = \ddot{x} + i \ddot{y} \end{align}

then z¨z\dfrac{\ddot{z}}{z} becomes

z¨z=x¨+iy¨x+iy\begin{align} \dfrac{\ddot{z}}{z} = \dfrac{ \ddot{x} + i \ddot{y} }{x + i y} \end{align}

and there are no further good simplifications. (One could multiple both top and bottom by xiyx - i y, but it doesn’t help much.)

In polar coordinates, the solution is much more complex. Starting with Eq. (37):

ddtz˙=ddt(r˙eiθ+iθ˙reiθ) z¨=r¨eiθ+iθ˙r˙eiθ+iθ¨reiθ+iθ˙r˙eiθrθ˙2eiθ z¨=r¨eiθrθ˙2eiθ+i(θ¨reiθ+2θ˙r˙eiθ)\begin{align} \dfrac{d}{dt} \dot{z} &= \dfrac{d}{dt} \left( \dot{r} e^{i \theta} + i \dot{\theta} r e^{i \theta} \right) \\~\\ \ddot{z} &= \ddot{r} e^{i \theta} + \underbrace{ i \dot{\theta} \dot{r} e^{i \theta} } + i \ddot{\theta} r e^{i \theta} + \underbrace{ i \dot{\theta} \dot{r} e^{i \theta} } - r \dot{\theta}^2 e^{i \theta}\\~\\ \ddot{z} &= \ddot{r} e^{i \theta} - r \dot{\theta}^2 e^{i \theta} + i ( \ddot{\theta} r e^{i \theta} + 2 \dot{\theta} \dot{r} e^{i \theta} ) \end{align}

Dividing again by zz:

z¨z=[r¨rθ˙2]+i[θ¨+2θ˙r˙r]\begin{align} \boxed{\dfrac{\ddot{z}}{z} = \left[ \dfrac{\ddot{r}}{r} - \dot{\theta}^2 \right] + i \left[ \ddot{\theta} + \dfrac{2 \dot{\theta} \dot{r}}{r} \right]} \end{align}

Each of these terms can be understood in terms of physics concepts we’re familiar with.

r¨r\dfrac{\ddot{r}}{r} is the raw radial acceleration term,

θ˙2\dot{\theta}^2 is the angular velocity squared term associated with centripetal motion,

θ¨\ddot{\theta} is the raw angular acceleration term,

2θ˙r˙r\dfrac{2 \dot{\theta} \dot{r}}{r} is product of the radial and angular velocity, which is sort of akin to angular momentum and accounts for how if radial and angular velocity are constant and nonzero, then we must have some acceleration in the angular direction to account for this. Think of a spiral into the origin, how the acceleration of such a path must appear. Question 3E on your homework explores such a path.

Fourier Transforms

Phasors offer a very convenient way of breaking down evolutions in time in terms of frequency ω\omega. In fact, they form the backbone of the infamous Fourier Transform.
If I have a real function signal x(t)x(t) (say x(t)x(t) represents the position of a mass on a pendulum), I can break down the mass’s position in terms of its frequency components by multiplying by a phasor eiωte^{-i \omega t}, then integrating over the entire signal time:

X(ω)=12πx(t)eiωtdt\begin{align} X(\omega) = \dfrac{1}{\sqrt{2 \pi}}\displaystyle\int_{-\infty}^{\infty} x(t) e^{-i \omega t} dt \end{align}

The resulting complex quantity X(ω)X(\omega) is a representation of the mass’s position in the frequency domain ωR\omega \in \mathbb{R}.

If a mass is moving sinusoidally at ν=1 Hz\nu = 1~\mathrm{Hz}, then this function “picks out” that motion and returns its amplitude and phase.

Solution to Exercise 5 #

First, express x(t)x(t) as an exponential:

x(t)=Asin(ω0t+ϕ)=A2i(ei(ω0t+ϕ)ei(ω0t+ϕ))x(t) = A \sin(\omega_0 t + \phi) = \dfrac{A}{2 i} (e^{i(\omega_0 t + \phi)} - e^{-i(\omega_0 t + \phi)})

Then we’ll get two distinct integrals:

X(ω)=12πAsin(ω0t+ϕ)eiωtdtX(ω)=12π(A2i(ei(ω0t+ϕ)ei(ω0t+ϕ)))eiωtdtX(ω)=A2i2π(ei(ω0t+ϕ)eiωtdtei(ω0t+ϕ)eiωtdt)X(ω)=A2i2π(ei(ω0ω)teiϕdtei(ω0+ω)t)eiϕdt)X(ω)=A2i2π(eiϕei(ω0ω)tdteiϕei(ω0+ω)t)dt)\begin{align} X(\omega) &= \dfrac{1}{\sqrt{2 \pi}} \displaystyle\int_{-\infty}^{\infty} A \sin(\omega_0 t + \phi) e^{-i \omega t} dt \\ X(\omega) &= \dfrac{1}{\sqrt{2 \pi}} \displaystyle\int_{-\infty}^{\infty} \left( \dfrac{A}{2 i} (e^{i(\omega_0 t + \phi)} - e^{-i(\omega_0 t + \phi)}) \right) e^{-i \omega t} dt\\ X(\omega) &= \dfrac{A}{2 i \sqrt{2 \pi}} \left( \displaystyle\int_{-\infty}^{\infty} e^{i(\omega_0 t + \phi)} e^{-i \omega t} dt - \displaystyle\int_{-\infty}^{\infty} e^{-i(\omega_0 t + \phi)} e^{-i \omega t} dt \right)\\ X(\omega) &= \dfrac{A}{2 i \sqrt{2 \pi}} \left( \displaystyle\int_{-\infty}^{\infty} e^{i(\omega_0 - \omega) t} e^{i \phi} dt - \displaystyle\int_{-\infty}^{\infty} e^{-i(\omega_0 + \omega) t)} e^{-i \phi} dt \right)\\ X(\omega) &= \dfrac{A}{2 i \sqrt{2 \pi}} \left( e^{i \phi} \displaystyle\int_{-\infty}^{\infty} e^{i(\omega_0 - \omega) t} dt - e^{-i \phi} \displaystyle\int_{-\infty}^{\infty} e^{-i(\omega_0 + \omega) t)} dt \right) \end{align}

At this point, we have two distinct integrals over infinite time for a complex exponential ei(ω0ω)te^{i(\omega_0 - \omega) t} and ei(ω0+ω)t)e^{-i(\omega_0 + \omega) t)}. These are just phasors, like we looked at before, that oscillate around zero infinitely.
They should integrate to exactly zero over infinite time.

There is only one possible value where no oscillations happen: when ω=+ω0\omega = +\omega_0 for the left integral, or ω=ω0\omega = -\omega_0 for the right integral. The integral over the exponentials yield Dirac delta functions at those frequencies: they evaluate to 2πδ(ωω0)2 \pi \delta(\omega - \omega_0) and 2πδ(ω+ω0)2 \pi \delta(\omega + \omega_0).

Plugging into our results above yields

X(ω)=A2i2π(eiϕ(2πδ(ωω0))eiϕ(2πδ(ω+ω0)))X(ω)=iAπ2(eiϕδ(ωω0)eiϕδ(ω+ω0))\begin{align} X(\omega) &= \dfrac{A}{2 i \sqrt{2 \pi}} \left( e^{i \phi} (2 \pi \delta(\omega - \omega_0)) - e^{-i \phi} (2 \pi \delta(\omega + \omega_0)) \right)\\ X(\omega) &= -i A \sqrt{\dfrac{\pi}{2}} \left( e^{i \phi} \delta(\omega - \omega_0) - e^{-i \phi} \delta(\omega + \omega_0) \right) \end{align}

So we get a Fourier Transform result with two Dirac delta peaks located at only ω=±ω0\omega = \pm \omega_0, with amplitude Aπ2A \sqrt{\dfrac{\pi}{2}} and phases ieiϕ-i e^{i \phi} and ieiϕi e^{-i \phi}