复数
复数类的模板。(然而如果你实现了一个template向量模板的话,只需要修改一点东西就可以变成复数)
形同 a + b i a+bi a+bi的数就称为复数,其中 i = − 1 i=\sqrt{-1} i=−1。
c++里面有std::complex,不过自己实现一个会更快。
模板
下面是以double实现的复数,也可以使用template。
struct Complex {
double x, y; // 实部与虚部
Complex(double x = 0, double y = 0) : x(x), y(y) {}
inline friend Complex operator + (const Complex &a, const Complex &b) {
return Complex(a.x + b.x, a.y + b.y);
}
inline friend Complex operator - (const Complex &a, const Complex &b) {
return Complex(a.x - b.x, a.y - b.y);
}
inline friend Complex operator * (const Complex &a, const Complex &b) {
return Complex(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
}
inline friend Complex operator / (const Complex &a, const Complex &b) {
double t = b.x * b.x + b.y * b.y;
return Complex((a.x * b.x + a.y * b.y) / t, (a.y * b.x - a.x * b.y) / t);
}
double modulo() { // 复数的模
return hypot(x, y);
}
};
复数的一些运算跟向量相似,比如加法和减法。
基本运算
这里只讲加减乘除和复数的模。
复数加法
复数加法,只需要两个复数的实部相加,然后两个虚部再相加,即可。
(
a
1
+
b
1
i
)
+
(
a
2
+
b
2
i
)
=
(
a
1
+
a
2
)
+
(
b
1
+
b
2
)
i
(a_1+b_1i)+(a_2+b_2i)=(a_1+a_2)+(b_1+b_2)i
(a1+b1i)+(a2+b2i)=(a1+a2)+(b1+b2)i
具体代码表现为:
inline friend Complex operator + (const Complex &a, const Complex &b) {
return Complex(a.x + b.x, a.y + b.y);
}
复数减法
复数的减法,可以看作为复数加法的逆运算。
(
a
1
+
b
1
i
)
−
(
a
2
+
b
2
i
)
=
(
a
1
−
a
2
)
+
(
b
1
−
b
2
)
i
(a_1+b_1i)-(a_2+b_2i)=(a_1-a_2)+(b_1-b_2)i
(a1+b1i)−(a2+b2i)=(a1−a2)+(b1−b2)i
具体代码为:
inline friend Complex operator - (const Complex &a, const Complex &b) {
return Complex(a.x - b.x, a.y - b.y);
}
复数乘法
复数乘法类似于多项式乘法,最后记得把
i
2
i^2
i2化简就好。
(
a
1
+
b
1
i
)
×
(
a
2
+
b
2
i
)
=
a
1
a
2
+
a
1
b
2
i
+
b
1
a
2
i
+
b
1
b
2
i
2
=
(
a
1
a
2
−
b
1
b
2
)
+
(
a
1
b
2
+
b
1
a
2
1
)
i
(a_1+b_1i) \times (a_2+b_2i)=a_1a_2+a_1b_2i+b_1a_2i+b_1b_2i^2=(a_1a_2-b_1b_2)+(a_1b_2+b_1a_21)i
(a1+b1i)×(a2+b2i)=a1a2+a1b2i+b1a2i+b1b2i2=(a1a2−b1b2)+(a1b2+b1a21)i
简单来说,就是:
(
a
1
+
b
1
i
)
×
(
a
2
+
b
2
i
)
=
(
a
1
a
2
−
b
1
b
2
)
+
(
a
1
b
2
+
b
1
a
2
1
)
i
(a_1+b_1i) \times (a_2+b_2i)=(a_1a_2-b_1b_2)+(a_1b_2+b_1a_21)i
(a1+b1i)×(a2+b2i)=(a1a2−b1b2)+(a1b2+b1a21)i
代码如下。
inline friend Complex operator * (const Complex &a, const Complex &b) {
return Complex(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
}
复数除法
复数除法需要引入一个关于复数的概念,即共轭复数。
具体来讲,共轭复数就是虚部为相反数的复数。比如, a + b i a+bi a+bi和 a − b i a-bi a−bi即为一对共轭复数。
引入共轭复数概念后,就可以进行复数除法了。
考虑一对共轭复数相乘
基于上述概念,对于
a
+
b
i
a+bi
a+bi和
a
−
b
i
a-bi
a−bi,相乘有如下结果:
(
a
+
b
i
)
×
(
a
−
b
i
)
=
a
2
−
a
b
i
+
b
a
i
+
b
2
=
a
2
+
b
2
(a+bi)\times(a-bi)=a^2-abi+bai+b^2=a^2+b^2
(a+bi)×(a−bi)=a2−abi+bai+b2=a2+b2
可见,共轭复数相乘的结果为一个实数(准确来讲是虚部为0的复数)。
进行除法
对于
a
1
+
b
1
i
a_1+b_1i
a1+b1i和
a
2
+
b
2
i
a_2+b_2i
a2+b2i,按照通常除法的定义,即为:
a
1
+
b
1
i
a
2
+
b
2
i
\frac{a_1+b_1i}{a_2+b_2i}
a2+b2ia1+b1i
这时候,这个新产生的复数有点复杂。让上下同时乘以分母的共轭复数,得:
(
a
1
+
b
1
i
)
(
a
2
−
b
2
i
)
(
a
2
+
b
2
i
)
(
a
2
−
b
2
i
)
=
(
a
1
+
b
1
i
)
(
a
2
−
b
2
i
)
a
2
2
+
b
2
2
\frac{(a_1+b_1i)(a_2-b_2i)}{(a_2+b_2i)(a_2-b_2i)}=\frac{(a_1+b_1i)(a_2-b_2i)}{a_2^2+b_2^2}
(a2+b2i)(a2−b2i)(a1+b1i)(a2−b2i)=a22+b22(a1+b1i)(a2−b2i)
这样,这个复数就看上去简单化了。 让上面的乘法张开,可得:
(
a
1
+
b
1
i
)
(
a
2
−
b
2
i
)
a
2
2
+
b
2
2
=
(
a
1
a
2
+
b
1
b
2
)
+
(
b
1
a
2
−
a
1
b
2
)
i
a
2
2
+
b
2
2
=
a
1
a
2
+
b
1
b
2
a
2
2
+
b
2
2
+
b
1
a
2
−
a
1
b
2
a
2
2
+
b
2
2
i
\frac{(a_1+b_1i)(a_2-b_2i)}{a_2^2+b_2^2}=\frac{(a_1a_2+b_1b_2)+(b_1a_2-a_1b_2)i}{a_2^2+b_2^2}=\frac{a_1a_2+b_1b_2}{a_2^2+b_2^2}+\frac{b_1a_2-a_1b_2}{a_2^2+b_2^2}i
a22+b22(a1+b1i)(a2−b2i)=a22+b22(a1a2+b1b2)+(b1a2−a1b2)i=a22+b22a1a2+b1b2+a22+b22b1a2−a1b2i
这样,就得到了复数除法的结果。
a
1
+
b
1
i
a
2
+
b
2
i
=
a
1
a
2
+
b
1
b
2
a
2
2
+
b
2
2
+
b
1
a
2
−
a
1
b
2
a
2
2
+
b
2
2
i
\frac{a_1+b_1i}{a_2+b_2i}=\frac{a_1a_2+b_1b_2}{a_2^2+b_2^2}+\frac{b_1a_2-a_1b_2}{a_2^2+b_2^2}i
a2+b2ia1+b1i=a22+b22a1a2+b1b2+a22+b22b1a2−a1b2i
这里是代码实现:
inline friend Complex operator / (const Complex &a, const Complex &b) {
double t = b.c * b.c + b.d * b.d;
return Complex((a.x * b.x + a.y * b.y) / t, (a.y * b.x - a.x * b.y) / t);
}
复数的模
复数的模和向量的模类似。
∣
a
+
b
i
∣
=
a
2
+
b
2
|a+bi|=\sqrt{a^2+b^2}
∣a+bi∣=a2+b2
这是其中一种实现方式:
double Complex::modulo() {
return sqrt(x * x + y * y);
}
另一种,可以使用hypot函数(这玩意也经常用来求向量的模)。
double Complex::modulo() {
return hypot(x, y);
}