29Комплексные числа

Мы начинали курс с обсуждения чисел, ими же и закончим. Всё началось с натуральных чисел. Натуральные числа можно складывать, умножать и возводить в степени, но не всегда можно вычитать. Попробуйте-ка вычесть пять из трёх — если вам известны только натуральные числа, не получится. Приходится изобретать отрицательные. С отрицательными числами вычитание работает без проблем, но с делением есть трудности — четыре на два поделятся, а на три — нет. Рациональные числа лишены этой проблемы: делить можно что угодно на что угодно, кроме нуля (с нулём так всегда будет, тут уж ничего не поделать). Однако, корни извлекать не всегда получается — например, корень из двух не является рациональным числом. Чтобы эту проблему решить, придумали вещественные числа. Теперь корни извлекаются — но только из неотрицательных чисел. А что делать, если очень хочется извлечь корень из отрицательного числа? Как обычно — придумывать новые числа!

29.1Построение комплексных чисел

29.1.1Мнимая единица

Когда мы не смогли поделить четыре на три, мы сказали — ну и ладно, давайте просто объявим, что — это новое число — не натуральное и не целое, но рациональное. Потом мы придумали две вещи: во-первых, как вложить множество целых чисел в множество рациональных — мы знаем, что целое число — это то же самое, что рациональное число . Во-вторых, как рациональные числа складывать и умножать.

С корнями из отрицательных чисел можно поступить аналогично. Допустим, очень хочется вычислить квадратный корень из минус единицы. Давайте считать, что мы его вычислили, и обозначим результат через . Эта штука называется мнимой единицей. Мы бы хотели извлекать квадратный корень не только из минус единицы, но и из других отрицательных чисел. Однако, как мы скоро увидим, ничего специального для этого делать не придётся.

Конечно, не является вещественным числом, поскольку мы хорошо знаем, что квадрат любого вещественного числа неотрицателен (ну вот просто так мы определили операции — минус на минус даёт плюс, поэтому отрицательного ничего не получится). Тем не менее, давайте считать, что это всё-таки число — какого-то нового, невиданного доселе типа — и что его можно включать в арифметические операции.

Самое главное (и, по большому счёту, единственное), что мы знаем про и арифметические операции — что если его умножить на себя, то получится минус единица:

Взаимодействие с вещественными числами определим самым простым образом: никак. То есть выражение, например, никак нельзя упростить — это просто запись одного из наших новых чисел. Когда мы придумали рациональные числа, у каждого такого числа оказалось две части — числитель и знаменатель, оба относились к ранее определенным классам чисел — целым и натуральным. А у комплексных чисел тоже две части, одна без , а другая с .

Итак, по определению, множество комплексных чисел — это множество

Пусть — какое-то комплексное число. Тогда называется его вещественной частью (real), а — мнимой (imaginary). Обозначаются:
Заметим, что и — вещественные числа. Всю комплексную магию добавляет число .

29.1.2Арифметические операции с комплексными числами

В дальнейшем мы будем предполагать, что привычные для нас правила работы с числами — например, «от перестановки слагаемых сумма не меняется» и т.д. сохраняются и в случае комплексных чисел — по крайней мере, до тех пор, пока это возможно.

Сложение. Пусть и — два комплексных числа. Их сумма определяется так:

Я воспользовался стандартными правилами — про перестановку слагаемых и про вынесение за скобку. Таким образом, чтобы сложить два комплексных числа, нужно сложить их вещественные и мнимые части по отдельности.

Умножение. Тут будет посложнее.

Коммутативность умножения, в которую мы по-прежнему верим, позволяет сказать, что и . Но мы знаем, что , и значит получается . Итак:
Формула не самая короткая, и сходу даже непонятно, какие свойства у этой операции. Например, точно ли выполняется ассоциативность (), как сложение взаимодействует с умножением и т.д. — всё это надо проверять (спойлер: всё работает). Чуть попозже мы обсудим, как умножение записывать короче и как правильно о нём думать.

Замечание 1. С умножением на вещественные числа всё просто:
то есть вещественная и комплексная части просто умножаются покомпонентно. Аналогично можно комплексные числа делить на вещественные. Как делить комплексные числа на комплексные мы обсудим позже.

29.1.3Комплексная плоскость

Всякие комплексное число задаётся парой вещественных чисел — действительной и мнимой частью. С другой стороны, мы знаем, что парами вещественных чисел задаются точки на плоскости. Каждой точке можно также сопоставить радиус-вектор — стрелочку, которая начинается в нуле, а заканчивается в этой точке. (Эту стрелочку также можно переносить по всей плоскости, сохраняя направление и длину — иногда бывает полезно откладывать вектор не от нуля, а от другой точки.) Мы будем думать про комплексные числа как про такие векторы. Точка и её радиус-вектор соответствуют вещественному числу , а точка — числу .

