在数学和工程计算中,复数(Complex Number)是一个基础但极其重要的概念。标准的复数由实部(real part)和虚部(imaginary part)组成,形式为a + bi,其中i是虚数单位,满足i² = -1。虽然Python等语言的标准库已经提供了复数类型,但自己实现一个复数类仍然是理解面向对象编程和运算符重载的绝佳练习。
通过这个项目,你将掌握:
我们先从最基本的类结构开始:
python复制class Complex:
def __init__(self, real=0, imag=0):
self.real = real
self.imag = imag
这个简单的构造函数允许我们通过两种方式创建复数:
Complex(3, 4) 创建3 + 4iComplex() 创建0 + 0i注意:这里我们为参数设置了默认值0,这是Python中的常见做法,可以增加API的灵活性。
为了让我们的类更友好,我们需要实现__str__方法:
python复制def __str__(self):
if self.imag >= 0:
return f"{self.real} + {self.imag}i"
else:
return f"{self.real} - {-self.imag}i"
这样当我们调用print(Complex(3, -4))时,会输出"3 - 4i"而不是默认的对象内存地址。
复数的加法遵循分量相加的原则:
(a + bi) + (c + di) = (a + c) + (b + d)i
实现代码:
python复制def __add__(self, other):
if isinstance(other, Complex):
return Complex(self.real + other.real, self.imag + other.imag)
elif isinstance(other, (int, float)):
return Complex(self.real + other, self.imag)
else:
raise TypeError("不支持的类型")
这里我们做了类型检查,允许复数和复数相加,也允许复数和实数相加。
复数的乘法稍微复杂一些:
(a + bi) * (c + di) = (ac - bd) + (ad + bc)i
实现代码:
python复制def __mul__(self, other):
if isinstance(other, Complex):
real = self.real * other.real - self.imag * other.imag
imag = self.real * other.imag + self.imag * other.real
return Complex(real, imag)
elif isinstance(other, (int, float)):
return Complex(self.real * other, self.imag * other)
else:
raise TypeError("不支持的类型")
类似地,我们可以实现减法和除法。复数除法需要有理化分母:
python复制def __truediv__(self, other):
if isinstance(other, Complex):
denominator = other.real**2 + other.imag**2
real = (self.real * other.real + self.imag * other.imag) / denominator
imag = (self.imag * other.real - self.real * other.imag) / denominator
return Complex(real, imag)
elif isinstance(other, (int, float)):
return Complex(self.real / other, self.imag / other)
else:
raise TypeError("不支持的类型")
复数的模定义为√(a² + b²):
python复制def modulus(self):
return (self.real**2 + self.imag**2)**0.5
共轭复数是将虚部取负:a - bi
python复制def conjugate(self):
return Complex(self.real, -self.imag)
复数在数学上不能直接比较大小,但我们可以比较它们的模:
python复制def __eq__(self, other):
if isinstance(other, Complex):
return self.real == other.real and self.imag == other.imag
elif isinstance(other, (int, float)):
return self.real == other and self.imag == 0
else:
raise TypeError("不支持的类型")
def __lt__(self, other):
if isinstance(other, (Complex, int, float)):
return self.modulus() < (other.modulus() if isinstance(other, Complex) else abs(other))
else:
raise TypeError("不支持的类型")
注意:复数比较是一个有争议的话题,因为复数本身没有自然的全序关系。这里我们选择比较模,但在实际应用中需要谨慎。
复数也可以用极坐标表示(r, θ),其中r是模,θ是幅角:
python复制import math
def to_polar(self):
r = self.modulus()
theta = math.atan2(self.imag, self.real)
return (r, theta)
@classmethod
def from_polar(cls, r, theta):
real = r * math.cos(theta)
imag = r * math.sin(theta)
return cls(real, imag)
我们可以实现一些常用的数学函数:
python复制def exp(self):
"""计算e^(a+bi) = e^a * (cosb + i sinb)"""
r = math.exp(self.real)
return Complex(r * math.cos(self.imag), r * math.sin(self.imag))
为我们的复数类编写单元测试是确保其正确性的关键:
python复制import unittest
class TestComplex(unittest.TestCase):
def test_add(self):
c1 = Complex(3, 4)
c2 = Complex(1, 2)
self.assertEqual(c1 + c2, Complex(4, 6))
def test_mul(self):
c1 = Complex(1, 1)
c2 = Complex(1, -1)
self.assertEqual(c1 * c2, Complex(2, 0))
def test_modulus(self):
c = Complex(3, 4)
self.assertAlmostEqual(c.modulus(), 5.0)
对于频繁的复数运算,纯Python实现可能不够高效。在实际应用中,可以考虑:
complex类型复数类的一个经典应用是绘制曼德勃罗集分形:
python复制def mandelbrot(c, max_iter=100):
z = Complex()
for i in range(max_iter):
z = z * z + c
if z.modulus() > 2:
return i
return max_iter
在信号处理中,复数用于表示相位和幅度:
python复制def dft(signal):
N = len(signal)
return [sum(signal[n] * Complex.exp(-2j * math.pi * k * n / N)
for n in range(N)) / N
for k in range(N)]
对于频繁调用的方法如modulus(),可以考虑缓存结果:
python复制def __init__(self, real=0, imag=0):
self.real = real
self.imag = imag
self._modulus = None
def modulus(self):
if self._modulus is None:
self._modulus = (self.real**2 + self.imag**2)**0.5
return self._modulus
可以继续扩展支持:
__pow__为增加代码可读性和IDE支持,可以添加类型注解:
python复制from typing import Union, Tuple
class Complex:
def __init__(self, real: float = 0, imag: float = 0) -> None:
self.real = real
self.imag = imag
def __add__(self, other: Union['Complex', float]) -> 'Complex':
...
实现一个完整的复数类是理解Python面向对象编程的绝佳练习。从基础运算到高级功能,每一步都涉及到重要的编程概念。在实际项目中,除非有特殊需求,否则建议使用Python内置的complex类型或NumPy的复数支持,它们经过高度优化且功能完善。