// umbcComplex.java /* * Copyright (c) 2003 Jon S. Squire. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * -Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the distribution. * * Neither the name of the author or the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. THE AUTHOR AND CONTRIBUTORS * SHALL NOT BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE * AS A RESULT OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE * SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL THE AUTHOR OR CONTRIBUTORS * OR SUCCEEDING LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, * ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF THE AUTHOR * OR CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed, licensed or * intended for use in the design, construction, operation or * maintenance of any human use medical device. */ package myjava; /** Immutable, umbcComplex numbers. A umbcComplex consists of a real * and imaginary part, called Cartesian coordinates. * * The umbcComplex class provides methods for arithmetic such as: * add, subtract, multiply, divide, negate and invert. * Also provided are umbcComplex functions sin, cos, tan, atan, * sqrt, log, exp, pow, sinh, cosh, tanh, atanh. * * Source code umbcComplex.java */ public strictfp class umbcComplex extends Object { double x, y; // Cartesian representation of umbcComplex /** cartesian coordinates real and imaginary are NaN */ public umbcComplex(){x=Double.NaN; y=Double.NaN;} /** construct a copy of a umbcComplex object */ public umbcComplex(umbcComplex z){x=z.real(); y=z.imaginary();} /** real value, imaginary=0.0 */ public umbcComplex(double x){this.x=x; y=0.0;} /** cartesian coordinates real and imaginary */ public umbcComplex(double x, double y){this.x=x; this.y=y;} /** convert cartesian to polar */ public umbcComplex polar(){double r = StrictMath.sqrt( this.x*this.x+this.y*this.y); double a = StrictMath.atan2(this.y,this.x); return new umbcComplex(r,a);} /** convert polar to cartesian */ public umbcComplex cartesian(){return new umbcComplex(this.x*StrictMath.cos(this.y), this.x*StrictMath.sin(this.y));} /** extract the real part of the umbcComplex number */ public double real(){return this.x;} /** extract the imaginary part of the umbcComplex number */ public double imaginary(){return this.y;} /** extract the magnitude of the umbcComplex number */ public double magnitude(){return StrictMath.sqrt(this.x*this.x+this.y*this.y);} /** extract the argument of the umbcComplex number */ public double argument(){return StrictMath.atan2(this.y,this.x);} /** add umbcComplex numbers */ public umbcComplex add(umbcComplex z){return new umbcComplex (this.x+z.x, this.y+z.y);} /** add a double to a umbcComplex number */ public umbcComplex add(double d){return new umbcComplex (this.x+d, this.y);} /** subtract z from the umbcComplex number */ public umbcComplex subtract(umbcComplex z){return new umbcComplex (this.x-z.x, this.y-z.y);} /** subtract the double d from the umbcComplex number */ public umbcComplex subtract(double d){return new umbcComplex (this.x-d, this.y);} /** negate the umbcComplex number */ public umbcComplex negate(){return new umbcComplex(-this.x, -this.y);} /** multiply umbcComplex numbers */ public umbcComplex multiply(umbcComplex z){return new umbcComplex (this.x*z.x-this.y*z.y, this.x*z.y+this.y*z.x);} /** multiply a umbcComplex number by a double */ public umbcComplex multiply(double d){return new umbcComplex(this.x*d,this.y*d);} /** divide the umbcComplex number by z */ public umbcComplex divide(umbcComplex z){double r=z.x*z.x+z.y*z.y; return new umbcComplex ((this.x*z.x+this.y*z.y)/r, (this.y*z.x-this.x*z.y)/r);} /** divide the umbcComplex number by the double d */ public umbcComplex divide(double d){return new umbcComplex(this.x/d,this.y/d);} /** invert the umbcComplex number */ public umbcComplex invert(){double r=this.x*this.x+this.y*this.y; return new umbcComplex(this.x/r, -this.y/r);} /** conjugate the umbcComplex number */ public umbcComplex conjugate(){return new umbcComplex(this.x, -this.y);} /** compute the absolute value of a umbcComplex number */ public double abs(){return StrictMath.sqrt(this.x*this.x+this.y*this.y);} /** compare umbcComplex numbers for equality */ public boolean equals(umbcComplex z){return (z.x==this.x) && (z.y==this.y);} /** convert a umbcComplex number to a String. * umbcComplex z = new umbcComplex(1.0,2.0); * System.out.println("z="+z); */ public String toString(){return new String("("+this.x+","+this.y+")");} /** convert text representation to a umbcComplex. * input format (real_double,imaginary_double) */ public static umbcComplex parseumbcComplex(String s){ int from = s.indexOf('('); if(from==-1) return null; int to = s.indexOf(',',from); double x = Double.parseDouble(s.substring(from+1,to)); from = to; to = s.indexOf(')',from); double y = Double.parseDouble(s.substring(from+1,to)); return new umbcComplex(x,y); } /** compute e to the power of the umbcComplex number */ public umbcComplex exp(){double exp_x=StrictMath.exp(this.x); return new umbcComplex (exp_x*StrictMath.cos(this.y), exp_x*StrictMath.sin(this.y));} /** compute the natural logarithm of the umbcComplex number */ public umbcComplex log(){double rpart=StrictMath.sqrt( this.x*this.x+this.y*this.y); double ipart=StrictMath.atan2(this.y,this.x); if(ipart>StrictMath.PI) ipart=ipart-2.0*StrictMath.PI; return new umbcComplex(StrictMath.log(rpart), ipart);} /** compute the square root of the umbcComplex number */ public umbcComplex sqrt(){double r=StrictMath.sqrt(this.x*this.x+this.y*this.y); double rpart=StrictMath.sqrt(0.5*(r+this.x)); double ipart=StrictMath.sqrt(0.5*(r-this.x)); if(this.y<0.0) ipart=-ipart; return new umbcComplex(rpart,ipart);} /** compute the umbcComplex number raised to the power z */ public umbcComplex pow(umbcComplex z){umbcComplex a=z.multiply(this.log()); return a.exp();} /** compute the umbcComplex number raised to the power double d */ public umbcComplex pow(double d){umbcComplex a=(this.log()).multiply(d); return a.exp();} /** compute the sin of the umbcComplex number */ public umbcComplex sin(){return new umbcComplex (StrictMath.sin(this.x)*cosh(this.y), StrictMath.cos(this.x)*sinh(this.y));} /** compute the cosine of the umbcComplex number */ public umbcComplex cos(){return new umbcComplex (StrictMath.cos(this.x)*cosh(this.y), -StrictMath.sin(this.x)*sinh(this.y));} /** compute the tangent of the umbcComplex number */ public umbcComplex tan(){return (this.sin()).divide(this.cos());} /** compute the arctangent of a umbcComplex number */ public umbcComplex atan(){umbcComplex IM = new umbcComplex(0.0,-1.0); umbcComplex ZP = new umbcComplex(1.0+this.y,this.x); umbcComplex ZM = new umbcComplex(1.0-this.y,this.x); return IM.multiply(((ZP.log()).subtract( ZM.log())).divide(2.0));} /** compute the hyperbolic sin of the umbcComplex number */ public umbcComplex sinh(){return new umbcComplex (sinh(this.x)*StrictMath.cos(this.y), cosh(this.x)*StrictMath.sin(this.y));} /** compute the hyperbolic cosine of the umbcComplex number */ public umbcComplex cosh(){return new umbcComplex (cosh(this.x)*StrictMath.cos(this.y), sinh(this.x)*StrictMath.sin(this.y));} /** compute the hyperbolic tangent of the umbcComplex number */ public umbcComplex tanh(){return (this.sinh()).divide(this.cosh());} /** compute the inverse hyperbolic tangent of a umbcComplex number */ public umbcComplex atanh(){return (((this.add(1.0)).log()).subtract( ((this.subtract(1.0)).negate()).log()) .divide(2.0));} // local - should be a good implementation in StrictMath private double sinh(double x){return( StrictMath.exp(x)-StrictMath.exp(-x))/2.0;} private double cosh(double x){return( StrictMath.exp(x)+StrictMath.exp(-x))/2.0;} }