smile.math.Complex Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openchemlib Show documentation
Show all versions of openchemlib Show documentation
Open Source Chemistry Library
/*******************************************************************************
* Copyright (c) 2010 Haifeng Li
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package smile.math;
import java.io.Serializable;
/**
* Complex number. The object is immutable so once you create and initialize
* a Complex object, you cannot modify it.
*
* @author Haifeng Li
*/
public class Complex implements Serializable {
private static final long serialVersionUID = 1L;
/**
* The real part.
*/
private final double re;
/**
* The imaginary part.
*/
private final double im;
/**
* Constructor.
* @param real real part
* @param imag imaginary part
*/
public Complex(double real, double imag) {
re = real;
im = imag;
}
@Override
public String toString() {
if (im == 0) {
return String.format("%.4f", re);
}
if (re == 0) {
return String.format("%.4fi", im);
}
if (im < 0) {
return String.format("%.4f - %.4fi", re, -im);
}
return String.format("%.4f + %.4fi", re, im);
}
@Override
public boolean equals(Object o) {
if (o instanceof Complex) {
Complex c = (Complex) o;
if (re == c.re && im == c.im) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
int hash = 7;
hash = 47 * hash + (int) (Double.doubleToLongBits(re) ^ (Double.doubleToLongBits(re) >>> 32));
hash = 47 * hash + (int) (Double.doubleToLongBits(im) ^ (Double.doubleToLongBits(im) >>> 32));
return hash;
}
/**
* Returns abs/modulus/magnitude.
*/
public double abs() {
return Math.hypot(re, im);
}
/**
* Returns angle/phase/argument between -pi and pi.
*/
public double phase() {
return Math.atan2(im, re);
}
/**
* Returns this + b.
*/
public Complex plus(Complex b) {
Complex a = this;
double real = a.re + b.re;
double imag = a.im + b.im;
return new Complex(real, imag);
}
/**
* Returns this - b.
*/
public Complex minus(Complex b) {
Complex a = this;
double real = a.re - b.re;
double imag = a.im - b.im;
return new Complex(real, imag);
}
/**
* Returns this * b.
*/
public Complex times(Complex b) {
Complex a = this;
double real = a.re * b.re - a.im * b.im;
double imag = a.re * b.im + a.im * b.re;
return new Complex(real, imag);
}
/**
* Scalar multiplication.* Returns this * b.
*/
public Complex times(double b) {
return new Complex(b * re, b * im);
}
/**
* Returns a / b.
*/
public Complex div(Complex b) {
double cdivr, cdivi;
double r, d;
if (Math.abs(b.re) > Math.abs(b.im)) {
r = b.im / b.re;
d = b.re + r * b.im;
cdivr = (re + r * im) / d;
cdivi = (im - r * re) / d;
} else {
r = b.re / b.im;
d = b.im + r * b.re;
cdivr = (r * re + im) / d;
cdivi = (r * im - re) / d;
}
return new Complex(cdivr, cdivi);
}
/**
* Returns the conjugate.
*/
public Complex conjugate() {
return new Complex(re, -im);
}
/**
* Returns the reciprocal.
*/
public Complex reciprocal() {
double scale = re * re + im * im;
return new Complex(re / scale, -im / scale);
}
/**
* Returns the real part.
*/
public double re() {
return re;
}
/**
* Returns the imaginary part.
*/
public double im() {
return im;
}
/**
* Returns the complex exponential.
*/
public Complex exp() {
return new Complex(Math.exp(re) * Math.cos(im), Math.exp(re) * Math.sin(im));
}
/**
* Returns the complex sine.
*/
public Complex sin() {
return new Complex(Math.sin(re) * Math.cosh(im), Math.cos(re) * Math.sinh(im));
}
/**
* Returns the complex cosine.
*/
public Complex cos() {
return new Complex(Math.cos(re) * Math.cosh(im), -Math.sin(re) * Math.sinh(im));
}
/**
* Returns the complex tangent.
*/
public Complex tan() {
return sin().div(cos());
}
}