001 // --- BEGIN LICENSE BLOCK --- 002 /* 003 * Copyright (c) 2009, Mikio L. Braun 004 * All rights reserved. 005 * 006 * Redistribution and use in source and binary forms, with or without 007 * modification, are permitted provided that the following conditions are 008 * met: 009 * 010 * * Redistributions of source code must retain the above copyright 011 * notice, this list of conditions and the following disclaimer. 012 * 013 * * Redistributions in binary form must reproduce the above 014 * copyright notice, this list of conditions and the following 015 * disclaimer in the documentation and/or other materials provided 016 * with the distribution. 017 * 018 * * Neither the name of the Technische Universit??t Berlin nor the 019 * names of its contributors may be used to endorse or promote 020 * products derived from this software without specific prior 021 * written permission. 022 * 023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 026 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 027 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 028 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 029 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 030 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 031 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 032 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 033 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 034 */ 035 // --- END LICENSE BLOCK --- 036 037 package org.jblas; 038 039 import static java.lang.Math.sqrt; 040 041 import java.nio.DoubleBuffer; 042 043 /** 044 * A complex value with double precision. 045 * 046 * @author Mikio L. Braun 047 * 048 */ 049 public class ComplexDouble { 050 051 private double r, i; 052 public static final ComplexDouble UNIT = new ComplexDouble(1.0, 0.0); 053 public static final ComplexDouble I = new ComplexDouble(0.0, 1.0); 054 public static final ComplexDouble NEG_UNIT = new ComplexDouble(-1.0, 0.0); 055 public static final ComplexDouble NEG_I = new ComplexDouble(0.0, -1.0); 056 public static final ComplexDouble ZERO = new ComplexDouble(0.0); 057 058 public ComplexDouble(double real, double imag) { 059 r = real; 060 i = imag; 061 } 062 063 public ComplexDouble(double real) { 064 this(real, 0.0); 065 } 066 067 public String toString() { 068 if (i >= 0) { 069 return r + " + " + i + "i"; 070 } else { 071 return r + " - " + (-i) + "i"; 072 } 073 } 074 075 public ComplexDouble set(double real, double imag) { 076 r = real; 077 i = imag; 078 return this; 079 } 080 081 public double real() { 082 return r; 083 } 084 085 public double imag() { 086 return i; 087 } 088 089 public ComplexDouble dup() { 090 return new ComplexDouble(r, i); 091 } 092 093 public ComplexDouble copy(ComplexDouble other) { 094 r = other.r; 095 i = other.i; 096 return this; 097 } 098 099 /** Add two complex numbers in-place */ 100 public ComplexDouble addi(ComplexDouble c, ComplexDouble result) { 101 if (this == result) { 102 r += c.r; 103 i += c.i; 104 } else { 105 result.r = r + c.r; 106 result.i = i + c.i; 107 } 108 return result; 109 } 110 111 /** Add two complex numbers in-place storing the result in this. */ 112 public ComplexDouble addi(ComplexDouble c) { 113 return addi(c, this); 114 } 115 116 /** Add two complex numbers. */ 117 public ComplexDouble add(ComplexDouble c) { 118 return dup().addi(c); 119 } 120 121 /** Add a real number to a complex number in-place. */ 122 public ComplexDouble addi(double a, ComplexDouble result) { 123 if (this == result) { 124 r += a; 125 } else { 126 result.r = r + a; 127 result.i = i; 128 } 129 return result; 130 } 131 132 /** Add a real number to complex number in-place, storing the result in this. */ 133 public ComplexDouble addi(double c) { 134 return addi(c, this); 135 } 136 137 /** Add a real number to a complex number. */ 138 public ComplexDouble add(double c) { 139 return dup().addi(c); 140 } 141 142 /** Subtract two complex numbers, in-place */ 143 public ComplexDouble subi(ComplexDouble c, ComplexDouble result) { 144 if (this == result) { 145 r -= c.r; 146 i -= c.i; 147 } else { 148 result.r = r - c.r; 149 result.i = i - c.i; 150 } 151 return this; 152 } 153 154 public ComplexDouble subi(ComplexDouble c) { 155 return subi(c, this); 156 } 157 158 /** Subtract two complex numbers */ 159 public ComplexDouble sub(ComplexDouble c) { 160 return dup().subi(c); 161 } 162 163 public ComplexDouble subi(double a, ComplexDouble result) { 164 if (this == result) { 165 r -= a; 166 } else { 167 result.r = r - a; 168 result.i = i; 169 } 170 return result; 171 } 172 173 public ComplexDouble subi(double a) { 174 return subi(a, this); 175 } 176 177 public ComplexDouble sub(double r) { 178 return dup().subi(r); 179 } 180 181 /** Multiply two complex numbers, inplace */ 182 public ComplexDouble muli(ComplexDouble c, ComplexDouble result) { 183 double newR = r * c.r - i * c.i; 184 double newI = r * c.i + i * c.r; 185 result.r = newR; 186 result.i = newI; 187 return result; 188 } 189 190 public ComplexDouble muli(ComplexDouble c) { 191 return muli(c, this); 192 } 193 194 /** Multiply two complex numbers */ 195 public ComplexDouble mul(ComplexDouble c) { 196 return dup().muli(c); 197 } 198 199 public ComplexDouble mul(double v) { 200 return dup().muli(v); 201 } 202 203 public ComplexDouble muli(double v, ComplexDouble result) { 204 if (this == result) { 205 r *= v; 206 i *= v; 207 } else { 208 result.r = r * v; 209 result.i = i * v; 210 } 211 return this; 212 } 213 214 public ComplexDouble muli(double v) { 215 return muli(v, this); 216 } 217 218 /** Divide two complex numbers */ 219 public ComplexDouble div(ComplexDouble c) { 220 return dup().divi(c); 221 } 222 223 /** Divide two complex numbers, in-place */ 224 public ComplexDouble divi(ComplexDouble c, ComplexDouble result) { 225 double d = c.r * c.r + c.i * c.i; 226 double newR = (r * c.r + i * c.i) / d; 227 double newI = (i * c.r - r * c.i) / d; 228 result.r = newR; 229 result.i = newI; 230 return result; 231 } 232 233 public ComplexDouble divi(ComplexDouble c) { 234 return divi(c, this); 235 } 236 237 public ComplexDouble divi(double v, ComplexDouble result) { 238 if (this == result) { 239 r /= v; 240 i /= v; 241 } else { 242 result.r = r / v; 243 result.i = i / v; 244 } 245 return this; 246 } 247 248 public ComplexDouble divi(double v) { 249 return divi(v, this); 250 } 251 252 public ComplexDouble div(double v) { 253 return dup().divi(v); 254 } 255 256 /** Return the absolute value */ 257 public double abs() { 258 return (double) sqrt(r * r + i * i); 259 } 260 261 public ComplexDouble invi() { 262 double d = r * r + i * i; 263 r = r / d; 264 i = -i / d; 265 return this; 266 } 267 268 public ComplexDouble inv() { 269 return dup().invi(); 270 } 271 272 public ComplexDouble neg() { 273 return dup().negi(); 274 } 275 276 public ComplexDouble negi() { 277 r = -r; 278 i = -i; 279 return this; 280 } 281 282 public ComplexDouble conji() { 283 i = -i; 284 return this; 285 } 286 287 public ComplexDouble conj() { 288 return dup().conji(); 289 } 290 291 /** 292 * Comparing two DoubleComplex values. 293 */ 294 public boolean equals(Object o) { 295 if (!(o instanceof ComplexDouble)) { 296 return false; 297 } 298 ComplexDouble c = (ComplexDouble) o; 299 300 return eq(c); 301 } 302 303 public boolean eq(ComplexDouble c) { 304 return Math.abs(r - c.r) + Math.abs(i - c.i) < (double) 1e-6; 305 } 306 307 public boolean ne(ComplexDouble c) { 308 return !eq(c); 309 } 310 311 public boolean isZero() { 312 return r == 0.0 && i == 0.0; 313 } 314 315 public boolean isReal() { 316 return i == 0.0; 317 } 318 319 public boolean isImag() { 320 return r == 0.0; 321 } 322 }