Data Science

🐍 Visualizing Complex Analysis With Python That Will 10x Your Python Developer!

Hey there! Ready to dive into Visualizing Complex Analysis With Python? This friendly guide will walk you through everything step-by-step with easy-to-follow examples. Perfect for beginners and pros alike!

SuperML Team
Share this article

Share:

🚀

💡 Pro tip: This is one of those techniques that will make you look like a data science wizard! Introduction to Complex Analysis - Made Simple!

Complex analysis is a branch of mathematics that studies functions of complex numbers. It has wide-ranging applications in physics, engineering, and other fields of mathematics.

This next part is really neat! Here’s how we can tackle this:

import numpy as np
import matplotlib.pyplot as plt

def complex_plane(z):
    return z.real, z.imag

z = 2 + 3j
x, y = complex_plane(z)

plt.figure(figsize=(8, 8))
plt.scatter(x, y, color='red')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.title('Complex Number on Complex Plane')
plt.xlabel('Real')
plt.ylabel('Imaginary')
plt.grid(True)
plt.show()

🚀

🎉 You’re doing great! This concept might seem tricky at first, but you’ve got this! Complex Numbers - Made Simple!

Complex numbers are numbers of the form a + bi, where a and b are real numbers and i is the imaginary unit (i² = -1).

Let’s break this down together! Here’s how we can tackle this:

class ComplexNumber:
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag
    
    def __str__(self):
        return f"{self.real} + {self.imag}i"

z1 = ComplexNumber(3, 4)
print(f"Complex number: {z1}")

🚀

Cool fact: Many professional data scientists use this exact approach in their daily work! Basic Operations on Complex Numbers - Made Simple!

Complex numbers support addition, subtraction, multiplication, and division.

Here’s a handy trick you’ll love! Here’s how we can tackle this:

def add_complex(z1, z2):
    return ComplexNumber(z1.real + z2.real, z1.imag + z2.imag)

def multiply_complex(z1, z2):
    real = z1.real * z2.real - z1.imag * z2.imag
    imag = z1.real * z2.imag + z1.imag * z2.real
    return ComplexNumber(real, imag)

z1 = ComplexNumber(1, 2)
z2 = ComplexNumber(3, 4)
print(f"Sum: {add_complex(z1, z2)}")
print(f"Product: {multiply_complex(z1, z2)}")

🚀

🔥 Level up: Once you master this, you’ll be solving problems like a pro! Polar Form of Complex Numbers - Made Simple!

Complex numbers can be represented in polar form (r, θ), where r is the magnitude and θ is the argument.

Don’t worry, this is easier than it looks! Here’s how we can tackle this:

import cmath

def polar_form(z):
    r = abs(z)
    theta = cmath.phase(z)
    return r, theta

z = 1 + 1j
r, theta = polar_form(z)
print(f"Polar form: r = {r:.2f}, θ = {theta:.2f} radians")

🚀 Euler’s Formula - Made Simple!

Euler’s formula establishes a fundamental relationship between trigonometric functions and the complex exponential function.

Let me walk you through this step by step! Here’s how we can tackle this:

import numpy as np

def euler_formula(x):
    return np.cos(x) + 1j * np.sin(x)

x = np.pi / 4
result = euler_formula(x)
print(f"e^(i*π/4) = {result:.4f}")

🚀 Complex Functions - Made Simple!

Complex functions map complex numbers to complex numbers. They can be visualized using domain coloring.

Don’t worry, this is easier than it looks! Here’s how we can tackle this:

import numpy as np
import matplotlib.pyplot as plt

def complex_function(z):
    return z**2 + 2*z + 1

x = np.linspace(-2, 2, 400)
y = np.linspace(-2, 2, 400)
X, Y = np.meshgrid(x, y)
Z = X + 1j*Y

W = complex_function(Z)
plt.imshow(np.angle(W), cmap='hsv', extent=[-2, 2, -2, 2])
plt.title('Domain Coloring of f(z) = z² + 2z + 1')
plt.xlabel('Real')
plt.ylabel('Imaginary')
plt.colorbar(label='Argument')
plt.show()

🚀 Analytic Functions - Made Simple!

Analytic functions are complex functions that are differentiable at every point in their domain.

Don’t worry, this is easier than it looks! Here’s how we can tackle this:

def is_analytic(f, z, h=1e-6):
    dz = h + 1j*h
    df_dx = (f(z + h) - f(z)) / h
    df_dy = (f(z + 1j*h) - f(z)) / (1j*h)
    return np.isclose(df_dx, df_dy.conjugate())

def f(z):
    return z**2

z = 1 + 1j
print(f"Is f(z) = z² analytic at {z}? {is_analytic(f, z)}")

🚀 Cauchy-Riemann Equations - Made Simple!

The Cauchy-Riemann equations are necessary conditions for a complex function to be analytic.

Don’t worry, this is easier than it looks! Here’s how we can tackle this:

def cauchy_riemann(u, v, x, y, h=1e-6):
    du_dx = (u(x + h, y) - u(x, y)) / h
    du_dy = (u(x, y + h) - u(x, y)) / h
    dv_dx = (v(x + h, y) - v(x, y)) / h
    dv_dy = (v(x, y + h) - v(x, y)) / h
    return np.isclose(du_dx, dv_dy) and np.isclose(du_dy, -dv_dx)

def u(x, y):
    return x**2 - y**2

