定义

什么是欧拉公式?

$$ e^{i\pi}+1=0 $$

这个公式将:

  • $e$:自然对数的底;
  • $i$:虚数的单位;
  • $\pi$:圆周率

结合到了一起,优美巧妙,因此也被称为“上帝公式”。

Quote / 参考

维基百科:欧拉公式

复数i与自然常数e

在推导与证明欧拉公式之前,有必要对其中两个重要组成部分:

  • 复数——$i$;
  • 自然常数——$e$

进行复习。

复数i

复数$i$的定义其实很简单,就是:

$$ i^2=-1 $$

最初提出复数的那一帮人,就是因为解高次方程的时候会遇到这样的情况:

$$ x^2+1=0 $$

虽然在我们对于自然数的理解下,这样求解出来的数没有任何实际意义,但是其在数学中却是真实存在的。

数学家们之间的解方程大赛
数学家们之间的解方程大赛

对于复数这个在自然界不存在,但是在数学中却是存在的东西,笛卡尔将其命名为Imaginary number——想象中的数字。

意义

所以,复数在数学中的意义到底应该是什么呢?仅仅就是为了解方程吗🤔?我们又是如何来表达它呢?接下来,让我们通过一个小例子来认识下它:

从自然数1开始,将其与$i$相乘,得到了:

$$ 1×i=i $$

在此基础上,然后再乘一个$i$:

$$ 1×i×i=-1 $$

可以看到,自然数1再经过两次乘$i$后,完成了反向。如果再乘上两个:

$$ 1×i×i×i×i=1 $$

之后会发现,1竟然又回到了最初的起点。

看到了这里,你的心里可能已经猜到了😆——这个过程,像极了旋转:

所以,这个时候我们很容易会发现复数虚部所在的轴与实部所在的轴构成了一个平面。在这个平面中,一个复数的实部为x轴,虚部$i$为y轴,两者张成了一个二维复平面。

对于一个复数$4+3i$,其在复平面上的表达类似于一个向量:

运算

加法运算

在复平面中,复数的运算法则遵循矢量运算法则(平行四边形法则,实部与实部相加,虚部与虚部相加),例如:

$$ (-1+2i)+(2-1i)=1+i $$

乘法运算

令:

$$ y=\begin{cases} 1, n=0\\ \left( 1+i \right) ^n, n>0\\ \end{cases} $$

计算得:

$$ y_{n=0}=1 \\ y_{n=1}=1+i \\ y_{n=2}=\left( 1+i \right) ^2=1+2i+\left( i \right) ^2=2i \\ y_{n=3}=\left( 1+i \right) ^3=2i\times \left( 1+i \right) =-2+2i \\ y_{n=4}=\left( 1+i \right) ^4=2i\times 2i=-4 \\ ... $$

依次绘制出$y_{n=0}、y_{n=1}、y_{n=2}、...$,会发现:$y_{m-1}$乘上$1+i$后变成了$y_{m}$。相比之下,$y_{m}$由$y_{m-1}$所代表的向量旋转45°,且模长变为原来得$\sqrt{2}$倍得来。其中45°是$1+i$与x轴的夹角,$\sqrt{2}$是$1+i$在复平面的模长。

由此,我们可以进行一个推广:在复平面上,一个复数$b=m+ni$乘上任意一个复数$a$,其几何含义为:让这个复数$a$所代表的向量进行旋转并缩放,旋转的角度(复数$b$的辐角,即$m+ni$与x轴的夹角)为$arctan\frac{n}{m}$,缩放倍数(复数$b$的模长)为$\sqrt{m^2+n^2}$。

一个有趣的现象,如果我们在复平面上绘制出$(1+i)^n$所代表的点:

参考Python绘图代码

def get_value(n):
    x = (1 + 1j) ** n
    return x.real, x.imag


def plot_arrow(x, y, ax=plt, lines=True):
    if lines:
        ax.vlines(x, 0, y, 'r', '--')
        ax.hlines(y, 0, x, 'r', '--')
    ax.arrow(0, 0, x, y,
             color='cyan',
             head_width=0.2,
             fc='y',
             length_includes_head=True
             )


