
edu.jas.arith.BigComplex Maven / Gradle / Ivy
The newest version!
/*
* $Id: BigComplex.java 4125 2012-08-19 19:05:22Z kredel $
*/
package edu.jas.arith;
import java.io.Reader;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.apache.log4j.Logger;
import edu.jas.kern.StringUtil;
import edu.jas.structure.GcdRingElem;
import edu.jas.structure.RingFactory;
import edu.jas.structure.StarRingElem;
/**
* BigComplex class based on BigRational implementing the RingElem respectively
* the StarRingElem interface. Objects of this class are immutable. The SAC2
* static methods are also provided.
* @author Heinz Kredel
*/
public final class BigComplex implements StarRingElem, GcdRingElem,
RingFactory {
/**
* Real part of the data structure.
*/
public final BigRational re;
/**
* Imaginary part of the data structure.
*/
public final BigRational im;
private final static Random random = new Random();
private static final Logger logger = Logger.getLogger(BigComplex.class);
/**
* The constructor creates a BigComplex object from two BigRational objects
* real and imaginary part.
* @param r real part.
* @param i imaginary part.
*/
public BigComplex(BigRational r, BigRational i) {
re = r;
im = i;
}
/**
* The constructor creates a BigComplex object from a BigRational object as
* real part, the imaginary part is set to 0.
* @param r real part.
*/
public BigComplex(BigRational r) {
this(r, BigRational.ZERO);
}
/**
* The constructor creates a BigComplex object from a long element as real
* part, the imaginary part is set to 0.
* @param r real part.
*/
public BigComplex(long r) {
this(new BigRational(r), BigRational.ZERO);
}
/**
* The constructor creates a BigComplex object with real part 0 and
* imaginary part 0.
*/
public BigComplex() {
this(BigRational.ZERO);
}
/**
* The constructor creates a BigComplex object from a String representation.
* @param s string of a BigComplex.
* @throws NumberFormatException
*/
public BigComplex(String s) throws NumberFormatException {
if (s == null || s.length() == 0) {
re = BigRational.ZERO;
im = BigRational.ZERO;
return;
}
s = s.trim();
int i = s.indexOf("i");
if (i < 0) {
re = new BigRational(s);
im = BigRational.ZERO;
return;
}
//logger.warn("String constructor not done");
String sr = "";
if (i > 0) {
sr = s.substring(0, i);
}
String si = "";
if (i < s.length()) {
si = s.substring(i + 1, s.length());
}
//int j = sr.indexOf("+");
re = new BigRational(sr.trim());
im = new BigRational(si.trim());
}
/**
* Get the corresponding element factory.
* @return factory for this Element.
* @see edu.jas.structure.Element#factory()
*/
public BigComplex factory() {
return this;
}
/**
* Get a list of the generating elements.
* @return list of generators for the algebraic structure.
* @see edu.jas.structure.ElemFactory#generators()
*/
public List generators() {
List g = new ArrayList(2);
g.add(getONE());
g.add(getIMAG());
return g;
}
/**
* Is this structure finite or infinite.
* @return true if this structure is finite, else false.
* @see edu.jas.structure.ElemFactory#isFinite()
*/
public boolean isFinite() {
return false;
}
/**
* Clone this.
* @see java.lang.Object#clone()
*/
@Override
public BigComplex copy() {
return new BigComplex(re, im);
}
/**
* Copy BigComplex element c.
* @param c BigComplex.
* @return a copy of c.
*/
public BigComplex copy(BigComplex c) {
return new BigComplex(c.re, c.im);
}
/**
* Get the zero element.
* @return 0 as BigComplex.
*/
public BigComplex getZERO() {
return ZERO;
}
/**
* Get the one element.
* @return 1 as BigComplex.
*/
public BigComplex getONE() {
return ONE;
}
/**
* Get the i element.
* @return i as BigComplex.
*/
public BigComplex getIMAG() {
return I;
}
/**
* Query if this ring is commutative.
* @return true.
*/
public boolean isCommutative() {
return true;
}
/**
* Query if this ring is associative.
* @return true.
*/
public boolean isAssociative() {
return true;
}
/**
* Query if this ring is a field.
* @return true.
*/
public boolean isField() {
return true;
}
/**
* Characteristic of this ring.
* @return characteristic of this ring.
*/
public java.math.BigInteger characteristic() {
return java.math.BigInteger.ZERO;
}
/**
* Get a BigComplex element from a BigInteger.
* @param a BigInteger.
* @return a BigComplex.
*/
public BigComplex fromInteger(BigInteger a) {
return new BigComplex(new BigRational(a));
}
/**
* Get a BigComplex element from a long.
* @param a long.
* @return a BigComplex.
*/
public BigComplex fromInteger(long a) {
return new BigComplex(new BigRational(a));
}
/**
* The constant 0.
*/
public static final BigComplex ZERO = new BigComplex();
/**
* The constant 1.
*/
public static final BigComplex ONE = new BigComplex(BigRational.ONE);
/**
* The constant i.
*/
public static final BigComplex I = new BigComplex(BigRational.ZERO, BigRational.ONE);
/**
* Get the real part.
* @return re.
*/
public BigRational getRe() {
return re;
}
/**
* Get the imaginary part.
* @return im.
*/
public BigRational getIm() {
return im;
}
/**
* Get the String representation.
*/
@Override
public String toString() {
String s = "" + re;
int i = im.compareTo(BigRational.ZERO);
//logger.info("compareTo "+im+" ? 0 = "+i);
if (i == 0)
return s;
s += "i" + im;
return s;
}
/**
* Get a scripting compatible string representation.
* @return script compatible representation for this Element.
* @see edu.jas.structure.Element#toScript()
*/
//JAVA6only: @Override
public String toScript() {
// Python case: re or re+im*i
// was (re,im) or (re,)
StringBuffer s = new StringBuffer();
boolean iz = im.isZERO();
if (iz) {
s.append(re.toScript());
return s.toString();
}
boolean rz = re.isZERO();
if (rz) {
if (!im.isONE()) {
if (im.signum() > 0) {
s.append(im.toScript() + "*");
} else {
s.append("-");
BigRational ii = im.negate();
if (!ii.isONE()) {
s.append(ii.toScript() + "*");
}
}
}
} else {
s.append(re.toScript());
if (im.signum() > 0) {
s.append("+");
if (!im.isONE()) {
s.append(im.toScript() + "*");
}
} else {
s.append("-");
BigRational ii = im.negate();
if (!ii.isONE()) {
s.append(ii.toScript() + "*");
}
}
}
s.append("I");
return s.toString();
}
/**
* Get a scripting compatible string representation of the factory.
* @return script compatible representation for this ElemFactory.
* @see edu.jas.structure.Element#toScriptFactory()
*/
//JAVA6only: @Override
public String toScriptFactory() {
// Python case
return "CC()";
}
/**
* Complex number zero.
* @param A is a complex number.
* @return If A is 0 then true is returned, else false.
*/
public static boolean isCZERO(BigComplex A) {
if (A == null)
return false;
return A.isZERO();
}
/**
* Is Complex number zero.
* @return If this is 0 then true is returned, else false.
* @see edu.jas.structure.RingElem#isZERO()
*/
public boolean isZERO() {
return re.equals(BigRational.ZERO) && im.equals(BigRational.ZERO);
}
/**
* Complex number one.
* @param A is a complex number.
* @return If A is 1 then true is returned, else false.
*/
public static boolean isCONE(BigComplex A) {
if (A == null)
return false;
return A.isONE();
}
/**
* Is Complex number one.
* @return If this is 1 then true is returned, else false.
* @see edu.jas.structure.RingElem#isONE()
*/
public boolean isONE() {
return re.equals(BigRational.ONE) && im.equals(BigRational.ZERO);
}
/**
* Is Complex imaginary one.
* @return If this is i then true is returned, else false.
*/
public boolean isIMAG() {
return re.equals(BigRational.ZERO) && im.equals(BigRational.ONE);
}
/**
* Is Complex unit element.
* @return If this is a unit then true is returned, else false.
* @see edu.jas.structure.RingElem#isUnit()
*/
public boolean isUnit() {
return (!isZERO());
}
/**
* Comparison with any other object.
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object b) {
if (!(b instanceof BigComplex)) {
return false;
}
BigComplex bc = (BigComplex) b;
return re.equals(bc.re) && im.equals(bc.im);
}
/**
* Hash code for this BigComplex.
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return 37 * re.hashCode() + im.hashCode();
}
/**
* Since complex numbers are unordered, we use lexicographical order of re
* and im.
* @return 0 if this is equal to b; 1 if re > b.re, or re == b.re and im >
* b.im; -1 if re < b.re, or re == b.re and im < b.im
*/
//JAVA6only: @Override
public int compareTo(BigComplex b) {
int s = re.compareTo(b.re);
if (s != 0) {
return s;
}
return im.compareTo(b.im);
}
/**
* Since complex numbers are unordered, we use lexicographical order of re
* and im.
* @return 0 if this is equal to 0; 1 if re > 0, or re == 0 and im > 0; -1
* if re < 0, or re == 0 and im < 0
* @see edu.jas.structure.RingElem#signum()
*/
public int signum() {
int s = re.signum();
if (s != 0) {
return s;
}
return im.signum();
}
/* arithmetic operations: +, -, -
*/
/**
* Complex number summation.
* @param B a BigComplex number.
* @return this+B.
*/
public BigComplex sum(BigComplex B) {
return new BigComplex(re.sum(B.re), im.sum(B.im));
}
/**
* Complex number sum.
* @param A and B are complex numbers.
* @return A+B.
*/
public static BigComplex CSUM(BigComplex A, BigComplex B) {
if (A == null)
return null;
return A.sum(B);
}
/**
* Complex number difference.
* @param A and B are complex numbers.
* @return A-B.
*/
public static BigComplex CDIF(BigComplex A, BigComplex B) {
if (A == null)
return null;
return A.subtract(B);
}
/**
* Complex number subtract.
* @param B a BigComplex number.
* @return this-B.
*/
public BigComplex subtract(BigComplex B) {
return new BigComplex(re.subtract(B.re), im.subtract(B.im));
}
/**
* Complex number negative.
* @param A is a complex number.
* @return -A
*/
public static BigComplex CNEG(BigComplex A) {
if (A == null)
return null;
return A.negate();
}
/**
* Complex number negative.
* @return -this.
* @see edu.jas.structure.RingElem#negate()
*/
public BigComplex negate() {
return new BigComplex(re.negate(), im.negate());
}
/**
* Complex number conjugate.
* @param A is a complex number.
* @return the complex conjugate of A.
*/
public static BigComplex CCON(BigComplex A) {
if (A == null)
return null;
return A.conjugate();
}
/* arithmetic operations: conjugate, absolut value
*/
/**
* Complex number conjugate.
* @return the complex conjugate of this.
*/
public BigComplex conjugate() {
return new BigComplex(re, im.negate());
}
/**
* Complex number norm.
* @see edu.jas.structure.StarRingElem#norm()
* @return ||this||.
*/
public BigComplex norm() {
// this.conjugate().multiply(this);
BigRational v = re.multiply(re);
v = v.sum(im.multiply(im));
return new BigComplex(v);
}
/**
* Complex number absolute value.
* @see edu.jas.structure.RingElem#abs()
* @return |this|^2. Note: The square root is not jet implemented.
*/
public BigComplex abs() {
BigComplex n = norm();
logger.error("abs() square root missing");
// n = n.sqrt();
return n;
}
/**
* Complex number absolute value.
* @param A is a complex number.
* @return the absolute value of A, a rational number. Note: The square root
* is not jet implemented.
*/
public static BigRational CABS(BigComplex A) {
if (A == null)
return null;
return A.abs().re;
}
/**
* Complex number product.
* @param A and B are complex numbers.
* @return A*B.
*/
public static BigComplex CPROD(BigComplex A, BigComplex B) {
if (A == null)
return null;
return A.multiply(B);
}
/* arithmetic operations: *, inverse, /
*/
/**
* Complex number product.
* @param B is a complex number.
* @return this*B.
*/
public BigComplex multiply(BigComplex B) {
return new BigComplex(re.multiply(B.re).subtract(im.multiply(B.im)), re.multiply(B.im).sum(
im.multiply(B.re)));
}
/**
* Complex number inverse.
* @param A is a non-zero complex number.
* @return S with S*A = 1.
*/
public static BigComplex CINV(BigComplex A) {
if (A == null)
return null;
return A.inverse();
}
/**
* Complex number inverse.
* @return S with S*this = 1.
* @see edu.jas.structure.RingElem#inverse()
*/
public BigComplex inverse() {
BigRational a = norm().re.inverse();
return new BigComplex(re.multiply(a), im.multiply(a.negate()));
}
/**
* Complex number inverse.
* @param S is a complex number.
* @return 0.
*/
public BigComplex remainder(BigComplex S) {
if (S.isZERO()) {
throw new ArithmeticException("division by zero");
}
return ZERO;
}
/**
* Complex number quotient.
* @param A and B are complex numbers, B non-zero.
* @return A/B.
*/
public static BigComplex CQ(BigComplex A, BigComplex B) {
if (A == null)
return null;
return A.divide(B);
}
/**
* Complex number divide.
* @param B is a complex number, non-zero.
* @return this/B.
*/
public BigComplex divide(BigComplex B) {
return this.multiply(B.inverse());
}
/**
* Complex number, random. Random rational numbers A and B are generated
* using random(n). Then R is the complex number with real part A and
* imaginary part B.
* @param n such that 0 ≤ A, B ≤ (2n-1).
* @return R.
*/
public BigComplex random(int n) {
return random(n, random);
}
/**
* Complex number, random. Random rational numbers A and B are generated
* using random(n). Then R is the complex number with real part A and
* imaginary part B.
* @param n such that 0 ≤ A, B ≤ (2n-1).
* @param rnd is a source for random bits.
* @return R.
*/
public BigComplex random(int n, Random rnd) {
BigRational r = BigRational.ONE.random(n, rnd);
BigRational i = BigRational.ONE.random(n, rnd);
return new BigComplex(r, i);
}
/**
* Complex number, random. Random rational numbers A and B are generated
* using random(n). Then R is the complex number with real part A and
* imaginary part B.
* @param n such that 0 ≤ A, B ≤ (2n-1).
* @return R.
*/
public static BigComplex CRAND(int n) {
return ONE.random(n, random);
}
/**
* Parse complex number from string.
* @param s String.
* @return BigComplex from s.
*/
public BigComplex parse(String s) {
return new BigComplex(s);
}
/**
* Parse complex number from Reader.
* @param r Reader.
* @return next BigComplex from r.
*/
public BigComplex parse(Reader r) {
return parse(StringUtil.nextString(r));
}
/**
* Complex number greatest common divisor.
* @param S BigComplex.
* @return gcd(this,S).
*/
public BigComplex gcd(BigComplex S) {
if (S == null || S.isZERO()) {
return this;
}
if (this.isZERO()) {
return S;
}
return ONE;
}
/**
* BigComplex extended greatest common divisor.
* @param S BigComplex.
* @return [ gcd(this,S), a, b ] with a*this + b*S = gcd(this,S).
*/
public BigComplex[] egcd(BigComplex S) {
BigComplex[] ret = new BigComplex[3];
ret[0] = null;
ret[1] = null;
ret[2] = null;
if (S == null || S.isZERO()) {
ret[0] = this;
return ret;
}
if (this.isZERO()) {
ret[0] = S;
return ret;
}
BigComplex half = new BigComplex(new BigRational(1, 2));
ret[0] = ONE;
ret[1] = this.inverse().multiply(half);
ret[2] = S.inverse().multiply(half);
return ret;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy