Треки
/
Python
Python
/
Салабус
/
Комплексні числа
Ко

Комплексні числа у Python

{one: "1 вправа", few: "%{count} вправи", many: "%{count} вправ", other: "%{count} вправи"}

Про концепцію Комплексні числа

Complex numbers не такі вже й складні. Їм просто потрібна назва, яка не так лякає.

Вони настільки корисні, особливо в інженерії та науці, що Python включає complex як стандартний числовий тип, поряд із цілими числами (int) і числами з плаваючою комою (float).

Основи

Значення complex у Python по суті є парою чисел з плаваючою комою. Їх називають «дійсною» та «уявною» частинами, з прикрих історичних причин. І знову ж таки, краще зосередитися на їхній внутрішній простоті, а не на дивних назвах.

Є два поширені способи створити комплексні числа.

  1. Конструктор complex(real, imag) приймає два параметри типу float:
>>> z1 = complex(1.5, 2.0)
>>> z1
(1.5+2j)

Конструктор також уміє розбирати вхідний рядок тексту (англ. string). Це має дивне обмеження: він не спрацьовує, якщо рядок тексту містить пробіли.

>>> complex('4+2j')
(4+2j)

>>> complex('4 + 2j')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: complex() arg is a malformed string
  1. Комплексне число можна задати літералом <real part> + <complex part>j, або просто <complex part>j, якщо дійсна частина дорівнює нулю:
>>> z2 = 2.0 + 1.5j
>>> z2
(2+1.5j)

Результат той самий, що й від використання конструктора complex().

Для уявної частини комплексного числа є два правила:

  • Її позначають через j (а не i, як іноді буває в підручниках з математики).

  • j має стояти одразу після числа, щоб Python не сприйняв його як імʼя змінної. За потреби використовуємо 1j.

>>> j
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'j' is not defined

>>> 1j
1j

>>> type(1j)
<class 'complex'>

Більшість інженерів цілком задоволені літерою j. Більшість науковців і математиків віддають перевагу математичному позначенню i для уявного, але це позначення конфліктує з використанням i на позначення струму в електротехніці. Тож під час створення Python перемогли електротехніки.

Щоб отримати частини комплексного числа окремо:

>>> z2.real
2.0
>>> z2.imag
1.5

Будь-яка з частин може дорівнювати нулю, і тоді математики кажуть, що число «цілком дійсне» або «цілком уявне». Однак у Python це все одно комплексне число:

>>> complex(0, 1)
1j
>>> type(complex(0, 1))
<class 'complex'>

>>> complex(1, 0)
(1+0j)

Можна почути, що «i (або j) є квадратним коренем із -1».

Поки що все це означає лише те, що уявна частина за визначенням задовольняє рівність

1j * 1j == -1  # => True

Це проста ідея, але вона веде до цікавих наслідків.

Арифметика

Більшість operators, які використовуються з числами з плаваючою комою та цілими числами, також працюють із комплексними числами:

>>> z1 = (1.5+2j)
>>> z2 = (2+1.5j)


>>> z1 + z2  # addition
(3.5+3.5j)

>>> z1 - z2  # subtraction
(-0.5+0.5j)

>>> z1 * z2  # multiplication
6.25j

>>> z1 / z2  # division
(0.96+0.28j)

>>> z1 ** 2  # exponentiation
(-1.75+6j)

>>> 2 ** z1  # another exponentiation
(0.5188946835878313+2.7804223253571183j)

>>> 1j ** 2  # j * j == -1
(-1+0j)

Пояснення правил множення та ділення комплексних чисел виходить за межі цієї концепції (і навряд чи комусь доведеться часто виконувати ці операції «вручну»).

Будь-який математичний чи електротехнічний вступ до комплексних чисел розкриє це, якщо захочеться заглибитися в тему.

Або ж на Exercism є практична вправа Complex Numbers, де можна реалізувати клас комплексного числа з цими операціями із самих основ.

Цілочисельне ділення для комплексних чисел не можливе, тому оператори // і % та функція divmod() не працюватимуть із типом комплексних чисел.

Для числових типів реалізовано дві функції, які дуже корисні під час роботи з комплексними числами:

  • <complex number>.conjugate() просто змінює знак уявної частини комплексного числа (з + на - або навпаки).
    • Через те, як працює множення комплексних чисел, це корисніше, ніж могло б здатися.
  • abs(<complex number>) гарантовано повертає дійсне число без уявної частини.
>>> z1
(1.5+2j)

>>> z1.conjugate() # flip the z1.imag sign
(1.5-2j)

>>> abs(z1) # sqrt(z1.real ** 2 + z1.imag ** 2)
2.5

Модуль cmath

Стандартна бібліотека Python має модуль math, сповнений корисних функцій для роботи з дійсними числами.

У ній також є відповідний модуль cmath для роботи з комплексними числами.

Радимо переглянути цей модуль і поекспериментувати, а основні категорії такі:

  • Перетворення між декартовими та полярними координатами,
  • Показникові та логарифмічні функції,
  • Тригонометричні функції,
  • Гіперболічні функції,
  • Функції класифікації, та
  • Корисні константи.

Ось приклад із використанням деяких констант:

>>> import cmath

>>> euler = cmath.exp(1j * cmath.pi) # Euler's equation

>>> euler.real
-1.0
>>> round(euler.imag, 15) # round to 15 decimal places
0.0

Отже, простий вираз із трьома найважливішими константами природи e, i (або j) та pi дає результат -1. Дехто вважає це найкрасивішим результатом у всій математиці. Він сягає приблизно 1740 року.


Необовʼязковий розділ: часті запитання про комплексні числа

Цю частину можна пропустити, якщо нецікаво.

Хіба це не якась дивна нова частина чистої математики?

Вона була дивною і новою у XVI столітті.

500 років потому вона лежить в основі більшості інженерних і фізичних наук.

Навіщо взагалі їх використовувати?

Виявляється, комплексні числа - це найпростіший спосіб описати будь-що, що обертається, або будь-що з хвильовими властивостями. Тож їх широко використовують в електротехніці, обробці звуку, фізиці, компʼютерних іграх і навігації, і це лише кілька прикладів застосування.

Обертання можна побачити будь-де. Можливо, комплексні числа не змушують світ обертатися, але вони чудово пояснюють те, що відбувається внаслідок цього обертання: погляньмо на будь-який супутниковий знімок великої бурі.

Менш очевидно, що звук має хвильову природу, світло має хвильову природу, радіосигнали мають хвильову природу, і навіть економіка нашої країни принаймні частково має хвильову природу.

Значну частину такої обробки хвиль можна виконати за допомогою тригонометричних функцій (sin() і cos()), але це досить швидко стає заплутаним.

З комплексними експонентами працювати набагато простіше.

Але мені не потрібні комплексні числа!

Це правда, лише якщо жити в печері й добувати їжу полюванням і збиральництвом.

Якщо ми читаємо це з будь-якого екрана, то цілком залежимо від корисних досягнень XX століття, здобутих завдяки використанню комплексних чисел.

  1. Напівпровідникові чипи.

    • Вони не мають сенсу в класичній фізиці, і їх можна пояснити (і спроєктувати) лише за допомогою квантової механіки (КМ).
    • У КМ усе за визначенням має комплексні значення. (самі хвильові функції, аж до самого низу)
  2. Алгоритм швидкого перетворення Фурʼє (ШПФ).

    • ШПФ - це застосування комплексних чисел, і воно присутнє в усьому, повʼязаному з передаванням звуку, обробкою аудіо, фотографіями та відео.

    • MP3 та інші аудіоформати використовують ШПФ для стиснення, завдяки чому більше аудіо вміщується в меншому обсязі памʼяті.

    • Стиснення JPEG і відео MP4, як і багато інших форматів зображень і відео, також використовують ШПФ для стиснення.

    • ШПФ також застосовують у цифрових фільтрах, які дають змогу вишкам стільникового звʼязку відокремлювати наш особистий сигнал від сигналів усіх інших.

Тож ми, ймовірно, користуємося технологіями, які покладаються на обчислення комплексних чисел тисячі разів на секунду.

Редагувати через GitHub Посилання відкривається в новому вікні або вкладці