def plot_text(x, y, ax=plt):
    valign, halign = None, None
    if y > 0:
        text_y = f'{y}i'
        if x != 0: text_y = '+' + text_y
        y += .2
        valign = 'bottom'
    elif y == 0:
        text_y = ''
        y += .2
        valign = 'bottom'
    else:
        text_y = f'{y}i'
        y -= .2
        valign = 'top'

    if x > 0:
        text_x = f'{x}'
        x += .2
        halign = 'left'
    elif x == 0:
        text_x = ''
        x += .2
        halign = 'left'
    else:
        text_x = f'{x}'
        x -= .2
        halign = 'right'

    ax.text(x=x, y=y,  #文本x、y轴坐标
            s=f'${text_x}{text_y}$',  #文本内容
            fontdict=dict(fontsize=12),  #字体属性字典
            verticalalignment=valign,
            horizontalalignment=halign,
            bbox={  #添加文字背景色
                'facecolor': 'white',  #填充色
                'edgecolor': 'gray',  #外框色
                'alpha': 0.3,  #框透明度
                'pad': .1,  #本文与框周围距离
                'boxstyle': 'round'
            }
            )


# 绘图全局设置
plt.rcParams.update({
    # 'font.size': 15,
    'font.family': ['Times New Roman', 'SimSun']
})

limit_coor_num = 200

plt.hlines(0, -limit_coor_num, limit_coor_num, '#ccc', '--')
plt.vlines(0, -limit_coor_num, limit_coor_num, '#ccc', '--')

plt.xlim([-limit_coor_num, limit_coor_num])
plt.ylim([-limit_coor_num, limit_coor_num])
plt.yticks(
    [i for i in range(-limit_coor_num, limit_coor_num + 1) if i % 40 == 0],
    [f'{i}i' for i in range(-limit_coor_num, limit_coor_num + 1) if i % 40 == 0]
)

plt.xlabel('Real')
plt.ylabel('Imaginary')
plt.title('Complex Plane')
# plt.grid()

# point_list = [(1, 0), (0, 1), (-1, 0), (0, -1)]
# point_list = [(-1, 2), (2, -1), (1, 1)]

# for x, y in point_list:
#     plot_arrow(x, y)
#     plot_text(x, y)

# for i in range(8):
#     x, y = get_value(i)
#     plot_arrow(x, y, lines=False)
#     plot_text(x, y)

points_plt = [get_value(i) for i in np.linspace(0, 100, 1000)]
x, y = zip(*points_plt)
plt.scatter(x, y)

# plot_arrow(0, -2, lines=False)
# plot_text(0, -2)

plt.show()

Quote / 参考

Bilibili @隐姓埋名的刘老:复数,一个充满故事又奇特的数

自然常数e

在数学中$e$被称为自然常数(Natural Constant)。

$$ e=2.71828... $$

可是,自然数有这么多,为什么偏偏$e$会被称为自然常数

先来看一个简单的案例,在经济学中,有一个概念叫做复利运算。假设银行一年的年利率为100%,你在银行存了1块钱,那么一年之后你的存款应该会变为:

$$ 1×(1+100\%)=2 $$

但其实银行的利率往往还可以进行拆分,比如你把1块钱存在银行半年,这个时候利率就变成了50%,在半年后你拿到的钱就是:

$$ 1×(1+50\%)=1.5 $$

然后你可以将你的一块五再存银行半年,再经过半年后,你的钱就会变成:

$$ 1×(1+50\%)×(1+50\%)=1.5×(1+50\%)=2.25 $$

这个时候,你会惊奇地发现,一年分两次存钱比一次存钱要多拿到$0.25$!!!

那是不是意味着我分的次数越多就拿到的越多呢?

假设我们分为n期,那经过n期后我们的利率就会变为:

$$ (1+\frac{1}{n})^n $$

问题就是,随着n的增大,上面的利率真的会无限增大吗?在高等数学中,有这么一个极限定义:

$$ \underset{n\rightarrow \infty}{\lim}\left( 1+\frac{1}{n} \right) ^n=e $$

也就是说,随着$n$的无限增大,$(1+\frac{1}{n})^n$并不是也可以无穷增大的,而是趋近于一个值$2.718281828459045...$。而这个值,就是自然常数$e$的值。

上面这个分为n期的假设,其实非常符合自然界中万事万物发展的规律,一切事物的变化都不是突然来的,都是经过n期的逐渐积累,然后引发了质变。这也就是其名字“自然常数”的来历,因此其定义像极了世间万物发展的模式。

Quote / 参考

  1. Bilibili @隐姓埋名的刘老:自然常数e这个数,怎么就自然了?
  2. Bilibili @隐姓埋名的刘老:用几何直觉理解欧拉公式!【中学生也能懂|manim】

欧拉公式

思想的转变

由上面对于自然常数$e$的讲解可知:

$$ \underset{n\rightarrow \infty}{\lim}\left( 1+\frac{1}{n} \right) ^n=e $$

$e$的定义并不是一个“实实在在”存在的数字,那么对于$e^{i\pi}$,其也并不意味着$i\pi$个$e$相乘!!!

