JSci.maths.Complex Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jsci Show documentation
Show all versions of jsci Show documentation
JSci is a set of open source Java packages. The aim is to encapsulate scientific methods/principles in the most natural way possible. As such they should greatly aid the development of scientific based software.
It offers: abstract math interfaces, linear algebra (support for various matrix and vector types), statistics (including probability distributions), wavelets, newtonian mechanics, chart/graph components (AWT and Swing), MathML DOM implementation, ...
Note: some packages, like javax.comm, for the astro and instruments package aren't listed as dependencies (not available).
The newest version!
package JSci.maths;
import JSci.GlobalSettings;
import JSci.maths.groups.AbelianGroup;
import JSci.maths.fields.*;
import JSci.maths.algebras.*;
/**
* The Complex class encapsulates complex numbers.
* @jsci.planetmath Complex
* @jsci.wikipedia Complex_number
* @version 2.25
* @author Mark Hale
*/
public final class Complex extends Object implements Field.Member, CStarAlgebra.Member {
private static final long serialVersionUID = 6561957920497208796L;
private double re;
private double im;
/**
* Caching.
*/
private transient boolean isModCached=false;
private transient double modCache;
private transient boolean isArgCached=false;
private transient double argCache;
/**
* The complex number 0+1i.
*/
public static final Complex I=ComplexField.I;
/**
* The complex number 1+0i.
*/
public static final Complex ONE=ComplexField.ONE;
/**
* The complex number 0+0i.
*/
public static final Complex ZERO=ComplexField.ZERO;
/**
* Constructs the complex number x+iy.
* @param x the real value of a complex number.
* @param y the imaginary value of a complex number.
*/
public Complex(final double x,final double y) {
re=x;
im=y;
}
/**
* Constructs the complex number represented by a string.
* @param s a string representing a complex number.
* @exception NumberFormatException if the string does not contain a parsable number.
*/
public Complex(final String s) throws NumberFormatException {
final int iPos = s.indexOf('i');
if(iPos == -1) {
// no 'i' so must be real
re = Double.parseDouble(s);
im = 0.0;
} else {
int signPos = indexOf(s, '+', '-', 1);
int expPos = indexOf(s, 'E', 'e', 1);
if(signPos == expPos+1)
signPos = indexOf(s, '+', '-', signPos+1);
String imStr;
if(signPos == -1) {
re=0.0;
imStr=s;
} else {
if(iPos=0.0)
buf.append("+");
buf.append(imag);
buf.append("i");
return buf.toString();
}
/**
* Returns a hashcode for this complex number.
*/
public int hashCode() {
return (int)(Math.exp(mod()));
}
/**
* Returns true if the modulus of this complex number is within the zero tolerance.
*/
public boolean isZero() {
return (mod() <= GlobalSettings.ZERO_TOL);
}
/**
* Returns true if either the real or imaginary part is NaN.
*/
public boolean isNaN() {
return (re==Double.NaN) || (im==Double.NaN);
}
/**
* Returns true if either the real or imaginary part is infinite.
*/
public boolean isInfinite() {
return (re==Double.POSITIVE_INFINITY) || (re==Double.NEGATIVE_INFINITY)
|| (im==Double.POSITIVE_INFINITY) || (im==Double.NEGATIVE_INFINITY);
}
/**
* Returns the real part of this complex number.
*/
public double real() {
return re;
}
/**
* Returns the imaginary part of this complex number.
*/
public double imag() {
return im;
}
/**
* Returns the modulus of this complex number.
*/
public double mod() {
if(isModCached)
return modCache;
modCache=mod(re,im);
isModCached=true;
return modCache;
}
private static double mod(final double real,final double imag) {
final double reAbs=Math.abs(real);
final double imAbs=Math.abs(imag);
if(reAbs==0.0 && imAbs==0.0)
return 0.0;
else if(reAbs* norm.
*/
public double norm() {
return mod();
}
public Object getSet() {
return ComplexField.getInstance();
}
//============
// OPERATIONS
//============
/**
* Returns the negative of this complex number.
*/
public AbelianGroup.Member negate() {
return new Complex(-re,-im);
}
/**
* Returns the inverse of this complex number.
*/
public Field.Member inverse() {
double denominator,real,imag;
if(Math.abs(re)/2 through /2,
* - through ).
* @param z a complex number.
*/
public static Complex asin(final Complex z) {
if(z.equals(ONE))
return ComplexField.PI_2;
else if(z.equals(ComplexField.MINUS_ONE))
return ComplexField.MINUS_PI_2;
else {
// atan(z/sqrt(1-z*z))
final Complex root=sqrt(1.0-z.re*z.re+z.im*z.im,-2.0*z.re*z.im);
final double zModSqr=z.re*z.re+z.im*z.im;
final double rootModSqr=root.re*root.re+root.im*root.im;
final double denom=rootModSqr+zModSqr+2.0*(root.re*z.im-root.im*z.re);
return log_2I((rootModSqr-zModSqr)/denom,2.0*(root.re*z.re+root.im*z.im)/denom);
}
}
// INVERSE COS
/**
* Returns the arc cosine of a complex number, in the range of
* (0.0 through ,
* 0.0 through ).
* @param z a complex number.
*/
public static Complex acos(final Complex z) {
if(z.equals(ONE))
return ZERO;
else if(z.equals(ComplexField.MINUS_ONE))
return ComplexField.PI;
else {
// atan(-z/sqrt(1-z*z))+PI/2
final Complex root=sqrt(1.0-z.re*z.re+z.im*z.im,-2.0*z.re*z.im);
final double zModSqr=z.re*z.re+z.im*z.im;
final double rootModSqr=root.re*root.re+root.im*root.im;
final double denom=rootModSqr+zModSqr+2.0*(root.im*z.re-root.re*z.im);
return log_2IplusPI_2((rootModSqr-zModSqr)/denom,-2.0*(root.re*z.re+root.im*z.im)/denom);
}
}
// INVERSE TAN
/**
* Returns the arc tangent of a complex number, in the range of
* (-/2 through /2,
* - through ).
* @param z a complex number.
*/
public static Complex atan(final Complex z) {
// -i atanh(iz) = -i/2 log((1+iz)/(1-iz))
final double modSqr=z.modSqr();
final double denom=1.0+modSqr+2.0*z.im;
return log_2I((1.0-modSqr)/denom,2.0*z.re/denom);
}
// INVERSE SINH
/**
* Returns the arc hyperbolic sine of a complex number, in the range of
* (- through ,
* -/2 through /2).
* @param z a complex number.
*/
public static Complex asinh(final Complex z) {
if(z.equals(I))
return ComplexField.PI_2_I;
else if(z.equals(ComplexField.MINUS_I))
return ComplexField.MINUS_PI_2_I;
else {
// log(z+sqrt(z*z+1))
final Complex root=sqrt(z.re*z.re-z.im*z.im+1.0,2.0*z.re*z.im);
return log(z.re+root.re,z.im+root.im);
}
}
// INVERSE COSH
/**
* Returns the arc hyperbolic cosine of a complex number, in the range of
* (0.0 through ,
* 0.0 through ).
* @param z a complex number.
*/
public static Complex acosh(final Complex z) {
if(z.equals(ONE))
return ZERO;
else if(z.equals(ComplexField.MINUS_ONE))
return ComplexField.PI_I;
else {
// log(z+sqrt(z*z-1))
final Complex root=sqrt(z.re*z.re-z.im*z.im-1.0,2.0*z.re*z.im);
return log(z.re+root.re,z.im+root.im);
}
}
// INVERSE TANH
/**
* Returns the arc hyperbolic tangent of a complex number, in the range of
* (- through ,
* -/2 through /2).
* @param z a complex number.
*/
public static Complex atanh(final Complex z) {
// 1/2 log((1+z)/(1-z))
final double modSqr=z.modSqr();
final double denom=1.0+modSqr-2.0*z.re;
return log_2((1.0-modSqr)/denom,2.0*z.im/denom);
}
}