1 4 package gnu.math; 5 6 public abstract class Complex extends Quantity 7 { 8 public Complex number() { return this; } 9 10 public boolean isExact () 11 { 12 return re().isExact() && im().isExact(); 14 } 15 16 private static CComplex imOne; 17 private static CComplex imMinusOne; 18 19 public static CComplex imOne() 20 { 21 if (imOne == null) 22 imOne = new CComplex (IntNum.zero(), IntNum.one()); 23 return imOne; 24 } 25 26 public static CComplex imMinusOne() 27 { 28 if (imMinusOne == null) 29 imMinusOne = new CComplex (IntNum.zero(), IntNum.minusOne()); 30 return imMinusOne; 31 } 32 33 public double doubleValue () { return re().doubleValue (); } 34 public double doubleImagValue () { return im().doubleValue (); } 35 public final double doubleRealValue () { return doubleValue (); } 36 public long longValue () { return re().longValue(); } 37 38 public static Complex make (RealNum re, RealNum im) 39 { 40 if (im.isZero ()) 41 return re; 42 if (! re.isExact() || ! im.isExact()) 43 return new DComplex(re.doubleValue(), im.doubleValue()); 44 return new CComplex (re, im); 45 } 46 47 public static Complex make (double re, double im) 48 { 49 if (im == 0.0) 50 return new DFloNum(re); 51 return new DComplex(re, im); 52 } 53 54 public static DComplex polar (double r, double t) 55 { 56 return new DComplex(r * Math.cos(t), r * Math.sin(t)); 57 } 58 59 public static DComplex polar (RealNum r, RealNum t) 60 { 61 return polar(r.doubleValue(), t.doubleValue()); 62 } 63 64 public static Complex power (Complex x, Complex y) 65 { 66 if (y instanceof IntNum) 67 return (Complex) x.power((IntNum) y); 68 double x_re = x.doubleRealValue(); 69 double x_im = x.doubleImagValue(); 70 double y_re = y.doubleRealValue(); 71 double y_im = y.doubleImagValue(); 72 if (x_im == 0.0 && y_im == 0 73 && (x_re >= 0 || Double.isInfinite(x_re) || Double.isNaN(x_re))) 74 return new DFloNum (Math.pow (x_re, y_re)); 75 return DComplex.power (x_re, x_im, y_re, y_im); 76 } 77 78 public Numeric abs () 79 { 80 81 83 return new DFloNum(DComplex.hypot(doubleRealValue(), doubleImagValue())); 84 85 } 86 87 public RealNum angle() 88 { 89 return new DFloNum(Math.atan2(doubleImagValue(), doubleRealValue())); 90 } 91 92 public static boolean equals (Complex x, Complex y) 93 { 94 return x.re().equals(y.re()) 95 && x.im().equals(x.im()); 96 } 97 98 public boolean equals (Object obj) 99 { 100 if (obj == null || ! (obj instanceof Complex)) 101 return false; 102 return Complex.equals (this, (Complex) obj); 103 } 104 105 public static int compare (Complex x, Complex y) 106 { 107 int code = x.im().compare(y.im()); 108 if (code != 0) 109 return code; 110 return x.re().compare(y.re()); 111 } 112 113 public int compare (Object obj) 114 { 115 if (! (obj instanceof Complex)) 116 return ((Numeric) obj).compareReversed(this); 117 return compare(this, (Complex) obj); 118 } 119 120 public boolean isZero () 121 { 122 return re().isZero () && im().isZero(); 123 } 124 125 127 131 132 133 public String toString (int radix) 134 { 135 if (im().isZero ()) 140 return re().toString(radix); 141 String imString = im().toString(radix) + "i"; 142 if (imString.charAt(0) != '-') 143 imString = "+" + imString; 144 if (re().isZero()) 145 return imString; 146 return re().toString(radix) + imString; 147 } 148 149 public static Complex neg (Complex x) 150 { 151 return Complex.make (x.re().rneg(), x.im().rneg()); 152 } 153 154 public Numeric neg () { return neg (this); } 155 156 public static Complex add (Complex x, Complex y, int k) 157 { 158 return Complex.make (RealNum.add(x.re(), y.re(), k), 159 RealNum.add(x.im(), y.im(), k)); 160 } 161 162 public Numeric add (Object y, int k) 163 { 164 if (y instanceof Complex) 165 return add (this, (Complex) y, k); 166 return ((Numeric)y).addReversed(this, k); 167 } 168 169 public Numeric addReversed (Numeric x, int k) 170 { 171 if (x instanceof Complex) 172 return add ((Complex)x, this, k); 173 throw new IllegalArgumentException (); 174 } 175 176 public static Complex times (Complex x, Complex y) 177 { 178 RealNum x_re = x.re(); 179 RealNum x_im = x.im(); 180 RealNum y_re = y.re(); 181 RealNum y_im = y.im(); 182 return Complex.make (RealNum.add (RealNum.times(x_re, y_re), 183 RealNum.times(x_im, y_im), -1), 184 RealNum.add (RealNum.times(x_re, y_im), 185 RealNum.times(x_im, y_re), 1)); 186 } 187 188 public Numeric mul (Object y) 189 { 190 if (y instanceof Complex) 191 return times(this, (Complex) y); 192 return ((Numeric)y).mulReversed(this); 193 } 194 195 public Numeric mulReversed (Numeric x) 196 { 197 if (x instanceof Complex) 198 return times((Complex)x, this); 199 throw new IllegalArgumentException (); 200 } 201 202 public static Complex divide (Complex x, Complex y) 203 { 204 if (! x.isExact () || ! y.isExact ()) 205 return DComplex.div (x.doubleRealValue(), x.doubleImagValue(), 206 y.doubleRealValue(), y.doubleImagValue()); 207 208 RealNum x_re = x.re(); 209 RealNum x_im = x.im(); 210 RealNum y_re = y.re(); 211 RealNum y_im = y.im(); 212 213 RealNum q = RealNum.add (RealNum.times(y_re, y_re), 214 RealNum.times(y_im, y_im), 1); 215 RealNum n = RealNum.add(RealNum.times(x_re, y_re), 216 RealNum.times(x_im, y_im), 1); 217 RealNum d = RealNum.add(RealNum.times(x_im, y_re), 218 RealNum.times(x_re, y_im), -1); 219 return Complex.make(RealNum.divide(n, q), RealNum.divide(d, q)); 220 } 221 222 public Numeric div (Object y) 223 { 224 if (y instanceof Complex) 225 return divide(this, (Complex) y); 226 return ((Numeric)y).divReversed(this); 227 } 228 229 public Numeric divReversed (Numeric x) 230 { 231 if (x instanceof Complex) 232 return divide((Complex)x, this); 233 throw new IllegalArgumentException (); 234 } 235 236 public Complex exp () 237 { 238 return polar (Math.exp(doubleRealValue()), doubleImagValue()); 239 } 240 241 242 public Complex log () 243 { 244 return DComplex.log(doubleRealValue(), doubleImagValue()); 245 } 246 247 public Complex sqrt () 248 { 249 return DComplex.sqrt(doubleRealValue(), doubleImagValue()); 250 } 251 } 252 | Popular Tags |