那么,$e^{i\pi}$到底代表什么呢?

对于上面提到的等式:

$$ \underset{n\rightarrow \infty}{\lim}\left( 1+\frac{1}{n} \right) ^n=e $$

还可以进行进一步的推广:

$$ \underset{n\rightarrow \infty}{\lim}\left( 1+\frac{x}{n} \right) ^n=e^x $$

那么欧拉公式就可以等价变换为:

$$ e^{i\pi} = \underset{n\rightarrow \infty}{\lim}\left( 1+\frac{i\pi}{n} \right) ^n $$

上面这个等式,才是$e^{i\pi}$的真正含义!!!

可视化求解

定义求极限的函数:

def get_value(n, p):
    x = np.power((1 + 3.14j / n), p)
    return x.real, x.imag

绘图:

plt.xlim([-3, 3])
plt.ylim([0, 4])
plt.yticks(
    [i for i in range(0, 5) if i % 2 == 0],
    [f'{i}i' for i in range(0, 5) if i % 2 == 0]
)

for i in [1, 2, 5, 10, 20, 10000]:
    point_coor = [get_value(i, j) for j in range(1, i + 1)]
    x, y = zip(*point_coor)
    plt.scatter(x, y, s=(1 / i) * 100, marker='*')
    plt.plot(x, y, label=f'n={i}')

# x、y轴等比例
ax = plt.gca()
ax.set_aspect(1)

plt.xlabel('Real')
plt.ylabel('Imaginary')
plt.title(r'$e^{i\pi} = \underset{n\rightarrow \infty}{\lim}\left( 1+\frac{i\pi}{n} \right) ^n=-1$')
plt.legend(ncol=3, loc='lower center', bbox_to_anchor=(0.5, -0.4))
plt.show()

由上面可视化的结果可以看出,对于:

$$ e^{i\pi} = \underset{n\rightarrow \infty}{\lim}\left( 1+\frac{i\pi}{n} \right) ^n $$

当$n\rightarrow \infty$时,$\left( 1+\frac{i\pi}{n} \right)^n$趋近于$-1$。

那么对于更一般的情况:

$$ e^{i\theta} = \underset{n\rightarrow \infty}{\lim}\left( 1+\frac{i\theta}{n} \right) ^n $$

应该为多少呢?

首先将求解极限的函数改写为:

def get_value(n, p, theta):
    x = np.power((1 + theta * 1j / n), p)
    return x.real, x.imag

以便用于支持任意角度的输入。

接下来以$\frac{\pi}{2}、\frac{2\pi}{3}、\frac{5\pi}{4}、\frac{7\pi}{4}$为例,可视化其结果:

fig, ax_arr = plt.subplots(2, 2)
fig.subplots_adjust(hspace=0.5)

theta_list = [1 / 2, 2 / 3, 5 / 4, 7 / 4]
sub_title = [r'\frac{1}{2}', r'\frac{2}{3}', r'\frac{5}{4}', r'\frac{7}{4}']
for i in range(ax_arr.shape[0]):
    for j in range(ax_arr.shape[1]):
        cur_ax = ax_arr[i, j]

        for k in [1, 2, 5, 10, 20, 10000]:
            point_coor = [get_value(k, v, theta_list[i * 2 + j] * np.pi) for v in range(1, k + 1)]
            x, y = zip(*point_coor)
            cur_ax.scatter(x, y, s=(1 / k) * 100, marker='*')
            cur_ax.plot(x, y, label=f'n={i}')

        cur_ax.axvline(0, color='#ccc', linestyle='--')
        cur_ax.axhline(0, color='#ccc', linestyle='--')

        # x、y轴等比例
        ax = plt.gca()
        ax.set_aspect(1)

        if j == 0:
            cur_ax.set_ylabel('Imaginary')
        if i == 1:
            cur_ax.set_xlabel('Real')

        cur_ax.set_title(f'$' + sub_title[i * 2 + j] + '\pi$')


lines, labels = fig.axes[-1].get_legend_handles_labels()  # 获取最后一个子图的图例
fig.legend(lines, labels, ncol=3, loc='upper center', bbox_to_anchor=(0.5, 0.03))
plt.tight_layout()
plt.show()

当$n\rightarrow \infty$时,$\left( 1+\frac{i\theta}{n} \right)^n$无限趋近于点$(\cos\theta, \sin\theta)$,也就是说:

$$ e^{i\theta} = \underset{n\rightarrow \infty}{\lim}\left( 1+\frac{i\theta}{n} \right) ^n = \cos\theta+i\sin\theta $$

这,便是宇宙间最优美的公式——欧拉公式。