package jsci.maths.polynomials;
import jsci.GlobalSettings;
import jsci.maths.Complex;
import jsci.maths.fields.*;
import jsci.maths.groups.*;
/**
* A Polynomial over the complex field.
* For a description of the methods
* @see jsci.maths.polynomials.RealPolynomial
*
* @author b.dietrich
*/
public class ComplexPolynomial implements Polynomial {
private Complex[] _coeff;
/** Creates a new instance of ComplexPolynomial */
public ComplexPolynomial( Complex[] coeff ) {
if ( coeff == null ) {
throw new NullPointerException("Coefficients cannot be null");
}
_coeff = normalise(coeff);
}
/**
* Normalises the coefficient array.
* Trims off any leading (high degree) zero terms.
*/
private static Complex[] normalise(Complex[] c) {
int i = c.length-1;
while(i >= 0 && c[i].norm() <= 2.0*GlobalSettings.ZERO_TOL)
i--;
if(i < 0) {
return new Complex[] {Complex.ZERO};
} else if(i < c.length-1) {
Complex[] arr = new Complex[i+1];
System.arraycopy(c, 0, arr, 0, arr.length);
return arr;
} else {
return c;
}
}
/**
* Creates a new ComplexPolynomial object.
*
* @param f
*/
public ComplexPolynomial( Field.Member[] f ) {
_coeff = normalise(ComplexPolynomialRing.toComplex( f ));
}
/**
*
* @param n
*/
public Field.Member getCoefficient( int n ) {
return getCoefficientAsComplex( n );
}
/**
*
* @param n
*/
public Complex getCoefficientAsComplex( int n ) {
if ( n >= _coeff.length ) {
return Complex.ZERO;
} else {
return _coeff[n];
}
}
/**
*/
public Field.Member[] getCoefficients() {
return getCoefficientsAsComplexes();
}
/**
* Return the coefficients as an array of complex numbers.
*/
public Complex[] getCoefficientsAsComplexes() {
return _coeff;
}
/**
* Evaluates this polynomial.
*/
public Complex map(Complex z) {
return PolynomialMath.evalPolynomial(this, z);
}
/**
* Evaluates this polynomial.
*/
public Complex map(double x, double y) {
return map(new Complex(x, y));
}
/**
*
* @return the degree
*/
public int degree() {
return _coeff.length-1;
}
public Object getSet() {
return ComplexPolynomialRing.getInstance();
}
/**
*
* @return true if this is equal to zero.
*/
public boolean isZero() {
for ( int k = 0; k < _coeff.length; k++ ) {
if ( _coeff[k].norm() > ( GlobalSettings.ZERO_TOL * 2.0 ) ) {
return false;
}
}
return true;
}
/**
*
* @return true if this is equal to one.
*/
public boolean isOne() {
if(_coeff[0].subtract( Complex.ONE ).norm() > ( GlobalSettings.ZERO_TOL * 2.0 ))
return false;
for ( int k = 1; k < _coeff.length; k++ ) {
if ( _coeff[k].norm() > ( 2.0 * GlobalSettings.ZERO_TOL ) ) {
return false;
}
}
return true;
}
/** The group composition law.
* @param g a group member
*
*/
public AbelianGroup.Member add( AbelianGroup.Member g ) {
AbelianGroup.Member result = null;
if ( g instanceof ComplexPolynomial ) {
ComplexPolynomial p = (ComplexPolynomial) g;
int maxgrade = PolynomialMath.maxDegree( this, p );
Complex[] c = new Complex[maxgrade+1];
for ( int k = 0; k < c.length; k++ ) {
c[k] = getCoefficientAsComplex( k ).add( p.getCoefficientAsComplex( k ) );
}
result = new ComplexPolynomial( c );
} else {
throw new IllegalArgumentException("Member class not recognised by this method.");
}
return result;
}
/**
* Returns the division of this polynomial by a scalar.
* @param f
*
*/
public Polynomial scalarDivide( Field.Member f ) {
if ( f instanceof Complex ) {
return scalarDivide( (Complex) f );
} else if ( f instanceof Number ) {
return scalarDivide( ( (Number) f ).doubleValue() );
} else {
throw new IllegalArgumentException("Member class not recognised by this method.");
}
}
/**
* Returns the division of this polynomial by a scalar.
* @param a
*/
public ComplexPolynomial scalarDivide( Complex a ) {
Complex[] c = new Complex[_coeff.length];
for ( int k = 0; k < c.length; k++ ) {
c[k] = _coeff[k].divide( a );
}
return new ComplexPolynomial( c );
}
/**
* Returns the division of this polynomial by a scalar.
* @param a
*/
public ComplexPolynomial scalarDivide( double a ) {
Complex[] c = new Complex[_coeff.length];
for ( int k = 0; k < c.length; k++ ) {
c[k] = _coeff[k].divide( a );
}
return new ComplexPolynomial( c );
}
/**
*
* @param o
*/
public boolean equals( Object o ) {
if ( o == this ) {
return true;
} else if ( o instanceof ComplexPolynomial ) {
ComplexPolynomial p = (ComplexPolynomial) o;
int maxgrade = PolynomialMath.maxDegree( this, p );
for ( int k = 0; k<=maxgrade; k++ ) {
if ( p.getCoefficientAsComplex(k).subtract( getCoefficientAsComplex(k) ).norm() > ( 2 * GlobalSettings.ZERO_TOL ) ) {
return false;
}
}
return true;
}
return false;
}
/**
*
*/
public int hashCode() {
int res = 0;
for ( int k = 0; k < _coeff.length; k++ ) {
res += (int) ( _coeff[k].norm() * 10.0 );
}
return res;
}
/**
* Returns the multiplication of this polynomial by a scalar.
* @param f
*/
public Polynomial scalarMultiply( Field.Member f ) {
if ( f instanceof Number ) {
double a = ( (Number) f ).doubleValue();
return scalarMultiply( a );
} else if ( f instanceof Complex ) {
return scalarMultiply( (Complex) f );
} else {
throw new IllegalArgumentException("Member class not recognised by this method.");
}
}
/**
* Returns the multiplication of this polynomial by a scalar.
* @param a
*/
public ComplexPolynomial scalarMultiply( double a ) {
Complex[] c = new Complex[_coeff.length];
for ( int k = 0; k < c.length; k++ ) {
c[k] = _coeff[k].multiply( a );
}
return new ComplexPolynomial( c );
}
/**
* Returns the multiplication of this polynomial by a scalar.
* @param a
*/
public ComplexPolynomial scalarMultiply( Complex a ) {
Complex[] c = new Complex[_coeff.length];
for ( int k = 0; k < c.length; k++ ) {
c[k] = _coeff[k].multiply( a );
}
return new ComplexPolynomial( c );
}
/** The multiplication law.
* @param r a ring member
*
*/
public Ring.Member multiply( Ring.Member r ) {
if ( r instanceof ComplexPolynomial ) {
ComplexPolynomial p = (ComplexPolynomial) r;
int maxgrade = PolynomialMath.maxDegree( this, p );
int mingrade = PolynomialMath.minDegree( this, p );
int destgrade = maxgrade + mingrade;
Complex[] n = new Complex[destgrade+1];
for ( int k = 0; k < n.length; k++ ) {
n[k] = Complex.ZERO;
}
for ( int k = 0; k < _coeff.length; k++ ) {
Complex tis = _coeff[k];
for ( int j = 0; j < p._coeff.length; j++ ) {
Complex tat = p._coeff[j];
n[k + j] = n[k + j].add( tis.multiply( tat ) );
}
}
return new ComplexPolynomial( n );
} else {
throw new IllegalArgumentException("Member class not recognised by this method.");
}
}
/** Returns the inverse member.
*
*/
public AbelianGroup.Member negate() {
Complex[] c = new Complex[_coeff.length];
for ( int k = 0; k < c.length; k++ ) {
c[k] = (Complex) _coeff[k].negate();
}
return new ComplexPolynomial( c );
}
/** The group composition law with inverse.
* @param g a group member
*
*/
public AbelianGroup.Member subtract( AbelianGroup.Member g ) {
if ( g instanceof ComplexPolynomial ) {
ComplexPolynomial p = (ComplexPolynomial) g;
int maxgrade = PolynomialMath.maxDegree( this, p );
Complex[] c = new Complex[maxgrade+1];
for ( int k = 0; k < c.length; k++ ) {
c[k] = getCoefficientAsComplex( k ).subtract( p.getCoefficientAsComplex( k ) );
}
return new ComplexPolynomial( c );
} else {
throw new IllegalArgumentException("Member class not recognised by this method.");
}
}
/**
*
*/
public String toString() {
StringBuffer sb = new StringBuffer( "P(z) = " );
for ( int k = degree(); k > 0; k-- ) {
sb.append( _coeff[k] ).append( "z^" ).append( k ).append( " + " );
}
sb.append( _coeff[0] );
return sb.toString();
}
}
Ads help maintain this website.