Complex numbers sind nicht kompliziert.
Sie brauchen nur einen weniger alarmierenden Namen.
Sie sind so nützlich, besonders im Ingenieurwesen und in der Wissenschaft, dass Python complex als standardmäßigen numerischen Typ enthält, neben Ganzzahlen (ints) und Gleitkommazahlen (floats).
Ein complex-Wert in Python ist im Wesentlichen ein Paar Gleitkommazahlen.
Aus bedauerlichen historischen Gründen heißen sie „Realteil“ und „Imaginärteil“.
Auch hier ist es am besten, sich auf die zugrunde liegende Einfachheit zu konzentrieren und nicht auf die seltsamen Namen.
Es gibt zwei übliche Wege, komplexe Zahlen zu erzeugen.
complex(real, imag) nimmt zwei float-Parameter:>>> z1 = complex(1.5, 2.0)
>>> z1
(1.5+2j)
Der Konstruktor kann auch eine String-Eingabe parsen. Das hat die seltsame Einschränkung, dass er fehlschlägt, wenn der String Leerzeichen enthält.
>>> 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
<real part> + <complex part>j angegeben werden, oder nur als <complex part>j, wenn der Realteil null ist:>>> z2 = 2.0 + 1.5j
>>> z2
(2+1.5j)
Das Ergebnis ist identisch mit der Verwendung des complex()-Konstruktors.
Für den Imaginärteil der komplexen Zahl gelten zwei Regeln:
Er wird mit j bezeichnet (nicht mit i, wie du es vielleicht in Mathematikbüchern siehst).
Das j muss unmittelbar auf eine Zahl folgen, damit Python es nicht als Variablennamen ansieht. Falls nötig, verwende 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'>
Die meisten Ingenieure sind mit j zufrieden.
Die meisten Wissenschaftler und Mathematiker bevorzugen die mathematische Schreibweise i für imaginär, aber diese Schreibweise steht in Konflikt mit der Verwendung von i für Strom in der Elektrotechnik.
Beim Entwurf von Python haben also die Elektroingenieure gewonnen.
Um auf die einzelnen Teile einer komplexen Zahl zuzugreifen:
>>> z2.real
2.0
>>> z2.imag
1.5
Jeder der beiden Teile kann null sein, und Mathematiker sprechen dann vielleicht davon, dass die Zahl „rein reell“ oder „rein imaginär“ ist. In Python ist sie aber trotzdem eine komplexe Zahl:
>>> complex(0, 1)
1j
>>> type(complex(0, 1))
<class 'complex'>
>>> complex(1, 0)
(1+0j)
Du hast vielleicht gehört, dass „i (oder j) die Quadratwurzel aus -1 ist“.
Vorerst bedeutet das nur, dass der Imaginärteil per Definition die Gleichung erfüllt
1j * 1j == -1 # => True
Das ist eine einfache Idee, aber sie führt zu interessanten Konsequenzen.
Die meisten operators, die mit Gleitkommazahlen und Ganzzahlen verwendet werden, funktionieren auch mit komplexen Zahlen:
>>> 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)
Die Regeln für die Multiplikation und Division komplexer Zahlen zu erklären, geht über den Rahmen dieses Konzepts hinaus (und du wirst diese Operationen wahrscheinlich nicht sehr oft „von Hand“ durchführen müssen).
Jede mathematische oder elektrotechnische Einführung in komplexe Zahlen behandelt das, falls du tiefer in das Thema einsteigen möchtest.
Alternativ gibt es bei Exercism eine Complex Numbers-Übung, in der du eine Klasse für komplexe Zahlen mit diesen Operationen von Grund auf implementieren kannst.
Ganzzahldivision ist bei komplexen Zahlen nicht möglich, daher schlagen die Operatoren // und % sowie die Funktion divmod() für den komplexen Zahlentyp fehl.
Es gibt zwei Funktionen, die für numerische Typen implementiert sind und die sehr nützlich sind, wenn man mit komplexen Zahlen arbeitet:
<complex number>.conjugate() kehrt einfach das Vorzeichen des Imaginärteils einer komplexen Zahl um (von + zu - oder umgekehrt).
abs(<complex number>) gibt garantiert eine reelle Zahl ohne Imaginärteil zurück.>>> 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-ModulDie Python-Standardbibliothek enthält ein math-Modul mit vielen nützlichen Funktionen für die Arbeit mit reellen Zahlen.
Sie enthält auch ein entsprechendes cmath-Modul für die Arbeit mit komplexen Zahlen.
Wir ermutigen dich, das Modul durchzulesen und zu experimentieren. Die wichtigsten Kategorien sind:
Hier ist ein Beispiel mit einigen Konstanten:
>>> 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
Ein einfacher Ausdruck mit drei der wichtigsten Konstanten der Natur e, i (oder j) und pi liefert also das Ergebnis -1.
Manche Menschen halten dies für das schönste Ergebnis der gesamten Mathematik.
Es geht auf die Zeit um 1740 zurück.
Diesen Teil kannst du überspringen, wenn du nicht daran interessiert bist.
Im 16. Jahrhundert war es seltsam und neu.
500 Jahre später ist es zentral für einen Großteil des Ingenieurwesens und der physikalischen Wissenschaften.
Es stellt sich heraus, dass komplexe Zahlen der einfachste Weg sind, alles zu beschreiben, was sich dreht, oder alles mit einer wellenartigen Eigenschaft. Deshalb werden sie in der Elektrotechnik, der Audiobearbeitung, der Physik, der Computerspielentwicklung und der Navigation häufig eingesetzt, um nur einige Anwendungen zu nennen.
Man kann Dinge rotieren sehen. Komplexe Zahlen sorgen vielleicht nicht dafür, dass sich die Welt dreht, aber sie eignen sich hervorragend, um zu erklären, was passiert, wenn sich die Welt dreht: Schau dir irgendein Satellitenbild eines großen Sturms an.
Weniger offensichtlich: Schall ist wellenartig, Licht ist wellenartig, Funksignale sind wellenartig, und sogar die Wirtschaft deines Heimatlandes ist zumindest teilweise wellenartig.
Ein Großteil dieser Wellenverarbeitung lässt sich mit trigonometrischen Funktionen (sin() und cos()) erledigen, aber das wird schnell unübersichtlich.
Komplexe Exponentialfunktionen sind viel einfacher zu handhaben.
Das stimmt nur, wenn du in einer Höhle lebst und dir dein Essen sammelst.
Wenn du das hier auf irgendeinem Bildschirm liest, bist du völlig auf einige nützliche Fortschritte des 20. Jahrhunderts angewiesen, die durch die Verwendung komplexer Zahlen möglich wurden.
Halbleiterchips.
Der Algorithmus der schnellen Fourier-Transformation (FFT).
Die FFT ist eine Anwendung komplexer Zahlen und steckt in allem, was mit Klangübertragung, Audiobearbeitung, Fotos und Videos zu tun hat.
MP3 und andere Audioformate verwenden die FFT zur Kompression, sodass mehr Audio in einen kleineren Speicherplatz passt.
Die JPEG-Kompression und MP4-Videos verwenden, wie viele andere Bild- und Videoformate, ebenfalls die FFT zur Kompression.
Die FFT kommt auch in den digitalen Filtern zum Einsatz, mit denen Mobilfunkmasten dein persönliches Funksignal von dem aller anderen trennen.
Du nutzt also wahrscheinlich Technologie, die tausendmal pro Sekunde auf Berechnungen mit komplexen Zahlen angewiesen ist.