package jp.hasc.hasctool.core.data;

/**
 * 複素数クラス
 * @author hiro
 */

public class Complex {

	private final double re;   // 実数
		private final double im;   // 虚数

		//コンストラクタ
		public Complex(double real, double imag) {
				re = real;
				im = imag;
		}

		//実数、虚数を返す
		public double re() { return re; }
		public double im() { return im; }

		//大きさ、位相を返す
		public double abs()   { return Math.hypot(re, im); }
		public double phase() { return Math.atan2(im, re); }

		//複素共役
		public Complex conjugate() {  return new Complex(re, -im); }

		//逆数
		public Complex reciprocal() {
				double scale = re*re + im*im;
				return new Complex(re / scale, -im / scale);
		}

		//引数を加える
		public Complex plus(Complex b) {
				Complex a = this;
				double real = a.re + b.re;
				double imag = a.im + b.im;
				return new Complex(real, imag);
		}

		//引数を差し引く
		public Complex minus(Complex b) {
				Complex a = this;
				double real = a.re - b.re;
				double imag = a.im - b.im;
				return new Complex(real, imag);
		}

		//引数をかける
		public Complex times(Complex b) {
				Complex a = this;
				double real = a.re * b.re - a.im * b.im;
				double imag = a.re * b.im + a.im * b.re;
				return new Complex(real, imag);
		}

		//引数倍
		public Complex times(double alpha) {
				return new Complex(alpha * re, alpha * im);
		}

		//引数で割る
		public Complex divides(Complex b) {
				Complex a = this;
				return a.times(b.reciprocal());
		}

		/** auto generated */
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			long temp;
			temp = Double.doubleToLongBits(im);
			result = prime * result + (int) (temp ^ (temp >>> 32));
			temp = Double.doubleToLongBits(re);
			result = prime * result + (int) (temp ^ (temp >>> 32));
			return result;
		}

		/** auto generated */
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			Complex other = (Complex) obj;
			if (Double.doubleToLongBits(im) != Double.doubleToLongBits(other.im))
				return false;
			if (Double.doubleToLongBits(re) != Double.doubleToLongBits(other.re))
				return false;
			return true;
		}
}

