/*
Program: Java-Complex-Number Class (JCN)
This program provides arithmetical functions for solving matrix-problems
Copyright (C) 2006 Karsten Bettray
Version: v0.1f
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library;
if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA *
*/
/**
* Klasse zur Berechnung und Rückgabe von komplexen Zahlen
* Dieser Quelltext ist vollständig für jeden frei verfügbar
* und steht der persönlichen Weiterverwendung zur Verfügung.
* @author Karsten Bettray - 27.09.2005
* Universität Duisburg-Essen
* @version 0.1f
*/
public class Complex
{
public static final Complex ZERO = new Complex();
public static final Complex ONE = new Complex(1.0d, 0.0d);
public static final Complex I = new Complex(0.0d, 1.0d);
private double real, imag, abs, arg; // double-Variablen fuer Realteil, Imaginaerteil, Betrag und Phase
private double[] sqrtArgArray = null; // double-Array, fuer n-Loesungen aus n-tr Wurzel
/**
* Leerer Konstruktor, initialisiert alle Werte mit 0
*/
public Complex() // Leerer Konstruktor, initialisiert alle Werte mit 0
{
this.real = 0d;
this.imag = 0d;
this.abs = 0d;
this.arg = 0d;
}
/**
* Initialisierung mittels Real- und imaginärteil
* @param real Realteil
* @param imag Imaginäteil
*/
public Complex(double real, double imag) // Initialisierung mittels Real- und imaginaerteil
{
this.real = real;
this.imag = imag;
solveAbsAndArg();
}
/**
* Initialisierung mittels Betrag- und Phase
* @param abs Betrag
* @param arg Phase
* @param bool ist bool==true, ist der Winkel in Radiant anzugeben, bei bool=false in '°'
*/
public Complex(double abs, double arg, boolean bool) // Initialisierung mittels Betrag- und Phase
{
this.abs = abs;
if(bool) // wenn bool==true, dann wird der Winkel in radiant uebergeben
this.arg = arg;
else // wenn bool==false, dann wird der Winkel in '°' uebergeben
this.arg = arg * (Math.PI / 180d);
solveRealAndImag();
}
/**
* Berechnen von Betrag und Phase mittels Real- und Imaginärteil
*/
private void solveAbsAndArg()
{
abs = Math.sqrt(Math.pow(real, 2) + Math.pow(imag, 2));
arg = Math.atan2(imag, real);
}
/**
* Berechnen von Real- und Imaginärteil mittels Betrag und Phase
*/
private void solveRealAndImag()
{
real = abs * Math.cos(arg);
imag = abs * Math.sin(arg);
}
/**
* Liefert den WInkel in ° zurück
* @return Winkel in Grad zurückliefern
*/
public double getArgAsDegrease()
{
return arg * (180d / Math.PI);
}
/**
* Ausgabe der Complexen Zahl auf der Konsole
*/
public void printComplexNumber()
{
System.out.println("Realteil="+real+" | Imaginärteil="+imag);
System.out.println("Betrag="+abs+" | Phase="+arg+" | Phase in °="+getArgAsDegrease());
}
/**
* Ausgabe der Complexen Zahl auf der Konsole, inklusive übergebenen String
* @param string Übergebene Zeichenkette wird der Ausgabe vorangestellt
*/
public void printComplexNumber(String string)
{
System.out.print(string);
System.out.println("Realteil="+real+" | Imaginärteil="+imag);
System.out.println("Betrag="+abs+" | Phase="+arg+" | Phase in °="+getArgAsDegrease());
}
/**
* Addition zweier komplexer Zahlen
* @param comp Komplexe Zahl
* @return Rückgabe von neuem Objekt mit Ergebnis aus Addition
*/
public Complex add(Complex comp)
{
return new Complex(this.real + comp.getReal(), this.imag + comp.getImag());
}
/**
* Subtraktion zweier komplexer Zahlen
* @param comp Komplexe Zahl
* @return Rückgabe von neuem Objekt mit Ergebnis aus Subtraktion
*/
public Complex sub(Complex comp)
{
return new Complex(this.real - comp.getReal(), this.imag - comp.getImag());
}
/**
* Multiplikation zweier komplexer Zahlen
* @param comp Komplexe Zahl
* @return Rückgabe von neuem Objekt mit Ergebnis aus Multiplikation
*/
public Complex mul(Complex comp)
{
return new Complex(this.abs * comp.getAbs(), this.arg + comp.getArg(), true);
}
/**
* Division zweier komplexer Zahlen
* @param comp Komplexe Zahl
* @return Rückgabe von neuem Objekt mit Ergebnis aus Division
*/
public Complex div(Complex comp)
{
return new Complex(this.abs / comp.getAbs(), this.arg - comp.getArg(), true);
}
/**
* Funktion zur Berechnung mit dem Exponenten 'expon' >= 1
* @param expon Exponenten, mit dem die komplexe Zahl exponiert ist.
* @return Rückgabe von neuem Objekt mit Ergebnis aus Exponierung
*/
public Complex pow(int expon)
{
double abs, arg; // interne Variablen fuer Betrag und Phase
Complex swap = null;
abs = Math.pow(this.getAbs(), (double)expon); // Betrag exponieren
arg = this.getArg() * (double)expon; // Winkel mit Exponenten multiplizieren
swap = new Complex(abs, arg, true);
return swap;
}
/**
* Berechnen der n-ten Wurzel der komplexen Zahl
* @param expon Wurzelexponent
* @return Rückgabe eines Vector mit n Lösungen
*/
public Complex sqrt(int expon)
{
double abs, arg; // interne Variablen fuer Betrag und Phase
double[] sqrtArgArray; // double-Array, mit n-Winkeln aus Wurzelberechnung
Complex swap = null;
if(expon>=1) {
sqrtArgArray = new double[expon]; // Anlegen des n double-Werte-Arrays für die n-Lösungen
abs = Math.pow(this.getAbs(), 1d/(double)expon); // n-te Wurzel aus Betrag ziehen
for(int i=0; i<=expon-1; i++) { // Anlegen der n double-Werte fuer die n-Loesungen
sqrtArgArray[i] = this.getArg()/(double)expon + ((double)i * 2*Math.PI)/(double)expon;
}
arg = sqrtArgArray[0]; // "Hauptwinkel" bekommt ersten Wert aus double-Werte-Array
swap = new Complex(abs, arg, true);
swap.setSqrtArgArray(sqrtArgArray);
}
else
System.out.println("! Wurzelexponent kleiner 1 !");
return swap;
}
/**
* Berechnen des Sinus der komplexen Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus sin(z)
*/
public Complex sin()
{
return new Complex(Math.sin(this.getReal()) * Math.cosh(this.getImag()),
Math.cos(this.getReal()) * Math.sinh(this.getImag()));
}
/**
* Berechnen des Kosinus der komplexen Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus cos(z)
*/
public Complex cos()
{
return new Complex(Math.cos(this.getReal()) * Math.cosh(this.getImag()),
Math.sin(this.getReal()) * Math.sinh(this.getImag()));
}
/**
* Berechnen des Tangens der komplexen Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus tan(z)
*/
public Complex tan()
{
double real, imag;
double nn = 1d + Math.pow(Math.tan(this.getReal()) * Math.tanh(this.getImag()), 2); // Nenner der Brueche
real = (Math.tan(this.getReal())*(1-Math.pow(Math.tanh(this.getImag()), 2))) / nn;
imag = (Math.tanh(this.getImag())*(1+Math.pow(Math.tan(this.getReal()), 2))) / nn;
return new Complex(real, imag);
}
/**
* Berechnen des Kotangens der komplexen Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus cot(z)
*/
public Complex cot()
{
double nn = Math.pow(Math.sin(this.real)*Math.cosh(this.imag), 2) + Math.pow(Math.cos(this.real)*Math.sinh(this.imag), 2);
return new Complex((Math.cos(this.real) * Math.sin(this.real)) / nn, (Math.cosh(this.imag) * Math.sinh(this.imag)) / nn);
}
/**
* Berechnen des Sinus-Hyperbolikus der komplexen Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus sinh(z)
*/
public Complex sinh()
{
return new Complex(Math.sinh(this.getReal()) * Math.cos(this.getImag()),
Math.cosh(this.getReal()) * Math.sin(this.getImag()));
}
/**
* Berechnen des Kosinus-Hyperbolikus der komplexen Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus cosh(z)
*/
public Complex cosh()
{
return new Complex(Math.cosh(this.getReal()) * Math.cos(this.getImag()),
Math.sinh(this.getReal()) * Math.sin(this.getImag()));
}
/**
* Berechnen des Tangens-Hyperbolikus der komplexen Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus tanh(z)
*/
public Complex tanh()
{
return Complex.div(this.sinh(), this.cosh());
}
/**
* Berechnen des Kotangens-Hyperbolikus der komplexen Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus coth(z)
*/
public Complex coth()
{
return Complex.div(this.cosh(), this.sinh());
}
/**
* Berechnen der e-Funktion der komplexen Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus exp(z)
*/
public Complex exp()
{
return new Complex(Math.cos(this.getImag()) * (Math.sinh(this.getReal()) + Math.cosh(this.getReal())),
Math.sin(this.getImag()) * (Math.cosh(this.getReal()) + Math.sinh(this.getReal())));
}
/**
* Berechnen des natürlichen Logarithmus der komplexen Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus ln(z)
*/
public Complex ln()
{
return new Complex(Math.log(this.getAbs()), this.getArg());
}
/**
* Berechnen des Logarithmus zur Basis 10 komplexen Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus log(z)
*/
public Complex log()
{
return new Complex(Math.log10(this.getAbs()), Math.log10(Math.exp(this.getArg())));
}
/**
* Berechnen der konjugierten komplexen Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus conj(z)
*/
public Complex conj()
{
return new Complex(this.getReal(), -this.getImag());
}
// --- Get- und Set-Methoden
/**
* Zurückgeben des Betrages
* @return Returns the abs.
*/
public double getAbs()
{
return abs;
}
/**
* Setzen des Betrages
* @param abs The abs to set.
*/
public void setAbs(double abs)
{
this.abs = abs;
}
/**
* Zurückgeben des Winkels
* @return Returns the arg.
*/
public double getArg()
{
return arg;
}
/**
* Setzen des Winkels
* @param arg The arg to set.
*/
public void setArg(double arg)
{
this.arg = arg;
}
/**
* Zurückgeben des Imaginärteiles
* @return Returns the imag.
*/
public double getImag()
{
return imag;
}
/**
* Setzen des Imaginärteiles
* @param imag The imag to set.
*/
public void setImag(double imag)
{
this.imag = imag;
}
/**
* Zurückgeben des Realteiles
* @return Returns the real.
*/
public double getReal()
{
return real;
}
/**
* Setzen des Realteiles
* @param real The real to set.
*/
public void setReal(double real)
{
this.real = real;
}
/**
* Liefert ein Array, mit den n Lösungen aus n-ter Wurzel zurück
* @return Returns the sqrtArgArray.
*/
public double[] getSqrtArgArray()
{
return sqrtArgArray;
}
/**
* @param sqrtArgArray The sqrtVector to set.
*/
public void setSqrtArgArray(double[] sqrtArgArray)
{
this.sqrtArgArray = sqrtArgArray;
}
// Funktionen als statische Funktionen einbinden
/**
* Addition zweier komplexer Zahlen
* @param comp1 1. Komplexe Zahl
* @param comp2 2. Komplexe Zahl
* @return Rückgabe von neuem Objekt mit Ergebnis aus Addition
*/
public static Complex add(Complex comp1, Complex comp2)
{
return new Complex(comp1.getReal() + comp2.getReal(), comp1.getImag() + comp2.getImag());
}
/**
* Subtraktion zweier komplexer Zahlen
* @param comp1 1. Komplexe Zahl
* @param comp2 2. Komplexe Zahl
* @return Rückgabe von neuem Objekt mit Ergebnis aus Subtraktion
*/
public static Complex sub(Complex comp1, Complex comp2)
{
return new Complex(comp1.getReal() - comp2.getReal(), comp1.getImag() - comp2.getImag());
}
/**
* Multiplikation zweier komplexer zahlen
* @param comp1 1. Komplexe Zahl
* @param comp2 2. Komplexe Zahl
* @return Rückgabe von neuem Objekt mit Ergebnis aus Multiplikation
*/
public static Complex mul(Complex comp1, Complex comp2)
{
return new Complex(comp1.getAbs() * comp2.getAbs(), comp1.getArg() + comp2.getArg(), true);
}
/**
* Division zweier komplexer zahlen
* @param comp1 1. Komplexe Zahl
* @param comp2 2. Komplexe Zahl
* @return Rückgabe von neuem Objekt mit Ergebnis aus Division
*/
public static Complex div(Complex comp1, Complex comp2)
{
return new Complex(comp1.getAbs() / comp2.getAbs(), comp1.getArg() - comp2.getArg(), true);
}
/**
* Funktion zur Berechnung mit dem Exponenten 'expon' >= 1
* @param comp Komplexe Zahl
* @param expon Exponenten, mit dem die komplexe Zahl exponiert ist.
* @return Rückgabe von neuem Objekt mit Ergebnis aus Exponierung
*/
public static Complex pow(Complex comp, int expon)
{
double abs, arg; // interne Variablen fuer Betrag und Phase
Complex swap = null;
if(expon>=1) {
abs = Math.pow(comp.getAbs(), (double)expon); // Betrag exponieren
arg = comp.getArg() * (double)expon; // Winkel mit Exponenten multiplizieren
swap = new Complex(abs, arg, true);
}
else
System.out.println("! Exponent kleiner 1 !");
return swap;
}
/**
* Berechnen der n-ten Wurzel der komplexen Zahl
* @param comp Komplexe Zahl
* @param expon Wurzelexponent
* @return Rückgabe eines Vector mit n Lösungen
*/
public static Complex sqrt(Complex comp, int expon)
{
double abs, arg; // interne Variablen fuer Betrag und Phase
double[] sqrtArgArray; // double-Array, mit n-Winkeln aus Wurzelberechnung
Complex swap = null;
if(expon>=1) {
sqrtArgArray = new double[expon]; // Anlegen des n double-Werte-Arrays für die n-Lösungen
abs = Math.pow(comp.getAbs(), 1d/(double)expon); // n-te Wurzel aus Betrag ziehen
for(int i=0; i<=expon-1; i++) { // Anlegen der n double-Werte fuer die n-Loesungen
sqrtArgArray[i] = comp.getArg()/(double)expon + ((double)i * 2*Math.PI)/(double)expon;
}
arg = sqrtArgArray[0]; // "Hauptwinkel" bekommt ersten Wert aus double-Werte-Array
swap = new Complex(abs, arg, true);
swap.setSqrtArgArray(sqrtArgArray);
}
else
System.out.println("! Wurzelexponent kleiner 1 !");
return swap;
}
/**
* Berechnen des Sinus der komplexen Zahl
* @param comp Komplexe Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus sin(z)
*/
public static Complex sin(Complex comp)
{
return new Complex(Math.sin(comp.getReal()) * Math.cosh(comp.getImag()),
Math.cos(comp.getReal()) * Math.sinh(comp.getImag()));
}
/**
* Berechnen des Kosinus der komplexen Zahl
* @param comp Komplexe Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus cos(z)
*/
public static Complex cos(Complex comp)
{
return new Complex(Math.cos(comp.getReal()) * Math.cosh(comp.getImag()),
Math.sin(comp.getReal()) * Math.sinh(comp.getImag()));
}
/**
* Berechnen des Tangens der komplexen Zahl
* @param comp Komplexe Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus tan(z)
*/
public static Complex tan(Complex comp)
{
double real, imag;
double nn = 1d + Math.pow(Math.tan(comp.getReal()) * Math.tanh(comp.getImag()), 2); // Nenner der Brueche
real = (Math.tan(comp.getReal())*(1-Math.pow(Math.tanh(comp.getImag()), 2))) / nn;
imag = (Math.tanh(comp.getImag())*(1+Math.pow(Math.tan(comp.getReal()), 2))) / nn;
return new Complex(real, imag);
}
/**
* Berechnen des Kotangens der komplexen Zahl
* @param comp Komplexe Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus cot(z)
*/
public static Complex cot(Complex comp)
{
double nn = Math.pow(Math.sin(comp.real)*Math.cosh(comp.imag), 2) + Math.pow(Math.cos(comp.real)*Math.sinh(comp.imag), 2);
return new Complex((Math.cos(comp.real) * Math.sin(comp.real)) / nn, (Math.cosh(comp.imag) * Math.sinh(comp.imag)) / nn);
}
/**
* Berechnen des Sinus-Hyperbolikus der komplexen Zahl
* @param comp Komplexe Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus sinh(z)
*/
public static Complex sinh(Complex comp)
{
return new Complex(Math.sinh(comp.getReal()) * Math.cos(comp.getImag()),
Math.cosh(comp.getReal()) * Math.sin(comp.getImag()));
}
/**
* Berechnen des Kosinus-Hyperbolikus der komplexen Zahl
* @param comp Komplexe Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus cosh(z)
*/
public static Complex cosh(Complex comp)
{
return new Complex(Math.cosh(comp.getReal()) * Math.cos(comp.getImag()),
Math.sinh(comp.getReal()) * Math.sin(comp.getImag()));
}
/**
* Berechnen des -Hyperbolikus der komplexen Zahl
* @param comp Komplexe Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus tanh(z)
*/
public static Complex tanh(Complex comp)
{
return Complex.div(comp.sinh(), comp.cosh());
}
/**
* Berechnen des Kotangens-Hyperbolikus der komplexen Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus coth(z)
*/
public static Complex coth(Complex comp)
{
return Complex.div(comp.cosh(), comp.sinh());
}
/**
* Berechnen der e-Funktion der komplexen Zahl
* @param comp Komplexe Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus exp(z)
*/
public static Complex exp(Complex comp)
{
return new Complex(Math.cos(comp.getImag()) * (Math.sinh(comp.getReal()) + Math.cosh(comp.getReal())),
Math.sin(comp.getImag()) * (Math.cosh(comp.getReal()) + Math.sinh(comp.getReal())));
}
/**
* Berechnen des natürlichen Logarithmus der komplexen Zahl
* @param comp Komplexe Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus ln(z)
*/
public static Complex ln(Complex comp)
{
return new Complex(Math.log(comp.getAbs()), comp.getArg());
}
/**
* Berechnen des Logarithmus zur Basis 10 komplexen Zahl
* @param comp Komplexe Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus log(z)
*/
public static Complex log(Complex comp)
{
return new Complex(Math.log10(comp.getAbs()), Math.log10(Math.exp(comp.getArg())));
}
/**
* Berechnen der konjugierten komplexen Zahl
* * @param comp Komplexe Zahl
* @return Rückgabe eines Objektes vom Typ Complex mit Lösung aus conj(z)
*/
public Complex conj(Complex comp)
{
return new Complex(comp.getReal(), -comp.getImag());
}
}