Komplexe Zahlen

Komplexe Zahlen wurden von Gerolamo Cardano im 16. Jahrhundert in die Mathematik eingeführt, als er sich mit der Lösung von kubischen Gleichungen beschäftigte. Dabei geht es um das Auffinden der möglichen Lösungen für x von a x³ + b x² + c x + d = 0. Mit den sogenannten Cardanischen Formeln kann man die Lösungen berechnen. Beim Rechnen mit den Lösungsformeln treten komplexe Zahlen auf, auch wenn alle Lösungen der kubischen Gleichung reelle Zahlen sind.

Eine komplexe Zahl kann man als Paar von zwei gewöhnlichen (reellen) Zahlen auffassen. Die beiden Bestandteile nennt man den reellen und den imaginären Teil der komplexen Zahl. Ist der imaginäre Teil 0, verhält sich eine komplexe Zahl wie eine gewöhnliche:

  (a, 0) + (b, 0) = (a + b, 0)
  (a, 0) - (b, 0) = (a - b, 0)
  (a, 0) * (b, 0) = (a * b, 0)
  (a, 0) / (b, 0) = (a / b, 0), wenn b ungleich 0 ist

Insofern kann man die komplexen Zahlen als eine Erweiterung der gewöhnlichen Zahlen verstehen.

Ist der imaginäre Teil der komplexen Zahl nicht 0, gelten kompliziertere Regeln.

Die Addition und die Subtraktion von komplexen Zahlen erfolgen komponentenweise.

  (a, c) + (b, d) = (a + b, c + d)
  (a, c) - (b, d) = (a - b, c - d)

Bei der Multiplikation wird die Differenz der Produkte der rellen und komplexen Teile gebildet und die Summe der Produkte "über Kreuz" (reller Teil mal komplexer Teil).

  (a, c) * (b, d) = (a * b - c * d, a * d + c * b)

Für die Division (a, c) / (b, d) erweitert man zunächst mit (b, -d) und nutzt dann aus, dass das Produkt im Divisior (b, d) * (b, -d) der gewöhnlichen Zahl b * b + d * d entspricht.

  (a, c) / (b, d) = (1 / (b * b + d * d), 0) * (a, c) * (b, -d)

In Lisp kann man komplexe Zahlen durch eine Datenstruktur definieren. Diese bekommt den Namen complex und hat zwei Komponenten mit den Namen real und imaginary. Eine Instanz der Datenstruktur ist nur dann gültig, wenn beide Komponenten Zahlen sind.

(defstruct complex
  (real imaginary)
  (and (number? real) (number? imaginary)))

Nach dieser Definition kann man neue komplexe Zahlen erzeugen, indem man das Macro new aufruft. So erzeugt z.B.

(new complex 2 3)

eine komplexe Zahl mit Realteil 2 und Imaginärteil 3. Auf die Teile bzw. Komponenten der Zahl kann man mit dem Macro . zugreifen. Wenn das Symbol c den Wert von (new complex 2 3) besitzt, ergibt (. c real) den Wert 2 und (. c imaginary) den Wert 3.

Die Grundrechenarten definiert man als Methoden, jeweils mit rein komplexen Argumenten und für gemischte Argumente (ein Argument gewöhnlich, ein Argument komplex).

(defmethod add ((this complex) (that complex))
  t
  (simplify
    (new complex
      (+ (. this real) (. that real))
      (+ (. this imaginary) (. that imaginary)))))

(defmethod add ((this complex) r)
  (number? r)
  (add this (new complex r 0)))

(defmethod add (r (this complex))
  (number? r)
  (add (new complex r 0) this))

(defmethod sub ((this complex) (that complex))
  t
  (simplify
    (new complex
      (- (. this real) (. that real))
      (- (. this imaginary) (. that imaginary)))))

(defmethod sub ((this complex) r)
  (number? r)
  (sub this (new complex r 0)))

(defmethod sub (r (this complex))
  (number? r)
  (sub (new complex r 0) this))

(defmethod times ((this complex) (that complex))
  t
  (simplify
    (new complex
      (- (* (. this real) (. that real))
         (* (. this imaginary) (. that imaginary)))
      (+ (* (. this real) (. that imaginary))
         (* (. this imaginary) (. that real))))))

(defmethod times ((this complex) r)
  (number? r)
  (times this (new complex r 0)))

(defmethod times (r (this complex))
  (number? r)
  (times (new complex r 0) this))

Die Methode simplify sorgt dafür, dass komplexe Zahlen, deren Imaginärteil 0 ist, in gewöhnliche Zahlen umgewandelt werden.

(defmethod simplify ((this complex))
  t
  (if
    (zero? (. this imaginary))
    (. this real)
    this))

Für die Division definiert man zunächst eine Methode mit Namen conjugate. Diese liefert zu einer komplexen Zahl (a, b) die sogenannte konjugierte Zahl (a, -b).

(defmethod conjugate ((this complex))
  t
  (if
    (zero? (. this imaginary))
    (. this real)
    (new complex
      (. this real)
      (- (. this imaginary)))))

(defmethod conjugate (r)
  (number? r)
  r)

(defmethod quotient ((this complex) r)
  (number? r)
  (simplify
    (new complex
      (/ (. this real) r)
      (/ (. this imaginary) r))))

(defmethod quotient ((this complex) (that complex))
  t
  (/ (* this (conjugate that))
     (* that (conjugate that))))

(defmethod quotient (r (this complex))
  (number? r)
  (quotient (new complex r 0) this))

Die unten verlinkte Datei enthält die Definitionen der Datenstruktur und der Methoden und einige Beispiele. Sie kann mit dem Programm Calc ausgeführt werden.


complex.sheet.xml