Вероятно, вы помните, что векторы на плоскости складываются по правилу параллелограмма или правилу треугольника (что в сущности одно и то же). В координатах, сложение векторов происходит покомпонентно — первая компонента первого вектора складывается с первой компонентой второго, втарая — со второй. Точно так же складываются комплексные числа. Поэтому сложение комплексных чисел работает в точности так же, как сложение векторов.

С умножением интереснее. На плоскости не существует обычного векторного умножения. (Вероятно, вы помните, что есть скалярное умножение, но оно на выходе возвращает не вектор, а число — скаляр; бывает ещё векторное умножение, но оно действует в трёхмерном пространстве, а не на плоскости.) А вот комплексные числа умножать можно. Есть ли у умножения какой-то геометрический смысл? Есть! Но сперва нужно поговорить про полярные координаты.

29.1.4Тригонометрическая форма записи комплексных чисел

Задать точку на плоскости можно по-разному. Можно — её координатами в декартовой системе, как мы это обычно делаем. А можно — в полярных координатах.

Возьмём некоторое направление — например, направление горизонтальной координатной оси от начала координат в сторону плюс бесконечности. Рассмотрим теперь какую-нибудь точку . Она однозначно задаётся двумя числами: расстоянием до начала координат и углом , который составляет с нашим исходным направлением. Числа и называются полярными координатами точки .

Полярные координаты иногда бывают удобнее декартовых. Например, чтобы задать единичную окружность, в декартовых координатах приходится вспоминать про теорему Пифагора и записывать уравнение , а в полярных соответствующее уравнение выглядит гораздо проще: .

Если заданы полярные координаты, восстановить декартовы легко. Если , то и — это определение синуса и косинуса. Если , всю картинку нужно растянуть в раз, то есть умножить обе координаты на . Получается такая штука:

Вернёмся к комплексным числам. Их тоже можно задавать в полярных координатах:
Число называется модулем комплексного числа, оно равно расстоянию от точки до начала координат, а число называется аргументом. Обозначения такие:
Таким образом, для любого ,

Замечание 2. Модуль комплексного числа задаётся однозначно — он находится по формуле . А вот аргумент — нет; его можно менять на целое число полных оборотов , и число не поменяется.

Умножение в тригонометрической форме. Посмотрим, как работает формула умножения комплексных чисел (29.1), если представлять их не в декартовых координатах, а в комплексных. Теперь нужно внимательно вглядеться и напрячь память… это же формулы для косинуса и синуса суммы!

Итак, при умножении комплексных чисел их модули умножаются, а аргументы складываются. В отличие от формулы (29.1), это правило реально запомнить, и оно имеет интересный геометрический смысл: умножение на комплексное число работает как поворот плоскости.

Вопрос 1. Умножение на приводит к
  повороту на угол против часовой стрелки;

Верный ответ. Верно! Собственно, если взять число , умножить его на , оно повернётся как раз на в положительном направлении (против часовой стрелки).

  повороту на угол по часове стрелке;

Неверный ответ. Попробуйте взять число и умножить его на . Куда оно повернётся?

  повороту на 180 градусов;

Неверный ответ. Попробуйте взять число и умножить его на . Куда оно повернётся?

  отражению относительно горизонтальной оси?

Неверный ответ. Попробуйте взять число и умножить его на . Что с ним произойдёт?

29.1.5Комплексное сопряжение и деление

Обсудим ещё две важные операции. Во-первых, с комплексным числом можно сделать такую штуку, которую нельзя сделать в вещественным числом: поменять знак мнимой части. Вернее, сделать её с вещественным числом можно, но вещественное число от этого не поменяется. Если же у комплексного числа есть ненулевая мнимая часть, её знак заменится на противоположный и получится другое комплексное число. Эта операция называется комплексным сопряжением и обозначается чертой:
Геометрически комплексное сопряжение соответствует отражению плоскости относительно вещественной оси. Если применить комплексное сопряжение дважды, всё вернётся на место:

Упражнение 1. Докажите, что и .

Рассмотрим теперь любое число . Что будет, если умножить его на сопряженное?

Получается вещественное число — квадрат модуля .

Научимся теперь делить комплексные числа. Для этого научимся для всякого находить такое число , что . То есть — обратное к .

Начнём с равенства, которое мы только что вывели:

и поделим его на , при условии, что и следовательно :
Итак, обратное к — это число
Почему такая запись лучше, чем просто ? Потому что в формуле выше мы делим на вещественное число , а как умножать (и делить) на вещественные числа мы знаем — это можно делать покомпонентно (см. замечание 1). Можно записать операцию деления в обычных координатах:
а можно и в полярных: взятие комплексного сопряжения меняет знак аргумента, а чтобы поделить комплексное число на вещественное, достаточно поделить его модуль:
Ну а раз для всякого числа определено обратное к нему число , то деление устроено как обычно — как умножение на обратное:

29.2Функции от комплексных чисел

29.2.1Возведение в квадрат

Мы начали с того, что добавили к обычным вещественным числам одно-единственное число — квадратный корень из минус единицы — и пообещали, что в получившейся системе чисел можно будет найти квадратный корень из любого числа. Давайте проверим, что это верно. Но сначала разберёмся, как действует возведение в квадрат.

Пусть , , то есть — это отобржаение из в — как говорят, комплекснозначная функция комплексного аргумента. К сожалению, представлять такие функции так, как мы привыкли, в виде графиком, практически невозможно — поскольку комплексное число соответствует двум вещественным, график такой функции пришлось бы рисовать в четыерёхмерном пространстве, которое очень трудно представить. Попробуем по-другому.

Запишем в тригонометрической форме:

Тогда
при возведении в квадрат модуль возводится в квадрат, а аргумент умножается на два.

Как действует это отображение? Для простоты рассмотрим случай, когда с радиусом ничего не происходит — а именно, пусть . В этом случае наше квадратичное отображение просто удваивает аргумент, то есть отображает точку на единичной окружности с угловой координатой в точку .

Пусть точка постепенно обходит окружность от точки в положительном направлении (против часовой стрелки). Что происходит с ? Она также обходит окружность, но вдвое быстрее, см. анимацию на рис. 29.1. Когда сделает четверть оборота и окажется в точке с (то есть в точке ), её квадрат сделает полоборота и окажется в — так и должно быть, мы знаем, что . Дальше будет преодолевать расстояние от до , за это время преодолеет ещё полоборота и окажется в точке . Всё логично: . Потом будет проходить вторую половину окружности, а — обходить всю окружность по второму разу. В частности, в тот момент, когда попадёт в точку (что соответствует ), её квадрат снова попадёт в . То есть не только , но и (что, конечно, мгновенно следует из правила «минус на минус даёт плюс», которое никто не отменял). Итак, полное прохождение окружности точкой соответствует двукратному прохождению окружности точкой ?

import matplotlib.pyplot as plt
import numpy as np
import qqmbr.odebook as ob
# see https://github.com/ischurov/qqmbr/blob/master/qqmbr/odebook.py

from mpl_toolkits.mplot3d import Axes3D
from celluloid import Camera
from scipy.integrate import odeint, simps

def draw_z2(Rs, labels):

    ph = np.linspace(0, 2 * np.pi, 301)
    fig = plt.figure(figsize=(7, 7))
    camera = Camera(fig)
    ax = fig.add_subplot(111, projection="3d")
    ax.set_axis_off()


    def v(ph):
        return np.sin(2 * ph) ** 2 + 0.1


    t_max = simps(1 / v(ph), ph)
    ph_steps = odeint(lambda ph, t: v(ph), 0, np.linspace(0, t_max, 101))
    for t in ph_steps.ravel():
        for plane in [1, -1]:
            ax.text(-0.1, 0, plane, "$0$")

            ax.text(0.8, 0.2, plane, "$1$")
            ob.arrow3D(ax,
                -1,
                0,
                plane,
                2,
                0,
                0,
                arrowstyle="-|>",
                mutation_scale=20,
                linestyle="dashed",
                color="gray",
            )

            ax.text(0, 1.2, plane, "$i$")
            ob.arrow3D(ax,
                0,
                -1,
                plane,
                0,
                2,
                0,
                arrowstyle="-|>",
                mutation_scale=20,
                linestyle="dashed",
                color="gray",
            )

        for R, label in zip(Rs, labels):
            # circles
            ax.plot(R * np.cos(ph), R * np.sin(ph), np.ones_like(ph), color="C0")
            ax.plot(R ** 2 * np.cos(ph), R ** 2 * np.sin(ph), -np.ones_like(ph), color="C1")

            # map
            ax.plot(
                [R * np.cos(t), R ** 2 * np.cos(2 * t)],
                [R * np.sin(t), R ** 2 * np.sin(2 * t)],
                [1, -1],
                "o-",
                color="C2",
            )
            rlabel = 1.1
            ax.text(rlabel * R * np.cos(t), rlabel * R * np.sin(t), 1, f"$ {label} $")
            ax.text(
                rlabel * R ** 2 * np.cos(2 * t),
                rlabel * R ** 2 * np.sin(2 * t),
                -1,
                f"$ {label}^2$",
            )

        camera.snap()
    animation = camera.animate()
    return animation
animation = draw_z2([1], ["z"])