def v(x, y):
    return 2*x*y

x, y = 1, 1
print(f"Do u and v satisfy C-R equations at ({x}, {y})? {cauchy_riemann(u, v, x, y)}")

🚀 Complex Integration - Made Simple!

Complex integration involves integrating complex functions along paths in the complex plane.

Ready for some cool stuff? Here’s how we can tackle this:

import scipy.integrate as integrate

def integrand(t):
    return np.exp(1j * t)

def path(t):
    return np.cos(t) + 1j * np.sin(t)

result, _ = integrate.quad(lambda t: integrand(t) * np.abs(path(t)), 0, 2*np.pi)
print(f"∫exp(iz)dz along the unit circle: {result:.4f}")

🚀 Cauchy’s Integral Formula - Made Simple!

Cauchy’s Integral Formula relates the values of an analytic function inside a closed contour to the values on the contour.

This next part is really neat! Here’s how we can tackle this:

def cauchy_integral(f, z0, radius, n_points=1000):
    theta = np.linspace(0, 2*np.pi, n_points)
    z = z0 + radius * np.exp(1j * theta)
    integrand = f(z) / (z - z0)
    integral = np.trapz(integrand, theta) * 1j / (2 * np.pi)
    return integral

def f(z):
    return 1 / (z**2 + 1)

z0 = 0 + 0j
radius = 2
result = cauchy_integral(f, z0, radius)
print(f"f({z0}) by Cauchy's formula: {result:.4f}")
print(f"f({z0}) directly: {f(z0):.4f}")

🚀 Residue Theorem - Made Simple!

The residue theorem is a powerful tool for evaluating complex integrals.

Let’s make this super clear! Here’s how we can tackle this:

def residue(f, z0, order=1):
    def coefficient(n):
        return np.polyder(lambda z: f(z + z0), n)(0) / np.math.factorial(n)
    return coefficient(order - 1)

def f(z):
    return 1 / (z**2 + 1)

z0 = 1j
res = residue(f, z0)
print(f"Residue of 1/(z²+1) at z = i: {res:.4f}")

🚀 Laurent Series - Made Simple!

Laurent series extend power series to include negative powers, useful for analyzing functions near singularities.

Let’s make this super clear! Here’s how we can tackle this:

from sympy import Symbol, series, oo

def laurent_series(f, z0, n):
    z = Symbol('z')
    return series(f(z), (z, z0), n=n)

def f(z):
    return 1 / (z**2 + 1)

z0 = 0
n = 5
laurent = laurent_series(f, z0, n)
print(f"Laurent series of 1/(z²+1) around z = 0:")
print(laurent)

🚀 Applications in Signal Processing - Made Simple!

Complex analysis is crucial in signal processing, particularly in Fourier analysis.

Don’t worry, this is easier than it looks! Here’s how we can tackle this:

import numpy as np
import matplotlib.pyplot as plt

def fourier_transform(t, signal):
    return np.fft.fft(signal)

t = np.linspace(0, 1, 1000)
signal = np.sin(2 * np.pi * 10 * t) + 0.5 * np.sin(2 * np.pi * 20 * t)

ft = fourier_transform(t, signal)
freq = np.fft.fftfreq(len(t), t[1] - t[0])

plt.figure(figsize=(12, 6))
plt.subplot(211)
plt.plot(t, signal)
plt.title('Original Signal')
plt.subplot(212)
plt.plot(freq, np.abs(ft))
plt.title('Frequency Spectrum')
plt.xlim(0, 30)
plt.show()

🚀 Applications in Fluid Dynamics - Made Simple!

Complex analysis is used in fluid dynamics to model 2D fluid flow.

Let’s break this down together! Here’s how we can tackle this:

import numpy as np
import matplotlib.pyplot as plt

def complex_potential(z, strength):
    return strength * np.log(z)

x = np.linspace(-2, 2, 100)
y = np.linspace(-2, 2, 100)
X, Y = np.meshgrid(x, y)
Z = X + 1j*Y

W = complex_potential(Z, 1)
phi = W.real
psi = W.imag

plt.figure(figsize=(10, 8))
plt.contour(X, Y, phi, colors='blue', levels=20)
plt.contour(X, Y, psi, colors='red', levels=20)
plt.title('Flow Around a Point Vortex')
plt.xlabel('x')
plt.ylabel('y')
plt.axis('equal')
plt.show()

🚀 Additional Resources - Made Simple!

For further study in complex analysis, consider these resources:

  1. ArXiv.org paper: “A Visual Introduction to Complex Analysis” by Elias Wegert URL: https://arxiv.org/abs/1208.3282
  2. ArXiv.org paper: “Complex Analysis: A Visual and Interactive Introduction” by Juan Carlos Ponce Campuzano URL: https://arxiv.org/abs/1905.01239

These papers provide visual and interactive approaches to learning complex analysis, which can complement the coding examples we’ve explored in this presentation.

🎊 Awesome Work!

You’ve just learned some really powerful techniques! Don’t worry if everything doesn’t click immediately - that’s totally normal. The best way to master these concepts is to practice with your own data.

What’s next? Try implementing these examples with your own datasets. Start small, experiment, and most importantly, have fun with it! Remember, every data science expert started exactly where you are right now.

Keep coding, keep learning, and keep being awesome! 🚀

Back to Blog

Related Posts

View All Posts »