Skip to main content

Python complex Lab

· 5 min read

Lab: The Complex Navigator​

Try this code to understand how complex numbers handle coordinates:

import cmath

# 1. Define a point in 2D space
point = 4 + 3j

# 2. Calculate distance from origin (Magnitude)
distance = abs(point)
print(f"Distance: {distance}") # Result: 5.0 (3-4-5 triangle)

# 3. Rotate the point by 90 degrees
# Multiplying by 1j rotates a point by 90 degrees counter-clockwise
rotated_point = point * 1j
print(f"Original: {point} | Rotated: {rotated_point}")

# 4. Extracting Polar Coordinates
magnitude, phase = cmath.polar(point)
print(f"Angle in Radians: {phase}")

Lab: The Vector Rotation Challenge (Beginner)​

Scenario: You are developing a simple 2D game engine. Rotating a point 90∘ is a frequent task.

  • Task: Define a complex number z = 5 + 2j.

  • The Problem: Multiply z by 1j and print the result. Then multiply it by 1j again.

  • The Discovery: Observe how multiplying by j rotates a point by 90∘ counter-clockwise on the complex plane.

  • Code Goal: ```python z = 5 + 2j rotate_90 = z * 1j rotate_180 = rotate_90 * 1j print(rotate_90, rotate_180)

Solution: The Vector Rotation Challenge

Logic: In mathematics, multiplying a coordinate (x,y) by the imaginary unit i (or j in Python) results in (−y,x), which is a 90∘ rotation.

z = 5 + 2j
# First 90-degree rotation
rotate_90 = z * 1j
print(f"90° Rotation: {rotate_90}")
# Expected Output: (-2+5j)

# Second rotation (180 degrees total)
rotate_180 = rotate_90 * 1j
print(f"180° Rotation: {rotate_180}")
# Expected Output: (-5-2j)

Lab : Safe Comparisons (Intermediate)​

Scenario: You are building a monitoring tool that ranks server "health scores" represented by complex numbers (where real is uptime and imaginary is load).

  • Task: Try to compare two complex numbers using >.

  • z1 = 3 + 4j

  • z2 = 5 + 2j

  • The Problem: Python will throw a TypeError.

  • The Fix: Write a function compare_complex(c1, c2) that compares them based on their Magnitude (distance from zero).

  • Hint: Use the abs() function.

Solution: Safe Comparisons (Magnitude Ranking)

Logic: Since Python doesn't know if 3+4j is "bigger" than 5+2j, we calculate their distance from the origin (0,0) using the Pythagorean theorem, which abs() handles automatically.

def compare_complex(c1, c2):
mag1 = abs(c1)
mag2 = abs(c2)

if mag1 > mag2:
return f"{c1} has a larger magnitude ({mag1:.2f}) than {c2} ({mag2:.2f})"
elif mag1 < mag2:
return f"{c2} has a larger magnitude ({mag2:.2f}) than {c1} ({mag1:.2f})"
else:
return "Both numbers have equal magnitude."

z1 = 3 + 4j # Magnitude 5.0
z2 = 5 + 2j # Magnitude 5.38
print(compare_complex(z1, z2))

Lab: Extracting Polar Data (Advanced)​

Scenario: You are working with radar data. The data arrives as (real, imag), but you need the Range (magnitude) and Bearing (angle).

  • Task: Import the cmath module.

  • The Problem: Use cmath.polar() to convert z = 1 + 1j into magnitude and phase.

  • The Validation: Use cmath.rect(magnitude, phase) to convert it back to its original form.

  • Missing Logic to Spot: Why is the phase of 1 + 1j equal to 0.785... radians? (Hint: It is 4π​ or 45∘).

Solution: Extracting Polar Data

Logic: Radar and Signal systems often need "Angle and Distance" rather than "X and Y".

import cmath

z = 1 + 1j

# Convert to Polar (Magnitude, Phase in Radians)
magnitude, phase = cmath.polar(z)
print(f"Distance: {magnitude}") # 1.414... (sqrt of 2)
print(f"Angle (Radians): {phase}") # 0.785... (pi/4)

# Convert back to Rectangular
original = cmath.rect(magnitude, phase)
print(f"Back to Rectangular: {original}")

Lab 4: Solving "Impossible" Quadratics (Architect Level)​

Scenario: You are writing a mathematical solver for a DevSecOps encryption algorithm that involves square roots of negative numbers.

  • Task: Solve the quadratic equation x2+1=0.

  • The Problem: Using math.sqrt(-1) will crash with a ValueError.

  • The Solution: Use cmath.sqrt(-1).

  • Architect Note: In production, always check if your inputs are likely to produce complex results to decide whether to use math (faster) or cmath (more capable).

Solution: Solving "Impossible" Quadratics​

Logic: Standard math.sqrt raises a ValueError for negative inputs because it only supports Real numbers. cmath is designed for the Complex domain.

import cmath

# Equation: x^2 + 1 = 0 -> x^2 = -1 -> x = sqrt(-1)
try:
# This would fail: import math; math.sqrt(-1)
solution1 = cmath.sqrt(-1)
solution2 = -cmath.sqrt(-1)

print(f"The roots of x^2 + 1 are: {solution1} and {solution2}")
except ValueError as e:
print(f"Calculation failed: {e}")

Lab 5: Precision and Floating Point Drift (Architect Level)​

Scenario: Complex numbers use two floats. This means they inherit all the "float traps" we discussed earlier.

  • Task: 1. Calculate z = (0.1 + 0.2j) + (0.1 + 0.2j). 2. Check if z.real == 0.2 and z.imag == 0.4.

  • The Problem: Observe the tiny precision errors in the real and imaginary components.

  • The Fix: Implement a complex_isclose function using math.isclose for both the .real and .imag parts separately.

Solution: The "Complex Is Close" Function

Logic: To avoid floating-point drift errors in complex numbers, you must verify that both the Real and Imaginary parts are "close enough" to the target.

import math

def complex_isclose(c1, c2, rel_tol=1e-9):
real_match = math.isclose(c1.real, c2.real, rel_tol=rel_tol)
imag_match = math.isclose(c1.imag, c2.imag, rel_tol=rel_tol)
return real_match and imag_match

# Testing precision drift
z_calc = (0.1 + 0.2j) + (0.1 + 0.2j)
z_target = 0.2 + 0.4j

print(f"Direct Equality: {z_calc == z_target}") # Might be False
print(f"Secure Equality: {complex_isclose(z_calc, z_target)}") # True