Python complex Lab

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

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top