importjava.util.regex.Matcher;importjava.util.regex.Pattern;/**
* A complex value with double precision.
*
* @author Cloudy1225
*/publicclassComplex{
privatedouble real, imag;/***** Constant Variables *****/publicstaticfinalComplex REAL_UNIT =newComplex(1.0,0.0);publicstaticfinalComplex NEG_REAL_UNIT =newComplex(-1.0,0.0);publicstaticfinalComplex IMAG_UNIT =newComplex(0.0,1.0);publicstaticfinalComplex NEG_IMAG_UNIT =newComplex(0.0,-1.0);publicstaticfinalComplex ZERO =newComplex(0.0);/***** Constructors *****/publicComplex(double real,double imag){
this.real = real;this.imag = imag;}publicComplex(double real){
this.real = real;this.imag =0;}publicComplex(){
this.real =0;this.imag =0;}/***** getter and setter *****/publicdoublereal(){
returnthis.real;}publicdoubleimag(){
returnthis.imag;}protectedvoidset(double real,double imag){
this.real = real;this.imag = imag;}protectedvoidsetReal(double real){
this.real = real;}protectedvoidsetImag(double imag){
this.imag = imag;}/***** Override some methods in Object *****/@OverridepublicStringtoString(){
if(this.imag >0){
return((real==0)?"": real+"+")+ imag +"i";}elseif(this.imag <0){
return((real==0)?"": real+"")+ imag +"i";}else{
returnString.valueOf(real);}}@Overridepublicbooleanequals(Object obj){
if(!(obj instanceofComplex))returnfalse;Complex other =(Complex) obj;returnthis.real == other.real &&this.imag == other.imag;}@OverridepublicinthashCode(){
returnDouble.valueOf(this.real).hashCode()^Double.valueOf(this.imag).hashCode();}/**
* Create a deep copy of the complex
*
* @return deep copy of the complex
*/publicComplexcopy(){
returnnewComplex(this.real,this.imag);}/**
* Constructs a newly allocated Complex object that
* represents the complex value represented by the double.
*
* @param d a double to be converted to a complex.
*/publicstaticComplexvalueOf(double d){
returnnewComplex(d);}/**
* Constructs a newly allocated Complex object that
* represents the complex value represented by the string.
*
* @param s a string to be converted to a complex.
* @throws NumberFormatException if the string does not contain a
* parsable number.
*/publicstaticComplexvalueOf(String s){
returnparseComplex(s);}/**
* Constructs a newly allocated Complex object that
* represents the complex value represented by the string.
*
* @param s a string to be converted to a complex.
* @throws NumberFormatException if the string does not contain a
* parsable number.
*/publicstaticComplexparseComplex(String s){
double real =0;double imag =0;finalString doubleRegex ="[-+]?(\\d+(\\.\\d*)?|\\.\\d+)([eE]([-+]?([012]?\\d{1,2}|30[0-7])|-3([01]?[4-9]|[012]?[0-3])))?";finalString pureImagRegex = doubleRegex+"[a-zA-Z]";finalString complexRegex1 ="(?<real>"+doubleRegex+")"+"(?<imag>"+doubleRegex+")"+"[a-zA-Z]";finalString complexRegex2 ="(?<imag>"+doubleRegex+")"+"[a-zA-Z]"+"(?<real>"+doubleRegex+")";if(Pattern.compile(doubleRegex).matcher(s).matches()){
// It's just a real number.
real =Double.parseDouble(s);}elseif(Pattern.compile(pureImagRegex).matcher(s).matches()){
// It's just a pure imaginary number.
imag =Double.parseDouble(s.substring(0, s.length()-1));}else{
Matcher matcher =Pattern.compile(complexRegex1).matcher(s);if(matcher.matches()){
// It's like '20.02+12.25i'.
real =Double.parseDouble(matcher.group("real"));
imag =Double.parseDouble(matcher.group("imag"));}else{
matcher =Pattern.compile(complexRegex2).matcher(s);if(matcher.matches()){
// It's like '12.25i+20.02'.
real =Double.parseDouble(matcher.group("real"));
imag =Double.parseDouble(matcher.group("imag"));}else{
thrownewNumberFormatException("\""+ s +"\" can't be translated as a complex.");}}}returnnewComplex(real, imag);}/***** Arithmetic Operations *****//**
* Does this equal another complex within the allowed error range 1e-6?
*
* @param complex complex to be compared with
* @return true / false
*/publicbooleaneq(Complex complex){
returnMath.abs(real-complex.real)+Math.abs(imag-complex.imag)<1e-6;}/**
* Returns a new Complex whose value is {this + augend}
*
* @param augend complex to be added to this
* @return {this + augend}
*/publicComplexadd(Complex augend){
returnnewComplex(this.real+augend.real,this.imag+augend.imag);}/**
* Returns a new Complex whose value is {this + real}
*
* @param real real number to be added to this
* @return {this + real}
*/publicComplexadd(double real){
returnnewComplex(this.real+real,this.imag);}/**
* Returns a new Complex whose value is {this - subtrahend}
*
* @param subtrahend complex to be subtracted from this
* @return {this - subtrahend}
*/publicComplexsub(Complex subtrahend){
returnnewComplex(this.real-subtrahend.real,this.imag-subtrahend.imag);}publicComplexsub(double real){
returnnewComplex(this.real-real,this.imag);}/**
* Returns a new Complex whose value is {this * multiplicand}
*
* @param multiplicand complex to be multiplied by this
* @return {this * multiplicand}
*/publicComplexmul(Complex multiplicand){
double real =this.real*multiplicand.real -this.imag*multiplicand.imag;double imag =this.real*multiplicand.imag +this.imag*multiplicand.real;returnnewComplex(real, imag);}publicComplexmul(double real){
returnnewComplex(this.real*real,this.imag*real);}/**
* Returns a new Complex whose value is {this / divisor}
*
* @param divisor complex by which this is to be divided
* @return {this / divisor}
* @throws ArithmeticException if /0
*/publicComplexdiv(Complex divisor){
double denominator = divisor.real*divisor.real + divisor.imag*divisor.imag;if(denominator ==0){
thrownewArithmeticException("Complex division by zero!");}double real =(this.real*divisor.real +this.imag*divisor.imag)/ denominator;double imag =(this.imag*divisor.real -this.real*divisor.imag)/ denominator;returnnewComplex(real, imag);}publicComplexdiv(double real){
if(real ==0){
thrownewArithmeticException("Complex division by zero!");}returnnewComplex(this.real/real,this.imag/real);}/**
* Returns the modulus value of a complex number ( 复数的模 )
*
* @return length of the vector in 2d plane
*/publicdoubleabs(){
returnMath.sqrt(real*real + imag*imag);}/**
* Returns the modulus value of a complex number ( 复数的模 )
*
* @return length of the vector in 2d plane
*/publicdoublemod(){
returnMath.sqrt(real*real + imag*imag);}/**
* Returns the argument of a complex number ( 复数的辐角 )
*
* @return angle in radians of the vector in 2d plane (-PI~PI)
*/publicdoublearg(){
returnMath.atan2(this.imag,this.real);}/**
* Returns the inverse of a complex number ( 复数的倒数 )
*
* @return inverse of this
* @throws ArithmeticException ZERO has no inverse.
*/publicComplexinv(){
double denominator = real*real + imag*imag;if(denominator ==0){
thrownewArithmeticException("ZERO has no inverse!");}double real =this.real / denominator;double imag =this.imag / denominator;returnnewComplex(real, imag);}/**
* Returns the numerical negative value of a complex number
*
* @return {0 - this}
*/publicComplexneg(){
returnnewComplex(-this.real,-this.imag);}/**
* Returns the conjugate of a complex number
*
* @return conjugate of this
*/publicComplexconj(){
returnnewComplex(this.real,-this.imag);}/**
* Returns the square root of a complex number
*
* @return square root of this
*/publicComplexsqrt(){
double mod =this.mod();double sqrt2 =Math.sqrt(2);double real =Math.sqrt(mod +this.real)/ sqrt2;double sgn =Math.signum(this.imag);if(sgn ==0.0){
sgn =1.0;}double imag =Math.sqrt(mod -this.real)/ sqrt2 *Math.signum(sgn);returnnewComplex(real, imag);}/**
* Is this exactly ZERO?
*
* @return true / false
*/publicbooleanisZero(){
returnthis.real ==0&&this.imag ==0;}/**
* Is this a pure real number?
*
* @return true / false
*/publicbooleanisReal(){
returnthis.imag ==0;}/**
* Is this a pure imaginary number?
*
* @return true / false
*/publicbooleanisImag(){
returnthis.real ==0;}}