/** * Complex.java - implements a complex number class * Copyright (C) 2003 by Michael F. Hutt * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ package com.huttsystems.math; /** * Complex.java - This class provides mathematical operations for complex numbers. * @author Michael F. Hutt * @author hutt@ieee.org * @author http://www.huttsystems.com * @version 1.0 * @version Copyright (C) 2003 * @date Feb. 21, 2003 * @todo Still need to add log10 */ public class Complex { private double real; private double imag; static double PI = Math.acos(-1); public Complex(){ real = 0; imag = 0; } public Complex(double r, double i) { real = r; imag = i; } public Complex(double r) { real = r; imag = 0; } public Complex(Complex z) { real = z.re(); imag = z.im(); } public double re() { return real; } public static double re(Complex z) { return z.real; } public double im() { return imag; } public static double im(Complex z) { return z.imag; } public static Complex conj(Complex z) { Complex retval = new Complex(z.real,-z.imag); return retval; } /** * @return Returns the absolute value or magnitude of a complex number */ public static double abs(Complex z) { double retval = Math.sqrt(z.real*z.real + z.imag*z.imag); return retval; } public static double arg(Complex z) { double retval = Math.atan2(z.imag,z.real); return retval; } /** * @return Returns the magnitude squared of a complex number */ public static double norm(Complex z) { double retval = z.real*z.real + z.imag*z.imag; return retval; } public Complex add(Complex z) { Complex retval = new Complex(real+z.real,imag+z.imag); return retval; } public Complex add(double a) { Complex retval = new Complex(real+a,imag); return retval; } public static Complex add(Complex y, Complex z) { Complex retval = new Complex(y.real+z.real,y.imag+z.imag); return retval; } public static Complex add(Complex z, double a) { Complex retval = new Complex(z.real+a,z.imag); return retval; } public static Complex add(double a, Complex z) { Complex retval = new Complex(a+z.real,z.imag); return retval; } public Complex sub(Complex z) { Complex retval = new Complex(real-z.real,imag-z.imag); return retval; } public Complex sub(double a) { Complex retval = new Complex(real-a,imag); return retval; } public static Complex sub(Complex y, Complex z) { Complex retval = new Complex(y.real-z.real,y.imag-z.imag); return retval; } public static Complex sub(Complex z, double a) { Complex retval = new Complex(z.real-a,z.imag); return retval; } public static Complex sub(double a, Complex z) { Complex retval = new Complex(a-z.real,-z.imag); return retval; } public static Complex negative(Complex z) { Complex retval = new Complex(-z.real,-z.imag); return retval; } public Complex mult(Complex z) { Complex retval = new Complex(real*z.real - imag*z.imag, real*z.imag + imag*z.real); return retval; } public Complex mult(double a) { Complex retval = new Complex(real*a,imag*a); return retval; } public static Complex mult(Complex y, Complex z) { Complex retval = new Complex(y.real*z.real - y.imag*z.imag, y.real*z.imag + y.imag*z.real); return retval; } public static Complex mult(Complex z, double a) { Complex retval = new Complex(z.real*a,z.imag*a); return retval; } public static Complex mult(double a, Complex z) { Complex retval = new Complex(a*z.real,a*z.imag); return retval; } public Complex div(double a) { Complex retval = new Complex(real/a,imag/a); return retval; } public Complex div(Complex z) { Complex retval,top = new Complex(); double bottom = norm(z); top = mult(conj(z)); retval = top.div(bottom); return retval; } public static Complex div(Complex y, Complex z) { Complex retval,top = new Complex(); double bottom = norm(z); top = y.mult(conj(z)); retval = top.div(bottom); return retval; } public static Complex div(Complex z, double a) { Complex retval = new Complex(z.real/a,z.imag/a); return retval; } public static Complex div(double a, Complex z) { Complex retval,top = new Complex(); top = conj(z).mult(a); double bottom = norm(z); retval = top.div(bottom); return retval; } public boolean equals(Complex z) { boolean retval = false; if (real == z.real && imag == z.imag) { retval = true; } return retval; } public static Complex sqrt(Complex z) { double zsqre, zsqim; Complex retval; zsqre = Math.sqrt(0.5*(abs(z) + z.real)); zsqim = Math.sqrt(0.5*(abs(z) - z.real)); if (z.imag >= 0) { retval = new Complex(zsqre,zsqim); return retval; } else { retval = new Complex(zsqre,-zsqim); return retval; } } /** * @return Returns the natural log of a complex number */ public static Complex log(Complex z) { Complex j = new Complex(0,1); Complex retval = new Complex(); if (z.real < 0 && z.imag == 0) { retval = add(Math.log(abs(z)),j.mult(PI)); } else { retval = add(Math.log(abs(z)),j.mult(arg(z))); } return retval; } public static Complex exp(Complex z) { Complex j = new Complex(0,1); Complex retval,c,d = new Complex(); double a,b; a = Math.exp(z.real); b = Math.cos(z.imag); c = j.mult(Math.sin(z.imag)); d = add(b,c); retval = mult(a,d); return retval; } public static Complex pow(Complex y, Complex z) { Complex retval = new Complex(); retval = exp(mult(z,log(y))); return retval; } public static Complex pow(Complex z, double a) { Complex retval = new Complex(); retval = exp(mult(a,log(z))); return retval; } public static Complex sin(Complex z) { Complex retval,a,b = new Complex(); Complex j = new Complex(0,1); b = mult(0.5,negative(j).mult(exp(negative(j).mult(z)))); a = mult(0.5,negative(j.mult(exp(j.mult(z))))); retval = sub(a,b); return retval; } public static Complex cos(Complex z) { Complex retval,a,b = new Complex(); Complex j = new Complex(0,1); b = mult(0.5,exp(negative(j.mult(z)))); a = mult(0.5,exp(j.mult(z))); retval = add(a,b); return retval; } public static Complex tan(Complex z) { Complex retval = new Complex(); retval = div(sin(z),cos(z)); return retval; } public static Complex sec(Complex z) { Complex retval = new Complex(); retval = div(1,cos(z)); return retval; } public static Complex csc(Complex z) { Complex retval = new Complex(); retval = div(1,sin(z)); return retval; } public static Complex cot(Complex z) { Complex retval = new Complex(); retval = div(cos(z),sin(z)); return retval; } public static Complex sinh(Complex z) { Complex retval,a = new Complex(); a = sub(exp(z),exp(negative(z))); retval = div(a,2); return retval; } public static Complex cosh(Complex z) { Complex retval,a = new Complex(); a = add(exp(z),exp(negative(z))); retval = div(a,2); return retval; } public static Complex tanh(Complex z) { Complex retval = new Complex(); retval = div(sinh(z),cosh(z)); return retval; } public static Complex sech(Complex z) { Complex retval = new Complex(div(1,cosh(z))); return retval; } public static Complex csch(Complex z) { Complex retval = new Complex(div(1,sinh(z))); return retval; } public static Complex coth(Complex z) { Complex retval = new Complex(div(cosh(z),sinh(z))); return retval; } public static Complex asin(Complex z) { Complex retval,a,b = new Complex(); Complex j = new Complex(0,1); b = sqrt(sub(1,mult(z,z))); a = mult(j,z); retval = negative(j).mult(log(add(a,b))); return retval; } /** * @return Returns the acos of a complex number, * since cos(x) = cos(-x), return the positive angle */ public static Complex acos(Complex z) { Complex retval,a = new Complex(); Complex j = new Complex(0,1); a = sqrt(sub(mult(z,z),1)); retval = negative(j).mult(log(add(z,a))); if (retval.real >= 0) { return retval; } else { return negative(retval); } } public static Complex atan(Complex z) { Complex retval,a,b = new Complex(); Complex j = new Complex(0,1); a = mult(0.5,j); b = log(div(add(j,z),sub(j,z))); retval = mult(a,b); return retval; } public static Complex asinh(Complex z) { Complex retval,a = new Complex(); a = sqrt(add(mult(z,z),1)); retval = log(add(z,a)); return retval; } /** * @return Returns the acosh of a complex number, * should return the positive angle like acos(). */ public static Complex acosh(Complex z) { Complex retval,a = new Complex(); a = sqrt(sub(mult(z,z),1)); retval = log(add(z,a)); if (retval.real >= 0) { return retval; } else { return negative(retval); } } public static Complex atanh(Complex z) { Complex retval,a = new Complex(); a = div(add(1,z),sub(1,z)); retval = mult(0.5,log(a)); return retval; } public void prt() { System.out.println(real+","+imag+"j"); } public static void prt(Complex z) { System.out.println(z.real+","+z.imag+"j"); } }